From e32f29e99eb10d4fbf1f2165738e2d92216f7088 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 19 Jun 2024 20:28:17 -0400 Subject: [PATCH 001/203] Adding new DoE object and skeleton functions First commit for DoE refactor. Skeleton functions added for development. --- pyomo/contrib/doe/doe.py | 108 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index a120add4200..6e45459a407 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -61,6 +61,114 @@ class ModelOptionLib(Enum): stage1 = "stage1" stage2 = "stage2" +class DesignOfExperiments_: + def __init__( + self, + experiment, + solver=None, + prior_FIM=None, + args=None, + only_compute_fim_lower=True, + logger_level=logging.INFO, + ): + """ + This package enables model-based design of experiments analysis with Pyomo. + Both direct optimization and enumeration modes are supported. + + The package has been refactored from its original form as of ##/##/##24. See + the documentation for more information. + + Parameters + ---------- + experiment: + Experiment object that holds the model and labels all the components. The object + should have a ``get_labeled_model`` where a model is returned with the following + labeled sets: ``unknown_parameters``, ``experimental_inputs``, ``experimental_outputs`` + solver: + A ``solver`` object specified by the user, default=None. + If not specified, default solver is IPOPT MA57. + prior_FIM: + A 2D numpy array containing Fisher information matrix (FIM) for prior experiments. + The default None means there is no prior information. + args: + Additional arguments for the ``get_labeled_model`` function on the Experiment object. + only_compute_fim_lower: + If True, only the lower triangle of the FIM is computed. Default is True. + logger_level: + Specify the level of the logger. Change to logging.DEBUG for all messages. + """ + # Assert that the Experiment object has callable ``get_labeled_model`` function + assert(callable(getattr(experiment, 'get_labeled_model'))) + + # Parameters, Design Variables, and Outputs are now directly connected + # to each model instance (meaning we no longer need to specify them + # in the constructor + + # Potentially keep something like this for deprecated version? Maybe not + # model_option_arg = ( + # "model_option" in inspect.getfullargspec(self.create_model).args + # ) + # mod_arg = "mod" in inspect.getfullargspec(self.create_model).args + # if model_option_arg and mod_arg: + # self._original_create_model_interface = True + # else: + # self._original_create_model_interface = False + + + # check if user-defined solver is given + if solver: + self.solver = solver + # if not given, use default solver + else: + self.solver = self._get_default_ipopt_solver() + + # check if there is prior info + if prior_FIM is None: + pass # Since the parameters are not yet populated, the prior_FIM will be + # set to zero when the prior_FIM is set. + else: + self.prior_FIM = prior_FIM + + # To-Do: Add check when parameters are populated that input FIM is the correct size + + # Set args as an empty dict if no arguments are passed + if args is None: + args = {} + self.args = args + + self.logger = logging.getLogger(__name__) + self.logger.setLevel(level=logger_level) + + self.only_compute_fim_lower = only_compute_fim_lower + + # Perform doe + def run_doe(self, ): + return + + # Perform multi-experiment doe (sequential, or ``greedy`` approach) + def run_multi_doe_sequential(self, N_exp=1): + return + + # Perform multi-experiment doe (simultaneous, optimal approach) + def run_multi_doe_simultaneous(self, N_exp=1): + return + + # Compute FIM for the DoE object + def compute_FIM(self, ): + return + + # Create the DoE model (with ``scenarios`` from finite differencing scheme) + def create_doe_model(self, ): + return + + # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) + def compute_FIM_full_factorial(self, ): + return + + +############################## +# Below is deprecated code # +############################## class DesignOfExperiments: def __init__( From c7a4da0306fdf751b993933485e2b52dce3b1ed6 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 20 Jun 2024 14:44:09 -0400 Subject: [PATCH 002/203] Refactoring scenario generation Mid-way through updating the scenario generation for the finite difference of the sensitivity matrix. Added an example file from the refactor hack-a-thon in November 2023. --- pyomo/contrib/doe/__init__.py | 2 +- pyomo/contrib/doe/doe.py | 425 +++++++++++++++++- .../doe/redesign/experiment_class_example.py | 256 +++++++++++ pyomo/contrib/doe/redesign/result.json | 1 + pyomo/contrib/doe/scenario.py | 114 +++-- 5 files changed, 743 insertions(+), 55 deletions(-) create mode 100644 pyomo/contrib/doe/redesign/experiment_class_example.py create mode 100644 pyomo/contrib/doe/redesign/result.json diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index e45aa3b44a3..a4c4b732343 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -9,6 +9,6 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ from .measurements import MeasurementVariables, DesignVariables, VariablesWithIndices -from .doe import DesignOfExperiments, CalculationMode, ObjectiveLib, ModelOptionLib +from .doe import DesignOfExperiments, CalculationMode, ObjectiveLib, ModelOptionLib, DesignOfExperiments_ from .scenario import ScenarioGenerator, FiniteDifferenceStep from .result import FisherResults, GridSearchResult diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 6e45459a407..1480b293b1b 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -98,7 +98,9 @@ def __init__( Specify the level of the logger. Change to logging.DEBUG for all messages. """ # Assert that the Experiment object has callable ``get_labeled_model`` function - assert(callable(getattr(experiment, 'get_labeled_model'))) + assert callable(getattr(experiment, 'get_labeled_model')), 'The experiment object must have a ``get_labeled_model`` function' + + self.experiment = experiment # Parameters, Design Variables, and Outputs are now directly connected # to each model instance (meaning we no longer need to specify them @@ -120,7 +122,11 @@ def __init__( self.solver = solver # if not given, use default solver else: - self.solver = self._get_default_ipopt_solver() + solver = pyo.SolverFactory("ipopt") + solver.options["linear_solver"] = "ma57" + solver.options["halt_on_ampl_error"] = "yes" + solver.options["max_iter"] = 3000 + self.solver = solver # check if there is prior info if prior_FIM is None: @@ -140,26 +146,429 @@ def __init__( self.logger.setLevel(level=logger_level) self.only_compute_fim_lower = only_compute_fim_lower + + # model attribute to avoid rebuilding models + self.model = None + self._built_scenarios = False # Perform doe - def run_doe(self, ): - return + def run_doe( + self, + objective_option="det", + scale_nominal_param_value=False, + scale_constant_value=1, + optimize_opt=None, + if_Cholesky=False, + L_LB=1e-7, + L_initial=None, + jac_initial=None, + fim_initial=None, + formula="central", + step=0.001, + tee_opt=True, + ): + """ + Optimize an experimental design. The procedure has a two steps + (1) Solve a square problem with the experimental design fixed [initializes model equations] + (2) Solve the unfixed system for optimal experimental design + + Parameters + ---------- + objective_option: + choose from the ObjectiveLib enum options, + "det": the determinant of the FIM, + "trace": the trace of the FIM, + "zero": a value of zero + scale_nominal_param_value: + if True, the parameters are scaled by its own nominal value in param_init + scale_constant_value: + scale all elements in Jacobian matrix, default is 1. + optimize_opt: + A dictionary, keys are design variables, values are True or False deciding if this design variable will be optimized as DOF or not + if_Cholesky: + if True, Cholesky decomposition is used for Objective function for D-optimality. + L_LB: + L is the Cholesky decomposition matrix for FIM, i.e. FIM = L*L.T. + L_LB is the lower bound for every element in L. + if FIM is positive definite, the diagonal element should be positive, so we can set a LB like 1E-10 + L_initial: + initialize the L + jac_initial: + a matrix used to initialize jacobian matrix + fim_initial: + a matrix used to initialize FIM matrix + formula: + choose from "central", "forward", "backward", + which refers to the Enum FiniteDifferenceStep.central, .forward, or .backward + step: + Sensitivity perturbation step size, a fraction between [0,1]. default is 0.001 + tee_opt: + if True, IPOPT console output is printed + + Returns + ------- + analysis_square: result summary of the square problem solved at the initial point + analysis_optimize: result summary of the optimization problem solved + + """ + # Check that experimental outputs exist + try: + outputs = [k.name for k, v in model.experiment_outputs.items()] + except: + RuntimeError( + 'Experiment list model does not have suffix ' + '"experiment_outputs".' + ) + + # Check that experimental inputs exist + # Check that unknown parameters exist + # Check that measurement errors exist + # store inputs in object + self.design_values = self.design_vars.variable_names_value + self.optimize = if_optimize + self.objective_option = ObjectiveLib(objective_option) + self.scale_nominal_param_value = scale_nominal_param_value + self.scale_constant_value = scale_constant_value + self.Cholesky_option = if_Cholesky + self.L_LB = L_LB + self.L_initial = L_initial + self.jac_initial = jac_initial + self.fim_initial = fim_initial + self.formula = FiniteDifferenceStep(formula) + self.step = step + self.tee_opt = tee_opt + + # Start timer + sp_timer = TicTocTimer() + sp_timer.tic(msg=None) + + # Generate model + if self.model is None: + self.model = pyo.ConcreteModel() + + # build the large DOE pyomo model + if not self._built_scenarios: + self.create_doe_model(mod=self.model) + + # solve model, achieve results for square problem, and results for optimization problem + m, analysis_square = self._compute_stochastic_program(m, optimize_opt) + + if self.optimize: + # If set to optimize, solve the optimization problem (with degrees of freedom) + analysis_optimize = self._optimize_stochastic_program(m) + dT = sp_timer.toc(msg=None) + self.logger.info("elapsed time: %0.1f seconds" % dT) + # Return both square problem and optimization problem results + return analysis_square, analysis_optimize + + else: + dT = sp_timer.toc(msg=None) + self.logger.info("elapsed time: %0.1f seconds" % dT) + # Return only square problem results + return analysis_square # Perform multi-experiment doe (sequential, or ``greedy`` approach) def run_multi_doe_sequential(self, N_exp=1): - return + raise NotImplementedError( + "Multipled experiment optimization note yet supported." + ) # Perform multi-experiment doe (simultaneous, optimal approach) def run_multi_doe_simultaneous(self, N_exp=1): - return + raise NotImplementedError( + "Multipled experiment optimization note yet supported." + ) # Compute FIM for the DoE object def compute_FIM(self, ): return # Create the DoE model (with ``scenarios`` from finite differencing scheme) - def create_doe_model(self, ): - return + def create_doe_model(self, mod=None): + """ + Add equations to compute sensitivities, FIM, and objective. + + Parameters + ----------- + no_obj: if True, objective function is 0. + + Return + ------- + model: the DOE model + """ + + # Developer recommendation: use the Cholesky decomposition for D-optimality + # The explicit formula is available for benchmarking purposes and is NOT recommended + if ( + self.only_compute_fim_lower + and self.objective_option == ObjectiveLib.det + and not self.Cholesky_option + ): + raise ValueError( + "Cannot compute determinant with explicit formula if only_compute_fim_lower is True." + ) + + self._generate_scenario_blocks(mod=mod) + + + # variables for jacobian and FIM + model.regression_parameters = pyo.Set(initialize=list(self.param.keys())) + model.measured_variables = pyo.Set(initialize=self.measure_name) + + def identity_matrix(m, i, j): + if i == j: + return 1 + else: + return 0 + + ### Initialize the Jacobian if provided by the user + + # If the user provides an initial Jacobian, convert it to a dictionary + if self.jac_initial is not None: + dict_jac_initialize = {} + for i, bu in enumerate(model.regression_parameters): + for j, un in enumerate(model.measured_variables): + if isinstance(self.jac_initial, dict): + # Jacobian is a dictionary of arrays or lists where the key is the regression parameter name + dict_jac_initialize[(bu, un)] = self.jac_initial[bu][j] + elif isinstance(self.jac_initial, np.ndarray): + # Jacobian is a numpy array, rows are regression parameters, columns are measured variables + dict_jac_initialize[(bu, un)] = self.jac_initial[i][j] + + # Initialize the Jacobian matrix + def initialize_jac(m, i, j): + # If provided by the user, use the values now stored in the dictionary + if self.jac_initial is not None: + return dict_jac_initialize[(i, j)] + # Otherwise initialize to 0.1 (which is an arbitrary non-zero value) + else: + return 0.1 + + model.sensitivity_jacobian = pyo.Var( + model.regression_parameters, + model.measured_variables, + initialize=initialize_jac, + ) + + if self.fim_initial is not None: + dict_fim_initialize = { + (bu, un): self.fim_initial[i][j] + for i, bu in enumerate(model.regression_parameters) + for j, un in enumerate(model.regression_parameters) + } + + def initialize_fim(m, j, d): + return dict_fim_initialize[(j, d)] + + if self.fim_initial is not None: + model.fim = pyo.Var( + model.regression_parameters, + model.regression_parameters, + initialize=initialize_fim, + ) + else: + model.fim = pyo.Var( + model.regression_parameters, + model.regression_parameters, + initialize=identity_matrix, + ) + + # if cholesky, define L elements as variables + if self.Cholesky_option and self.objective_option == ObjectiveLib.det: + + # move the L matrix initial point to a dictionary + if self.L_initial is not None: + dict_cho = { + (bu, un): self.L_initial[i][j] + for i, bu in enumerate(model.regression_parameters) + for j, un in enumerate(model.regression_parameters) + } + + # use the L dictionary to initialize L matrix + def init_cho(m, i, j): + return dict_cho[(i, j)] + + # Define elements of Cholesky decomposition matrix as Pyomo variables and either + # Initialize with L in L_initial + if self.L_initial is not None: + model.L_ele = pyo.Var( + model.regression_parameters, + model.regression_parameters, + initialize=init_cho, + ) + # or initialize with the identity matrix + else: + model.L_ele = pyo.Var( + model.regression_parameters, + model.regression_parameters, + initialize=identity_matrix, + ) + + # loop over parameter name + for i, c in enumerate(model.regression_parameters): + for j, d in enumerate(model.regression_parameters): + # fix the 0 half of L matrix to be 0.0 + if i < j: + model.L_ele[c, d].fix(0.0) + # Give LB to the diagonal entries + if self.L_LB: + if c == d: + model.L_ele[c, d].setlb(self.L_LB) + + # jacobian rule + def jacobian_rule(m, p, n): + """ + m: Pyomo model + p: parameter + n: response + """ + cuid = pyo.ComponentUID(n) + var_up = cuid.find_component_on(m.block[self.scenario_num[p][0]]) + var_lo = cuid.find_component_on(m.block[self.scenario_num[p][1]]) + if self.scale_nominal_param_value: + return ( + m.sensitivity_jacobian[p, n] + == (var_up - var_lo) + / self.eps_abs[p] + * self.param[p] + * self.scale_constant_value + ) + else: + return ( + m.sensitivity_jacobian[p, n] + == (var_up - var_lo) / self.eps_abs[p] * self.scale_constant_value + ) + + # A constraint to calculate elements in Hessian matrix + # transfer prior FIM to be Expressions + fim_initial_dict = { + (bu, un): self.prior_FIM[i][j] + for i, bu in enumerate(model.regression_parameters) + for j, un in enumerate(model.regression_parameters) + } + + def read_prior(m, i, j): + return fim_initial_dict[(i, j)] + + model.priorFIM = pyo.Expression( + model.regression_parameters, model.regression_parameters, rule=read_prior + ) + + # The off-diagonal elements are symmetric, thus only half of the elements need to be calculated + def fim_rule(m, p, q): + """ + m: Pyomo model + p: parameter + q: parameter + """ + + if p > q: + if self.only_compute_fim_lower: + return pyo.Constraint.Skip + else: + return m.fim[p, q] == m.fim[q, p] + else: + return ( + m.fim[p, q] + == sum( + 1 + / self.measurement_vars.variance[n] + * m.sensitivity_jacobian[p, n] + * m.sensitivity_jacobian[q, n] + for n in model.measured_variables + ) + + m.priorFIM[p, q] * self.fim_scale_constant_value + ) + + model.jacobian_constraint = pyo.Constraint( + model.regression_parameters, model.measured_variables, rule=jacobian_rule + ) + model.fim_constraint = pyo.Constraint( + model.regression_parameters, model.regression_parameters, rule=fim_rule + ) + + if self.only_compute_fim_lower: + # Fix the upper half of the FIM matrix elements to be 0.0. + # This eliminates extra variables and ensures the expected number of + # degrees of freedom in the optimization problem. + for p in model.regression_parameters: + for q in model.regression_parameters: + if p > q: + model.fim[p, q].fix(0.0) + + return model + + # Create scenario block structure + def _generate_scenario_blocks(self, mod=None): + """ + Generates the modeling blocks corresponding to the scenarios for + the finite differencing scheme to compute the sensitivity jacobian + to compute the FIM. + + The function alters the ``mod`` input. + + In the single experiment case, ``mod`` will be self.model. In the + multi-experiment case, ``mod`` will be one experiment to be enumerated. + + Parameters + ---------- + mod: model to add finite difference scenarios + """ + + # Generate initial scenario to populate unknown parameter values + mod.global_model = self.experiment.get_labeled_model(**self.args) + + # create scenario information for block scenarios + scena_gen = ScenarioGenerator( + parameter_dict=mod.global_model.unknown_parameters, formula=self.formula, step=self.step + ) + + # To-Do: Should this be saved? Or no? + # To-Do: If save, allow different scenario_data objects for different models --> scenario_data is a list? + # This is important for differing unknown parameter values --> stochastic + # Important attributes of scena_gen.ScenarioData listed below + # scenario - list of dictionaries of unknown parameter values (with one perturbed) + # scena_num - dictionary where key is the parameter and value is a list of scenarios in which the parameter is involved + # eps_abs - dictionary where key is the parameter and value is the perturbation step + + self.scenario_data = scena_gen.ScenarioData + + # Set for block/scenarios + mod.scenarios = pyo.Set(initialize=scena_gen.ScenarioData.scenario_indices) + + # To-Do: Fix parameter values if they are not Params? + + def build_block_scenarios(b, s): + # create block scenarios + # idea: check if create_model takes theta as an optional input, if so, pass parameter values to create_model + + # Generate model for the finite difference scenario + temp_mod = self.experiment.get_labeled_model(**self.args) + + # Update parameter values for the given scenario + theta_values = scena_gen.ScenarioData.scenario[s] + for k, v in theta_values.items(): + # To-Do: ensure k is a Param? + # If not Param, make sure k is fixed + k.find_component_on(b).set_value(theta_values[k.name]) + + # Return the model with updated unknown parameter values + return temp_mod + + mod.scenario_blocks = pyo.Block(mod.scenarios, rule=build_block_scenarios) + + # To-Do: this might have to change if experiment inputs have + # a different value in the Suffix (currently it is the CUID) + # Add constraints to equate block design with global design + def global_design_fixing(m, k, s): + global_design_var = mod.experiment_inputs[k] + block_design_var = global_design_var.find_component_on(mod.scenario_blocks[s]) + return global_design_var == block_design_var + + # Assuming that the user will specify the design variable bounds... + # Otherwise, we will need to add something similar to what is written here + # for k, v in mod.experiment_inputs[k]: + # v.setlb(self.design_vars.lower_bounds[name]) + # v.setub(self.design_vars.upper_bounds[name]) # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) def compute_FIM_full_factorial(self, ): diff --git a/pyomo/contrib/doe/redesign/experiment_class_example.py b/pyomo/contrib/doe/redesign/experiment_class_example.py new file mode 100644 index 00000000000..2b9ac55ced8 --- /dev/null +++ b/pyomo/contrib/doe/redesign/experiment_class_example.py @@ -0,0 +1,256 @@ +# === Required imports === +import pyomo.environ as pyo +from pyomo.dae import ContinuousSet, DerivativeVar, Simulator + +import itertools +import json +# ======================== + + +def expand_model_components(m, base_components, index_sets): + """ + Takes model components and index sets and returns the + model component labels. + + Arguments + --------- + m: Pyomo model + base_components: list of variables from model 'm' + index_sets: list, same length as base_components, where each + element is a list of index sets, or None + """ + for val, indexes in itertools.zip_longest(base_components, index_sets): + # If the variable has no index, + # add just the model component + if not val.is_indexed(): + yield val + # If the component is indexed but no + # index supplied, add all indices + elif indexes is None: + yield from val.values() + else: + for j in itertools.product(*indexes): + yield val[j] + + +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) + + +class ReactorExperiment(object): + def __init__(self, data, nfe, ncp): + self.data = data + self.nfe = nfe + self.ncp = ncp + self.model = None + + def get_labeled_model(self): + if self.model is None: + self.create_model() + self.finalize_model() + self.label_experiment() + return self.model + + def create_model(self): + """ + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. + + Return + ------ + m: a Pyomo.DAE model + """ + + m = self.model = pyo.ConcreteModel() + + # Model parameters + m.R = pyo.Param(mutable=False, initialize=8.314) + + # Define model variables + ######################## + # time + m.t = ContinuousSet(bounds=[0, 1]) + + # Concentrations + m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Temperature + m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Arrhenius rate law equations + m.A1 = pyo.Var(within=pyo.NonNegativeReals) + m.E1 = pyo.Var(within=pyo.NonNegativeReals) + m.A2 = pyo.Var(within=pyo.NonNegativeReals) + m.E2 = pyo.Var(within=pyo.NonNegativeReals) + + # Differential variables (Conc.) + m.dCAdt = DerivativeVar(m.CA, wrt=m.t) + m.dCBdt = DerivativeVar(m.CB, wrt=m.t) + + ######################## + # End variable def. + + # Equation def'n + ######################## + + # Expression for rate constants + @m.Expression(m.t) + def k1(m, t): + return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) + + @m.Expression(m.t) + def k2(m, t): + return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) + + # Concentration odes + @m.Constraint(m.t) + def CA_rxn_ode(m, t): + return m.dCAdt[t] == -m.k1[t] * m.CA[t] + + @m.Constraint(m.t) + def CB_rxn_ode(m, t): + return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] + + # algebraic balance for concentration of C + # Valid because the reaction system (A --> B --> C) is equimolar + @m.Constraint(m.t) + def CC_balance(m, t): + return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] + + ######################## + # End equation def'n + + def finalize_model(self): + """ + Example finalize model function. There are two main tasks + here: + 1. Extracting useful information for the model to align + with the experiment. (Here: CA0, t_final, t_control) + 2. Discretizing the model subject to this information. + + Arguments + --------- + m: Pyomo model + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ + m = self.model + + # Unpacking data before simulation + control_points = self.data['control_points'] + + m.CA[0].fix(self.data['CA0']) + m.CB[0].fix(self.data['CB0']) + m.CC[0].fix(self.data['CC0']) + m.t.update(self.data['t_range']) + m.t.update(control_points) + m.A1 = self.data['A1'] + m.A2 = self.data['A2'] + m.E1 = self.data['E1'] + m.E2 = self.data['E2'] + + m.t_control = control_points + + # TODO: add simulation for initialization????? + # Call the simulator (optional) + + # Discretizing the model + discr = pyo.TransformationFactory("dae.collocation") + discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) + + # Initializing Temperature in the model + cv = None + for t in m.t: + if t in control_points: + cv = control_points[t] + m.T[t] = cv + + # Unfixing initial temperature + m.T[0.0].unfix() + + @m.Constraint(m.t - control_points) + def T_control(m, t): + """ + Piecewise constant Temperature between control points + """ + neighbour_t = max(tc for tc in control_points if tc < t) + return m.T[t] == m.T[neighbour_t] + + def label_experiment_impl(self, index_sets_meas): + """ + Example for annotating (labeling) the model with a + full experiment. + + Arguments + --------- + + """ + m = self.model + + # Grab measurement labels + base_comp_meas = [m.CA, m.CB, m.CC] + m.experiment_outputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Adding no error for measurements currently + m.measurement_error = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.measurement_error.update((k, 0.0) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Grab design variables + base_comp_des = [m.CA, m.T] + index_sets_des = [[[m.t.first()]], [m.t_control]] + m.experiment_inputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) + + m.unknown_parameters = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) + + +class FullReactorExperiment(ReactorExperiment): + def label_experiment(self): + m = self.model + return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]]) + + +class PartialReactorExperiment(ReactorExperiment): + def label_experiment(self): + """ + Example for annotating (labeling) the model with a + "partial" experiment. + + Arguments + --------- + + """ + m = self.model + return self.label_experiment_impl([[m.t_control], [[m.t.last()]], [[m.t.last()]]]) + + +f = open('result.json') +data_ex = json.load(f) +data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} + +experiments = [ + FullReactorExperiment(data_ex, 32, 3), + PartialReactorExperiment(data_ex, 32, 3), +] + +# in parmest / DoE: +expanded_experiments = [e.get_labeled_model() for e in experiments] \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/result.json b/pyomo/contrib/doe/redesign/result.json new file mode 100644 index 00000000000..f8392e115ed --- /dev/null +++ b/pyomo/contrib/doe/redesign/result.json @@ -0,0 +1 @@ +{"CA0": 1.0, "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 300, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/scenario.py b/pyomo/contrib/doe/scenario.py index b44ce1ab4d3..d3b8bc46f07 100644 --- a/pyomo/contrib/doe/scenario.py +++ b/pyomo/contrib/doe/scenario.py @@ -28,6 +28,7 @@ import pickle from enum import Enum from collections import namedtuple +import copy class FiniteDifferenceStep(Enum): @@ -60,6 +61,7 @@ def __init__(self, parameter_dict=None, formula="central", step=0.001, store=Fal if True, store results. """ # get info from parameter dictionary + self.parameters = parameter_dict self.parameter_dict = parameter_dict self.para_names = list(parameter_dict.keys()) self.no_para = len(self.para_names) @@ -101,54 +103,74 @@ def generate_scenario(self): scenario = [] # number of scenario scena_num = {} - - # loop over parameter name - for p, para in enumerate(self.para_names): - ## get scenario dictionary - if self.formula == FiniteDifferenceStep.central: - scena_num[para] = [2 * p, 2 * p + 1] - scena_dict_up, scena_dict_lo = ( - self.parameter_dict.copy(), - self.parameter_dict.copy(), - ) - # corresponding parameter dictionary for the scenario - scena_dict_up[para] *= 1 + self.step - scena_dict_lo[para] *= 1 - self.step - - scenario.append(scena_dict_up) - scenario.append(scena_dict_lo) - - elif self.formula in [ - FiniteDifferenceStep.forward, - FiniteDifferenceStep.backward, - ]: - # the base case is added as the last one - scena_num[para] = [p, len(self.param_names)] - scena_dict_up, scena_dict_lo = ( - self.parameter_dict.copy(), - self.parameter_dict.copy(), - ) - if self.formula == FiniteDifferenceStep.forward: - scena_dict_up[para] *= 1 + self.step - - elif self.formula == FiniteDifferenceStep.backward: - scena_dict_lo[para] *= 1 - self.step - - scenario.append(scena_dict_up) - scenario.append(scena_dict_lo) - - ## get perturbation sizes - # for central difference scheme, perturbation size is two times the step size + + count_scens = 0 + for k, v in self.parameters.items(): if self.formula == FiniteDifferenceStep.central: - eps_abs[para] = 2 * self.step * self.parameter_dict[para] - else: - eps_abs[para] = self.step * self.parameter_dict[para] - + scena_num[k.name] = [2 * count_scens, 2 * count_scens + 1] + scena_dict_hi = {k.name: v * (1 + self.step)} + scena_dict_lo = {k.name: v * (1 + self.step)} + + eps_abs[k.name] = 2 * self.step * v + + scenario.append(scena_dict_hi) + scenario.append(scena_dict_lo) + self.ScenarioData = ScenarioData( scenario, scena_num, eps_abs, list(range(len(scenario))) ) + + ############################## + # Below is deprecated code # + ############################## - # store scenario - if self.store: - with open("scenario_simultaneous.pickle", "wb") as f: - pickle.dump(self.scenario_data, f) + # loop over parameter name + # for p, para in enumerate(self.para_names): + # ## get scenario dictionary + # if self.formula == FiniteDifferenceStep.central: + # scena_num[para.name] = [2 * p, 2 * p + 1] + # scena_dict_up, scena_dict_lo = ( + # copy.deepcopy(self.parameter_dict), + # copy.deepcopy(self.parameter_dict), + # ) + # # corresponding parameter dictionary for the scenario + # scena_dict_up[para.name] *= 1 + self.step + # scena_dict_lo[para.name] *= 1 - self.step + + # scenario.append(scena_dict_up) + # scenario.append(scena_dict_lo) + + # elif self.formula in [ + # FiniteDifferenceStep.forward, + # FiniteDifferenceStep.backward, + # ]: + # # the base case is added as the last one + # scena_num[para] = [p, len(self.param_names)] + # scena_dict_up, scena_dict_lo = ( + # self.parameter_dict.copy(), + # self.parameter_dict.copy(), + # ) + # if self.formula == FiniteDifferenceStep.forward: + # scena_dict_up[para] *= 1 + self.step + + # elif self.formula == FiniteDifferenceStep.backward: + # scena_dict_lo[para] *= 1 - self.step + + # scenario.append(scena_dict_up) + # scenario.append(scena_dict_lo) + + # ## get perturbation sizes + # # for central difference scheme, perturbation size is two times the step size + # if self.formula == FiniteDifferenceStep.central: + # eps_abs[para] = 2 * self.step * self.parameter_dict[para] + # else: + # eps_abs[para] = self.step * self.parameter_dict[para] + + # self.ScenarioData = ScenarioData( + # scenario, scena_num, eps_abs, list(range(len(scenario))) + # ) + + # # store scenario + # if self.store: + # with open("scenario_simultaneous.pickle", "wb") as f: + # pickle.dump(self.scenario_data, f) From 6631c48b510506d23847d82a7a9343e581558134 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 20 Jun 2024 18:49:02 -0400 Subject: [PATCH 003/203] Further progress on generating FD scenarios Worked around Block construction. Pass-by-reference issues with with Experiment object requires some sort of cloning of the model for each block. Still working through global connecting constraints for design variables. --- pyomo/contrib/doe/doe.py | 114 +++++++++++++++++++++++++++------------ 1 file changed, 80 insertions(+), 34 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 1480b293b1b..c4a727127c7 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -61,6 +61,13 @@ class ModelOptionLib(Enum): stage1 = "stage1" stage2 = "stage2" + +class FiniteDifferenceStep(Enum): + forward = "forward" + central = "central" + backward = "backward" + + class DesignOfExperiments_: def __init__( self, @@ -515,54 +522,87 @@ def _generate_scenario_blocks(self, mod=None): """ # Generate initial scenario to populate unknown parameter values - mod.global_model = self.experiment.get_labeled_model(**self.args) - - # create scenario information for block scenarios - scena_gen = ScenarioGenerator( - parameter_dict=mod.global_model.unknown_parameters, formula=self.formula, step=self.step + mod = self.experiment.get_labeled_model(**self.args) + + # Make a new Suffix to hold which scenarios are associated with parameters + mod.parameter_scenarios = pyo.Suffix( + direction=pyo.Suffix.LOCAL, ) - # To-Do: Should this be saved? Or no? - # To-Do: If save, allow different scenario_data objects for different models --> scenario_data is a list? - # This is important for differing unknown parameter values --> stochastic - # Important attributes of scena_gen.ScenarioData listed below - # scenario - list of dictionaries of unknown parameter values (with one perturbed) - # scena_num - dictionary where key is the parameter and value is a list of scenarios in which the parameter is involved - # eps_abs - dictionary where key is the parameter and value is the perturbation step + # Central finite difference definition + self.fd_formula = FiniteDifferenceStep(self.fd_formula) - self.scenario_data = scena_gen.ScenarioData - - # Set for block/scenarios - mod.scenarios = pyo.Set(initialize=scena_gen.ScenarioData.scenario_indices) + if self.fd_formula == FiniteDifferenceStep.central: + # mod.parameter_scenarios.update((k, (2*ind, 2*ind + 1)) for k, ind in enumerate(mod.unknown_parameters.keys())) + mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.unknown_parameters.keys())) + mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) + mod.scenarios = range(len(mod.unknown_parameters) * 2) + elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: + # mod.parameter_scenarios.update((k, (0, ind + 1)) for k, ind in enumerate(mod.unknown_parameters.keys())) + mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) + mod.scenarios = range(len(mod.unknown_parameters) + 1) + else: + # To-Do: add an error message for this as not being implemented yet + pass # To-Do: Fix parameter values if they are not Params? + # Is there a way to make this general for both? Probably not. + # Finite difference scheme-specific function definition + # This doesn't work but I think it should. def build_block_scenarios(b, s): - # create block scenarios - # idea: check if create_model takes theta as an optional input, if so, pass parameter values to create_model - # Generate model for the finite difference scenario - temp_mod = self.experiment.get_labeled_model(**self.args) + b.transfer_attributes_from(self.experiment.get_labeled_model(**self.args).clone()) + param = mod.parameter_scenarios[s] - # Update parameter values for the given scenario - theta_values = scena_gen.ScenarioData.scenario[s] - for k, v in theta_values.items(): - # To-Do: ensure k is a Param? - # If not Param, make sure k is fixed - k.find_component_on(b).set_value(theta_values[k.name]) + # Perturbation to be (1 + diff) * param_value + if self.fd_formula == FiniteDifferenceStep.central: + diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd + elif self.fd_formula == FiniteDifferenceStep.forward: + diff = self.step * -1 # Backward always negative perturbation + elif self.fd_formula == FiniteDifferenceStep.backward: + diff = self.step # Forward always positive + else: + diff = 0 + pass - # Return the model with updated unknown parameter values - return temp_mod - + # Update parameter values for the given scenario + pyo.ComponentUID(param).find_component_on(b).set_value(mod.unknown_parameters[param] * (1 + diff)) mod.scenario_blocks = pyo.Block(mod.scenarios, rule=build_block_scenarios) - + + mod.scenario_blocks[0].pprint() + + # for s in mod.scenarios: + # block_name = 'scenario_' + str(s) + # temp_model = self.experiment.get_labeled_model(**self.args) + # setattr(mod, block_name, temp_model) + # param = mod.parameter_scenarios[s] + + # # Perturbation to be (1 + diff) * param_value + # if self.fd_formula == FiniteDifferenceStep.central: + # diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd + # elif self.fd_formula == FiniteDifferenceStep.forward: + # diff = self.step * -1 # Backward always negative perturbation + # elif self.fd_formula == FiniteDifferenceStep.backward: + # diff = self.step # Forward always positive + # else: + # diff = 0 + # pass + + # # Update parameter values for the given scenario + # pyo.ComponentUID(param).find_component_on(getattr(mod, block_name)).set_value(mod.unknown_parameters[param] * (1 + diff)) + # To-Do: this might have to change if experiment inputs have # a different value in the Suffix (currently it is the CUID) # Add constraints to equate block design with global design - def global_design_fixing(m, k, s): - global_design_var = mod.experiment_inputs[k] - block_design_var = global_design_var.find_component_on(mod.scenario_blocks[s]) - return global_design_var == block_design_var + design_vars = [k for k, v in mod.experiment_inputs.items()] + for ind, d in enumerate(design_vars): + con_name = 'global_design_eq_con_' + str(ind) + def global_design_fixing(m, s): + global_design_var = mod.experiment_inputs[d] + block_design_var = pyo.ComponentUID(global_design_var).find_component_on(mod.scenario_blocks[s]) + return global_design_var == block_design_var + setattr(mod, con_name, pyo.Constraint(mod.scenarios, rule=global_design_fixing)) # Assuming that the user will specify the design variable bounds... # Otherwise, we will need to add something similar to what is written here @@ -570,6 +610,12 @@ def global_design_fixing(m, k, s): # v.setlb(self.design_vars.lower_bounds[name]) # v.setub(self.design_vars.upper_bounds[name]) + def _scenario_generator(self, ): + """ + Helper function to generate + """ + + # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) def compute_FIM_full_factorial(self, ): return From 9535062360f390f7b74a05fba657836a7e77dbdf Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 20 Jun 2024 19:12:24 -0400 Subject: [PATCH 004/203] Scenario generator appears to work Finished some more edits. Will check back in tomorrow to clean and make sure the scenario generator is working properly. Need to work on whether the full model should be present or not for the central case. Could use the "global model" to be "case 0" and reassign the values to be one of the cases. --- pyomo/contrib/doe/doe.py | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index c4a727127c7..6749faac253 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -522,7 +522,9 @@ def _generate_scenario_blocks(self, mod=None): """ # Generate initial scenario to populate unknown parameter values - mod = self.experiment.get_labeled_model(**self.args) + self.model = self.experiment.get_labeled_model(**self.args).clone() + + mod = self.model # Make a new Suffix to hold which scenarios are associated with parameters mod.parameter_scenarios = pyo.Suffix( @@ -552,9 +554,13 @@ def _generate_scenario_blocks(self, mod=None): # This doesn't work but I think it should. def build_block_scenarios(b, s): # Generate model for the finite difference scenario - b.transfer_attributes_from(self.experiment.get_labeled_model(**self.args).clone()) + b.transfer_attributes_from(self.experiment.get_labeled_model().clone()) param = mod.parameter_scenarios[s] + param.pprint() + print(pyo.ComponentUID(param)) + print(pyo.ComponentUID(param).find_component_on(b)) + # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd @@ -570,28 +576,6 @@ def build_block_scenarios(b, s): pyo.ComponentUID(param).find_component_on(b).set_value(mod.unknown_parameters[param] * (1 + diff)) mod.scenario_blocks = pyo.Block(mod.scenarios, rule=build_block_scenarios) - mod.scenario_blocks[0].pprint() - - # for s in mod.scenarios: - # block_name = 'scenario_' + str(s) - # temp_model = self.experiment.get_labeled_model(**self.args) - # setattr(mod, block_name, temp_model) - # param = mod.parameter_scenarios[s] - - # # Perturbation to be (1 + diff) * param_value - # if self.fd_formula == FiniteDifferenceStep.central: - # diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd - # elif self.fd_formula == FiniteDifferenceStep.forward: - # diff = self.step * -1 # Backward always negative perturbation - # elif self.fd_formula == FiniteDifferenceStep.backward: - # diff = self.step # Forward always positive - # else: - # diff = 0 - # pass - - # # Update parameter values for the given scenario - # pyo.ComponentUID(param).find_component_on(getattr(mod, block_name)).set_value(mod.unknown_parameters[param] * (1 + diff)) - # To-Do: this might have to change if experiment inputs have # a different value in the Suffix (currently it is the CUID) # Add constraints to equate block design with global design @@ -600,8 +584,8 @@ def build_block_scenarios(b, s): con_name = 'global_design_eq_con_' + str(ind) def global_design_fixing(m, s): global_design_var = mod.experiment_inputs[d] - block_design_var = pyo.ComponentUID(global_design_var).find_component_on(mod.scenario_blocks[s]) - return global_design_var == block_design_var + block_design_var = global_design_var.find_component_on(mod.scenario_blocks[s]) + return d == block_design_var setattr(mod, con_name, pyo.Constraint(mod.scenarios, rule=global_design_fixing)) # Assuming that the user will specify the design variable bounds... From ea1b2d6c5614673b70a04d39a48585bea8b4f84b Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 25 Jun 2024 11:21:13 -0400 Subject: [PATCH 005/203] Added a check_model_labels function Add functionality to test if the labeled model has the expected labels for the DoE model to be created. --- pyomo/contrib/doe/doe.py | 75 +++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 6749faac253..3a45e382ca5 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -76,7 +76,7 @@ def __init__( prior_FIM=None, args=None, only_compute_fim_lower=True, - logger_level=logging.INFO, + logger_level=logging.WARNING, ): """ This package enables model-based design of experiments analysis with Pyomo. @@ -108,21 +108,6 @@ def __init__( assert callable(getattr(experiment, 'get_labeled_model')), 'The experiment object must have a ``get_labeled_model`` function' self.experiment = experiment - - # Parameters, Design Variables, and Outputs are now directly connected - # to each model instance (meaning we no longer need to specify them - # in the constructor - - # Potentially keep something like this for deprecated version? Maybe not - # model_option_arg = ( - # "model_option" in inspect.getfullargspec(self.create_model).args - # ) - # mod_arg = "mod" in inspect.getfullargspec(self.create_model).args - # if model_option_arg and mod_arg: - # self._original_create_model_interface = True - # else: - # self._original_create_model_interface = False - # check if user-defined solver is given if solver: @@ -155,8 +140,10 @@ def __init__( self.only_compute_fim_lower = only_compute_fim_lower # model attribute to avoid rebuilding models - self.model = None - self._built_scenarios = False + self.model = pyo.ConcreteModel() # Build empty model + # May need this attribute for more complicated structures? + # (i.e., no model rebuilding for large models with sequential) + # self._built_scenarios = False # Perform doe def run_doe( @@ -223,7 +210,7 @@ def run_doe( outputs = [k.name for k, v in model.experiment_outputs.items()] except: RuntimeError( - 'Experiment list model does not have suffix ' + '"experiment_outputs".' + 'Experiment model does not have suffix ' + '"experiment_outputs".' ) # Check that experimental inputs exist @@ -524,6 +511,9 @@ def _generate_scenario_blocks(self, mod=None): # Generate initial scenario to populate unknown parameter values self.model = self.experiment.get_labeled_model(**self.args).clone() + # Check the model that labels are correct + + mod = self.model # Make a new Suffix to hold which scenarios are associated with parameters @@ -535,12 +525,10 @@ def _generate_scenario_blocks(self, mod=None): self.fd_formula = FiniteDifferenceStep(self.fd_formula) if self.fd_formula == FiniteDifferenceStep.central: - # mod.parameter_scenarios.update((k, (2*ind, 2*ind + 1)) for k, ind in enumerate(mod.unknown_parameters.keys())) mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.unknown_parameters.keys())) mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) mod.scenarios = range(len(mod.unknown_parameters) * 2) elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: - # mod.parameter_scenarios.update((k, (0, ind + 1)) for k, ind in enumerate(mod.unknown_parameters.keys())) mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) mod.scenarios = range(len(mod.unknown_parameters) + 1) else: @@ -564,9 +552,9 @@ def build_block_scenarios(b, s): # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd - elif self.fd_formula == FiniteDifferenceStep.forward: - diff = self.step * -1 # Backward always negative perturbation elif self.fd_formula == FiniteDifferenceStep.backward: + diff = self.step * -1 # Backward always negative perturbation + elif self.fd_formula == FiniteDifferenceStep.forward: diff = self.step # Forward always positive else: diff = 0 @@ -587,12 +575,43 @@ def global_design_fixing(m, s): block_design_var = global_design_var.find_component_on(mod.scenario_blocks[s]) return d == block_design_var setattr(mod, con_name, pyo.Constraint(mod.scenarios, rule=global_design_fixing)) + + + # Check to see if the model has all the required suffixes + def check_model_labels(self, mod=None): + # Check that experimental outputs exist + try: + outputs = [k.name for k, v in mod.experiment_outputs.items()] + except: + RuntimeError( + 'Experiment model does not have suffix ' + '"experiment_outputs".' + ) + + # Check that experimental inputs exist + try: + outputs = [k.name for k, v in mod.experiment_inputs.items()] + except: + RuntimeError( + 'Experiment model does not have suffix ' + '"experiment_inputs".' + ) + + # Check that unknown parameters exist + try: + outputs = [k.name for k, v in mod.unknown_parameters.items()] + except: + RuntimeError( + 'Experiment model does not have suffix ' + '"unknown_parameters".' + ) + + # Check that measurement errors exist + try: + outputs = [k.name for k, v in mod.measurement_error.items()] + except: + RuntimeError( + 'Experiment model does not have suffix ' + '"measurement_error".' + ) - # Assuming that the user will specify the design variable bounds... - # Otherwise, we will need to add something similar to what is written here - # for k, v in mod.experiment_inputs[k]: - # v.setlb(self.design_vars.lower_bounds[name]) - # v.setub(self.design_vars.upper_bounds[name]) + logger.info('Model has expected labels.') def _scenario_generator(self, ): """ From caa194945bb15f00d36f989664fe38c65dec9678 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 25 Jun 2024 13:33:03 -0400 Subject: [PATCH 006/203] Cleaned and standardized scenario generation --- pyomo/contrib/doe/doe.py | 63 ++++++++++++++++-------- pyomo/contrib/doe/redesign/test_build.py | 8 +++ 2 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 pyomo/contrib/doe/redesign/test_build.py diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 3a45e382ca5..20cf0080b08 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -300,10 +300,10 @@ def create_doe_model(self, mod=None): raise ValueError( "Cannot compute determinant with explicit formula if only_compute_fim_lower is True." ) - - self._generate_scenario_blocks(mod=mod) - + # Generate scenarios for finite difference formulae + self._generate_scenario_blocks() + # variables for jacobian and FIM model.regression_parameters = pyo.Set(initialize=list(self.param.keys())) model.measured_variables = pyo.Set(initialize=self.measure_name) @@ -509,11 +509,12 @@ def _generate_scenario_blocks(self, mod=None): """ # Generate initial scenario to populate unknown parameter values - self.model = self.experiment.get_labeled_model(**self.args).clone() + self.model.base_model = self.experiment.get_labeled_model(**self.args).clone() # Check the model that labels are correct + self.check_model_labels() - + # Set shorthand for self.model mod = self.model # Make a new Suffix to hold which scenarios are associated with parameters @@ -525,12 +526,12 @@ def _generate_scenario_blocks(self, mod=None): self.fd_formula = FiniteDifferenceStep(self.fd_formula) if self.fd_formula == FiniteDifferenceStep.central: - mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.unknown_parameters.keys())) - mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) - mod.scenarios = range(len(mod.unknown_parameters) * 2) + mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) + mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) + mod.scenarios = range(len(mod.base_model.unknown_parameters) * 2) elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: - mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) - mod.scenarios = range(len(mod.unknown_parameters) + 1) + mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) + mod.scenarios = range(len(mod.base_model.unknown_parameters) + 1) else: # To-Do: add an error message for this as not being implemented yet pass @@ -545,40 +546,60 @@ def build_block_scenarios(b, s): b.transfer_attributes_from(self.experiment.get_labeled_model().clone()) param = mod.parameter_scenarios[s] - param.pprint() - print(pyo.ComponentUID(param)) - print(pyo.ComponentUID(param).find_component_on(b)) + # Grabbing the location of the parameter without the "base_model" precursor + param_loc = ".".join(param.name.split('.')[1:]) # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd + # Perturbation at scenario 0 for forward/backward is nothing (stationary case) elif self.fd_formula == FiniteDifferenceStep.backward: - diff = self.step * -1 # Backward always negative perturbation + diff = self.step * -1 * (0 != s) # Backward always negative perturbation elif self.fd_formula == FiniteDifferenceStep.forward: - diff = self.step # Forward always positive + diff = self.step * (0 != s) # Forward always positive else: diff = 0 pass # Update parameter values for the given scenario - pyo.ComponentUID(param).find_component_on(b).set_value(mod.unknown_parameters[param] * (1 + diff)) + pyo.ComponentUID(param_loc).find_component_on(b).set_value(mod.base_model.unknown_parameters[param] * (1 + diff)) mod.scenario_blocks = pyo.Block(mod.scenarios, rule=build_block_scenarios) # To-Do: this might have to change if experiment inputs have # a different value in the Suffix (currently it is the CUID) - # Add constraints to equate block design with global design - design_vars = [k for k, v in mod.experiment_inputs.items()] + # Add constraints to equate block design with global design: + design_vars = [k for k, v in mod.scenario_blocks[0].experiment_inputs.items()] + for ind, d in enumerate(design_vars): con_name = 'global_design_eq_con_' + str(ind) + + # Constraint rule for global design constraints def global_design_fixing(m, s): - global_design_var = mod.experiment_inputs[d] - block_design_var = global_design_var.find_component_on(mod.scenario_blocks[s]) + if s == 0: + return pyo.Constraint.Skip + ref_design_var = mod.scenario_blocks[0].experiment_inputs[d] + ref_design_var_loc = ".".join(ref_design_var.get_repr().split('.')[0:]) + block_design_var = pyo.ComponentUID(ref_design_var_loc).find_component_on(mod.scenario_blocks[s]) return d == block_design_var setattr(mod, con_name, pyo.Constraint(mod.scenarios, rule=global_design_fixing)) + + # Clean up the base model used to generate the scenarios + self.model.del_component(self.model.base_model) # Check to see if the model has all the required suffixes def check_model_labels(self, mod=None): + """ + Checks if the model contains the necessary suffixes for the + DoE model to be constructed automatically. + + Parameters + ---------- + mod: model for suffix checking, Default: None, (self.model) + """ + if mod is None: + mod = self.model.base_model + # Check that experimental outputs exist try: outputs = [k.name for k, v in mod.experiment_outputs.items()] @@ -611,7 +632,7 @@ def check_model_labels(self, mod=None): 'Experiment model does not have suffix ' + '"measurement_error".' ) - logger.info('Model has expected labels.') + self.logger.info('Model has expected labels.') def _scenario_generator(self, ): """ diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py new file mode 100644 index 00000000000..2c95529b5ca --- /dev/null +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -0,0 +1,8 @@ +from experiment_class_example import * +from pyomo.contrib.doe import * + +experiment = FullReactorExperiment(data_ex, 32, 3) +doe_obj = DesignOfExperiments_(experiment) +doe_obj.fd_formula = 'central' +doe_obj.step = 0.001 +doe_obj._generate_scenario_blocks() \ No newline at end of file From 37e554bfd844b115d312f94c8f2d8c41c71888e4 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 25 Jun 2024 13:45:34 -0400 Subject: [PATCH 007/203] Fixed forward and backward case for scenario generation --- pyomo/contrib/doe/doe.py | 13 +++++++++---- pyomo/contrib/doe/redesign/test_build.py | 14 +++++++++----- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 20cf0080b08..e0cdb9ab165 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -522,7 +522,7 @@ def _generate_scenario_blocks(self, mod=None): direction=pyo.Suffix.LOCAL, ) - # Central finite difference definition + # TODO: move to somewhere else (constructor?) self.fd_formula = FiniteDifferenceStep(self.fd_formula) if self.fd_formula == FiniteDifferenceStep.central: @@ -544,6 +544,12 @@ def _generate_scenario_blocks(self, mod=None): def build_block_scenarios(b, s): # Generate model for the finite difference scenario b.transfer_attributes_from(self.experiment.get_labeled_model().clone()) + + # Forward/Backward difference have a stationary case (s == 0), no parameter to perturb + if self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: + if s == 0: + return + param = mod.parameter_scenarios[s] # Grabbing the location of the parameter without the "base_model" precursor @@ -552,11 +558,10 @@ def build_block_scenarios(b, s): # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd - # Perturbation at scenario 0 for forward/backward is nothing (stationary case) elif self.fd_formula == FiniteDifferenceStep.backward: - diff = self.step * -1 * (0 != s) # Backward always negative perturbation + diff = self.step * -1 # Backward always negative perturbation elif self.fd_formula == FiniteDifferenceStep.forward: - diff = self.step * (0 != s) # Forward always positive + diff = self.step # Forward always positive else: diff = 0 pass diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 2c95529b5ca..fd4de9103d1 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -1,8 +1,12 @@ from experiment_class_example import * from pyomo.contrib.doe import * -experiment = FullReactorExperiment(data_ex, 32, 3) -doe_obj = DesignOfExperiments_(experiment) -doe_obj.fd_formula = 'central' -doe_obj.step = 0.001 -doe_obj._generate_scenario_blocks() \ No newline at end of file + +doe_obj = [0, 0, 0,] + +for ind, fd in enumerate(['central', 'backward', 'forward']): + experiment = FullReactorExperiment(data_ex, 32, 3) + doe_obj[ind] = DesignOfExperiments_(experiment) + doe_obj[ind].fd_formula = fd + doe_obj[ind].step = 0.001 + doe_obj[ind]._generate_scenario_blocks() \ No newline at end of file From 125ce8567db4fd32bbed5e88db8df5a2e7dc0cef Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 25 Jun 2024 14:05:08 -0400 Subject: [PATCH 008/203] More cleanup Added FiniteDifferenceStep initialization to the constructor. Removed and cleaned some defunct commenting/documentation. --- pyomo/contrib/doe/doe.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index e0cdb9ab165..1cd5022c70d 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -72,6 +72,7 @@ class DesignOfExperiments_: def __init__( self, experiment, + fd_formula='central', solver=None, prior_FIM=None, args=None, @@ -91,6 +92,9 @@ def __init__( Experiment object that holds the model and labels all the components. The object should have a ``get_labeled_model`` where a model is returned with the following labeled sets: ``unknown_parameters``, ``experimental_inputs``, ``experimental_outputs`` + fd_formula: + Finite difference formula for computing the sensitivy matrix. Must be one of + [``central``, ``forward``, ``backward``] solver: A ``solver`` object specified by the user, default=None. If not specified, default solver is IPOPT MA57. @@ -108,6 +112,7 @@ def __init__( assert callable(getattr(experiment, 'get_labeled_model')), 'The experiment object must have a ``get_labeled_model`` function' self.experiment = experiment + self.formula = FiniteDifferenceStep(fd_formula) # check if user-defined solver is given if solver: @@ -522,9 +527,6 @@ def _generate_scenario_blocks(self, mod=None): direction=pyo.Suffix.LOCAL, ) - # TODO: move to somewhere else (constructor?) - self.fd_formula = FiniteDifferenceStep(self.fd_formula) - if self.fd_formula == FiniteDifferenceStep.central: mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) @@ -538,9 +540,7 @@ def _generate_scenario_blocks(self, mod=None): # To-Do: Fix parameter values if they are not Params? - # Is there a way to make this general for both? Probably not. - # Finite difference scheme-specific function definition - # This doesn't work but I think it should. + # Generate blocks for finite difference scenarios def build_block_scenarios(b, s): # Generate model for the finite difference scenario b.transfer_attributes_from(self.experiment.get_labeled_model().clone()) @@ -566,15 +566,15 @@ def build_block_scenarios(b, s): diff = 0 pass - # Update parameter values for the given scenario + # Update parameter values for the given finite difference scenario pyo.ComponentUID(param_loc).find_component_on(b).set_value(mod.base_model.unknown_parameters[param] * (1 + diff)) mod.scenario_blocks = pyo.Block(mod.scenarios, rule=build_block_scenarios) # To-Do: this might have to change if experiment inputs have # a different value in the Suffix (currently it is the CUID) - # Add constraints to equate block design with global design: design_vars = [k for k, v in mod.scenario_blocks[0].experiment_inputs.items()] + # Add constraints to equate block design with global design: for ind, d in enumerate(design_vars): con_name = 'global_design_eq_con_' + str(ind) From 5ba95769e5632f11b26a1f45cafbf66186addaea Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 25 Jun 2024 14:15:31 -0400 Subject: [PATCH 009/203] Removed unnecessary function --- pyomo/contrib/doe/doe.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 1cd5022c70d..2368c938566 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -527,6 +527,7 @@ def _generate_scenario_blocks(self, mod=None): direction=pyo.Suffix.LOCAL, ) + # Populate parameter scenarios, and scenario inds based on finite difference scheme if self.fd_formula == FiniteDifferenceStep.central: mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) @@ -563,6 +564,7 @@ def build_block_scenarios(b, s): elif self.fd_formula == FiniteDifferenceStep.forward: diff = self.step # Forward always positive else: + # To-Do: add an error message for this as not being implemented yet diff = 0 pass @@ -638,11 +640,6 @@ def check_model_labels(self, mod=None): ) self.logger.info('Model has expected labels.') - - def _scenario_generator(self, ): - """ - Helper function to generate - """ # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) From e5d62f3988019a371d550c879f39e92eb7cca7cb Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 25 Jun 2024 16:24:07 -0400 Subject: [PATCH 010/203] Updating create model Significant development in create_doe_model. Modernized to new methodology. Tests to follow. --- pyomo/contrib/doe/doe.py | 125 +++++++++++------- .../doe/redesign/experiment_class_example.py | 2 +- pyomo/contrib/doe/redesign/test_build.py | 16 ++- 3 files changed, 88 insertions(+), 55 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 2368c938566..78372dad825 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -76,7 +76,7 @@ def __init__( solver=None, prior_FIM=None, args=None, - only_compute_fim_lower=True, + only_compute_fim_lower=False, logger_level=logging.WARNING, ): """ @@ -112,7 +112,7 @@ def __init__( assert callable(getattr(experiment, 'get_labeled_model')), 'The experiment object must have a ``get_labeled_model`` function' self.experiment = experiment - self.formula = FiniteDifferenceStep(fd_formula) + self.fd_formula = FiniteDifferenceStep(fd_formula) # check if user-defined solver is given if solver: @@ -294,7 +294,6 @@ def create_doe_model(self, mod=None): ------- model: the DOE model """ - # Developer recommendation: use the Cholesky decomposition for D-optimality # The explicit formula is available for benchmarking purposes and is NOT recommended if ( @@ -309,9 +308,11 @@ def create_doe_model(self, mod=None): # Generate scenarios for finite difference formulae self._generate_scenario_blocks() - # variables for jacobian and FIM - model.regression_parameters = pyo.Set(initialize=list(self.param.keys())) - model.measured_variables = pyo.Set(initialize=self.measure_name) + mod = self.model + + # Set names to index sensitivity matrix (jacobian) and FIM + mod.parameter_names = pyo.Set(initialize=[".".join(k.name.split('.')[1:]) for k in mod.scenario_blocks[0].unknown_parameters.keys()]) + mod.output_names = pyo.Set(initialize=[".".join(k.name.split('.')[1:]) for k in mod.scenario_blocks[0].experiment_outputs.keys()]) def identity_matrix(m, i, j): if i == j: @@ -324,8 +325,8 @@ def identity_matrix(m, i, j): # If the user provides an initial Jacobian, convert it to a dictionary if self.jac_initial is not None: dict_jac_initialize = {} - for i, bu in enumerate(model.regression_parameters): - for j, un in enumerate(model.measured_variables): + for i, bu in enumerate(mod.parameter_names): + for j, un in enumerate(mod.output_names): if isinstance(self.jac_initial, dict): # Jacobian is a dictionary of arrays or lists where the key is the regression parameter name dict_jac_initialize[(bu, un)] = self.jac_initial[bu][j] @@ -342,35 +343,38 @@ def initialize_jac(m, i, j): else: return 0.1 - model.sensitivity_jacobian = pyo.Var( - model.regression_parameters, - model.measured_variables, + mod.sensitivity_jacobian = pyo.Var( + mod.parameter_names, + mod.output_names, initialize=initialize_jac, ) + # Initialize the FIM + # ToDo: add dictionary dependence for FIM? OR remove Jacobian dictionary input option. if self.fim_initial is not None: dict_fim_initialize = { (bu, un): self.fim_initial[i][j] - for i, bu in enumerate(model.regression_parameters) - for j, un in enumerate(model.regression_parameters) + for i, bu in enumerate(mod.parameter_names) + for j, un in enumerate(mod.parameter_names) } def initialize_fim(m, j, d): return dict_fim_initialize[(j, d)] if self.fim_initial is not None: - model.fim = pyo.Var( - model.regression_parameters, - model.regression_parameters, + mod.fim = pyo.Var( + mod.parameter_names, + mod.parameter_names, initialize=initialize_fim, ) else: - model.fim = pyo.Var( - model.regression_parameters, - model.regression_parameters, + mod.fim = pyo.Var( + mod.parameter_names, + mod.parameter_names, initialize=identity_matrix, ) + # To-Do: Look into this functionality..... # if cholesky, define L elements as variables if self.Cholesky_option and self.objective_option == ObjectiveLib.det: @@ -378,8 +382,8 @@ def initialize_fim(m, j, d): if self.L_initial is not None: dict_cho = { (bu, un): self.L_initial[i][j] - for i, bu in enumerate(model.regression_parameters) - for j, un in enumerate(model.regression_parameters) + for i, bu in enumerate(mod.parameter_names) + for j, un in enumerate(mod.parameter_names) } # use the L dictionary to initialize L matrix @@ -389,29 +393,29 @@ def init_cho(m, i, j): # Define elements of Cholesky decomposition matrix as Pyomo variables and either # Initialize with L in L_initial if self.L_initial is not None: - model.L_ele = pyo.Var( - model.regression_parameters, - model.regression_parameters, + mod.L_ele = pyo.Var( + mod.parameter_names, + mod.parameter_names, initialize=init_cho, ) # or initialize with the identity matrix else: - model.L_ele = pyo.Var( - model.regression_parameters, - model.regression_parameters, + mod.L_ele = pyo.Var( + mod.parameter_names, + mod.parameter_names, initialize=identity_matrix, ) # loop over parameter name - for i, c in enumerate(model.regression_parameters): - for j, d in enumerate(model.regression_parameters): + for i, c in enumerate(mod.parameter_names): + for j, d in enumerate(mod.parameter_names): # fix the 0 half of L matrix to be 0.0 if i < j: - model.L_ele[c, d].fix(0.0) + mod.L_ele[c, d].fix(0.0) # Give LB to the diagonal entries if self.L_LB: if c == d: - model.L_ele[c, d].setlb(self.L_LB) + mod.L_ele[c, d].setlb(self.L_LB) # jacobian rule def jacobian_rule(m, p, n): @@ -420,36 +424,57 @@ def jacobian_rule(m, p, n): p: parameter n: response """ + fd_step_mult = 1 cuid = pyo.ComponentUID(n) - var_up = cuid.find_component_on(m.block[self.scenario_num[p][0]]) - var_lo = cuid.find_component_on(m.block[self.scenario_num[p][1]]) + param_ind = self.model.parameter_names.data().index(p) + + # Different FD schemes lead to different scenarios for the computation + if self.fd_formula == FiniteDifferenceStep.central: + s1 = param_ind * 2 + s2 = param_ind * 2 + 1 + fd_step_mult = 2 + elif self.fd_formula == FiniteDifferenceStep.forward: + s1 = param_ind + 1 + s2 = 0 + elif self.fd_formula == FiniteDifferenceStep.backward: + s1 = 0 + s2 = param_ind + 1 + + var_up = cuid.find_component_on(m.scenario_blocks[s1]) + var_lo = cuid.find_component_on(m.scenario_blocks[s2]) + + param = mod.parameter_scenarios[max(s1, s2)] + param_loc = pyo.ComponentUID(param).find_component_on(mod.scenario_blocks[0]) + param_val = mod.scenario_blocks[0].unknown_parameters[param_loc] + param_diff = param_val * fd_step_mult * self.step + if self.scale_nominal_param_value: return ( m.sensitivity_jacobian[p, n] == (var_up - var_lo) - / self.eps_abs[p] - * self.param[p] + / param_diff + * param_val * self.scale_constant_value ) else: return ( m.sensitivity_jacobian[p, n] - == (var_up - var_lo) / self.eps_abs[p] * self.scale_constant_value + == (var_up - var_lo) / param_diff * self.scale_constant_value ) # A constraint to calculate elements in Hessian matrix # transfer prior FIM to be Expressions fim_initial_dict = { (bu, un): self.prior_FIM[i][j] - for i, bu in enumerate(model.regression_parameters) - for j, un in enumerate(model.regression_parameters) + for i, bu in enumerate(mod.parameter_names) + for j, un in enumerate(mod.parameter_names) } def read_prior(m, i, j): return fim_initial_dict[(i, j)] - model.priorFIM = pyo.Expression( - model.regression_parameters, model.regression_parameters, rule=read_prior + mod.priorFIM = pyo.Expression( + mod.parameter_names, mod.parameter_names, rule=read_prior ) # The off-diagonal elements are symmetric, thus only half of the elements need to be calculated @@ -470,31 +495,29 @@ def fim_rule(m, p, q): m.fim[p, q] == sum( 1 - / self.measurement_vars.variance[n] + / self.model.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(mod.scenario_blocks[0])] * m.sensitivity_jacobian[p, n] * m.sensitivity_jacobian[q, n] - for n in model.measured_variables + for n in mod.output_names ) - + m.priorFIM[p, q] * self.fim_scale_constant_value + + m.priorFIM[p, q] ) - model.jacobian_constraint = pyo.Constraint( - model.regression_parameters, model.measured_variables, rule=jacobian_rule + mod.jacobian_constraint = pyo.Constraint( + mod.parameter_names, mod.output_names, rule=jacobian_rule ) - model.fim_constraint = pyo.Constraint( - model.regression_parameters, model.regression_parameters, rule=fim_rule + mod.fim_constraint = pyo.Constraint( + mod.parameter_names, mod.parameter_names, rule=fim_rule ) if self.only_compute_fim_lower: # Fix the upper half of the FIM matrix elements to be 0.0. # This eliminates extra variables and ensures the expected number of # degrees of freedom in the optimization problem. - for p in model.regression_parameters: - for q in model.regression_parameters: + for p in mod.parameter_names: + for q in mod.parameter_names: if p > q: model.fim[p, q].fix(0.0) - - return model # Create scenario block structure def _generate_scenario_blocks(self, mod=None): diff --git a/pyomo/contrib/doe/redesign/experiment_class_example.py b/pyomo/contrib/doe/redesign/experiment_class_example.py index 2b9ac55ced8..76b6c0ab59b 100644 --- a/pyomo/contrib/doe/redesign/experiment_class_example.py +++ b/pyomo/contrib/doe/redesign/experiment_class_example.py @@ -207,7 +207,7 @@ def label_experiment_impl(self, index_sets_meas): m.measurement_error = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - m.measurement_error.update((k, 0.0) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) # Grab design variables base_comp_des = [m.CA, m.T] diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index fd4de9103d1..03cf5d9df5e 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -1,12 +1,22 @@ from experiment_class_example import * from pyomo.contrib.doe import * +import numpy as np doe_obj = [0, 0, 0,] for ind, fd in enumerate(['central', 'backward', 'forward']): + print(fd) experiment = FullReactorExperiment(data_ex, 32, 3) - doe_obj[ind] = DesignOfExperiments_(experiment) - doe_obj[ind].fd_formula = fd + doe_obj[ind] = DesignOfExperiments_(experiment, fd_formula=fd) + doe_obj[ind].jac_initial = None + doe_obj[ind].prior_FIM = np.eye(4) + doe_obj[ind].fim_initial = None + doe_obj[ind].L_initial = None + doe_obj[ind].L_LB = 1e-7 + doe_obj[ind].Cholesky_option = True + doe_obj[ind].objective_option = ObjectiveLib.det + doe_obj[ind].scale_nominal_param_value = True + doe_obj[ind].scale_constant_value = 1 doe_obj[ind].step = 0.001 - doe_obj[ind]._generate_scenario_blocks() \ No newline at end of file + doe_obj[ind].create_doe_model() \ No newline at end of file From 097638d339b626c5896951fee22d7665e0793011 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 25 Jun 2024 16:34:10 -0400 Subject: [PATCH 011/203] Added comment --- pyomo/contrib/doe/doe.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 78372dad825..9ebba0b5fd7 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -308,6 +308,7 @@ def create_doe_model(self, mod=None): # Generate scenarios for finite difference formulae self._generate_scenario_blocks() + # Shorthand for easier reading mod = self.model # Set names to index sensitivity matrix (jacobian) and FIM From 1379aba68951e7a3cf4112b8f0ed31c636681e1e Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 26 Jun 2024 08:45:07 -0400 Subject: [PATCH 012/203] Added checks for input FIM, jacobian, labels Added size checks to make sure everything is consistent before being automatically generated by the create_model function. --- pyomo/contrib/doe/doe.py | 58 +++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 9ebba0b5fd7..aec4ed4a89a 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -125,12 +125,8 @@ def __init__( solver.options["max_iter"] = 3000 self.solver = solver - # check if there is prior info - if prior_FIM is None: - pass # Since the parameters are not yet populated, the prior_FIM will be - # set to zero when the prior_FIM is set. - else: - self.prior_FIM = prior_FIM + # Prior FIM will be checked when the first model instance is built. + self.prior_FIM = prior_FIM # To-Do: Add check when parameters are populated that input FIM is the correct size @@ -542,6 +538,30 @@ def _generate_scenario_blocks(self, mod=None): # Check the model that labels are correct self.check_model_labels() + + # Gather lengths of label structures for later use in the model build process + self.n_parameters = len(self.model.base_model.unknown_parameters) + self.n_measurement_error = len(self.model.base_model.measurement_error) + self.n_experiment_inputs = len(self.model.base_model.experiment_inputs) + self.n_experiment_outputs = len(self.model.base_model.experiment_outputs) + + assert (self.n_measurement_error == self.n_experiment_outputs), "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format(self.n_experiment_outputs, self.n_measurement_error) + + self.logger.info('Experiment output and measurement error lengths match.') + + # Check that the user input FIM and Jacobian are the correct dimension + if self.prior_FIM is not None: + self.check_model_FIM(self.prior_FIM) + else: + self.prior_FIM = np.zeros(self.n_parameters, self.n_parameters) + if self.fim_initial is not None: + self.check_model_FIM(self.fim_initial) + else: + self.fim_initial = np.eye(self.n_parameters) + self.prior_FIM + if self.jac_initial is not None: + self.check_model_jac(self.jac_initial) + else: + self.jac_initial = np.eye(self.n_experiment_outputs, self.n_parameters) # Set shorthand for self.model mod = self.model @@ -568,7 +588,7 @@ def _generate_scenario_blocks(self, mod=None): # Generate blocks for finite difference scenarios def build_block_scenarios(b, s): # Generate model for the finite difference scenario - b.transfer_attributes_from(self.experiment.get_labeled_model().clone()) + b.transfer_attributes_from(self.model.base_model.clone()) # Forward/Backward difference have a stationary case (s == 0), no parameter to perturb if self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: @@ -666,6 +686,30 @@ def check_model_labels(self, mod=None): self.logger.info('Model has expected labels.') + # Check the FIM shape against what is expected from the model. + def check_model_FIM(self, FIM=None): + """ + Checks if the specified matrix, FIM, matches the shape expected + from the model. This method should only be called after the + model has been probed for the length of the unknown parameter, + experiment input, experiment output, and measurement error + has been stored to the object. + + Parameters + ---------- + mod: model for suffix checking, Default: None, (self.model) + """ + assert FIM.shape == (self.n_parameters, self.n_parameters), "Shape of FIM provided should be n_parameters x n_parameters, or {}, FIM provided has shape: {}".format((self.n_parameters, self.n_parameters), FIM.shape) + + self.logger.info('FIM provided matches expected dimensions from model.') + + + # Check the jacobian shape against what is expected from the model. + def check_model_jac(self, jac=None): + assert jac.shape == (self.n_experiment_outputs, self.n_parameters), "Shape of Jacobian provided should be n_experiment_outputs x n_parameters, or {}, Jacobian provided has shape: {}".format((self.n_experiment_outputs, self.n_parameters), jac.shape) + + self.logger.info('Jacobian provided matches expected dimensions from model.') + # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) def compute_FIM_full_factorial(self, ): return From bb26bdfb667be0df0d0a94129904bdc2e1328d91 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:14:07 -0400 Subject: [PATCH 013/203] Update Jacobian representation Made the Jacobian representation consistent with the paper as well as sources on what the sensitivity matrix should be (i.e., (n_experiment_outputs x n_parameters) such that Q^T @ Q is (n_parameters x n_parameters). --- pyomo/contrib/doe/doe.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index aec4ed4a89a..65945428852 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -165,7 +165,7 @@ def run_doe( """ Optimize an experimental design. The procedure has a two steps (1) Solve a square problem with the experimental design fixed [initializes model equations] - (2) Solve the unfixed system for optimal experimental design + (2) Solve the unfixed system for optimal experimental design [optimizes experimental outputs] Parameters ---------- @@ -322,14 +322,10 @@ def identity_matrix(m, i, j): # If the user provides an initial Jacobian, convert it to a dictionary if self.jac_initial is not None: dict_jac_initialize = {} - for i, bu in enumerate(mod.parameter_names): - for j, un in enumerate(mod.output_names): - if isinstance(self.jac_initial, dict): - # Jacobian is a dictionary of arrays or lists where the key is the regression parameter name - dict_jac_initialize[(bu, un)] = self.jac_initial[bu][j] - elif isinstance(self.jac_initial, np.ndarray): - # Jacobian is a numpy array, rows are regression parameters, columns are measured variables - dict_jac_initialize[(bu, un)] = self.jac_initial[i][j] + for i, bu in enumerate(mod.output_names): + for j, un in enumerate(mod.parameter_names): + # Jacobian is a numpy array, rows are experimental outputs, columns are unknown parameters + dict_jac_initialize[(bu, un)] = self.jac_initial[i][j] # Initialize the Jacobian matrix def initialize_jac(m, i, j): @@ -341,8 +337,8 @@ def initialize_jac(m, i, j): return 0.1 mod.sensitivity_jacobian = pyo.Var( - mod.parameter_names, mod.output_names, + mod.parameter_names, initialize=initialize_jac, ) @@ -415,7 +411,7 @@ def init_cho(m, i, j): mod.L_ele[c, d].setlb(self.L_LB) # jacobian rule - def jacobian_rule(m, p, n): + def jacobian_rule(m, n, p): """ m: Pyomo model p: parameter @@ -447,7 +443,7 @@ def jacobian_rule(m, p, n): if self.scale_nominal_param_value: return ( - m.sensitivity_jacobian[p, n] + m.sensitivity_jacobian[n, p] == (var_up - var_lo) / param_diff * param_val @@ -455,7 +451,7 @@ def jacobian_rule(m, p, n): ) else: return ( - m.sensitivity_jacobian[p, n] + m.sensitivity_jacobian[n, p] == (var_up - var_lo) / param_diff * self.scale_constant_value ) @@ -493,15 +489,15 @@ def fim_rule(m, p, q): == sum( 1 / self.model.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(mod.scenario_blocks[0])] - * m.sensitivity_jacobian[p, n] - * m.sensitivity_jacobian[q, n] + * m.sensitivity_jacobian[n, p] + * m.sensitivity_jacobian[n, q] for n in mod.output_names ) + m.priorFIM[p, q] ) mod.jacobian_constraint = pyo.Constraint( - mod.parameter_names, mod.output_names, rule=jacobian_rule + mod.output_names, mod.parameter_names, rule=jacobian_rule ) mod.fim_constraint = pyo.Constraint( mod.parameter_names, mod.parameter_names, rule=fim_rule From 258ebfda5d670644a26dc636e5f2ed66a27122c2 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 26 Jun 2024 09:59:45 -0400 Subject: [PATCH 014/203] Added functionality for incoming block-models Changed how the tree is traversed so the parameter location starts after the "base_model" or "scenario_blocks[0]" keyword. This way, an arbitrary block structure should be support. This will help for making multiple instances of the DoE model (i.e., multiple simultaneous estimations or stochastic-based experiment implementation). --- pyomo/contrib/doe/doe.py | 83 +++++++++++++----------- pyomo/contrib/doe/redesign/test_build.py | 27 +++++++- 2 files changed, 71 insertions(+), 39 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 65945428852..eea74a3cca7 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -144,7 +144,7 @@ def __init__( self.model = pyo.ConcreteModel() # Build empty model # May need this attribute for more complicated structures? # (i.e., no model rebuilding for large models with sequential) - # self._built_scenarios = False + self._built_model = False # Perform doe def run_doe( @@ -185,7 +185,7 @@ def run_doe( L_LB: L is the Cholesky decomposition matrix for FIM, i.e. FIM = L*L.T. L_LB is the lower bound for every element in L. - if FIM is positive definite, the diagonal element should be positive, so we can set a LB like 1E-10 + if FIM is positive definite, the diagonal element should be positive, so we can set a LB similar to 1E-10 L_initial: initialize the L jac_initial: @@ -281,15 +281,22 @@ def compute_FIM(self, ): def create_doe_model(self, mod=None): """ Add equations to compute sensitivities, FIM, and objective. - + Builds the DoE model. Adds the scenarios, the sensitivity matrix + Q, the FIM, as well as the objective function to the model. + + The function alters the ``mod`` input. + + In the single experiment case, ``mod`` will be self.model. In the + multi-experiment case, ``mod`` will be one experiment to be enumerated. + Parameters - ----------- - no_obj: if True, objective function is 0. + ---------- + mod: model to add finite difference scenarios - Return - ------- - model: the DOE model """ + if mod is None: + mod = self.model + # Developer recommendation: use the Cholesky decomposition for D-optimality # The explicit formula is available for benchmarking purposes and is NOT recommended if ( @@ -302,14 +309,12 @@ def create_doe_model(self, mod=None): ) # Generate scenarios for finite difference formulae - self._generate_scenario_blocks() - - # Shorthand for easier reading - mod = self.model + self._generate_scenario_blocks(mod=mod) # Set names to index sensitivity matrix (jacobian) and FIM - mod.parameter_names = pyo.Set(initialize=[".".join(k.name.split('.')[1:]) for k in mod.scenario_blocks[0].unknown_parameters.keys()]) - mod.output_names = pyo.Set(initialize=[".".join(k.name.split('.')[1:]) for k in mod.scenario_blocks[0].experiment_outputs.keys()]) + scen_block_ind = min([k.name.split('.').index('scenario_blocks[0]') for k in mod.scenario_blocks[0].unknown_parameters.keys()]) + mod.parameter_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in mod.scenario_blocks[0].unknown_parameters.keys()]) + mod.output_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in mod.scenario_blocks[0].experiment_outputs.keys()]) def identity_matrix(m, i, j): if i == j: @@ -414,12 +419,12 @@ def init_cho(m, i, j): def jacobian_rule(m, n, p): """ m: Pyomo model - p: parameter - n: response + n: experimental output + p: unknown parameter """ fd_step_mult = 1 cuid = pyo.ComponentUID(n) - param_ind = self.model.parameter_names.data().index(p) + param_ind = mod.parameter_names.data().index(p) # Different FD schemes lead to different scenarios for the computation if self.fd_formula == FiniteDifferenceStep.central: @@ -432,10 +437,10 @@ def jacobian_rule(m, n, p): elif self.fd_formula == FiniteDifferenceStep.backward: s1 = 0 s2 = param_ind + 1 - + var_up = cuid.find_component_on(m.scenario_blocks[s1]) var_lo = cuid.find_component_on(m.scenario_blocks[s2]) - + param = mod.parameter_scenarios[max(s1, s2)] param_loc = pyo.ComponentUID(param).find_component_on(mod.scenario_blocks[0]) param_val = mod.scenario_blocks[0].unknown_parameters[param_loc] @@ -470,12 +475,12 @@ def read_prior(m, i, j): mod.parameter_names, mod.parameter_names, rule=read_prior ) - # The off-diagonal elements are symmetric, thus only half of the elements need to be calculated + # Off-diagonal elements are symmetric, so only half of the off-diagonal elements need to be specified. def fim_rule(m, p, q): """ m: Pyomo model - p: parameter - q: parameter + p: unknown parameter + q: unknown parameter """ if p > q: @@ -488,7 +493,7 @@ def fim_rule(m, p, q): m.fim[p, q] == sum( 1 - / self.model.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(mod.scenario_blocks[0])] + / mod.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(mod.scenario_blocks[0])] * m.sensitivity_jacobian[n, p] * m.sensitivity_jacobian[n, q] for n in mod.output_names @@ -528,18 +533,21 @@ def _generate_scenario_blocks(self, mod=None): ---------- mod: model to add finite difference scenarios """ - + # If model is none, assume it is self.model + if mod is None: + mod = self.model + # Generate initial scenario to populate unknown parameter values - self.model.base_model = self.experiment.get_labeled_model(**self.args).clone() + mod.base_model = self.experiment.get_labeled_model(**self.args).clone() # Check the model that labels are correct - self.check_model_labels() + self.check_model_labels(mod=mod) # Gather lengths of label structures for later use in the model build process - self.n_parameters = len(self.model.base_model.unknown_parameters) - self.n_measurement_error = len(self.model.base_model.measurement_error) - self.n_experiment_inputs = len(self.model.base_model.experiment_inputs) - self.n_experiment_outputs = len(self.model.base_model.experiment_outputs) + self.n_parameters = len(mod.base_model.unknown_parameters) + self.n_measurement_error = len(mod.base_model.measurement_error) + self.n_experiment_inputs = len(mod.base_model.experiment_inputs) + self.n_experiment_outputs = len(mod.base_model.experiment_outputs) assert (self.n_measurement_error == self.n_experiment_outputs), "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format(self.n_experiment_outputs, self.n_measurement_error) @@ -559,9 +567,6 @@ def _generate_scenario_blocks(self, mod=None): else: self.jac_initial = np.eye(self.n_experiment_outputs, self.n_parameters) - # Set shorthand for self.model - mod = self.model - # Make a new Suffix to hold which scenarios are associated with parameters mod.parameter_scenarios = pyo.Suffix( direction=pyo.Suffix.LOCAL, @@ -584,7 +589,7 @@ def _generate_scenario_blocks(self, mod=None): # Generate blocks for finite difference scenarios def build_block_scenarios(b, s): # Generate model for the finite difference scenario - b.transfer_attributes_from(self.model.base_model.clone()) + b.transfer_attributes_from(mod.base_model.clone()) # Forward/Backward difference have a stationary case (s == 0), no parameter to perturb if self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: @@ -594,8 +599,9 @@ def build_block_scenarios(b, s): param = mod.parameter_scenarios[s] # Grabbing the location of the parameter without the "base_model" precursor - param_loc = ".".join(param.name.split('.')[1:]) - + base_model_loc = param.name.split('.').index('base_model') + param_loc = ".".join(param.name.split('.')[(base_model_loc + 1):]) + # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd @@ -631,7 +637,10 @@ def global_design_fixing(m, s): setattr(mod, con_name, pyo.Constraint(mod.scenarios, rule=global_design_fixing)) # Clean up the base model used to generate the scenarios - self.model.del_component(self.model.base_model) + mod.del_component(mod.base_model) + + + # Check to see if the model has all the required suffixes diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 03cf5d9df5e..7a389c17459 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -3,7 +3,7 @@ import numpy as np -doe_obj = [0, 0, 0,] +doe_obj = [0, 0, 0, 0,] for ind, fd in enumerate(['central', 'backward', 'forward']): print(fd) @@ -19,4 +19,27 @@ doe_obj[ind].scale_nominal_param_value = True doe_obj[ind].scale_constant_value = 1 doe_obj[ind].step = 0.001 - doe_obj[ind].create_doe_model() \ No newline at end of file + doe_obj[ind].create_doe_model() + + +ind = 3 + +doe_obj[ind] = DesignOfExperiments_(experiment, fd_formula=fd) +doe_obj[ind].model = pyo.ConcreteModel() +doe_obj[ind].model.set_blocks = pyo.Set(initialize=[0, 1, 2]) +doe_obj[ind].model.block_instances = pyo.Block(doe_obj[ind].model.set_blocks) +doe_obj[ind].jac_initial = None +doe_obj[ind].prior_FIM = np.eye(4) +doe_obj[ind].fim_initial = None +doe_obj[ind].L_initial = None +doe_obj[ind].L_LB = 1e-7 +doe_obj[ind].Cholesky_option = True +doe_obj[ind].objective_option = ObjectiveLib.det +doe_obj[ind].scale_nominal_param_value = True +doe_obj[ind].scale_constant_value = 1 +doe_obj[ind].step = 0.001 +doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[0]) +doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[1]) +doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[2]) + +print('Multi-block build complete') From b13826c82442d13a37944f13e7030934fac1cb32 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:04:20 -0400 Subject: [PATCH 015/203] Slight language update for readability --- pyomo/contrib/doe/doe.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index eea74a3cca7..7927cdb2c7e 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -311,7 +311,7 @@ def create_doe_model(self, mod=None): # Generate scenarios for finite difference formulae self._generate_scenario_blocks(mod=mod) - # Set names to index sensitivity matrix (jacobian) and FIM + # Set names for indexing sensitivity matrix (jacobian) and FIM scen_block_ind = min([k.name.split('.').index('scenario_blocks[0]') for k in mod.scenario_blocks[0].unknown_parameters.keys()]) mod.parameter_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in mod.scenario_blocks[0].unknown_parameters.keys()]) mod.output_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in mod.scenario_blocks[0].experiment_outputs.keys()]) @@ -598,9 +598,9 @@ def build_block_scenarios(b, s): param = mod.parameter_scenarios[s] - # Grabbing the location of the parameter without the "base_model" precursor - base_model_loc = param.name.split('.').index('base_model') - param_loc = ".".join(param.name.split('.')[(base_model_loc + 1):]) + # Grabbing the index of the parameter without the "base_model" precursor + base_model_ind = param.name.split('.').index('base_model') + param_loc = ".".join(param.name.split('.')[(base_model_ind + 1):]) # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: From c2ffbe5f5c82209dce985b0df39803dff0d18634 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:07:43 -0400 Subject: [PATCH 016/203] Slight cleaning --- pyomo/contrib/doe/doe.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 7927cdb2c7e..95d6a024085 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -348,7 +348,6 @@ def initialize_jac(m, i, j): ) # Initialize the FIM - # ToDo: add dictionary dependence for FIM? OR remove Jacobian dictionary input option. if self.fim_initial is not None: dict_fim_initialize = { (bu, un): self.fim_initial[i][j] @@ -640,9 +639,6 @@ def global_design_fixing(m, s): mod.del_component(mod.base_model) - - - # Check to see if the model has all the required suffixes def check_model_labels(self, mod=None): """ From 516d52c9688b60930baeace5fec82e02b872992c Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:16:19 -0400 Subject: [PATCH 017/203] Updating refactor test functions --- .../doe/redesign/experiment_class_example.py | 37 +++- .../doe/redesign/simple_reaction_example | 188 ++++++++++++++++ .../doe/redesign/simple_reaction_example.py | 208 ++++++++++++++++++ pyomo/contrib/doe/redesign/test_build.py | 4 +- 4 files changed, 426 insertions(+), 11 deletions(-) create mode 100644 pyomo/contrib/doe/redesign/simple_reaction_example create mode 100644 pyomo/contrib/doe/redesign/simple_reaction_example.py diff --git a/pyomo/contrib/doe/redesign/experiment_class_example.py b/pyomo/contrib/doe/redesign/experiment_class_example.py index 76b6c0ab59b..7a8238ee739 100644 --- a/pyomo/contrib/doe/redesign/experiment_class_example.py +++ b/pyomo/contrib/doe/redesign/experiment_class_example.py @@ -72,6 +72,11 @@ def create_model(self): # Model parameters m.R = pyo.Param(mutable=False, initialize=8.314) + # m.A1 = pyo.Param(mutable=True) + # m.E1 = pyo.Param(mutable=True) + # m.A2 = pyo.Param(mutable=True) + # m.E2 = pyo.Param(mutable=True) + # Define model variables ######################## # time @@ -148,20 +153,29 @@ def finalize_model(self): # Unpacking data before simulation control_points = self.data['control_points'] - m.CA[0].fix(self.data['CA0']) + # m.CA[0].fix(self.data['CA0']) + m.CA[0].value = self.data['CA0'] m.CB[0].fix(self.data['CB0']) - m.CC[0].fix(self.data['CC0']) + # m.CC[0].fix(self.data['CC0']) m.t.update(self.data['t_range']) m.t.update(control_points) - m.A1 = self.data['A1'] - m.A2 = self.data['A2'] - m.E1 = self.data['E1'] - m.E2 = self.data['E2'] + # m.A1 = self.data['A1'] + # m.A2 = self.data['A2'] + # m.E1 = self.data['E1'] + # m.E2 = self.data['E2'] + m.A1.fix(self.data['A1']) + m.A2.fix(self.data['A2']) + m.E1.fix(self.data['E1']) + m.E2.fix(self.data['E2']) + + # m.T[0].fix(control_points[0]) m.t_control = control_points # TODO: add simulation for initialization????? # Call the simulator (optional) + # sim = Simulator(m, package='casadi') + # tsim, profiles = sim.simulate(numpoints=100, integrator='idas') # Discretizing the model discr = pyo.TransformationFactory("dae.collocation") @@ -172,10 +186,10 @@ def finalize_model(self): for t in m.t: if t in control_points: cv = control_points[t] + # m.T[t].fix(cv) m.T[t] = cv - # Unfixing initial temperature - m.T[0.0].unfix() + # m.extra_con = pyo.Constraint(expr=m.T[0.0] == m.T[1.0]) @m.Constraint(m.t - control_points) def T_control(m, t): @@ -185,6 +199,9 @@ def T_control(m, t): neighbour_t = max(tc for tc in control_points if tc < t) return m.T[t] == m.T[neighbour_t] + # sim.initialize_model() + + def label_experiment_impl(self, index_sets_meas): """ Example for annotating (labeling) the model with a @@ -248,8 +265,8 @@ def label_experiment(self): data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} experiments = [ - FullReactorExperiment(data_ex, 32, 3), - PartialReactorExperiment(data_ex, 32, 3), + FullReactorExperiment(data_ex, 10, 3), + PartialReactorExperiment(data_ex, 10, 3), ] # in parmest / DoE: diff --git a/pyomo/contrib/doe/redesign/simple_reaction_example b/pyomo/contrib/doe/redesign/simple_reaction_example new file mode 100644 index 00000000000..416cbff1c13 --- /dev/null +++ b/pyomo/contrib/doe/redesign/simple_reaction_example @@ -0,0 +1,188 @@ +def expand_model_components(m, base_components, index_sets): + """ + Takes model components and index sets and returns the + model component labels. + + Arguments + --------- + m: Pyomo model + base_components: list of variables from model 'm' + index_sets: list, same length as base_components, where each + element is a list of index sets, or None + """ + for val, indexes in itertools.zip_longest(base_components, index_sets): + # If the variable has no index, + # add just the model component + if not val.is_indexed(): + yield val + # If the component is indexed but no + # index supplied, add all indices + elif indexes is None: + yield from val.values() + else: + for j in itertools.product(*indexes): + yield val[j] + +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) + + +class SimpleReactorExperiment(object): + def __init__(self, data, nfe, ncp): + self.data = data + self.nfe = nfe + self.ncp = ncp + self.model = None + + def get_labeled_model(self): + if self.model is None: + self.create_model() + self.finalize_model() + self.label_experiment_impl() + return self.model + + def create_model(self): + """ + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. + + Return + ------ + m: a Pyomo.DAE model + """ + + m = self.model = pyo.ConcreteModel() + + # Model parameters + m.R = pyo.Param(mutable=False, initialize=8.314) + + # Define model variables + ######################## + # time + m.t = ContinuousSet(bounds=[0, 1]) + + # Concentrations + m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Arrhenius rate law equations + m.A1 = pyo.Var(within=pyo.NonNegativeReals) + + # Differential variables (Conc.) + m.dCAdt = DerivativeVar(m.CA, wrt=m.t) + + ######################## + # End variable def. + + # Equation def'n + ######################## + + # Expression for rate constants + @m.Expression(m.t) + def k1(m, t): + return m.A1 + + # Concentration odes + @m.Constraint(m.t) + def CA_rxn_ode(m, t): + return m.dCAdt[t] == -m.k1[t] * m.CA[t] + + # algebraic balance for concentration of B + # Valid because the reaction system (A --> B) is equimolar + @m.Constraint(m.t) + def CB_balance(m, t): + return m.CA[0] == m.CA[t] + m.CB[t] + + ######################## + # End equation def'n + + def finalize_model(self): + """ + Example finalize model function. There are two main tasks + here: + 1. Extracting useful information for the model to align + with the experiment. (Here: CA0, t_final, t_control) + 2. Discretizing the model subject to this information. + + Arguments + --------- + m: Pyomo model + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ + m = self.model + + # Unpacking data before simulation + control_points = self.data['control_points'] + + m.CA[0].fix(self.data['CA0']) + m.CB[0].fix(self.data['CB0']) + # m.A1 = self.data['A1'] + m.A1.fix(self.data['A1']) + + # TODO: add simulation for initialization????? + # Call the simulator (optional) + # sim = Simulator(m, package='casadi') + # tsim, profiles = sim.simulate(numpoints=100, integrator='idas') + + # Discretizing the model + discr = pyo.TransformationFactory("dae.collocation") + discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) + + # sim.initialize_model() + + + def label_experiment_impl(self, index_sets_meas): + """ + Example for annotating (labeling) the model with a + full experiment. + + Arguments + --------- + + """ + m = self.model + + # Grab measurement labels + base_comp_meas = [m.CA, m.CB, ] + m.experiment_outputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Adding no error for measurements currently + m.measurement_error = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Grab design variables + base_comp_des = [m.CA, ] + index_sets_des = [[[m.t.first()]], ] + m.experiment_inputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) + + m.unknown_parameters = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1,]) + +f = open('result.json') +data_ex = json.load(f) +data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} + +experiments_simple = [ + SimpleReactorExperiment(data_ex, 32, 3), +] + +# in parmest / DoE: +expanded_experiments_simple = [e.get_labeled_model() for e in experiments_simple] \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/simple_reaction_example.py b/pyomo/contrib/doe/redesign/simple_reaction_example.py new file mode 100644 index 00000000000..8c26ee57a5f --- /dev/null +++ b/pyomo/contrib/doe/redesign/simple_reaction_example.py @@ -0,0 +1,208 @@ +# === Required imports === +import pyomo.environ as pyo +from pyomo.dae import ContinuousSet, DerivativeVar, Simulator + +import itertools +import json +# ======================== + +def expand_model_components(m, base_components, index_sets): + """ + Takes model components and index sets and returns the + model component labels. + + Arguments + --------- + m: Pyomo model + base_components: list of variables from model 'm' + index_sets: list, same length as base_components, where each + element is a list of index sets, or None + """ + for val, indexes in itertools.zip_longest(base_components, index_sets): + # If the variable has no index, + # add just the model component + if not val.is_indexed(): + yield val + # If the component is indexed but no + # index supplied, add all indices + elif indexes is None: + yield from val.values() + else: + for j in itertools.product(*indexes): + yield val[j] + +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) + + +class SimpleReactorExperiment(object): + def __init__(self, data, nfe, ncp): + self.data = data + self.nfe = nfe + self.ncp = ncp + self.model = None + + def get_labeled_model(self): + if self.model is None: + self.create_model() + self.finalize_model() + self.label_experiment_impl(index_sets_meas=[[self.model.t_control], [self.model.t_control],]) + return self.model + + def create_model(self): + """ + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. + + Return + ------ + m: a Pyomo.DAE model + """ + + m = self.model = pyo.ConcreteModel() + + # Model parameters + m.R = pyo.Param(mutable=False, initialize=8.314) + + # Define model variables + ######################## + # time + m.t = ContinuousSet(bounds=[0, 1]) + + # Concentrations + m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Arrhenius rate law equations + # m.A1 = pyo.Var(within=pyo.NonNegativeReals) + m.A1 = pyo.Param(initialize=0, mutable=True) + + # Differential variables (Conc.) + m.dCAdt = DerivativeVar(m.CA, wrt=m.t) + # m.dCBdt = DerivativeVar(m.CB, wrt=m.t) + + ######################## + # End variable def. + + # Equation def'n + ######################## + + m.k1 = pyo.Var(m.t, initialize=0) + + @m.Constraint(m.t) + def k1_con(m, t): + return m.k1[t] == m.A1 + + # @m.Expression(m.t) + # def k1(m, t): + # return m.A1 + + # Concentration odes + @m.Constraint(m.t) + def CA_rxn_ode(m, t): + return m.dCAdt[t] == -m.k1[t] * m.CA[t] + + # @m.Constraint(m.t) + # def CB_rxn_ode(m, t): + # return m.dCBdt[t] == m.A1 * m.CB[t] + + # algebraic balance for concentration of B + # Valid because the reaction system (A --> B) is equimolar + @m.Constraint(m.t) + def CB_balance(m, t): + return m.CA[0] == m.CA[t] + m.CB[t] + + ######################## + # End equation def'n + + def finalize_model(self): + """ + Example finalize model function. There are two main tasks + here: + 1. Extracting useful information for the model to align + with the experiment. (Here: CA0, t_final, t_control) + 2. Discretizing the model subject to this information. + + Arguments + --------- + m: Pyomo model + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ + m = self.model + + # Unpacking data before simulation + control_points = self.data['control_points'] + + m.CA[0].fix(self.data['CA0']) + # m.CB[0].fix(self.data['CB0']) + m.A1.value = self.data['A1'] + # m.A1.fix(self.data['A1']) + + m.k1.pprint() + + m.t_control = control_points + + # TODO: add simulation for initialization????? + # Call the simulator (optional) + sim = Simulator(m, package='casadi') + tsim, profiles = sim.simulate(integrator='idas') + + # Discretizing the model + discr = pyo.TransformationFactory("dae.collocation") + discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) + + # sim.initialize_model() + + + def label_experiment_impl(self, index_sets_meas): + """ + Example for annotating (labeling) the model with a + full experiment. + + Arguments + --------- + + """ + m = self.model + + # Grab measurement labels + base_comp_meas = [m.CA, m.CB, ] + m.experiment_outputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Adding no error for measurements currently + m.measurement_error = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Grab design variables + base_comp_des = [m.CA, ] + index_sets_des = [[[m.t.first()]], ] + m.experiment_inputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) + + m.unknown_parameters = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1,]) + +f = open('result.json') +data_ex = json.load(f) +data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} + +experiments_simple = [ + SimpleReactorExperiment(data_ex, 32, 3), +] diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 7a389c17459..bbffc1d7cf2 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -1,13 +1,15 @@ from experiment_class_example import * from pyomo.contrib.doe import * +from simple_reaction_example import * + import numpy as np doe_obj = [0, 0, 0, 0,] for ind, fd in enumerate(['central', 'backward', 'forward']): print(fd) - experiment = FullReactorExperiment(data_ex, 32, 3) + experiment = FullReactorExperiment(data_ex, 10, 3) doe_obj[ind] = DesignOfExperiments_(experiment, fd_formula=fd) doe_obj[ind].jac_initial = None doe_obj[ind].prior_FIM = np.eye(4) From 0644b025bdf61ccd341426f500437fd8d95416e7 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 27 Jun 2024 13:54:08 -0400 Subject: [PATCH 018/203] Small typo fix in create_doe_model --- pyomo/contrib/doe/doe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 95d6a024085..d734bd5f9ee 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -514,7 +514,7 @@ def fim_rule(m, p, q): for p in mod.parameter_names: for q in mod.parameter_names: if p > q: - model.fim[p, q].fix(0.0) + mod.fim[p, q].fix(0.0) # Create scenario block structure def _generate_scenario_blocks(self, mod=None): From 51026f7b4887934b5ffa3aa46906723f19ebcb06 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:11:25 -0400 Subject: [PATCH 019/203] Create objective functionadded Also updated the test build, result.json, and experiment class example to be well-posed DoE models. --- pyomo/contrib/doe/doe.py | 169 ++++++++++++++++++ .../doe/redesign/experiment_class_example.py | 5 + pyomo/contrib/doe/redesign/result.json | 2 +- pyomo/contrib/doe/redesign/test_build.py | 6 +- 4 files changed, 179 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index d734bd5f9ee..27014acfad5 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -585,6 +585,16 @@ def _generate_scenario_blocks(self, mod=None): # To-Do: Fix parameter values if they are not Params? + # Run base model to get initialized model and check model function + for comp, _ in mod.base_model.experiment_inputs.items(): + comp.fix() + + self.solver.solve(mod.base_model, tee='True') + + for comp, _ in mod.base_model.experiment_inputs.items(): + comp.unfix() + + # Generate blocks for finite difference scenarios def build_block_scenarios(b, s): # Generate model for the finite difference scenario @@ -639,6 +649,152 @@ def global_design_fixing(m, s): mod.del_component(mod.base_model) + # Create objective function + def create_objective_function(self, mod=None): + """ + Generates the objective function as an expression and as a + Pyomo Objective object + + The function alters the ``mod`` input. + + In the single experiment case, ``mod`` will be self.model. In the + multi-experiment case, ``mod`` will be one experiment to be enumerated. + + Parameters + ---------- + mod: model to add finite difference scenarios + """ + if mod is None: + mod = self.model + + small_number = 1e-10 + + # Assemble the FIM matrix. This is helpful for initialization! + # + # Suggestion from JS: "It might be more efficient to form the NP array in one shot + # (from a list or using fromatter), and then reshaping to the 2-D matrix" + # + + # fim = np.zeros((len(self.param), len(self.param))) + # for i, bu in enumerate(m.regression_parameters): + # for j, un in enumerate(m.regression_parameters): + # # Copy value from Pyomo model into numpy array + # fim[i][j] = m.fim[bu, un].value + + mod.fim.pprint() + + fim_vals = [ + mod.fim[bu, un].value + for i, bu in enumerate(mod.parameter_names) + for j, un in enumerate(mod.parameter_names) + ] + fim = np.array(fim_vals).reshape(len(mod.parameter_names), len(mod.parameter_names)) + + ### Initialize the Cholesky decomposition matrix + if self.Cholesky_option and self.objective_option == ObjectiveLib.det: + + # Calculate the eigenvalues of the FIM matrix + eig = np.linalg.eigvals(fim) + + # If the smallest eigenvalue is (practically) negative, add a diagonal matrix to make it positive definite + small_number = 1e-10 + if min(eig) < small_number: + fim = fim + np.eye(len(mod.parameter_names)) * (small_number - min(eig)) + + # Compute the Cholesky decomposition of the FIM matrix + L = np.linalg.cholesky(fim) + + # Initialize the Cholesky matrix + for i, c in enumerate(mod.parameter_names): + for j, d in enumerate(mod.parameter_names): + mod.L_ele[c, d].value = L[i, j] + + def cholesky_imp(m, c, d): + """ + Calculate Cholesky L matrix using algebraic constraints + """ + # If it is the left bottom half of L + if list(mod.parameter_names).index(c) >= list(mod.parameter_names).index(d): + return m.fim[c, d] == sum( + m.L_ele[c, mod.parameter_names[k + 1]] + * m.L_ele[d, mod.parameter_names[k + 1]] + for k in range(list(mod.parameter_names).index(d) + 1) + ) + else: + # This is the empty half of L above the diagonal + return pyo.Constraint.Skip + + def trace_calc(m): + """ + Calculate FIM elements. Can scale each element with 1000 for performance + """ + return m.trace == sum(m.fim[j, j] for j in mod.parameter_names) + + def det_general(m): + r"""Calculate determinant. Can be applied to FIM of any size. + det(A) = \sum_{\sigma in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) + Use permutation() to get permutations, sgn() to get signature + """ + r_list = list(range(len(mod.parameter_names))) + # get all permutations + object_p = permutations(r_list) + list_p = list(object_p) + + # generate a name_order to iterate \sigma_i + det_perm = 0 + for i in range(len(list_p)): + name_order = [] + x_order = list_p[i] + # sigma_i is the value in the i-th position after the reordering \sigma + for x in range(len(x_order)): + for y, element in enumerate(mod.parameter_names): + if x_order[x] == y: + name_order.append(element) + + # det(A) = sum_{\sigma \in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) + det_perm = sum( + self._sgn(list_p[d]) + * sum( + m.fim[each, name_order[b]] + for b, each in enumerate(mod.parameter_names) + ) + for d in range(len(list_p)) + ) + return m.det == det_perm + + if self.Cholesky_option and self.objective_option == ObjectiveLib.det: + mod.cholesky_cons = pyo.Constraint( + mod.parameter_names, mod.parameter_names, rule=cholesky_imp + ) + mod.Obj = pyo.Objective( + expr=2 * sum(pyo.log10(mod.L_ele[j, j]) for j in mod.parameter_names), + sense=pyo.maximize, + ) + + elif self.objective_option == ObjectiveLib.det: + # if not cholesky but determinant, calculating det and evaluate the OBJ with det + mod.det = pyo.Var(initialize=np.linalg.det(fim), bounds=(small_number, None)) + mod.det_rule = pyo.Constraint(rule=det_general) + mod.Obj = pyo.Objective(expr=pyo.log10(mod.det), sense=pyo.maximize) + + elif self.objective_option == ObjectiveLib.trace: + # if not determinant or cholesky, calculating the OBJ with trace + mod.trace = pyo.Var(initialize=np.trace(fim), bounds=(small_number, None)) + mod.trace_rule = pyo.Constraint(rule=trace_calc) + mod.Obj = pyo.Objective(expr=pyo.log10(mod.trace), sense=pyo.maximize) + + elif self.objective_option == ObjectiveLib.zero: + # add dummy objective function + mod.Obj = pyo.Objective(expr=0) + else: + # something went wrong! + raise DeveloperError( + "Objective option not recognized. Please contact the developers as you should not see this error." + ) + + + + # Check to see if the model has all the required suffixes def check_model_labels(self, mod=None): """ @@ -711,6 +867,19 @@ def check_model_jac(self, jac=None): self.logger.info('Jacobian provided matches expected dimensions from model.') + # Rescale FIM (a scaling function to help rescale FIM from parameter values) + def rescale_FIM(self, FIM, param_vals): + if isinstance(param_vals, list): + param_vals = np.array([param_vals, ]) + elif isinstance(param_vals, np.ndarray): + if len(param_vals.shape) > 2 or ((len(param_vals.shape) == 2) and (param_vals.shape[0] != 1)): + raise ValueError('param_vals should be a vector of dimensions (1, n_params). The shape you provided is {}.'.format(param_vals.shape)) + if len(param_vals.shape) == 1: + param_vals = np.array([param_vals, ]) + scaling_mat = (1 / param_vals).transpose().dot((1 / param_vals)) + scaled_FIM = np.multiply(FIM, scaling_mat) + return scaled_FIM + # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) def compute_FIM_full_factorial(self, ): return diff --git a/pyomo/contrib/doe/redesign/experiment_class_example.py b/pyomo/contrib/doe/redesign/experiment_class_example.py index 7a8238ee739..7855e32d2fc 100644 --- a/pyomo/contrib/doe/redesign/experiment_class_example.py +++ b/pyomo/contrib/doe/redesign/experiment_class_example.py @@ -168,6 +168,9 @@ def finalize_model(self): m.E1.fix(self.data['E1']) m.E2.fix(self.data['E2']) + m.CA[0].setlb(self.data['CA_bounds'][0]) + m.CA[0].setub(self.data['CA_bounds'][1]) + # m.T[0].fix(control_points[0]) m.t_control = control_points @@ -187,6 +190,8 @@ def finalize_model(self): if t in control_points: cv = control_points[t] # m.T[t].fix(cv) + m.T[t].setlb(self.data['T_bounds'][0]) + m.T[t].setub(self.data['T_bounds'][1]) m.T[t] = cv # m.extra_con = pyo.Constraint(expr=m.T[0.0] == m.T[1.0]) diff --git a/pyomo/contrib/doe/redesign/result.json b/pyomo/contrib/doe/redesign/result.json index f8392e115ed..b7a5ebfb7e2 100644 --- a/pyomo/contrib/doe/redesign/result.json +++ b/pyomo/contrib/doe/redesign/result.json @@ -1 +1 @@ -{"CA0": 1.0, "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 300, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file +{"CA0": 1.0, "CA_bounds": [0.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 300, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index bbffc1d7cf2..dfb89ffc1c9 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -6,6 +6,7 @@ import numpy as np doe_obj = [0, 0, 0, 0,] +obj = ['trace', 'det', 'det'] for ind, fd in enumerate(['central', 'backward', 'forward']): print(fd) @@ -17,11 +18,12 @@ doe_obj[ind].L_initial = None doe_obj[ind].L_LB = 1e-7 doe_obj[ind].Cholesky_option = True - doe_obj[ind].objective_option = ObjectiveLib.det - doe_obj[ind].scale_nominal_param_value = True + doe_obj[ind].objective_option = ObjectiveLib(obj[ind]) + doe_obj[ind].scale_nominal_param_value = (True and (ind != 2)) doe_obj[ind].scale_constant_value = 1 doe_obj[ind].step = 0.001 doe_obj[ind].create_doe_model() + doe_obj[ind].create_objective_function() ind = 3 From c3247e3011644754d4efc47583890a786cf46c43 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 1 Jul 2024 12:12:07 -0400 Subject: [PATCH 020/203] Blank space removal --- pyomo/contrib/doe/doe.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 27014acfad5..27157dc8b03 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -791,8 +791,6 @@ def det_general(m): raise DeveloperError( "Objective option not recognized. Please contact the developers as you should not see this error." ) - - # Check to see if the model has all the required suffixes From 4ed74f300a32a98b72ab46fcaee51502871386f0 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 1 Jul 2024 17:31:39 -0400 Subject: [PATCH 021/203] Moved most attributes to constructor Also added documentation for the inputs. --- pyomo/contrib/doe/doe.py | 165 +++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 76 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 27157dc8b03..a4deaf8a757 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -62,22 +62,31 @@ class ModelOptionLib(Enum): stage2 = "stage2" -class FiniteDifferenceStep(Enum): - forward = "forward" - central = "central" - backward = "backward" +# class FiniteDifferenceStep(Enum): + # forward = "forward" + # central = "central" + # backward = "backward" class DesignOfExperiments_: def __init__( self, experiment, - fd_formula='central', - solver=None, + fd_formula="central", + step=1e-3, + objective_option='det', + scale_constant_value=1, + scale_nominal_param_value=False, prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, args=None, - only_compute_fim_lower=False, logger_level=logging.WARNING, + _Cholesky_option=True, + _only_compute_fim_lower=True, ): """ This package enables model-based design of experiments analysis with Pyomo. @@ -95,24 +104,79 @@ def __init__( fd_formula: Finite difference formula for computing the sensitivy matrix. Must be one of [``central``, ``forward``, ``backward``] + step: + Relative step size for the finite difference formula. + default: 1e-3 + objective_option: + String representation of the objective option. Current available options are: + ``det`` (for determinant, or D-optimality) and ``trace`` (for trace or + A-optimality) + scale_constant_value: + Constant scaling for the sensitivty matrix. Every element will be multiplied by this + scaling factor. + default: 1 + scale_nominal_param_value: + Boolean for whether or not to scale the sensitivity matrix by the nominal parameter + values. Every column of the sensitivity matrix will be divided by the respective + nominal paramter value. + default: False + prior_FIM: + 2D numpy array representing information from prior experiments. If no value is given, + the assumed prior will be a matrix of zeros. This matrix will be assumed to be scaled + as the user has specified (i.e., if scale_nominal_param_value is true, we will assume + the FIM provided here has been scaled by the parameter values) + jac_initial: + 2D numpy array as the initial values for the sensitivity matrix. + fim_initial: + 2D numpy array as the initial values for the FIM. + L_initial: + 2D numpy array as the initial values for the Cholesky matrix. + L_LB: + Lower bound for the values of the lower triangular Cholesky factorization matrix. + default: 1e-7 solver: A ``solver`` object specified by the user, default=None. - If not specified, default solver is IPOPT MA57. - prior_FIM: - A 2D numpy array containing Fisher information matrix (FIM) for prior experiments. - The default None means there is no prior information. + If not specified, default solver is set to IPOPT with MA57. args: Additional arguments for the ``get_labeled_model`` function on the Experiment object. - only_compute_fim_lower: - If True, only the lower triangle of the FIM is computed. Default is True. + _Cholesky_option: + Boolean value of whether or not to use the choleskyn factorization to compute the + determinant for the D-optimality criteria. This parameter should not be changed + unless the user intends to make performance worse (i.e., compare an existing tool + that uses the full FIM to this algorithm) + _only_compute_fim_lower: + If True, only the lower triangle of the FIM is computed. This parameter should not + be changed unless the user intends to make performance worse (i.e., compare an + existing tool that uses the full FIM to this algorithm) logger_level: Specify the level of the logger. Change to logging.DEBUG for all messages. """ # Assert that the Experiment object has callable ``get_labeled_model`` function assert callable(getattr(experiment, 'get_labeled_model')), 'The experiment object must have a ``get_labeled_model`` function' + # Set the experiment object from the user self.experiment = experiment + + # Set the finite difference and subsequent step size self.fd_formula = FiniteDifferenceStep(fd_formula) + self.step = step + + # Set the objective type and scaling options: + self.objective_option = ObjectiveLib(objective_option) + + self.scale_constant_value = scale_constant_value + self.scale_nominal_param_value = scale_nominal_param_value + + # Set the prior FIM (will be checked upon model construction) + self.prior_FIM = prior_FIM + + # Set the initial values for the jacobian, fim, and L matrices + self.jac_initial = jac_initial + self.fim_initial = fim_initial + self.L_initial = L_initial + + # Set the lower bound on the Cholesky lower triangular matrix + self.L_LB = L_LB # check if user-defined solver is given if solver: @@ -124,24 +188,23 @@ def __init__( solver.options["halt_on_ampl_error"] = "yes" solver.options["max_iter"] = 3000 self.solver = solver - - # Prior FIM will be checked when the first model instance is built. - self.prior_FIM = prior_FIM - - # To-Do: Add check when parameters are populated that input FIM is the correct size # Set args as an empty dict if no arguments are passed if args is None: args = {} self.args = args + # Revtrieve logger and set logging level self.logger = logging.getLogger(__name__) self.logger.setLevel(level=logger_level) - self.only_compute_fim_lower = only_compute_fim_lower + # Set the private options if passed (only developers should pass these) + self.Cholesky_option = _Cholesky_option + self.only_compute_fim_lower = _only_compute_fim_lower # model attribute to avoid rebuilding models self.model = pyo.ConcreteModel() # Build empty model + # May need this attribute for more complicated structures? # (i.e., no model rebuilding for large models with sequential) self._built_model = False @@ -162,61 +225,6 @@ def run_doe( step=0.001, tee_opt=True, ): - """ - Optimize an experimental design. The procedure has a two steps - (1) Solve a square problem with the experimental design fixed [initializes model equations] - (2) Solve the unfixed system for optimal experimental design [optimizes experimental outputs] - - Parameters - ---------- - objective_option: - choose from the ObjectiveLib enum options, - "det": the determinant of the FIM, - "trace": the trace of the FIM, - "zero": a value of zero - scale_nominal_param_value: - if True, the parameters are scaled by its own nominal value in param_init - scale_constant_value: - scale all elements in Jacobian matrix, default is 1. - optimize_opt: - A dictionary, keys are design variables, values are True or False deciding if this design variable will be optimized as DOF or not - if_Cholesky: - if True, Cholesky decomposition is used for Objective function for D-optimality. - L_LB: - L is the Cholesky decomposition matrix for FIM, i.e. FIM = L*L.T. - L_LB is the lower bound for every element in L. - if FIM is positive definite, the diagonal element should be positive, so we can set a LB similar to 1E-10 - L_initial: - initialize the L - jac_initial: - a matrix used to initialize jacobian matrix - fim_initial: - a matrix used to initialize FIM matrix - formula: - choose from "central", "forward", "backward", - which refers to the Enum FiniteDifferenceStep.central, .forward, or .backward - step: - Sensitivity perturbation step size, a fraction between [0,1]. default is 0.001 - tee_opt: - if True, IPOPT console output is printed - - Returns - ------- - analysis_square: result summary of the square problem solved at the initial point - analysis_optimize: result summary of the optimization problem solved - - """ - # Check that experimental outputs exist - try: - outputs = [k.name for k, v in model.experiment_outputs.items()] - except: - RuntimeError( - 'Experiment model does not have suffix ' + '"experiment_outputs".' - ) - - # Check that experimental inputs exist - # Check that unknown parameters exist - # Check that measurement errors exist # store inputs in object self.design_values = self.design_vars.variable_names_value self.optimize = if_optimize @@ -273,6 +281,10 @@ def run_multi_doe_simultaneous(self, N_exp=1): "Multipled experiment optimization note yet supported." ) + # ToDo: Add "Update FIM" method + def update_FIM(self, ): + return + # Compute FIM for the DoE object def compute_FIM(self, ): return @@ -647,6 +659,9 @@ def global_design_fixing(m, s): # Clean up the base model used to generate the scenarios mod.del_component(mod.base_model) + + # ToDo: consider this logic? Multi-block systems need something more fancy + # self._built_scenarios = True # Create objective function @@ -681,8 +696,6 @@ def create_objective_function(self, mod=None): # # Copy value from Pyomo model into numpy array # fim[i][j] = m.fim[bu, un].value - mod.fim.pprint() - fim_vals = [ mod.fim[bu, un].value for i, bu in enumerate(mod.parameter_names) From 7defa33f4f8fcb710c0b89f707d5ece94f3124e8 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 1 Jul 2024 18:01:00 -0400 Subject: [PATCH 022/203] Updating example to compare against old code --- pyomo/contrib/doe/redesign/result.json | 2 +- pyomo/contrib/doe/redesign/test_build.py | 185 ++++++++++++++++++++--- pyomo/contrib/doe/scenario.py | 125 +++++++-------- 3 files changed, 226 insertions(+), 86 deletions(-) diff --git a/pyomo/contrib/doe/redesign/result.json b/pyomo/contrib/doe/redesign/result.json index b7a5ebfb7e2..b7f56011e0f 100644 --- a/pyomo/contrib/doe/redesign/result.json +++ b/pyomo/contrib/doe/redesign/result.json @@ -1 +1 @@ -{"CA0": 1.0, "CA_bounds": [0.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 300, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file +{"CA0": 1.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 300, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index dfb89ffc1c9..56c0c744458 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -11,39 +11,174 @@ for ind, fd in enumerate(['central', 'backward', 'forward']): print(fd) experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj[ind] = DesignOfExperiments_(experiment, fd_formula=fd) - doe_obj[ind].jac_initial = None - doe_obj[ind].prior_FIM = np.eye(4) - doe_obj[ind].fim_initial = None - doe_obj[ind].L_initial = None - doe_obj[ind].L_LB = 1e-7 - doe_obj[ind].Cholesky_option = True - doe_obj[ind].objective_option = ObjectiveLib(obj[ind]) - doe_obj[ind].scale_nominal_param_value = (True and (ind != 2)) - doe_obj[ind].scale_constant_value = 1 - doe_obj[ind].step = 0.001 - doe_obj[ind].create_doe_model() - doe_obj[ind].create_objective_function() + doe_obj[ind] = DesignOfExperiments_( + experiment, + fd_formula='central', + step=1e-3, + objective_option=ObjectiveLib(obj[ind]), + scale_constant_value=1, + scale_nominal_param_value=(True and (ind != 2)), + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=True, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + doe_obj[ind].run_doe() ind = 3 -doe_obj[ind] = DesignOfExperiments_(experiment, fd_formula=fd) -doe_obj[ind].model = pyo.ConcreteModel() +doe_obj[ind] = DesignOfExperiments_( + experiment, + fd_formula='central', + step=1e-3, + objective_option=ObjectiveLib.det, + scale_constant_value=1, + scale_nominal_param_value=(True and (ind != 2)), + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) doe_obj[ind].model.set_blocks = pyo.Set(initialize=[0, 1, 2]) doe_obj[ind].model.block_instances = pyo.Block(doe_obj[ind].model.set_blocks) -doe_obj[ind].jac_initial = None -doe_obj[ind].prior_FIM = np.eye(4) -doe_obj[ind].fim_initial = None -doe_obj[ind].L_initial = None -doe_obj[ind].L_LB = 1e-7 -doe_obj[ind].Cholesky_option = True -doe_obj[ind].objective_option = ObjectiveLib.det -doe_obj[ind].scale_nominal_param_value = True -doe_obj[ind].scale_constant_value = 1 -doe_obj[ind].step = 0.001 doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[0]) doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[1]) doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[2]) +# doe_obj[ind].run_doe() print('Multi-block build complete') + +# Old interface comparison +def create_model(m=None, ): + experiment = FullReactorExperiment(data_ex, 10, 3) + m = experiment.get_labeled_model().clone() + return m + +### Define inputs +# Control time set [h] +t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] +# Define parameter nominal value +parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} + +# measurement object +measurements = MeasurementVariables() +measurements.add_variables( + "CA", # name of measurement + indices={0: t_control}, # indices of measurement + time_index_position=0, + variance=1e-2, +) # position of time index + +measurements.add_variables( + "CB", # name of measurement + indices={0: t_control}, # indices of measurement + time_index_position=0, + variance=1e-2, +) # position of time index + +measurements.add_variables( + "CC", # name of measurement + indices={0: t_control}, # indices of measurement + time_index_position=0, + variance=1e-2, +) # position of time index + +# design object +exp_design = DesignVariables() + +# add CAO as design variable +exp_design.add_variables( + "CA", # name of design variable + indices={0: [0]}, # indices of design variable + time_index_position=0, # position of time index + values=[5], # nominal value of design variable + lower_bounds=1, # lower bound of design variable + upper_bounds=5, # upper bound of design variable +) + +# add T as design variable +exp_design.add_variables( + "T", # name of design variable + indices={0: t_control}, # indices of design variable + time_index_position=0, # position of time index + values=[ + 300, + 300, + 300, + 300, + 300, + 300, + 300, + 300, + 300, + ], # nominal value of design variable + lower_bounds=300, # lower bound of design variable + upper_bounds=700, # upper bound of design variable +) + +design_names = exp_design.variable_names +exp1 = [5, 300, 300, 300, 300, 300, 300, 300, 300, 300] +exp1_design_dict = dict(zip(design_names, exp1)) +exp_design.update_values(exp1_design_dict) + +# add a prior information (scaled FIM with T=500 and T=300 experiments) +# prior = np.asarray( + # [ + # [28.67892806, 5.41249739, -81.73674601, -24.02377324], + # [5.41249739, 26.40935036, -12.41816477, -139.23992532], + # [-81.73674601, -12.41816477, 240.46276004, 58.76422806], + # [-24.02377324, -139.23992532, 58.76422806, 767.25584508], + # ] +# ) + +prior = None + +doe_object = DesignOfExperiments( + parameter_dict, # dictionary of parameters + exp_design, # design variables + measurements, # measurement variables + create_model, # function to create model + only_compute_fim_lower=True, +) + +square_result, optimize_result = doe_object.stochastic_program( + if_optimize=True, # if optimize + if_Cholesky=True, # if use Cholesky decomposition + scale_nominal_param_value=True, # if scale nominal parameter value + objective_option="det", # objective option +) + +doe_object2 = DesignOfExperiments( + parameter_dict, # dictionary of parameters + exp_design, # design variables + measurements, # measurement variables + create_model, # function to create model + only_compute_fim_lower=True, +) + +square_result2, optimize_result2 = doe_object2.stochastic_program( + if_optimize=True, # if optimize + if_Cholesky=True, # if use Cholesky decomposition + scale_nominal_param_value=False, # if scale nominal parameter value + objective_option="det", # objective option +) + +# Optimal values +print("Optimal values for determinant optimized experimental design:") +print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.Obj))) +print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.Obj))) +print("Old formulation, scaled: {}".format(pyo.value(optimize_result.model.Obj))) +print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) \ No newline at end of file diff --git a/pyomo/contrib/doe/scenario.py b/pyomo/contrib/doe/scenario.py index d3b8bc46f07..3faeb78dd10 100644 --- a/pyomo/contrib/doe/scenario.py +++ b/pyomo/contrib/doe/scenario.py @@ -65,7 +65,8 @@ def __init__(self, parameter_dict=None, formula="central", step=0.001, store=Fal self.parameter_dict = parameter_dict self.para_names = list(parameter_dict.keys()) self.no_para = len(self.para_names) - self.formula = FiniteDifferenceStep(formula) + # self.formula = FiniteDifferenceStep(formula) + self.formula = formula self.step = step self.store = store self.scenario_nominal = [parameter_dict[d] for d in self.para_names] @@ -104,73 +105,77 @@ def generate_scenario(self): # number of scenario scena_num = {} - count_scens = 0 - for k, v in self.parameters.items(): - if self.formula == FiniteDifferenceStep.central: - scena_num[k.name] = [2 * count_scens, 2 * count_scens + 1] - scena_dict_hi = {k.name: v * (1 + self.step)} - scena_dict_lo = {k.name: v * (1 + self.step)} + # count_scens = 0 + # for k, v in self.parameters.items(): + # if self.formula == FiniteDifferenceStep.central: + # scena_num[k.name] = [2 * count_scens, 2 * count_scens + 1] + # scena_dict_hi = {k.name: v * (1 + self.step)} + # scena_dict_lo = {k.name: v * (1 + self.step)} - eps_abs[k.name] = 2 * self.step * v + # eps_abs[k.name] = 2 * self.step * v - scenario.append(scena_dict_hi) - scenario.append(scena_dict_lo) + # scenario.append(scena_dict_hi) + # scenario.append(scena_dict_lo) - self.ScenarioData = ScenarioData( - scenario, scena_num, eps_abs, list(range(len(scenario))) - ) + # self.ScenarioData = ScenarioData( + # scenario, scena_num, eps_abs, list(range(len(scenario))) + # ) ############################## # Below is deprecated code # ############################## # loop over parameter name - # for p, para in enumerate(self.para_names): - # ## get scenario dictionary - # if self.formula == FiniteDifferenceStep.central: - # scena_num[para.name] = [2 * p, 2 * p + 1] - # scena_dict_up, scena_dict_lo = ( - # copy.deepcopy(self.parameter_dict), - # copy.deepcopy(self.parameter_dict), - # ) - # # corresponding parameter dictionary for the scenario - # scena_dict_up[para.name] *= 1 + self.step - # scena_dict_lo[para.name] *= 1 - self.step - - # scenario.append(scena_dict_up) - # scenario.append(scena_dict_lo) - - # elif self.formula in [ - # FiniteDifferenceStep.forward, - # FiniteDifferenceStep.backward, - # ]: - # # the base case is added as the last one - # scena_num[para] = [p, len(self.param_names)] - # scena_dict_up, scena_dict_lo = ( - # self.parameter_dict.copy(), - # self.parameter_dict.copy(), - # ) - # if self.formula == FiniteDifferenceStep.forward: - # scena_dict_up[para] *= 1 + self.step - - # elif self.formula == FiniteDifferenceStep.backward: - # scena_dict_lo[para] *= 1 - self.step - - # scenario.append(scena_dict_up) - # scenario.append(scena_dict_lo) - - # ## get perturbation sizes - # # for central difference scheme, perturbation size is two times the step size - # if self.formula == FiniteDifferenceStep.central: - # eps_abs[para] = 2 * self.step * self.parameter_dict[para] - # else: - # eps_abs[para] = self.step * self.parameter_dict[para] + for p, para in enumerate(self.para_names): + ## get scenario dictionary + if self.formula == FiniteDifferenceStep.central: + if isinstance(para, str): + name = para + else: + name = para.name + scena_num[name] = [2 * p, 2 * p + 1] + scena_dict_up, scena_dict_lo = ( + copy.deepcopy(self.parameter_dict), + copy.deepcopy(self.parameter_dict), + ) + # corresponding parameter dictionary for the scenario + scena_dict_up[name] *= 1 + self.step + scena_dict_lo[name] *= 1 - self.step + + scenario.append(scena_dict_up) + scenario.append(scena_dict_lo) + + elif self.formula in [ + FiniteDifferenceStep.forward, + FiniteDifferenceStep.backward, + ]: + # the base case is added as the last one + scena_num[para] = [p, len(self.param_names)] + scena_dict_up, scena_dict_lo = ( + self.parameter_dict.copy(), + self.parameter_dict.copy(), + ) + if self.formula == FiniteDifferenceStep.forward: + scena_dict_up[para] *= 1 + self.step + + elif self.formula == FiniteDifferenceStep.backward: + scena_dict_lo[para] *= 1 - self.step + + scenario.append(scena_dict_up) + scenario.append(scena_dict_lo) + + ## get perturbation sizes + # for central difference scheme, perturbation size is two times the step size + if self.formula == FiniteDifferenceStep.central: + eps_abs[para] = 2 * self.step * self.parameter_dict[para] + else: + eps_abs[para] = self.step * self.parameter_dict[para] - # self.ScenarioData = ScenarioData( - # scenario, scena_num, eps_abs, list(range(len(scenario))) - # ) + self.ScenarioData = ScenarioData( + scenario, scena_num, eps_abs, list(range(len(scenario))) + ) - # # store scenario - # if self.store: - # with open("scenario_simultaneous.pickle", "wb") as f: - # pickle.dump(self.scenario_data, f) + # store scenario + if self.store: + with open("scenario_simultaneous.pickle", "wb") as f: + pickle.dump(self.scenario_data, f) From bf81b6c4d00e46bc9f43171b16f7c9d53e2524ca Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 1 Jul 2024 18:01:53 -0400 Subject: [PATCH 023/203] Updated run_doe to perform experimental design Seems to work based on comparison to old code. Will look into this more later. --- pyomo/contrib/doe/doe.py | 81 ++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 48 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index a4deaf8a757..4f4ae2cfd3e 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -83,6 +83,7 @@ def __init__( L_initial=None, L_LB=1e-7, solver=None, + tee=False, args=None, logger_level=logging.WARNING, _Cholesky_option=True, @@ -137,6 +138,8 @@ def __init__( solver: A ``solver`` object specified by the user, default=None. If not specified, default solver is set to IPOPT with MA57. + tee: + Solver option to be passed for verbose output. args: Additional arguments for the ``get_labeled_model`` function on the Experiment object. _Cholesky_option: @@ -189,6 +192,8 @@ def __init__( solver.options["max_iter"] = 3000 self.solver = solver + self.tee = tee + # Set args as an empty dict if no arguments are passed if args is None: args = {} @@ -207,67 +212,47 @@ def __init__( # May need this attribute for more complicated structures? # (i.e., no model rebuilding for large models with sequential) - self._built_model = False + self._built_scenarios = False # Perform doe - def run_doe( - self, - objective_option="det", - scale_nominal_param_value=False, - scale_constant_value=1, - optimize_opt=None, - if_Cholesky=False, - L_LB=1e-7, - L_initial=None, - jac_initial=None, - fim_initial=None, - formula="central", - step=0.001, - tee_opt=True, - ): - # store inputs in object - self.design_values = self.design_vars.variable_names_value - self.optimize = if_optimize - self.objective_option = ObjectiveLib(objective_option) - self.scale_nominal_param_value = scale_nominal_param_value - self.scale_constant_value = scale_constant_value - self.Cholesky_option = if_Cholesky - self.L_LB = L_LB - self.L_initial = L_initial - self.jac_initial = jac_initial - self.fim_initial = fim_initial - self.formula = FiniteDifferenceStep(formula) - self.step = step - self.tee_opt = tee_opt - + def run_doe(self, mod=None): # Start timer sp_timer = TicTocTimer() sp_timer.tic(msg=None) + self.logger.info("Beginning experimental optimization.") # Generate model if self.model is None: self.model = pyo.ConcreteModel() + # ToDo: potentially work with this for more complicated models # build the large DOE pyomo model if not self._built_scenarios: self.create_doe_model(mod=self.model) - # solve model, achieve results for square problem, and results for optimization problem - m, analysis_square = self._compute_stochastic_program(m, optimize_opt) - - if self.optimize: - # If set to optimize, solve the optimization problem (with degrees of freedom) - analysis_optimize = self._optimize_stochastic_program(m) - dT = sp_timer.toc(msg=None) - self.logger.info("elapsed time: %0.1f seconds" % dT) - # Return both square problem and optimization problem results - return analysis_square, analysis_optimize - - else: - dT = sp_timer.toc(msg=None) - self.logger.info("elapsed time: %0.1f seconds" % dT) - # Return only square problem results - return analysis_square + # Add the objective function to the model + self.create_objective_function(mod=self.model) + + # Solve the square problem first to initialize the fim and + # sensitivity constraints + # Deactivate object and fix experimental design decisions to make square + self.model.Obj.deactivate() + for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): + comp.fix() + + self.solver.solve(self.model, tee=self.tee) + + # Reactivate objective and unfix experimental design decisions + for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): + comp.unfix() + self.model.Obj.activate() + + # Solve the full model, which has now been initialized with the square solve + self.solver.solve(self.model, tee=self.tee) + + # Finish timing + dT = sp_timer.toc(msg=None) + self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % dT) # Perform multi-experiment doe (sequential, or ``greedy`` approach) def run_multi_doe_sequential(self, N_exp=1): @@ -568,7 +553,7 @@ def _generate_scenario_blocks(self, mod=None): if self.prior_FIM is not None: self.check_model_FIM(self.prior_FIM) else: - self.prior_FIM = np.zeros(self.n_parameters, self.n_parameters) + self.prior_FIM = np.zeros((self.n_parameters, self.n_parameters)) if self.fim_initial is not None: self.check_model_FIM(self.fim_initial) else: From eb08ba722a2e79a13ec7bf02d976b9a1b2afa4b7 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:29:04 -0400 Subject: [PATCH 024/203] Added FIM prior update function --- pyomo/contrib/doe/doe.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 4f4ae2cfd3e..a81d4dc1d2c 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -863,6 +863,43 @@ def check_model_jac(self, jac=None): self.logger.info('Jacobian provided matches expected dimensions from model.') + + # Update the FIM for the specified model + def update_FIM_prior(self, mod=None, FIM=None): + """ + Updates the prior FIM on the model object. This may be useful when + running a loop and the user doesn't want to rebuild the model + because it is expensive to build/initialize. + + Parameters + ---------- + mod: model where FIM prior is to be updated, Default: None, (self.model) + FIM: 2D np array to be the new FIM prior, Default: None + """ + if mod is None: + mod = self.model + + # Check FIM input + if FIM is None: + raise ValueError('FIM input for update_FIM_prior must be a 2D, square numpy array.') + + assert hasattr(mod, 'fim'), '``fim`` is not defined on the model provided. Please build the model first.' + + self.check_model_FIM(mod, FIM) + + # Update FIM prior + for ind1, p1 in enumerate(mod.parameter_names): + for ind2, p2 in enumerate(mod.parameter_names): + mod.prior_FIM[p1, p2].set_value(FIM[ind1, ind2]) + + self.logger.info('FIM prior has been updated.') + + + # ToDo: Add an update function for the parameter values? --> closed loop parameter estimation? + # Or leave this to the user????? + def udpate_unknown_parameter_values(self, mod=None, param_vals=None): + return + # Rescale FIM (a scaling function to help rescale FIM from parameter values) def rescale_FIM(self, FIM, param_vals): if isinstance(param_vals, list): From d5a9dbc8b503d27d077678a796304af26b068963 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Tue, 2 Jul 2024 09:42:31 -0400 Subject: [PATCH 025/203] Started adding full factorial exploration function. --- pyomo/contrib/doe/doe.py | 194 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 188 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index a81d4dc1d2c..8342deef7f0 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -221,9 +221,9 @@ def run_doe(self, mod=None): sp_timer.tic(msg=None) self.logger.info("Beginning experimental optimization.") - # Generate model - if self.model is None: - self.model = pyo.ConcreteModel() + # Model is none, set it to self.model + if mod is None: + mod = self.model() # ToDo: potentially work with this for more complicated models # build the large DOE pyomo model @@ -646,7 +646,7 @@ def global_design_fixing(m, s): mod.del_component(mod.base_model) # ToDo: consider this logic? Multi-block systems need something more fancy - # self._built_scenarios = True + self._built_scenarios = True # Create objective function @@ -914,8 +914,190 @@ def rescale_FIM(self, FIM, param_vals): return scaled_FIM # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) - def compute_FIM_full_factorial(self, ): - return + def compute_FIM_full_factorial(self, mod=None, design_ranges=None): + """ + Will run a simulation-based full factorial exploration of + the experimental input space. (i.e., a ``grid search`` or + ``parameter sweep`` to see how sensitive the FIM is to the + experimental design parameters). + + Parameters + ---------- + mod: model to perform the full factorial exploration on + design_ranges: dict of lists, of the form {: [upper, lower, numsteps]} + + """ + # Start timer + sp_timer = TicTocTimer() + sp_timer.tic(msg=None) + self.logger.info("Beginning Full Factorial Design.") + + # Generate model + if mod is None: + mod = self.model() + + # ToDo: potentially work with this for more complicated models + # build the large DOE pyomo model + if not self._built_scenarios: + self.create_doe_model(mod=self.model) + + + + # Solve the square problem first to initialize the fim and + # sensitivity constraints + # Deactivate object and fix experimental design decisions to make square + self.model.Obj.deactivate() + for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): + comp.fix() + + self.solver.solve(self.model, tee=self.tee) + + # Reactivate objective and unfix experimental design decisions + for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): + comp.unfix() + self.model.Obj.activate() + + # Solve the full model, which has now been initialized with the square solve + self.solver.solve(self.model, tee=self.tee) + + # Finish timing + dT = sp_timer.toc(msg=None) + self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % dT) + + # Set the Objective Function to 0 helps solve square problem quickly + self.objective_option = ObjectiveLib.zero + self.store_optimality_as_csv = store_optimality_as_csv + + # calculate how much the FIM element is scaled + self.fim_scale_constant_value = scale_constant_value**2 + + # to store all FIM results + result_combine = {} + + # all lists of values of each design variable to go over + design_ranges_list = list(design_ranges.values()) + # design variable names to go over + design_dimension_names = list(design_ranges.keys()) + + # iteration 0 + count = 0 + failed_count = 0 + # how many sets of design variables will be run + total_count = 1 + for rng in design_ranges_list: + total_count *= len(rng) + + time_set = [] # record time for every iteration + + # generate combinations of design variable values to go over + search_design_set = product(*design_ranges_list) + + # loop over design value combinations + for design_set_iter in search_design_set: + # generate the design variable dictionary needed for running compute_FIM + # first copy value from design_values + design_iter = self.design_vars.variable_names_value.copy() + + # convert to a list and cache + list_design_set_iter = list(design_set_iter) + + # update the controlled value of certain time points for certain design variables + for i, names in enumerate(design_dimension_names): + if isinstance(names, str): + # if 'names' is simply a string, copy the new value + design_iter[names] = list_design_set_iter[i] + elif isinstance(names, collections.abc.Sequence): + # if the element is a list, all design variables in this list share the same values + for n in names: + design_iter[n] = list_design_set_iter[i] + else: + # otherwise just copy the value + # design_iter[names] = list(design_set_iter)[i] + raise NotImplementedError( + "You should not see this error message. Please report it to the Pyomo.DoE developers." + ) + + self.design_vars.variable_names_value = design_iter + iter_timer = TicTocTimer() + self.logger.info("=======Iteration Number: %s =====", count + 1) + self.logger.debug( + "Design variable values of this iteration: %s", design_iter + ) + iter_timer.tic(msg=None) + # generate store name + if store_name is None: + store_output_name = None + else: + store_output_name = store_name + str(count) + + if read_name is not None: + read_input_name = read_name + str(count) + else: + read_input_name = None + + # call compute_FIM to get FIM + try: + result_iter = self.compute_FIM( + mode=mode, + tee_opt=tee_option, + scale_nominal_param_value=scale_nominal_param_value, + scale_constant_value=scale_constant_value, + store_output=store_output_name, + read_output=read_input_name, + formula=formula, + step=step, + ) + + count += 1 + + result_iter.result_analysis() + + # iteration time + iter_t = iter_timer.toc(msg=None) + time_set.append(iter_t) + + # give run information at each iteration + self.logger.info("This is run %s out of %s.", count, total_count) + self.logger.info( + "The code has run %s seconds.", round(sum(time_set), 2) + ) + self.logger.info( + "Estimated remaining time: %s seconds", + round( + sum(time_set) / (count) * (total_count - count), 2 + ), # need to check this math... it gives a negative number for the final count + ) + + if post_processing_function is not None: + # Call the post processing function + post_processing_function(self._square_model_from_compute_FIM) + + # the combined result object are organized as a dictionary, keys are a tuple of the design variable values, values are a result object + result_combine[tuple(design_set_iter)] = result_iter + + except: + self.logger.warning( + ":::::::::::Warning: Cannot converge this run.::::::::::::" + ) + count += 1 + failed_count += 1 + self.logger.warning("failed count:", failed_count) + result_combine[tuple(design_set_iter)] = None + + # For user's access + self.all_fim = result_combine + + # Create figure drawing object + figure_draw_object = GridSearchResult( + design_ranges_list, + design_dimension_names, + result_combine, + store_optimality_name=store_optimality_as_csv, + ) + + self.logger.info("Overall wall clock time [s]: %s", sum(time_set)) + + return figure_draw_object ############################## From e050d4e677984cfad0a7111edae803a14276742e Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Tue, 2 Jul 2024 12:35:46 -0400 Subject: [PATCH 026/203] Adding kaug functionality to new interface Also updated the test files and results file to match and generate the same optimal point. --- pyomo/contrib/doe/doe.py | 131 ++++++++++++++++------- pyomo/contrib/doe/redesign/result.json | 2 +- pyomo/contrib/doe/redesign/test_build.py | 19 +++- 3 files changed, 114 insertions(+), 38 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 8342deef7f0..94747b594e6 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -223,32 +223,32 @@ def run_doe(self, mod=None): # Model is none, set it to self.model if mod is None: - mod = self.model() + mod = self.model # ToDo: potentially work with this for more complicated models # build the large DOE pyomo model if not self._built_scenarios: - self.create_doe_model(mod=self.model) + self.create_doe_model(mod=mod) # Add the objective function to the model - self.create_objective_function(mod=self.model) + self.create_objective_function(mod=mod) # Solve the square problem first to initialize the fim and # sensitivity constraints # Deactivate object and fix experimental design decisions to make square - self.model.Obj.deactivate() - for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): + mod.Obj.deactivate() + for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): comp.fix() self.solver.solve(self.model, tee=self.tee) # Reactivate objective and unfix experimental design decisions - for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): + for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): comp.unfix() - self.model.Obj.activate() + mod.Obj.activate() # Solve the full model, which has now been initialized with the square solve - self.solver.solve(self.model, tee=self.tee) + self.solver.solve(mod, tee=self.tee) # Finish timing dT = sp_timer.toc(msg=None) @@ -266,14 +266,91 @@ def run_multi_doe_simultaneous(self, N_exp=1): "Multipled experiment optimization note yet supported." ) - # ToDo: Add "Update FIM" method - def update_FIM(self, ): - return - # Compute FIM for the DoE object - def compute_FIM(self, ): + def compute_FIM(self, mod=None): + return + # Use kaug to get FIM + def _direct_kaug(self): + """ + Used to compute the FIM using kaug, a sensitivity-based approach instead + of forming the finite differencing blocks. + + """ + # Make a special version of the model for kaug + self.kaug_model = self.experiment.get_labeled_model(**self.args).clone() + mod = self.kaug_model + + # Check the model labels on the kaug model + self.check_model_labels(mod=mod) + + # add zero (dummy/placeholder) objective function + mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) + + # call k_aug get_dsdp function + # Solve the square problem + # Deactivate object and fix experimental design decisions to make square + for comp, _ in mod.experiment_inputs.items(): + comp.fix() + + self.solver.solve(mod, tee=self.tee) + + # Probe the solved model for dsdp results (sensitivities s.t. parameters) + params_dict = {k.name: v for k, v in mod.unknown_parameters.items()} + params_names = list(params_dict.keys()) + + dsdp_re, col = get_dsdp( + mod, params_names, params_dict, tee=self.tee + ) + + # analyze result + dsdp_array = dsdp_re.toarray().T + + # store dsdp returned + dsdp_extract = [] + # get right lines from results + measurement_index = [] + + # loop over measurement variables and their time points + for k, v in mod.experiment_outputs.items(): + name = k.name + try: + kaug_no = col.index(name) + measurement_index.append(kaug_no) + # get right line of dsdp + dsdp_extract.append(dsdp_array[kaug_no]) + except: + # k_aug does not provide value for fixed variables + self.logger.debug("The variable is fixed: %s", name) + # produce the sensitivity for fixed variables + zero_sens = np.zeros(len(params_names)) + # for fixed variables, the sensitivity are a zero vector + dsdp_extract.append(zero_sens) + + # Extract and calculate sensitivity if scaled by constants or parameters. + jac = [[] for k in params_names] + + for d in range(len(dsdp_extract)): + for k, v in mod.unknown_parameters.items(): + p = params_names.index(k.name) # Index of parameter in np array + # if scaled by parameter value or constant value + sensi = dsdp_extract[d][p] * self.scale_constant_value + if self.scale_nominal_param_value: + sensi *= v + jac[p].append(sensi) + + # record kaug jacobian + self.kaug_jac = np.array(jac).T + + # Compute FIM + if self.prior_FIM is None: + self.prior_FIM = np.zeros((len(params_names), len(params_names))) + else: + self.check_model_FIM(FIM=self.prior_FIM) + + self.kaug_fim = self.kaug_jac.T @ self.kaug_jac + self.prior_FIM + # Create the DoE model (with ``scenarios`` from finite differencing scheme) def create_doe_model(self, mod=None): """ @@ -648,7 +725,6 @@ def global_design_fixing(m, s): # ToDo: consider this logic? Multi-block systems need something more fancy self._built_scenarios = True - # Create objective function def create_objective_function(self, mod=None): """ @@ -670,17 +746,6 @@ def create_objective_function(self, mod=None): small_number = 1e-10 # Assemble the FIM matrix. This is helpful for initialization! - # - # Suggestion from JS: "It might be more efficient to form the NP array in one shot - # (from a list or using fromatter), and then reshaping to the 2-D matrix" - # - - # fim = np.zeros((len(self.param), len(self.param))) - # for i, bu in enumerate(m.regression_parameters): - # for j, un in enumerate(m.regression_parameters): - # # Copy value from Pyomo model into numpy array - # fim[i][j] = m.fim[bu, un].value - fim_vals = [ mod.fim[bu, un].value for i, bu in enumerate(mod.parameter_names) @@ -714,8 +779,8 @@ def cholesky_imp(m, c, d): # If it is the left bottom half of L if list(mod.parameter_names).index(c) >= list(mod.parameter_names).index(d): return m.fim[c, d] == sum( - m.L_ele[c, mod.parameter_names[k + 1]] - * m.L_ele[d, mod.parameter_names[k + 1]] + m.L_ele[c, mod.parameter_names.at(k + 1)] + * m.L_ele[d, mod.parameter_names.at(k + 1)] for k in range(list(mod.parameter_names).index(d) + 1) ) else: @@ -790,7 +855,6 @@ def det_general(m): "Objective option not recognized. Please contact the developers as you should not see this error." ) - # Check to see if the model has all the required suffixes def check_model_labels(self, mod=None): """ @@ -837,8 +901,7 @@ def check_model_labels(self, mod=None): ) self.logger.info('Model has expected labels.') - - + # Check the FIM shape against what is expected from the model. def check_model_FIM(self, FIM=None): """ @@ -856,14 +919,12 @@ def check_model_FIM(self, FIM=None): self.logger.info('FIM provided matches expected dimensions from model.') - # Check the jacobian shape against what is expected from the model. def check_model_jac(self, jac=None): assert jac.shape == (self.n_experiment_outputs, self.n_parameters), "Shape of Jacobian provided should be n_experiment_outputs x n_parameters, or {}, Jacobian provided has shape: {}".format((self.n_experiment_outputs, self.n_parameters), jac.shape) self.logger.info('Jacobian provided matches expected dimensions from model.') - # Update the FIM for the specified model def update_FIM_prior(self, mod=None, FIM=None): """ @@ -894,7 +955,6 @@ def update_FIM_prior(self, mod=None, FIM=None): self.logger.info('FIM prior has been updated.') - # ToDo: Add an update function for the parameter values? --> closed loop parameter estimation? # Or leave this to the user????? def udpate_unknown_parameter_values(self, mod=None, param_vals=None): @@ -925,7 +985,7 @@ def compute_FIM_full_factorial(self, mod=None, design_ranges=None): ---------- mod: model to perform the full factorial exploration on design_ranges: dict of lists, of the form {: [upper, lower, numsteps]} - + """ # Start timer sp_timer = TicTocTimer() @@ -940,9 +1000,8 @@ def compute_FIM_full_factorial(self, mod=None, design_ranges=None): # build the large DOE pyomo model if not self._built_scenarios: self.create_doe_model(mod=self.model) - - + # Solve the square problem first to initialize the fim and # sensitivity constraints # Deactivate object and fix experimental design decisions to make square diff --git a/pyomo/contrib/doe/redesign/result.json b/pyomo/contrib/doe/redesign/result.json index b7f56011e0f..89b8056e4c3 100644 --- a/pyomo/contrib/doe/redesign/result.json +++ b/pyomo/contrib/doe/redesign/result.json @@ -1 +1 @@ -{"CA0": 1.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 300, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file +{"CA0": 1.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 56c0c744458..7e79c9fb1ff 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -71,7 +71,7 @@ def create_model(m=None, ): # Control time set [h] t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] # Define parameter nominal value -parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} +parameter_dict = {"A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} # measurement object measurements = MeasurementVariables() @@ -176,6 +176,23 @@ def create_model(m=None, ): objective_option="det", # objective option ) +# Testing the kaug runs +doe_object3 = DesignOfExperiments( + parameter_dict, # dictionary of parameters + exp_design, # design variables + measurements, # measurement variables + create_model, # function to create model + only_compute_fim_lower=True, +) + +res = doe_object3.compute_FIM() +res.result_analysis() +doe_obj[0]._direct_kaug() + +print(res.FIM) +print(doe_obj[0].kaug_fim) + + # Optimal values print("Optimal values for determinant optimized experimental design:") print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.Obj))) From 7e37cc2a1f346e697a7d4e88f15d2ae130bf6e39 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:37:07 -0400 Subject: [PATCH 027/203] Fixed k_aug method for new interface Matches the old interface --- pyomo/contrib/doe/doe.py | 20 +++++++++++++++++++- pyomo/contrib/doe/redesign/result.json | 2 +- pyomo/contrib/doe/redesign/test_build.py | 6 +++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 94747b594e6..e585edd15e3 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -240,7 +240,9 @@ def run_doe(self, mod=None): for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): comp.fix() + mod.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) self.solver.solve(self.model, tee=self.tee) + mod.dummy_obj.deactivate() # Reactivate objective and unfix experimental design decisions for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): @@ -349,7 +351,22 @@ def _direct_kaug(self): else: self.check_model_FIM(FIM=self.prior_FIM) - self.kaug_fim = self.kaug_jac.T @ self.kaug_jac + self.prior_FIM + self.kaug_fim = np.zeros((len(params_names), len(params_names))) + for p in range(len(params_names)): + for q in range(len(params_names)): + n = 0 + for k, v in mod.measurement_error.items(): + self.kaug_fim[p, q] += 1 / v * self.kaug_jac[n, p] * self.kaug_jac[n, q] + n += 1 + # sum( + # 1 + # / mod.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(mod.scenario_blocks[0])] + # * m.sensitivity_jacobian[n, p] + # * m.sensitivity_jacobian[n, q] + + # The fim expression below doesn't include measurement error. + # Can we add measurement error in a one-line matrix multiplication? + #self.kaug_fim = self.kaug_jac.T @ self.kaug_jac + self.prior_FIM # Create the DoE model (with ``scenarios`` from finite differencing scheme) def create_doe_model(self, mod=None): @@ -413,6 +430,7 @@ def initialize_jac(m, i, j): return dict_jac_initialize[(i, j)] # Otherwise initialize to 0.1 (which is an arbitrary non-zero value) else: + # Add flag as this should never be reached. return 0.1 mod.sensitivity_jacobian = pyo.Var( diff --git a/pyomo/contrib/doe/redesign/result.json b/pyomo/contrib/doe/redesign/result.json index 89b8056e4c3..7e1b1a79a1b 100644 --- a/pyomo/contrib/doe/redesign/result.json +++ b/pyomo/contrib/doe/redesign/result.json @@ -1 +1 @@ -{"CA0": 1.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file +{"CA0": 5.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 7e79c9fb1ff..07efb929622 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -115,7 +115,7 @@ def create_model(m=None, ): indices={0: t_control}, # indices of design variable time_index_position=0, # position of time index values=[ - 300, + 500, 300, 300, 300, @@ -130,7 +130,7 @@ def create_model(m=None, ): ) design_names = exp_design.variable_names -exp1 = [5, 300, 300, 300, 300, 300, 300, 300, 300, 300] +exp1 = [5, 500, 300, 300, 300, 300, 300, 300, 300, 300] exp1_design_dict = dict(zip(design_names, exp1)) exp_design.update_values(exp1_design_dict) @@ -185,7 +185,7 @@ def create_model(m=None, ): only_compute_fim_lower=True, ) -res = doe_object3.compute_FIM() +res = doe_object3.compute_FIM(scale_nominal_param_value=True) res.result_analysis() doe_obj[0]._direct_kaug() From 4930c95127901b5c57a756f6619ce8786aee05a2 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Wed, 3 Jul 2024 10:04:20 -0400 Subject: [PATCH 028/203] Simplified kaug method and added obj cons block Objective cons block are deactivated for the square solve as they can sometimes cause convergence issues. --- pyomo/contrib/doe/doe.py | 63 +++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index e585edd15e3..fddd1e3672e 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -235,8 +235,9 @@ def run_doe(self, mod=None): # Solve the square problem first to initialize the fim and # sensitivity constraints - # Deactivate object and fix experimental design decisions to make square + # Deactivate object and objective constraints, and fix design variables mod.Obj.deactivate() + mod.obj_cons.deactivate() for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): comp.fix() @@ -248,6 +249,7 @@ def run_doe(self, mod=None): for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): comp.unfix() mod.Obj.activate() + mod.obj_cons.activate() # Solve the full model, which has now been initialized with the square solve self.solver.solve(mod, tee=self.tee) @@ -269,7 +271,8 @@ def run_multi_doe_simultaneous(self, N_exp=1): ) # Compute FIM for the DoE object - def compute_FIM(self, mod=None): + def compute_FIM(self, mod=None, method='sequential'): + return @@ -351,22 +354,20 @@ def _direct_kaug(self): else: self.check_model_FIM(FIM=self.prior_FIM) - self.kaug_fim = np.zeros((len(params_names), len(params_names))) - for p in range(len(params_names)): - for q in range(len(params_names)): - n = 0 - for k, v in mod.measurement_error.items(): - self.kaug_fim[p, q] += 1 / v * self.kaug_jac[n, p] * self.kaug_jac[n, q] - n += 1 - # sum( - # 1 - # / mod.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(mod.scenario_blocks[0])] - # * m.sensitivity_jacobian[n, p] - # * m.sensitivity_jacobian[n, q] - # The fim expression below doesn't include measurement error. - # Can we add measurement error in a one-line matrix multiplication? - #self.kaug_fim = self.kaug_jac.T @ self.kaug_jac + self.prior_FIM + # Constructing the Covariance of the measurements for the FIM calculation + # The following assumes independent measurement error. + cov_y = np.zeros((len(mod.measurement_error), len(mod.measurement_error))) + count = 0 + for k, v in mod.measurement_error.items(): + cov_y[count, count] = 1 / v + count += 1 + + # ToDo: need to add a covariance matrix for measurements (sigma inverse) + # i.e., cov_y = self.cov_y or mod.cov_y + # Still deciding where this would be best. + + self.kaug_fim = self.kaug_jac.T @ cov_y @ self.kaug_jac + self.prior_FIM # Create the DoE model (with ``scenarios`` from finite differencing scheme) def create_doe_model(self, mod=None): @@ -681,7 +682,12 @@ def _generate_scenario_blocks(self, mod=None): for comp, _ in mod.base_model.experiment_inputs.items(): comp.fix() - self.solver.solve(mod.base_model, tee='True') + try: + self.solver.solve(mod.base_model, tee='True') + self.logger.info('Model from experiment solved.') + except: + raise RuntimeError('Model from experiment did not solve appropriately. Make sure the model is well-posed.') + for comp, _ in mod.base_model.experiment_inputs.items(): comp.unfix() @@ -762,6 +768,9 @@ def create_objective_function(self, mod=None): mod = self.model small_number = 1e-10 + + # Make objective block for constraints connected to objective + mod.obj_cons = pyo.Block() # Assemble the FIM matrix. This is helpful for initialization! fim_vals = [ @@ -796,9 +805,9 @@ def cholesky_imp(m, c, d): """ # If it is the left bottom half of L if list(mod.parameter_names).index(c) >= list(mod.parameter_names).index(d): - return m.fim[c, d] == sum( - m.L_ele[c, mod.parameter_names.at(k + 1)] - * m.L_ele[d, mod.parameter_names.at(k + 1)] + return mod.fim[c, d] == sum( + mod.L_ele[c, mod.parameter_names.at(k + 1)] + * mod.L_ele[d, mod.parameter_names.at(k + 1)] for k in range(list(mod.parameter_names).index(d) + 1) ) else: @@ -809,7 +818,7 @@ def trace_calc(m): """ Calculate FIM elements. Can scale each element with 1000 for performance """ - return m.trace == sum(m.fim[j, j] for j in mod.parameter_names) + return mod.trace == sum(mod.fim[j, j] for j in mod.parameter_names) def det_general(m): r"""Calculate determinant. Can be applied to FIM of any size. @@ -836,15 +845,15 @@ def det_general(m): det_perm = sum( self._sgn(list_p[d]) * sum( - m.fim[each, name_order[b]] + mod.fim[each, name_order[b]] for b, each in enumerate(mod.parameter_names) ) for d in range(len(list_p)) ) - return m.det == det_perm + return mod.det == det_perm if self.Cholesky_option and self.objective_option == ObjectiveLib.det: - mod.cholesky_cons = pyo.Constraint( + mod.obj_cons.cholesky_cons = pyo.Constraint( mod.parameter_names, mod.parameter_names, rule=cholesky_imp ) mod.Obj = pyo.Objective( @@ -855,13 +864,13 @@ def det_general(m): elif self.objective_option == ObjectiveLib.det: # if not cholesky but determinant, calculating det and evaluate the OBJ with det mod.det = pyo.Var(initialize=np.linalg.det(fim), bounds=(small_number, None)) - mod.det_rule = pyo.Constraint(rule=det_general) + mod.obj_cons.det_rule = pyo.Constraint(rule=det_general) mod.Obj = pyo.Objective(expr=pyo.log10(mod.det), sense=pyo.maximize) elif self.objective_option == ObjectiveLib.trace: # if not determinant or cholesky, calculating the OBJ with trace mod.trace = pyo.Var(initialize=np.trace(fim), bounds=(small_number, None)) - mod.trace_rule = pyo.Constraint(rule=trace_calc) + mod.obj_cons.trace_rule = pyo.Constraint(rule=trace_calc) mod.Obj = pyo.Objective(expr=pyo.log10(mod.trace), sense=pyo.maximize) elif self.objective_option == ObjectiveLib.zero: From 2f4c5bdad5614ea97899e0fcef45946a7816ba26 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Wed, 3 Jul 2024 10:39:56 -0400 Subject: [PATCH 029/203] Added compute_FIM method --- pyomo/contrib/doe/doe.py | 68 ++++++++++++++++++------ pyomo/contrib/doe/redesign/test_build.py | 4 +- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index fddd1e3672e..68555bca0eb 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -261,35 +261,73 @@ def run_doe(self, mod=None): # Perform multi-experiment doe (sequential, or ``greedy`` approach) def run_multi_doe_sequential(self, N_exp=1): raise NotImplementedError( - "Multipled experiment optimization note yet supported." + "Multipled experiment optimization not yet supported." ) # Perform multi-experiment doe (simultaneous, optimal approach) def run_multi_doe_simultaneous(self, N_exp=1): raise NotImplementedError( - "Multipled experiment optimization note yet supported." + "Multipled experiment optimization not yet supported." ) # Compute FIM for the DoE object - def compute_FIM(self, mod=None, method='sequential'): + def compute_FIM(self, method='sequential'): + """ + Computes the FIM for the experimental design that is + initialized from the experiment`s ``get_labeled_model()`` + function. + Parameters + ---------- + mod: model to compute FIM, default: None, (self.model) + method: string to specify which method should be used + options are ``kaug`` and ``sequential`` - return - - # Use kaug to get FIM - def _direct_kaug(self): """ - Used to compute the FIM using kaug, a sensitivity-based approach instead - of forming the finite differencing blocks. + self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() + + mod = self.compute_FIM_model + + self.check_model_labels(mod=mod) + + # Check FIM input, if it exists. Otherwise, set the prior_FIM attribute + if self.prior_FIM is None: + self.prior_FIM = np.zeros((len(mod.unknown_parameters), len(mod.unknown_parameters))) + else: + self.check_model_FIM(FIM=self.prior_FIM) + + # ToDo: Decide where the FIM should be saved. + if method == 'sequential': + self._sequential_FIM() + self._computed_FIM = self.sequential_FIM + elif method == 'kaug': + self._kaug_FIM() + self._computed_FIM = self.kaug_FIM + else: + raise ValueError('The method provided, {}, must be either `sequential` or `kaug`'.format(method)) + # Use a sequential method to get the FIM + def _sequential_FIM(self): """ - # Make a special version of the model for kaug - self.kaug_model = self.experiment.get_labeled_model(**self.args).clone() - mod = self.kaug_model + Used to compute the FIM using a sequential approach, + solving the model consecutively under each of the + finite difference scenarios to build the sensitivity + matrix to subsequently compute the FIM. - # Check the model labels on the kaug model - self.check_model_labels(mod=mod) + """ + raise NotImplementedError( + "Sequential FIM calculation not yet supported." + ) + + # Use kaug to get FIM + def _kaug_FIM(self): + """ + Used to compute the FIM using kaug, a sensitivity-based + approach that directly computes the FIM. + """ + mod = self.compute_FIM_model + # add zero (dummy/placeholder) objective function mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) @@ -367,7 +405,7 @@ def _direct_kaug(self): # i.e., cov_y = self.cov_y or mod.cov_y # Still deciding where this would be best. - self.kaug_fim = self.kaug_jac.T @ cov_y @ self.kaug_jac + self.prior_FIM + self.kaug_FIM = self.kaug_jac.T @ cov_y @ self.kaug_jac + self.prior_FIM # Create the DoE model (with ``scenarios`` from finite differencing scheme) def create_doe_model(self, mod=None): diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 07efb929622..171bfbbb991 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -187,10 +187,10 @@ def create_model(m=None, ): res = doe_object3.compute_FIM(scale_nominal_param_value=True) res.result_analysis() -doe_obj[0]._direct_kaug() +doe_obj[0].compute_FIM(method='kaug') print(res.FIM) -print(doe_obj[0].kaug_fim) +print(doe_obj[0].kaug_FIM) # Optimal values From f136602e232a97d37e699eda7377cb5896e02a4e Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Wed, 3 Jul 2024 10:45:56 -0400 Subject: [PATCH 030/203] Added description for rescale_FIM --- pyomo/contrib/doe/doe.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 68555bca0eb..c2ce3e525dd 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1027,6 +1027,18 @@ def udpate_unknown_parameter_values(self, mod=None, param_vals=None): # Rescale FIM (a scaling function to help rescale FIM from parameter values) def rescale_FIM(self, FIM, param_vals): + """ + Rescales the FIM based on the input and parameter vals. + It is assumed the parameter vals align with the FIM + dimensions such that (1, i) corresponds to the i-th + column or row of the FIM. + + Parameters + ---------- + FIM: 2D numpy array to be scaled + param_vals: scaling factors for the parameters + + """ if isinstance(param_vals, list): param_vals = np.array([param_vals, ]) elif isinstance(param_vals, np.ndarray): From fc6cbac2deb02605a5837430e1914b399a25d144 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Wed, 3 Jul 2024 10:54:53 -0400 Subject: [PATCH 031/203] Made compute_FIM more flexible Potentially will use this for the grid search functionality. --- pyomo/contrib/doe/doe.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index c2ce3e525dd..26ddd9a43af 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -271,7 +271,7 @@ def run_multi_doe_simultaneous(self, N_exp=1): ) # Compute FIM for the DoE object - def compute_FIM(self, method='sequential'): + def compute_FIM(self, mod=None, method='sequential'): """ Computes the FIM for the experimental design that is initialized from the experiment`s ``get_labeled_model()`` @@ -279,14 +279,14 @@ def compute_FIM(self, method='sequential'): Parameters ---------- - mod: model to compute FIM, default: None, (self.model) + mod: model to compute FIM, default: None, (self.compute_FIM_model) method: string to specify which method should be used options are ``kaug`` and ``sequential`` """ - self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() - - mod = self.compute_FIM_model + if mod is None: + self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() + mod = self.compute_FIM_model self.check_model_labels(mod=mod) @@ -298,10 +298,10 @@ def compute_FIM(self, method='sequential'): # ToDo: Decide where the FIM should be saved. if method == 'sequential': - self._sequential_FIM() + self._sequential_FIM(mod=mod) self._computed_FIM = self.sequential_FIM elif method == 'kaug': - self._kaug_FIM() + self._kaug_FIM(mod=mod) self._computed_FIM = self.kaug_FIM else: raise ValueError('The method provided, {}, must be either `sequential` or `kaug`'.format(method)) @@ -320,13 +320,21 @@ def _sequential_FIM(self): ) # Use kaug to get FIM - def _kaug_FIM(self): + def _kaug_FIM(self, mod=None): """ Used to compute the FIM using kaug, a sensitivity-based approach that directly computes the FIM. + + Parameters + ---------- + mod: model to compute FIM, default: None, (self.compute_FIM_model) """ - mod = self.compute_FIM_model + # Remake compute_FIM_model if model is None. + # compute_FIM_model needs to be the right version for function to work. + if mod is None: + self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() + mod = self.compute_FIM_model # add zero (dummy/placeholder) objective function mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) @@ -1054,9 +1062,9 @@ def rescale_FIM(self, FIM, param_vals): def compute_FIM_full_factorial(self, mod=None, design_ranges=None): """ Will run a simulation-based full factorial exploration of - the experimental input space. (i.e., a ``grid search`` or - ``parameter sweep`` to see how sensitive the FIM is to the - experimental design parameters). + the experimental input space (i.e., a ``grid search`` or + ``parameter sweep``) to understand how the FIM metrics + change as a function of the experimental design space. Parameters ---------- @@ -1069,7 +1077,7 @@ def compute_FIM_full_factorial(self, mod=None, design_ranges=None): sp_timer.tic(msg=None) self.logger.info("Beginning Full Factorial Design.") - # Generate model + # Set model as self.model if no model is provided if mod is None: mod = self.model() From 559272345ffcee39e248a4b942a0024620fccaf2 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Wed, 3 Jul 2024 12:45:44 -0400 Subject: [PATCH 032/203] Added full factorial design space exploration This function is similar to the "grid search" function from before. Plotting capabilities still need to be added. --- pyomo/contrib/doe/doe.py | 234 ++++++++--------------- pyomo/contrib/doe/redesign/test_build.py | 12 +- 2 files changed, 96 insertions(+), 150 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 26ddd9a43af..e3668d0a1fe 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -337,7 +337,8 @@ def _kaug_FIM(self, mod=None): mod = self.compute_FIM_model # add zero (dummy/placeholder) objective function - mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) + if not hasattr(mod, 'Obj'): + mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) # call k_aug get_dsdp function # Solve the square problem @@ -729,7 +730,7 @@ def _generate_scenario_blocks(self, mod=None): comp.fix() try: - self.solver.solve(mod.base_model, tee='True') + self.solver.solve(mod.base_model, tee=self.tee) self.logger.info('Model from experiment solved.') except: raise RuntimeError('Model from experiment did not solve appropriately. Make sure the model is well-posed.') @@ -1059,7 +1060,7 @@ def rescale_FIM(self, FIM, param_vals): return scaled_FIM # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) - def compute_FIM_full_factorial(self, mod=None, design_ranges=None): + def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): """ Will run a simulation-based full factorial exploration of the experimental input space (i.e., a ``grid search`` or @@ -1069,7 +1070,9 @@ def compute_FIM_full_factorial(self, mod=None, design_ranges=None): Parameters ---------- mod: model to perform the full factorial exploration on - design_ranges: dict of lists, of the form {: [upper, lower, numsteps]} + design_ranges: dict of lists, of the form {: [start, stop, numsteps]} + method: string to specify which method should be used + options are ``kaug`` and ``sequential`` """ # Start timer @@ -1077,171 +1080,104 @@ def compute_FIM_full_factorial(self, mod=None, design_ranges=None): sp_timer.tic(msg=None) self.logger.info("Beginning Full Factorial Design.") - # Set model as self.model if no model is provided - if mod is None: - mod = self.model() - - # ToDo: potentially work with this for more complicated models - # build the large DOE pyomo model - if not self._built_scenarios: - self.create_doe_model(mod=self.model) - + # Make new model for factorial design + self.factorial_model = self.experiment.get_labeled_model(**self.args).clone() + mod = self.factorial_model - # Solve the square problem first to initialize the fim and - # sensitivity constraints - # Deactivate object and fix experimental design decisions to make square - self.model.Obj.deactivate() - for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): - comp.fix() - - self.solver.solve(self.model, tee=self.tee) + # Permute the inputs to be aligned with the experiment input indicies + design_ranges_enum = {k: np.linspace(*v) for k, v in design_ranges.items()} + design_map = {ind: (k[0].name, k[0]) for ind, k in enumerate(mod.experiment_inputs.items())} - # Reactivate objective and unfix experimental design decisions - for comp, _ in self.model.scenario_blocks[0].experiment_inputs.items(): - comp.unfix() - self.model.Obj.activate() + # Make the full space + try: + valid_inputs = 0 + des_ranges = [] + for k,v in design_map.items(): + if v[0] in design_ranges_enum.keys(): + des_ranges.append(design_ranges_enum[v[0]]) + valid_inputs += 1 + assert (valid_inputs > 0) + + factorial_points = product(*des_ranges) + except: + raise ValueError('Design ranges keys must be a subset of experimental design names.') - # Solve the full model, which has now been initialized with the square solve - self.solver.solve(self.model, tee=self.tee) + # ToDo: Add more objetive types? i.e., modified-E; G-opt; V-opt; etc? + # ToDo: Also, make this a result object, or more user friendly. + fim_factorial_results = { + 'design_points': [], + 'log D-opt': [], + 'log A-opt': [], + 'log E-opt': [], + 'solve_time': [], + } - # Finish timing - dT = sp_timer.toc(msg=None) - self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % dT) - - # Set the Objective Function to 0 helps solve square problem quickly - self.objective_option = ObjectiveLib.zero - self.store_optimality_as_csv = store_optimality_as_csv - - # calculate how much the FIM element is scaled - self.fim_scale_constant_value = scale_constant_value**2 - - # to store all FIM results - result_combine = {} - - # all lists of values of each design variable to go over - design_ranges_list = list(design_ranges.values()) - # design variable names to go over - design_dimension_names = list(design_ranges.keys()) - - # iteration 0 - count = 0 - failed_count = 0 - # how many sets of design variables will be run - total_count = 1 - for rng in design_ranges_list: - total_count *= len(rng) - - time_set = [] # record time for every iteration - - # generate combinations of design variable values to go over - search_design_set = product(*design_ranges_list) - - # loop over design value combinations - for design_set_iter in search_design_set: - # generate the design variable dictionary needed for running compute_FIM - # first copy value from design_values - design_iter = self.design_vars.variable_names_value.copy() - - # convert to a list and cache - list_design_set_iter = list(design_set_iter) - - # update the controlled value of certain time points for certain design variables - for i, names in enumerate(design_dimension_names): - if isinstance(names, str): - # if 'names' is simply a string, copy the new value - design_iter[names] = list_design_set_iter[i] - elif isinstance(names, collections.abc.Sequence): - # if the element is a list, all design variables in this list share the same values - for n in names: - design_iter[n] = list_design_set_iter[i] - else: - # otherwise just copy the value - # design_iter[names] = list(design_set_iter)[i] - raise NotImplementedError( - "You should not see this error message. Please report it to the Pyomo.DoE developers." - ) - - self.design_vars.variable_names_value = design_iter + succeses = 0 + failures = 0 + total_points = np.prod(np.array([len(v) for k, v in design_ranges_enum.items()])) + time_set = [] + curr_point = 1 # Initial current point + for design_point in factorial_points: + print(design_point) + # Fix design variables at fixed experimental design point + for i in range(len(design_point)): + design_map[i][1].fix(design_point[i]) + + # Timing and logging objects + self.logger.info("=======Iteration Number: %s =====", curr_point) iter_timer = TicTocTimer() - self.logger.info("=======Iteration Number: %s =====", count + 1) - self.logger.debug( - "Design variable values of this iteration: %s", design_iter - ) iter_timer.tic(msg=None) - # generate store name - if store_name is None: - store_output_name = None - else: - store_output_name = store_name + str(count) - - if read_name is not None: - read_input_name = read_name + str(count) - else: - read_input_name = None - - # call compute_FIM to get FIM + + # Compute FIM with given options try: - result_iter = self.compute_FIM( - mode=mode, - tee_opt=tee_option, - scale_nominal_param_value=scale_nominal_param_value, - scale_constant_value=scale_constant_value, - store_output=store_output_name, - read_output=read_input_name, - formula=formula, - step=step, - ) - - count += 1 - - result_iter.result_analysis() - + curr_point = succeses + 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(mod=mod, method=method) + succeses += 1 + # iteration time iter_t = iter_timer.toc(msg=None) time_set.append(iter_t) - - # give run information at each iteration - self.logger.info("This is run %s out of %s.", count, total_count) + + # More logging self.logger.info( - "The code has run %s seconds.", round(sum(time_set), 2) + "The code has run for %s seconds.", round(sum(time_set), 2) ) self.logger.info( "Estimated remaining time: %s seconds", round( - sum(time_set) / (count) * (total_count - count), 2 - ), # need to check this math... it gives a negative number for the final count + sum(time_set) / (curr_point) * (total_points - curr_point + 1), 2 + ), ) - - if post_processing_function is not None: - # Call the post processing function - post_processing_function(self._square_model_from_compute_FIM) - - # the combined result object are organized as a dictionary, keys are a tuple of the design variable values, values are a result object - result_combine[tuple(design_set_iter)] = result_iter - except: self.logger.warning( ":::::::::::Warning: Cannot converge this run.::::::::::::" ) - count += 1 - failed_count += 1 - self.logger.warning("failed count:", failed_count) - result_combine[tuple(design_set_iter)] = None - - # For user's access - self.all_fim = result_combine - - # Create figure drawing object - figure_draw_object = GridSearchResult( - design_ranges_list, - design_dimension_names, - result_combine, - store_optimality_name=store_optimality_as_csv, - ) - - self.logger.info("Overall wall clock time [s]: %s", sum(time_set)) - - return figure_draw_object + failures += 1 + self.logger.warning("failed count:", failures) + + self._computed_FIM = np.zeros(self.prior_FIM.shape) + iter_timer.tic(msg=None) + + FIM = self._computed_FIM + + # Compute and record metrics on FIM + D_opt = np.log10(np.linalg.det(FIM)) + A_opt = np.log10(np.trace(FIM)) + E_opt = np.log10(min(np.linalg.eig(FIM)[0])) + + fim_factorial_results['design_points'].append({design_map[ind][0]: design_point[ind] for ind, _ in enumerate(design_point)}) + fim_factorial_results['log D-opt'].append(D_opt) + fim_factorial_results['log A-opt'].append(A_opt) + fim_factorial_results['log E-opt'].append(E_opt) + + self.fim_factorial_results = fim_factorial_results + # ToDo: add automated figure drawing as it was before (perhaps reuse the code) + ############################## diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 171bfbbb991..f47a0d0e2fb 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -4,6 +4,7 @@ from simple_reaction_example import * import numpy as np +import logging doe_obj = [0, 0, 0, 0,] obj = ['trace', 'det', 'det'] @@ -24,10 +25,11 @@ L_initial=None, L_LB=1e-7, solver=None, - tee=True, + tee=False, args=None, _Cholesky_option=True, _only_compute_fim_lower=True, + logger_level=logging.INFO, ) doe_obj[ind].run_doe() @@ -51,6 +53,7 @@ args=None, _Cholesky_option=True, _only_compute_fim_lower=True, + logger_level=logging.INFO, ) doe_obj[ind].model.set_blocks = pyo.Set(initialize=[0, 1, 2]) doe_obj[ind].model.block_instances = pyo.Block(doe_obj[ind].model.set_blocks) @@ -187,6 +190,13 @@ def create_model(m=None, ): res = doe_object3.compute_FIM(scale_nominal_param_value=True) res.result_analysis() + +design_ranges = { + 'CA[0]': [1, 5, 3], + 'T[0]': [300, 700, 3], +} +doe_obj[0].compute_FIM_full_factorial(design_ranges=design_ranges, method='kaug') + doe_obj[0].compute_FIM(method='kaug') print(res.FIM) From 5dd133c149b7520c577480db771181f966f26b9e Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 4 Jul 2024 12:15:16 -0400 Subject: [PATCH 033/203] Fixed Cholesky bug, added L initiailization --- pyomo/contrib/doe/doe.py | 31 +++++++++++++---- pyomo/contrib/doe/redesign/test_build.py | 44 ++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index e3668d0a1fe..24cbcd9651e 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -251,6 +251,18 @@ def run_doe(self, mod=None): mod.Obj.activate() mod.obj_cons.activate() + # ToDo: add a ``get FIM from model`` function + # If the model has L_ele, initialize it with the solved FIM + if hasattr(mod, 'L_ele'): + # Get the FIM values --> ToDo: add this as a function + fim_vals = [pyo.value(mod.fim[i, j]) for i in mod.parameter_names for j in mod.parameter_names] + fim_np = np.array(fim_vals).reshape((len(mod.parameter_names), len(mod.parameter_names))) + + L_vals_sq = np.linalg.cholesky(fim_np) + for i, c in enumerate(mod.parameter_names): + for j, d in enumerate(mod.parameter_names): + mod.L_ele[c, d].value = L_vals_sq[i, j] + # Solve the full model, which has now been initialized with the square solve self.solver.solve(mod, tee=self.tee) @@ -621,8 +633,13 @@ def fim_rule(m, p, q): p: unknown parameter q: unknown parameter """ - - if p > q: + p_ind = list(mod.parameter_names).index(p) + q_ind = list(mod.parameter_names).index(q) + + # If the row is less than the column, skip the constraint + # This logic is consistent with making the FIM a lower + # triangular matrix (as is done later in this function) + if p_ind < q_ind: if self.only_compute_fim_lower: return pyo.Constraint.Skip else: @@ -651,9 +668,9 @@ def fim_rule(m, p, q): # Fix the upper half of the FIM matrix elements to be 0.0. # This eliminates extra variables and ensures the expected number of # degrees of freedom in the optimization problem. - for p in mod.parameter_names: - for q in mod.parameter_names: - if p > q: + for ind_p, p in enumerate(mod.parameter_names): + for ind_q, q in enumerate(mod.parameter_names): + if ind_p < ind_q: mod.fim[p, q].fix(0.0) # Create scenario block structure @@ -850,7 +867,9 @@ def cholesky_imp(m, c, d): """ Calculate Cholesky L matrix using algebraic constraints """ - # If it is the left bottom half of L + # If the row is greater than or equal to the column, we are in the + # lower traingle region of the L and FIM matrices. + # This region is where our equations are well-defined. if list(mod.parameter_names).index(c) >= list(mod.parameter_names).index(d): return mod.fim[c, d] == sum( mod.L_ele[c, mod.parameter_names.at(k + 1)] diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index f47a0d0e2fb..4ca7d713cc8 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -25,7 +25,7 @@ L_initial=None, L_LB=1e-7, solver=None, - tee=False, + tee=True, args=None, _Cholesky_option=True, _only_compute_fim_lower=True, @@ -208,4 +208,44 @@ def create_model(m=None, ): print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.Obj))) print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.Obj))) print("Old formulation, scaled: {}".format(pyo.value(optimize_result.model.Obj))) -print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) \ No newline at end of file +print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) + +# Old values +FIM_vals_old = [pyo.value(optimize_result.model.fim[i, j]) for i in optimize_result.model.regression_parameters for j in optimize_result.model.regression_parameters] +L_vals_old = [pyo.value(optimize_result.model.L_ele[i, j]) for i in optimize_result.model.regression_parameters for j in optimize_result.model.regression_parameters] +Q_vals_old = [pyo.value(optimize_result.model.sensitivity_jacobian[i, j]) for i in optimize_result.model.regression_parameters for j in optimize_result.model.measured_variables] +sigma_inv_old = [1 / v for k,v in doe_object.measurement_vars.variance.items()] + +FIM_vals_old_np = np.array(FIM_vals_old).reshape((4, 4)) + +for i in range(4): + for j in range(4): + if j > i: + FIM_vals_old_np[j, i] = FIM_vals_old_np[i, j] + +L_vals_old_np = np.array(L_vals_old).reshape((4, 4)) +Q_vals_old_np = np.array(Q_vals_old).reshape((4, 27)) + +sigma_inv_old_np = np.zeros((27, 27)) +for i in range(27): + sigma_inv_old_np[i, i] = sigma_inv_old[i] + +# New values +FIM_vals_new = [pyo.value(doe_obj[1].model.fim[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] +L_vals_new = [pyo.value(doe_obj[1].model.L_ele[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] +Q_vals_new = [pyo.value(doe_obj[1].model.sensitivity_jacobian[i, j]) for i in doe_obj[1].model.output_names for j in doe_obj[1].model.parameter_names] +sigma_inv_new = [1 / v for k,v in doe_obj[1].model.scenario_blocks[0].measurement_error.items()] + +FIM_vals_new_np = np.array(FIM_vals_new).reshape((4, 4)) + +for i in range(4): + for j in range(4): + if j > i: + FIM_vals_new_np[j, i] = FIM_vals_new_np[i, j] + +L_vals_new_np = np.array(L_vals_new).reshape((4, 4)) +Q_vals_new_np = np.array(Q_vals_new).reshape((27, 4)) + +sigma_inv_new_np = np.zeros((27, 27)) +for i in range(27): + sigma_inv_new_np[i, i] = sigma_inv_new[i] \ No newline at end of file From 6724fbe6d8d7eb300e3cefa7d35e8f2208ca0780 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 5 Jul 2024 11:10:41 -0400 Subject: [PATCH 034/203] Added small check for FIM rescaling function Will probably move the FIM rescaling function to a `utils` or similar file name since the rescaling is agnostic to the DoE object. --- pyomo/contrib/doe/redesign/test_build.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 4ca7d713cc8..1f2c3f1b9b8 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -25,7 +25,7 @@ L_initial=None, L_LB=1e-7, solver=None, - tee=True, + tee=False, args=None, _Cholesky_option=True, _only_compute_fim_lower=True, @@ -235,12 +235,13 @@ def create_model(m=None, ): L_vals_new = [pyo.value(doe_obj[1].model.L_ele[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] Q_vals_new = [pyo.value(doe_obj[1].model.sensitivity_jacobian[i, j]) for i in doe_obj[1].model.output_names for j in doe_obj[1].model.parameter_names] sigma_inv_new = [1 / v for k,v in doe_obj[1].model.scenario_blocks[0].measurement_error.items()] +param_vals = np.array([[v for k, v in doe_obj[1].model.scenario_blocks[0].unknown_parameters.items()], ]) FIM_vals_new_np = np.array(FIM_vals_new).reshape((4, 4)) for i in range(4): for j in range(4): - if j > i: + if j < i: FIM_vals_new_np[j, i] = FIM_vals_new_np[i, j] L_vals_new_np = np.array(L_vals_new).reshape((4, 4)) @@ -248,4 +249,20 @@ def create_model(m=None, ): sigma_inv_new_np = np.zeros((27, 27)) for i in range(27): - sigma_inv_new_np[i, i] = sigma_inv_new[i] \ No newline at end of file + sigma_inv_new_np[i, i] = sigma_inv_new[i] + +rescaled_FIM = doe_obj[1].rescale_FIM(FIM_vals_new_np, param_vals) + +# Comparing values from compute FIM +print("Results from using compute FIM (first old, then new)") +print(res.FIM) +print(doe_obj[0].kaug_FIM) + + +# Optimal values +print("Optimal values for determinant optimized experimental design:") +print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.Obj))) +print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.Obj))) +print("New formulation, rescaled: {}".format(np.log10(np.linalg.det(rescaled_FIM)))) +print("Old formulation, scaled: {}".format(pyo.value(optimize_result.model.Obj))) +print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) \ No newline at end of file From d98ce6aadbbcb3eb531e4d947a7e5724f45d83fa Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 5 Jul 2024 12:24:57 -0400 Subject: [PATCH 035/203] Added sequential compute_FIM method. The FIM output of both methods is quite different but the determinant value is similar. We are looking into this to see if the method is computed incorrectly. --- pyomo/contrib/doe/doe.py | 111 +++++++++++++++++++++-- pyomo/contrib/doe/redesign/test_build.py | 5 + 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 24cbcd9651e..6ab5e9c93e1 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -104,7 +104,7 @@ def __init__( labeled sets: ``unknown_parameters``, ``experimental_inputs``, ``experimental_outputs`` fd_formula: Finite difference formula for computing the sensitivy matrix. Must be one of - [``central``, ``forward``, ``backward``] + [``central``, ``forward``, ``backward``], default: ``central`` step: Relative step size for the finite difference formula. default: 1e-3 @@ -311,7 +311,7 @@ def compute_FIM(self, mod=None, method='sequential'): # ToDo: Decide where the FIM should be saved. if method == 'sequential': self._sequential_FIM(mod=mod) - self._computed_FIM = self.sequential_FIM + self._computed_FIM = self.seq_FIM elif method == 'kaug': self._kaug_FIM(mod=mod) self._computed_FIM = self.kaug_FIM @@ -319,7 +319,7 @@ def compute_FIM(self, mod=None, method='sequential'): raise ValueError('The method provided, {}, must be either `sequential` or `kaug`'.format(method)) # Use a sequential method to get the FIM - def _sequential_FIM(self): + def _sequential_FIM(self, mod=None): """ Used to compute the FIM using a sequential approach, solving the model consecutively under each of the @@ -327,9 +327,105 @@ def _sequential_FIM(self): matrix to subsequently compute the FIM. """ - raise NotImplementedError( - "Sequential FIM calculation not yet supported." + # Build a singular model instance + if mod is None: + self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() + mod = self.compute_FIM_model + + # Create suffix to keep track of parameter scenarios + mod.parameter_scenarios = pyo.Suffix( + direction=pyo.Suffix.LOCAL, ) + + # Populate parameter scenarios, and scenario inds based on finite difference scheme + if self.fd_formula == FiniteDifferenceStep.central: + mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.unknown_parameters.keys())) + mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) + mod.scenarios = range(len(mod.unknown_parameters) * 2) + elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: + mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) + mod.scenarios = range(len(mod.unknown_parameters) + 1) + else: + # To-Do: add an error message for this as not being implemented yet + pass + + measurement_vals = [] + # In a loop..... + # Calculate measurement values for each scenario + for s in mod.scenarios: + param = mod.parameter_scenarios[s] + + # Perturbation to be (1 + diff) * param_value + if self.fd_formula == FiniteDifferenceStep.central: + diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd + elif self.fd_formula == FiniteDifferenceStep.backward: + diff = self.step * -1 * (s != 0) # Backward always negative perturbation; 0 at s = 0 + elif self.fd_formula == FiniteDifferenceStep.forward: + diff = self.step * (s != 0) # Forward always positive; 0 at s = 0 + else: + raise DeveloperError( + "Finite difference option not recognized. Please contact the developers as you should not see this error." + ) + diff = 0 + pass + + # Update parameter values for the given finite difference scenario + param.set_value(mod.unknown_parameters[param] * (1 + diff)) + + param.pprint() + + # Simulate the model + self.solver.solve(mod) + + # Extract the measurement values for the scenario and append + measurement_vals.append([pyo.value(k) for k, v in mod.experiment_outputs.items()]) + + # Use the measurement outputs to make the Q matrix + measurement_vals_np = np.array(measurement_vals).T + + self.seq_jac = np.zeros((len(mod.experiment_outputs.items()), len(mod.unknown_parameters.items()))) + + # Counting variable for loop + i = 0 + + # Loop over parameter values and grab correct columns for finite difference calculation + + for k, v in mod.unknown_parameters.items(): + curr_step = v * self.step + + if self.fd_formula == FiniteDifferenceStep.central: + col_1 = 2*i + col_2 = 2*i + 1 + curr_step *= 2 + elif self.fd_formula == FiniteDifferenceStep.forward: + col_1 = i + col_2 = 0 + elif self.fd_formula == FiniteDifferenceStep.backward: + col_1 = 0 + col_2 = i + + k.pprint() + print(curr_step) + + # If scale_nominal_param_value is False, v ** 0 = 1 (not scaled with parameter value) + scale_factor = (1 / curr_step) * self.scale_constant_value * (v ** self.scale_nominal_param_value) + + # Calculate the column of the sensitivity matrix + self.seq_jac[:, i] = (measurement_vals_np[:, col_1] - measurement_vals_np[:, col_2]) * scale_factor + + # Increment the count + i += 1 + + # ToDo: As more complex measurement error schemes are put in place, this needs to change + # Add independent (non-correlated) measurement error for FIM calculation + cov_y = np.zeros((len(mod.measurement_error), len(mod.measurement_error))) + count = 0 + for k, v in mod.measurement_error.items(): + cov_y[count, count] = 1 / v + count += 1 + + # Compute and record FIM + self.seq_FIM = self.seq_jac.T @ cov_y @ self.seq_jac + self.prior_FIM # Use kaug to get FIM def _kaug_FIM(self, mod=None): @@ -737,8 +833,9 @@ def _generate_scenario_blocks(self, mod=None): mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) mod.scenarios = range(len(mod.base_model.unknown_parameters) + 1) else: - # To-Do: add an error message for this as not being implemented yet - pass + raise DeveloperError( + "Finite difference option not recognized. Please contact the developers as you should not see this error." + ) # To-Do: Fix parameter values if they are not Params? diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 1f2c3f1b9b8..005e1d8731c 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -199,6 +199,8 @@ def create_model(m=None, ): doe_obj[0].compute_FIM(method='kaug') +doe_obj[0].compute_FIM(method='sequential') + print(res.FIM) print(doe_obj[0].kaug_FIM) @@ -257,6 +259,9 @@ def create_model(m=None, ): print("Results from using compute FIM (first old, then new)") print(res.FIM) print(doe_obj[0].kaug_FIM) +print(doe_obj[0].seq_FIM) +print(np.log10(np.linalg.det(doe_obj[0].kaug_FIM))) +print(np.log10(np.linalg.det(doe_obj[0].seq_FIM))) # Optimal values From 1b9b08f435dea7178dcb9a7ed1a12d57651dd36f Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 5 Jul 2024 14:22:46 -0400 Subject: [PATCH 036/203] Updated grid search Made each experimental design to have its own dict key. This way the dictionary can be directly translated to a pandas dataframe. --- pyomo/contrib/doe/doe.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 6ab5e9c93e1..b46c1ba8b75 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1220,13 +1220,8 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): # ToDo: Add more objetive types? i.e., modified-E; G-opt; V-opt; etc? # ToDo: Also, make this a result object, or more user friendly. - fim_factorial_results = { - 'design_points': [], - 'log D-opt': [], - 'log A-opt': [], - 'log E-opt': [], - 'solve_time': [], - } + fim_factorial_results = {k.name: [] for k, v in mod.experiment_inputs.items()} + fim_factorial_results.update({'log D-opt': [], 'log A-opt': [], 'log E-opt': [], 'solve_time': [], }) succeses = 0 failures = 0 @@ -1234,7 +1229,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): time_set = [] curr_point = 1 # Initial current point for design_point in factorial_points: - print(design_point) + # Fix design variables at fixed experimental design point for i in range(len(design_point)): design_map[i][1].fix(design_point[i]) @@ -1286,10 +1281,14 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): A_opt = np.log10(np.trace(FIM)) E_opt = np.log10(min(np.linalg.eig(FIM)[0])) - fim_factorial_results['design_points'].append({design_map[ind][0]: design_point[ind] for ind, _ in enumerate(design_point)}) + # Append the values for each of the experiment inputs + for k, v in mod.experiment_inputs.items(): + fim_factorial_results[k.name].append(pyo.value(k)) + fim_factorial_results['log D-opt'].append(D_opt) fim_factorial_results['log A-opt'].append(A_opt) fim_factorial_results['log E-opt'].append(E_opt) + fim_factorial_results['solve_time'].append(time_set[-1]) self.fim_factorial_results = fim_factorial_results # ToDo: add automated figure drawing as it was before (perhaps reuse the code) From 14ee13280bf79e744397d9a4b470f50ee1e8f00a Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 5 Jul 2024 14:24:02 -0400 Subject: [PATCH 037/203] Made the full factorial return the data structure --- pyomo/contrib/doe/doe.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index b46c1ba8b75..fe32d3caadd 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1291,6 +1291,8 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): fim_factorial_results['solve_time'].append(time_set[-1]) self.fim_factorial_results = fim_factorial_results + + return self.fim_factorial_results # ToDo: add automated figure drawing as it was before (perhaps reuse the code) From e2f16d0c67ea8e233f2e5f0b8fa9f50261f105a4 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 5 Jul 2024 15:42:54 -0400 Subject: [PATCH 038/203] Added results object Also added the retrieval functions for populating the results object. --- pyomo/contrib/doe/doe.py | 220 ++++++++++++++++++++++- pyomo/contrib/doe/redesign/test_build.py | 4 +- 2 files changed, 220 insertions(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index fe32d3caadd..2b4bae5c38c 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -41,6 +41,8 @@ import collections.abc import inspect +import json +from pathlib import Path from pyomo.common import DeveloperError @@ -210,12 +212,27 @@ def __init__( # model attribute to avoid rebuilding models self.model = pyo.ConcreteModel() # Build empty model + # Empty results object + self.results = {} + # May need this attribute for more complicated structures? # (i.e., no model rebuilding for large models with sequential) self._built_scenarios = False # Perform doe - def run_doe(self, mod=None): + def run_doe(self, mod=None, results_file=None): + """ + Runs DoE for a single experiment estimation. Can save results in + a file based on the flag. + + Parameters + ---------- + mod: model to run the DoE, default: None (self.model) + results_file: string name of the file path to save the results + to in the form of a .json file + default: None --> don't save + + """ # Start timer sp_timer = TicTocTimer() sp_timer.tic(msg=None) @@ -266,6 +283,31 @@ def run_doe(self, mod=None): # Solve the full model, which has now been initialized with the square solve self.solver.solve(mod, tee=self.tee) + # ToDo: Make this more complicated? --> Should results be an object? Or just a dict? + # Populate results object; Important info: FIM, Q, outputs, inputs, param values, + # measurement error, prior FIM, + fim_local = self.get_FIM() + self.results['FIM'] = fim_local + self.results['Sensitivity Matrix'] = self.get_sensitivity_matrix() + self.results['Experiment Design'] = self.get_experiment_input_values() + self.results['Experiment Outputs'] = self.get_experiment_output_values() + self.results['Unknown Parameters'] = self.get_unknown_parameter_values() + self.results['Measurement Error'] = self.get_measurement_error_values() + + self.results['Prior FIM'] = [list(row) for row in list(self.prior_FIM)] + + # Saving some stats on the FIM for convenience + self.results['log10 A-opt'] = np.log10(np.trace(fim_local)) + self.results['log10 D-opt'] = np.log10(np.linalg.det(fim_local)) + self.results['log10 E-opt'] = np.log10(min(np.linalg.eig(fim_local)[0])) + self.results['FIM Condition Number'] = np.linalg.cond(fim_local) + + # If the user specifies to save the file, do it here as a json + if results_file is not None: + assert type(results_file) in [Path, str], "`results_file` must be either a Path object or a string." + with open(results_file, 'w') as file: + json.dump(self.results, file) + # Finish timing dT = sp_timer.toc(msg=None) self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % dT) @@ -295,6 +337,9 @@ def compute_FIM(self, mod=None, method='sequential'): method: string to specify which method should be used options are ``kaug`` and ``sequential`` + Returns + ------- + computed FIM: 2D numpy array of the FIM """ if mod is None: self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() @@ -317,6 +362,8 @@ def compute_FIM(self, mod=None, method='sequential'): self._computed_FIM = self.kaug_FIM else: raise ValueError('The method provided, {}, must be either `sequential` or `kaug`'.format(method)) + + return self._computed_FIM # Use a sequential method to get the FIM def _sequential_FIM(self, mod=None): @@ -1054,6 +1101,7 @@ def check_model_labels(self, mod=None): Parameters ---------- mod: model for suffix checking, Default: None, (self.model) + """ if mod is None: mod = self.model.base_model @@ -1292,10 +1340,178 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): self.fim_factorial_results = fim_factorial_results - return self.fim_factorial_results # ToDo: add automated figure drawing as it was before (perhaps reuse the code) + return self.fim_factorial_results + + + # Gets the FIM from an existing model + def get_FIM(self, mod=None): + """ + Gets the FIM values from the model specified + + Parameters + ---------- + mod: model to grab FIM from, Default: None, (self.model) + + Returns + ------- + FIM: 2D list representation of the FIM (can be cast to numpy) + + """ + if mod is None: + mod = self.model + assert hasattr(mod, 'fim'), "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" + + fim_vals = [pyo.value(mod.fim[i, j]) for i in mod.parameter_names for j in mod.parameter_names] + fim_np = np.array(fim_vals).reshape((len(mod.parameter_names), len(mod.parameter_names))) + + # FIM is a lower triangular matrix for the optimal DoE problem. + # Exploit symmetry to fill in the zeros. + for i in range(4): + for j in range(4): + if j < i: + fim_np[j, i] = fim_np[i, j] + + return [list(row) for row in list(fim_np)] + + # Gets the sensitivity matrix from an existing model + def get_sensitivity_matrix(self, mod=None): + """ + Gets the sensitivity matrix (Q) values from the model specified. + + Parameters + ---------- + mod: model to grab Q from, Default: None, (self.model) + + Returns + ------- + Q: 2D list representation of the sensitivity matrix (can be cast to numpy) + + """ + if mod is None: + mod = self.model + + assert hasattr(mod, 'sensitivity_jacobian'), "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" + + Q_vals = [pyo.value(mod.sensitivity_jacobian[i, j]) for i in mod.output_names for j in mod.parameter_names] + Q_np = np.array(Q_vals).reshape((len(mod.output_names), len(mod.parameter_names))) + return [list(row) for row in list(Q_np)] + + # Gets the experiment input values from an existing model + def get_experiment_input_values(self, mod=None): + """ + Gets the experiment input values (experimental design) + from the model specified. + + Parameters + ---------- + mod: model to grab the experimental design from, + default: None, (self.model) + + Returns + ------- + d: 1D list of experiment input values (optimal or specified design) + + """ + if mod is None: + mod = self.model + + if not hasattr(mod, 'experiment_inputs'): + assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + d_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].experiment_inputs.items()] + else: + d_vals = [pyo.value(k) for k, v in mod.experiment_inputs.items()] + + return d_vals + + # Gets the unknown parameter values from an existing model + def get_unknown_parameter_values(self, mod=None): + """ + Gets the unknown parameter values (theta) + from the model specified. + + Parameters + ---------- + mod: model to grab theta from, + default: None, (self.model) + + Returns + ------- + theta: 1D list of unknown parameter values at which this experiment was designed + + """ + if mod is None: + mod = self.model + + if not hasattr(mod, 'unknown_parameters'): + assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + theta_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].unknown_parameters.items()] + else: + theta_vals = [pyo.value(k) for k, v in mod.unknown_parameters.items()] + + return theta_vals + + # Gets the experiment output values from an existing model + def get_experiment_output_values(self, mod=None): + """ + Gets the experiment output values (y hat) + from the model specified. + + Parameters + ---------- + mod: model to grab y hat from, + default: None, (self.model) + + Returns + ------- + y_hat: 1D list of experiment output values from the design experiment + + """ + if mod is None: + mod = self.model + + if not hasattr(mod, 'experiment_outputs'): + assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + y_hat_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].measurement_error.items()] + else: + y_hat_vals = [pyo.value(k) for k, v in mod.measurement_error.items()] + + return y_hat_vals + + # ToDo: For more complicated error structures, this should become + # get cov_y, or so, and this method will be deprecated + # Gets the measurement error values from an existing model + def get_measurement_error_values(self, mod=None): + """ + Gets the experiment output values (sigma) + from the model specified. + + Parameters + ---------- + mod: model to grab sigma values from, + default: None, (self.model) + + Returns + ------- + sigma_diag: 1D list of measurement errors used to design the experiment + + """ + if mod is None: + mod = self.model + + if not hasattr(mod, 'measurement_error'): + assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + sigma_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].measurement_error.items()] + else: + sigma_vals = [pyo.value(k) for k, v in mod.measurement_error.items()] + + return sigma_vals ############################## # Below is deprecated code # diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 005e1d8731c..8777c7a9703 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -8,9 +8,9 @@ doe_obj = [0, 0, 0, 0,] obj = ['trace', 'det', 'det'] +file_name = ['trash1.json', 'trash2.json', 'trash3.json'] for ind, fd in enumerate(['central', 'backward', 'forward']): - print(fd) experiment = FullReactorExperiment(data_ex, 10, 3) doe_obj[ind] = DesignOfExperiments_( experiment, @@ -31,7 +31,7 @@ _only_compute_fim_lower=True, logger_level=logging.INFO, ) - doe_obj[ind].run_doe() + doe_obj[ind].run_doe(results_file=file_name[ind]) ind = 3 From 08a963099794970bf5f48870c4eee6bd71f74bb4 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Sat, 6 Jul 2024 14:20:10 -0400 Subject: [PATCH 039/203] Fixed bug in sequential compute FIM --- pyomo/contrib/doe/doe.py | 17 +++++++------ pyomo/contrib/doe/redesign/test_build.py | 31 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 2b4bae5c38c..c870de3cd5e 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -77,7 +77,7 @@ def __init__( fd_formula="central", step=1e-3, objective_option='det', - scale_constant_value=1, + scale_constant_value=1.0, scale_nominal_param_value=False, prior_FIM=None, jac_initial=None, @@ -396,6 +396,10 @@ def _sequential_FIM(self, mod=None): # To-Do: add an error message for this as not being implemented yet pass + # Fix design variables + for comp, _ in mod.experiment_inputs.items(): + comp.fix() + measurement_vals = [] # In a loop..... # Calculate measurement values for each scenario @@ -419,8 +423,6 @@ def _sequential_FIM(self, mod=None): # Update parameter values for the given finite difference scenario param.set_value(mod.unknown_parameters[param] * (1 + diff)) - param.pprint() - # Simulate the model self.solver.solve(mod) @@ -451,11 +453,10 @@ def _sequential_FIM(self, mod=None): col_1 = 0 col_2 = i - k.pprint() - print(curr_step) - - # If scale_nominal_param_value is False, v ** 0 = 1 (not scaled with parameter value) - scale_factor = (1 / curr_step) * self.scale_constant_value * (v ** self.scale_nominal_param_value) + # If scale_nominal_param_value is active, scale by nominal parameter value (v) + scale_factor = (1.0 / curr_step) * self.scale_constant_value + if self.scale_nominal_param_value: + scale_factor *= v # Calculate the column of the sensitivity matrix self.seq_jac[:, i] = (measurement_vals_np[:, col_1] - measurement_vals_np[:, col_2]) * scale_factor diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 8777c7a9703..14a9016e49a 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -262,6 +262,37 @@ def create_model(m=None, ): print(doe_obj[0].seq_FIM) print(np.log10(np.linalg.det(doe_obj[0].kaug_FIM))) print(np.log10(np.linalg.det(doe_obj[0].seq_FIM))) +A = doe_obj[0].kaug_jac +B = doe_obj[0].seq_jac +C = np.array(doe_obj[0].jac_debug) +print(np.sum((A - B) ** 2)) +print(np.sum((A - C) ** 2)) +print(np.sum((B - C) ** 2)) + +measurement_vals_model = [] +meas_from_model = [] +mod = doe_obj[0].model +for p in mod.parameter_names: + fd_step_mult = 1 + param_ind = mod.parameter_names.data().index(p) + + # Different FD schemes lead to different scenarios for the computation + if doe_obj[0].fd_formula == FiniteDifferenceStep.central: + s1 = param_ind * 2 + s2 = param_ind * 2 + 1 + fd_step_mult = 2 + elif doe_obj[0].fd_formula == FiniteDifferenceStep.forward: + s1 = param_ind + 1 + s2 = 0 + elif doe_obj[0].fd_formula == FiniteDifferenceStep.backward: + s1 = 0 + s2 = param_ind + 1 + + var_up = [pyo.value(k) for k, v in mod.scenario_blocks[s1].experiment_outputs.items()] + var_lo = [pyo.value(k) for k, v in mod.scenario_blocks[s2].experiment_outputs.items()] + + meas_from_model.append(var_up) + meas_from_model.append(var_lo) # Optimal values From 5ba54c8220a3d76cde89f78806d5707d6a48fcd6 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Sat, 6 Jul 2024 17:47:08 -0400 Subject: [PATCH 040/203] Refactored factorial design plotting function Also added a utils module to hold agnostic tasks (e.g. rescaling the FIM) --- pyomo/contrib/doe/__init__.py | 1 + pyomo/contrib/doe/doe.py | 433 +++++++++++++++++++++-- pyomo/contrib/doe/redesign/test_build.py | 14 +- pyomo/contrib/doe/utils.py | 53 +++ 4 files changed, 466 insertions(+), 35 deletions(-) create mode 100644 pyomo/contrib/doe/utils.py diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index a4c4b732343..bea94e4ace0 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -12,3 +12,4 @@ from .doe import DesignOfExperiments, CalculationMode, ObjectiveLib, ModelOptionLib, DesignOfExperiments_ from .scenario import ScenarioGenerator, FiniteDifferenceStep from .result import FisherResults, GridSearchResult +from .utils import rescale_FIM \ No newline at end of file diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index c870de3cd5e..212cf530842 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -26,7 +26,7 @@ # ___________________________________________________________________________ -from pyomo.common.dependencies import numpy as np, numpy_available +from pyomo.common.dependencies import numpy as np, numpy_available, pandas as pd, matplotlib as plt import pyomo.environ as pyo from pyomo.opt import SolverFactory @@ -1199,31 +1199,6 @@ def update_FIM_prior(self, mod=None, FIM=None): def udpate_unknown_parameter_values(self, mod=None, param_vals=None): return - # Rescale FIM (a scaling function to help rescale FIM from parameter values) - def rescale_FIM(self, FIM, param_vals): - """ - Rescales the FIM based on the input and parameter vals. - It is assumed the parameter vals align with the FIM - dimensions such that (1, i) corresponds to the i-th - column or row of the FIM. - - Parameters - ---------- - FIM: 2D numpy array to be scaled - param_vals: scaling factors for the parameters - - """ - if isinstance(param_vals, list): - param_vals = np.array([param_vals, ]) - elif isinstance(param_vals, np.ndarray): - if len(param_vals.shape) > 2 or ((len(param_vals.shape) == 2) and (param_vals.shape[0] != 1)): - raise ValueError('param_vals should be a vector of dimensions (1, n_params). The shape you provided is {}.'.format(param_vals.shape)) - if len(param_vals.shape) == 1: - param_vals = np.array([param_vals, ]) - scaling_mat = (1 / param_vals).transpose().dot((1 / param_vals)) - scaled_FIM = np.multiply(FIM, scaling_mat) - return scaled_FIM - # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): """ @@ -1270,7 +1245,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): # ToDo: Add more objetive types? i.e., modified-E; G-opt; V-opt; etc? # ToDo: Also, make this a result object, or more user friendly. fim_factorial_results = {k.name: [] for k, v in mod.experiment_inputs.items()} - fim_factorial_results.update({'log D-opt': [], 'log A-opt': [], 'log E-opt': [], 'solve_time': [], }) + fim_factorial_results.update({'log10 D-opt': [], 'log10 A-opt': [], 'log10 E-opt': [], 'log10 ME-opt': [], 'solve_time': [], }) succeses = 0 failures = 0 @@ -1329,14 +1304,19 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): D_opt = np.log10(np.linalg.det(FIM)) A_opt = np.log10(np.trace(FIM)) E_opt = np.log10(min(np.linalg.eig(FIM)[0])) + # ToDo: Make this complex check bit more intuitive + if np.iscomplex(E_opt): + E_opt = 0.0 + ME_opt = np.log10(np.linalg.cond(FIM)) # Append the values for each of the experiment inputs for k, v in mod.experiment_inputs.items(): fim_factorial_results[k.name].append(pyo.value(k)) - fim_factorial_results['log D-opt'].append(D_opt) - fim_factorial_results['log A-opt'].append(A_opt) - fim_factorial_results['log E-opt'].append(E_opt) + fim_factorial_results['log10 D-opt'].append(D_opt) + fim_factorial_results['log10 A-opt'].append(A_opt) + fim_factorial_results['log10 E-opt'].append(E_opt) + fim_factorial_results['log10 ME-opt'].append(ME_opt) fim_factorial_results['solve_time'].append(time_set[-1]) self.fim_factorial_results = fim_factorial_results @@ -1345,6 +1325,399 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): return self.fim_factorial_results + # Plotting + def draw_factorial_figure( + self, + results=None, + sensitivity_design_variables=None, + fixed_design_variables=None, + full_design_variable_names=None, + title_text=None, + xlabel_text=None, + ylabel_text=None, + figure_file_name=None, + font_axes=16, + font_tick=14, + log_scale=True, + ): + """ + Extract results needed for drawing figures from the results dictionary provided by + the ``compute_FIM_full_factorial`` function. + + Draw either the 1D sensitivity curve or 2D heatmap. + + Parameters + ---------- + results: dictionary, results dictionary from ``compute_FIM_full_factorial``, default: None (self.fim_factorial_results) + sensitivity_design_variables: a list, design variable names to draw sensitivity + fixed_design_variables: a dictionary, keys are the design variable names to be fixed, values are the value of it to be fixed. + full_design_variable_names: a list, all the design variables in the problem. + title_text: a string, name for the figure + xlabel_text: a string, label for the x-axis of the figure (default: last design variable name) + In a 1D sensitivity curve, it should be design variable by which the curve is drawn. + In a 2D heatmap, it should be the second design variable in the design_ranges + ylabel_text: a string, label for the y-axis of the figure (default: None (1D); first design variable name (2D)) + A 1D sensitivity curve does not need it. In a 2D heatmap, it should be the first design variable in the dv_ranges + figure_file_name: string or Path, path to save the figure as + font_axes: axes label font size + font_tick: tick label font size + log_scale: if True, the result matrix will be scaled by log10 + + """ + if results is None: + assert hasattr(self, 'fim_factorial_results'), "Results must be provided or the compute_FIM_full_factorial function must be run." + results = self.fim_factorial_results + full_design_variable_names = [k.name for k, v in self.factorial_model.experiment_inputs.items()] + else: + assert full_design_variable_names is not None, "If results object is provided, you must include all the design variable names." + + des_names = full_design_variable_names + + # Inputs must exist for the function to do anything + # ToDo: Put in a default value function????? + assert (sensitivity_design_variables is not None), "``sensitivity_design_variables`` must be included." + assert (fixed_design_variables is not None), "``sensitivity_design_variables`` must be included." + + # Check that the provided design variables are within the results object + check_des_vars = True + for k,v in fixed_design_variables.items(): + check_des_vars *= (k in [k for k,v in results.items()]) + check_sens_vars = True + for k in sensitivity_design_variables: + check_sens_vars *= (k in [k for k,v in results.items()]) + + assert (check_des_vars), "Fixed design variables {} do not all appear in the results object keys {}.".format(fixed_design_variables.keys(), results.keys()) + assert (check_sens_vars), "Sensitivity design variables {} do not all appear in the results object keys {}.".format(sensitivity_design_variables.keys(), results.keys()) + + # ToDo: Make it possible to plot pair-wise sensitivities for all variables + # e.g. a curve like low-dimensional posterior distributions + if len(sensitivity_design_variables) > 2: + raise NotImplementedError( + "Currently, only 1D and 2D sensitivity plotting is supported." + ) + + if len(fixed_design_variables.keys()) + len(sensitivity_design_variables) != len( + des_names + ): + raise ValueError( + "Error: All design variables that are not used to generate sensitivity plots must be fixed." + ) + + if type(results) is dict: + results_pd = pd.DataFrame(results) + else: + results_pd = results + + # generate a combination of logic sentences to filter the results of the DOF needed. + # an example filter: (self.store_all_results_dataframe["CA0"]==5). + if len(fixed_design_variables.keys()) != 0: + filter = "" + i = 0 + for k, v in fixed_design_variables.items(): + filter += "(results_pd['" + filter += str(k) + filter += "']==" + filter += str(v) + filter += ")" + if i < (len(fixed_design_variables.keys()) - 1): + filter += "&" + i += 1 + # extract results with other dimensions fixed + print(filter) + figure_result_data = results_pd.loc[eval(filter)] + + # if there is no other fixed dimensions + else: + figure_result_data = results_pd + + # Add attributes for drawing figures in later functions + self.figure_result_data = figure_result_data + self.figure_sens_des_vars = sensitivity_design_variables + self.figure_fixed_des_vars = fixed_design_variables + + # ToDo: Add figure saving capabilities + if figure_file_name is not None: + self.logger.warning('File saving for drawing is not yet implemented.') + + # if one design variable name is given as DOF, draw 1D sensitivity curve + if len(self.figure_sens_des_vars) == 1: + self._curve1D( + title_text, + xlabel_text, + font_axes=font_axes, + font_tick=font_tick, + log_scale=log_scale, + figure_file_name=figure_file_name, + ) + # if two design variable names are given as DOF, draw 2D heatmaps + elif len(self.figure_sens_des_vars) == 2: + self._heatmap( + title_text, + xlabel_text, + ylabel_text, + font_axes=font_axes, + font_tick=font_tick, + log_scale=log_scale, + figure_file_name=figure_file_name, + ) + # ToDo: Add the multidimensional plotting + else: + pass + + def _curve1D( + self, title_text, xlabel_text, font_axes=16, font_tick=14, figure_file_name=None, log_scale=True + ): + """ + Draw 1D sensitivity curves for all design criteria + + Parameters + ---------- + title_text: name of the figure, a string + xlabel_text: x label title, a string. + In a 1D sensitivity curve, it is the design variable by which the curve is drawn. + font_axes: axes label font size + font_tick: tick label font size + log_scale: if True, the result matrix will be scaled by log10 + + Returns + -------- + 4 Figures of 1D sensitivity curves for each criteria + """ + + # extract the range of the DOF design variable + x_range = self.figure_result_data[self.figure_sens_des_vars[0]].values.tolist() + + # decide if the results are log scaled + if log_scale: + y_range_A = np.log10(self.figure_result_data["log10 A-opt"].values.tolist()) + y_range_D = np.log10(self.figure_result_data["log10 D-opt"].values.tolist()) + y_range_E = np.log10(self.figure_result_data["log10 E-opt"].values.tolist()) + y_range_ME = np.log10(self.figure_result_data["log10 ME-opt"].values.tolist()) + else: + y_range_A = self.figure_result_data["log10 A-opt"].values.tolist() + y_range_D = self.figure_result_data["log10 D-opt"].values.tolist() + y_range_E = self.figure_result_data["log10 E-opt"].values.tolist() + y_range_ME = self.figure_result_data["log10 ME-opt"].values.tolist() + + # Draw A-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + # plt.rcParams.update(params) + ax.plot(x_range, y_range_A) + ax.scatter(x_range, y_range_A) + ax.set_ylabel("$log_{10}$ Trace") + ax.set_xlabel(xlabel_text) + plt.pyplot.title(title_text + ": A-optimality") + plt.pyplot.show() + + # Draw D-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + # plt.rcParams.update(params) + ax.plot(x_range, y_range_D) + ax.scatter(x_range, y_range_D) + ax.set_ylabel("$log_{10}$ Determinant") + ax.set_xlabel(xlabel_text) + plt.pyplot.title(title_text + ": D-optimality") + plt.pyplot.show() + + # Draw E-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + # plt.rcParams.update(params) + ax.plot(x_range, y_range_E) + ax.scatter(x_range, y_range_E) + ax.set_ylabel("$log_{10}$ Minimal eigenvalue") + ax.set_xlabel(xlabel_text) + plt.pyplot.title(title_text + ": E-optimality") + plt.pyplot.show() + + # Draw Modified E-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + # plt.rcParams.update(params) + ax.plot(x_range, y_range_ME) + ax.scatter(x_range, y_range_ME) + ax.set_ylabel("$log_{10}$ Condition number") + ax.set_xlabel(xlabel_text) + plt.pyplot.title(title_text + ": Modified E-optimality") + plt.pyplot.show() + + def _heatmap( + self, + title_text, + xlabel_text, + ylabel_text, + font_axes=16, + font_tick=14, + figure_file_name=None, + log_scale=True, + ): + """ + Draw 2D heatmaps for all design criteria + + Parameters + ---------- + title_text: name of the figure, a string + xlabel_text: x label title, a string. + In a 2D heatmap, it should be the second design variable in the design_ranges + ylabel_text: y label title, a string. + In a 2D heatmap, it should be the first design variable in the dv_ranges + font_axes: axes label font size + font_tick: tick label font size + log_scale: if True, the result matrix will be scaled by log10 + + Returns + -------- + 4 Figures of 2D heatmap for each criteria + """ + des_names = [k for k,v in self.figure_fixed_des_vars.items()] + sens_ranges = {} + for i in self.figure_sens_des_vars: + sens_ranges[i] = list(self.figure_result_data[i].unique()) + + x_range = sens_ranges[self.figure_sens_des_vars[0]] + y_range = sens_ranges[self.figure_sens_des_vars[1]] + + # extract the design criteria values + A_range = self.figure_result_data["log10 A-opt"].values.tolist() + D_range = self.figure_result_data["log10 D-opt"].values.tolist() + E_range = self.figure_result_data["log10 E-opt"].values.tolist() + ME_range = self.figure_result_data["log10 ME-opt"].values.tolist() + + # reshape the design criteria values for heatmaps + cri_a = np.asarray(A_range).reshape(len(x_range), len(y_range)) + cri_d = np.asarray(D_range).reshape(len(x_range), len(y_range)) + cri_e = np.asarray(E_range).reshape(len(x_range), len(y_range)) + cri_e_cond = np.asarray(ME_range).reshape(len(x_range), len(y_range)) + + self.cri_a = cri_a + self.cri_d = cri_d + self.cri_e = cri_e + self.cri_e_cond = cri_e_cond + + # decide if log scaled + if log_scale: + hes_a = np.log10(self.cri_a) + hes_e = np.log10(self.cri_e) + hes_d = np.log10(self.cri_d) + hes_e2 = np.log10(self.cri_e_cond) + else: + hes_a = self.cri_a + hes_e = self.cri_e + hes_d = self.cri_d + hes_e2 = self.cri_e_cond + + # set heatmap x,y ranges + xLabel = x_range + yLabel = y_range + + # A-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + plt.pyplot.rcParams.update(params) + ax.set_yticks(range(len(yLabel))) + ax.set_yticklabels(yLabel) + ax.set_ylabel(ylabel_text) + ax.set_xticks(range(len(xLabel))) + ax.set_xticklabels(xLabel) + ax.set_xlabel(xlabel_text) + im = ax.imshow(hes_a.T, cmap=plt.pyplot.cm.hot_r) + ba = plt.pyplot.colorbar(im) + ba.set_label("log10(trace(FIM))") + plt.pyplot.title(title_text + ": A-optimality") + plt.pyplot.show() + + # D-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + plt.pyplot.rcParams.update(params) + ax.set_yticks(range(len(yLabel))) + ax.set_yticklabels(yLabel) + ax.set_ylabel(ylabel_text) + ax.set_xticks(range(len(xLabel))) + ax.set_xticklabels(xLabel) + ax.set_xlabel(xlabel_text) + im = ax.imshow(hes_d.T, cmap=plt.pyplot.cm.hot_r) + ba = plt.pyplot.colorbar(im) + ba.set_label("log10(det(FIM))") + plt.pyplot.title(title_text + ": D-optimality") + plt.pyplot.show() + + # E-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + plt.pyplot.rcParams.update(params) + ax.set_yticks(range(len(yLabel))) + ax.set_yticklabels(yLabel) + ax.set_ylabel(ylabel_text) + ax.set_xticks(range(len(xLabel))) + ax.set_xticklabels(xLabel) + ax.set_xlabel(xlabel_text) + im = ax.imshow(hes_e.T, cmap=plt.pyplot.cm.hot_r) + ba = plt.pyplot.colorbar(im) + ba.set_label("log10(minimal eig(FIM))") + plt.pyplot.title(title_text + ": E-optimality") + plt.pyplot.show() + + # modified E-optimality + fig = plt.pyplot.figure() + plt.pyplot.rc("axes", titlesize=font_axes) + plt.pyplot.rc("axes", labelsize=font_axes) + plt.pyplot.rc("xtick", labelsize=font_tick) + plt.pyplot.rc("ytick", labelsize=font_tick) + ax = fig.add_subplot(111) + params = {"mathtext.default": "regular"} + plt.pyplot.rcParams.update(params) + ax.set_yticks(range(len(yLabel))) + ax.set_yticklabels(yLabel) + ax.set_ylabel(ylabel_text) + ax.set_xticks(range(len(xLabel))) + ax.set_xticklabels(xLabel) + ax.set_xlabel(xlabel_text) + im = ax.imshow(hes_e2.T, cmap=plt.pyplot.cm.hot_r) + ba = plt.pyplot.colorbar(im) + ba.set_label("log10(cond(FIM))") + plt.pyplot.title(title_text + ": Modified E-optimality") + plt.pyplot.show() + + + # Gets the FIM from an existing model def get_FIM(self, mod=None): """ diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 14a9016e49a..8636b6dc05f 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -1,5 +1,6 @@ from experiment_class_example import * from pyomo.contrib.doe import * +from pyomo.contrib.doe import * from simple_reaction_example import * @@ -253,7 +254,7 @@ def create_model(m=None, ): for i in range(27): sigma_inv_new_np[i, i] = sigma_inv_new[i] -rescaled_FIM = doe_obj[1].rescale_FIM(FIM_vals_new_np, param_vals) +rescaled_FIM = rescale_FIM(FIM=FIM_vals_new_np, param_vals=param_vals) # Comparing values from compute FIM print("Results from using compute FIM (first old, then new)") @@ -264,10 +265,7 @@ def create_model(m=None, ): print(np.log10(np.linalg.det(doe_obj[0].seq_FIM))) A = doe_obj[0].kaug_jac B = doe_obj[0].seq_jac -C = np.array(doe_obj[0].jac_debug) print(np.sum((A - B) ** 2)) -print(np.sum((A - C) ** 2)) -print(np.sum((B - C) ** 2)) measurement_vals_model = [] meas_from_model = [] @@ -301,4 +299,10 @@ def create_model(m=None, ): print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.Obj))) print("New formulation, rescaled: {}".format(np.log10(np.linalg.det(rescaled_FIM)))) print("Old formulation, scaled: {}".format(pyo.value(optimize_result.model.Obj))) -print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) \ No newline at end of file +print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) + +# Draw figures +sens_vars = ['CA[0]', 'T[0]'] +des_vars_fixed = {'T[' + str((i + 1) / 8) + ']': 300 for i in range(7)} +des_vars_fixed['T[1]'] = 300 +doe_obj[0].draw_factorial_figure(title_text='', xlabel_text='', ylabel_text='', sensitivity_design_variables=sens_vars, fixed_design_variables=des_vars_fixed,) \ No newline at end of file diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py new file mode 100644 index 00000000000..7bae3d42015 --- /dev/null +++ b/pyomo/contrib/doe/utils.py @@ -0,0 +1,53 @@ +# ___________________________________________________________________________ +# +# 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. +# +# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation +# Initiative (CCSI), and is copyright (c) 2022 by the software owners: +# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., +# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, +# Battelle Memorial Institute, University of Notre Dame, +# The University of Pittsburgh, The University of Texas at Austin, +# University of Toledo, West Virginia University, et al. All rights reserved. +# +# NOTICE. This Software was developed under funding from the +# U.S. Department of Energy and the U.S. Government consequently retains +# certain rights. As such, the U.S. Government has been granted for itself +# and others acting on its behalf a paid-up, nonexclusive, irrevocable, +# worldwide license in the Software to reproduce, distribute copies to the +# public, prepare derivative works, and perform publicly and display +# publicly, and to permit other to do so. +# ___________________________________________________________________________ + +from pyomo.common.dependencies import numpy as np, numpy_available + +# Rescale FIM (a scaling function to help rescale FIM from parameter values) +def rescale_FIM(FIM, param_vals): + """ + Rescales the FIM based on the input and parameter vals. + It is assumed the parameter vals align with the FIM + dimensions such that (1, i) corresponds to the i-th + column or row of the FIM. + + Parameters + ---------- + FIM: 2D numpy array to be scaled + param_vals: scaling factors for the parameters + + """ + if isinstance(param_vals, list): + param_vals = np.array([param_vals, ]) + elif isinstance(param_vals, np.ndarray): + if len(param_vals.shape) > 2 or ((len(param_vals.shape) == 2) and (param_vals.shape[0] != 1)): + raise ValueError('param_vals should be a vector of dimensions (1, n_params). The shape you provided is {}.'.format(param_vals.shape)) + if len(param_vals.shape) == 1: + param_vals = np.array([param_vals, ]) + scaling_mat = (1 / param_vals).transpose().dot((1 / param_vals)) + scaled_FIM = np.multiply(FIM, scaling_mat) + return scaled_FIM From 16aa150a3c05d41c992fe8a83748efa7f29421d3 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 10 Jul 2024 14:59:40 -0400 Subject: [PATCH 041/203] Small updates on results and objective naming --- pyomo/contrib/doe/doe.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 212cf530842..7b1fbb91d5b 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -243,7 +243,7 @@ def run_doe(self, mod=None, results_file=None): mod = self.model # ToDo: potentially work with this for more complicated models - # build the large DOE pyomo model + # Create the full DoE model (build scenarios for F.D. scheme) if not self._built_scenarios: self.create_doe_model(mod=mod) @@ -252,7 +252,7 @@ def run_doe(self, mod=None, results_file=None): # Solve the square problem first to initialize the fim and # sensitivity constraints - # Deactivate object and objective constraints, and fix design variables + # Deactivate objective expression and objective constraints (on a block), and fix design variables mod.Obj.deactivate() mod.obj_cons.deactivate() for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): @@ -282,11 +282,19 @@ def run_doe(self, mod=None, results_file=None): # Solve the full model, which has now been initialized with the square solve self.solver.solve(mod, tee=self.tee) + + # Finish timing + solve_time = sp_timer.toc(msg=None) + self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % dT) # ToDo: Make this more complicated? --> Should results be an object? Or just a dict? # Populate results object; Important info: FIM, Q, outputs, inputs, param values, # measurement error, prior FIM, fim_local = self.get_FIM() + + # Make sure stale results don't follow the DoE object instance + self.results = {} + self.results['FIM'] = fim_local self.results['Sensitivity Matrix'] = self.get_sensitivity_matrix() self.results['Experiment Design'] = self.get_experiment_input_values() @@ -301,16 +309,20 @@ def run_doe(self, mod=None, results_file=None): self.results['log10 D-opt'] = np.log10(np.linalg.det(fim_local)) self.results['log10 E-opt'] = np.log10(min(np.linalg.eig(fim_local)[0])) self.results['FIM Condition Number'] = np.linalg.cond(fim_local) + self.results['Wall-clock Time'] = solve_time + + # ToDo: Add ``useful`` fields to the results object? + # objective type (i.e., det, trace, etc.) + # Finite Difference Formula type + # Finite Difference step size + # If parameter scaling is used or not (self.scale_nominal_param_value) + # # If the user specifies to save the file, do it here as a json if results_file is not None: assert type(results_file) in [Path, str], "`results_file` must be either a Path object or a string." with open(results_file, 'w') as file: json.dump(self.results, file) - - # Finish timing - dT = sp_timer.toc(msg=None) - self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % dT) # Perform multi-experiment doe (sequential, or ``greedy`` approach) def run_multi_doe_sequential(self, N_exp=1): @@ -1307,6 +1319,9 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): # ToDo: Make this complex check bit more intuitive if np.iscomplex(E_opt): E_opt = 0.0 + print("Imaginary eigenvalues") + print(FIM) + print(np.linalg.eig(FIM)) ME_opt = np.log10(np.linalg.cond(FIM)) # Append the values for each of the experiment inputs From 0822e0dbde594301b2111e77a4241eac37f997b0 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 11 Jul 2024 11:49:23 -0400 Subject: [PATCH 042/203] Removing deprecated code --- pyomo/contrib/doe/doe.py | 1392 +---------------- .../doe/redesign/simple_reaction_example.py | 6 + 2 files changed, 23 insertions(+), 1375 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 7b1fbb91d5b..f85a8025d31 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -285,7 +285,8 @@ def run_doe(self, mod=None, results_file=None): # Finish timing solve_time = sp_timer.toc(msg=None) - self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % dT) + # TODO: CHANGE THIS FOLLOWING LINE WITH THE UPDATED SOLUTION TIME BREAKDOWN + self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % solve_time) # ToDo: Make this more complicated? --> Should results be an object? Or just a dict? # Populate results object; Important info: FIM, Q, outputs, inputs, param values, @@ -1315,13 +1316,18 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): # Compute and record metrics on FIM D_opt = np.log10(np.linalg.det(FIM)) A_opt = np.log10(np.trace(FIM)) - E_opt = np.log10(min(np.linalg.eig(FIM)[0])) - # ToDo: Make this complex check bit more intuitive - if np.iscomplex(E_opt): - E_opt = 0.0 - print("Imaginary eigenvalues") - print(FIM) - print(np.linalg.eig(FIM)) + E_vals, E_vecs = np.linalg.eig(FIM) # Grab eigenvalues + E_ind = np.argmin(E_vals.real) # Grab index of minima to check imaginary + # Warn the user if there is a ``large`` imaginary component (should not be) + if abs(E_vals.imag[E_ind]) > 1e-8: + self.logger.warning("Eigenvalue has imaginary component greater than 1e-6, contact developers if this issue persists.") + + # If the real value is less than or equal to zero, set the E_opt value to np.NaN + if E_vals.real[E_ind] <= 0: + E_opt = np.NaN + else: + E_opt = np.log10(E_vals.real[E_ind]) + ME_opt = np.log10(np.linalg.cond(FIM)) # Append the values for each of the experiment inputs @@ -1438,7 +1444,6 @@ def draw_factorial_figure( filter += "&" i += 1 # extract results with other dimensions fixed - print(filter) figure_result_data = results_pd.loc[eval(filter)] # if there is no other fixed dimensions @@ -1902,1374 +1907,11 @@ def get_measurement_error_values(self, mod=None): return sigma_vals -############################## -# Below is deprecated code # -############################## - -class DesignOfExperiments: - def __init__( - self, - param_init, - design_vars, - measurement_vars, - create_model, - solver=None, - prior_FIM=None, - discretize_model=None, - args=None, - logger_level=logging.INFO, - only_compute_fim_lower=True, - ): - """ - This package enables model-based design of experiments analysis with Pyomo. - Both direct optimization and enumeration modes are supported. - NLP sensitivity tools, e.g., sipopt and k_aug, are supported to accelerate analysis via enumeration. - It can be applied to dynamic models, where design variables are controlled throughout the experiment. - - Parameters - ---------- - param_init: - A ``dictionary`` of parameter names and values. - If they defined as indexed Pyomo variable, put the variable name and index, such as 'theta["A1"]'. - design_vars: - A ``DesignVariables`` which contains the Pyomo variable names and their corresponding indices - and bounds for experiment degrees of freedom - measurement_vars: - A ``MeasurementVariables`` which contains the Pyomo variable names and their corresponding indices and - bounds for experimental measurements - create_model: - A Python ``function`` that returns a Concrete Pyomo model, similar to the interface for ``parmest`` - solver: - A ``solver`` object that User specified, default=None. - If not specified, default solver is IPOPT MA57. - prior_FIM: - A 2D numpy array containing Fisher information matrix (FIM) for prior experiments. - The default None means there is no prior information. - discretize_model: - A user-specified ``function`` that discretizes the model. Only use with Pyomo.DAE, default=None - args: - Additional arguments for the create_model function. - logger_level: - Specify the level of the logger. Change to logging.DEBUG for all messages. - only_compute_fim_lower: - If True, only the lower triangle of the FIM is computed. Default is True. - """ - - # parameters - if not isinstance(param_init, collections.abc.Mapping): - raise ValueError("param_init should be a dictionary.") - self.param = param_init - # design variable name - self.design_name = design_vars.variable_names - self.design_vars = design_vars - self.create_model = create_model - - # check if create model function conforms to the original - # Pyomo.DoE interface - model_option_arg = ( - "model_option" in inspect.getfullargspec(self.create_model).args - ) - mod_arg = "mod" in inspect.getfullargspec(self.create_model).args - if model_option_arg and mod_arg: - self._original_create_model_interface = True - else: - self._original_create_model_interface = False - - if args is None: - args = {} - self.args = args - - # create the measurement information object - self.measurement_vars = measurement_vars - self.measure_name = self.measurement_vars.variable_names - - if ( - self.measurement_vars.variable_names is None - or not self.measurement_vars.variable_names - ): - raise ValueError( - "There are no measurement variables. Check for a modeling mistake." - ) - - # check if user-defined solver is given - if solver: - self.solver = solver - # if not given, use default solver - else: - self.solver = self._get_default_ipopt_solver() - - # check if discretization is needed - self.discretize_model = discretize_model - - # check if there is prior info - if prior_FIM is None: - self.prior_FIM = np.zeros((len(self.param), len(self.param))) - else: - self.prior_FIM = prior_FIM - self._check_inputs() - - # if print statements - self.logger = logging.getLogger(__name__) - self.logger.setLevel(level=logger_level) - - self.only_compute_fim_lower = only_compute_fim_lower - - def _check_inputs(self): - """ - Check if the prior FIM is N*N matrix, where N is the number of parameter - """ - if self.prior_FIM is not None: - if np.shape(self.prior_FIM)[0] != np.shape(self.prior_FIM)[1]: - raise ValueError("Found wrong prior information matrix shape.") - elif np.shape(self.prior_FIM)[0] != len(self.param): - raise ValueError("Found wrong prior information matrix shape.") - - def stochastic_program( - self, - if_optimize=True, - objective_option="det", - scale_nominal_param_value=False, - scale_constant_value=1, - optimize_opt=None, - if_Cholesky=False, - L_LB=1e-7, - L_initial=None, - jac_initial=None, - fim_initial=None, - formula="central", - step=0.001, - tee_opt=True, - ): - """ - Optimize DOE problem with design variables being the decisions. - The DOE model is formed invasively and all scenarios are computed simultaneously. - The function will first run a square problem with design variable being fixed at - the given initial points (Objective function being 0), then a square problem with - design variables being fixed at the given initial points (Objective function being Design optimality), - and then unfix the design variable and do the optimization. - - Parameters - ---------- - if_optimize: - if true, continue to do optimization. else, just run square problem with given design variable values - objective_option: - choose from the ObjectiveLib enum, - "det": maximizing the determinant with ObjectiveLib.det, - "trace": or the trace of the FIM with ObjectiveLib.trace - scale_nominal_param_value: - if True, the parameters are scaled by its own nominal value in param_init - scale_constant_value: - scale all elements in Jacobian matrix, default is 1. - optimize_opt: - A dictionary, keys are design variables, values are True or False deciding if this design variable will be optimized as DOF or not - if_Cholesky: - if True, Cholesky decomposition is used for Objective function for D-optimality. - L_LB: - L is the Cholesky decomposition matrix for FIM, i.e. FIM = L*L.T. - L_LB is the lower bound for every element in L. - if FIM is positive definite, the diagonal element should be positive, so we can set a LB like 1E-10 - L_initial: - initialize the L - jac_initial: - a matrix used to initialize jacobian matrix - fim_initial: - a matrix used to initialize FIM matrix - formula: - choose from "central", "forward", "backward", - which refers to the Enum FiniteDifferenceStep.central, .forward, or .backward - step: - Sensitivity perturbation step size, a fraction between [0,1]. default is 0.001 - tee_opt: - if True, IPOPT console output is printed - - Returns - ------- - analysis_square: result summary of the square problem solved at the initial point - analysis_optimize: result summary of the optimization problem solved - - """ - # store inputs in object - self.design_values = self.design_vars.variable_names_value - self.optimize = if_optimize - self.objective_option = ObjectiveLib(objective_option) - self.scale_nominal_param_value = scale_nominal_param_value - self.scale_constant_value = scale_constant_value - self.Cholesky_option = if_Cholesky - self.L_LB = L_LB - self.L_initial = L_initial - self.jac_initial = jac_initial - self.fim_initial = fim_initial - self.formula = FiniteDifferenceStep(formula) - self.step = step - self.tee_opt = tee_opt - - # calculate how much the FIM element is scaled by a constant number - # FIM = Jacobian.T@Jacobian, the FIM is scaled by squared value the Jacobian is scaled - self.fim_scale_constant_value = self.scale_constant_value**2 - - # Start timer - sp_timer = TicTocTimer() - sp_timer.tic(msg=None) - - # build the large DOE pyomo model - m = self._create_doe_model(no_obj=True) - - # solve model, achieve results for square problem, and results for optimization problem - m, analysis_square = self._compute_stochastic_program(m, optimize_opt) - - if self.optimize: - # If set to optimize, solve the optimization problem (with degrees of freedom) - analysis_optimize = self._optimize_stochastic_program(m) - dT = sp_timer.toc(msg=None) - self.logger.info("elapsed time: %0.1f seconds" % dT) - # Return both square problem and optimization problem results - return analysis_square, analysis_optimize - - else: - dT = sp_timer.toc(msg=None) - self.logger.info("elapsed time: %0.1f seconds" % dT) - # Return only square problem results - return analysis_square - - def _compute_stochastic_program(self, m, optimize_option): - """ - Solve the stochastic program problem as a square problem. - """ - - # Solve square problem first - # result_square: solver result - result_square = self._solve_doe(m, fix=True, opt_option=optimize_option) - - # extract Jac - jac_square = self._extract_jac(m) - - # create result object - analysis_square = FisherResults( - list(self.param.keys()), - self.measurement_vars, - jacobian_info=None, - all_jacobian_info=jac_square, - prior_FIM=self.prior_FIM, - scale_constant_value=self.scale_constant_value, - ) - # for simultaneous mode, FIM and Jacobian are extracted with extract_FIM() - analysis_square.result_analysis(result=result_square) - - analysis_square.model = m - - self.analysis_square = analysis_square - return m, analysis_square - - def _optimize_stochastic_program(self, m): - """ - Solve the stochastic program problem as an optimization problem. - """ - - m = self._add_objective(m) - - result_doe = self._solve_doe(m, fix=False) - - # extract Jac - jac_optimize = self._extract_jac(m) - - # create result object - analysis_optimize = FisherResults( - list(self.param.keys()), - self.measurement_vars, - jacobian_info=None, - all_jacobian_info=jac_optimize, - prior_FIM=self.prior_FIM, - ) - # for simultaneous mode, FIM and Jacobian are extracted with extract_FIM() - analysis_optimize.result_analysis(result=result_doe) - analysis_optimize.model = m - - return analysis_optimize - - def compute_FIM( - self, - mode="direct_kaug", - FIM_store_name=None, - specified_prior=None, - tee_opt=True, - scale_nominal_param_value=False, - scale_constant_value=1, - store_output=None, - read_output=None, - extract_single_model=None, - formula="central", - step=0.001, - only_compute_fim_lower=False, - ): - """ - This function calculates the Fisher information matrix (FIM) using sensitivity information obtained - from two possible modes (defined by the CalculationMode Enum): - - 1. sequential_finite: sequentially solve square problems and use finite difference approximation - 2. direct_kaug: solve a single square problem then extract derivatives using NLP sensitivity theory - - Parameters - ---------- - mode: - supports CalculationMode.sequential_finite or CalculationMode.direct_kaug - FIM_store_name: - if storing the FIM in a .csv or .txt, give the file name here as a string. - specified_prior: - a 2D numpy array providing alternate prior matrix, default is no prior. - tee_opt: - if True, IPOPT console output is printed - scale_nominal_param_value: - if True, the parameters are scaled by its own nominal value in param_init - scale_constant_value: - scale all elements in Jacobian matrix, default is 1. - store_output: - if storing the output (value stored in Var 'output_record') as a pickle file, give the file name here as a string. - read_output: - if reading the output (value for Var 'output_record') as a pickle file, give the file name here as a string. - extract_single_model: - if True, the solved model outputs for each scenario are all recorded as a .csv file. - The output file uses the name AB.csv, where string A is store_output input, B is the index of scenario. - scenario index is the number of the scenario outputs which is stored. - formula: - choose from the Enum FiniteDifferenceStep.central, .forward, or .backward. - This option is only used for CalculationMode.sequential_finite mode. - step: - Sensitivity perturbation step size, a fraction between [0,1]. default is 0.001 - - Returns - ------- - FIM_analysis: result summary object of this solve - """ - - # save inputs in object - self.design_values = self.design_vars.variable_names_value - self.scale_nominal_param_value = scale_nominal_param_value - self.scale_constant_value = scale_constant_value - self.formula = FiniteDifferenceStep(formula) - self.mode = CalculationMode(mode) - self.step = step - - # This method only solves square problem - self.optimize = False - # Set the Objective Function to 0 helps solve square problem quickly - self.objective_option = ObjectiveLib.zero - self.tee_opt = tee_opt - - self.FIM_store_name = FIM_store_name - self.specified_prior = specified_prior - - # calculate how much the FIM element is scaled by a constant number - # As FIM~Jacobian.T@Jacobian, FIM is scaled twice the number the Q is scaled - self.fim_scale_constant_value = self.scale_constant_value**2 - - square_timer = TicTocTimer() - square_timer.tic(msg=None) - if self.mode == CalculationMode.sequential_finite: - FIM_analysis = self._sequential_finite( - read_output, extract_single_model, store_output - ) - - elif self.mode == CalculationMode.direct_kaug: - FIM_analysis = self._direct_kaug() - - dT = square_timer.toc(msg=None) - self.logger.info("elapsed time: %0.1f seconds" % dT) - - return FIM_analysis - - def _sequential_finite(self, read_output, extract_single_model, store_output): - """Sequential_finite mode uses Pyomo Block to evaluate the sensitivity information.""" - - # if measurements are provided - if read_output: - with open(read_output, "rb") as f: - output_record = pickle.load(f) - f.close() - jac = self._finite_calculation(output_record) - - # if measurements are not provided - else: - mod = self._create_block() - - # dict for storing model outputs - output_record = {} - - # Deactivate any existing objective functions - for obj in mod.component_objects(pyo.Objective): - obj.deactivate() - - # add zero (dummy/placeholder) objective function - mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) - - # solve model - square_result = self._solve_doe(mod, fix=True) - - # save model from optional post processing function - self._square_model_from_compute_FIM = mod - - if extract_single_model: - mod_name = store_output + ".csv" - dataframe = extract_single_model(mod, square_result) - dataframe.to_csv(mod_name) - - # loop over blocks for results - for s in range(len(self.scenario_list)): - # loop over measurement item and time to store model measurements - output_iter = [] - - # extract variable values - for r in self.measure_name: - cuid = pyo.ComponentUID(r) - try: - var_up = cuid.find_component_on(mod.block[s]) - except: - raise ValueError( - f"measurement {r} cannot be found in the model." - ) - output_iter.append(pyo.value(var_up)) - - output_record[s] = output_iter - - output_record["design"] = self.design_values - - if store_output: - f = open(store_output, "wb") - pickle.dump(output_record, f) - f.close() - - # calculate jacobian - jac = self._finite_calculation(output_record) - - # return all models formed - self.model = mod - - # Store the Jacobian information for access by users, not necessarily call result object to achieve jacobian information - # It is the overall set of Jacobian information, - # while in the result object the jacobian can be cut to achieve part of the FIM information - self.jac = jac - - # Assemble and analyze results - if self.specified_prior is None: - prior_in_use = self.prior_FIM - else: - prior_in_use = self.specified_prior - - FIM_analysis = FisherResults( - list(self.param.keys()), - self.measurement_vars, - jacobian_info=None, - all_jacobian_info=jac, - prior_FIM=prior_in_use, - store_FIM=self.FIM_store_name, - scale_constant_value=self.scale_constant_value, - ) - - return FIM_analysis - - def _direct_kaug(self): - # create model - if self._original_create_model_interface: - mod = self.create_model(model_option=ModelOptionLib.parmest, **self.args) - else: - mod = self.create_model(**self.args) - - # discretize if needed - if self.discretize_model is not None: - mod = self.discretize_model(mod, block=False) - - # Deactivate any existing objective functions - for obj in mod.component_objects(pyo.Objective): - obj.deactivate() - - # add zero (dummy/placeholder) objective function - mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) - - # set ub and lb to parameters - for par in self.param.keys(): - cuid = pyo.ComponentUID(par) - var = cuid.find_component_on(mod) - var.setlb(self.param[par]) - var.setub(self.param[par]) - - # generate parameter name list and value dictionary with index - var_name = list(self.param.keys()) - - # call k_aug get_dsdp function - square_result = self._solve_doe(mod, fix=True) - - # save model from optional post processing function - self._square_model_from_compute_FIM = mod - - dsdp_re, col = get_dsdp( - mod, list(self.param.keys()), self.param, tee=self.tee_opt - ) - - # analyze result - dsdp_array = dsdp_re.toarray().T - self.dsdp = dsdp_array - self.dsdp = col - # store dsdp returned - dsdp_extract = [] - # get right lines from results - measurement_index = [] - - # loop over measurement variables and their time points - for mname in self.measure_name: - try: - kaug_no = col.index(mname) - measurement_index.append(kaug_no) - # get right line of dsdp - dsdp_extract.append(dsdp_array[kaug_no]) - except: - # k_aug does not provide value for fixed variables - self.logger.debug("The variable is fixed: %s", mname) - # produce the sensitivity for fixed variables - zero_sens = np.zeros(len(self.param)) - # for fixed variables, the sensitivity are a zero vector - dsdp_extract.append(zero_sens) - - # Extract and calculate sensitivity if scaled by constants or parameters. - # Convert sensitivity to a dictionary - jac = {} - for par in self.param.keys(): - jac[par] = [] - - for d in range(len(dsdp_extract)): - for p, par in enumerate(self.param.keys()): - # if scaled by parameter value or constant value - sensi = dsdp_extract[d][p] * self.scale_constant_value - if self.scale_nominal_param_value: - sensi *= self.param[par] - jac[par].append(sensi) - - # check if another prior experiment FIM is provided other than the user-specified one - if self.specified_prior is None: - prior_in_use = self.prior_FIM - else: - prior_in_use = self.specified_prior - - # Assemble and analyze results - FIM_analysis = FisherResults( - list(self.param.keys()), - self.measurement_vars, - jacobian_info=None, - all_jacobian_info=jac, - prior_FIM=prior_in_use, - store_FIM=self.FIM_store_name, - scale_constant_value=self.scale_constant_value, - ) - - self.jac = jac - self.mod = mod - - return FIM_analysis - - def _create_block(self): - """ - Create a pyomo Concrete model and add blocks with different parameter perturbation scenarios. - - Returns - ------- - mod: Concrete Pyomo model - """ - - # create scenario information for block scenarios - scena_gen = ScenarioGenerator( - parameter_dict=self.param, formula=self.formula, step=self.step - ) - - self.scenario_data = scena_gen.ScenarioData - - # a list of dictionary, each one is a parameter dictionary with perturbed parameter values - self.scenario_list = self.scenario_data.scenario - # dictionary, keys are parameter name, values are a list of scenario index where this parameter is perturbed. - self.scenario_num = self.scenario_data.scena_num - # dictionary, keys are parameter name, values are the perturbation step - self.eps_abs = self.scenario_data.eps_abs - self.scena_gen = scena_gen - - # Determine if create_model takes theta as an optional input - pass_theta_to_initialize = ( - "theta" in inspect.getfullargspec(self.create_model).args - ) - - # Allow user to self-define complex design variables - if self._original_create_model_interface: - - # Create a global model - mod = pyo.ConcreteModel() - - if pass_theta_to_initialize: - # Add model on block with theta values - self.create_model( - mod=mod, - model_option=ModelOptionLib.stage1, - theta=self.param, - **self.args, - ) - else: - # Add model on block without theta values - self.create_model( - mod=mod, model_option=ModelOptionLib.stage1, **self.args - ) - - else: - # Create a global model - mod = self.create_model(**self.args) - - # Set for block/scenarios - mod.scenario = pyo.Set(initialize=self.scenario_data.scenario_indices) - - # Fix parameter values in the copy of the stage1 model (if they exist) - for par in self.param: - cuid = pyo.ComponentUID(par) - var = cuid.find_component_on(mod) - if var is not None: - # Fix the parameter value - # Otherwise, the parameter does not exist on the stage 1 model - var.fix(self.param[par]) - - def block_build(b, s): - # create block scenarios - # idea: check if create_model takes theta as an optional input, if so, pass parameter values to create_model - - if self._original_create_model_interface: - if pass_theta_to_initialize: - # Grab the values of theta for this scenario/block - theta_initialize = self.scenario_data.scenario[s] - # Add model on block with theta values - self.create_model( - mod=b, - model_option=ModelOptionLib.stage2, - theta=theta_initialize, - **self.args, - ) - else: - # Otherwise add model on block without theta values - self.create_model( - mod=b, model_option=ModelOptionLib.stage2, **self.args - ) - - # save block in a temporary variable - mod_ = b - else: - # Add model on block - if pass_theta_to_initialize: - # Grab the values of theta for this scenario/block - theta_initialize = self.scenario_data.scenario[s] - mod_ = self.create_model(theta=theta_initialize, **self.args) - else: - mod_ = self.create_model(**self.args) - - # fix parameter values to perturbed values - for par in self.param: - cuid = pyo.ComponentUID(par) - var = cuid.find_component_on(mod_) - var.fix(self.scenario_data.scenario[s][par]) - - if not self._original_create_model_interface: - # for the "new"/"slim" interface, we need to add the block to the model - return mod_ - - mod.block = pyo.Block(mod.scenario, rule=block_build) - - # discretize the model - if self.discretize_model is not None: - mod = self.discretize_model(mod) - - # force design variables in blocks to be equal to global design values - for name in self.design_name: - - def fix1(mod, s): - cuid = pyo.ComponentUID(name) - design_var_global = cuid.find_component_on(mod) - design_var = cuid.find_component_on(mod.block[s]) - return design_var == design_var_global - - con_name = "con" + name - mod.add_component(con_name, pyo.Constraint(mod.scenario, expr=fix1)) - - # Add user-defined design variable bounds - cuid = pyo.ComponentUID(name) - design_var_global = cuid.find_component_on(mod) - # Set the lower and upper bounds of the design variables - design_var_global.setlb(self.design_vars.lower_bounds[name]) - design_var_global.setub(self.design_vars.upper_bounds[name]) - - return mod - - def _finite_calculation(self, output_record): - """ - Calculate Jacobian for sequential_finite mode - - Parameters - ---------- - output_record: a dict of outputs, keys are scenario names, values are a list of measurements values - scena_gen: an object generated by Scenario_creator class - - Returns - ------- - jac: Jacobian matrix, a dictionary, keys are parameter names, values are a list of jacobian values with respect to this parameter - """ - # dictionary form of jacobian - jac = {} - - # After collecting outputs from all scenarios, calculate sensitivity - for para in self.param.keys(): - # extract involved scenario No. for each parameter from scenario class - involved_s = self.scenario_data.scena_num[para] - - # each parameter has two involved scenarios - s1 = involved_s[0] # positive perturbation - s2 = involved_s[1] # negative perturbation - list_jac = [] - for i in range(len(output_record[s1])): - sensi = ( - (output_record[s1][i] - output_record[s2][i]) - / self.scenario_data.eps_abs[para] - * self.scale_constant_value - ) - if self.scale_nominal_param_value: - sensi *= self.param[para] - list_jac.append(sensi) - # get Jacobian dict, keys are parameter name, values are sensitivity info - jac[para] = list_jac - - return jac - - def _extract_jac(self, m): - """ - Extract jacobian from the stochastic program - - Parameters - ---------- - m: solved stochastic program model - - Returns - ------- - JAC: the overall jacobian as a dictionary - """ - # dictionary form of jacobian - jac = {} - # loop over parameters - for p in self.param.keys(): - jac_para = [] - for res in m.measured_variables: - jac_para.append(pyo.value(m.sensitivity_jacobian[p, res])) - jac[p] = jac_para - return jac - - def run_grid_search( - self, - design_ranges, - mode="sequential_finite", - tee_option=False, - scale_nominal_param_value=False, - scale_constant_value=1, - store_name=None, - read_name=None, - store_optimality_as_csv=None, - formula="central", - step=0.001, - post_processing_function=None, - ): - """ - Enumerate through full grid search for any number of design variables; - solve square problems sequentially to compute FIMs. - It calculates FIM with sensitivity information from two modes: - - 1. sequential_finite: Calculates a one scenario model multiple times for multiple scenarios. - Sensitivity info estimated by finite difference - 2. direct_kaug: calculate sensitivity by k_aug with direct sensitivity - - Parameters - ---------- - design_ranges: - a ``dict``, keys are design variable names, - values are a list of design variable values to go over - mode: - choose from CalculationMode.sequential_finite, .direct_kaug. - tee_option: - if solver console output is made - scale_nominal_param_value: - if True, the parameters are scaled by its own nominal value in param_init - scale_constant_value: - scale all elements in Jacobian matrix, default is 1. - store_name: - a string of file name. If not None, store results with this name. - It is a pickle file containing all measurement information after solving the - model with perturbations. - Since there are multiple experiments, results are numbered with a scalar number, - and the result for one grid is 'store_name(count).csv' (count is the number of count). - read_name: - a string of file name. If not None, read result files. - It should be a pickle file previously generated by store_name option. - Since there are multiple experiments, this string should be the common part of all files; - Real name of the file is "read_name(count)", where count is the number of the experiment. - store_optimality_as_csv: - if True, the design criterion values of grid search results stored with this file name as a csv - formula: - choose from FiniteDifferenceStep.central, .forward, or .backward. - This option is only used for CalculationMode.sequential_finite. - step: - Sensitivity perturbation step size, a fraction between [0,1]. default is 0.001 - post_processing_function: - An optional function that executes after each solve of the grid search. - The function should take one input: the Pyomo model. This could be a plotting function. - Default is None. - - Returns - ------- - figure_draw_object: a combined result object of class Grid_search_result - """ - # Set the Objective Function to 0 helps solve square problem quickly - self.objective_option = ObjectiveLib.zero - self.store_optimality_as_csv = store_optimality_as_csv - - # calculate how much the FIM element is scaled - self.fim_scale_constant_value = scale_constant_value**2 - - # to store all FIM results - result_combine = {} - - # all lists of values of each design variable to go over - design_ranges_list = list(design_ranges.values()) - # design variable names to go over - design_dimension_names = list(design_ranges.keys()) - - # iteration 0 - count = 0 - failed_count = 0 - # how many sets of design variables will be run - total_count = 1 - for rng in design_ranges_list: - total_count *= len(rng) - - time_set = [] # record time for every iteration - - # generate combinations of design variable values to go over - search_design_set = product(*design_ranges_list) - - # loop over design value combinations - for design_set_iter in search_design_set: - # generate the design variable dictionary needed for running compute_FIM - # first copy value from design_values - design_iter = self.design_vars.variable_names_value.copy() - - # convert to a list and cache - list_design_set_iter = list(design_set_iter) - - # update the controlled value of certain time points for certain design variables - for i, names in enumerate(design_dimension_names): - if isinstance(names, str): - # if 'names' is simply a string, copy the new value - design_iter[names] = list_design_set_iter[i] - elif isinstance(names, collections.abc.Sequence): - # if the element is a list, all design variables in this list share the same values - for n in names: - design_iter[n] = list_design_set_iter[i] - else: - # otherwise just copy the value - # design_iter[names] = list(design_set_iter)[i] - raise NotImplementedError( - "You should not see this error message. Please report it to the Pyomo.DoE developers." - ) - - self.design_vars.variable_names_value = design_iter - iter_timer = TicTocTimer() - self.logger.info("=======Iteration Number: %s =====", count + 1) - self.logger.debug( - "Design variable values of this iteration: %s", design_iter - ) - iter_timer.tic(msg=None) - # generate store name - if store_name is None: - store_output_name = None - else: - store_output_name = store_name + str(count) - - if read_name is not None: - read_input_name = read_name + str(count) - else: - read_input_name = None - - # call compute_FIM to get FIM - try: - result_iter = self.compute_FIM( - mode=mode, - tee_opt=tee_option, - scale_nominal_param_value=scale_nominal_param_value, - scale_constant_value=scale_constant_value, - store_output=store_output_name, - read_output=read_input_name, - formula=formula, - step=step, - ) - - count += 1 - - result_iter.result_analysis() - - # iteration time - iter_t = iter_timer.toc(msg=None) - time_set.append(iter_t) - - # give run information at each iteration - self.logger.info("This is run %s out of %s.", count, total_count) - self.logger.info( - "The code has run %s seconds.", round(sum(time_set), 2) - ) - self.logger.info( - "Estimated remaining time: %s seconds", - round( - sum(time_set) / (count) * (total_count - count), 2 - ), # need to check this math... it gives a negative number for the final count - ) - - if post_processing_function is not None: - # Call the post processing function - post_processing_function(self._square_model_from_compute_FIM) - - # the combined result object are organized as a dictionary, keys are a tuple of the design variable values, values are a result object - result_combine[tuple(design_set_iter)] = result_iter - - except: - self.logger.warning( - ":::::::::::Warning: Cannot converge this run.::::::::::::" - ) - count += 1 - failed_count += 1 - self.logger.warning("failed count:", failed_count) - result_combine[tuple(design_set_iter)] = None - - # For user's access - self.all_fim = result_combine - - # Create figure drawing object - figure_draw_object = GridSearchResult( - design_ranges_list, - design_dimension_names, - result_combine, - store_optimality_name=store_optimality_as_csv, - ) - - self.logger.info("Overall wall clock time [s]: %s", sum(time_set)) - - return figure_draw_object - - def _create_doe_model(self, no_obj=True): - """ - Add equations to compute sensitivities, FIM, and objective. - - Parameters - ----------- - no_obj: if True, objective function is 0. - - Return - ------- - model: the DOE model - """ - - # Developer recommendation: use the Cholesky decomposition for D-optimality - # The explicit formula is available for benchmarking purposes and is NOT recommended - if ( - self.only_compute_fim_lower - and self.objective_option == ObjectiveLib.det - and not self.Cholesky_option - ): - raise ValueError( - "Cannot compute determinant with explicit formula if only_compute_fim_lower is True." - ) - - model = self._create_block() - - # variables for jacobian and FIM - model.regression_parameters = pyo.Set(initialize=list(self.param.keys())) - model.measured_variables = pyo.Set(initialize=self.measure_name) - - def identity_matrix(m, i, j): - if i == j: - return 1 - else: - return 0 - - ### Initialize the Jacobian if provided by the user - - # If the user provides an initial Jacobian, convert it to a dictionary - if self.jac_initial is not None: - dict_jac_initialize = {} - for i, bu in enumerate(model.regression_parameters): - for j, un in enumerate(model.measured_variables): - if isinstance(self.jac_initial, dict): - # Jacobian is a dictionary of arrays or lists where the key is the regression parameter name - dict_jac_initialize[(bu, un)] = self.jac_initial[bu][j] - elif isinstance(self.jac_initial, np.ndarray): - # Jacobian is a numpy array, rows are regression parameters, columns are measured variables - dict_jac_initialize[(bu, un)] = self.jac_initial[i][j] - - # Initialize the Jacobian matrix - def initialize_jac(m, i, j): - # If provided by the user, use the values now stored in the dictionary - if self.jac_initial is not None: - return dict_jac_initialize[(i, j)] - # Otherwise initialize to 0.1 (which is an arbitrary non-zero value) - else: - return 0.1 - - model.sensitivity_jacobian = pyo.Var( - model.regression_parameters, - model.measured_variables, - initialize=initialize_jac, - ) - - if self.fim_initial is not None: - dict_fim_initialize = { - (bu, un): self.fim_initial[i][j] - for i, bu in enumerate(model.regression_parameters) - for j, un in enumerate(model.regression_parameters) - } - - def initialize_fim(m, j, d): - return dict_fim_initialize[(j, d)] - - if self.fim_initial is not None: - model.fim = pyo.Var( - model.regression_parameters, - model.regression_parameters, - initialize=initialize_fim, - ) - else: - model.fim = pyo.Var( - model.regression_parameters, - model.regression_parameters, - initialize=identity_matrix, - ) - - # if cholesky, define L elements as variables - if self.Cholesky_option and self.objective_option == ObjectiveLib.det: - - # move the L matrix initial point to a dictionary - if self.L_initial is not None: - dict_cho = { - (bu, un): self.L_initial[i][j] - for i, bu in enumerate(model.regression_parameters) - for j, un in enumerate(model.regression_parameters) - } - - # use the L dictionary to initialize L matrix - def init_cho(m, i, j): - return dict_cho[(i, j)] - - # Define elements of Cholesky decomposition matrix as Pyomo variables and either - # Initialize with L in L_initial - if self.L_initial is not None: - model.L_ele = pyo.Var( - model.regression_parameters, - model.regression_parameters, - initialize=init_cho, - ) - # or initialize with the identity matrix - else: - model.L_ele = pyo.Var( - model.regression_parameters, - model.regression_parameters, - initialize=identity_matrix, - ) - - # loop over parameter name - for i, c in enumerate(model.regression_parameters): - for j, d in enumerate(model.regression_parameters): - # fix the 0 half of L matrix to be 0.0 - if i < j: - model.L_ele[c, d].fix(0.0) - # Give LB to the diagonal entries - if self.L_LB: - if c == d: - model.L_ele[c, d].setlb(self.L_LB) - - # jacobian rule - def jacobian_rule(m, p, n): - """ - m: Pyomo model - p: parameter - n: response - """ - cuid = pyo.ComponentUID(n) - var_up = cuid.find_component_on(m.block[self.scenario_num[p][0]]) - var_lo = cuid.find_component_on(m.block[self.scenario_num[p][1]]) - if self.scale_nominal_param_value: - return ( - m.sensitivity_jacobian[p, n] - == (var_up - var_lo) - / self.eps_abs[p] - * self.param[p] - * self.scale_constant_value - ) - else: - return ( - m.sensitivity_jacobian[p, n] - == (var_up - var_lo) / self.eps_abs[p] * self.scale_constant_value - ) - - # A constraint to calculate elements in Hessian matrix - # transfer prior FIM to be Expressions - fim_initial_dict = { - (bu, un): self.prior_FIM[i][j] - for i, bu in enumerate(model.regression_parameters) - for j, un in enumerate(model.regression_parameters) - } - - def read_prior(m, i, j): - return fim_initial_dict[(i, j)] - - model.priorFIM = pyo.Expression( - model.regression_parameters, model.regression_parameters, rule=read_prior - ) - - # The off-diagonal elements are symmetric, thus only half of the elements need to be calculated - def fim_rule(m, p, q): - """ - m: Pyomo model - p: parameter - q: parameter - """ - - if p > q: - if self.only_compute_fim_lower: - return pyo.Constraint.Skip - else: - return m.fim[p, q] == m.fim[q, p] - else: - return ( - m.fim[p, q] - == sum( - 1 - / self.measurement_vars.variance[n] - * m.sensitivity_jacobian[p, n] - * m.sensitivity_jacobian[q, n] - for n in model.measured_variables - ) - + m.priorFIM[p, q] * self.fim_scale_constant_value - ) - - model.jacobian_constraint = pyo.Constraint( - model.regression_parameters, model.measured_variables, rule=jacobian_rule - ) - model.fim_constraint = pyo.Constraint( - model.regression_parameters, model.regression_parameters, rule=fim_rule - ) - - if self.only_compute_fim_lower: - # Fix the upper half of the FIM matrix elements to be 0.0. - # This eliminates extra variables and ensures the expected number of - # degrees of freedom in the optimization problem. - for p in model.regression_parameters: - for q in model.regression_parameters: - if p > q: - model.fim[p, q].fix(0.0) - - return model - - def _add_objective(self, m): - - small_number = 1e-10 - - # Assemble the FIM matrix. This is helpful for initialization! - # - # Suggestion from JS: "It might be more efficient to form the NP array in one shot - # (from a list or using fromiter), and then reshaping to the 2-D matrix" - # - fim = np.zeros((len(self.param), len(self.param))) - for i, bu in enumerate(m.regression_parameters): - for j, un in enumerate(m.regression_parameters): - # Copy value from Pyomo model into numpy array - fim[i][j] = m.fim[bu, un].value - - # Set lower bound to ensure diagonal elements are (almost) non-negative - # if i == j: - # m.fim[bu, un].setlb(-small_number) - - ### Initialize the Cholesky decomposition matrix - if self.Cholesky_option and self.objective_option == ObjectiveLib.det: - - # Calculate the eigenvalues of the FIM matrix - eig = np.linalg.eigvals(fim) - - # If the smallest eigenvalue is (practically) negative, add a diagonal matrix to make it positive definite - small_number = 1e-10 - if min(eig) < small_number: - fim = fim + np.eye(len(self.param)) * (small_number - min(eig)) - - # Compute the Cholesky decomposition of the FIM matrix - L = np.linalg.cholesky(fim) - - # Initialize the Cholesky matrix - for i, c in enumerate(m.regression_parameters): - for j, d in enumerate(m.regression_parameters): - m.L_ele[c, d].value = L[i, j] - - def cholesky_imp(m, c, d): - """ - Calculate Cholesky L matrix using algebraic constraints - """ - # If it is the left bottom half of L - if list(self.param.keys()).index(c) >= list(self.param.keys()).index(d): - return m.fim[c, d] == sum( - m.L_ele[c, list(self.param.keys())[k]] - * m.L_ele[d, list(self.param.keys())[k]] - for k in range(list(self.param.keys()).index(d) + 1) - ) - else: - # This is the empty half of L above the diagonal - return pyo.Constraint.Skip - - def trace_calc(m): - """ - Calculate FIM elements. Can scale each element with 1000 for performance - """ - return m.trace == sum(m.fim[j, j] for j in m.regression_parameters) - - def det_general(m): - r"""Calculate determinant. Can be applied to FIM of any size. - det(A) = \sum_{\sigma in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) - Use permutation() to get permutations, sgn() to get signature - """ - r_list = list(range(len(m.regression_parameters))) - # get all permutations - object_p = permutations(r_list) - list_p = list(object_p) - - # generate a name_order to iterate \sigma_i - det_perm = 0 - for i in range(len(list_p)): - name_order = [] - x_order = list_p[i] - # sigma_i is the value in the i-th position after the reordering \sigma - for x in range(len(x_order)): - for y, element in enumerate(m.regression_parameters): - if x_order[x] == y: - name_order.append(element) - - # det(A) = sum_{\sigma \in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) - det_perm = sum( - self._sgn(list_p[d]) - * sum( - m.fim[each, name_order[b]] - for b, each in enumerate(m.regression_parameters) - ) - for d in range(len(list_p)) - ) - return m.det == det_perm - - if self.Cholesky_option and self.objective_option == ObjectiveLib.det: - m.cholesky_cons = pyo.Constraint( - m.regression_parameters, m.regression_parameters, rule=cholesky_imp - ) - m.Obj = pyo.Objective( - expr=2 * sum(pyo.log10(m.L_ele[j, j]) for j in m.regression_parameters), - sense=pyo.maximize, - ) - - elif self.objective_option == ObjectiveLib.det: - # if not cholesky but determinant, calculating det and evaluate the OBJ with det - m.det = pyo.Var(initialize=np.linalg.det(fim), bounds=(small_number, None)) - m.det_rule = pyo.Constraint(rule=det_general) - m.Obj = pyo.Objective(expr=pyo.log10(m.det), sense=pyo.maximize) - - elif self.objective_option == ObjectiveLib.trace: - # if not determinant or cholesky, calculating the OBJ with trace - m.trace = pyo.Var(initialize=np.trace(fim), bounds=(small_number, None)) - m.trace_rule = pyo.Constraint(rule=trace_calc) - m.Obj = pyo.Objective(expr=pyo.log10(m.trace), sense=pyo.maximize) - # m.Obj = pyo.Objective(expr=m.trace, sense=pyo.maximize) - - elif self.objective_option == ObjectiveLib.zero: - # add dummy objective function - m.Obj = pyo.Objective(expr=0) - else: - # something went wrong! - raise DeveloperError( - "Objective option not recognized. Please contact the developers as you should not see this error." - ) - - return m - - def _fix_design(self, m, design_val, fix_opt=True, optimize_option=None): - """ - Fix design variable - - Parameters - ---------- - m: model - design_val: design variable values dict - fix_opt: if True, fix. Else, unfix - optimize: a dictionary, keys are design variable name, values are True or False, deciding if this design variable is optimized as DOF this time - - Returns - ------- - m: model - """ - for name in self.design_name: - # Loop over design variables - # Get Pyomo variable object - cuid = pyo.ComponentUID(name) - var = cuid.find_component_on(m) - if fix_opt: - # If fix_opt is True, fix the design variable - var.fix(design_val[name]) - else: - # Otherwise check optimize_option - if optimize_option is None: - # If optimize_option is None, unfix all design variables - var.unfix() - else: - # Otherwise, unfix only the design variables listed in optimize_option with value True - if optimize_option[name]: - var.unfix() - return m - - def _get_default_ipopt_solver(self): - """Default solver""" - solver = SolverFactory("ipopt") - solver.options["linear_solver"] = "ma57" - solver.options["halt_on_ampl_error"] = "yes" - solver.options["max_iter"] = 3000 - return solver - - def _solve_doe(self, m, fix=False, opt_option=None): - """Solve DOE model. - If it's a square problem, fix design variable and solve. - Else, fix design variable and solve square problem first, then unfix them and solve the optimization problem - - Parameters - ---------- - m:model - fix: if true, solve two times (square first). Else, just solve the square problem - opt_option: a dictionary, keys are design variable name, values are True or False, - deciding if this design variable is optimized as DOF this time. - If None, all design variables are optimized as DOF this time. - - Returns - ------- - solver_results: solver results - """ - # if fix = False, solve the optimization problem - # if fix = True, solve the square problem - - # either fix or unfix the design variables - mod = self._fix_design( - m, self.design_values, fix_opt=fix, optimize_option=opt_option - ) - - # if user gives solver, use this solver. if not, use default IPOPT solver - solver_result = self.solver.solve(mod, tee=self.tee_opt) - - return solver_result - + # Helper function for determinant calculation def _sgn(self, p): """ - This is a helper function for stochastic_program function to compute the determinant formula. - Give the signature of a permutation + This is a helper function for when constructing the determinant formula + without the Cholesky factorization. Parameters ----------- diff --git a/pyomo/contrib/doe/redesign/simple_reaction_example.py b/pyomo/contrib/doe/redesign/simple_reaction_example.py index 8c26ee57a5f..3bf4ac8ef74 100644 --- a/pyomo/contrib/doe/redesign/simple_reaction_example.py +++ b/pyomo/contrib/doe/redesign/simple_reaction_example.py @@ -150,11 +150,15 @@ def finalize_model(self): m.t_control = control_points + print('SIMULATING MODEL.') + # TODO: add simulation for initialization????? # Call the simulator (optional) sim = Simulator(m, package='casadi') tsim, profiles = sim.simulate(integrator='idas') + print('SIMULATION COMPLETE.') + # Discretizing the model discr = pyo.TransformationFactory("dae.collocation") discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) @@ -206,3 +210,5 @@ def label_experiment_impl(self, index_sets_meas): experiments_simple = [ SimpleReactorExperiment(data_ex, 32, 3), ] + +expanded_experiments_simple = [e.get_labeled_model() for e in experiments_simple] \ No newline at end of file From 18e3bd225567fffad342cb3ba2b27e797c3e90e4 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:05:09 -0400 Subject: [PATCH 043/203] Updated init.py to remove deprecated dependencies --- pyomo/contrib/doe/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index bea94e4ace0..fc7ec95f53a 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -8,8 +8,5 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -from .measurements import MeasurementVariables, DesignVariables, VariablesWithIndices -from .doe import DesignOfExperiments, CalculationMode, ObjectiveLib, ModelOptionLib, DesignOfExperiments_ -from .scenario import ScenarioGenerator, FiniteDifferenceStep -from .result import FisherResults, GridSearchResult +from .doe import DesignOfExperiments, CalculationMode, ObjectiveLib, ModelOptionLib, FiniteDifferenceStep from .utils import rescale_FIM \ No newline at end of file From f46f06d20502472a321bfd2242ec43e602e277f2 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:06:30 -0400 Subject: [PATCH 044/203] Updated variable names to be more readable For example, changed ``mod`` to ``model`` and ``Obj`` to ``objective`` and ``L_ele`` to ``L``, etc. --- pyomo/contrib/doe/doe.py | 532 +++++++++++++++++++-------------------- 1 file changed, 265 insertions(+), 267 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index f85a8025d31..3fe6c788d68 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -36,8 +36,6 @@ from enum import Enum from pyomo.common.timing import TicTocTimer from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp -from pyomo.contrib.doe.scenario import ScenarioGenerator, FiniteDifferenceStep -from pyomo.contrib.doe.result import FisherResults, GridSearchResult import collections.abc import inspect @@ -64,13 +62,13 @@ class ModelOptionLib(Enum): stage2 = "stage2" -# class FiniteDifferenceStep(Enum): - # forward = "forward" - # central = "central" - # backward = "backward" +class FiniteDifferenceStep(Enum): + forward = "forward" + central = "central" + backward = "backward" -class DesignOfExperiments_: +class DesignOfExperiments: def __init__( self, experiment, @@ -220,14 +218,14 @@ def __init__( self._built_scenarios = False # Perform doe - def run_doe(self, mod=None, results_file=None): + def run_doe(self, model=None, results_file=None): """ Runs DoE for a single experiment estimation. Can save results in a file based on the flag. Parameters ---------- - mod: model to run the DoE, default: None (self.model) + model: model to run the DoE, default: None (self.model) results_file: string name of the file path to save the results to in the form of a .json file default: None --> don't save @@ -239,49 +237,49 @@ def run_doe(self, mod=None, results_file=None): self.logger.info("Beginning experimental optimization.") # Model is none, set it to self.model - if mod is None: - mod = self.model + if model is None: + model = self.model # ToDo: potentially work with this for more complicated models # Create the full DoE model (build scenarios for F.D. scheme) if not self._built_scenarios: - self.create_doe_model(mod=mod) + self.create_doe_model(model=model) # Add the objective function to the model - self.create_objective_function(mod=mod) + self.create_objective_function(model=model) # Solve the square problem first to initialize the fim and # sensitivity constraints # Deactivate objective expression and objective constraints (on a block), and fix design variables - mod.Obj.deactivate() - mod.obj_cons.deactivate() - for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): + model.objective.deactivate() + model.obj_cons.deactivate() + for comp, _ in model.scenario_blocks[0].experiment_inputs.items(): comp.fix() - mod.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) + model.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) self.solver.solve(self.model, tee=self.tee) - mod.dummy_obj.deactivate() + model.dummy_obj.deactivate() # Reactivate objective and unfix experimental design decisions - for comp, _ in mod.scenario_blocks[0].experiment_inputs.items(): + for comp, _ in model.scenario_blocks[0].experiment_inputs.items(): comp.unfix() - mod.Obj.activate() - mod.obj_cons.activate() + model.objective.activate() + model.obj_cons.activate() # ToDo: add a ``get FIM from model`` function - # If the model has L_ele, initialize it with the solved FIM - if hasattr(mod, 'L_ele'): + # If the model has L, initialize it with the solved FIM + if hasattr(model, 'L'): # Get the FIM values --> ToDo: add this as a function - fim_vals = [pyo.value(mod.fim[i, j]) for i in mod.parameter_names for j in mod.parameter_names] - fim_np = np.array(fim_vals).reshape((len(mod.parameter_names), len(mod.parameter_names))) + fim_vals = [pyo.value(model.fim[i, j]) for i in model.parameter_names for j in model.parameter_names] + fim_np = np.array(fim_vals).reshape((len(model.parameter_names), len(model.parameter_names))) L_vals_sq = np.linalg.cholesky(fim_np) - for i, c in enumerate(mod.parameter_names): - for j, d in enumerate(mod.parameter_names): - mod.L_ele[c, d].value = L_vals_sq[i, j] + for i, c in enumerate(model.parameter_names): + for j, d in enumerate(model.parameter_names): + model.L[c, d].value = L_vals_sq[i, j] # Solve the full model, which has now been initialized with the square solve - self.solver.solve(mod, tee=self.tee) + self.solver.solve(model, tee=self.tee) # Finish timing solve_time = sp_timer.toc(msg=None) @@ -338,7 +336,7 @@ def run_multi_doe_simultaneous(self, N_exp=1): ) # Compute FIM for the DoE object - def compute_FIM(self, mod=None, method='sequential'): + def compute_FIM(self, model=None, method='sequential'): """ Computes the FIM for the experimental design that is initialized from the experiment`s ``get_labeled_model()`` @@ -346,7 +344,7 @@ def compute_FIM(self, mod=None, method='sequential'): Parameters ---------- - mod: model to compute FIM, default: None, (self.compute_FIM_model) + model: model to compute FIM, default: None, (self.compute_FIM_model) method: string to specify which method should be used options are ``kaug`` and ``sequential`` @@ -354,24 +352,24 @@ def compute_FIM(self, mod=None, method='sequential'): ------- computed FIM: 2D numpy array of the FIM """ - if mod is None: + if model is None: self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() - mod = self.compute_FIM_model + model = self.compute_FIM_model - self.check_model_labels(mod=mod) + self.check_model_labels(model=model) # Check FIM input, if it exists. Otherwise, set the prior_FIM attribute if self.prior_FIM is None: - self.prior_FIM = np.zeros((len(mod.unknown_parameters), len(mod.unknown_parameters))) + self.prior_FIM = np.zeros((len(model.unknown_parameters), len(model.unknown_parameters))) else: self.check_model_FIM(FIM=self.prior_FIM) # ToDo: Decide where the FIM should be saved. if method == 'sequential': - self._sequential_FIM(mod=mod) + self._sequential_FIM(model=model) self._computed_FIM = self.seq_FIM elif method == 'kaug': - self._kaug_FIM(mod=mod) + self._kaug_FIM(model=model) self._computed_FIM = self.kaug_FIM else: raise ValueError('The method provided, {}, must be either `sequential` or `kaug`'.format(method)) @@ -379,7 +377,7 @@ def compute_FIM(self, mod=None, method='sequential'): return self._computed_FIM # Use a sequential method to get the FIM - def _sequential_FIM(self, mod=None): + def _sequential_FIM(self, model=None): """ Used to compute the FIM using a sequential approach, solving the model consecutively under each of the @@ -388,36 +386,36 @@ def _sequential_FIM(self, mod=None): """ # Build a singular model instance - if mod is None: + if model is None: self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() - mod = self.compute_FIM_model + model = self.compute_FIM_model # Create suffix to keep track of parameter scenarios - mod.parameter_scenarios = pyo.Suffix( + model.parameter_scenarios = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) # Populate parameter scenarios, and scenario inds based on finite difference scheme if self.fd_formula == FiniteDifferenceStep.central: - mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.unknown_parameters.keys())) - mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) - mod.scenarios = range(len(mod.unknown_parameters) * 2) + model.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(model.unknown_parameters.keys())) + model.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(model.unknown_parameters.keys())) + model.scenarios = range(len(model.unknown_parameters) * 2) elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: - mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.unknown_parameters.keys())) - mod.scenarios = range(len(mod.unknown_parameters) + 1) + model.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(model.unknown_parameters.keys())) + model.scenarios = range(len(model.unknown_parameters) + 1) else: # To-Do: add an error message for this as not being implemented yet pass # Fix design variables - for comp, _ in mod.experiment_inputs.items(): + for comp, _ in model.experiment_inputs.items(): comp.fix() measurement_vals = [] # In a loop..... # Calculate measurement values for each scenario - for s in mod.scenarios: - param = mod.parameter_scenarios[s] + for s in model.scenarios: + param = model.parameter_scenarios[s] # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: @@ -434,25 +432,25 @@ def _sequential_FIM(self, mod=None): pass # Update parameter values for the given finite difference scenario - param.set_value(mod.unknown_parameters[param] * (1 + diff)) + param.set_value(model.unknown_parameters[param] * (1 + diff)) # Simulate the model - self.solver.solve(mod) + self.solver.solve(model) # Extract the measurement values for the scenario and append - measurement_vals.append([pyo.value(k) for k, v in mod.experiment_outputs.items()]) + measurement_vals.append([pyo.value(k) for k, v in model.experiment_outputs.items()]) # Use the measurement outputs to make the Q matrix measurement_vals_np = np.array(measurement_vals).T - self.seq_jac = np.zeros((len(mod.experiment_outputs.items()), len(mod.unknown_parameters.items()))) + self.seq_jac = np.zeros((len(model.experiment_outputs.items()), len(model.unknown_parameters.items()))) # Counting variable for loop i = 0 # Loop over parameter values and grab correct columns for finite difference calculation - for k, v in mod.unknown_parameters.items(): + for k, v in model.unknown_parameters.items(): curr_step = v * self.step if self.fd_formula == FiniteDifferenceStep.central: @@ -479,9 +477,9 @@ def _sequential_FIM(self, mod=None): # ToDo: As more complex measurement error schemes are put in place, this needs to change # Add independent (non-correlated) measurement error for FIM calculation - cov_y = np.zeros((len(mod.measurement_error), len(mod.measurement_error))) + cov_y = np.zeros((len(model.measurement_error), len(model.measurement_error))) count = 0 - for k, v in mod.measurement_error.items(): + for k, v in model.measurement_error.items(): cov_y[count, count] = 1 / v count += 1 @@ -489,40 +487,40 @@ def _sequential_FIM(self, mod=None): self.seq_FIM = self.seq_jac.T @ cov_y @ self.seq_jac + self.prior_FIM # Use kaug to get FIM - def _kaug_FIM(self, mod=None): + def _kaug_FIM(self, model=None): """ Used to compute the FIM using kaug, a sensitivity-based approach that directly computes the FIM. Parameters ---------- - mod: model to compute FIM, default: None, (self.compute_FIM_model) + model: model to compute FIM, default: None, (self.compute_FIM_model) """ # Remake compute_FIM_model if model is None. # compute_FIM_model needs to be the right version for function to work. - if mod is None: + if model is None: self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() - mod = self.compute_FIM_model + model = self.compute_FIM_model # add zero (dummy/placeholder) objective function - if not hasattr(mod, 'Obj'): - mod.Obj = pyo.Objective(expr=0, sense=pyo.minimize) + if not hasattr(model, 'objective'): + model.objective = pyo.Objective(expr=0, sense=pyo.minimize) # call k_aug get_dsdp function # Solve the square problem # Deactivate object and fix experimental design decisions to make square - for comp, _ in mod.experiment_inputs.items(): + for comp, _ in model.experiment_inputs.items(): comp.fix() - self.solver.solve(mod, tee=self.tee) + self.solver.solve(model, tee=self.tee) # Probe the solved model for dsdp results (sensitivities s.t. parameters) - params_dict = {k.name: v for k, v in mod.unknown_parameters.items()} + params_dict = {k.name: v for k, v in model.unknown_parameters.items()} params_names = list(params_dict.keys()) dsdp_re, col = get_dsdp( - mod, params_names, params_dict, tee=self.tee + model, params_names, params_dict, tee=self.tee ) # analyze result @@ -534,7 +532,7 @@ def _kaug_FIM(self, mod=None): measurement_index = [] # loop over measurement variables and their time points - for k, v in mod.experiment_outputs.items(): + for k, v in model.experiment_outputs.items(): name = k.name try: kaug_no = col.index(name) @@ -553,7 +551,7 @@ def _kaug_FIM(self, mod=None): jac = [[] for k in params_names] for d in range(len(dsdp_extract)): - for k, v in mod.unknown_parameters.items(): + for k, v in model.unknown_parameters.items(): p = params_names.index(k.name) # Index of parameter in np array # if scaled by parameter value or constant value sensi = dsdp_extract[d][p] * self.scale_constant_value @@ -573,37 +571,37 @@ def _kaug_FIM(self, mod=None): # Constructing the Covariance of the measurements for the FIM calculation # The following assumes independent measurement error. - cov_y = np.zeros((len(mod.measurement_error), len(mod.measurement_error))) + cov_y = np.zeros((len(model.measurement_error), len(model.measurement_error))) count = 0 - for k, v in mod.measurement_error.items(): + for k, v in model.measurement_error.items(): cov_y[count, count] = 1 / v count += 1 # ToDo: need to add a covariance matrix for measurements (sigma inverse) - # i.e., cov_y = self.cov_y or mod.cov_y + # i.e., cov_y = self.cov_y or model.cov_y # Still deciding where this would be best. self.kaug_FIM = self.kaug_jac.T @ cov_y @ self.kaug_jac + self.prior_FIM # Create the DoE model (with ``scenarios`` from finite differencing scheme) - def create_doe_model(self, mod=None): + def create_doe_model(self, model=None): """ Add equations to compute sensitivities, FIM, and objective. Builds the DoE model. Adds the scenarios, the sensitivity matrix Q, the FIM, as well as the objective function to the model. - The function alters the ``mod`` input. + The function alters the ``model`` input. - In the single experiment case, ``mod`` will be self.model. In the - multi-experiment case, ``mod`` will be one experiment to be enumerated. + In the single experiment case, ``model`` will be self.model. In the + multi-experiment case, ``model`` will be one experiment to be enumerated. Parameters ---------- - mod: model to add finite difference scenarios + model: model to add finite difference scenarios """ - if mod is None: - mod = self.model + if model is None: + model = self.model # Developer recommendation: use the Cholesky decomposition for D-optimality # The explicit formula is available for benchmarking purposes and is NOT recommended @@ -617,12 +615,12 @@ def create_doe_model(self, mod=None): ) # Generate scenarios for finite difference formulae - self._generate_scenario_blocks(mod=mod) + self._generate_scenario_blocks(model=model) # Set names for indexing sensitivity matrix (jacobian) and FIM - scen_block_ind = min([k.name.split('.').index('scenario_blocks[0]') for k in mod.scenario_blocks[0].unknown_parameters.keys()]) - mod.parameter_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in mod.scenario_blocks[0].unknown_parameters.keys()]) - mod.output_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in mod.scenario_blocks[0].experiment_outputs.keys()]) + scen_block_ind = min([k.name.split('.').index('scenario_blocks[0]') for k in model.scenario_blocks[0].unknown_parameters.keys()]) + model.parameter_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in model.scenario_blocks[0].unknown_parameters.keys()]) + model.output_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in model.scenario_blocks[0].experiment_outputs.keys()]) def identity_matrix(m, i, j): if i == j: @@ -635,8 +633,8 @@ def identity_matrix(m, i, j): # If the user provides an initial Jacobian, convert it to a dictionary if self.jac_initial is not None: dict_jac_initialize = {} - for i, bu in enumerate(mod.output_names): - for j, un in enumerate(mod.parameter_names): + for i, bu in enumerate(model.output_names): + for j, un in enumerate(model.parameter_names): # Jacobian is a numpy array, rows are experimental outputs, columns are unknown parameters dict_jac_initialize[(bu, un)] = self.jac_initial[i][j] @@ -650,9 +648,9 @@ def initialize_jac(m, i, j): # Add flag as this should never be reached. return 0.1 - mod.sensitivity_jacobian = pyo.Var( - mod.output_names, - mod.parameter_names, + model.sensitivity_jacobian = pyo.Var( + model.output_names, + model.parameter_names, initialize=initialize_jac, ) @@ -660,23 +658,23 @@ def initialize_jac(m, i, j): if self.fim_initial is not None: dict_fim_initialize = { (bu, un): self.fim_initial[i][j] - for i, bu in enumerate(mod.parameter_names) - for j, un in enumerate(mod.parameter_names) + for i, bu in enumerate(model.parameter_names) + for j, un in enumerate(model.parameter_names) } def initialize_fim(m, j, d): return dict_fim_initialize[(j, d)] if self.fim_initial is not None: - mod.fim = pyo.Var( - mod.parameter_names, - mod.parameter_names, + model.fim = pyo.Var( + model.parameter_names, + model.parameter_names, initialize=initialize_fim, ) else: - mod.fim = pyo.Var( - mod.parameter_names, - mod.parameter_names, + model.fim = pyo.Var( + model.parameter_names, + model.parameter_names, initialize=identity_matrix, ) @@ -688,8 +686,8 @@ def initialize_fim(m, j, d): if self.L_initial is not None: dict_cho = { (bu, un): self.L_initial[i][j] - for i, bu in enumerate(mod.parameter_names) - for j, un in enumerate(mod.parameter_names) + for i, bu in enumerate(model.parameter_names) + for j, un in enumerate(model.parameter_names) } # use the L dictionary to initialize L matrix @@ -699,29 +697,29 @@ def init_cho(m, i, j): # Define elements of Cholesky decomposition matrix as Pyomo variables and either # Initialize with L in L_initial if self.L_initial is not None: - mod.L_ele = pyo.Var( - mod.parameter_names, - mod.parameter_names, + model.L = pyo.Var( + model.parameter_names, + model.parameter_names, initialize=init_cho, ) # or initialize with the identity matrix else: - mod.L_ele = pyo.Var( - mod.parameter_names, - mod.parameter_names, + model.L = pyo.Var( + model.parameter_names, + model.parameter_names, initialize=identity_matrix, ) # loop over parameter name - for i, c in enumerate(mod.parameter_names): - for j, d in enumerate(mod.parameter_names): + for i, c in enumerate(model.parameter_names): + for j, d in enumerate(model.parameter_names): # fix the 0 half of L matrix to be 0.0 if i < j: - mod.L_ele[c, d].fix(0.0) + model.L[c, d].fix(0.0) # Give LB to the diagonal entries if self.L_LB: if c == d: - mod.L_ele[c, d].setlb(self.L_LB) + model.L[c, d].setlb(self.L_LB) # jacobian rule def jacobian_rule(m, n, p): @@ -732,7 +730,7 @@ def jacobian_rule(m, n, p): """ fd_step_mult = 1 cuid = pyo.ComponentUID(n) - param_ind = mod.parameter_names.data().index(p) + param_ind = model.parameter_names.data().index(p) # Different FD schemes lead to different scenarios for the computation if self.fd_formula == FiniteDifferenceStep.central: @@ -749,9 +747,9 @@ def jacobian_rule(m, n, p): var_up = cuid.find_component_on(m.scenario_blocks[s1]) var_lo = cuid.find_component_on(m.scenario_blocks[s2]) - param = mod.parameter_scenarios[max(s1, s2)] - param_loc = pyo.ComponentUID(param).find_component_on(mod.scenario_blocks[0]) - param_val = mod.scenario_blocks[0].unknown_parameters[param_loc] + param = model.parameter_scenarios[max(s1, s2)] + param_loc = pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0]) + param_val = model.scenario_blocks[0].unknown_parameters[param_loc] param_diff = param_val * fd_step_mult * self.step if self.scale_nominal_param_value: @@ -772,15 +770,15 @@ def jacobian_rule(m, n, p): # transfer prior FIM to be Expressions fim_initial_dict = { (bu, un): self.prior_FIM[i][j] - for i, bu in enumerate(mod.parameter_names) - for j, un in enumerate(mod.parameter_names) + for i, bu in enumerate(model.parameter_names) + for j, un in enumerate(model.parameter_names) } def read_prior(m, i, j): return fim_initial_dict[(i, j)] - mod.priorFIM = pyo.Expression( - mod.parameter_names, mod.parameter_names, rule=read_prior + model.priorFIM = pyo.Expression( + model.parameter_names, model.parameter_names, rule=read_prior ) # Off-diagonal elements are symmetric, so only half of the off-diagonal elements need to be specified. @@ -790,8 +788,8 @@ def fim_rule(m, p, q): p: unknown parameter q: unknown parameter """ - p_ind = list(mod.parameter_names).index(p) - q_ind = list(mod.parameter_names).index(q) + p_ind = list(model.parameter_names).index(p) + q_ind = list(model.parameter_names).index(q) # If the row is less than the column, skip the constraint # This logic is consistent with making the FIM a lower @@ -806,61 +804,61 @@ def fim_rule(m, p, q): m.fim[p, q] == sum( 1 - / mod.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(mod.scenario_blocks[0])] + / model.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(model.scenario_blocks[0])] * m.sensitivity_jacobian[n, p] * m.sensitivity_jacobian[n, q] - for n in mod.output_names + for n in model.output_names ) + m.priorFIM[p, q] ) - mod.jacobian_constraint = pyo.Constraint( - mod.output_names, mod.parameter_names, rule=jacobian_rule + model.jacobian_constraint = pyo.Constraint( + model.output_names, model.parameter_names, rule=jacobian_rule ) - mod.fim_constraint = pyo.Constraint( - mod.parameter_names, mod.parameter_names, rule=fim_rule + model.fim_constraint = pyo.Constraint( + model.parameter_names, model.parameter_names, rule=fim_rule ) if self.only_compute_fim_lower: # Fix the upper half of the FIM matrix elements to be 0.0. # This eliminates extra variables and ensures the expected number of # degrees of freedom in the optimization problem. - for ind_p, p in enumerate(mod.parameter_names): - for ind_q, q in enumerate(mod.parameter_names): + for ind_p, p in enumerate(model.parameter_names): + for ind_q, q in enumerate(model.parameter_names): if ind_p < ind_q: - mod.fim[p, q].fix(0.0) + model.fim[p, q].fix(0.0) # Create scenario block structure - def _generate_scenario_blocks(self, mod=None): + def _generate_scenario_blocks(self, model=None): """ Generates the modeling blocks corresponding to the scenarios for the finite differencing scheme to compute the sensitivity jacobian to compute the FIM. - The function alters the ``mod`` input. + The function alters the ``model`` input. - In the single experiment case, ``mod`` will be self.model. In the - multi-experiment case, ``mod`` will be one experiment to be enumerated. + In the single experiment case, ``model`` will be self.model. In the + multi-experiment case, ``model`` will be one experiment to be enumerated. Parameters ---------- - mod: model to add finite difference scenarios + model: model to add finite difference scenarios """ # If model is none, assume it is self.model - if mod is None: - mod = self.model + if model is None: + model = self.model # Generate initial scenario to populate unknown parameter values - mod.base_model = self.experiment.get_labeled_model(**self.args).clone() + model.base_model = self.experiment.get_labeled_model(**self.args).clone() # Check the model that labels are correct - self.check_model_labels(mod=mod) + self.check_model_labels(model=model) # Gather lengths of label structures for later use in the model build process - self.n_parameters = len(mod.base_model.unknown_parameters) - self.n_measurement_error = len(mod.base_model.measurement_error) - self.n_experiment_inputs = len(mod.base_model.experiment_inputs) - self.n_experiment_outputs = len(mod.base_model.experiment_outputs) + self.n_parameters = len(model.base_model.unknown_parameters) + self.n_measurement_error = len(model.base_model.measurement_error) + self.n_experiment_inputs = len(model.base_model.experiment_inputs) + self.n_experiment_outputs = len(model.base_model.experiment_outputs) assert (self.n_measurement_error == self.n_experiment_outputs), "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format(self.n_experiment_outputs, self.n_measurement_error) @@ -881,18 +879,18 @@ def _generate_scenario_blocks(self, mod=None): self.jac_initial = np.eye(self.n_experiment_outputs, self.n_parameters) # Make a new Suffix to hold which scenarios are associated with parameters - mod.parameter_scenarios = pyo.Suffix( + model.parameter_scenarios = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) # Populate parameter scenarios, and scenario inds based on finite difference scheme if self.fd_formula == FiniteDifferenceStep.central: - mod.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) - mod.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) - mod.scenarios = range(len(mod.base_model.unknown_parameters) * 2) + model.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(model.base_model.unknown_parameters.keys())) + model.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(model.base_model.unknown_parameters.keys())) + model.scenarios = range(len(model.base_model.unknown_parameters) * 2) elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: - mod.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(mod.base_model.unknown_parameters.keys())) - mod.scenarios = range(len(mod.base_model.unknown_parameters) + 1) + model.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(model.base_model.unknown_parameters.keys())) + model.scenarios = range(len(model.base_model.unknown_parameters) + 1) else: raise DeveloperError( "Finite difference option not recognized. Please contact the developers as you should not see this error." @@ -901,31 +899,31 @@ def _generate_scenario_blocks(self, mod=None): # To-Do: Fix parameter values if they are not Params? # Run base model to get initialized model and check model function - for comp, _ in mod.base_model.experiment_inputs.items(): + for comp, _ in model.base_model.experiment_inputs.items(): comp.fix() try: - self.solver.solve(mod.base_model, tee=self.tee) + self.solver.solve(model.base_model, tee=self.tee) self.logger.info('Model from experiment solved.') except: raise RuntimeError('Model from experiment did not solve appropriately. Make sure the model is well-posed.') - for comp, _ in mod.base_model.experiment_inputs.items(): + for comp, _ in model.base_model.experiment_inputs.items(): comp.unfix() # Generate blocks for finite difference scenarios def build_block_scenarios(b, s): # Generate model for the finite difference scenario - b.transfer_attributes_from(mod.base_model.clone()) + b.transfer_attributes_from(model.base_model.clone()) # Forward/Backward difference have a stationary case (s == 0), no parameter to perturb if self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: if s == 0: return - param = mod.parameter_scenarios[s] + param = model.parameter_scenarios[s] # Grabbing the index of the parameter without the "base_model" precursor base_model_ind = param.name.split('.').index('base_model') @@ -944,12 +942,12 @@ def build_block_scenarios(b, s): pass # Update parameter values for the given finite difference scenario - pyo.ComponentUID(param_loc).find_component_on(b).set_value(mod.base_model.unknown_parameters[param] * (1 + diff)) - mod.scenario_blocks = pyo.Block(mod.scenarios, rule=build_block_scenarios) + pyo.ComponentUID(param_loc).find_component_on(b).set_value(model.base_model.unknown_parameters[param] * (1 + diff)) + model.scenario_blocks = pyo.Block(model.scenarios, rule=build_block_scenarios) # To-Do: this might have to change if experiment inputs have # a different value in the Suffix (currently it is the CUID) - design_vars = [k for k, v in mod.scenario_blocks[0].experiment_inputs.items()] + design_vars = [k for k, v in model.scenario_blocks[0].experiment_inputs.items()] # Add constraints to equate block design with global design: for ind, d in enumerate(design_vars): @@ -959,48 +957,48 @@ def build_block_scenarios(b, s): def global_design_fixing(m, s): if s == 0: return pyo.Constraint.Skip - ref_design_var = mod.scenario_blocks[0].experiment_inputs[d] + ref_design_var = model.scenario_blocks[0].experiment_inputs[d] ref_design_var_loc = ".".join(ref_design_var.get_repr().split('.')[0:]) - block_design_var = pyo.ComponentUID(ref_design_var_loc).find_component_on(mod.scenario_blocks[s]) + block_design_var = pyo.ComponentUID(ref_design_var_loc).find_component_on(model.scenario_blocks[s]) return d == block_design_var - setattr(mod, con_name, pyo.Constraint(mod.scenarios, rule=global_design_fixing)) + setattr(model, con_name, pyo.Constraint(model.scenarios, rule=global_design_fixing)) # Clean up the base model used to generate the scenarios - mod.del_component(mod.base_model) + model.del_component(model.base_model) # ToDo: consider this logic? Multi-block systems need something more fancy self._built_scenarios = True # Create objective function - def create_objective_function(self, mod=None): + def create_objective_function(self, model=None): """ Generates the objective function as an expression and as a Pyomo Objective object - The function alters the ``mod`` input. + The function alters the ``model`` input. - In the single experiment case, ``mod`` will be self.model. In the - multi-experiment case, ``mod`` will be one experiment to be enumerated. + In the single experiment case, ``model`` will be self.model. In the + multi-experiment case, ``model`` will be one experiment to be enumerated. Parameters ---------- - mod: model to add finite difference scenarios + model: model to add finite difference scenarios """ - if mod is None: - mod = self.model + if model is None: + model = self.model small_number = 1e-10 # Make objective block for constraints connected to objective - mod.obj_cons = pyo.Block() + model.obj_cons = pyo.Block() # Assemble the FIM matrix. This is helpful for initialization! fim_vals = [ - mod.fim[bu, un].value - for i, bu in enumerate(mod.parameter_names) - for j, un in enumerate(mod.parameter_names) + model.fim[bu, un].value + for i, bu in enumerate(model.parameter_names) + for j, un in enumerate(model.parameter_names) ] - fim = np.array(fim_vals).reshape(len(mod.parameter_names), len(mod.parameter_names)) + fim = np.array(fim_vals).reshape(len(model.parameter_names), len(model.parameter_names)) ### Initialize the Cholesky decomposition matrix if self.Cholesky_option and self.objective_option == ObjectiveLib.det: @@ -1011,15 +1009,15 @@ def create_objective_function(self, mod=None): # If the smallest eigenvalue is (practically) negative, add a diagonal matrix to make it positive definite small_number = 1e-10 if min(eig) < small_number: - fim = fim + np.eye(len(mod.parameter_names)) * (small_number - min(eig)) + fim = fim + np.eye(len(model.parameter_names)) * (small_number - min(eig)) # Compute the Cholesky decomposition of the FIM matrix L = np.linalg.cholesky(fim) # Initialize the Cholesky matrix - for i, c in enumerate(mod.parameter_names): - for j, d in enumerate(mod.parameter_names): - mod.L_ele[c, d].value = L[i, j] + for i, c in enumerate(model.parameter_names): + for j, d in enumerate(model.parameter_names): + model.L[c, d].value = L[i, j] def cholesky_imp(m, c, d): """ @@ -1028,11 +1026,11 @@ def cholesky_imp(m, c, d): # If the row is greater than or equal to the column, we are in the # lower traingle region of the L and FIM matrices. # This region is where our equations are well-defined. - if list(mod.parameter_names).index(c) >= list(mod.parameter_names).index(d): - return mod.fim[c, d] == sum( - mod.L_ele[c, mod.parameter_names.at(k + 1)] - * mod.L_ele[d, mod.parameter_names.at(k + 1)] - for k in range(list(mod.parameter_names).index(d) + 1) + if list(model.parameter_names).index(c) >= list(model.parameter_names).index(d): + return model.fim[c, d] == sum( + model.L[c, model.parameter_names.at(k + 1)] + * model.L[d, model.parameter_names.at(k + 1)] + for k in range(list(model.parameter_names).index(d) + 1) ) else: # This is the empty half of L above the diagonal @@ -1042,14 +1040,14 @@ def trace_calc(m): """ Calculate FIM elements. Can scale each element with 1000 for performance """ - return mod.trace == sum(mod.fim[j, j] for j in mod.parameter_names) + return model.trace == sum(model.fim[j, j] for j in model.parameter_names) def det_general(m): r"""Calculate determinant. Can be applied to FIM of any size. det(A) = \sum_{\sigma in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) Use permutation() to get permutations, sgn() to get signature """ - r_list = list(range(len(mod.parameter_names))) + r_list = list(range(len(model.parameter_names))) # get all permutations object_p = permutations(r_list) list_p = list(object_p) @@ -1061,7 +1059,7 @@ def det_general(m): x_order = list_p[i] # sigma_i is the value in the i-th position after the reordering \sigma for x in range(len(x_order)): - for y, element in enumerate(mod.parameter_names): + for y, element in enumerate(model.parameter_names): if x_order[x] == y: name_order.append(element) @@ -1069,37 +1067,37 @@ def det_general(m): det_perm = sum( self._sgn(list_p[d]) * sum( - mod.fim[each, name_order[b]] - for b, each in enumerate(mod.parameter_names) + model.fim[each, name_order[b]] + for b, each in enumerate(model.parameter_names) ) for d in range(len(list_p)) ) - return mod.det == det_perm + return model.det == det_perm if self.Cholesky_option and self.objective_option == ObjectiveLib.det: - mod.obj_cons.cholesky_cons = pyo.Constraint( - mod.parameter_names, mod.parameter_names, rule=cholesky_imp + model.obj_cons.cholesky_cons = pyo.Constraint( + model.parameter_names, model.parameter_names, rule=cholesky_imp ) - mod.Obj = pyo.Objective( - expr=2 * sum(pyo.log10(mod.L_ele[j, j]) for j in mod.parameter_names), + model.objective = pyo.Objective( + expr=2 * sum(pyo.log10(model.L[j, j]) for j in model.parameter_names), sense=pyo.maximize, ) elif self.objective_option == ObjectiveLib.det: # if not cholesky but determinant, calculating det and evaluate the OBJ with det - mod.det = pyo.Var(initialize=np.linalg.det(fim), bounds=(small_number, None)) - mod.obj_cons.det_rule = pyo.Constraint(rule=det_general) - mod.Obj = pyo.Objective(expr=pyo.log10(mod.det), sense=pyo.maximize) + model.det = pyo.Var(initialize=np.linalg.det(fim), bounds=(small_number, None)) + model.obj_cons.det_rule = pyo.Constraint(rule=det_general) + model.objective = pyo.Objective(expr=pyo.log10(model.det), sense=pyo.maximize) elif self.objective_option == ObjectiveLib.trace: # if not determinant or cholesky, calculating the OBJ with trace - mod.trace = pyo.Var(initialize=np.trace(fim), bounds=(small_number, None)) - mod.obj_cons.trace_rule = pyo.Constraint(rule=trace_calc) - mod.Obj = pyo.Objective(expr=pyo.log10(mod.trace), sense=pyo.maximize) + model.trace = pyo.Var(initialize=np.trace(fim), bounds=(small_number, None)) + model.obj_cons.trace_rule = pyo.Constraint(rule=trace_calc) + model.objective = pyo.Objective(expr=pyo.log10(model.trace), sense=pyo.maximize) elif self.objective_option == ObjectiveLib.zero: # add dummy objective function - mod.Obj = pyo.Objective(expr=0) + model.objective = pyo.Objective(expr=0) else: # something went wrong! raise DeveloperError( @@ -1107,22 +1105,22 @@ def det_general(m): ) # Check to see if the model has all the required suffixes - def check_model_labels(self, mod=None): + def check_model_labels(self, model=None): """ Checks if the model contains the necessary suffixes for the DoE model to be constructed automatically. Parameters ---------- - mod: model for suffix checking, Default: None, (self.model) + model: model for suffix checking, Default: None, (self.model) """ - if mod is None: - mod = self.model.base_model + if model is None: + model = self.model.base_model # Check that experimental outputs exist try: - outputs = [k.name for k, v in mod.experiment_outputs.items()] + outputs = [k.name for k, v in model.experiment_outputs.items()] except: RuntimeError( 'Experiment model does not have suffix ' + '"experiment_outputs".' @@ -1130,7 +1128,7 @@ def check_model_labels(self, mod=None): # Check that experimental inputs exist try: - outputs = [k.name for k, v in mod.experiment_inputs.items()] + outputs = [k.name for k, v in model.experiment_inputs.items()] except: RuntimeError( 'Experiment model does not have suffix ' + '"experiment_inputs".' @@ -1138,7 +1136,7 @@ def check_model_labels(self, mod=None): # Check that unknown parameters exist try: - outputs = [k.name for k, v in mod.unknown_parameters.items()] + outputs = [k.name for k, v in model.unknown_parameters.items()] except: RuntimeError( 'Experiment model does not have suffix ' + '"unknown_parameters".' @@ -1146,7 +1144,7 @@ def check_model_labels(self, mod=None): # Check that measurement errors exist try: - outputs = [k.name for k, v in mod.measurement_error.items()] + outputs = [k.name for k, v in model.measurement_error.items()] except: RuntimeError( 'Experiment model does not have suffix ' + '"measurement_error".' @@ -1165,7 +1163,7 @@ def check_model_FIM(self, FIM=None): Parameters ---------- - mod: model for suffix checking, Default: None, (self.model) + model: model for suffix checking, Default: None, (self.model) """ assert FIM.shape == (self.n_parameters, self.n_parameters), "Shape of FIM provided should be n_parameters x n_parameters, or {}, FIM provided has shape: {}".format((self.n_parameters, self.n_parameters), FIM.shape) @@ -1178,7 +1176,7 @@ def check_model_jac(self, jac=None): self.logger.info('Jacobian provided matches expected dimensions from model.') # Update the FIM for the specified model - def update_FIM_prior(self, mod=None, FIM=None): + def update_FIM_prior(self, model=None, FIM=None): """ Updates the prior FIM on the model object. This may be useful when running a loop and the user doesn't want to rebuild the model @@ -1186,30 +1184,30 @@ def update_FIM_prior(self, mod=None, FIM=None): Parameters ---------- - mod: model where FIM prior is to be updated, Default: None, (self.model) + model: model where FIM prior is to be updated, Default: None, (self.model) FIM: 2D np array to be the new FIM prior, Default: None """ - if mod is None: - mod = self.model + if model is None: + model = self.model # Check FIM input if FIM is None: raise ValueError('FIM input for update_FIM_prior must be a 2D, square numpy array.') - assert hasattr(mod, 'fim'), '``fim`` is not defined on the model provided. Please build the model first.' + assert hasattr(model, 'fim'), '``fim`` is not defined on the model provided. Please build the model first.' - self.check_model_FIM(mod, FIM) + self.check_model_FIM(model, FIM) # Update FIM prior - for ind1, p1 in enumerate(mod.parameter_names): - for ind2, p2 in enumerate(mod.parameter_names): - mod.prior_FIM[p1, p2].set_value(FIM[ind1, ind2]) + for ind1, p1 in enumerate(model.parameter_names): + for ind2, p2 in enumerate(model.parameter_names): + model.prior_FIM[p1, p2].set_value(FIM[ind1, ind2]) self.logger.info('FIM prior has been updated.') # ToDo: Add an update function for the parameter values? --> closed loop parameter estimation? # Or leave this to the user????? - def udpate_unknown_parameter_values(self, mod=None, param_vals=None): + def udpate_unknown_parameter_values(self, model=None, param_vals=None): return # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) @@ -1222,7 +1220,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): Parameters ---------- - mod: model to perform the full factorial exploration on + model: model to perform the full factorial exploration on design_ranges: dict of lists, of the form {: [start, stop, numsteps]} method: string to specify which method should be used options are ``kaug`` and ``sequential`` @@ -1235,11 +1233,11 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): # Make new model for factorial design self.factorial_model = self.experiment.get_labeled_model(**self.args).clone() - mod = self.factorial_model + model = self.factorial_model # Permute the inputs to be aligned with the experiment input indicies design_ranges_enum = {k: np.linspace(*v) for k, v in design_ranges.items()} - design_map = {ind: (k[0].name, k[0]) for ind, k in enumerate(mod.experiment_inputs.items())} + design_map = {ind: (k[0].name, k[0]) for ind, k in enumerate(model.experiment_inputs.items())} # Make the full space try: @@ -1257,7 +1255,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): # ToDo: Add more objetive types? i.e., modified-E; G-opt; V-opt; etc? # ToDo: Also, make this a result object, or more user friendly. - fim_factorial_results = {k.name: [] for k, v in mod.experiment_inputs.items()} + fim_factorial_results = {k.name: [] for k, v in model.experiment_inputs.items()} fim_factorial_results.update({'log10 D-opt': [], 'log10 A-opt': [], 'log10 E-opt': [], 'log10 ME-opt': [], 'solve_time': [], }) succeses = 0 @@ -1284,7 +1282,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): self.logger.info("This is run %s out of %s.", curr_point, total_points) # Attempt the FIM computation - self.compute_FIM(mod=mod, method=method) + self.compute_FIM(model=model, method=method) succeses += 1 # iteration time @@ -1331,7 +1329,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): ME_opt = np.log10(np.linalg.cond(FIM)) # Append the values for each of the experiment inputs - for k, v in mod.experiment_inputs.items(): + for k, v in model.experiment_inputs.items(): fim_factorial_results[k.name].append(pyo.value(k)) fim_factorial_results['log10 D-opt'].append(D_opt) @@ -1715,7 +1713,7 @@ def _heatmap( plt.pyplot.title(title_text + ": E-optimality") plt.pyplot.show() - # modified E-optimality + # Modified E-optimality fig = plt.pyplot.figure() plt.pyplot.rc("axes", titlesize=font_axes) plt.pyplot.rc("axes", labelsize=font_axes) @@ -1739,26 +1737,26 @@ def _heatmap( # Gets the FIM from an existing model - def get_FIM(self, mod=None): + def get_FIM(self, model=None): """ Gets the FIM values from the model specified Parameters ---------- - mod: model to grab FIM from, Default: None, (self.model) + model: model to grab FIM from, Default: None, (self.model) Returns ------- FIM: 2D list representation of the FIM (can be cast to numpy) """ - if mod is None: - mod = self.model + if model is None: + model = self.model - assert hasattr(mod, 'fim'), "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" + assert hasattr(model, 'fim'), "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" - fim_vals = [pyo.value(mod.fim[i, j]) for i in mod.parameter_names for j in mod.parameter_names] - fim_np = np.array(fim_vals).reshape((len(mod.parameter_names), len(mod.parameter_names))) + fim_vals = [pyo.value(model.fim[i, j]) for i in model.parameter_names for j in model.parameter_names] + fim_np = np.array(fim_vals).reshape((len(model.parameter_names), len(model.parameter_names))) # FIM is a lower triangular matrix for the optimal DoE problem. # Exploit symmetry to fill in the zeros. @@ -1770,38 +1768,38 @@ def get_FIM(self, mod=None): return [list(row) for row in list(fim_np)] # Gets the sensitivity matrix from an existing model - def get_sensitivity_matrix(self, mod=None): + def get_sensitivity_matrix(self, model=None): """ Gets the sensitivity matrix (Q) values from the model specified. Parameters ---------- - mod: model to grab Q from, Default: None, (self.model) + model: model to grab Q from, Default: None, (self.model) Returns ------- Q: 2D list representation of the sensitivity matrix (can be cast to numpy) """ - if mod is None: - mod = self.model + if model is None: + model = self.model - assert hasattr(mod, 'sensitivity_jacobian'), "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" + assert hasattr(model, 'sensitivity_jacobian'), "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" - Q_vals = [pyo.value(mod.sensitivity_jacobian[i, j]) for i in mod.output_names for j in mod.parameter_names] - Q_np = np.array(Q_vals).reshape((len(mod.output_names), len(mod.parameter_names))) + Q_vals = [pyo.value(model.sensitivity_jacobian[i, j]) for i in model.output_names for j in model.parameter_names] + Q_np = np.array(Q_vals).reshape((len(model.output_names), len(model.parameter_names))) return [list(row) for row in list(Q_np)] # Gets the experiment input values from an existing model - def get_experiment_input_values(self, mod=None): + def get_experiment_input_values(self, model=None): """ Gets the experiment input values (experimental design) from the model specified. Parameters ---------- - mod: model to grab the experimental design from, + model: model to grab the experimental design from, default: None, (self.model) Returns @@ -1809,27 +1807,27 @@ def get_experiment_input_values(self, mod=None): d: 1D list of experiment input values (optimal or specified design) """ - if mod is None: - mod = self.model + if model is None: + model = self.model - if not hasattr(mod, 'experiment_inputs'): - assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, 'experiment_inputs'): + assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - d_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].experiment_inputs.items()] + d_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].experiment_inputs.items()] else: - d_vals = [pyo.value(k) for k, v in mod.experiment_inputs.items()] + d_vals = [pyo.value(k) for k, v in model.experiment_inputs.items()] return d_vals # Gets the unknown parameter values from an existing model - def get_unknown_parameter_values(self, mod=None): + def get_unknown_parameter_values(self, model=None): """ Gets the unknown parameter values (theta) from the model specified. Parameters ---------- - mod: model to grab theta from, + model: model to grab theta from, default: None, (self.model) Returns @@ -1837,27 +1835,27 @@ def get_unknown_parameter_values(self, mod=None): theta: 1D list of unknown parameter values at which this experiment was designed """ - if mod is None: - mod = self.model + if model is None: + model = self.model - if not hasattr(mod, 'unknown_parameters'): - assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, 'unknown_parameters'): + assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - theta_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].unknown_parameters.items()] + theta_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].unknown_parameters.items()] else: - theta_vals = [pyo.value(k) for k, v in mod.unknown_parameters.items()] + theta_vals = [pyo.value(k) for k, v in model.unknown_parameters.items()] return theta_vals # Gets the experiment output values from an existing model - def get_experiment_output_values(self, mod=None): + def get_experiment_output_values(self, model=None): """ Gets the experiment output values (y hat) from the model specified. Parameters ---------- - mod: model to grab y hat from, + model: model to grab y hat from, default: None, (self.model) Returns @@ -1865,29 +1863,29 @@ def get_experiment_output_values(self, mod=None): y_hat: 1D list of experiment output values from the design experiment """ - if mod is None: - mod = self.model + if model is None: + model = self.model - if not hasattr(mod, 'experiment_outputs'): - assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, 'experiment_outputs'): + assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - y_hat_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].measurement_error.items()] + y_hat_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].measurement_error.items()] else: - y_hat_vals = [pyo.value(k) for k, v in mod.measurement_error.items()] + y_hat_vals = [pyo.value(k) for k, v in model.measurement_error.items()] return y_hat_vals # ToDo: For more complicated error structures, this should become # get cov_y, or so, and this method will be deprecated # Gets the measurement error values from an existing model - def get_measurement_error_values(self, mod=None): + def get_measurement_error_values(self, model=None): """ Gets the experiment output values (sigma) from the model specified. Parameters ---------- - mod: model to grab sigma values from, + model: model to grab sigma values from, default: None, (self.model) Returns @@ -1895,15 +1893,15 @@ def get_measurement_error_values(self, mod=None): sigma_diag: 1D list of measurement errors used to design the experiment """ - if mod is None: - mod = self.model + if model is None: + model = self.model - if not hasattr(mod, 'measurement_error'): - assert hasattr(mod, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, 'measurement_error'): + assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - sigma_vals = [pyo.value(k) for k, v in mod.scenario_blocks[0].measurement_error.items()] + sigma_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].measurement_error.items()] else: - sigma_vals = [pyo.value(k) for k, v in mod.measurement_error.items()] + sigma_vals = [pyo.value(k) for k, v in model.measurement_error.items()] return sigma_vals From 2476c3bc6df5e2292fb16bf20ba166c69e752fb7 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:06:50 -0400 Subject: [PATCH 045/203] Updated test file with naming changes --- pyomo/contrib/doe/redesign/test_build.py | 162 ++--------------------- 1 file changed, 10 insertions(+), 152 deletions(-) diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 8636b6dc05f..0d1d84b217b 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -13,7 +13,7 @@ for ind, fd in enumerate(['central', 'backward', 'forward']): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj[ind] = DesignOfExperiments_( + doe_obj[ind] = DesignOfExperiments( experiment, fd_formula='central', step=1e-3, @@ -37,7 +37,7 @@ ind = 3 -doe_obj[ind] = DesignOfExperiments_( +doe_obj[ind] = DesignOfExperiments( experiment, fd_formula='central', step=1e-3, @@ -58,86 +58,12 @@ ) doe_obj[ind].model.set_blocks = pyo.Set(initialize=[0, 1, 2]) doe_obj[ind].model.block_instances = pyo.Block(doe_obj[ind].model.set_blocks) -doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[0]) -doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[1]) -doe_obj[ind].create_doe_model(mod=doe_obj[ind].model.block_instances[2]) -# doe_obj[ind].run_doe() +doe_obj[ind].create_doe_model(model=doe_obj[ind].model.block_instances[0]) +doe_obj[ind].create_doe_model(model=doe_obj[ind].model.block_instances[1]) +doe_obj[ind].create_doe_model(model=doe_obj[ind].model.block_instances[2]) print('Multi-block build complete') -# Old interface comparison -def create_model(m=None, ): - experiment = FullReactorExperiment(data_ex, 10, 3) - m = experiment.get_labeled_model().clone() - return m - -### Define inputs -# Control time set [h] -t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] -# Define parameter nominal value -parameter_dict = {"A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} - -# measurement object -measurements = MeasurementVariables() -measurements.add_variables( - "CA", # name of measurement - indices={0: t_control}, # indices of measurement - time_index_position=0, - variance=1e-2, -) # position of time index - -measurements.add_variables( - "CB", # name of measurement - indices={0: t_control}, # indices of measurement - time_index_position=0, - variance=1e-2, -) # position of time index - -measurements.add_variables( - "CC", # name of measurement - indices={0: t_control}, # indices of measurement - time_index_position=0, - variance=1e-2, -) # position of time index - -# design object -exp_design = DesignVariables() - -# add CAO as design variable -exp_design.add_variables( - "CA", # name of design variable - indices={0: [0]}, # indices of design variable - time_index_position=0, # position of time index - values=[5], # nominal value of design variable - lower_bounds=1, # lower bound of design variable - upper_bounds=5, # upper bound of design variable -) - -# add T as design variable -exp_design.add_variables( - "T", # name of design variable - indices={0: t_control}, # indices of design variable - time_index_position=0, # position of time index - values=[ - 500, - 300, - 300, - 300, - 300, - 300, - 300, - 300, - 300, - ], # nominal value of design variable - lower_bounds=300, # lower bound of design variable - upper_bounds=700, # upper bound of design variable -) - -design_names = exp_design.variable_names -exp1 = [5, 500, 300, 300, 300, 300, 300, 300, 300, 300] -exp1_design_dict = dict(zip(design_names, exp1)) -exp_design.update_values(exp1_design_dict) - # add a prior information (scaled FIM with T=500 and T=300 experiments) # prior = np.asarray( # [ @@ -150,48 +76,6 @@ def create_model(m=None, ): prior = None -doe_object = DesignOfExperiments( - parameter_dict, # dictionary of parameters - exp_design, # design variables - measurements, # measurement variables - create_model, # function to create model - only_compute_fim_lower=True, -) - -square_result, optimize_result = doe_object.stochastic_program( - if_optimize=True, # if optimize - if_Cholesky=True, # if use Cholesky decomposition - scale_nominal_param_value=True, # if scale nominal parameter value - objective_option="det", # objective option -) - -doe_object2 = DesignOfExperiments( - parameter_dict, # dictionary of parameters - exp_design, # design variables - measurements, # measurement variables - create_model, # function to create model - only_compute_fim_lower=True, -) - -square_result2, optimize_result2 = doe_object2.stochastic_program( - if_optimize=True, # if optimize - if_Cholesky=True, # if use Cholesky decomposition - scale_nominal_param_value=False, # if scale nominal parameter value - objective_option="det", # objective option -) - -# Testing the kaug runs -doe_object3 = DesignOfExperiments( - parameter_dict, # dictionary of parameters - exp_design, # design variables - measurements, # measurement variables - create_model, # function to create model - only_compute_fim_lower=True, -) - -res = doe_object3.compute_FIM(scale_nominal_param_value=True) -res.result_analysis() - design_ranges = { 'CA[0]': [1, 5, 3], 'T[0]': [300, 700, 3], @@ -202,40 +86,17 @@ def create_model(m=None, ): doe_obj[0].compute_FIM(method='sequential') -print(res.FIM) print(doe_obj[0].kaug_FIM) # Optimal values print("Optimal values for determinant optimized experimental design:") -print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.Obj))) -print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.Obj))) -print("Old formulation, scaled: {}".format(pyo.value(optimize_result.model.Obj))) -print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) - -# Old values -FIM_vals_old = [pyo.value(optimize_result.model.fim[i, j]) for i in optimize_result.model.regression_parameters for j in optimize_result.model.regression_parameters] -L_vals_old = [pyo.value(optimize_result.model.L_ele[i, j]) for i in optimize_result.model.regression_parameters for j in optimize_result.model.regression_parameters] -Q_vals_old = [pyo.value(optimize_result.model.sensitivity_jacobian[i, j]) for i in optimize_result.model.regression_parameters for j in optimize_result.model.measured_variables] -sigma_inv_old = [1 / v for k,v in doe_object.measurement_vars.variance.items()] - -FIM_vals_old_np = np.array(FIM_vals_old).reshape((4, 4)) - -for i in range(4): - for j in range(4): - if j > i: - FIM_vals_old_np[j, i] = FIM_vals_old_np[i, j] - -L_vals_old_np = np.array(L_vals_old).reshape((4, 4)) -Q_vals_old_np = np.array(Q_vals_old).reshape((4, 27)) - -sigma_inv_old_np = np.zeros((27, 27)) -for i in range(27): - sigma_inv_old_np[i, i] = sigma_inv_old[i] +print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.objective))) +print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.objective))) # New values FIM_vals_new = [pyo.value(doe_obj[1].model.fim[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] -L_vals_new = [pyo.value(doe_obj[1].model.L_ele[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] +L_vals_new = [pyo.value(doe_obj[1].model.L[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] Q_vals_new = [pyo.value(doe_obj[1].model.sensitivity_jacobian[i, j]) for i in doe_obj[1].model.output_names for j in doe_obj[1].model.parameter_names] sigma_inv_new = [1 / v for k,v in doe_obj[1].model.scenario_blocks[0].measurement_error.items()] param_vals = np.array([[v for k, v in doe_obj[1].model.scenario_blocks[0].unknown_parameters.items()], ]) @@ -258,7 +119,6 @@ def create_model(m=None, ): # Comparing values from compute FIM print("Results from using compute FIM (first old, then new)") -print(res.FIM) print(doe_obj[0].kaug_FIM) print(doe_obj[0].seq_FIM) print(np.log10(np.linalg.det(doe_obj[0].kaug_FIM))) @@ -295,11 +155,9 @@ def create_model(m=None, ): # Optimal values print("Optimal values for determinant optimized experimental design:") -print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.Obj))) -print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.Obj))) +print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.objective))) +print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.objective))) print("New formulation, rescaled: {}".format(np.log10(np.linalg.det(rescaled_FIM)))) -print("Old formulation, scaled: {}".format(pyo.value(optimize_result.model.Obj))) -print("Old formulation, unscaled: {}".format(pyo.value(optimize_result2.model.Obj))) # Draw figures sens_vars = ['CA[0]', 'T[0]'] From 9a71ad70f46da1f2b9ad9cc9149b4afc6cb37260 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:23:33 -0400 Subject: [PATCH 046/203] Added more results data Wanted to be able to re-run the analysis with all the required inputs for the model barring the optional input ``args`` from the user. As an aside, the L_init, jac_init, and fim_init values may be moot at this point. --- pyomo/contrib/doe/doe.py | 44 +++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 3fe6c788d68..1db95435ad2 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -247,6 +247,10 @@ def run_doe(self, model=None, results_file=None): # Add the objective function to the model self.create_objective_function(model=model) + + # Track time required to build the DoE model + build_time = sp_timer.toc(msg=None) + self.logger.info("Succesfully built the DoE model.\nBuild time: %0.1f seconds" % build_time) # Solve the square problem first to initialize the fim and # sensitivity constraints @@ -258,6 +262,11 @@ def run_doe(self, model=None, results_file=None): model.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) self.solver.solve(self.model, tee=self.tee) + + # Track time to initialize the DoE model + initialization_time = sp_timer.toc(msg=None) + self.logger.info("Succesfully initialized the DoE model.\nInitialization time: %0.1f seconds" % initialization_time) + model.dummy_obj.deactivate() # Reactivate objective and unfix experimental design decisions @@ -281,19 +290,19 @@ def run_doe(self, model=None, results_file=None): # Solve the full model, which has now been initialized with the square solve self.solver.solve(model, tee=self.tee) - # Finish timing + # Track time used to solve the DoE model solve_time = sp_timer.toc(msg=None) - # TODO: CHANGE THIS FOLLOWING LINE WITH THE UPDATED SOLUTION TIME BREAKDOWN - self.logger.info("Succesfully optimized experiment.\nElapsed time: %0.1f seconds" % solve_time) + + self.logger.info("Succesfully optimized experiment.\nSolve time: %0.1f seconds" % solve_time) + self.logger.info("Total time for build, initialization, and solve: %0.1f seconds" % (build_time + initialization_time + solve_time)) - # ToDo: Make this more complicated? --> Should results be an object? Or just a dict? - # Populate results object; Important info: FIM, Q, outputs, inputs, param values, - # measurement error, prior FIM, + # fim_local = self.get_FIM() # Make sure stale results don't follow the DoE object instance self.results = {} + # Important quantities for optimal design self.results['FIM'] = fim_local self.results['Sensitivity Matrix'] = self.get_sensitivity_matrix() self.results['Experiment Design'] = self.get_experiment_input_values() @@ -304,18 +313,25 @@ def run_doe(self, model=None, results_file=None): self.results['Prior FIM'] = [list(row) for row in list(self.prior_FIM)] # Saving some stats on the FIM for convenience + self.results['Objective expression'] = str(self.objective_option).split('.')[-1] self.results['log10 A-opt'] = np.log10(np.trace(fim_local)) self.results['log10 D-opt'] = np.log10(np.linalg.det(fim_local)) self.results['log10 E-opt'] = np.log10(min(np.linalg.eig(fim_local)[0])) self.results['FIM Condition Number'] = np.linalg.cond(fim_local) - self.results['Wall-clock Time'] = solve_time - - # ToDo: Add ``useful`` fields to the results object? - # objective type (i.e., det, trace, etc.) - # Finite Difference Formula type - # Finite Difference step size - # If parameter scaling is used or not (self.scale_nominal_param_value) - # + + # Solve timing stats + self.results['Build Time'] = build_time + self.results['Initialization Time'] = initialization_time + self.results['Solve Time'] = solve_time + self.results['Wall-clock Time'] = build_time + initialization_time + solve_time + + # Settings used to generate the optimal DoE + self.results['Finite Difference Scheme'] = str(self.fd_formula).split('.')[-1] + self.results['Finite Difference Step'] = self.step + self.results['Nominal Parameter Scaling'] = self.scale_nominal_param_value + + # ToDo: Add more useful fields to the results object? + # ToDo: Add MetaData from the user to the results object? Or leave to the user? # If the user specifies to save the file, do it here as a json if results_file is not None: From 4c50c6425ffa1d438cc0719ea915247be1a292fe Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 11 Jul 2024 14:03:40 -0400 Subject: [PATCH 047/203] Removed stale imports, updated ordering --- pyomo/contrib/doe/doe.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 1db95435ad2..c7fde917dc0 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -25,24 +25,19 @@ # publicly, and to permit other to do so. # ___________________________________________________________________________ +import pyomo.environ as pyo +from pyomo.common import DeveloperError +from pyomo.common.timing import TicTocTimer +from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp from pyomo.common.dependencies import numpy as np, numpy_available, pandas as pd, matplotlib as plt -import pyomo.environ as pyo -from pyomo.opt import SolverFactory -import pickle from itertools import permutations, product -import logging from enum import Enum -from pyomo.common.timing import TicTocTimer -from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp -import collections.abc - -import inspect -import json from pathlib import Path -from pyomo.common import DeveloperError +import logging +import json class CalculationMode(Enum): From 43ae0bae195487b0e49dc65e463a8477d4e3bffa Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 11 Jul 2024 14:23:00 -0400 Subject: [PATCH 048/203] Ran Black --- pyomo/contrib/doe/__init__.py | 10 +- pyomo/contrib/doe/doe.py | 923 +++++++++++++++++++++------------- pyomo/contrib/doe/utils.py | 25 +- 3 files changed, 596 insertions(+), 362 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index fc7ec95f53a..2a667660056 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -8,5 +8,11 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -from .doe import DesignOfExperiments, CalculationMode, ObjectiveLib, ModelOptionLib, FiniteDifferenceStep -from .utils import rescale_FIM \ No newline at end of file +from .doe import ( + DesignOfExperiments, + CalculationMode, + ObjectiveLib, + ModelOptionLib, + FiniteDifferenceStep, +) +from .utils import rescale_FIM diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index c7fde917dc0..fafff8f1954 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -30,7 +30,12 @@ from pyomo.common.timing import TicTocTimer from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp -from pyomo.common.dependencies import numpy as np, numpy_available, pandas as pd, matplotlib as plt +from pyomo.common.dependencies import ( + numpy as np, + numpy_available, + pandas as pd, + matplotlib as plt, +) from itertools import permutations, product from enum import Enum @@ -69,7 +74,7 @@ def __init__( experiment, fd_formula="central", step=1e-3, - objective_option='det', + objective_option="det", scale_constant_value=1.0, scale_nominal_param_value=False, prior_FIM=None, @@ -85,9 +90,9 @@ def __init__( _only_compute_fim_lower=True, ): """ - This package enables model-based design of experiments analysis with Pyomo. + This package enables model-based design of experiments analysis with Pyomo. Both direct optimization and enumeration modes are supported. - + The package has been refactored from its original form as of ##/##/##24. See the documentation for more information. @@ -101,7 +106,7 @@ def __init__( Finite difference formula for computing the sensitivy matrix. Must be one of [``central``, ``forward``, ``backward``], default: ``central`` step: - Relative step size for the finite difference formula. + Relative step size for the finite difference formula. default: 1e-3 objective_option: String representation of the objective option. Current available options are: @@ -109,12 +114,12 @@ def __init__( A-optimality) scale_constant_value: Constant scaling for the sensitivty matrix. Every element will be multiplied by this - scaling factor. + scaling factor. default: 1 scale_nominal_param_value: Boolean for whether or not to scale the sensitivity matrix by the nominal parameter values. Every column of the sensitivity matrix will be divided by the respective - nominal paramter value. + nominal paramter value. default: False prior_FIM: 2D numpy array representing information from prior experiments. If no value is given, @@ -150,29 +155,31 @@ def __init__( Specify the level of the logger. Change to logging.DEBUG for all messages. """ # Assert that the Experiment object has callable ``get_labeled_model`` function - assert callable(getattr(experiment, 'get_labeled_model')), 'The experiment object must have a ``get_labeled_model`` function' - + assert callable( + getattr(experiment, "get_labeled_model") + ), "The experiment object must have a ``get_labeled_model`` function" + # Set the experiment object from the user self.experiment = experiment - + # Set the finite difference and subsequent step size self.fd_formula = FiniteDifferenceStep(fd_formula) self.step = step # Set the objective type and scaling options: self.objective_option = ObjectiveLib(objective_option) - + self.scale_constant_value = scale_constant_value self.scale_nominal_param_value = scale_nominal_param_value - + # Set the prior FIM (will be checked upon model construction) self.prior_FIM = prior_FIM - + # Set the initial values for the jacobian, fim, and L matrices self.jac_initial = jac_initial self.fim_initial = fim_initial self.L_initial = L_initial - + # Set the lower bound on the Cholesky lower triangular matrix self.L_LB = L_LB @@ -186,9 +193,9 @@ def __init__( solver.options["halt_on_ampl_error"] = "yes" solver.options["max_iter"] = 3000 self.solver = solver - + self.tee = tee - + # Set args as an empty dict if no arguments are passed if args is None: args = {} @@ -201,30 +208,30 @@ def __init__( # Set the private options if passed (only developers should pass these) self.Cholesky_option = _Cholesky_option self.only_compute_fim_lower = _only_compute_fim_lower - + # model attribute to avoid rebuilding models self.model = pyo.ConcreteModel() # Build empty model - + # Empty results object self.results = {} - + # May need this attribute for more complicated structures? # (i.e., no model rebuilding for large models with sequential) self._built_scenarios = False - + # Perform doe def run_doe(self, model=None, results_file=None): """ Runs DoE for a single experiment estimation. Can save results in a file based on the flag. - + Parameters ---------- model: model to run the DoE, default: None (self.model) results_file: string name of the file path to save the results to in the form of a .json file default: None --> don't save - + """ # Start timer sp_timer = TicTocTimer() @@ -234,7 +241,7 @@ def run_doe(self, model=None, results_file=None): # Model is none, set it to self.model if model is None: model = self.model - + # ToDo: potentially work with this for more complicated models # Create the full DoE model (build scenarios for F.D. scheme) if not self._built_scenarios: @@ -245,8 +252,10 @@ def run_doe(self, model=None, results_file=None): # Track time required to build the DoE model build_time = sp_timer.toc(msg=None) - self.logger.info("Succesfully built the DoE model.\nBuild time: %0.1f seconds" % build_time) - + self.logger.info( + "Succesfully built the DoE model.\nBuild time: %0.1f seconds" % build_time + ) + # Solve the square problem first to initialize the fim and # sensitivity constraints # Deactivate objective expression and objective constraints (on a block), and fix design variables @@ -254,137 +263,162 @@ def run_doe(self, model=None, results_file=None): model.obj_cons.deactivate() for comp, _ in model.scenario_blocks[0].experiment_inputs.items(): comp.fix() - + model.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) self.solver.solve(self.model, tee=self.tee) # Track time to initialize the DoE model initialization_time = sp_timer.toc(msg=None) - self.logger.info("Succesfully initialized the DoE model.\nInitialization time: %0.1f seconds" % initialization_time) + self.logger.info( + "Succesfully initialized the DoE model.\nInitialization time: %0.1f seconds" + % initialization_time + ) model.dummy_obj.deactivate() - + # Reactivate objective and unfix experimental design decisions for comp, _ in model.scenario_blocks[0].experiment_inputs.items(): comp.unfix() model.objective.activate() model.obj_cons.activate() - + # ToDo: add a ``get FIM from model`` function # If the model has L, initialize it with the solved FIM - if hasattr(model, 'L'): + if hasattr(model, "L"): # Get the FIM values --> ToDo: add this as a function - fim_vals = [pyo.value(model.fim[i, j]) for i in model.parameter_names for j in model.parameter_names] - fim_np = np.array(fim_vals).reshape((len(model.parameter_names), len(model.parameter_names))) - + fim_vals = [ + pyo.value(model.fim[i, j]) + for i in model.parameter_names + for j in model.parameter_names + ] + fim_np = np.array(fim_vals).reshape( + (len(model.parameter_names), len(model.parameter_names)) + ) + L_vals_sq = np.linalg.cholesky(fim_np) for i, c in enumerate(model.parameter_names): for j, d in enumerate(model.parameter_names): model.L[c, d].value = L_vals_sq[i, j] - + # Solve the full model, which has now been initialized with the square solve self.solver.solve(model, tee=self.tee) # Track time used to solve the DoE model solve_time = sp_timer.toc(msg=None) - self.logger.info("Succesfully optimized experiment.\nSolve time: %0.1f seconds" % solve_time) - self.logger.info("Total time for build, initialization, and solve: %0.1f seconds" % (build_time + initialization_time + solve_time)) - - # + self.logger.info( + "Succesfully optimized experiment.\nSolve time: %0.1f seconds" % solve_time + ) + self.logger.info( + "Total time for build, initialization, and solve: %0.1f seconds" + % (build_time + initialization_time + solve_time) + ) + + # fim_local = self.get_FIM() - + # Make sure stale results don't follow the DoE object instance self.results = {} - + # Important quantities for optimal design - self.results['FIM'] = fim_local - self.results['Sensitivity Matrix'] = self.get_sensitivity_matrix() - self.results['Experiment Design'] = self.get_experiment_input_values() - self.results['Experiment Outputs'] = self.get_experiment_output_values() - self.results['Unknown Parameters'] = self.get_unknown_parameter_values() - self.results['Measurement Error'] = self.get_measurement_error_values() - - self.results['Prior FIM'] = [list(row) for row in list(self.prior_FIM)] - + self.results["FIM"] = fim_local + self.results["Sensitivity Matrix"] = self.get_sensitivity_matrix() + self.results["Experiment Design"] = self.get_experiment_input_values() + self.results["Experiment Outputs"] = self.get_experiment_output_values() + self.results["Unknown Parameters"] = self.get_unknown_parameter_values() + self.results["Measurement Error"] = self.get_measurement_error_values() + + self.results["Prior FIM"] = [list(row) for row in list(self.prior_FIM)] + # Saving some stats on the FIM for convenience - self.results['Objective expression'] = str(self.objective_option).split('.')[-1] - self.results['log10 A-opt'] = np.log10(np.trace(fim_local)) - self.results['log10 D-opt'] = np.log10(np.linalg.det(fim_local)) - self.results['log10 E-opt'] = np.log10(min(np.linalg.eig(fim_local)[0])) - self.results['FIM Condition Number'] = np.linalg.cond(fim_local) + self.results["Objective expression"] = str(self.objective_option).split(".")[-1] + self.results["log10 A-opt"] = np.log10(np.trace(fim_local)) + self.results["log10 D-opt"] = np.log10(np.linalg.det(fim_local)) + self.results["log10 E-opt"] = np.log10(min(np.linalg.eig(fim_local)[0])) + self.results["FIM Condition Number"] = np.linalg.cond(fim_local) # Solve timing stats - self.results['Build Time'] = build_time - self.results['Initialization Time'] = initialization_time - self.results['Solve Time'] = solve_time - self.results['Wall-clock Time'] = build_time + initialization_time + solve_time + self.results["Build Time"] = build_time + self.results["Initialization Time"] = initialization_time + self.results["Solve Time"] = solve_time + self.results["Wall-clock Time"] = build_time + initialization_time + solve_time # Settings used to generate the optimal DoE - self.results['Finite Difference Scheme'] = str(self.fd_formula).split('.')[-1] - self.results['Finite Difference Step'] = self.step - self.results['Nominal Parameter Scaling'] = self.scale_nominal_param_value - + self.results["Finite Difference Scheme"] = str(self.fd_formula).split(".")[-1] + self.results["Finite Difference Step"] = self.step + self.results["Nominal Parameter Scaling"] = self.scale_nominal_param_value + # ToDo: Add more useful fields to the results object? # ToDo: Add MetaData from the user to the results object? Or leave to the user? - + # If the user specifies to save the file, do it here as a json if results_file is not None: - assert type(results_file) in [Path, str], "`results_file` must be either a Path object or a string." - with open(results_file, 'w') as file: + assert type(results_file) in [ + Path, + str, + ], "`results_file` must be either a Path object or a string." + with open(results_file, "w") as file: json.dump(self.results, file) - + # Perform multi-experiment doe (sequential, or ``greedy`` approach) def run_multi_doe_sequential(self, N_exp=1): raise NotImplementedError( "Multipled experiment optimization not yet supported." ) - + # Perform multi-experiment doe (simultaneous, optimal approach) def run_multi_doe_simultaneous(self, N_exp=1): raise NotImplementedError( "Multipled experiment optimization not yet supported." ) - + # Compute FIM for the DoE object - def compute_FIM(self, model=None, method='sequential'): + def compute_FIM(self, model=None, method="sequential"): """ Computes the FIM for the experimental design that is initialized from the experiment`s ``get_labeled_model()`` function. - + Parameters ---------- model: model to compute FIM, default: None, (self.compute_FIM_model) method: string to specify which method should be used options are ``kaug`` and ``sequential`` - + Returns ------- computed FIM: 2D numpy array of the FIM """ if model is None: - self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() + self.compute_FIM_model = self.experiment.get_labeled_model( + **self.args + ).clone() model = self.compute_FIM_model - + self.check_model_labels(model=model) - + # Check FIM input, if it exists. Otherwise, set the prior_FIM attribute if self.prior_FIM is None: - self.prior_FIM = np.zeros((len(model.unknown_parameters), len(model.unknown_parameters))) + self.prior_FIM = np.zeros( + (len(model.unknown_parameters), len(model.unknown_parameters)) + ) else: self.check_model_FIM(FIM=self.prior_FIM) - + # ToDo: Decide where the FIM should be saved. - if method == 'sequential': + if method == "sequential": self._sequential_FIM(model=model) self._computed_FIM = self.seq_FIM - elif method == 'kaug': + elif method == "kaug": self._kaug_FIM(model=model) self._computed_FIM = self.kaug_FIM else: - raise ValueError('The method provided, {}, must be either `sequential` or `kaug`'.format(method)) - + raise ValueError( + "The method provided, {}, must be either `sequential` or `kaug`".format( + method + ) + ) + return self._computed_FIM # Use a sequential method to get the FIM @@ -398,75 +432,98 @@ def _sequential_FIM(self, model=None): """ # Build a singular model instance if model is None: - self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() + self.compute_FIM_model = self.experiment.get_labeled_model( + **self.args + ).clone() model = self.compute_FIM_model - + # Create suffix to keep track of parameter scenarios model.parameter_scenarios = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - + # Populate parameter scenarios, and scenario inds based on finite difference scheme if self.fd_formula == FiniteDifferenceStep.central: - model.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(model.unknown_parameters.keys())) - model.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(model.unknown_parameters.keys())) + model.parameter_scenarios.update( + (2 * ind, k) for ind, k in enumerate(model.unknown_parameters.keys()) + ) + model.parameter_scenarios.update( + (2 * ind + 1, k) + for ind, k in enumerate(model.unknown_parameters.keys()) + ) model.scenarios = range(len(model.unknown_parameters) * 2) - elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: - model.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(model.unknown_parameters.keys())) + elif self.fd_formula in [ + FiniteDifferenceStep.forward, + FiniteDifferenceStep.backward, + ]: + model.parameter_scenarios.update( + (ind + 1, k) for ind, k in enumerate(model.unknown_parameters.keys()) + ) model.scenarios = range(len(model.unknown_parameters) + 1) else: # To-Do: add an error message for this as not being implemented yet pass - + # Fix design variables for comp, _ in model.experiment_inputs.items(): comp.fix() - + measurement_vals = [] # In a loop..... # Calculate measurement values for each scenario for s in model.scenarios: param = model.parameter_scenarios[s] - + # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: - diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd + diff = self.step * ( + (-1) ** s + ) # Positive perturbation, even; negative, odd elif self.fd_formula == FiniteDifferenceStep.backward: - diff = self.step * -1 * (s != 0) # Backward always negative perturbation; 0 at s = 0 + diff = ( + self.step * -1 * (s != 0) + ) # Backward always negative perturbation; 0 at s = 0 elif self.fd_formula == FiniteDifferenceStep.forward: - diff = self.step * (s != 0) # Forward always positive; 0 at s = 0 + diff = self.step * (s != 0) # Forward always positive; 0 at s = 0 else: raise DeveloperError( - "Finite difference option not recognized. Please contact the developers as you should not see this error." - ) + "Finite difference option not recognized. Please contact the developers as you should not see this error." + ) diff = 0 pass - + # Update parameter values for the given finite difference scenario param.set_value(model.unknown_parameters[param] * (1 + diff)) - + # Simulate the model self.solver.solve(model) - + # Extract the measurement values for the scenario and append - measurement_vals.append([pyo.value(k) for k, v in model.experiment_outputs.items()]) - + measurement_vals.append( + [pyo.value(k) for k, v in model.experiment_outputs.items()] + ) + # Use the measurement outputs to make the Q matrix measurement_vals_np = np.array(measurement_vals).T - - self.seq_jac = np.zeros((len(model.experiment_outputs.items()), len(model.unknown_parameters.items()))) - + + self.seq_jac = np.zeros( + ( + len(model.experiment_outputs.items()), + len(model.unknown_parameters.items()), + ) + ) + # Counting variable for loop i = 0 - + # Loop over parameter values and grab correct columns for finite difference calculation - + for k, v in model.unknown_parameters.items(): curr_step = v * self.step - + if self.fd_formula == FiniteDifferenceStep.central: - col_1 = 2*i - col_2 = 2*i + 1 + col_1 = 2 * i + col_2 = 2 * i + 1 curr_step *= 2 elif self.fd_formula == FiniteDifferenceStep.forward: col_1 = i @@ -474,18 +531,20 @@ def _sequential_FIM(self, model=None): elif self.fd_formula == FiniteDifferenceStep.backward: col_1 = 0 col_2 = i - + # If scale_nominal_param_value is active, scale by nominal parameter value (v) scale_factor = (1.0 / curr_step) * self.scale_constant_value if self.scale_nominal_param_value: scale_factor *= v - + # Calculate the column of the sensitivity matrix - self.seq_jac[:, i] = (measurement_vals_np[:, col_1] - measurement_vals_np[:, col_2]) * scale_factor - + self.seq_jac[:, i] = ( + measurement_vals_np[:, col_1] - measurement_vals_np[:, col_2] + ) * scale_factor + # Increment the count i += 1 - + # ToDo: As more complex measurement error schemes are put in place, this needs to change # Add independent (non-correlated) measurement error for FIM calculation cov_y = np.zeros((len(model.measurement_error), len(model.measurement_error))) @@ -493,7 +552,7 @@ def _sequential_FIM(self, model=None): for k, v in model.measurement_error.items(): cov_y[count, count] = 1 / v count += 1 - + # Compute and record FIM self.seq_FIM = self.seq_jac.T @ cov_y @ self.seq_jac + self.prior_FIM @@ -502,7 +561,7 @@ def _kaug_FIM(self, model=None): """ Used to compute the FIM using kaug, a sensitivity-based approach that directly computes the FIM. - + Parameters ---------- model: model to compute FIM, default: None, (self.compute_FIM_model) @@ -511,11 +570,13 @@ def _kaug_FIM(self, model=None): # Remake compute_FIM_model if model is None. # compute_FIM_model needs to be the right version for function to work. if model is None: - self.compute_FIM_model = self.experiment.get_labeled_model(**self.args).clone() + self.compute_FIM_model = self.experiment.get_labeled_model( + **self.args + ).clone() model = self.compute_FIM_model - + # add zero (dummy/placeholder) objective function - if not hasattr(model, 'objective'): + if not hasattr(model, "objective"): model.objective = pyo.Objective(expr=0, sense=pyo.minimize) # call k_aug get_dsdp function @@ -523,16 +584,14 @@ def _kaug_FIM(self, model=None): # Deactivate object and fix experimental design decisions to make square for comp, _ in model.experiment_inputs.items(): comp.fix() - + self.solver.solve(model, tee=self.tee) # Probe the solved model for dsdp results (sensitivities s.t. parameters) params_dict = {k.name: v for k, v in model.unknown_parameters.items()} params_names = list(params_dict.keys()) - dsdp_re, col = get_dsdp( - model, params_names, params_dict, tee=self.tee - ) + dsdp_re, col = get_dsdp(model, params_names, params_dict, tee=self.tee) # analyze result dsdp_array = dsdp_re.toarray().T @@ -579,7 +638,6 @@ def _kaug_FIM(self, model=None): else: self.check_model_FIM(FIM=self.prior_FIM) - # Constructing the Covariance of the measurements for the FIM calculation # The following assumes independent measurement error. cov_y = np.zeros((len(model.measurement_error), len(model.measurement_error))) @@ -587,11 +645,11 @@ def _kaug_FIM(self, model=None): for k, v in model.measurement_error.items(): cov_y[count, count] = 1 / v count += 1 - + # ToDo: need to add a covariance matrix for measurements (sigma inverse) # i.e., cov_y = self.cov_y or model.cov_y # Still deciding where this would be best. - + self.kaug_FIM = self.kaug_jac.T @ cov_y @ self.kaug_jac + self.prior_FIM # Create the DoE model (with ``scenarios`` from finite differencing scheme) @@ -600,12 +658,12 @@ def create_doe_model(self, model=None): Add equations to compute sensitivities, FIM, and objective. Builds the DoE model. Adds the scenarios, the sensitivity matrix Q, the FIM, as well as the objective function to the model. - + The function alters the ``model`` input. - - In the single experiment case, ``model`` will be self.model. In the + + In the single experiment case, ``model`` will be self.model. In the multi-experiment case, ``model`` will be one experiment to be enumerated. - + Parameters ---------- model: model to add finite difference scenarios @@ -624,14 +682,29 @@ def create_doe_model(self, model=None): raise ValueError( "Cannot compute determinant with explicit formula if only_compute_fim_lower is True." ) - + # Generate scenarios for finite difference formulae self._generate_scenario_blocks(model=model) - + # Set names for indexing sensitivity matrix (jacobian) and FIM - scen_block_ind = min([k.name.split('.').index('scenario_blocks[0]') for k in model.scenario_blocks[0].unknown_parameters.keys()]) - model.parameter_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in model.scenario_blocks[0].unknown_parameters.keys()]) - model.output_names = pyo.Set(initialize=[".".join(k.name.split('.')[(scen_block_ind + 1):]) for k in model.scenario_blocks[0].experiment_outputs.keys()]) + scen_block_ind = min( + [ + k.name.split(".").index("scenario_blocks[0]") + for k in model.scenario_blocks[0].unknown_parameters.keys() + ] + ) + model.parameter_names = pyo.Set( + initialize=[ + ".".join(k.name.split(".")[(scen_block_ind + 1) :]) + for k in model.scenario_blocks[0].unknown_parameters.keys() + ] + ) + model.output_names = pyo.Set( + initialize=[ + ".".join(k.name.split(".")[(scen_block_ind + 1) :]) + for k in model.scenario_blocks[0].experiment_outputs.keys() + ] + ) def identity_matrix(m, i, j): if i == j: @@ -742,7 +815,7 @@ def jacobian_rule(m, n, p): fd_step_mult = 1 cuid = pyo.ComponentUID(n) param_ind = model.parameter_names.data().index(p) - + # Different FD schemes lead to different scenarios for the computation if self.fd_formula == FiniteDifferenceStep.central: s1 = param_ind * 2 @@ -759,10 +832,12 @@ def jacobian_rule(m, n, p): var_lo = cuid.find_component_on(m.scenario_blocks[s2]) param = model.parameter_scenarios[max(s1, s2)] - param_loc = pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0]) + param_loc = pyo.ComponentUID(param).find_component_on( + model.scenario_blocks[0] + ) param_val = model.scenario_blocks[0].unknown_parameters[param_loc] param_diff = param_val * fd_step_mult * self.step - + if self.scale_nominal_param_value: return ( m.sensitivity_jacobian[n, p] @@ -801,7 +876,7 @@ def fim_rule(m, p, q): """ p_ind = list(model.parameter_names).index(p) q_ind = list(model.parameter_names).index(q) - + # If the row is less than the column, skip the constraint # This logic is consistent with making the FIM a lower # triangular matrix (as is done later in this function) @@ -815,7 +890,11 @@ def fim_rule(m, p, q): m.fim[p, q] == sum( 1 - / model.scenario_blocks[0].measurement_error[pyo.ComponentUID(n).find_component_on(model.scenario_blocks[0])] + / model.scenario_blocks[0].measurement_error[ + pyo.ComponentUID(n).find_component_on( + model.scenario_blocks[0] + ) + ] * m.sensitivity_jacobian[n, p] * m.sensitivity_jacobian[n, q] for n in model.output_names @@ -838,19 +917,19 @@ def fim_rule(m, p, q): for ind_q, q in enumerate(model.parameter_names): if ind_p < ind_q: model.fim[p, q].fix(0.0) - + # Create scenario block structure def _generate_scenario_blocks(self, model=None): """ - Generates the modeling blocks corresponding to the scenarios for + Generates the modeling blocks corresponding to the scenarios for the finite differencing scheme to compute the sensitivity jacobian to compute the FIM. - + The function alters the ``model`` input. - - In the single experiment case, ``model`` will be self.model. In the + + In the single experiment case, ``model`` will be self.model. In the multi-experiment case, ``model`` will be one experiment to be enumerated. - + Parameters ---------- model: model to add finite difference scenarios @@ -861,7 +940,7 @@ def _generate_scenario_blocks(self, model=None): # Generate initial scenario to populate unknown parameter values model.base_model = self.experiment.get_labeled_model(**self.args).clone() - + # Check the model that labels are correct self.check_model_labels(model=model) @@ -871,9 +950,13 @@ def _generate_scenario_blocks(self, model=None): self.n_experiment_inputs = len(model.base_model.experiment_inputs) self.n_experiment_outputs = len(model.base_model.experiment_outputs) - assert (self.n_measurement_error == self.n_experiment_outputs), "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format(self.n_experiment_outputs, self.n_measurement_error) + assert ( + self.n_measurement_error == self.n_experiment_outputs + ), "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( + self.n_experiment_outputs, self.n_measurement_error + ) - self.logger.info('Experiment output and measurement error lengths match.') + self.logger.info("Experiment output and measurement error lengths match.") # Check that the user input FIM and Jacobian are the correct dimension if self.prior_FIM is not None: @@ -888,19 +971,31 @@ def _generate_scenario_blocks(self, model=None): self.check_model_jac(self.jac_initial) else: self.jac_initial = np.eye(self.n_experiment_outputs, self.n_parameters) - - # Make a new Suffix to hold which scenarios are associated with parameters + + # Make a new Suffix to hold which scenarios are associated with parameters model.parameter_scenarios = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - + # Populate parameter scenarios, and scenario inds based on finite difference scheme if self.fd_formula == FiniteDifferenceStep.central: - model.parameter_scenarios.update((2*ind, k) for ind, k in enumerate(model.base_model.unknown_parameters.keys())) - model.parameter_scenarios.update((2*ind + 1, k) for ind, k in enumerate(model.base_model.unknown_parameters.keys())) + model.parameter_scenarios.update( + (2 * ind, k) + for ind, k in enumerate(model.base_model.unknown_parameters.keys()) + ) + model.parameter_scenarios.update( + (2 * ind + 1, k) + for ind, k in enumerate(model.base_model.unknown_parameters.keys()) + ) model.scenarios = range(len(model.base_model.unknown_parameters) * 2) - elif self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: - model.parameter_scenarios.update((ind + 1, k) for ind, k in enumerate(model.base_model.unknown_parameters.keys())) + elif self.fd_formula in [ + FiniteDifferenceStep.forward, + FiniteDifferenceStep.backward, + ]: + model.parameter_scenarios.update( + (ind + 1, k) + for ind, k in enumerate(model.base_model.unknown_parameters.keys()) + ) model.scenarios = range(len(model.base_model.unknown_parameters) + 1) else: raise DeveloperError( @@ -912,71 +1007,86 @@ def _generate_scenario_blocks(self, model=None): # Run base model to get initialized model and check model function for comp, _ in model.base_model.experiment_inputs.items(): comp.fix() - + try: self.solver.solve(model.base_model, tee=self.tee) - self.logger.info('Model from experiment solved.') + self.logger.info("Model from experiment solved.") except: - raise RuntimeError('Model from experiment did not solve appropriately. Make sure the model is well-posed.') - + raise RuntimeError( + "Model from experiment did not solve appropriately. Make sure the model is well-posed." + ) for comp, _ in model.base_model.experiment_inputs.items(): comp.unfix() - # Generate blocks for finite difference scenarios def build_block_scenarios(b, s): # Generate model for the finite difference scenario b.transfer_attributes_from(model.base_model.clone()) - + # Forward/Backward difference have a stationary case (s == 0), no parameter to perturb - if self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]: + if self.fd_formula in [ + FiniteDifferenceStep.forward, + FiniteDifferenceStep.backward, + ]: if s == 0: return - + param = model.parameter_scenarios[s] - + # Grabbing the index of the parameter without the "base_model" precursor - base_model_ind = param.name.split('.').index('base_model') - param_loc = ".".join(param.name.split('.')[(base_model_ind + 1):]) + base_model_ind = param.name.split(".").index("base_model") + param_loc = ".".join(param.name.split(".")[(base_model_ind + 1) :]) # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: - diff = self.step * ((-1) ** s) # Positive perturbation, even; negative, odd + diff = self.step * ( + (-1) ** s + ) # Positive perturbation, even; negative, odd elif self.fd_formula == FiniteDifferenceStep.backward: diff = self.step * -1 # Backward always negative perturbation elif self.fd_formula == FiniteDifferenceStep.forward: - diff = self.step # Forward always positive + diff = self.step # Forward always positive else: # To-Do: add an error message for this as not being implemented yet diff = 0 pass - + # Update parameter values for the given finite difference scenario - pyo.ComponentUID(param_loc).find_component_on(b).set_value(model.base_model.unknown_parameters[param] * (1 + diff)) + pyo.ComponentUID(param_loc).find_component_on(b).set_value( + model.base_model.unknown_parameters[param] * (1 + diff) + ) + model.scenario_blocks = pyo.Block(model.scenarios, rule=build_block_scenarios) - - # To-Do: this might have to change if experiment inputs have + + # To-Do: this might have to change if experiment inputs have # a different value in the Suffix (currently it is the CUID) design_vars = [k for k, v in model.scenario_blocks[0].experiment_inputs.items()] - + # Add constraints to equate block design with global design: for ind, d in enumerate(design_vars): - con_name = 'global_design_eq_con_' + str(ind) - + con_name = "global_design_eq_con_" + str(ind) + # Constraint rule for global design constraints def global_design_fixing(m, s): if s == 0: return pyo.Constraint.Skip ref_design_var = model.scenario_blocks[0].experiment_inputs[d] - ref_design_var_loc = ".".join(ref_design_var.get_repr().split('.')[0:]) - block_design_var = pyo.ComponentUID(ref_design_var_loc).find_component_on(model.scenario_blocks[s]) + ref_design_var_loc = ".".join(ref_design_var.get_repr().split(".")[0:]) + block_design_var = pyo.ComponentUID( + ref_design_var_loc + ).find_component_on(model.scenario_blocks[s]) return d == block_design_var - setattr(model, con_name, pyo.Constraint(model.scenarios, rule=global_design_fixing)) - + + setattr( + model, + con_name, + pyo.Constraint(model.scenarios, rule=global_design_fixing), + ) + # Clean up the base model used to generate the scenarios model.del_component(model.base_model) - + # ToDo: consider this logic? Multi-block systems need something more fancy self._built_scenarios = True @@ -985,21 +1095,21 @@ def create_objective_function(self, model=None): """ Generates the objective function as an expression and as a Pyomo Objective object - + The function alters the ``model`` input. - - In the single experiment case, ``model`` will be self.model. In the + + In the single experiment case, ``model`` will be self.model. In the multi-experiment case, ``model`` will be one experiment to be enumerated. - + Parameters ---------- model: model to add finite difference scenarios """ if model is None: model = self.model - + small_number = 1e-10 - + # Make objective block for constraints connected to objective model.obj_cons = pyo.Block() @@ -1009,7 +1119,9 @@ def create_objective_function(self, model=None): for i, bu in enumerate(model.parameter_names) for j, un in enumerate(model.parameter_names) ] - fim = np.array(fim_vals).reshape(len(model.parameter_names), len(model.parameter_names)) + fim = np.array(fim_vals).reshape( + len(model.parameter_names), len(model.parameter_names) + ) ### Initialize the Cholesky decomposition matrix if self.Cholesky_option and self.objective_option == ObjectiveLib.det: @@ -1020,7 +1132,9 @@ def create_objective_function(self, model=None): # If the smallest eigenvalue is (practically) negative, add a diagonal matrix to make it positive definite small_number = 1e-10 if min(eig) < small_number: - fim = fim + np.eye(len(model.parameter_names)) * (small_number - min(eig)) + fim = fim + np.eye(len(model.parameter_names)) * ( + small_number - min(eig) + ) # Compute the Cholesky decomposition of the FIM matrix L = np.linalg.cholesky(fim) @@ -1037,7 +1151,9 @@ def cholesky_imp(m, c, d): # If the row is greater than or equal to the column, we are in the # lower traingle region of the L and FIM matrices. # This region is where our equations are well-defined. - if list(model.parameter_names).index(c) >= list(model.parameter_names).index(d): + if list(model.parameter_names).index(c) >= list( + model.parameter_names + ).index(d): return model.fim[c, d] == sum( model.L[c, model.parameter_names.at(k + 1)] * model.L[d, model.parameter_names.at(k + 1)] @@ -1096,15 +1212,21 @@ def det_general(m): elif self.objective_option == ObjectiveLib.det: # if not cholesky but determinant, calculating det and evaluate the OBJ with det - model.det = pyo.Var(initialize=np.linalg.det(fim), bounds=(small_number, None)) + model.det = pyo.Var( + initialize=np.linalg.det(fim), bounds=(small_number, None) + ) model.obj_cons.det_rule = pyo.Constraint(rule=det_general) - model.objective = pyo.Objective(expr=pyo.log10(model.det), sense=pyo.maximize) + model.objective = pyo.Objective( + expr=pyo.log10(model.det), sense=pyo.maximize + ) elif self.objective_option == ObjectiveLib.trace: # if not determinant or cholesky, calculating the OBJ with trace model.trace = pyo.Var(initialize=np.trace(fim), bounds=(small_number, None)) model.obj_cons.trace_rule = pyo.Constraint(rule=trace_calc) - model.objective = pyo.Objective(expr=pyo.log10(model.trace), sense=pyo.maximize) + model.objective = pyo.Objective( + expr=pyo.log10(model.trace), sense=pyo.maximize + ) elif self.objective_option == ObjectiveLib.zero: # add dummy objective function @@ -1120,21 +1242,21 @@ def check_model_labels(self, model=None): """ Checks if the model contains the necessary suffixes for the DoE model to be constructed automatically. - + Parameters ---------- model: model for suffix checking, Default: None, (self.model) - + """ if model is None: model = self.model.base_model - + # Check that experimental outputs exist try: outputs = [k.name for k, v in model.experiment_outputs.items()] except: RuntimeError( - 'Experiment model does not have suffix ' + '"experiment_outputs".' + "Experiment model does not have suffix " + '"experiment_outputs".' ) # Check that experimental inputs exist @@ -1142,7 +1264,7 @@ def check_model_labels(self, model=None): outputs = [k.name for k, v in model.experiment_inputs.items()] except: RuntimeError( - 'Experiment model does not have suffix ' + '"experiment_inputs".' + "Experiment model does not have suffix " + '"experiment_inputs".' ) # Check that unknown parameters exist @@ -1150,41 +1272,51 @@ def check_model_labels(self, model=None): outputs = [k.name for k, v in model.unknown_parameters.items()] except: RuntimeError( - 'Experiment model does not have suffix ' + '"unknown_parameters".' + "Experiment model does not have suffix " + '"unknown_parameters".' ) - + # Check that measurement errors exist try: outputs = [k.name for k, v in model.measurement_error.items()] except: RuntimeError( - 'Experiment model does not have suffix ' + '"measurement_error".' + "Experiment model does not have suffix " + '"measurement_error".' ) - - self.logger.info('Model has expected labels.') - + + self.logger.info("Model has expected labels.") + # Check the FIM shape against what is expected from the model. def check_model_FIM(self, FIM=None): """ Checks if the specified matrix, FIM, matches the shape expected from the model. This method should only be called after the model has been probed for the length of the unknown parameter, - experiment input, experiment output, and measurement error - has been stored to the object. - + experiment input, experiment output, and measurement error + has been stored to the object. + Parameters ---------- model: model for suffix checking, Default: None, (self.model) """ - assert FIM.shape == (self.n_parameters, self.n_parameters), "Shape of FIM provided should be n_parameters x n_parameters, or {}, FIM provided has shape: {}".format((self.n_parameters, self.n_parameters), FIM.shape) + assert FIM.shape == ( + self.n_parameters, + self.n_parameters, + ), "Shape of FIM provided should be n_parameters x n_parameters, or {}, FIM provided has shape: {}".format( + (self.n_parameters, self.n_parameters), FIM.shape + ) + + self.logger.info("FIM provided matches expected dimensions from model.") - self.logger.info('FIM provided matches expected dimensions from model.') - # Check the jacobian shape against what is expected from the model. def check_model_jac(self, jac=None): - assert jac.shape == (self.n_experiment_outputs, self.n_parameters), "Shape of Jacobian provided should be n_experiment_outputs x n_parameters, or {}, Jacobian provided has shape: {}".format((self.n_experiment_outputs, self.n_parameters), jac.shape) + assert jac.shape == ( + self.n_experiment_outputs, + self.n_parameters, + ), "Shape of Jacobian provided should be n_experiment_outputs x n_parameters, or {}, Jacobian provided has shape: {}".format( + (self.n_experiment_outputs, self.n_parameters), jac.shape + ) - self.logger.info('Jacobian provided matches expected dimensions from model.') + self.logger.info("Jacobian provided matches expected dimensions from model.") # Update the FIM for the specified model def update_FIM_prior(self, model=None, FIM=None): @@ -1192,7 +1324,7 @@ def update_FIM_prior(self, model=None, FIM=None): Updates the prior FIM on the model object. This may be useful when running a loop and the user doesn't want to rebuild the model because it is expensive to build/initialize. - + Parameters ---------- model: model where FIM prior is to be updated, Default: None, (self.model) @@ -1200,35 +1332,39 @@ def update_FIM_prior(self, model=None, FIM=None): """ if model is None: model = self.model - + # Check FIM input if FIM is None: - raise ValueError('FIM input for update_FIM_prior must be a 2D, square numpy array.') + raise ValueError( + "FIM input for update_FIM_prior must be a 2D, square numpy array." + ) - assert hasattr(model, 'fim'), '``fim`` is not defined on the model provided. Please build the model first.' + assert hasattr( + model, "fim" + ), "``fim`` is not defined on the model provided. Please build the model first." self.check_model_FIM(model, FIM) # Update FIM prior for ind1, p1 in enumerate(model.parameter_names): for ind2, p2 in enumerate(model.parameter_names): - model.prior_FIM[p1, p2].set_value(FIM[ind1, ind2]) + model.prior_FIM[p1, p2].set_value(FIM[ind1, ind2]) + + self.logger.info("FIM prior has been updated.") - self.logger.info('FIM prior has been updated.') - # ToDo: Add an update function for the parameter values? --> closed loop parameter estimation? # Or leave this to the user????? def udpate_unknown_parameter_values(self, model=None, param_vals=None): return # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) - def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): + def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): """ Will run a simulation-based full factorial exploration of the experimental input space (i.e., a ``grid search`` or ``parameter sweep``) to understand how the FIM metrics change as a function of the experimental design space. - + Parameters ---------- model: model to perform the full factorial exploration on @@ -1245,61 +1381,76 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): # Make new model for factorial design self.factorial_model = self.experiment.get_labeled_model(**self.args).clone() model = self.factorial_model - + # Permute the inputs to be aligned with the experiment input indicies design_ranges_enum = {k: np.linspace(*v) for k, v in design_ranges.items()} - design_map = {ind: (k[0].name, k[0]) for ind, k in enumerate(model.experiment_inputs.items())} - + design_map = { + ind: (k[0].name, k[0]) + for ind, k in enumerate(model.experiment_inputs.items()) + } + # Make the full space try: valid_inputs = 0 des_ranges = [] - for k,v in design_map.items(): + for k, v in design_map.items(): if v[0] in design_ranges_enum.keys(): des_ranges.append(design_ranges_enum[v[0]]) valid_inputs += 1 - assert (valid_inputs > 0) - + assert valid_inputs > 0 + factorial_points = product(*des_ranges) except: - raise ValueError('Design ranges keys must be a subset of experimental design names.') - + raise ValueError( + "Design ranges keys must be a subset of experimental design names." + ) + # ToDo: Add more objetive types? i.e., modified-E; G-opt; V-opt; etc? # ToDo: Also, make this a result object, or more user friendly. fim_factorial_results = {k.name: [] for k, v in model.experiment_inputs.items()} - fim_factorial_results.update({'log10 D-opt': [], 'log10 A-opt': [], 'log10 E-opt': [], 'log10 ME-opt': [], 'solve_time': [], }) - + fim_factorial_results.update( + { + "log10 D-opt": [], + "log10 A-opt": [], + "log10 E-opt": [], + "log10 ME-opt": [], + "solve_time": [], + } + ) + succeses = 0 failures = 0 - total_points = np.prod(np.array([len(v) for k, v in design_ranges_enum.items()])) + total_points = np.prod( + np.array([len(v) for k, v in design_ranges_enum.items()]) + ) time_set = [] curr_point = 1 # Initial current point for design_point in factorial_points: - + # Fix design variables at fixed experimental design point for i in range(len(design_point)): design_map[i][1].fix(design_point[i]) - + # Timing and logging objects self.logger.info("=======Iteration Number: %s =====", curr_point) iter_timer = TicTocTimer() iter_timer.tic(msg=None) - + # Compute FIM with given options try: curr_point = succeses + 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 - + # iteration time iter_t = iter_timer.toc(msg=None) time_set.append(iter_t) - + # More logging self.logger.info( "The code has run for %s seconds.", round(sum(time_set), 2) @@ -1307,7 +1458,8 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): self.logger.info( "Estimated remaining time: %s seconds", round( - sum(time_set) / (curr_point) * (total_points - curr_point + 1), 2 + sum(time_set) / (curr_point) * (total_points - curr_point + 1), + 2, ), ) except: @@ -1316,12 +1468,12 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): ) failures += 1 self.logger.warning("failed count:", failures) - + self._computed_FIM = np.zeros(self.prior_FIM.shape) iter_timer.tic(msg=None) - + FIM = self._computed_FIM - + # Compute and record metrics on FIM D_opt = np.log10(np.linalg.det(FIM)) A_opt = np.log10(np.trace(FIM)) @@ -1329,33 +1481,34 @@ def compute_FIM_full_factorial(self, design_ranges=None, method='sequential'): E_ind = np.argmin(E_vals.real) # Grab index of minima to check imaginary # Warn the user if there is a ``large`` imaginary component (should not be) if abs(E_vals.imag[E_ind]) > 1e-8: - self.logger.warning("Eigenvalue has imaginary component greater than 1e-6, contact developers if this issue persists.") - + self.logger.warning( + "Eigenvalue has imaginary component greater than 1e-6, contact developers if this issue persists." + ) + # If the real value is less than or equal to zero, set the E_opt value to np.NaN if E_vals.real[E_ind] <= 0: E_opt = np.NaN else: E_opt = np.log10(E_vals.real[E_ind]) - + ME_opt = np.log10(np.linalg.cond(FIM)) - + # Append the values for each of the experiment inputs for k, v in model.experiment_inputs.items(): fim_factorial_results[k.name].append(pyo.value(k)) - - fim_factorial_results['log10 D-opt'].append(D_opt) - fim_factorial_results['log10 A-opt'].append(A_opt) - fim_factorial_results['log10 E-opt'].append(E_opt) - fim_factorial_results['log10 ME-opt'].append(ME_opt) - fim_factorial_results['solve_time'].append(time_set[-1]) - + + fim_factorial_results["log10 D-opt"].append(D_opt) + fim_factorial_results["log10 A-opt"].append(A_opt) + fim_factorial_results["log10 E-opt"].append(E_opt) + fim_factorial_results["log10 ME-opt"].append(ME_opt) + fim_factorial_results["solve_time"].append(time_set[-1]) + self.fim_factorial_results = fim_factorial_results - + # ToDo: add automated figure drawing as it was before (perhaps reuse the code) return self.fim_factorial_results - - - # Plotting + + # Plotting def draw_factorial_figure( self, results=None, @@ -1371,7 +1524,7 @@ def draw_factorial_figure( log_scale=True, ): """ - Extract results needed for drawing figures from the results dictionary provided by + Extract results needed for drawing figures from the results dictionary provided by the ``compute_FIM_full_factorial`` function. Draw either the 1D sensitivity curve or 2D heatmap. @@ -1395,29 +1548,47 @@ def draw_factorial_figure( """ if results is None: - assert hasattr(self, 'fim_factorial_results'), "Results must be provided or the compute_FIM_full_factorial function must be run." + assert hasattr( + self, "fim_factorial_results" + ), "Results must be provided or the compute_FIM_full_factorial function must be run." results = self.fim_factorial_results - full_design_variable_names = [k.name for k, v in self.factorial_model.experiment_inputs.items()] + full_design_variable_names = [ + k.name for k, v in self.factorial_model.experiment_inputs.items() + ] else: - assert full_design_variable_names is not None, "If results object is provided, you must include all the design variable names." - + assert ( + full_design_variable_names is not None + ), "If results object is provided, you must include all the design variable names." + des_names = full_design_variable_names - + # Inputs must exist for the function to do anything # ToDo: Put in a default value function????? - assert (sensitivity_design_variables is not None), "``sensitivity_design_variables`` must be included." - assert (fixed_design_variables is not None), "``sensitivity_design_variables`` must be included." - + assert ( + sensitivity_design_variables is not None + ), "``sensitivity_design_variables`` must be included." + assert ( + fixed_design_variables is not None + ), "``sensitivity_design_variables`` must be included." + # Check that the provided design variables are within the results object check_des_vars = True - for k,v in fixed_design_variables.items(): - check_des_vars *= (k in [k for k,v in results.items()]) + for k, v in fixed_design_variables.items(): + check_des_vars *= k in [k for k, v in results.items()] check_sens_vars = True for k in sensitivity_design_variables: - check_sens_vars *= (k in [k for k,v in results.items()]) - - assert (check_des_vars), "Fixed design variables {} do not all appear in the results object keys {}.".format(fixed_design_variables.keys(), results.keys()) - assert (check_sens_vars), "Sensitivity design variables {} do not all appear in the results object keys {}.".format(sensitivity_design_variables.keys(), results.keys()) + check_sens_vars *= k in [k for k, v in results.items()] + + assert ( + check_des_vars + ), "Fixed design variables {} do not all appear in the results object keys {}.".format( + fixed_design_variables.keys(), results.keys() + ) + assert ( + check_sens_vars + ), "Sensitivity design variables {} do not all appear in the results object keys {}.".format( + sensitivity_design_variables.keys(), results.keys() + ) # ToDo: Make it possible to plot pair-wise sensitivities for all variables # e.g. a curve like low-dimensional posterior distributions @@ -1426,9 +1597,9 @@ def draw_factorial_figure( "Currently, only 1D and 2D sensitivity plotting is supported." ) - if len(fixed_design_variables.keys()) + len(sensitivity_design_variables) != len( - des_names - ): + if len(fixed_design_variables.keys()) + len( + sensitivity_design_variables + ) != len(des_names): raise ValueError( "Error: All design variables that are not used to generate sensitivity plots must be fixed." ) @@ -1454,7 +1625,7 @@ def draw_factorial_figure( i += 1 # extract results with other dimensions fixed figure_result_data = results_pd.loc[eval(filter)] - + # if there is no other fixed dimensions else: figure_result_data = results_pd @@ -1466,16 +1637,16 @@ def draw_factorial_figure( # ToDo: Add figure saving capabilities if figure_file_name is not None: - self.logger.warning('File saving for drawing is not yet implemented.') - + self.logger.warning("File saving for drawing is not yet implemented.") + # if one design variable name is given as DOF, draw 1D sensitivity curve if len(self.figure_sens_des_vars) == 1: self._curve1D( - title_text, - xlabel_text, - font_axes=font_axes, - font_tick=font_tick, - log_scale=log_scale, + title_text, + xlabel_text, + font_axes=font_axes, + font_tick=font_tick, + log_scale=log_scale, figure_file_name=figure_file_name, ) # if two design variable names are given as DOF, draw 2D heatmaps @@ -1494,7 +1665,13 @@ def draw_factorial_figure( pass def _curve1D( - self, title_text, xlabel_text, font_axes=16, font_tick=14, figure_file_name=None, log_scale=True + self, + title_text, + xlabel_text, + font_axes=16, + font_tick=14, + figure_file_name=None, + log_scale=True, ): """ Draw 1D sensitivity curves for all design criteria @@ -1521,7 +1698,9 @@ def _curve1D( y_range_A = np.log10(self.figure_result_data["log10 A-opt"].values.tolist()) y_range_D = np.log10(self.figure_result_data["log10 D-opt"].values.tolist()) y_range_E = np.log10(self.figure_result_data["log10 E-opt"].values.tolist()) - y_range_ME = np.log10(self.figure_result_data["log10 ME-opt"].values.tolist()) + y_range_ME = np.log10( + self.figure_result_data["log10 ME-opt"].values.tolist() + ) else: y_range_A = self.figure_result_data["log10 A-opt"].values.tolist() y_range_D = self.figure_result_data["log10 D-opt"].values.tolist() @@ -1620,7 +1799,7 @@ def _heatmap( -------- 4 Figures of 2D heatmap for each criteria """ - des_names = [k for k,v in self.figure_fixed_des_vars.items()] + des_names = [k for k, v in self.figure_fixed_des_vars.items()] sens_ranges = {} for i in self.figure_sens_des_vars: sens_ranges[i] = list(self.figure_result_data[i].unique()) @@ -1744,176 +1923,210 @@ def _heatmap( ba.set_label("log10(cond(FIM))") plt.pyplot.title(title_text + ": Modified E-optimality") plt.pyplot.show() - - - + # Gets the FIM from an existing model def get_FIM(self, model=None): """ Gets the FIM values from the model specified - + Parameters ---------- model: model to grab FIM from, Default: None, (self.model) - + Returns ------- FIM: 2D list representation of the FIM (can be cast to numpy) - + """ if model is None: model = self.model - - assert hasattr(model, 'fim'), "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" - - fim_vals = [pyo.value(model.fim[i, j]) for i in model.parameter_names for j in model.parameter_names] - fim_np = np.array(fim_vals).reshape((len(model.parameter_names), len(model.parameter_names))) - + + assert hasattr( + model, "fim" + ), "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" + + fim_vals = [ + pyo.value(model.fim[i, j]) + for i in model.parameter_names + for j in model.parameter_names + ] + fim_np = np.array(fim_vals).reshape( + (len(model.parameter_names), len(model.parameter_names)) + ) + # FIM is a lower triangular matrix for the optimal DoE problem. # Exploit symmetry to fill in the zeros. for i in range(4): for j in range(4): if j < i: fim_np[j, i] = fim_np[i, j] - + return [list(row) for row in list(fim_np)] - + # Gets the sensitivity matrix from an existing model def get_sensitivity_matrix(self, model=None): """ Gets the sensitivity matrix (Q) values from the model specified. - + Parameters ---------- model: model to grab Q from, Default: None, (self.model) - + Returns ------- Q: 2D list representation of the sensitivity matrix (can be cast to numpy) - + """ if model is None: model = self.model - - assert hasattr(model, 'sensitivity_jacobian'), "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" - - Q_vals = [pyo.value(model.sensitivity_jacobian[i, j]) for i in model.output_names for j in model.parameter_names] - Q_np = np.array(Q_vals).reshape((len(model.output_names), len(model.parameter_names))) + + assert hasattr( + model, "sensitivity_jacobian" + ), "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" + + Q_vals = [ + pyo.value(model.sensitivity_jacobian[i, j]) + for i in model.output_names + for j in model.parameter_names + ] + Q_np = np.array(Q_vals).reshape( + (len(model.output_names), len(model.parameter_names)) + ) return [list(row) for row in list(Q_np)] - + # Gets the experiment input values from an existing model def get_experiment_input_values(self, model=None): """ - Gets the experiment input values (experimental design) + Gets the experiment input values (experimental design) from the model specified. - + Parameters ---------- - model: model to grab the experimental design from, + model: model to grab the experimental design from, default: None, (self.model) - + Returns ------- d: 1D list of experiment input values (optimal or specified design) - + """ if model is None: model = self.model - - if not hasattr(model, 'experiment_inputs'): - assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - - d_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].experiment_inputs.items()] + + if not hasattr(model, "experiment_inputs"): + assert hasattr( + model, "scenario_blocks" + ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + d_vals = [ + pyo.value(k) + for k, v in model.scenario_blocks[0].experiment_inputs.items() + ] else: d_vals = [pyo.value(k) for k, v in model.experiment_inputs.items()] - + return d_vals - + # Gets the unknown parameter values from an existing model def get_unknown_parameter_values(self, model=None): """ - Gets the unknown parameter values (theta) + Gets the unknown parameter values (theta) from the model specified. - + Parameters ---------- - model: model to grab theta from, + model: model to grab theta from, default: None, (self.model) - + Returns ------- theta: 1D list of unknown parameter values at which this experiment was designed - + """ if model is None: model = self.model - - if not hasattr(model, 'unknown_parameters'): - assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - - theta_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].unknown_parameters.items()] + + if not hasattr(model, "unknown_parameters"): + assert hasattr( + model, "scenario_blocks" + ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + theta_vals = [ + pyo.value(k) + for k, v in model.scenario_blocks[0].unknown_parameters.items() + ] else: theta_vals = [pyo.value(k) for k, v in model.unknown_parameters.items()] - + return theta_vals - + # Gets the experiment output values from an existing model def get_experiment_output_values(self, model=None): """ - Gets the experiment output values (y hat) + Gets the experiment output values (y hat) from the model specified. - + Parameters ---------- - model: model to grab y hat from, + model: model to grab y hat from, default: None, (self.model) - + Returns ------- y_hat: 1D list of experiment output values from the design experiment - + """ if model is None: model = self.model - - if not hasattr(model, 'experiment_outputs'): - assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - - y_hat_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].measurement_error.items()] + + if not hasattr(model, "experiment_outputs"): + assert hasattr( + model, "scenario_blocks" + ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + y_hat_vals = [ + pyo.value(k) + for k, v in model.scenario_blocks[0].measurement_error.items() + ] else: y_hat_vals = [pyo.value(k) for k, v in model.measurement_error.items()] - + return y_hat_vals - + # ToDo: For more complicated error structures, this should become # get cov_y, or so, and this method will be deprecated # Gets the measurement error values from an existing model def get_measurement_error_values(self, model=None): """ - Gets the experiment output values (sigma) + Gets the experiment output values (sigma) from the model specified. - + Parameters ---------- - model: model to grab sigma values from, + model: model to grab sigma values from, default: None, (self.model) - + Returns ------- sigma_diag: 1D list of measurement errors used to design the experiment - + """ if model is None: model = self.model - - if not hasattr(model, 'measurement_error'): - assert hasattr(model, 'scenario_blocks'), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" - - sigma_vals = [pyo.value(k) for k, v in model.scenario_blocks[0].measurement_error.items()] + + if not hasattr(model, "measurement_error"): + assert hasattr( + model, "scenario_blocks" + ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + + sigma_vals = [ + pyo.value(k) + for k, v in model.scenario_blocks[0].measurement_error.items() + ] else: sigma_vals = [pyo.value(k) for k, v in model.measurement_error.items()] - + return sigma_vals # Helper function for determinant calculation diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py index 7bae3d42015..ed0569e461f 100644 --- a/pyomo/contrib/doe/utils.py +++ b/pyomo/contrib/doe/utils.py @@ -27,6 +27,7 @@ from pyomo.common.dependencies import numpy as np, numpy_available + # Rescale FIM (a scaling function to help rescale FIM from parameter values) def rescale_FIM(FIM, param_vals): """ @@ -34,7 +35,7 @@ def rescale_FIM(FIM, param_vals): It is assumed the parameter vals align with the FIM dimensions such that (1, i) corresponds to the i-th column or row of the FIM. - + Parameters ---------- FIM: 2D numpy array to be scaled @@ -42,12 +43,26 @@ def rescale_FIM(FIM, param_vals): """ if isinstance(param_vals, list): - param_vals = np.array([param_vals, ]) + param_vals = np.array( + [ + param_vals, + ] + ) elif isinstance(param_vals, np.ndarray): - if len(param_vals.shape) > 2 or ((len(param_vals.shape) == 2) and (param_vals.shape[0] != 1)): - raise ValueError('param_vals should be a vector of dimensions (1, n_params). The shape you provided is {}.'.format(param_vals.shape)) + if len(param_vals.shape) > 2 or ( + (len(param_vals.shape) == 2) and (param_vals.shape[0] != 1) + ): + raise ValueError( + "param_vals should be a vector of dimensions (1, n_params). The shape you provided is {}.".format( + param_vals.shape + ) + ) if len(param_vals.shape) == 1: - param_vals = np.array([param_vals, ]) + param_vals = np.array( + [ + param_vals, + ] + ) scaling_mat = (1 / param_vals).transpose().dot((1 / param_vals)) scaled_FIM = np.multiply(FIM, scaling_mat) return scaled_FIM From 37e389947fb1130e8ae9260e454629a2478c206b Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 11 Jul 2024 14:30:49 -0400 Subject: [PATCH 049/203] Removing old files Removing deprecated tests and deprecated DoE files (result, measurements, scenario). --- .../contrib/doe/examples/PyomoDoE-plots.ipynb | 9116 ++++++++++++++ .../doe/examples/debugging_compute_FIM.ipynb | 10011 ++++++++++++++++ .../doe/examples/reactor_optimize_doe_DJL.py | 180 + pyomo/contrib/doe/result.py | 758 -- pyomo/contrib/doe/scenario.py | 181 - 5 files changed, 19307 insertions(+), 939 deletions(-) create mode 100644 pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb create mode 100644 pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb create mode 100644 pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py delete mode 100644 pyomo/contrib/doe/result.py delete mode 100644 pyomo/contrib/doe/scenario.py diff --git a/pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb b/pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb new file mode 100644 index 00000000000..f2d83550458 --- /dev/null +++ b/pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb @@ -0,0 +1,9116 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 60, + "id": "22f7850b-5a09-4b71-a9cf-64555f21f7f5", + "metadata": {}, + "outputs": [], + "source": [ + "import pyomo.environ as pyo\n", + "from pyomo.dae import ContinuousSet, DerivativeVar\n", + "from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables, ModelOptionLib\n", + "import numpy as np\n", + "from random import sample\n", + "from matplotlib import pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "2607b8c0-527c-4a6e-b73d-989b1471aa8f", + "metadata": {}, + "outputs": [], + "source": [ + "def create_model(\n", + " mod=None,\n", + " model_option=\"stage2\",\n", + " control_time=[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],\n", + " control_val=None,\n", + " t_range=[0.0, 1],\n", + " CA_init=1,\n", + " C_init=0.1,\n", + "):\n", + " \"\"\"\n", + " This is an example user model provided to DoE library.\n", + " It is a dynamic problem solved by Pyomo.DAE.\n", + "\n", + " Arguments\n", + " ---------\n", + " mod: Pyomo model. If None, a Pyomo concrete model is created\n", + " model_option: choose from the 3 options in model_option\n", + " if ModelOptionLib.parmest, create a process model.\n", + " if ModelOptionLib.stage1, create the global model.\n", + " if ModelOptionLib.stage2, add model variables and constraints for block.\n", + " control_time: a list of control timepoints\n", + " control_val: control design variable values T at corresponding timepoints\n", + " t_range: time range, h\n", + " CA_init: time-independent design (control) variable, an initial value for CA\n", + " C_init: An initial value for C\n", + "\n", + " Return\n", + " ------\n", + " m: a Pyomo.DAE model\n", + " \"\"\"\n", + "\n", + " theta = {\"A1\": 84.79, \"A2\": 371.72, \"E1\": 7.78, \"E2\": 15.05}\n", + "\n", + " model_option = ModelOptionLib(model_option)\n", + "\n", + " if model_option == ModelOptionLib.parmest:\n", + " mod = pyo.ConcreteModel()\n", + " return_m = True\n", + " elif model_option == ModelOptionLib.stage1 or model_option == ModelOptionLib.stage2:\n", + " if not mod:\n", + " raise ValueError(\n", + " \"If model option is stage1 or stage2, a created model needs to be provided.\"\n", + " )\n", + " return_m = False\n", + " else:\n", + " raise ValueError(\n", + " \"model_option needs to be defined as parmest,stage1, or stage2.\"\n", + " )\n", + "\n", + " if not control_val:\n", + " control_val = [300] * 9\n", + "\n", + " controls = {}\n", + " for i, t in enumerate(control_time):\n", + " controls[t] = control_val[i]\n", + "\n", + " mod.t0 = pyo.Set(initialize=[0])\n", + " mod.t_con = pyo.Set(initialize=control_time)\n", + " mod.CA0 = pyo.Var(\n", + " mod.t0, initialize=CA_init, bounds=(1.0, 5.0), within=pyo.NonNegativeReals\n", + " ) # mol/L\n", + "\n", + " # check if control_time is in time range\n", + " assert (\n", + " control_time[0] >= t_range[0] and control_time[-1] <= t_range[1]\n", + " ), \"control time is outside time range.\"\n", + "\n", + " if model_option == ModelOptionLib.stage1:\n", + " mod.T = pyo.Var(\n", + " mod.t_con,\n", + " initialize=controls,\n", + " bounds=(300, 700),\n", + " within=pyo.NonNegativeReals,\n", + " )\n", + " return\n", + "\n", + " else:\n", + " para_list = [\"A1\", \"A2\", \"E1\", \"E2\"]\n", + "\n", + " ### Add variables\n", + " mod.CA_init = CA_init\n", + " mod.para_list = para_list\n", + "\n", + " # timepoints\n", + " mod.t = ContinuousSet(bounds=t_range, initialize=control_time)\n", + "\n", + " # time-dependent design variable, initialized with the first control value\n", + " def T_initial(m, t):\n", + " if t in m.t_con:\n", + " return controls[t]\n", + " else:\n", + " # count how many control points are before the current t;\n", + " # locate the nearest neighbouring control point before this t\n", + " neighbour_t = max(tc for tc in control_time if tc < t)\n", + " return controls[neighbour_t]\n", + "\n", + " mod.T = pyo.Var(\n", + " mod.t, initialize=T_initial, bounds=(300, 700), within=pyo.NonNegativeReals\n", + " )\n", + "\n", + " mod.R = 8.31446261815324 # J / K / mole\n", + "\n", + " # Define parameters as Param\n", + " mod.A1 = pyo.Var(initialize=theta[\"A1\"])\n", + " mod.A2 = pyo.Var(initialize=theta[\"A2\"])\n", + " mod.E1 = pyo.Var(initialize=theta[\"E1\"])\n", + " mod.E2 = pyo.Var(initialize=theta[\"E2\"])\n", + "\n", + " # Concentration variables under perturbation\n", + " mod.C_set = pyo.Set(initialize=[\"CA\", \"CB\", \"CC\"])\n", + " mod.C = pyo.Var(\n", + " mod.C_set, mod.t, initialize=C_init, within=pyo.NonNegativeReals\n", + " )\n", + "\n", + " # time derivative of C\n", + " mod.dCdt = DerivativeVar(mod.C, wrt=mod.t)\n", + "\n", + " # kinetic parameters\n", + " def kp1_init(m, t):\n", + " return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", + "\n", + " def kp2_init(m, t):\n", + " return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", + "\n", + " mod.kp1 = pyo.Var(mod.t, initialize=kp1_init)\n", + " mod.kp2 = pyo.Var(mod.t, initialize=kp2_init)\n", + "\n", + " def T_control(m, t):\n", + " \"\"\"\n", + " T at interval timepoint equal to the T of the control time point at the beginning of this interval\n", + " Count how many control points are before the current t;\n", + " locate the nearest neighbouring control point before this t\n", + " \"\"\"\n", + " if t in m.t_con:\n", + " return pyo.Constraint.Skip\n", + " else:\n", + " neighbour_t = max(tc for tc in control_time if tc < t)\n", + " return m.T[t] == m.T[neighbour_t]\n", + "\n", + " def cal_kp1(m, t):\n", + " \"\"\"\n", + " Create the perturbation parameter sets\n", + " m: model\n", + " t: time\n", + " \"\"\"\n", + " # LHS: 1/h\n", + " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", + " return m.kp1[t] == m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", + "\n", + " def cal_kp2(m, t):\n", + " \"\"\"\n", + " Create the perturbation parameter sets\n", + " m: model\n", + " t: time\n", + " \"\"\"\n", + " # LHS: 1/h\n", + " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", + " return m.kp2[t] == m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", + "\n", + " def dCdt_control(m, y, t):\n", + " \"\"\"\n", + " Calculate CA in Jacobian matrix analytically\n", + " y: CA, CB, CC\n", + " t: timepoints\n", + " \"\"\"\n", + " if y == \"CA\":\n", + " return m.dCdt[y, t] == -m.kp1[t] * m.C[\"CA\", t]\n", + " elif y == \"CB\":\n", + " return m.dCdt[y, t] == m.kp1[t] * m.C[\"CA\", t] - m.kp2[t] * m.C[\"CB\", t]\n", + " elif y == \"CC\":\n", + " return pyo.Constraint.Skip\n", + "\n", + " def alge(m, t):\n", + " \"\"\"\n", + " The algebraic equation for mole balance\n", + " z: m.pert\n", + " t: time\n", + " \"\"\"\n", + " return m.C[\"CA\", t] + m.C[\"CB\", t] + m.C[\"CC\", t] == m.CA0[0]\n", + "\n", + " # Control time\n", + " mod.T_rule = pyo.Constraint(mod.t, rule=T_control)\n", + "\n", + " # calculating C, Jacobian, FIM\n", + " mod.k1_pert_rule = pyo.Constraint(mod.t, rule=cal_kp1)\n", + " mod.k2_pert_rule = pyo.Constraint(mod.t, rule=cal_kp2)\n", + " mod.dCdt_rule = pyo.Constraint(mod.C_set, mod.t, rule=dCdt_control)\n", + "\n", + " mod.alge_rule = pyo.Constraint(mod.t, rule=alge)\n", + "\n", + " # B.C.\n", + " mod.C[\"CB\", 0.0].fix(0.0)\n", + " mod.C[\"CC\", 0.0].fix(0.0)\n", + "\n", + " if return_m:\n", + " return mod" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "e76ef4de-7319-4047-9cc8-b61c8ce2c57f", + "metadata": {}, + "outputs": [], + "source": [ + "def disc_for_measure(m, nfe=32, block=True):\n", + " \"\"\"Pyomo.DAE discretization\n", + "\n", + " Arguments\n", + " ---------\n", + " m: Pyomo model\n", + " nfe: number of finite elements b\n", + " block: if True, the input model has blocks\n", + " \"\"\"\n", + " discretizer = pyo.TransformationFactory(\"dae.collocation\")\n", + " if block:\n", + " for s in range(len(m.block)):\n", + " discretizer.apply_to(m.block[s], nfe=nfe, ncp=3, wrt=m.block[s].t)\n", + " else:\n", + " discretizer.apply_to(m, nfe=nfe, ncp=3, wrt=m.t)\n", + " return m" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "42186821-ccaf-4a93-bf0e-86d8cd6098c0", + "metadata": {}, + "outputs": [], + "source": [ + " # Control time set [h]\n", + " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", + " # Define parameter nominal value\n", + " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", + "\n", + " # Define measurement object\n", + " measurements = MeasurementVariables()\n", + " measurements.add_variables(\n", + " \"C\", # measurement variable name\n", + " indices={\n", + " 0: [\"CA\", \"CB\", \"CC\"],\n", + " 1: t_control,\n", + " }, # 0,1 are indices of the index sets\n", + " time_index_position=1,\n", + " )\n", + "\n", + " # design object\n", + " exp_design = DesignVariables()\n", + "\n", + " # add CAO as design variable\n", + " exp_design.add_variables(\n", + " \"CA0\", # design variable name\n", + " indices={0: [0]}, # index dictionary\n", + " time_index_position=0, # time index position\n", + " values=[5], # design variable values\n", + " lower_bounds=1, # design variable lower bounds\n", + " upper_bounds=5, # design variable upper bounds\n", + " )\n", + "\n", + " # add T as design variable\n", + " exp_design.add_variables(\n", + " \"T\", # design variable name\n", + " indices={0: t_control}, # index dictionary\n", + " time_index_position=0, # time index position\n", + " values=[\n", + " 570,\n", + " 300,\n", + " 300,\n", + " 300,\n", + " 300,\n", + " 300,\n", + " 300,\n", + " 300,\n", + " 300,\n", + " ], # same length with t_control\n", + " lower_bounds=300, # design variable lower bounds\n", + " upper_bounds=700, # design variable upper bounds\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "70a60f53-bee2-401b-8c23-5d3998447946", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.67e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 4.76e+01 3.85e+02 -1.0 2.67e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.83e+01 2.78e+02 -1.0 5.91e+01 - 6.65e-02 9.90e-01h 1\n", + " 3 0.0000000e+00 1.33e-01 7.65e+01 -1.0 1.09e+01 - 7.59e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 4.86e-06 2.23e+02 -1.0 8.75e-02 - 9.91e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (287125)\n", + " 5 0.0000000e+00 3.41e-13 1.00e-06 -1.0 2.73e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.4215102496496944e-13 3.4106051316484809e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.4215102496496944e-13 3.4106051316484809e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.173\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1\n" + ] + } + ], + "source": [ + " doe_object = DesignOfExperiments(\n", + " parameter_dict, # parameter dictionary\n", + " exp_design, # DesignVariables object\n", + " measurements, # MeasurementVariables object\n", + " create_model, # create model function\n", + " discretize_model=disc_for_measure, # discretize model function\n", + " )\n", + "\n", + " result = doe_object.compute_FIM(\n", + " mode=\"sequential_finite\", # calculation mode\n", + " scale_nominal_param_value=True, # scale nominal parameter value\n", + " formula=\"central\", # formula for finite difference\n", + " )\n", + "\n", + " result.result_analysis()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "dd45bb25-e3e4-4438-9f5e-b1544346d262", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.78e-01 9.66e+00 -1.0 3.72e+00 - 1.10e-01 9.90e-01h 1\n", + " 2 0.0000000e+00 2.78e-03 7.85e-02 -1.0 2.50e-01 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 2.23e-09 1.61e-04 -1.0 2.50e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 3\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.2346848815857356e-09 2.2346848815857356e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.2346848815857356e-09 2.2346848815857356e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 4\n", + "Number of objective gradient evaluations = 4\n", + "Number of equality constraint evaluations = 4\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 4\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 3\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.083\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 0.7\n", + "[[ 23.4919678 1.90035398 -73.31983907 -11.45520905]\n", + " [ 1.90035398 18.78885651 -5.92812017 -113.31030691]\n", + " [ -73.31983907 -5.92812017 228.84307107 35.73423936]\n", + " [ -11.45520905 -113.31030691 35.73423936 683.34280812]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.27e+02 2.27e+01 -1.0 1.97e+02 - 1.49e-02 3.57e-01f 1\n", + " 2 0.0000000e+00 1.18e+02 2.13e+01 -1.0 1.27e+02 - 2.20e-01 6.59e-02h 1\n", + " 3 0.0000000e+00 1.18e+02 1.57e+04 -1.0 1.18e+02 - 4.58e-01 1.07e-03h 1\n", + " 4 0.0000000e+00 1.18e+02 8.18e+08 -1.0 1.18e+02 - 5.67e-01 1.08e-05h 1\n", + " 5r 0.0000000e+00 1.18e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 5.40e-08R 2\n", + " 6r 0.0000000e+00 1.08e+02 8.37e+03 2.1 2.06e+04 - 5.73e-02 5.68e-03f 1\n", + " 7r 0.0000000e+00 9.81e+01 9.52e+03 2.1 1.83e+03 - 1.09e-01 5.87e-03f 1\n", + " 8r 0.0000000e+00 3.98e+01 5.75e+03 2.1 1.58e+03 - 8.18e-02 4.13e-02f 1\n", + " 9r 0.0000000e+00 2.03e+01 6.57e+03 1.4 9.62e+02 - 1.41e-01 2.07e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 3.00e+00 8.02e+03 1.4 3.63e+02 - 3.32e-01 5.56e-02f 1\n", + " 11r 0.0000000e+00 1.44e+00 5.13e+03 1.4 9.12e+00 - 6.26e-01 2.87e-01f 1\n", + " 12r 0.0000000e+00 8.25e-01 3.35e+03 1.4 6.02e+00 - 3.97e-01 3.54e-01f 1\n", + " 13r 0.0000000e+00 3.34e-01 1.92e+03 1.4 1.38e+00 - 1.00e+00 5.65e-01f 1\n", + " 14r 0.0000000e+00 8.90e-02 2.52e+01 1.4 4.37e-01 - 1.00e+00 1.00e+00f 1\n", + " 15r 0.0000000e+00 6.06e-02 6.19e+02 -0.7 3.41e+00 - 9.23e-01 2.41e-01f 1\n", + " 16r 0.0000000e+00 2.81e-02 7.76e+02 -0.7 5.14e+00 - 9.06e-01 4.55e-01f 1\n", + " 17r 0.0000000e+00 7.09e-03 4.75e+02 -0.7 2.70e+00 - 1.00e+00 7.43e-01f 1\n", + " 18r 0.0000000e+00 2.33e-03 8.38e+02 -0.7 5.62e-01 - 1.00e+00 6.77e-01f 1\n", + " 19r 0.0000000e+00 4.95e-04 3.26e+02 -0.7 3.01e-01 - 1.00e+00 8.74e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 3.22e-04 7.71e-03 -0.7 3.84e-02 - 1.00e+00 1.00e+00f 1\n", + " 21r 0.0000000e+00 5.09e-05 3.36e+02 -3.2 4.74e-02 - 1.00e+00 7.57e-01f 1\n", + " 22r 0.0000000e+00 2.83e-05 9.25e+02 -3.2 2.60e-02 - 9.52e-01 6.49e-01f 1\n", + " 23r 0.0000000e+00 8.26e-06 8.54e+02 -3.2 4.25e-03 - 9.08e-01 7.50e-01f 1\n", + " 24r 0.0000000e+00 1.07e-06 3.61e+01 -3.2 1.20e-03 - 9.68e-01 1.00e+00f 1\n", + " 25r 0.0000000e+00 1.06e-06 1.08e-07 -3.2 3.22e-06 - 1.00e+00 1.00e+00f 1\n", + " 26r 0.0000000e+00 1.25e-08 1.36e+00 -7.2 1.30e-05 - 1.00e+00 9.91e-01f 1\n", + " 27r 0.0000000e+00 4.44e-09 9.66e+01 -7.2 1.80e-07 - 1.00e+00 6.43e-01f 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 3.8353336372415511e-09 4.4417719505051396e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 3.8353336372415511e-09 4.4417719505051396e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 30\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 30\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 29\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.415\n", + "Total CPU secs in NLP function evaluations = 0.011\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.7\n", + "[[ 22.79600957 1.98478998 -70.74572684 -11.61551788]\n", + " [ 1.98478998 18.42336506 -6.01361754 -110.33089639]\n", + " [ -70.74572684 -6.01361754 219.92911039 35.57976045]\n", + " [ -11.61551788 -110.33089639 35.57976045 662.60606496]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.16e+02 2.62e+01 -1.0 3.97e+02 - 7.43e-03 2.04e-01f 1\n", + " 2 0.0000000e+00 3.03e+02 2.51e+01 -1.0 3.16e+02 - 1.45e-01 4.23e-02h 1\n", + " 3 0.0000000e+00 3.03e+02 8.97e+03 -1.0 3.03e+02 - 2.61e-01 7.62e-04h 1\n", + " 4r 0.0000000e+00 3.03e+02 1.00e+03 2.5 0.00e+00 - 0.00e+00 4.81e-07R 5\n", + " 5r 0.0000000e+00 2.80e+02 2.51e+04 2.5 1.49e+04 - 8.36e-04 2.01e-02f 1\n", + " 6r 0.0000000e+00 2.77e+02 4.72e+04 2.5 1.15e+03 - 4.92e-01 2.99e-03f 1\n", + " 7r 0.0000000e+00 1.44e+02 3.94e+04 2.5 8.87e+02 - 1.66e-01 1.77e-01f 1\n", + " 8r 0.0000000e+00 8.40e+01 2.88e+04 2.5 7.02e+02 - 5.33e-01 1.02e-01f 1\n", + " 9r 0.0000000e+00 7.98e+00 2.05e+04 2.5 2.25e+02 - 6.82e-01 3.66e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 2.42e+00 1.01e+04 1.8 1.19e+01 - 1.00e+00 5.27e-01f 1\n", + " 11r 0.0000000e+00 8.94e-01 1.27e+03 1.8 3.82e+00 - 1.00e+00 8.53e-01f 1\n", + " 12r 0.0000000e+00 5.02e-01 1.87e+03 1.1 1.61e+00 - 1.00e+00 5.52e-01f 1\n", + " 13r 0.0000000e+00 2.92e-01 1.58e+03 1.1 3.89e+00 - 1.00e+00 5.66e-01f 1\n", + " 14r 0.0000000e+00 2.10e-01 3.14e+00 1.1 1.42e+00 - 1.00e+00 1.00e+00f 1\n", + " 15r 0.0000000e+00 2.28e-01 5.05e+02 -1.0 9.32e-01 - 9.06e-01 6.86e-01f 1\n", + " 16r 0.0000000e+00 1.61e-01 3.01e+03 -1.0 4.16e+01 - 4.10e-01 6.33e-02f 1\n", + " 17r 0.0000000e+00 3.96e-02 2.90e+03 -1.0 3.34e+01 - 4.84e-01 2.04e-01f 1\n", + " 18r 0.0000000e+00 3.80e-02 2.77e+03 -1.0 1.90e+01 - 2.00e-02 3.94e-02f 1\n", + " 19r 0.0000000e+00 3.76e-02 3.37e+03 -1.0 1.24e+01 - 1.00e+00 1.20e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 3.18e-02 3.17e+03 -1.0 6.34e+00 - 1.00e+00 1.59e-01f 1\n", + " 21r 0.0000000e+00 1.30e-02 1.27e+03 -1.0 2.32e+00 - 1.00e+00 6.13e-01f 1\n", + " 22r 0.0000000e+00 2.75e-03 2.56e+02 -1.0 7.79e-01 - 1.00e+00 8.72e-01f 1\n", + " 23r 0.0000000e+00 1.24e-03 1.45e-02 -1.0 8.66e-02 - 1.00e+00 1.00e+00f 1\n", + " 24r 0.0000000e+00 4.49e-04 9.60e+02 -3.9 4.13e-02 - 1.00e+00 6.37e-01f 1\n", + " 25r 0.0000000e+00 2.39e-04 1.95e+03 -3.9 3.96e-02 - 9.64e-01 4.59e-01f 1\n", + " 26r 0.0000000e+00 6.90e-05 1.04e+03 -3.9 3.37e-03 - 9.83e-01 6.98e-01f 1\n", + " 27r 0.0000000e+00 2.36e-05 1.29e+03 -3.9 1.13e-03 - 9.70e-01 6.16e-01f 1\n", + " 28r 0.0000000e+00 4.53e-06 1.22e+03 -3.9 4.33e-04 - 1.00e+00 6.79e-01f 1\n", + " 29r 0.0000000e+00 1.29e-06 1.43e+03 -3.9 1.39e-04 - 1.00e+00 5.77e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 4.96e-07 7.07e-06 -3.9 5.89e-05 - 1.00e+00 1.00e+00f 1\n", + " 31r 0.0000000e+00 1.34e-07 1.42e+03 -5.8 4.88e-06 - 1.00e+00 5.68e-01f 1\n", + " 32r 0.0000000e+00 4.98e-08 1.83e+03 -5.8 2.01e-06 - 9.73e-01 6.09e-01f 1\n", + " 33r 0.0000000e+00 1.06e-08 2.39e+02 -5.8 8.73e-07 - 9.85e-01 9.28e-01f 1\n", + "\n", + "Number of Iterations....: 33\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 6.2369178856385201e-09 1.0648229654397684e-08\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 6.2369178856385201e-09 1.0648229654397684e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 35\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 33\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.459\n", + "Total CPU secs in NLP function evaluations = 0.090\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "[[ 22.63335364 1.90230787 -70.37558022 -11.25402903]\n", + " [ 1.90230787 18.17182952 -5.82082335 -109.34769934]\n", + " [ -70.37558022 -5.82082335 219.13827714 34.79632173]\n", + " [ -11.25402903 -109.34769934 34.79632173 658.86364692]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 9.05e-01 1.87e+02 -1.0 1.12e+01 - 5.21e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 9.03e-03 1.85e+00 -1.0 8.13e-01 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.20e-09 5.47e-05 -1.0 8.12e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 3\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.2006525186907311e-09 7.2006525186907311e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.2006525186907311e-09 7.2006525186907311e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 4\n", + "Number of objective gradient evaluations = 4\n", + "Number of equality constraint evaluations = 4\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 4\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 3\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.079\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 0.7\n", + "[[ 31.19226828 2.38044072 -98.01668477 -14.34224445]\n", + " [ 2.38044072 24.31185934 -7.46787881 -146.52347138]\n", + " [ -98.01668477 -7.46787881 308.05221217 44.99368637]\n", + " [ -14.34224445 -146.52347138 44.99368637 883.07370235]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.06e+02 8.67e+01 -1.0 1.97e+02 - 5.21e-03 4.63e-01f 1\n", + " 2 0.0000000e+00 1.03e+02 8.41e+01 -1.0 1.06e+02 - 1.23e-01 3.00e-02h 1\n", + " 3 0.0000000e+00 1.03e+02 1.14e+04 -1.0 1.03e+02 - 2.02e-01 3.66e-04h 1\n", + " 4r 0.0000000e+00 1.03e+02 1.00e+03 2.0 0.00e+00 - 0.00e+00 4.59e-07R 4\n", + " 5r 0.0000000e+00 9.98e+01 3.34e+03 2.0 1.78e+04 - 5.49e-03 2.23e-03f 1\n", + " 6r 0.0000000e+00 9.58e+01 1.77e+04 1.3 1.22e+04 - 2.58e-02 2.86e-03f 1\n", + " 7r 0.0000000e+00 7.91e+01 4.28e+04 1.3 3.59e+03 - 3.01e-02 5.36e-03f 1\n", + " 8r 0.0000000e+00 3.41e+01 4.38e+04 1.3 3.03e+03 - 3.45e-02 1.54e-02f 1\n", + " 9r 0.0000000e+00 2.48e+01 3.96e+04 1.3 1.85e+03 - 2.78e-01 5.04e-03f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 5.64e+00 3.44e+04 1.3 2.01e+02 - 1.86e-01 1.23e-01f 1\n", + " 11r 0.0000000e+00 2.42e+00 1.91e+04 1.3 1.70e+01 - 5.49e-01 2.58e-01f 1\n", + " 12r 0.0000000e+00 1.24e+00 8.44e+03 1.3 7.64e+00 - 6.61e-01 4.56e-01f 1\n", + " 13r 0.0000000e+00 1.19e+00 2.99e+03 1.3 2.61e+00 - 5.40e-01 3.71e-01f 1\n", + " 14r 0.0000000e+00 1.15e+00 4.69e+03 1.3 1.51e+00 - 8.83e-01 6.33e-01f 1\n", + " 15r 0.0000000e+00 1.13e+00 4.99e+03 1.3 6.01e-01 - 5.32e-01 7.72e-01f 1\n", + " 16r 0.0000000e+00 1.13e+00 1.09e+00 1.3 1.75e-01 - 1.00e+00 1.00e+00f 1\n", + " 17r 0.0000000e+00 1.62e+00 1.19e+02 -0.8 7.16e+00 - 6.51e-01 8.04e-01f 1\n", + " 18r 0.0000000e+00 1.29e+00 5.12e+02 -0.8 8.63e+00 - 3.56e-01 4.94e-01f 1\n", + " 19r 0.0000000e+00 7.07e-01 1.78e+02 -0.8 1.47e+01 - 5.56e-01 4.96e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 9.00e-03 8.30e+02 -0.8 2.77e+01 - 4.78e-01 3.14e-01f 1\n", + " 21r 0.0000000e+00 4.40e-03 2.34e+03 -0.8 1.62e+01 - 8.28e-01 5.79e-03f 1\n", + " 22r 0.0000000e+00 2.91e-03 1.69e+03 -0.8 2.80e+00 - 1.00e+00 2.71e-01f 1\n", + " 23r 0.0000000e+00 8.18e-04 5.53e+02 -0.8 1.23e+00 - 1.00e+00 6.90e-01f 1\n", + " 24r 0.0000000e+00 1.16e-03 1.32e-03 -0.8 2.40e-01 - 1.00e+00 1.00e+00f 1\n", + " 25r 0.0000000e+00 4.27e-04 4.03e+02 -3.3 2.88e-01 - 1.00e+00 7.55e-01f 1\n", + " 26r 0.0000000e+00 4.49e-05 3.83e+03 -3.3 7.00e-01 - 9.34e-01 1.68e-01f 1\n", + " 27r 0.0000000e+00 2.16e-06 1.67e+02 -3.3 2.07e-02 - 9.48e-01 9.55e-01f 1\n", + " 28r 0.0000000e+00 3.64e-08 1.90e-06 -3.3 8.95e-04 - 1.00e+00 1.00e+00f 1\n", + " 29r 0.0000000e+00 2.25e-09 2.47e-01 -7.5 1.53e-05 - 1.00e+00 9.98e-01f 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.9395965331428192e-09 2.2481533234965274e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.9395965331428192e-09 2.2481533234965274e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 31\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.614\n", + "Total CPU secs in NLP function evaluations = 0.081\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "[[ 24.92864423 3.14036468 -74.84967466 -15.78502396]\n", + " [ 3.14036468 21.02243624 -8.23735511 -119.70877671]\n", + " [ -74.84967466 -8.23735511 227.82656607 43.60337618]\n", + " [ -15.78502396 -119.70877671 43.60337618 696.44301405]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.04e+02 4.34e+01 -1.0 3.97e+02 - 5.21e-03 2.34e-01f 1\n", + " 2 0.0000000e+00 2.98e+02 4.26e+01 -1.0 3.04e+02 - 7.70e-02 2.01e-02h 1\n", + " 3 0.0000000e+00 2.98e+02 7.36e+03 -1.0 2.98e+02 - 1.28e-01 2.60e-04h 1\n", + " 4r 0.0000000e+00 2.98e+02 1.00e+03 2.5 0.00e+00 - 0.00e+00 3.26e-07R 4\n", + " 5r 0.0000000e+00 2.77e+02 1.21e+04 2.5 1.42e+04 - 1.92e-03 2.08e-02f 1\n", + " 6r 0.0000000e+00 2.74e+02 1.33e+04 1.8 1.29e+03 - 1.28e-01 2.52e-03f 1\n", + " 7r 0.0000000e+00 2.26e+02 1.74e+04 1.8 2.17e+03 - 1.75e-01 2.27e-02f 1\n", + " 8r 0.0000000e+00 1.70e+02 1.94e+04 1.8 1.50e+03 - 3.05e-01 4.00e-02f 1\n", + " 9r 0.0000000e+00 8.81e+01 1.78e+04 1.8 7.79e+02 - 2.82e-01 1.08e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 2.94e+01 1.40e+04 1.8 2.94e+02 - 5.10e-01 2.10e-01f 1\n", + " 11r 0.0000000e+00 2.15e+01 1.17e+04 1.8 4.85e+01 - 1.00e+00 1.67e-01f 1\n", + " 12r 0.0000000e+00 5.21e+00 2.64e+03 1.8 2.09e+01 - 1.00e+00 7.79e-01f 1\n", + " 13r 0.0000000e+00 2.67e+00 3.16e+03 1.1 5.47e+00 - 9.78e-01 5.06e-01f 1\n", + " 14r 0.0000000e+00 1.98e+00 9.35e+02 1.1 2.78e+00 - 1.00e+00 8.27e-01f 1\n", + " 15r 0.0000000e+00 2.00e+00 2.79e+03 0.4 1.09e+00 - 9.98e-01 4.40e-01f 1\n", + " 16r 0.0000000e+00 2.00e+00 1.21e+03 0.4 3.21e+00 - 9.19e-01 6.28e-01f 1\n", + " 17r 0.0000000e+00 1.99e+00 1.22e+00 0.4 8.67e-01 - 1.00e+00 1.00e+00f 1\n", + " 18r 0.0000000e+00 2.00e+00 1.65e+03 -1.7 5.96e-01 - 9.91e-01 4.10e-01f 1\n", + " 19r 0.0000000e+00 2.00e+00 1.83e+03 -1.7 2.35e+01 - 4.40e-01 1.42e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.00e+00 1.60e+03 -1.7 1.13e+01 - 7.62e-03 9.12e-02f 1\n", + " 21r 0.0000000e+00 1.88e+00 1.11e+03 -1.7 7.12e+01 - 4.10e-04 1.86e-01f 1\n", + " 22r 0.0000000e+00 7.03e-01 3.48e+03 -1.7 8.30e+01 - 3.09e-02 3.12e-01f 1\n", + " 23r 0.0000000e+00 4.00e-01 3.15e+03 -1.7 6.39e+01 - 9.85e-02 1.02e-01f 1\n", + " 24r 0.0000000e+00 3.97e-01 3.03e+03 -1.7 5.91e+01 - 2.08e-02 1.19e-03f 1\n", + " 25r 0.0000000e+00 2.62e-01 2.91e+03 -1.7 5.95e+01 - 4.23e-02 4.88e-02f 1\n", + " 26r 0.0000000e+00 1.40e-01 2.63e+03 -1.7 5.67e+01 - 9.35e-02 4.62e-02f 1\n", + " 27r 0.0000000e+00 1.38e-01 1.95e+03 -1.7 5.44e+01 - 2.47e-01 7.95e-04f 1\n", + " 28r 0.0000000e+00 9.04e-02 1.90e+03 -1.7 5.42e+01 - 1.88e-01 1.90e-02f 1\n", + " 29r 0.0000000e+00 3.77e-02 3.31e+03 -1.7 4.98e+01 - 5.30e-01 2.27e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 6.02e-03 3.61e+03 -1.7 1.34e+01 - 9.70e-01 6.02e-02f 1\n", + " 31r 0.0000000e+00 5.14e-03 3.30e+03 -1.7 6.99e+00 - 1.00e+00 1.53e-01f 1\n", + " 32r 0.0000000e+00 3.66e-03 2.50e+03 -1.7 5.55e-01 - 1.00e+00 3.01e-01f 1\n", + " 33r 0.0000000e+00 5.42e-04 2.44e+02 -1.7 3.24e-01 - 1.00e+00 9.11e-01f 1\n", + " 34r 0.0000000e+00 2.39e-04 3.00e-03 -1.7 2.78e-02 - 1.00e+00 1.00e+00f 1\n", + " 35r 0.0000000e+00 8.49e-05 1.01e+03 -3.9 1.83e-02 - 1.00e+00 6.33e-01f 1\n", + " 36r 0.0000000e+00 6.04e-05 2.69e+03 -3.9 2.68e-02 - 9.77e-01 2.72e-01f 1\n", + " 37r 0.0000000e+00 1.04e-05 8.23e+02 -3.9 1.42e-03 - 1.00e+00 7.69e-01f 1\n", + " 38r 0.0000000e+00 1.46e-06 1.11e+03 -3.9 2.73e-04 - 1.00e+00 6.80e-01f 1\n", + " 39r 0.0000000e+00 9.63e-07 2.09e+03 -3.9 8.74e-05 - 1.00e+00 3.68e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40r 0.0000000e+00 1.97e-07 3.12e-06 -3.9 5.52e-05 - 1.00e+00 1.00e+00f 1\n", + " 41r 0.0000000e+00 5.22e-08 1.13e+03 -5.8 5.75e-06 - 1.00e+00 6.12e-01f 1\n", + " 42r 0.0000000e+00 2.38e-08 1.61e+03 -5.8 4.28e-06 - 9.81e-01 6.72e-01f 1\n", + " 43r 0.0000000e+00 2.62e-09 1.78e-07 -5.8 5.81e-07 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 43\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.5727324704138637e-09 2.6229877388222538e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.5727324704138637e-09 2.6229877388222538e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 48\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 48\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 45\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 43\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.628\n", + "Total CPU secs in NLP function evaluations = 0.025\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.7\n", + "[[ 23.46474083 2.39802572 -71.51835509 -12.53162432]\n", + " [ 2.39802572 18.75861639 -6.50220745 -110.86000329]\n", + " [ -71.51835509 -6.50220745 220.70906678 36.55242777]\n", + " [ -12.53162432 -110.86000329 36.55242777 662.76125156]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.53e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.54e-02 3.85e+00 -1.0 1.38e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.52e-04 4.39e+00 -1.0 1.39e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 1.21e-12 1.02e-06 -1.0 1.37e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.2079226507921703e-12 1.2079226507921703e-12\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.2079226507921703e-12 1.2079226507921703e-12\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.108\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.4\n", + "[[ 46.59286925 3.34061422 -147.41037617 -20.11631538]\n", + " [ 3.34061422 35.357865 -10.54739617 -212.94980026]\n", + " [-147.41037617 -10.54739617 466.47049433 63.51258081]\n", + " [ -20.11631538 -212.94980026 63.51258081 1282.53549019]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 6.79e+01 2.55e+02 -1.0 1.97e+02 - 2.54e-03 6.55e-01f 1\n", + " 2 0.0000000e+00 6.61e+01 2.48e+02 -1.0 6.79e+01 - 9.64e-02 2.70e-02h 1\n", + " 3 0.0000000e+00 6.61e+01 8.37e+03 -1.0 6.61e+01 - 1.53e-01 3.12e-04h 1\n", + " 4r 0.0000000e+00 6.61e+01 1.00e+03 1.8 0.00e+00 - 0.00e+00 3.91e-07R 4\n", + " 5r 0.0000000e+00 6.67e+01 5.63e+03 1.8 1.73e+04 - 7.67e-03 9.94e-04f 1\n", + " 6r 0.0000000e+00 6.61e+01 9.66e+03 1.8 1.05e+04 - 7.18e-03 1.92e-03f 1\n", + " 7r 0.0000000e+00 5.73e+01 2.19e+04 1.8 3.17e+03 - 2.31e-02 8.98e-03f 1\n", + " 8r 0.0000000e+00 4.55e+01 4.36e+04 1.8 2.06e+03 - 3.06e-02 6.44e-03f 1\n", + " 9r 0.0000000e+00 1.70e+01 4.20e+04 1.8 1.76e+03 - 2.61e-02 1.63e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 3.30e+00 3.66e+04 1.8 1.16e+03 - 1.46e-01 1.44e-02f 1\n", + " 11r 0.0000000e+00 3.25e+00 3.00e+04 1.8 3.01e+01 - 2.44e-01 4.88e-02f 1\n", + " 12r 0.0000000e+00 2.82e+00 3.21e+04 1.8 2.66e+01 - 1.32e-01 2.76e-01f 1\n", + " 13r 0.0000000e+00 2.37e+00 3.59e+04 1.8 1.50e+01 - 2.84e-01 4.41e-01f 1\n", + " 14r 0.0000000e+00 2.16e+00 1.80e+04 1.8 5.42e+00 - 4.72e-01 4.96e-01f 1\n", + " 15r 0.0000000e+00 2.03e+00 1.32e+04 1.8 2.30e+00 - 3.74e-01 7.02e-01f 1\n", + " 16r 0.0000000e+00 1.98e+00 1.17e+03 1.8 7.23e-01 - 8.25e-01 1.00e+00f 1\n", + " 17r 0.0000000e+00 2.82e+00 1.50e+02 1.1 1.05e+01 - 8.15e-01 1.00e+00f 1\n", + " 18r 0.0000000e+00 2.91e+00 7.78e+02 -0.3 1.91e+00 - 1.00e+00 6.05e-01f 1\n", + " 19r 0.0000000e+00 1.90e+00 4.96e+02 -0.3 2.51e+01 - 3.68e-01 5.07e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 8.26e-01 1.70e+02 -0.3 2.16e+01 - 6.29e-01 6.19e-01f 1\n", + " 21r 0.0000000e+00 2.72e-02 5.46e+01 -0.3 1.07e+01 - 9.66e-01 9.45e-01f 1\n", + " 22r 0.0000000e+00 2.41e-01 9.04e-02 -0.3 2.89e+00 - 1.00e+00 1.00e+00h 1\n", + " 23r 0.0000000e+00 1.84e-01 2.23e+02 -1.7 8.95e-01 - 9.77e-01 8.00e-01f 1\n", + " 24r 0.0000000e+00 9.24e-02 3.27e+03 -1.7 7.88e+01 - 4.30e-01 2.01e-02f 1\n", + " 25r 0.0000000e+00 6.91e-02 4.42e+03 -1.7 2.78e+01 - 1.00e+00 8.35e-02f 1\n", + " 26r 0.0000000e+00 6.19e-02 4.27e+03 -1.7 2.15e+01 - 1.00e+00 1.01e-01f 1\n", + " 27r 0.0000000e+00 5.33e-02 3.71e+03 -1.7 1.63e+01 - 1.00e+00 1.38e-01f 1\n", + " 28r 0.0000000e+00 4.09e-02 2.86e+03 -1.7 1.70e+00 - 1.00e+00 2.31e-01f 1\n", + " 29r 0.0000000e+00 5.26e-04 3.44e+01 -1.7 6.11e-01 - 1.00e+00 9.88e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 4.79e-05 1.18e-05 -1.7 7.08e-03 - 1.00e+00 1.00e+00f 1\n", + " 31r 0.0000000e+00 2.78e-06 4.99e+01 -3.8 9.31e-03 - 1.00e+00 9.51e-01f 1\n", + " 32r 0.0000000e+00 9.04e-07 1.47e+02 -3.8 1.14e-03 - 1.00e+00 6.33e-01f 1\n", + " 33r 0.0000000e+00 2.71e-07 1.48e-07 -3.8 1.85e-04 - 1.00e+00 1.00e+00f 1\n", + " 34r 0.0000000e+00 9.86e-09 2.31e+00 -8.5 6.77e-06 - 1.00e+00 9.30e-01f 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.8581836027733516e-09 9.8581836027733516e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.8581836027733516e-09 9.8581836027733516e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 36\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.544\n", + "Total CPU secs in NLP function evaluations = 0.064\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "[[ 29.19391386 5.4515142 -83.05757061 -24.12403549]\n", + " [ 5.4515142 26.22057856 -12.68483021 -138.46453604]\n", + " [ -83.05757061 -12.68483021 243.6214775 59.65060539]\n", + " [ -24.12403549 -138.46453604 59.65060539 764.11690335]]\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.88e+02 1.06e+02 -1.0 3.97e+02 - 2.54e-03 2.75e-01f 1\n", + " 2 0.0000000e+00 2.84e+02 1.05e+02 -1.0 2.88e+02 - 5.84e-02 1.38e-02h 1\n", + " 3 0.0000000e+00 2.84e+02 6.74e+03 -1.0 2.84e+02 - 8.78e-02 1.63e-04h 1\n", + " 4r 0.0000000e+00 2.84e+02 1.00e+03 2.5 0.00e+00 - 0.00e+00 4.09e-07R 3\n", + " 5r 0.0000000e+00 2.65e+02 4.54e+03 2.5 1.27e+04 - 9.57e-03 2.21e-02f 1\n", + " 6r 0.0000000e+00 2.62e+02 5.22e+03 1.8 1.16e+03 - 1.22e-01 2.99e-03f 1\n", + " 7r 0.0000000e+00 2.17e+02 1.22e+04 1.8 2.24e+03 - 1.37e-01 2.14e-02f 1\n", + " 8r 0.0000000e+00 1.98e+02 2.11e+04 1.8 1.52e+03 - 3.43e-01 1.19e-02f 1\n", + " 9r 0.0000000e+00 7.11e+01 1.83e+04 1.8 8.57e+02 - 1.81e-01 1.62e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 3.55e+01 2.82e+04 1.8 3.09e+02 - 5.74e-01 1.19e-01f 1\n", + " 11r 0.0000000e+00 2.71e+01 2.37e+04 1.8 5.61e+01 - 2.77e-01 1.52e-01f 1\n", + " 12r 0.0000000e+00 1.86e+01 1.20e+04 1.8 3.65e+01 - 1.00e+00 2.34e-01f 1\n", + " 13r 0.0000000e+00 4.96e+00 1.82e+03 1.8 1.80e+01 - 1.00e+00 7.59e-01f 1\n", + " 14r 0.0000000e+00 3.88e+00 2.00e+03 1.1 8.16e+00 - 1.00e+00 6.28e-01f 1\n", + " 15r 0.0000000e+00 3.88e+00 2.12e+03 1.1 1.91e+00 - 1.00e+00 6.37e-01f 1\n", + " 16r 0.0000000e+00 3.89e+00 2.53e+01 1.1 5.29e-01 - 1.00e+00 1.00e+00f 1\n", + " 17r 0.0000000e+00 4.00e+00 9.24e+02 -1.0 6.41e+00 - 9.23e-01 3.65e-01f 1\n", + " 18r 0.0000000e+00 4.00e+00 6.06e+02 -1.0 8.54e+00 - 2.38e-01 6.12e-01f 1\n", + " 19r 0.0000000e+00 3.82e+00 2.67e+03 -1.0 1.38e+01 - 8.45e-03 4.34e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 3.49e+00 2.91e+03 -1.0 2.16e+01 - 1.81e-01 3.33e-01f 1\n", + " 21r 0.0000000e+00 3.04e+00 2.45e+03 -1.0 2.44e+01 - 2.81e-01 4.00e-01f 1\n", + " 22r 0.0000000e+00 2.49e+00 2.47e+03 -1.0 2.48e+01 - 1.11e-01 4.77e-01f 1\n", + " 23r 0.0000000e+00 2.02e+00 9.87e+02 -1.0 1.69e+01 - 5.96e-01 5.88e-01f 1\n", + " 24r 0.0000000e+00 1.58e+00 6.84e+02 -1.0 1.01e+01 - 7.58e-01 9.54e-01f 1\n", + " 25r 0.0000000e+00 1.54e+00 2.82e-03 -1.0 8.65e-01 - 1.00e+00 1.00e+00f 1\n", + " 26r 0.0000000e+00 1.55e+00 4.05e+02 -3.9 4.34e-01 - 9.88e-01 7.49e-01f 1\n", + " 27r 0.0000000e+00 6.78e-02 1.12e+03 -3.9 1.80e+03 - 2.85e-02 1.85e-02f 1\n", + " 28r 0.0000000e+00 6.78e-02 3.06e+03 -3.9 1.77e+03 - 5.48e-02 2.33e-06f 1\n", + " 29r 0.0000000e+00 6.78e-02 3.68e+03 -3.9 1.06e+03 - 9.19e-02 1.15e-04f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 4.53e-02 4.22e+03 -3.9 3.54e+02 - 1.00e+00 1.57e-02f 1\n", + " 31r 0.0000000e+00 3.59e-02 4.41e+03 -3.9 3.39e+02 - 1.00e+00 6.72e-03f 1\n", + " 32r 0.0000000e+00 4.50e-03 4.37e+03 -3.9 3.23e+02 - 1.00e+00 2.67e-02f 1\n", + " 33r 0.0000000e+00 3.36e-03 4.21e+03 -3.9 6.29e+00 - 1.00e+00 4.40e-02f 1\n", + " 34r 0.0000000e+00 1.89e-04 3.05e+02 -3.9 8.22e-01 - 1.00e+00 9.29e-01f 1\n", + " 35r 0.0000000e+00 6.15e-05 1.17e+03 -3.9 4.55e-02 - 1.00e+00 6.75e-01f 1\n", + " 36r 0.0000000e+00 3.79e-05 2.05e+03 -3.9 1.48e-02 - 1.00e+00 3.85e-01f 1\n", + " 37r 0.0000000e+00 1.94e-07 3.86e-06 -3.9 9.09e-03 - 1.00e+00 1.00e+00f 1\n", + " 38r 0.0000000e+00 6.81e-08 1.50e+03 -5.9 1.01e-05 - 1.00e+00 5.73e-01f 1\n", + " 39r 0.0000000e+00 2.35e-08 1.26e+03 -5.9 7.54e-06 - 9.51e-01 7.37e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40r 0.0000000e+00 6.36e-09 4.69e+02 -5.9 1.34e-06 - 1.00e+00 7.63e-01f 1\n", + "\n", + "Number of Iterations....: 40\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 6.3620335666314531e-09 6.3620335666314531e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 6.3620335666314531e-09 6.3620335666314531e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 44\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 44\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 42\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 40\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.718\n", + "Total CPU secs in NLP function evaluations = 0.045\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "[[ 25.12751441 3.3894616 -73.80390505 -15.08681458]\n", + " [ 3.3894616 19.93219076 -7.86497679 -113.88461226]\n", + " [ -73.80390505 -7.86497679 223.85064824 40.06464174]\n", + " [ -15.08681458 -113.88461226 40.06464174 670.5564622 ]]\n" + ] + } + ], + "source": [ + "# Make a function that takes in experimental design and gives you a new doe object\n", + "def new_doe_object(Ca, T0):\n", + " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", + " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", + " \n", + " measurements = MeasurementVariables()\n", + " measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", + " \n", + " exp_design = DesignVariables()\n", + " exp_design.add_variables(\n", + " \"CA0\",\n", + " time_index_position=0,\n", + " # values=[Ca],\n", + " lower_bounds=1,\n", + " indices={0: [0]},\n", + " upper_bounds=5,\n", + " )\n", + " exp_design.add_variables(\n", + " \"T\",\n", + " indices={0: t_control},\n", + " time_index_position=0,\n", + " # values=[T0]*9,\n", + " lower_bounds=300,\n", + " upper_bounds=700,\n", + " )\n", + "\n", + " exp_design.update_values({\"CA0[0]\": Ca, \"T[0]\": T0, \"T[0.125]\": T0, \"T[0.25]\": T0, \"T[0.375]\": T0, \"T[0.5]\": T0, \"T[0.625]\": T0,\n", + " \"T[0.75]\": T0, \"T[0.875]\": T0, \"T[1]\": T0})\n", + "\n", + " prior_pass = [\n", + " [22.52943024, 1.84034314, -70.23273336, -11.09432962],\n", + " [1.84034314, 18.09848116, -5.73565034, -109.15866135],\n", + " [-70.23273336, -5.73565034, 218.94192843, 34.57680848],\n", + " [-11.09432962, -109.15866135, 34.57680848, 658.37644634]\n", + " ]\n", + " \n", + " doe_object = DesignOfExperiments(\n", + " parameter_dict,\n", + " exp_design, \n", + " measurements, \n", + " create_model,\n", + " prior_FIM=prior_pass,\n", + " discretize_model=disc_for_measure,\n", + " )\n", + "\n", + " result = doe_object.compute_FIM(\n", + " mode=\"sequential_finite\",\n", + " scale_nominal_param_value=True,\n", + " formula=\"central\",\n", + " )\n", + "\n", + " result.result_analysis()\n", + " \n", + " return result\n", + "\n", + "\n", + "# Discretize the experimental design space (make a linspace) for sensitivity analysis\n", + "T_vals = np.linspace(300, 700, 3)\n", + "C_vals = np.linspace(1, 5, 3)\n", + "\n", + "A_opt_vals = []\n", + "D_opt_vals = []\n", + "E_opt_vals = []\n", + "ME_opt_vals = []\n", + "for i in C_vals:\n", + " for j in T_vals:\n", + " fims = new_doe_object(i, j)\n", + " print(fims.FIM)\n", + " A_opt = np.trace(fims.FIM)\n", + " D_opt = np.linalg.det(fims.FIM)\n", + " E_opt = min(np.linalg.eigvals(fims.FIM))\n", + " ME_opt = np.linalg.cond(fims.FIM)\n", + " \n", + " A_opt_vals.append(np.log10(A_opt))\n", + " D_opt_vals.append(np.log10(D_opt))\n", + " E_opt_vals.append(np.log10(E_opt))\n", + " ME_opt_vals.append(np.log10(ME_opt))" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "id": "f05a1814-1b73-4eef-853b-58594589635f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([4.10820024])" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# random experiment loop\n", + "np.random.rand(1) * 4 + 1" + ] + }, + { + "cell_type": "code", + "execution_count": 94, + "id": "3127f8a2-798e-474e-a90d-89eb1c2aca06", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.47e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.64e+01 3.85e+02 -1.0 1.47e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.71e+00 5.99e+01 -1.0 3.11e+01 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 3.98e-02 2.06e+00 -1.0 3.19e+00 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 7.87e-07 2.39e-04 -1.0 2.80e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (287125)\n", + " 5 0.0000000e+00 2.27e-13 1.50e-09 -3.8 5.42e-07 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.3691704763652764e-13 2.2737367544323206e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.3691704763652764e-13 2.2737367544323206e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.072\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.4\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.79e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 9.63e+01 2.70e+02 -1.0 3.79e+02 - 2.73e-03 7.46e-01f 1\n", + " 2 0.0000000e+00 9.32e+01 2.61e+02 -1.0 9.63e+01 - 6.76e-02 3.18e-02h 1\n", + " 3 0.0000000e+00 9.32e+01 4.47e+03 -1.0 9.32e+01 - 1.23e-01 3.69e-04h 1\n", + " 4r 0.0000000e+00 9.32e+01 1.00e+03 2.0 0.00e+00 - 0.00e+00 4.62e-07R 4\n", + " 5r 0.0000000e+00 9.47e+01 3.38e+03 2.0 1.88e+04 - 7.23e-03 1.52e-03f 1\n", + " 6r 0.0000000e+00 9.56e+01 8.77e+03 1.3 9.69e+03 - 1.49e-02 2.29e-03f 1\n", + " 7r 0.0000000e+00 9.02e+01 1.81e+04 1.3 2.12e+03 - 1.81e-02 5.67e-03f 1\n", + " 8r 0.0000000e+00 7.27e+01 4.84e+04 1.3 2.78e+03 - 4.24e-02 8.77e-03f 1\n", + " 9r 0.0000000e+00 7.18e+01 4.87e+04 1.3 1.96e+03 - 1.12e-02 4.83e-04f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 3.41e+01 4.77e+04 1.3 1.67e+03 - 1.59e-02 2.26e-02f 1\n", + " 11r 0.0000000e+00 2.89e+01 4.49e+04 1.3 1.04e+03 - 1.79e-01 4.94e-03f 1\n", + " 12r 0.0000000e+00 2.20e+01 3.81e+04 1.3 2.29e+02 - 2.37e-01 3.01e-02f 1\n", + " 13r 0.0000000e+00 7.18e+00 3.39e+04 1.3 9.62e+01 - 3.56e-01 1.55e-01f 1\n", + " 14r 0.0000000e+00 3.48e+00 3.59e+04 1.3 2.78e+01 - 6.26e-01 2.52e-01f 1\n", + " 15r 0.0000000e+00 2.86e+00 2.83e+04 1.3 1.68e+01 - 3.20e-02 1.85e-01f 1\n", + " 16r 0.0000000e+00 2.68e+00 2.65e+04 1.3 1.50e+01 - 1.58e-01 6.45e-02f 1\n", + " 17r 0.0000000e+00 2.20e+00 2.12e+04 1.3 6.49e+00 - 5.44e-01 1.84e-01f 1\n", + " 18r 0.0000000e+00 1.93e+00 9.46e+03 1.3 4.48e+00 - 7.25e-01 5.25e-01f 1\n", + " 19r 0.0000000e+00 1.89e+00 6.10e+03 1.3 1.60e+00 - 1.00e+00 3.45e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 1.87e+00 3.70e+03 1.3 7.92e-01 - 3.59e-01 4.16e-01f 1\n", + " 21r 0.0000000e+00 1.87e+00 3.40e+04 1.3 4.32e-01 - 6.73e-01 2.10e-01f 1\n", + " 22r 0.0000000e+00 1.87e+00 1.96e+04 1.3 3.07e-01 - 2.16e-01 3.56e-01f 1\n", + " 23r 0.0000000e+00 1.88e+00 5.64e+04 1.3 2.13e-01 - 2.36e-01 1.00e+00f 1\n", + " 24r 0.0000000e+00 1.86e+00 2.34e+00 1.3 2.78e-01 - 1.00e+00 1.00e+00f 1\n", + " 25r 0.0000000e+00 2.46e+00 3.10e+01 -0.8 8.15e+00 - 6.90e-01 7.24e-01f 1\n", + " 26r 0.0000000e+00 1.88e+00 3.41e+02 -0.8 2.98e+01 - 4.36e-01 3.54e-01f 1\n", + " 27r 0.0000000e+00 5.36e-01 3.71e+02 -0.8 3.60e+01 - 4.50e-01 4.02e-01f 1\n", + " 28r 0.0000000e+00 9.73e-02 1.52e+03 -0.8 4.27e+01 - 3.79e-01 1.29e-01f 1\n", + " 29r 0.0000000e+00 9.74e-02 4.95e+03 -0.8 3.18e+01 - 6.93e-01 3.32e-03f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 9.31e-02 5.14e+03 -0.8 8.75e+00 - 1.00e+00 1.62e-01f 1\n", + " 31r 0.0000000e+00 7.82e-02 1.83e+03 -0.8 6.58e+00 - 1.00e+00 6.63e-01f 1\n", + " 32r 0.0000000e+00 7.12e-02 1.65e+02 -0.8 2.21e+00 - 1.00e+00 9.14e-01f 1\n", + " 33r 0.0000000e+00 7.05e-02 2.39e-05 -0.8 2.63e-01 - 1.00e+00 1.00e+00f 1\n", + " 34r 0.0000000e+00 7.07e-02 1.56e+02 -3.4 4.12e-01 - 1.00e+00 7.89e-01f 1\n", + " 35r 0.0000000e+00 3.58e-04 8.04e+02 -3.4 5.07e+02 - 9.62e-01 3.36e-02f 1\n", + " 36r 0.0000000e+00 3.58e-04 8.39e+02 -3.4 2.26e+02 - 1.00e+00 8.40e-05f 1\n", + " 37r 0.0000000e+00 1.64e-04 4.20e+02 -3.4 9.66e-02 - 1.00e+00 5.43e-01f 1\n", + " 38r 0.0000000e+00 6.08e-08 1.58e-05 -3.4 4.52e-02 - 1.00e+00 1.00e+00f 1\n", + " 39r 0.0000000e+00 4.61e-10 3.50e-01 -7.7 2.55e-05 - 1.00e+00 9.99e-01f 1\n", + "\n", + "Number of Iterations....: 39\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.6097259343014230e-10 4.6097259343014230e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.6097259343014230e-10 4.6097259343014230e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 44\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 44\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 41\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 39\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.332\n", + "Total CPU secs in NLP function evaluations = 0.028\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.47e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.21e+02 1.90e+02 -1.0 3.47e+02 - 3.38e-03 6.51e-01f 1\n", + " 2 0.0000000e+00 1.16e+02 1.83e+02 -1.0 1.21e+02 - 8.04e-02 3.68e-02h 1\n", + " 3 0.0000000e+00 1.16e+02 5.05e+03 -1.0 1.16e+02 - 1.48e-01 4.53e-04h 1\n", + " 4r 0.0000000e+00 1.16e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 2.84e-07R 5\n", + " 5r 0.0000000e+00 1.14e+02 2.71e+03 2.1 7.90e+03 - 1.08e-02 5.20e-03f 1\n", + " 6r 0.0000000e+00 1.10e+02 8.74e+03 1.4 1.44e+03 - 2.83e-02 5.26e-03f 1\n", + " 7r 0.0000000e+00 8.03e+01 1.59e+04 1.4 3.04e+03 - 4.49e-02 1.19e-02f 1\n", + " 8r 0.0000000e+00 4.23e+01 1.55e+04 1.4 2.42e+03 - 6.77e-02 1.57e-02f 1\n", + " 9r 0.0000000e+00 2.55e+01 9.59e+03 1.4 1.06e+03 - 3.03e-01 1.60e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 2.97e+00 6.56e+03 1.4 1.85e+02 - 1.66e-01 1.30e-01f 1\n", + " 11r 0.0000000e+00 2.46e+00 6.17e+03 1.4 2.18e+01 - 2.39e-01 1.35e-01f 1\n", + " 12r 0.0000000e+00 1.69e+00 8.83e+03 1.4 1.49e+01 - 2.90e-01 5.14e-01f 1\n", + " 13r 0.0000000e+00 1.63e+00 5.65e+03 1.4 2.04e+00 - 4.09e-01 3.77e-01f 1\n", + " 14r 0.0000000e+00 1.63e+00 4.72e+03 1.4 1.76e+00 - 1.17e-01 4.02e-01f 1\n", + " 15r 0.0000000e+00 1.63e+00 4.34e+03 1.4 1.14e+00 - 3.39e-01 2.20e-01f 1\n", + " 16r 0.0000000e+00 1.63e+00 5.17e+03 1.4 5.39e-01 - 2.44e-01 3.70e-01f 1\n", + " 17r 0.0000000e+00 1.61e+00 1.25e+04 1.4 2.67e-01 - 3.33e-01 1.00e+00f 1\n", + " 18r 0.0000000e+00 1.57e+00 6.37e-01 1.4 3.12e-01 - 1.00e+00 1.00e+00f 1\n", + " 19r 0.0000000e+00 2.14e+00 7.01e+01 -0.7 5.85e+00 - 6.75e-01 7.41e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 1.66e+00 6.97e+01 -0.7 1.81e+01 - 4.31e-01 4.08e-01f 1\n", + " 21r 0.0000000e+00 7.63e-01 5.00e+02 -0.7 2.19e+01 - 5.02e-01 3.90e-01f 1\n", + " 22r 0.0000000e+00 7.13e-02 6.33e+02 -0.7 2.85e+01 - 4.13e-01 2.39e-01f 1\n", + " 23r 0.0000000e+00 7.15e-02 1.44e+03 -0.7 2.04e+01 - 4.36e-01 4.86e-03f 1\n", + " 24r 0.0000000e+00 7.02e-02 2.07e+03 -0.7 5.19e+00 - 1.00e+00 8.72e-02f 1\n", + " 25r 0.0000000e+00 5.96e-02 3.86e+02 -0.7 4.18e+00 - 1.00e+00 8.42e-01f 1\n", + " 26r 0.0000000e+00 5.77e-02 2.81e-03 -0.7 6.30e-01 - 1.00e+00 1.00e+00f 1\n", + " 27r 0.0000000e+00 5.79e-02 6.37e+02 -3.2 5.03e-01 - 9.99e-01 6.84e-01f 1\n", + " 28r 0.0000000e+00 3.93e-02 2.66e+03 -3.2 2.99e+02 - 9.51e-01 1.50e-02f 1\n", + " 29r 0.0000000e+00 4.06e-04 3.64e+03 -3.2 2.94e+02 - 1.00e+00 3.22e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 4.05e-04 3.79e+03 -3.2 2.60e+01 - 1.00e+00 1.82e-03f 1\n", + " 31r 0.0000000e+00 2.92e-05 2.72e+02 -3.2 1.69e-01 - 1.00e+00 9.28e-01f 1\n", + " 32r 0.0000000e+00 1.25e-07 7.91e-06 -3.2 1.22e-02 - 1.00e+00 1.00e+00f 1\n", + " 33r 0.0000000e+00 5.10e-09 4.43e-01 -7.2 5.28e-05 - 1.00e+00 9.97e-01f 1\n", + "\n", + "Number of Iterations....: 33\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.1933425768594618e-09 5.0964019530138488e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.1933425768594618e-09 5.0964019530138488e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 35\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 33\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.281\n", + "Total CPU secs in NLP function evaluations = 0.043\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.75e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.27e+02 8.39e+01 -1.0 3.75e+02 - 7.66e-03 6.60e-01f 1\n", + " 2 0.0000000e+00 1.21e+02 7.95e+01 -1.0 1.27e+02 - 8.92e-02 5.26e-02h 1\n", + " 3 0.0000000e+00 1.21e+02 5.06e+03 -1.0 1.21e+02 - 1.90e-01 6.85e-04h 1\n", + " 4r 0.0000000e+00 1.21e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 4.29e-07R 5\n", + " 5r 0.0000000e+00 1.18e+02 3.76e+03 2.1 1.32e+04 - 1.10e-02 4.67e-03f 1\n", + " 6r 0.0000000e+00 1.13e+02 1.04e+04 1.4 1.51e+03 - 2.60e-02 6.04e-03f 1\n", + " 7r 0.0000000e+00 7.22e+01 1.49e+04 1.4 2.88e+03 - 2.82e-02 1.57e-02f 1\n", + " 8r 0.0000000e+00 4.91e+01 1.55e+04 1.4 2.25e+03 - 1.34e-01 1.11e-02f 1\n", + " 9r 0.0000000e+00 4.46e+01 1.03e+04 1.4 6.00e+02 - 1.39e-01 7.47e-03f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 1.28e+01 2.43e+04 1.4 2.89e+02 - 3.16e-01 1.10e-01f 1\n", + " 11r 0.0000000e+00 2.22e+00 2.04e+04 1.4 6.20e+01 - 2.94e-01 2.05e-01f 1\n", + " 12r 0.0000000e+00 1.78e+00 1.86e+04 1.4 1.16e+01 - 6.29e-01 1.84e-01f 1\n", + " 13r 0.0000000e+00 1.60e+00 1.47e+04 1.4 1.15e+01 - 2.26e-01 1.37e-01f 1\n", + " 14r 0.0000000e+00 1.18e+00 1.20e+04 1.4 5.45e+00 - 1.92e-01 2.67e-01f 1\n", + " 15r 0.0000000e+00 8.27e-01 7.10e+03 1.4 4.24e+00 - 3.39e-01 2.57e-01f 1\n", + " 16r 0.0000000e+00 7.55e-01 4.82e+03 1.4 2.29e+00 - 4.12e-01 1.42e-01f 1\n", + " 17r 0.0000000e+00 5.13e-01 1.07e+04 1.4 1.12e+00 - 2.45e-01 4.22e-01f 1\n", + " 18r 0.0000000e+00 5.10e-01 8.28e+03 1.4 6.72e-01 - 2.21e-01 2.17e-01f 1\n", + " 19r 0.0000000e+00 5.06e-01 9.33e+03 1.4 5.23e-01 - 2.44e-01 5.04e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 4.54e-01 9.33e+01 1.4 5.96e-01 - 9.69e-01 1.00e+00f 1\n", + " 21r 0.0000000e+00 9.44e-01 4.24e+02 -0.0 4.97e+00 - 4.34e-01 7.87e-01f 1\n", + " 22r 0.0000000e+00 7.53e-01 9.03e+01 -0.0 7.82e+00 - 5.74e-01 5.18e-01f 1\n", + " 23r 0.0000000e+00 3.96e-01 3.26e+02 -0.0 6.53e+00 - 7.93e-01 6.49e-01f 1\n", + " 24r 0.0000000e+00 6.22e-02 1.69e+02 -0.0 5.24e+00 - 1.00e+00 8.48e-01f 1\n", + " 25r 0.0000000e+00 1.21e-01 5.96e-02 -0.0 1.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 26r 0.0000000e+00 1.23e-01 2.48e+01 -1.4 6.66e-01 - 7.98e-01 7.68e-01f 1\n", + " 27r 0.0000000e+00 8.31e-02 1.67e+03 -1.4 6.15e+01 - 1.89e-01 1.54e-02f 1\n", + " 28r 0.0000000e+00 7.45e-02 3.08e+03 -1.4 2.92e+01 - 8.39e-01 1.52e-02f 1\n", + " 29r 0.0000000e+00 5.63e-02 2.74e+03 -1.4 2.79e+01 - 1.00e+00 1.93e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 3.32e-02 1.62e+03 -1.4 2.20e+01 - 1.00e+00 4.05e-01f 1\n", + " 31r 0.0000000e+00 3.05e-02 1.50e+03 -1.4 4.31e+00 - 1.00e+00 7.84e-02f 1\n", + " 32r 0.0000000e+00 2.85e-03 1.41e+02 -1.4 5.52e-01 - 1.00e+00 9.06e-01f 1\n", + " 33r 0.0000000e+00 8.12e-05 5.53e-04 -1.4 4.22e-02 - 1.00e+00 1.00e+00f 1\n", + " 34r 0.0000000e+00 5.19e-06 2.99e+01 -4.8 3.09e-02 - 1.00e+00 9.39e-01f 1\n", + " 35r 0.0000000e+00 2.12e-06 3.88e+02 -4.8 5.79e-03 - 1.00e+00 3.73e-01f 1\n", + " 36r 0.0000000e+00 4.48e-10 1.79e-06 -4.8 5.54e-04 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 36\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.4780146257750175e-10 4.4780146257750175e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.4780146257750175e-10 4.4780146257750175e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 42\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 42\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 38\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 36\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.329\n", + "Total CPU secs in NLP function evaluations = 0.023\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.8\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.15e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 5.48e+01 2.03e+02 -1.0 3.15e+02 - 4.01e-03 8.26e-01f 1\n", + " 2 0.0000000e+00 5.18e+01 1.92e+02 -1.0 5.48e+01 - 8.17e-02 5.52e-02h 1\n", + " 3 0.0000000e+00 5.17e+01 4.29e+03 -1.0 5.18e+01 - 1.73e-01 6.99e-04h 1\n", + " 4r 0.0000000e+00 5.17e+01 1.00e+03 1.7 0.00e+00 - 0.00e+00 4.38e-07R 5\n", + " 5r 0.0000000e+00 5.21e+01 3.90e+03 1.7 2.34e+03 - 4.16e-03 6.39e-04f 1\n", + " 6r 0.0000000e+00 5.22e+01 7.89e+03 1.7 1.59e+03 - 5.68e-03 1.06e-03f 1\n", + " 7r 0.0000000e+00 5.14e+01 4.08e+04 1.7 1.33e+03 - 4.31e-02 4.03e-03f 1\n", + " 8r 0.0000000e+00 3.35e+01 4.38e+04 1.7 1.29e+03 - 2.87e-02 1.99e-02f 1\n", + " 9r 0.0000000e+00 2.33e+01 3.77e+04 1.7 2.06e+03 - 8.82e-02 4.96e-03f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 5.31e+00 2.32e+04 1.7 8.19e+02 - 4.10e-01 2.82e-02f 1\n", + " 11r 0.0000000e+00 3.31e+00 9.35e+03 1.7 2.79e+01 - 4.57e-01 2.18e-01f 1\n", + " 12r 0.0000000e+00 1.54e+00 1.11e+04 1.7 1.44e+01 - 3.37e-01 4.76e-01f 1\n", + " 13r 0.0000000e+00 9.67e-01 5.00e+03 1.7 3.61e+00 - 6.85e-01 6.15e-01f 1\n", + " 14r 0.0000000e+00 7.59e-01 7.16e+00 1.7 2.56e+00 - 1.00e+00 1.00e+00f 1\n", + " 15r 0.0000000e+00 1.45e+00 2.49e+02 -0.4 9.91e+00 - 4.68e-01 7.63e-01f 1\n", + " 16r 0.0000000e+00 1.16e+00 3.68e+02 -0.4 1.08e+01 - 6.33e-01 4.50e-01f 1\n", + " 17r 0.0000000e+00 3.39e-01 2.33e+02 -0.4 1.75e+01 - 6.02e-01 5.35e-01f 1\n", + " 18r 0.0000000e+00 2.54e-02 1.04e+03 -0.4 2.08e+01 - 6.33e-01 1.79e-01f 1\n", + " 19r 0.0000000e+00 2.53e-02 1.45e+03 -0.4 6.72e+00 - 1.00e+00 1.86e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 1.60e-02 1.72e+02 -0.4 4.41e+00 - 1.00e+00 8.92e-01f 1\n", + " 21r 0.0000000e+00 1.49e-02 3.13e-03 -0.4 4.38e-01 - 1.00e+00 1.00e+00f 1\n", + " 22r 0.0000000e+00 1.46e-02 4.88e+02 -2.7 5.10e-01 - 1.00e+00 7.79e-01f 1\n", + " 23r 0.0000000e+00 1.62e-03 1.95e+03 -2.7 1.98e+02 - 8.89e-01 1.78e-02f 1\n", + " 24r 0.0000000e+00 1.33e-03 1.81e+03 -2.7 1.39e+00 - 1.00e+00 6.22e-02f 1\n", + " 25r 0.0000000e+00 7.19e-06 1.11e+01 -2.7 4.06e-01 - 1.00e+00 9.94e-01f 1\n", + " 26r 0.0000000e+00 3.77e-07 6.55e-08 -2.7 2.13e-03 - 1.00e+00 1.00e+00f 1\n", + " 27r 0.0000000e+00 7.89e-09 4.38e-01 -6.0 1.65e-04 - 1.00e+00 9.99e-01f 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 6.8976688608700370e-09 7.8893271863306191e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 6.8976688608700370e-09 7.8893271863306191e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 29\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.279\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.45e+02 4.98e+01 -1.0 3.96e+02 - 7.44e-03 3.82e-01f 1\n", + " 2 0.0000000e+00 2.36e+02 4.81e+01 -1.0 2.45e+02 - 1.33e-01 3.44e-02h 1\n", + " 3 0.0000000e+00 2.36e+02 1.20e+04 -1.0 2.36e+02 - 2.37e-01 4.38e-04h 1\n", + " 4r 0.0000000e+00 2.36e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 2.75e-07R 5\n", + " 5r 0.0000000e+00 2.26e+02 1.13e+03 2.4 1.23e+04 - 7.14e-03 8.92e-03f 1\n", + " 6r 0.0000000e+00 2.22e+02 2.63e+03 1.0 1.35e+03 - 4.20e-02 3.84e-03f 1\n", + " 7r 0.0000000e+00 1.66e+02 4.09e+03 1.0 4.68e+03 - 2.15e-02 1.19e-02f 1\n", + " 8r 0.0000000e+00 1.54e+02 7.04e+03 1.0 3.41e+03 - 6.48e-02 3.70e-03f 1\n", + " 9r 0.0000000e+00 1.00e+02 9.04e+03 1.0 2.10e+03 - 1.47e-01 2.81e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 5.77e+01 9.14e+03 1.0 6.36e+02 - 2.78e-01 6.69e-02f 1\n", + " 11r 0.0000000e+00 2.10e+01 7.43e+03 1.0 1.64e+02 - 2.45e-01 2.24e-01f 1\n", + " 12r 0.0000000e+00 6.07e+00 7.89e+03 1.0 4.33e+01 - 6.44e-01 3.46e-01f 1\n", + " 13r 0.0000000e+00 2.19e+00 4.02e+03 1.0 8.39e+00 - 5.64e-01 4.67e-01f 1\n", + " 14r 0.0000000e+00 9.56e-01 1.95e+03 1.0 3.19e+00 - 4.50e-01 3.89e-01f 1\n", + " 15r 0.0000000e+00 5.36e-01 9.74e+02 1.0 1.71e+00 - 3.50e-01 3.26e-01f 1\n", + " 16r 0.0000000e+00 5.38e-01 2.58e+03 1.0 9.75e-01 - 3.56e-01 4.28e-01f 1\n", + " 17r 0.0000000e+00 5.42e-01 1.63e+03 1.0 6.88e-01 - 6.24e-01 5.31e-01f 1\n", + " 18r 0.0000000e+00 5.46e-01 7.82e+00 1.0 5.18e-01 - 1.00e+00 1.00e+00f 1\n", + " 19r 0.0000000e+00 9.22e-01 4.37e+02 -1.1 5.33e+00 - 5.40e-01 8.04e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 5.65e-01 1.82e+03 -1.1 1.08e+01 - 1.64e-01 4.12e-01f 1\n", + " 21r 0.0000000e+00 4.50e-02 1.28e+03 -1.1 1.65e+01 - 3.58e-01 3.90e-01f 1\n", + " 22r 0.0000000e+00 2.31e-03 2.20e+03 -1.1 2.78e+01 - 4.49e-01 1.90e-02f 1\n", + " 23r 0.0000000e+00 2.27e-03 2.78e+03 -1.1 2.10e+00 - 1.00e+00 1.41e-02f 1\n", + " 24r 0.0000000e+00 1.39e-04 2.09e+02 -1.1 9.81e-01 - 1.00e+00 9.24e-01f 1\n", + " 25r 0.0000000e+00 6.99e-05 1.01e-03 -1.1 2.85e-02 - 1.00e+00 1.00e+00f 1\n", + " 26r 0.0000000e+00 2.43e-05 6.84e+02 -4.1 2.96e-02 - 1.00e+00 7.85e-01f 1\n", + " 27r 0.0000000e+00 1.04e-05 1.23e+03 -4.1 1.49e-02 - 8.56e-01 6.16e-01f 1\n", + " 28r 0.0000000e+00 4.47e-07 1.96e+01 -4.1 2.40e-03 - 1.00e+00 9.84e-01f 1\n", + " 29r 0.0000000e+00 2.05e-09 1.48e-08 -4.1 2.07e-04 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.0521482846369565e-09 2.0521482846369565e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.0521482846369565e-09 2.0521482846369565e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 35\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 35\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 31\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.239\n", + "Total CPU secs in NLP function evaluations = 0.039\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.72e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.61e+02 3.60e+01 -1.0 3.72e+02 - 7.93e-03 2.96e-01f 1\n", + " 2 0.0000000e+00 2.53e+02 3.49e+01 -1.0 2.61e+02 - 1.58e-01 3.06e-02h 1\n", + " 3 0.0000000e+00 2.53e+02 2.01e+04 -1.0 2.53e+02 - 3.10e-01 3.94e-04h 1\n", + " 4r 0.0000000e+00 2.53e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.95e-07R 4\n", + " 5r 0.0000000e+00 2.37e+02 1.05e+04 2.4 1.51e+04 - 1.17e-03 1.25e-02f 1\n", + " 6r 0.0000000e+00 2.35e+02 1.18e+04 1.7 1.30e+03 - 8.34e-02 1.70e-03f 1\n", + " 7r 0.0000000e+00 1.83e+02 1.27e+04 1.7 2.44e+03 - 6.29e-02 2.12e-02f 1\n", + " 8r 0.0000000e+00 1.24e+02 1.00e+04 1.7 1.85e+03 - 1.40e-01 3.23e-02f 1\n", + " 9r 0.0000000e+00 6.63e+01 1.21e+04 1.7 1.16e+03 - 2.28e-01 5.10e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 3.68e+01 1.07e+04 1.7 4.32e+02 - 2.77e-01 6.82e-02f 1\n", + " 11r 0.0000000e+00 1.57e+01 9.36e+03 1.7 1.56e+02 - 2.53e-01 1.35e-01f 1\n", + " 12r 0.0000000e+00 2.87e+00 8.33e+03 1.7 6.40e+01 - 5.80e-01 2.43e-01f 1\n", + " 13r 0.0000000e+00 1.93e+00 5.21e+03 1.7 3.30e+00 - 7.93e-01 3.21e-01f 1\n", + " 14r 0.0000000e+00 2.80e-01 2.68e+03 1.7 1.93e+00 - 7.69e-01 1.00e+00f 1\n", + " 15r 0.0000000e+00 1.98e-01 2.17e+03 1.0 2.62e+00 - 1.00e+00 3.68e-01f 1\n", + " 16r 0.0000000e+00 9.94e-02 2.32e+02 1.0 2.49e+00 - 1.00e+00 9.35e-01f 1\n", + " 17r 0.0000000e+00 1.07e-01 2.05e+02 0.3 1.61e+00 - 3.29e-01 4.41e-01f 1\n", + " 18r 0.0000000e+00 1.04e-01 1.05e+03 0.3 3.32e+00 - 1.00e+00 5.33e-01f 1\n", + " 19r 0.0000000e+00 6.40e-02 4.29e-01 0.3 1.54e+00 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 1.07e-01 1.10e+02 -1.8 1.41e+00 - 3.80e-01 4.37e-01f 1\n", + " 21r 0.0000000e+00 1.07e-01 2.01e+02 -1.8 1.95e+01 - 1.74e-01 2.31e-01f 1\n", + " 22r 0.0000000e+00 6.49e-02 5.91e+02 -1.8 9.96e+00 - 2.51e-03 1.11e-01f 1\n", + " 23r 0.0000000e+00 6.33e-02 4.58e+02 -1.8 1.93e+01 - 2.98e-02 7.77e-04f 1\n", + " 24r 0.0000000e+00 5.10e-02 3.76e+02 -1.8 1.93e+01 - 4.61e-02 5.71e-03f 1\n", + " 25r 0.0000000e+00 2.14e-02 2.76e+02 -1.8 1.72e+01 - 6.59e-02 1.56e-02f 1\n", + " 26r 0.0000000e+00 2.87e-03 1.64e+03 -1.8 7.05e+00 - 6.11e-01 3.14e-02f 1\n", + " 27r 0.0000000e+00 1.38e-03 1.02e+03 -1.8 7.30e-01 - 1.00e+00 5.15e-01f 1\n", + " 28r 0.0000000e+00 2.95e-04 3.93e+02 -1.8 1.31e-01 - 1.00e+00 8.08e-01f 1\n", + " 29r 0.0000000e+00 9.46e-05 7.73e+02 -1.8 2.27e-02 - 1.00e+00 7.75e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 3.57e-05 3.29e-04 -1.8 5.02e-03 - 1.00e+00 1.00e+00f 1\n", + " 31r 0.0000000e+00 6.02e-06 6.92e+02 -4.0 3.94e-03 - 1.00e+00 6.62e-01f 1\n", + " 32r 0.0000000e+00 2.81e-06 1.20e+03 -4.0 2.72e-03 - 9.73e-01 6.04e-01f 1\n", + " 33r 0.0000000e+00 9.98e-07 5.98e+02 -4.0 2.90e-04 - 9.64e-01 7.94e-01f 1\n", + " 34r 0.0000000e+00 2.20e-08 6.50e-06 -4.0 7.03e-05 - 1.00e+00 1.00e+00f 1\n", + " 35r 0.0000000e+00 2.23e-09 8.19e-02 -6.0 1.55e-06 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 35\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8426819152568400e-09 2.2255034382400569e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8426819152568400e-09 2.2255034382400569e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 40\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 40\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 37\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 35\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.274\n", + "Total CPU secs in NLP function evaluations = 0.058\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.87e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.68e+02 8.00e+01 -1.0 3.87e+02 - 6.89e-03 5.66e-01f 1\n", + " 2 0.0000000e+00 1.63e+02 7.76e+01 -1.0 1.68e+02 - 7.67e-02 2.95e-02h 1\n", + " 3 0.0000000e+00 1.63e+02 5.80e+03 -1.0 1.63e+02 - 1.40e-01 3.53e-04h 1\n", + " 4r 0.0000000e+00 1.63e+02 1.00e+03 2.2 0.00e+00 - 0.00e+00 4.43e-07R 4\n", + " 5r 0.0000000e+00 1.59e+02 6.51e+03 2.2 1.63e+04 - 1.20e-03 7.89e-03f 1\n", + " 6r 0.0000000e+00 1.58e+02 7.34e+03 1.5 1.51e+03 - 3.35e-02 1.55e-03f 1\n", + " 7r 0.0000000e+00 1.25e+02 9.10e+03 1.5 2.75e+03 - 3.40e-02 1.20e-02f 1\n", + " 8r 0.0000000e+00 7.96e+01 1.06e+04 1.5 2.37e+03 - 1.07e-01 2.00e-02f 1\n", + " 9r 0.0000000e+00 5.15e+01 1.07e+04 1.5 1.06e+03 - 1.37e-01 2.93e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 2.98e+01 9.15e+03 1.5 3.66e+02 - 1.10e-01 6.31e-02f 1\n", + " 11r 0.0000000e+00 1.42e+01 7.49e+03 1.5 1.56e+02 - 1.92e-01 1.00e-01f 1\n", + " 12r 0.0000000e+00 5.99e+00 6.19e+03 1.5 5.89e+01 - 2.77e-01 1.39e-01f 1\n", + " 13r 0.0000000e+00 1.73e+00 4.52e+03 1.5 2.35e+01 - 3.82e-01 2.55e-01f 1\n", + " 14r 0.0000000e+00 1.29e+00 2.91e+03 1.5 6.53e+00 - 4.45e-01 3.67e-01f 1\n", + " 15r 0.0000000e+00 1.23e+00 5.95e+03 1.5 2.69e+00 - 2.74e-01 5.38e-01f 1\n", + " 16r 0.0000000e+00 1.17e+00 1.13e+03 1.5 2.10e+00 - 7.15e-01 9.68e-01f 1\n", + " 17r 0.0000000e+00 1.51e+00 1.07e+02 0.8 7.88e+00 - 8.98e-01 9.05e-01f 1\n", + " 18r 0.0000000e+00 1.52e+00 5.98e+02 0.1 1.35e+00 - 1.00e+00 6.47e-01f 1\n", + " 19r 0.0000000e+00 1.45e+00 8.89e+02 0.1 2.43e+00 - 1.94e-01 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 1.11e+00 1.71e+02 0.1 7.15e+00 - 9.26e-01 1.00e+00f 1\n", + " 21r 0.0000000e+00 1.05e+00 4.83e-02 0.1 1.29e+00 - 1.00e+00 1.00e+00f 1\n", + " 22r 0.0000000e+00 1.19e+00 1.23e+02 -2.0 3.72e+00 - 8.52e-01 7.58e-01f 1\n", + " 23r 0.0000000e+00 4.52e-02 1.95e+03 -2.0 1.34e+02 - 5.22e-02 1.81e-01f 1\n", + " 24r 0.0000000e+00 2.87e-02 1.09e+03 -2.0 1.48e+02 - 1.91e-01 5.32e-03f 1\n", + " 25r 0.0000000e+00 2.87e-02 2.29e+03 -2.0 9.93e+01 - 3.30e-01 8.99e-04f 1\n", + " 26r 0.0000000e+00 1.33e-02 2.25e+03 -2.0 2.85e+01 - 1.00e+00 1.34e-01f 1\n", + " 27r 0.0000000e+00 3.43e-03 2.10e+03 -2.0 2.20e+01 - 1.00e+00 1.39e-01f 1\n", + " 28r 0.0000000e+00 1.99e-03 1.83e+03 -2.0 2.20e+00 - 1.00e+00 1.64e-01f 1\n", + " 29r 0.0000000e+00 1.11e-04 1.19e+02 -2.0 6.96e-01 - 1.00e+00 9.38e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 1.14e-05 2.14e-04 -2.0 4.33e-02 - 1.00e+00 1.00e+00f 1\n", + " 31r 0.0000000e+00 3.06e-06 1.72e+02 -4.5 3.76e-03 - 1.00e+00 8.67e-01f 1\n", + " 32r 0.0000000e+00 1.29e-06 1.73e+02 -4.5 1.18e-03 - 1.00e+00 5.83e-01f 1\n", + " 33r 0.0000000e+00 1.76e-09 1.28e-06 -4.5 1.67e-04 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 33\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.7635167770535531e-09 1.7635167770535531e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.7635167770535531e-09 1.7635167770535531e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 38\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 38\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 35\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 33\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.309\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.5\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.79e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.32e+02 8.73e+01 -1.0 3.79e+02 - 4.33e-03 3.87e-01f 1\n", + " 2 0.0000000e+00 2.27e+02 8.51e+01 -1.0 2.32e+02 - 8.32e-02 2.51e-02h 1\n", + " 3 0.0000000e+00 2.26e+02 6.87e+03 -1.0 2.27e+02 - 1.38e-01 3.13e-04h 1\n", + " 4r 0.0000000e+00 2.26e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 3.92e-07R 4\n", + " 5r 0.0000000e+00 2.18e+02 5.24e+03 2.4 6.72e+03 - 1.53e-03 8.08e-03f 1\n", + " 6r 0.0000000e+00 2.11e+02 6.39e+03 1.7 1.35e+03 - 5.23e-02 5.22e-03f 1\n", + " 7r 0.0000000e+00 1.63e+02 7.61e+03 1.7 2.61e+03 - 4.63e-02 1.85e-02f 1\n", + " 8r 0.0000000e+00 1.52e+02 8.34e+03 1.7 2.11e+03 - 1.43e-01 5.53e-03f 1\n", + " 9r 0.0000000e+00 8.62e+01 6.88e+03 1.7 1.35e+03 - 2.57e-01 5.01e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 4.41e+01 7.80e+03 1.7 4.99e+02 - 3.92e-01 8.96e-02f 1\n", + " 11r 0.0000000e+00 1.76e+01 6.21e+03 1.7 1.36e+02 - 1.98e-01 2.04e-01f 1\n", + " 12r 0.0000000e+00 7.94e+00 6.72e+03 1.7 5.67e+01 - 7.95e-01 1.70e-01f 1\n", + " 13r 0.0000000e+00 2.01e+00 4.62e+03 1.7 1.94e+01 - 1.00e+00 4.08e-01f 1\n", + " 14r 0.0000000e+00 1.95e+00 5.95e+02 1.7 3.44e+00 - 9.75e-01 8.56e-01f 1\n", + " 15r 0.0000000e+00 2.34e+00 1.49e+02 0.3 9.78e+00 - 8.14e-01 7.50e-01f 1\n", + " 16r 0.0000000e+00 2.29e+00 1.06e+03 0.3 2.00e+00 - 3.58e-01 6.35e-01f 1\n", + " 17r 0.0000000e+00 2.20e+00 4.59e+02 0.3 2.88e+00 - 8.54e-01 6.97e-01f 1\n", + " 18r 0.0000000e+00 2.04e+00 3.75e+02 0.3 3.28e+00 - 8.25e-01 1.00e+00f 1\n", + " 19r 0.0000000e+00 2.03e+00 4.69e-03 0.3 2.66e-01 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.19e+00 1.23e+02 -1.8 4.02e+00 - 9.06e-01 7.70e-01f 1\n", + " 21r 0.0000000e+00 9.38e-01 2.90e+03 -1.8 9.16e+01 - 4.10e-02 2.74e-01f 1\n", + " 22r 0.0000000e+00 2.46e-02 1.94e+03 -1.8 1.08e+02 - 2.21e-01 1.72e-01f 1\n", + " 23r 0.0000000e+00 2.47e-02 2.02e+03 -1.8 1.09e+02 - 2.16e-01 1.72e-03f 1\n", + " 24r 0.0000000e+00 2.45e-02 3.75e+03 -1.8 2.59e+01 - 7.11e-01 4.29e-03f 1\n", + " 25r 0.0000000e+00 1.61e-02 3.51e+03 -1.8 1.76e+01 - 1.00e+00 1.16e-01f 1\n", + " 26r 0.0000000e+00 1.08e-02 3.50e+03 -1.8 1.47e+01 - 1.00e+00 8.73e-02f 1\n", + " 27r 0.0000000e+00 2.06e-03 2.80e+03 -1.8 1.05e+01 - 1.00e+00 2.47e-01f 1\n", + " 28r 0.0000000e+00 1.24e-03 1.74e+03 -1.8 8.12e-01 - 1.00e+00 3.99e-01f 1\n", + " 29r 0.0000000e+00 5.90e-05 5.81e+01 -1.8 2.34e-01 - 1.00e+00 9.68e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 3.22e-05 1.22e-04 -1.8 7.57e-03 - 1.00e+00 1.00e+00f 1\n", + " 31r 0.0000000e+00 8.59e-06 4.05e+02 -4.1 9.74e-03 - 1.00e+00 7.37e-01f 1\n", + " 32r 0.0000000e+00 2.82e-06 1.88e+03 -4.1 7.91e-03 - 9.72e-01 3.73e-01f 1\n", + " 33r 0.0000000e+00 6.13e-07 5.39e+02 -4.1 3.14e-04 - 1.00e+00 8.82e-01f 1\n", + " 34r 0.0000000e+00 7.85e-09 2.16e-06 -4.1 5.11e-05 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 6.6954687905074195e-09 7.8509231044920165e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 6.6954687905074195e-09 7.8509231044920165e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 36\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.295\n", + "Total CPU secs in NLP function evaluations = 0.035\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.76e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.67e+02 3.55e+01 -1.0 3.76e+02 - 7.84e-03 2.89e-01f 1\n", + " 2 0.0000000e+00 2.58e+02 3.43e+01 -1.0 2.67e+02 - 1.36e-01 3.43e-02h 1\n", + " 3 0.0000000e+00 2.58e+02 1.25e+04 -1.0 2.58e+02 - 2.56e-01 4.71e-04h 1\n", + " 4r 0.0000000e+00 2.58e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 2.96e-07R 5\n", + " 5r 0.0000000e+00 2.45e+02 7.55e+03 2.4 1.31e+04 - 1.36e-03 1.03e-02f 1\n", + " 6r 0.0000000e+00 2.41e+02 8.88e+03 1.7 1.32e+03 - 7.60e-02 2.33e-03f 1\n", + " 7r 0.0000000e+00 1.91e+02 1.08e+04 1.7 2.50e+03 - 8.74e-02 2.02e-02f 1\n", + " 8r 0.0000000e+00 1.66e+02 1.34e+04 1.7 1.82e+03 - 3.14e-01 1.41e-02f 1\n", + " 9r 0.0000000e+00 6.77e+01 1.15e+04 1.7 9.90e+02 - 1.96e-01 9.89e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 4.22e+01 8.73e+03 1.7 4.00e+02 - 6.92e-01 7.58e-02f 1\n", + " 11r 0.0000000e+00 1.28e+01 7.30e+03 1.7 9.32e+01 - 1.00e+00 3.35e-01f 1\n", + " 12r 0.0000000e+00 3.55e+00 4.88e+03 1.7 2.64e+01 - 1.00e+00 3.50e-01f 1\n", + " 13r 0.0000000e+00 1.69e+00 2.88e+03 1.7 7.90e+00 - 1.00e+00 4.53e-01f 1\n", + " 14r 0.0000000e+00 6.03e-01 8.23e+02 1.0 2.33e+00 - 4.43e-01 8.26e-01f 1\n", + " 15r 0.0000000e+00 5.44e-01 6.26e+00 1.0 1.57e+00 - 1.00e+00 9.98e-01f 1\n", + " 16r 0.0000000e+00 7.15e-01 2.12e+02 -1.1 3.16e+00 - 5.99e-01 4.65e-01f 1\n", + " 17r 0.0000000e+00 7.08e-01 4.60e+02 -1.1 7.26e+00 - 7.72e-02 3.24e-01f 1\n", + " 18r 0.0000000e+00 5.24e-01 1.33e+03 -1.1 7.74e+00 - 1.41e-02 2.59e-01f 1\n", + " 19r 0.0000000e+00 2.34e-01 1.24e+03 -1.1 7.27e+00 - 2.80e-01 3.71e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 9.07e-03 1.06e+03 -1.1 9.86e+00 - 5.50e-01 2.08e-01f 1\n", + " 21r 0.0000000e+00 7.28e-03 1.75e+03 -1.1 1.31e+01 - 3.75e-01 2.95e-03f 1\n", + " 22r 0.0000000e+00 6.06e-03 2.39e+03 -1.1 4.91e+00 - 1.00e+00 1.03e-01f 1\n", + " 23r 0.0000000e+00 2.62e-03 1.50e+03 -1.1 4.00e+00 - 1.00e+00 4.71e-01f 1\n", + " 24r 0.0000000e+00 1.40e-03 3.97e+02 -1.1 1.08e+00 - 1.00e+00 7.99e-01f 1\n", + " 25r 0.0000000e+00 5.02e-04 1.55e-03 -1.1 1.68e-01 - 1.00e+00 1.00e+00f 1\n", + " 26r 0.0000000e+00 2.02e-04 1.03e+03 -4.0 1.53e-01 - 1.00e+00 6.42e-01f 1\n", + " 27r 0.0000000e+00 4.23e-05 3.32e+03 -4.0 3.68e-01 - 9.45e-01 1.64e-01f 1\n", + " 28r 0.0000000e+00 6.59e-06 8.73e+02 -4.0 6.96e-03 - 9.73e-01 7.76e-01f 1\n", + " 29r 0.0000000e+00 2.70e-06 1.28e+03 -4.0 1.13e-03 - 9.39e-01 6.61e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 6.39e-07 2.14e+02 -4.0 3.79e-04 - 8.88e-01 9.54e-01f 1\n", + " 31r 0.0000000e+00 5.66e-09 3.83e-07 -4.0 1.73e-05 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 31\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.6641896728493180e-09 5.6641896728493180e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.6641896728493180e-09 5.6641896728493180e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 37\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 37\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 33\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 31\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.299\n", + "Total CPU secs in NLP function evaluations = 0.020\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.4\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.12e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.42e+02 7.75e+01 -1.0 3.12e+02 - 6.86e-03 5.47e-01f 1\n", + " 2 0.0000000e+00 1.36e+02 7.44e+01 -1.0 1.42e+02 - 1.36e-01 4.13e-02h 1\n", + " 3 0.0000000e+00 1.36e+02 1.08e+04 -1.0 1.36e+02 - 2.46e-01 5.18e-04h 1\n", + " 4r 0.0000000e+00 1.36e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 3.25e-07R 5\n", + " 5r 0.0000000e+00 9.30e+01 4.20e+03 2.1 1.83e+04 - 1.01e-02 4.22e-03f 1\n", + " 6r 0.0000000e+00 8.60e+01 6.51e+03 1.4 1.12e+04 - 1.11e-02 5.18e-03f 1\n", + " 7r 0.0000000e+00 6.37e+01 2.08e+04 1.4 2.99e+03 - 3.09e-02 8.06e-03f 1\n", + " 8r 0.0000000e+00 6.32e+01 2.86e+04 1.4 2.43e+03 - 7.46e-02 2.34e-04f 1\n", + " 9r 0.0000000e+00 8.20e+00 2.07e+04 1.4 1.52e+03 - 3.82e-01 4.12e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 4.76e+00 1.27e+04 1.4 2.31e+01 - 3.36e-01 1.49e-01f 1\n", + " 11r 0.0000000e+00 9.35e-01 4.92e+03 1.4 1.05e+01 - 1.00e+00 4.51e-01f 1\n", + " 12r 0.0000000e+00 4.23e-01 6.26e+03 1.4 3.59e+00 - 6.30e-01 8.74e-01f 1\n", + " 13r 0.0000000e+00 4.02e-01 2.59e+00 1.4 5.34e-01 - 1.00e+00 1.00e+00f 1\n", + " 14r 0.0000000e+00 9.60e-01 2.09e+02 -0.7 5.84e+00 - 3.71e-01 7.86e-01f 1\n", + " 15r 0.0000000e+00 6.90e-01 1.17e+02 -0.7 5.80e+00 - 5.49e-01 5.65e-01f 1\n", + " 16r 0.0000000e+00 1.01e-01 1.58e+02 -0.7 1.02e+01 - 5.69e-01 5.29e-01f 1\n", + " 17r 0.0000000e+00 1.53e-02 1.59e+03 -0.7 1.68e+01 - 4.32e-01 5.29e-02f 1\n", + " 18r 0.0000000e+00 1.52e-02 2.33e+03 -0.7 2.54e+00 - 1.00e+00 2.41e-02f 1\n", + " 19r 0.0000000e+00 1.15e-02 1.53e+02 -0.7 2.10e+00 - 1.00e+00 9.43e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 1.14e-02 1.06e-03 -0.7 1.03e-01 - 1.00e+00 1.00e+00f 1\n", + " 21r 0.0000000e+00 1.13e-02 2.33e+02 -3.1 3.47e-01 - 1.00e+00 8.62e-01f 1\n", + " 22r 0.0000000e+00 3.48e-04 7.69e+02 -3.1 1.30e+02 - 9.77e-01 2.08e-02f 1\n", + " 23r 0.0000000e+00 3.41e-04 8.97e+02 -3.1 1.87e+00 - 1.00e+00 2.00e-02f 1\n", + " 24r 0.0000000e+00 2.53e-06 6.41e+00 -3.1 1.20e-01 - 1.00e+00 9.93e-01f 1\n", + " 25r 0.0000000e+00 1.31e-07 8.18e-09 -3.1 8.77e-04 - 1.00e+00 1.00e+00f 1\n", + " 26r 0.0000000e+00 9.78e-10 3.71e-01 -7.0 5.48e-05 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.1057295037444419e-10 9.7818515353703672e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.1057295037444419e-10 9.7818515353703672e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 32\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 32\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 28\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.258\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.5\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.85e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.56e+02 9.16e+01 -1.0 3.85e+02 - 3.57e-03 3.35e-01f 1\n", + " 2 0.0000000e+00 2.51e+02 8.99e+01 -1.0 2.56e+02 - 7.05e-02 1.89e-02h 1\n", + " 3 0.0000000e+00 2.51e+02 6.86e+03 -1.0 2.51e+02 - 1.12e-01 2.27e-04h 1\n", + " 4r 0.0000000e+00 2.51e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 2.84e-07R 4\n", + " 5r 0.0000000e+00 2.35e+02 2.10e+03 2.4 1.31e+04 - 8.56e-03 1.49e-02f 1\n", + " 6r 0.0000000e+00 2.33e+02 3.45e+03 1.0 1.24e+03 - 5.51e-02 2.07e-03f 1\n", + " 7r 0.0000000e+00 1.83e+02 5.32e+03 1.0 5.02e+03 - 2.27e-02 1.09e-02f 1\n", + " 8r 0.0000000e+00 1.70e+02 7.52e+03 1.0 3.56e+03 - 5.25e-02 4.04e-03f 1\n", + " 9r 0.0000000e+00 1.27e+02 1.02e+04 1.0 2.46e+03 - 1.06e-01 1.87e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 6.56e+01 2.01e+04 1.0 1.12e+03 - 3.63e-01 5.60e-02f 1\n", + " 11r 0.0000000e+00 3.55e+01 2.18e+04 1.0 2.21e+02 - 3.03e-01 1.42e-01f 1\n", + " 12r 0.0000000e+00 1.70e+01 2.29e+04 1.0 8.53e+01 - 5.79e-01 2.17e-01f 1\n", + " 13r 0.0000000e+00 1.39e+01 2.07e+04 1.0 3.36e+01 - 4.90e-02 9.28e-02f 1\n", + " 14r 0.0000000e+00 1.09e+01 1.86e+04 1.0 2.91e+01 - 2.30e-01 1.02e-01f 1\n", + " 15r 0.0000000e+00 3.48e+00 1.19e+04 1.0 2.33e+01 - 7.44e-01 3.19e-01f 1\n", + " 16r 0.0000000e+00 2.42e+00 8.14e+03 1.0 8.84e+00 - 2.88e-01 3.68e-01f 1\n", + " 17r 0.0000000e+00 2.45e+00 6.21e+03 1.0 1.85e+00 - 2.52e-01 2.81e-01f 1\n", + " 18r 0.0000000e+00 2.48e+00 4.36e+03 1.0 1.26e+00 - 2.84e-01 2.74e-01f 1\n", + " 19r 0.0000000e+00 2.51e+00 3.06e+03 1.0 6.66e-01 - 2.68e-01 2.60e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.53e+00 3.28e+03 1.0 7.04e-01 - 3.07e-01 3.65e-01f 1\n", + " 21r 0.0000000e+00 2.55e+00 2.35e+03 1.0 6.09e-01 - 3.82e-01 3.99e-01f 1\n", + " 22r 0.0000000e+00 2.57e+00 3.23e+03 1.0 4.76e-01 - 6.82e-01 1.00e+00f 1\n", + " 23r 0.0000000e+00 2.57e+00 1.41e-01 1.0 1.60e-01 - 1.00e+00 1.00e+00f 1\n", + " 24r 0.0000000e+00 2.87e+00 1.18e+02 -1.1 5.95e+00 - 8.69e-01 7.73e-01f 1\n", + " 25r 0.0000000e+00 2.84e+00 1.05e+03 -1.1 6.87e+00 - 4.86e-02 4.92e-01f 1\n", + " 26r 0.0000000e+00 2.47e+00 2.21e+03 -1.1 1.78e+01 - 3.48e-02 3.34e-01f 1\n", + " 27r 0.0000000e+00 2.00e+00 7.63e+02 -1.1 1.99e+01 - 5.19e-01 3.89e-01f 1\n", + " 28r 0.0000000e+00 7.56e-01 1.03e+03 -1.1 4.01e+01 - 3.41e-01 5.09e-01f 1\n", + " 29r 0.0000000e+00 1.13e-02 2.08e+03 -1.1 2.16e+01 - 1.78e-01 5.64e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 5.30e-03 1.16e+03 -1.1 9.51e+00 - 3.26e-01 1.34e-02f 1\n", + " 31r 0.0000000e+00 5.52e-03 1.97e+03 -1.1 1.86e+00 - 1.00e+00 3.77e-02f 1\n", + " 32r 0.0000000e+00 1.14e-02 1.04e+02 -1.1 1.87e+00 - 7.66e-01 1.00e+00f 1\n", + " 33r 0.0000000e+00 1.15e-02 1.58e-05 -1.1 1.75e-01 - 1.00e+00 1.00e+00f 1\n", + " 34r 0.0000000e+00 1.15e-02 3.84e+02 -4.0 3.45e-01 - 9.63e-01 7.35e-01f 1\n", + " 35r 0.0000000e+00 1.39e-03 3.05e+03 -4.0 4.05e+02 - 9.71e-01 6.73e-03f 1\n", + " 36r 0.0000000e+00 1.39e-03 3.64e+03 -4.0 2.50e+02 - 1.00e+00 2.55e-04f 1\n", + " 37r 0.0000000e+00 7.73e-04 2.45e+03 -4.0 4.49e-01 - 1.00e+00 3.79e-01f 1\n", + " 38r 0.0000000e+00 1.11e-04 3.84e+02 -4.0 1.97e-01 - 1.00e+00 8.57e-01f 1\n", + " 39r 0.0000000e+00 3.89e-05 1.28e+03 -4.0 2.82e-02 - 1.00e+00 6.49e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40r 0.0000000e+00 5.46e-06 8.75e+02 -4.0 9.91e-03 - 1.00e+00 8.60e-01f 1\n", + " 41r 0.0000000e+00 7.94e-09 8.92e-07 -4.0 1.39e-03 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 41\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.5392754261827122e-09 7.9367750923575655e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.5392754261827122e-09 7.9367750923575655e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 46\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 46\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 43\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 41\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.370\n", + "Total CPU secs in NLP function evaluations = 0.031\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.4\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.63e+02 4.22e+01 -1.0 3.92e+02 - 7.52e-03 3.28e-01f 1\n", + " 2 0.0000000e+00 2.56e+02 4.09e+01 -1.0 2.63e+02 - 1.51e-01 2.93e-02h 1\n", + " 3 0.0000000e+00 2.56e+02 1.88e+04 -1.0 2.56e+02 - 2.78e-01 3.64e-04h 1\n", + " 4r 0.0000000e+00 2.56e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.56e-07R 4\n", + " 5r 0.0000000e+00 2.11e+02 9.30e+03 2.4 1.35e+03 - 5.28e-03 3.32e-02f 1\n", + " 6r 0.0000000e+00 1.91e+02 8.43e+03 1.7 1.19e+03 - 4.36e-02 1.76e-02f 1\n", + " 7r 0.0000000e+00 1.47e+02 6.95e+03 1.7 2.30e+03 - 4.86e-02 2.14e-02f 1\n", + " 8r 0.0000000e+00 1.17e+02 9.39e+03 1.7 1.63e+03 - 2.42e-01 1.83e-02f 1\n", + " 9r 0.0000000e+00 6.91e+01 1.17e+04 1.7 9.11e+02 - 3.84e-01 5.68e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 3.46e+01 1.09e+04 1.7 2.42e+02 - 1.00e+00 1.53e-01f 1\n", + " 11r 0.0000000e+00 2.02e+01 7.14e+03 1.7 4.19e+01 - 6.28e-01 3.44e-01f 1\n", + " 12r 0.0000000e+00 3.51e-01 1.44e+03 1.7 2.48e+01 - 1.00e+00 8.12e-01f 1\n", + " 13r 0.0000000e+00 4.10e-01 1.23e+03 1.0 4.59e+00 - 6.08e-01 1.61e-01f 1\n", + " 14r 0.0000000e+00 4.75e-01 1.49e+02 1.0 2.07e+00 - 1.00e+00 8.77e-01f 1\n", + " 15r 0.0000000e+00 5.52e-01 6.94e+02 0.3 3.21e+00 - 8.25e-01 3.97e-01f 1\n", + " 16r 0.0000000e+00 5.50e-01 3.86e+02 0.3 2.58e+00 - 1.00e+00 7.86e-01f 1\n", + " 17r 0.0000000e+00 5.27e-01 1.24e-01 0.3 7.99e-01 - 1.00e+00 1.00e+00f 1\n", + " 18r 0.0000000e+00 5.52e-01 7.33e+02 -1.8 1.28e+00 - 8.78e-01 3.61e-01f 1\n", + " 19r 0.0000000e+00 5.52e-01 7.69e+02 -1.8 1.91e+01 - 3.11e-01 1.63e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 5.43e-01 5.05e+02 -1.8 3.60e+00 - 4.54e-03 1.68e-01f 1\n", + " 21r 0.0000000e+00 2.60e-01 6.69e+02 -1.8 6.84e+01 - 4.13e-03 1.48e-01f 1\n", + " 22r 0.0000000e+00 2.55e-01 3.52e+02 -1.8 6.82e+01 - 7.60e-02 1.55e-03f 1\n", + " 23r 0.0000000e+00 2.37e-01 5.27e+02 -1.8 7.29e+01 - 8.64e-02 4.59e-03f 1\n", + " 24r 0.0000000e+00 2.03e-01 1.07e+03 -1.8 7.70e+01 - 1.27e-01 8.57e-03f 1\n", + " 25r 0.0000000e+00 1.31e-01 2.01e+03 -1.8 8.06e+01 - 2.26e-01 1.70e-02f 1\n", + " 26r 0.0000000e+00 2.55e-02 2.65e+03 -1.8 7.48e+01 - 3.10e-01 2.71e-02f 1\n", + " 27r 0.0000000e+00 3.51e-03 3.18e+03 -1.8 9.82e+00 - 9.46e-01 4.99e-02f 1\n", + " 28r 0.0000000e+00 2.39e-04 4.89e+02 -1.8 3.27e-01 - 1.00e+00 8.56e-01f 1\n", + " 29r 0.0000000e+00 5.43e-05 8.27e+02 -1.8 4.57e-02 - 1.00e+00 7.04e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 1.52e-05 6.90e-04 -1.8 1.36e-02 - 1.00e+00 1.00e+00f 1\n", + " 31r 0.0000000e+00 8.56e-06 1.25e+03 -4.0 3.76e-03 - 1.00e+00 7.07e-01f 1\n", + " 32r 0.0000000e+00 2.49e-06 9.69e+02 -4.0 2.26e-03 - 8.51e-01 7.40e-01f 1\n", + " 33r 0.0000000e+00 5.33e-08 6.71e-06 -4.0 5.23e-04 - 1.00e+00 1.00e+00f 1\n", + " 34r 0.0000000e+00 5.37e-10 1.01e-01 -6.0 2.49e-05 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.4637958782706658e-10 5.3720153514778086e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.4637958782706658e-10 5.3720153514778086e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 36\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.319\n", + "Total CPU secs in NLP function evaluations = 0.007\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.51e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.10e+02 4.62e+01 -1.0 3.51e+02 - 8.40e-03 4.00e-01f 1\n", + " 2 0.0000000e+00 2.04e+02 4.48e+01 -1.0 2.10e+02 - 2.17e-01 2.95e-02h 1\n", + " 3 0.0000000e+00 2.04e+02 3.94e+04 -1.0 2.04e+02 - 4.22e-01 3.55e-04h 1\n", + " 4r 0.0000000e+00 2.04e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 4.44e-07R 4\n", + " 5r 0.0000000e+00 1.81e+02 3.64e+03 2.3 1.78e+04 - 3.08e-03 1.14e-02f 1\n", + " 6r 0.0000000e+00 1.79e+02 5.13e+03 1.6 1.42e+03 - 8.45e-02 1.49e-03f 1\n", + " 7r 0.0000000e+00 1.19e+02 1.08e+04 1.6 2.58e+03 - 7.51e-02 2.40e-02f 1\n", + " 8r 0.0000000e+00 6.76e+01 6.25e+03 1.6 1.81e+03 - 1.70e-01 2.92e-02f 1\n", + " 9r 0.0000000e+00 1.88e+01 6.76e+03 1.6 8.62e+02 - 3.07e-01 5.65e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 5.08e+00 6.06e+03 1.6 1.67e+02 - 2.49e-01 1.12e-01f 1\n", + " 11r 0.0000000e+00 3.81e+00 4.70e+03 1.6 1.06e+01 - 3.13e-01 2.13e-01f 1\n", + " 12r 0.0000000e+00 2.12e+00 1.83e+03 1.6 6.54e+00 - 7.68e-01 4.05e-01f 1\n", + " 13r 0.0000000e+00 1.94e+00 1.61e+03 0.9 2.15e+00 - 6.59e-01 8.52e-02f 1\n", + " 14r 0.0000000e+00 2.67e-01 2.64e+02 0.9 2.93e+00 - 1.00e+00 8.54e-01f 1\n", + " 15r 0.0000000e+00 1.91e-01 8.59e+02 0.2 8.87e-01 - 8.22e-01 2.83e-01f 1\n", + " 16r 0.0000000e+00 6.01e-02 8.76e+02 0.2 2.97e+00 - 1.00e+00 6.84e-01f 1\n", + " 17r 0.0000000e+00 2.69e-02 2.67e+00 0.2 1.04e+00 - 1.00e+00 1.00e+00f 1\n", + " 18r 0.0000000e+00 3.87e-02 1.69e+02 -1.9 6.90e-01 - 4.97e-01 4.22e-01f 1\n", + " 19r 0.0000000e+00 3.87e-02 3.21e+02 -1.9 1.56e+01 - 2.54e-01 1.72e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.81e-02 3.53e+02 -1.9 3.29e+00 - 3.47e-03 2.20e-01f 1\n", + " 21r 0.0000000e+00 1.46e-02 3.77e+02 -1.9 4.69e+01 - 5.08e-03 8.11e-03f 1\n", + " 22r 0.0000000e+00 1.26e-02 3.42e+02 -1.9 3.88e+01 - 1.21e-02 1.00e-03f 1\n", + " 23r 0.0000000e+00 3.16e-03 2.94e+02 -1.9 2.90e+01 - 2.40e-02 6.20e-03f 1\n", + " 24r 0.0000000e+00 1.80e-03 2.20e+03 -1.9 4.26e+00 - 8.01e-01 1.54e-02f 1\n", + " 25r 0.0000000e+00 2.09e-04 6.36e+02 -1.9 5.92e-01 - 1.00e+00 7.90e-01f 1\n", + " 26r 0.0000000e+00 4.97e-05 7.73e+02 -1.9 4.07e-02 - 1.00e+00 7.06e-01f 1\n", + " 27r 0.0000000e+00 1.73e-05 2.67e+01 -1.9 1.17e-02 - 1.00e+00 9.81e-01f 1\n", + " 28r 0.0000000e+00 4.43e-06 1.78e-04 -1.9 2.17e-04 - 1.00e+00 1.00e+00f 1\n", + " 29r 0.0000000e+00 2.35e-06 5.22e+01 -4.2 1.68e-03 - 1.00e+00 9.10e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 2.92e-07 1.85e+01 -4.2 3.04e-04 - 1.00e+00 8.79e-01f 1\n", + " 31r 0.0000000e+00 1.26e-09 7.00e-08 -4.2 1.09e-04 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 31\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.2612473843098826e-09 1.2612473843098826e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.2612473843098826e-09 1.2612473843098826e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 36\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 36\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 33\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 31\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.271\n", + "Total CPU secs in NLP function evaluations = 0.023\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.83e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 6.16e+01 3.98e+01 -1.0 1.83e+02 - 1.60e-02 6.64e-01f 1\n", + " 2 0.0000000e+00 5.16e+01 3.35e+01 -1.0 6.16e+01 - 3.45e-01 1.63e-01h 1\n", + " 3 0.0000000e+00 5.14e+01 1.26e+04 -1.0 5.16e+01 - 7.21e-01 4.84e-03h 1\n", + " 4 0.0000000e+00 5.14e+01 2.29e+08 -1.0 5.14e+01 - 9.11e-01 5.02e-05h 1\n", + " 5r 0.0000000e+00 5.14e+01 1.00e+03 1.7 0.00e+00 - 0.00e+00 2.52e-07R 2\n", + " 6r 0.0000000e+00 4.50e+01 1.23e+04 1.7 1.84e+04 - 2.52e-02 2.32e-03f 1\n", + " 7r 0.0000000e+00 3.54e+01 4.07e+04 1.7 2.49e+03 - 6.96e-02 3.85e-03f 1\n", + " 8r 0.0000000e+00 5.85e+00 4.93e+04 1.7 1.43e+03 - 8.64e-02 2.45e-02f 1\n", + " 9r 0.0000000e+00 3.35e+00 1.48e+04 1.7 5.73e+01 - 7.58e-01 5.86e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 2.86e+00 1.09e+04 1.7 4.88e+00 - 1.57e-01 1.13e-01f 1\n", + " 11r 0.0000000e+00 2.68e-01 2.71e+04 1.7 4.02e+00 - 1.46e-01 8.12e-01f 1\n", + " 12r 0.0000000e+00 1.04e+00 2.76e+03 1.7 4.27e+00 - 8.58e-01 1.00e+00f 1\n", + " 13r 0.0000000e+00 2.25e-01 1.74e+02 1.0 4.50e+00 - 8.78e-01 9.22e-01f 1\n", + " 14r 0.0000000e+00 3.86e-02 9.86e+02 0.3 2.51e+00 - 1.00e+00 4.78e-01f 1\n", + " 15r 0.0000000e+00 2.63e-02 1.70e+03 0.3 1.78e+00 - 1.00e+00 4.16e-01f 1\n", + " 16r 0.0000000e+00 8.78e-03 1.77e+02 0.3 1.30e+00 - 1.00e+00 9.07e-01f 1\n", + " 17r 0.0000000e+00 8.83e-03 5.64e-04 0.3 3.49e-01 - 1.00e+00 1.00e+00f 1\n", + " 18r 0.0000000e+00 2.39e-03 2.14e+02 -1.8 1.08e+00 - 9.93e-01 7.08e-01f 1\n", + " 19r 0.0000000e+00 6.59e-04 3.82e+02 -1.8 2.55e+00 - 1.00e+00 3.14e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 1.07e-04 7.78e+01 -1.8 1.63e-01 - 1.00e+00 8.17e-01f 1\n", + " 21r 0.0000000e+00 2.42e-05 4.73e+01 -1.8 2.45e-02 - 1.00e+00 8.44e-01f 1\n", + " 22r 0.0000000e+00 2.70e-06 4.22e-07 -1.8 4.46e-03 - 1.00e+00 1.00e+00f 1\n", + " 23r 0.0000000e+00 1.78e-06 3.08e+00 -4.0 1.12e-03 - 1.00e+00 9.46e-01f 1\n", + " 24r 0.0000000e+00 1.34e-07 4.68e-07 -4.0 4.21e-04 - 1.00e+00 1.00e+00f 1\n", + " 25r 0.0000000e+00 9.50e-11 2.65e-02 -6.0 5.53e-05 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 25\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.5036423175542950e-11 9.5036423175542950e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.5036423175542950e-11 9.5036423175542950e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 28\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 28\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 25\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.235\n", + "Total CPU secs in NLP function evaluations = 0.015\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.5\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.85e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.08e+02 1.71e+02 -1.0 3.85e+02 - 2.65e-03 4.60e-01f 1\n", + " 2 0.0000000e+00 2.04e+02 1.68e+02 -1.0 2.08e+02 - 7.77e-02 1.78e-02h 1\n", + " 3 0.0000000e+00 2.04e+02 8.66e+03 -1.0 2.04e+02 - 1.18e-01 2.03e-04h 1\n", + " 4r 0.0000000e+00 2.04e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 2.54e-07R 4\n", + " 5r 0.0000000e+00 1.94e+02 9.86e+02 2.3 1.29e+04 - 1.19e-02 1.28e-02f 1\n", + " 6r 0.0000000e+00 1.91e+02 1.69e+04 0.9 1.49e+03 - 5.89e-02 2.58e-03f 1\n", + " 7r 0.0000000e+00 1.47e+02 3.49e+04 0.9 4.77e+03 - 2.90e-02 9.30e-03f 1\n", + " 8r 0.0000000e+00 1.09e+02 3.82e+04 0.9 3.42e+03 - 5.74e-02 1.25e-02f 1\n", + " 9r 0.0000000e+00 1.03e+02 3.57e+04 0.9 1.67e+03 - 2.11e-01 3.92e-03f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 3.97e+01 3.04e+04 0.9 5.25e+02 - 1.76e-01 1.26e-01f 1\n", + " 11r 0.0000000e+00 2.44e+01 3.83e+04 0.9 1.50e+02 - 5.49e-01 1.02e-01f 1\n", + " 12r 0.0000000e+00 7.22e+00 3.16e+04 0.9 5.01e+01 - 7.21e-01 3.44e-01f 1\n", + " 13r 0.0000000e+00 2.66e+00 1.79e+04 0.9 1.69e+01 - 6.25e-01 4.25e-01f 1\n", + " 14r 0.0000000e+00 2.70e+00 1.27e+04 0.9 1.52e+00 - 3.28e-01 2.87e-01f 1\n", + " 15r 0.0000000e+00 2.72e+00 8.79e+03 0.9 1.07e+00 - 3.59e-01 2.85e-01f 1\n", + " 16r 0.0000000e+00 2.79e+00 6.00e+03 0.9 1.91e+00 - 3.34e-01 2.96e-01f 1\n", + " 17r 0.0000000e+00 2.81e+00 4.53e+03 0.9 1.14e+00 - 2.48e-01 2.63e-01f 1\n", + " 18r 0.0000000e+00 2.86e+00 2.90e+03 0.9 1.45e+00 - 3.42e-01 3.27e-01f 1\n", + " 19r 0.0000000e+00 2.88e+00 1.22e+03 0.9 7.48e-01 - 3.63e-01 3.24e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.92e+00 3.75e+03 0.9 6.52e-01 - 5.04e-01 5.89e-01f 1\n", + " 21r 0.0000000e+00 2.93e+00 4.25e+04 0.9 2.49e-01 - 4.20e-01 9.81e-01f 1\n", + " 22r 0.0000000e+00 2.93e+00 1.50e+03 0.9 5.14e-02 - 8.63e-01 1.00e+00f 1\n", + " 23r 0.0000000e+00 2.93e+00 7.38e-03 0.9 6.94e-03 - 1.00e+00 1.00e+00f 1\n", + " 24r 0.0000000e+00 3.29e+00 1.59e+02 -1.2 4.49e+00 - 8.54e-01 7.15e-01f 1\n", + " 25r 0.0000000e+00 2.68e+00 3.13e+02 -1.2 3.24e+01 - 1.92e-01 2.63e-01f 1\n", + " 26r 0.0000000e+00 1.50e+00 3.12e+02 -1.2 3.25e+01 - 3.28e-01 3.55e-01f 1\n", + " 27r 0.0000000e+00 1.07e-01 3.03e+02 -1.2 3.79e+01 - 3.23e-01 3.74e-01f 1\n", + " 28r 0.0000000e+00 1.07e-01 9.17e+02 -1.2 3.15e+01 - 2.55e-01 5.49e-03f 1\n", + " 29r 0.0000000e+00 1.07e-01 2.86e+03 -1.2 1.92e+01 - 7.85e-01 1.14e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 1.01e-01 2.05e+03 -1.2 5.56e+00 - 1.00e+00 3.41e-01f 1\n", + " 31r 0.0000000e+00 9.73e-02 1.58e+03 -1.2 3.30e+00 - 1.00e+00 3.01e-01f 1\n", + " 32r 0.0000000e+00 8.92e-02 4.60e+01 -1.2 2.31e+00 - 1.00e+00 9.73e-01f 1\n", + " 33r 0.0000000e+00 8.90e-02 8.87e-04 -1.2 1.20e-01 - 1.00e+00 1.00e+00f 1\n", + " 34r 0.0000000e+00 8.91e-02 3.61e+02 -4.2 1.72e-01 - 9.81e-01 7.79e-01f 1\n", + " 35r 0.0000000e+00 7.41e-02 1.37e+03 -4.2 6.60e+02 - 1.61e-01 5.45e-03f 1\n", + " 36r 0.0000000e+00 7.35e-02 6.49e+03 -4.2 6.55e+02 - 9.03e-01 2.46e-04f 1\n", + " 37r 0.0000000e+00 3.03e-04 6.68e+03 -4.2 5.94e+02 - 8.93e-01 2.98e-02f 1\n", + " 38r 0.0000000e+00 2.75e-04 6.08e+03 -4.2 2.39e-01 - 1.00e+00 8.74e-02f 1\n", + " 39r 0.0000000e+00 1.08e-08 2.67e-04 -4.2 8.74e-02 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40r 0.0000000e+00 8.78e-11 2.37e-01 -6.4 2.18e-06 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 40\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.3066333062577876e-11 8.7764854222018352e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.3066333062577876e-11 8.7764854222018352e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 45\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 45\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 42\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 40\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.307\n", + "Total CPU secs in NLP function evaluations = 0.049\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.36e+02 1.43e+02 -1.0 3.96e+02 - 2.78e-03 4.05e-01f 1\n", + " 2 0.0000000e+00 2.32e+02 1.41e+02 -1.0 2.36e+02 - 1.32e-01 1.71e-02h 1\n", + " 3 0.0000000e+00 2.32e+02 2.28e+04 -1.0 2.32e+02 - 1.88e-01 1.93e-04h 1\n", + " 4r 0.0000000e+00 2.32e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.83e-07R 3\n", + " 5r 0.0000000e+00 2.17e+02 9.85e+02 2.4 1.19e+04 - 1.06e-02 1.36e-02f 1\n", + " 6r 0.0000000e+00 2.14e+02 1.30e+04 1.0 1.27e+03 - 5.82e-02 2.44e-03f 1\n", + " 7r 0.0000000e+00 1.62e+02 2.34e+04 1.0 4.91e+03 - 2.38e-02 1.16e-02f 1\n", + " 8r 0.0000000e+00 1.57e+02 2.45e+04 1.0 3.32e+03 - 6.10e-02 1.67e-03f 1\n", + " 9r 0.0000000e+00 1.32e+02 2.26e+04 1.0 2.02e+03 - 1.26e-01 1.32e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 6.58e+01 2.03e+04 1.0 9.37e+02 - 1.95e-01 7.75e-02f 1\n", + " 11r 0.0000000e+00 4.25e+01 3.75e+04 1.0 2.34e+02 - 5.24e-01 9.91e-02f 1\n", + " 12r 0.0000000e+00 9.87e+00 1.92e+04 1.0 6.76e+01 - 4.88e-01 4.85e-01f 1\n", + " 13r 0.0000000e+00 8.03e+00 1.63e+04 1.0 1.29e+01 - 1.21e-01 1.43e-01f 1\n", + " 14r 0.0000000e+00 6.78e+00 1.54e+04 1.0 1.03e+01 - 4.81e-01 1.22e-01f 1\n", + " 15r 0.0000000e+00 2.80e+00 7.26e+03 1.0 8.05e+00 - 6.67e-01 4.96e-01f 1\n", + " 16r 0.0000000e+00 2.51e+00 5.18e+03 1.0 3.44e+00 - 2.86e-01 2.98e-01f 1\n", + " 17r 0.0000000e+00 2.53e+00 3.39e+03 1.0 2.35e+00 - 2.85e-01 1.95e-01f 1\n", + " 18r 0.0000000e+00 2.56e+00 2.71e+03 1.0 1.86e+00 - 2.75e-01 3.16e-01f 1\n", + " 19r 0.0000000e+00 2.58e+00 2.08e+03 1.0 1.22e+00 - 2.65e-01 2.72e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.61e+00 2.39e+03 1.0 8.14e-01 - 3.60e-01 4.17e-01f 1\n", + " 21r 0.0000000e+00 2.62e+00 1.38e+03 1.0 3.95e-01 - 4.37e-01 3.67e-01f 1\n", + " 22r 0.0000000e+00 2.63e+00 9.07e+03 1.0 2.59e-01 - 7.30e-01 1.00e+00f 1\n", + " 23r 0.0000000e+00 2.63e+00 2.12e-01 1.0 7.58e-02 - 1.00e+00 1.00e+00f 1\n", + " 24r 0.0000000e+00 3.06e+00 6.51e+01 -1.1 8.23e+00 - 8.22e-01 7.61e-01f 1\n", + " 25r 0.0000000e+00 2.19e+00 1.34e+03 -1.1 2.73e+01 - 2.45e-01 4.74e-01f 1\n", + " 26r 0.0000000e+00 9.32e-01 7.84e+02 -1.1 4.34e+01 - 4.27e-01 4.32e-01f 1\n", + " 27r 0.0000000e+00 1.88e-02 5.84e+02 -1.1 5.35e+01 - 2.86e-01 2.55e-01f 1\n", + " 28r 0.0000000e+00 1.89e-02 2.49e+03 -1.1 3.90e+01 - 3.89e-01 3.63e-03f 1\n", + " 29r 0.0000000e+00 1.87e-02 5.16e+03 -1.1 2.92e+00 - 1.00e+00 3.09e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 1.28e-02 9.16e-03 -1.1 2.56e+00 - 1.00e+00 1.00e+00f 1\n", + " 31r 0.0000000e+00 1.27e-02 1.52e+02 -4.1 1.56e-01 - 9.63e-01 9.13e-01f 1\n", + " 32r 0.0000000e+00 5.45e-03 5.50e+02 -4.1 4.28e+02 - 1.00e+00 4.09e-03f 1\n", + " 33r 0.0000000e+00 3.87e-04 9.26e+02 -4.1 3.38e+01 - 1.00e+00 3.76e-02f 1\n", + " 34r 0.0000000e+00 1.37e-05 6.68e+01 -4.1 1.08e-01 - 1.00e+00 9.28e-01f 1\n", + " 35r 0.0000000e+00 5.96e-09 2.75e-07 -4.1 3.78e-03 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 35\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.9644783556578318e-09 5.9644783556578318e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.9644783556578318e-09 5.9644783556578318e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 37\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 35\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.282\n", + "Total CPU secs in NLP function evaluations = 0.018\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.91e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.24e+02 8.48e+01 -1.0 3.91e+02 - 4.93e-03 4.28e-01f 1\n", + " 2 0.0000000e+00 2.19e+02 8.30e+01 -1.0 2.24e+02 - 1.02e-01 2.13e-02h 1\n", + " 3 0.0000000e+00 2.19e+02 1.20e+04 -1.0 2.19e+02 - 1.62e-01 2.46e-04h 1\n", + " 4r 0.0000000e+00 2.19e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 3.08e-07R 4\n", + " 5r 0.0000000e+00 2.10e+02 9.91e+02 2.3 9.42e+03 - 6.94e-03 7.96e-03f 1\n", + " 6r 0.0000000e+00 2.03e+02 8.13e+03 0.9 1.28e+03 - 5.02e-02 5.28e-03f 1\n", + " 7r 0.0000000e+00 1.48e+02 1.44e+04 0.9 5.00e+03 - 2.26e-02 1.21e-02f 1\n", + " 8r 0.0000000e+00 1.39e+02 1.73e+04 0.9 3.27e+03 - 5.92e-02 2.98e-03f 1\n", + " 9r 0.0000000e+00 1.03e+02 1.60e+04 0.9 1.87e+03 - 1.25e-01 1.91e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 4.88e+01 2.24e+04 0.9 7.38e+02 - 4.01e-01 7.65e-02f 1\n", + " 11r 0.0000000e+00 1.43e+01 1.91e+04 0.9 1.24e+02 - 4.48e-01 2.85e-01f 1\n", + " 12r 0.0000000e+00 1.09e+01 2.06e+04 0.9 2.83e+01 - 5.27e-01 1.19e-01f 1\n", + " 13r 0.0000000e+00 1.73e+00 8.52e+03 0.9 1.86e+01 - 3.55e-01 5.53e-01f 1\n", + " 14r 0.0000000e+00 1.74e+00 6.65e+03 0.9 3.33e+00 - 6.71e-01 2.03e-01f 1\n", + " 15r 0.0000000e+00 1.77e+00 3.19e+03 0.9 6.45e-01 - 5.58e-01 5.19e-01f 1\n", + " 16r 0.0000000e+00 1.81e+00 1.87e+03 0.9 7.55e-01 - 4.69e-01 4.19e-01f 1\n", + " 17r 0.0000000e+00 1.84e+00 8.90e+02 0.9 6.66e-01 - 5.24e-01 5.24e-01f 1\n", + " 18r 0.0000000e+00 1.86e+00 7.28e+03 0.9 3.80e-01 - 6.38e-01 9.45e-01f 1\n", + " 19r 0.0000000e+00 1.86e+00 2.29e-01 0.9 1.35e-01 - 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.11e+00 1.47e+02 -1.2 7.42e+00 - 8.33e-01 6.69e-01f 1\n", + " 21r 0.0000000e+00 2.09e+00 8.04e+02 -1.2 9.84e+00 - 5.60e-02 5.23e-01f 1\n", + " 22r 0.0000000e+00 1.67e+00 2.28e+03 -1.2 2.04e+01 - 2.82e-02 4.16e-01f 1\n", + " 23r 0.0000000e+00 1.29e+00 1.28e+03 -1.2 2.24e+01 - 3.92e-01 3.52e-01f 1\n", + " 24r 0.0000000e+00 4.93e-01 1.35e+03 -1.2 3.49e+01 - 1.31e-01 4.69e-01f 1\n", + " 25r 0.0000000e+00 1.86e-02 1.21e+03 -1.2 2.81e+01 - 2.80e-01 3.53e-01f 1\n", + " 26r 0.0000000e+00 1.87e-02 7.43e+02 -1.2 2.09e+01 - 2.66e-01 5.16e-03f 1\n", + " 27r 0.0000000e+00 1.89e-02 1.38e+03 -1.2 5.45e+00 - 9.74e-01 2.34e-02f 1\n", + " 28r 0.0000000e+00 2.27e-02 6.45e-03 -1.2 8.25e-01 - 1.00e+00 1.00e+00f 1\n", + " 29r 0.0000000e+00 2.26e-02 9.20e+02 -4.2 1.72e-01 - 9.80e-01 7.59e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 1.75e-02 5.71e+03 -4.2 4.73e+02 - 8.52e-01 2.65e-03f 1\n", + " 31r 0.0000000e+00 1.72e-02 5.75e+03 -4.2 2.67e+02 - 9.30e-01 2.46e-04f 1\n", + " 32r 0.0000000e+00 4.12e-04 3.38e+03 -4.2 1.00e+01 - 1.00e+00 4.12e-01f 1\n", + " 33r 0.0000000e+00 5.00e-06 4.10e+01 -4.2 9.28e-02 - 1.00e+00 9.88e-01f 1\n", + " 34r 0.0000000e+00 5.72e-09 1.95e-08 -4.2 1.14e-03 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.7186637647532734e-09 5.7186637647532734e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.7186637647532734e-09 5.7186637647532734e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 36\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.280\n", + "Total CPU secs in NLP function evaluations = 0.016\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.2\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.20e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.98e+02 4.01e+01 -1.0 3.20e+02 - 9.18e-03 3.81e-01f 1\n", + " 2 0.0000000e+00 1.89e+02 3.82e+01 -1.0 1.98e+02 - 1.50e-01 4.65e-02h 1\n", + " 3 0.0000000e+00 1.89e+02 1.15e+04 -1.0 1.89e+02 - 2.92e-01 6.46e-04h 1\n", + " 4r 0.0000000e+00 1.89e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 4.05e-07R 5\n", + " 5r 0.0000000e+00 1.48e+02 9.55e+03 2.3 1.59e+03 - 3.15e-03 2.97e-02f 1\n", + " 6r 0.0000000e+00 1.35e+02 9.39e+03 1.6 1.41e+03 - 5.41e-02 8.85e-03f 1\n", + " 7r 0.0000000e+00 1.07e+02 9.99e+03 1.6 2.53e+03 - 6.98e-02 1.11e-02f 1\n", + " 8r 0.0000000e+00 5.51e+01 1.07e+04 1.6 1.83e+03 - 1.60e-01 2.86e-02f 1\n", + " 9r 0.0000000e+00 1.52e+01 1.04e+04 1.6 8.87e+02 - 3.72e-01 4.50e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 2.13e+00 9.47e+03 1.6 1.20e+02 - 5.89e-01 1.26e-01f 1\n", + " 11r 0.0000000e+00 1.13e+00 6.09e+03 1.6 5.27e+00 - 4.85e-01 3.78e-01f 1\n", + " 12r 0.0000000e+00 4.39e-01 3.50e+03 1.6 2.77e+00 - 9.96e-01 5.47e-01f 1\n", + " 13r 0.0000000e+00 1.67e-01 5.99e+01 1.6 7.56e-01 - 1.00e+00 1.00e+00f 1\n", + " 14r 0.0000000e+00 1.43e-01 6.08e+02 -0.5 2.07e+00 - 4.41e-01 2.19e-01f 1\n", + " 15r 0.0000000e+00 1.14e-01 9.82e+02 -0.5 5.71e+00 - 6.67e-01 2.18e-01f 1\n", + " 16r 0.0000000e+00 1.01e-01 1.95e+03 -0.5 6.61e+00 - 9.73e-01 1.02e-01f 1\n", + " 17r 0.0000000e+00 2.24e-02 6.60e+02 -0.5 4.47e+00 - 1.00e+00 7.58e-01f 1\n", + " 18r 0.0000000e+00 5.86e-03 6.65e+02 -0.5 2.81e+00 - 1.00e+00 7.35e-01f 1\n", + " 19r 0.0000000e+00 1.87e-03 5.67e+02 -0.5 8.99e-01 - 1.00e+00 8.08e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 9.39e-04 7.94e-03 -0.5 3.57e-01 - 1.00e+00 1.00e+00f 1\n", + " 21r 0.0000000e+00 3.11e-04 4.65e+02 -2.9 2.41e-01 - 1.00e+00 6.65e-01f 1\n", + " 22r 0.0000000e+00 7.23e-05 1.37e+03 -2.9 3.38e-01 - 9.96e-01 3.40e-01f 1\n", + " 23r 0.0000000e+00 1.78e-05 6.46e+02 -2.9 1.48e-02 - 1.00e+00 8.26e-01f 1\n", + " 24r 0.0000000e+00 2.87e-06 2.62e+02 -2.9 3.33e-03 - 9.07e-01 1.00e+00f 1\n", + " 25r 0.0000000e+00 1.20e-07 2.54e-06 -2.9 2.24e-04 - 1.00e+00 1.00e+00f 1\n", + " 26r 0.0000000e+00 2.61e-08 1.39e+00 -6.5 4.87e-05 - 1.00e+00 9.92e-01f 1\n", + " 27r 0.0000000e+00 9.46e-10 7.24e-01 -6.5 3.19e-06 - 1.00e+00 9.84e-01f 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.4556971974579795e-10 9.4556971974579795e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.4556971974579795e-10 9.4556971974579795e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 29\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.236\n", + "Total CPU secs in NLP function evaluations = 0.016\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.4\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.79e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.95e+02 1.42e+02 -1.0 3.79e+02 - 3.35e-03 4.85e-01f 1\n", + " 2 0.0000000e+00 1.90e+02 1.39e+02 -1.0 1.95e+02 - 6.27e-02 2.35e-02h 1\n", + " 3 0.0000000e+00 1.90e+02 4.85e+03 -1.0 1.90e+02 - 1.07e-01 2.78e-04h 1\n", + " 4r 0.0000000e+00 1.90e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 3.48e-07R 4\n", + " 5r 0.0000000e+00 1.83e+02 1.25e+03 2.3 1.20e+04 - 9.88e-03 9.54e-03f 1\n", + " 6r 0.0000000e+00 1.80e+02 1.08e+04 0.9 1.40e+03 - 5.06e-02 3.21e-03f 1\n", + " 7r 0.0000000e+00 1.29e+02 1.89e+04 0.9 5.14e+03 - 2.68e-02 1.17e-02f 1\n", + " 8r 0.0000000e+00 1.20e+02 1.97e+04 0.9 3.41e+03 - 6.44e-02 2.90e-03f 1\n", + " 9r 0.0000000e+00 7.81e+01 1.73e+04 0.9 1.72e+03 - 1.46e-01 2.61e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 4.04e+01 1.34e+04 0.9 5.31e+02 - 1.94e-01 7.10e-02f 1\n", + " 11r 0.0000000e+00 1.84e+01 2.35e+04 0.9 1.78e+02 - 4.56e-01 1.24e-01f 1\n", + " 12r 0.0000000e+00 2.31e+00 1.73e+04 0.9 5.28e+01 - 4.92e-01 3.46e-01f 1\n", + " 13r 0.0000000e+00 2.32e+00 1.46e+04 0.9 2.67e+00 - 2.76e-01 1.71e-01f 1\n", + " 14r 0.0000000e+00 2.38e+00 8.69e+03 0.9 2.34e+00 - 1.52e-01 4.16e-01f 1\n", + " 15r 0.0000000e+00 2.46e+00 5.56e+03 0.9 2.11e+00 - 3.20e-01 4.13e-01f 1\n", + " 16r 0.0000000e+00 2.49e+00 2.92e+03 0.9 7.46e-01 - 5.68e-01 6.55e-01f 1\n", + " 17r 0.0000000e+00 2.50e+00 6.54e+03 0.9 6.35e-01 - 6.89e-01 4.64e-01f 1\n", + " 18r 0.0000000e+00 2.50e+00 1.87e+03 0.9 4.61e-01 - 3.88e-01 4.89e-01f 1\n", + " 19r 0.0000000e+00 2.51e+00 4.78e+03 0.9 3.13e-01 - 5.43e-01 9.57e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 2.50e+00 1.46e-01 0.9 1.10e-01 - 1.00e+00 1.00e+00f 1\n", + " 21r 0.0000000e+00 2.82e+00 5.49e+01 -1.2 7.01e+00 - 8.58e-01 7.83e-01f 1\n", + " 22r 0.0000000e+00 2.11e+00 1.56e+03 -1.2 2.69e+01 - 1.33e-01 4.64e-01f 1\n", + " 23r 0.0000000e+00 1.24e+00 1.21e+03 -1.2 3.79e+01 - 3.54e-01 4.06e-01f 1\n", + " 24r 0.0000000e+00 2.10e-02 1.01e+03 -1.2 4.93e+01 - 2.92e-01 4.34e-01f 1\n", + " 25r 0.0000000e+00 2.13e-02 1.06e+03 -1.2 3.44e+01 - 3.13e-01 6.32e-03f 1\n", + " 26r 0.0000000e+00 2.12e-02 2.85e+03 -1.2 8.72e+00 - 9.89e-01 1.30e-02f 1\n", + " 27r 0.0000000e+00 1.80e-02 1.32e+03 -1.2 1.90e+00 - 1.00e+00 5.52e-01f 1\n", + " 28r 0.0000000e+00 1.54e-02 1.66e-03 -1.2 6.86e-01 - 1.00e+00 1.00e+00f 1\n", + " 29r 0.0000000e+00 1.52e-02 6.58e+02 -4.3 1.27e-01 - 9.97e-01 6.89e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30r 0.0000000e+00 4.21e-03 4.72e+03 -4.3 5.52e+02 - 9.32e-01 4.85e-03f 1\n", + " 31r 0.0000000e+00 2.80e-03 5.53e+03 -4.3 7.54e+01 - 9.19e-01 4.50e-03f 1\n", + " 32r 0.0000000e+00 4.43e-05 1.13e+03 -4.3 8.54e-01 - 1.00e+00 7.96e-01f 1\n", + " 33r 0.0000000e+00 1.04e-08 2.00e-05 -4.3 9.88e-03 - 1.00e+00 1.00e+00f 1\n", + " 34r 0.0000000e+00 6.20e-11 1.70e-01 -6.5 2.71e-06 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.3625672114701202e-11 6.1975749971474384e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.3625672114701202e-11 6.1975749971474384e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 36\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.303\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.91e+02 3.29e+01 -1.0 3.92e+02 - 7.53e-03 2.58e-01f 1\n", + " 2 0.0000000e+00 2.82e+02 3.20e+01 -1.0 2.91e+02 - 1.86e-01 2.98e-02h 1\n", + " 3 0.0000000e+00 2.82e+02 2.19e+04 -1.0 2.82e+02 - 2.86e-01 3.83e-04h 1\n", + " 4r 0.0000000e+00 2.82e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.80e-07R 4\n", + " 5r 0.0000000e+00 2.69e+02 2.38e+03 2.4 1.17e+04 - 4.31e-03 9.93e-03f 1\n", + " 6r 0.0000000e+00 2.64e+02 2.51e+03 1.1 1.25e+03 - 4.37e-02 3.56e-03f 1\n", + " 7r 0.0000000e+00 2.09e+02 3.67e+03 1.1 4.56e+03 - 2.42e-02 1.23e-02f 1\n", + " 8r 0.0000000e+00 2.03e+02 7.82e+03 1.1 3.40e+03 - 1.53e-01 1.74e-03f 1\n", + " 9r 0.0000000e+00 9.66e+01 7.79e+03 1.1 1.93e+03 - 7.98e-02 5.71e-02f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10r 0.0000000e+00 6.20e+01 8.90e+03 1.1 8.06e+02 - 1.95e-01 4.86e-02f 1\n", + " 11r 0.0000000e+00 3.84e+01 1.20e+04 1.1 2.44e+02 - 7.62e-01 9.71e-02f 1\n", + " 12r 0.0000000e+00 1.60e+01 6.06e+03 1.1 5.46e+01 - 1.00e+00 4.10e-01f 1\n", + " 13r 0.0000000e+00 5.82e-01 1.27e+03 1.1 2.06e+01 - 1.00e+00 7.70e-01f 1\n", + " 14r 0.0000000e+00 4.84e-01 3.32e+03 1.1 9.52e-01 - 1.00e+00 1.69e-01f 1\n", + " 15r 0.0000000e+00 9.97e-02 2.79e+01 1.1 1.14e+00 - 1.00e+00 1.00e+00f 1\n", + " 16r 0.0000000e+00 8.91e-02 4.40e+02 -1.0 1.27e+00 - 5.29e-01 3.11e-01f 1\n", + " 17r 0.0000000e+00 7.90e-02 4.60e+02 -1.0 8.04e+00 - 2.34e-01 8.48e-02f 1\n", + " 18r 0.0000000e+00 7.13e-02 1.09e+03 -1.0 6.71e+00 - 7.40e-01 7.36e-02f 1\n", + " 19r 0.0000000e+00 2.65e-02 6.12e+02 -1.0 5.05e+00 - 1.00e+00 5.80e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20r 0.0000000e+00 9.27e-03 5.14e+02 -1.0 3.33e+00 - 1.00e+00 7.03e-01f 1\n", + " 21r 0.0000000e+00 6.56e-04 5.07e+02 -1.0 1.64e+00 - 1.00e+00 7.90e-01f 1\n", + " 22r 0.0000000e+00 1.79e-04 7.46e+01 -1.0 2.19e-01 - 1.00e+00 9.76e-01f 1\n", + " 23r 0.0000000e+00 2.84e-04 8.65e+02 -1.0 5.80e-02 - 4.80e-01 1.00e+00f 1\n", + " 24r 0.0000000e+00 3.74e-04 9.40e-06 -1.0 2.16e-02 - 1.00e+00 1.00e+00f 1\n", + " 25r 0.0000000e+00 3.06e-05 5.52e+02 -3.9 6.97e-02 - 1.00e+00 7.26e-01f 1\n", + " 26r 0.0000000e+00 1.41e-05 2.27e+03 -3.9 2.89e-02 - 9.71e-01 4.66e-01f 1\n", + " 27r 0.0000000e+00 4.15e-06 1.11e+03 -3.9 1.25e-03 - 9.53e-01 8.10e-01f 1\n", + " 28r 0.0000000e+00 1.67e-07 1.22e+02 -3.9 7.64e-04 - 9.19e-01 1.00e+00f 1\n", + " 29r 0.0000000e+00 4.10e-09 2.54e-08 -3.9 3.49e-06 - 1.00e+00 1.00e+00f 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.0956430746863504e-09 4.0956430746863504e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.0956430746863504e-09 4.0956430746863504e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 31\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.216\n", + "Total CPU secs in NLP function evaluations = 0.049\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n" + ] + } + ], + "source": [ + "def new_doe_object2(Ca, T0, FIM_prior):\n", + " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", + " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", + " \n", + " measurements = MeasurementVariables()\n", + " measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", + " \n", + " exp_design = DesignVariables()\n", + " exp_design.add_variables(\n", + " \"CA0\",\n", + " time_index_position=0,\n", + " values=[Ca, ],\n", + " lower_bounds=1,\n", + " indices={0: [0]},\n", + " upper_bounds=5,\n", + " )\n", + " exp_design.add_variables(\n", + " \"T\",\n", + " indices={0: t_control},\n", + " time_index_position=0,\n", + " values=list(T0),\n", + " lower_bounds=300,\n", + " upper_bounds=700,\n", + " )\n", + "\n", + " # exp_design.update_values({\"CA0[0]\": Ca, \"T[0]\": T0[0], \"T[0.125]\": T0[1], \"T[0.25]\": T0[2], \"T[0.375]\": T0[3], \"T[0.5]\": T0[4], \"T[0.625]\": T0[5],\n", + " # \"T[0.75]\": T0[6], \"T[0.875]\": T0[7], \"T[1]\": T0[8]})\n", + " \n", + " doe_object = DesignOfExperiments(\n", + " parameter_dict,\n", + " exp_design, \n", + " measurements, \n", + " create_model,\n", + " # prior_FIM=FIM_prior,\n", + " discretize_model=disc_for_measure,\n", + " )\n", + "\n", + " result = doe_object.compute_FIM(\n", + " mode=\"sequential_finite\",\n", + " scale_nominal_param_value=True,\n", + " formula=\"central\",\n", + " )\n", + "\n", + " result.result_analysis()\n", + " \n", + " return result\n", + "\n", + "n_para = len(parameter_dict)\n", + "\n", + "\n", + "t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", + "parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", + " \n", + "measurements = MeasurementVariables()\n", + "measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", + " \n", + "exp_design = DesignVariables()\n", + "exp_design.add_variables(\n", + " \"CA0\",\n", + " indices={0: [0]},\n", + " time_index_position=0,\n", + " lower_bounds=1,\n", + " upper_bounds=5,\n", + " )\n", + "exp_design.add_variables(\n", + " \"T\",\n", + " indices={0: t_control},\n", + " time_index_position=0,\n", + " lower_bounds=300,\n", + " upper_bounds=700,\n", + " )\n", + "\n", + "exp_design.update_values({\"CA0[0]\": 5, \"T[0]\": 450, \"T[0.125]\": 300, \"T[0.25]\": 300, \"T[0.375]\": 300, \"T[0.5]\": 300, \"T[0.625]\": 300,\n", + " \"T[0.75]\": 300, \"T[0.875]\": 300, \"T[1]\": 300})\n", + " \n", + "doe_object = DesignOfExperiments(\n", + " parameter_dict,\n", + " exp_design, \n", + " measurements, \n", + " create_model,\n", + " discretize_model=disc_for_measure,\n", + " )\n", + "\n", + "result = doe_object.compute_FIM(\n", + " mode=\"sequential_finite\",\n", + " scale_nominal_param_value=True,\n", + " formula=\"central\",\n", + " )\n", + "\n", + "result.result_analysis()\n", + "\n", + "FIM_prior = result.FIM\n", + "FIM_new = np.zeros((n_para, n_para))\n", + "A_vals_rand = []\n", + "D_vals_rand = []\n", + "exp_conds_rand = []\n", + "FIM_rand = None\n", + "\n", + "for i in range(20):\n", + " FIM_prior += FIM_new\n", + " # T_val = sample(range(300, 750, 50), 1)\n", + " T_val = np.random.rand(9)\n", + " T_val = 300 + (700 - 300) * T_val\n", + " # C_val = sample([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0], 1)\n", + " C_val = np.random.rand(1)\n", + " C_val = 1.0 + (5.0 - 1.0) * C_val\n", + " \n", + " new_exp = new_doe_object2(C_val[0], T_val, FIM_prior)\n", + " FIM_new = new_exp.FIM\n", + " if FIM_rand is None:\n", + " FIM_rand = [FIM_new, ]\n", + " else:\n", + " FIM_rand.append(FIM_new)\n", + " A_opt = np.trace(FIM_new)\n", + " D_opt = np.linalg.det(FIM_new)\n", + " A_vals_rand.append(np.log10(A_opt))\n", + " D_vals_rand.append(np.log10(D_opt))" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "id": "883c7a88-c484-4d30-a240-0f59b7851641", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[array([[ 7.41191972, 1.91892715, -17.16569693, -5.13978557],\n", + " [ 1.91892715, 3.00288018, -3.30481097, -9.22942421],\n", + " [-17.16569693, -3.30481097, 40.83791667, 8.43170603],\n", + " [ -5.13978557, -9.22942421, 8.43170603, 29.03347955]]), array([[ 4.85545081, 0.91633779, -11.26700706, -2.3725946 ],\n", + " [ 0.91633779, 2.07545769, -1.67466172, -6.76212137],\n", + " [-11.26700706, -1.67466172, 26.48743701, 4.09255167],\n", + " [ -2.3725946 , -6.76212137, 4.09255167, 22.59510839]]), array([[ 1.63712282, 0.26253947, -3.61049017, -0.64461976],\n", + " [ 0.26253947, 0.65918137, -0.44757963, -2.18785091],\n", + " [-3.61049017, -0.44757963, 8.05695621, 1.03503989],\n", + " [-0.64461976, -2.18785091, 1.03503989, 7.4873944 ]]), array([[ 2.97488904, 0.93745651, -5.81666255, -3.06492446],\n", + " [ 0.93745651, 2.37956777, -1.78533978, -8.23677851],\n", + " [-5.81666255, -1.78533978, 11.39473346, 5.858635 ],\n", + " [-3.06492446, -8.23677851, 5.858635 , 28.72717236]]), array([[ 1.45973057, 0.98386612, -2.86168557, -3.83501583],\n", + " [ 0.98386612, 2.15443774, -1.91504893, -8.31274632],\n", + " [-2.86168557, -1.91504893, 5.61339247, 7.46485661],\n", + " [-3.83501583, -8.31274632, 7.46485661, 32.13147505]]), array([[ 0.32942076, 0.05277751, -0.72206457, -0.14075814],\n", + " [ 0.05277751, 0.16812912, -0.10170988, -0.57890579],\n", + " [-0.72206457, -0.10170988, 1.59135893, 0.26682263],\n", + " [-0.14075814, -0.57890579, 0.26682263, 2.03945911]]), array([[ 0.76173934, 0.46813848, -1.06469869, -1.24519301],\n", + " [ 0.46813848, 0.55668808, -0.65355734, -1.47375114],\n", + " [-1.06469869, -0.65355734, 1.48829363, 1.73857997],\n", + " [-1.24519301, -1.47375114, 1.73857997, 3.90772047]]), array([[ 1.58568372, 1.03312929, -2.30508585, -2.88710352],\n", + " [ 1.03312929, 1.33624454, -1.49728349, -3.71846817],\n", + " [-2.30508585, -1.49728349, 3.35175044, 4.18651955],\n", + " [-2.88710352, -3.71846817, 4.18651955, 10.36697694]]), array([[ 0.9146211 , 0.2098628 , -2.02667857, -0.78736555],\n", + " [ 0.2098628 , 0.76055504, -0.46593176, -2.99906867],\n", + " [-2.02667857, -0.46593176, 4.49422093, 1.7552855 ],\n", + " [-0.78736555, -2.99906867, 1.7552855 , 11.87833482]]), array([[ 2.26254966, 1.09103039, -4.86569687, -3.9775466 ],\n", + " [ 1.09103039, 2.48711336, -2.27302328, -9.29606811],\n", + " [-4.86569687, -2.27302328, 10.48284989, 8.27766951],\n", + " [-3.9775466 , -9.29606811, 8.27766951, 34.86643729]]), array([[ 2.37963826, 1.31101885, -3.90017864, -3.96581534],\n", + " [ 1.31101885, 2.32934987, -2.15691544, -7.08276537],\n", + " [-3.90017864, -2.15691544, 6.39343664, 6.52737831],\n", + " [-3.96581534, -7.08276537, 6.52737831, 21.54981334]]), array([[ 0.39317634, 0.27099406, -0.59222429, -0.7984167 ],\n", + " [ 0.27099406, 0.37061251, -0.40707655, -1.08492437],\n", + " [-0.59222429, -0.40707655, 0.8924423 , 1.20061859],\n", + " [-0.7984167 , -1.08492437, 1.20061859, 3.18892252]]), array([[ 0.22495 , 0.17358708, -0.34404272, -0.54730493],\n", + " [ 0.17358708, 0.2354521 , -0.2639738 , -0.73582788],\n", + " [-0.34404272, -0.2639738 , 0.52689608, 0.83381041],\n", + " [-0.54730493, -0.73582788, 0.83381041, 2.32359059]]), array([[ 1.46276597, 0.62662469, -3.9557259 , -2.91076272],\n", + " [ 0.62662469, 2.25275237, -1.67394427, -10.7119166 ],\n", + " [ -3.9557259 , -1.67394427, 10.70199128, 7.76623662],\n", + " [ -2.91076272, -10.7119166 , 7.76623662, 51.07349918]]), array([[ 6.54061161, 1.02433269, -16.03397716, -2.356947 ],\n", + " [ 1.02433269, 2.12804573, -1.76843941, -6.46991952],\n", + " [-16.03397716, -1.76843941, 40.14490486, 3.56281626],\n", + " [ -2.356947 , -6.46991952, 3.56281626, 20.19787514]]), array([[ 9.75348357, 7.80718051, -17.89422681, -30.05800918],\n", + " [ 7.80718051, 14.92544475, -13.33572462, -56.99505773],\n", + " [-17.89422681, -13.33572462, 33.23087006, 51.41850532],\n", + " [-30.05800918, -56.99505773, 51.41850532, 219.15103769]]), array([[ 1.77917606, 1.29540968, -2.57471389, -3.86435101],\n", + " [ 1.29540968, 1.60079675, -1.84799977, -4.7469565 ],\n", + " [-2.57471389, -1.84799977, 3.73604891, 5.52039717],\n", + " [-3.86435101, -4.7469565 , 5.52039717, 14.22683014]]), array([[ 1.0426306 , 0.31074057, -2.58096954, -1.12614861],\n", + " [ 0.31074057, 0.89576898, -0.74096629, -3.4507674 ],\n", + " [-2.58096954, -0.74096629, 6.42529421, 2.68122134],\n", + " [-1.12614861, -3.4507674 , 2.68122134, 13.34402829]]), array([[ 2.62318377, 1.58532964, -4.11611868, -4.65267119],\n", + " [ 1.58532964, 2.43243152, -2.4907991 , -7.1402936 ],\n", + " [-4.11611868, -2.4907991 , 6.46038325, 7.31016341],\n", + " [-4.65267119, -7.1402936 , 7.31016341, 20.97349451]]), array([[ 0.45863109, 0.06430434, -1.28081215, -0.18713209],\n", + " [ 0.06430434, 0.24416895, -0.16066722, -0.93320429],\n", + " [-1.28081215, -0.16066722, 3.61921878, 0.46801022],\n", + " [-0.18713209, -0.93320429, 0.46801022, 3.64970397]])]\n" + ] + }, + { + "data": { + "image/png": "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ypQp9O/fn8TERJo3b85Pf/pT1q5dW+tz5syZg8vlOu62Zs0aH1XdMPfee+9xNaemptb6nED8TN0yMzNr/JwmTpxY4/GB9LnOmzePn/zkJ6SlpeFyuXjvvfeqfd1xHO69917S0tKIjY3l7LPPZuXKlSd93enTp9OtWzeio6Pp1q0b7777rpfeQd3V9l5LS0v5/e9/T48ePYiPjyctLY1rr72W7OzsWl/z5ZdfrvGzLioq8vK7ObmTfbbXX3/9cXUPHDjwpK8baJ8tUONn5HK5eOihh074mv782XpL0AaRN998k9tvv50//vGPLF26lKFDh3LhhReybdu2Go/fvHkzo0aNYujQoSxdupQ//OEP3HbbbUyfPt3HldfP3LlzmThxIgsXLmTmzJmUlZUxYsQICgoKTvrctWvXsnPnzspbx44dfVDxqTnttNOq1bx8+fITHhuon6nbokWLqr3XmTNnAnDFFVfU+rxA+FwLCgro2bMnTz75ZI1f/8c//sEjjzzCk08+yaJFi0hNTeX888+v3H+qJt988w1XXXUV48aNY9myZYwbN44rr7ySb7/91ltvo05qe6+FhYV8//33/PnPf+b777/nnXfeYd26dVxyySUnfd2kpKRqn/POnTuJiYnxxluol5N9tgAjR46sVvcnn3xS62sG4mcLHPf5vPjii7hcLi6//PJaX9dfP1uvcYLUGWec4UyYMKHaY126dHHuuuuuGo//3e9+53Tp0qXaY7/85S+dgQMHeq1Gb9izZ48DOHPnzj3hMbNnz3YA58CBA74rzAPuuecep2fPnnU+Plg+U7df//rXTvv27Z2Kiooavx6onyvgvPvuu5X/rqiocFJTU50HH3yw8rGioiInOTnZefbZZ0/4OldeeaUzcuTIao9dcMEFzpgxYzxec0Md+15r8t133zmAs3Xr1hMe89JLLznJycmeLc4Lanq/1113nXPppZfW63WC5bO99NJLnXPOOafWYwLls/WkoOwRKSkpYcmSJYwYMaLa4yNGjGDBggU1Puebb7457vgLLriAxYsXU1pa6rVaPS03NxeAxo0bn/TY3r1707JlS84991xmz57t7dI8Yv369aSlpdG2bVvGjBnDpk2bTnhssHymYP6ffvXVV7nxxhtPugFkIH6uR9u8eTO7du2q9tlFR0czbNiwE37/wok/79qe449yc3NxuVw0atSo1uMOHTpEmzZtSE9P5+KLL2bp0qW+KdAD5syZQ/PmzenUqRM333wze/bsqfX4YPhsd+/ezccff8z48eNPemwgf7YNEZRBJCcnh/Lyclq0aFHt8RYtWrBr164an7Nr164ajy8rKyMnJ8drtXqS4zhMnjyZIUOG0L179xMe17JlS55//nmmT5/OO++8Q+fOnTn33HOZN2+eD6utvwEDBvCf//yHzz//nBdeeIFdu3YxePBg9u3bV+PxwfCZur333nscPHiQ66+//oTHBOrneiz392h9vn/dz6vvc/xNUVERd911F2PHjq11Q7QuXbrw8ssv88EHH/D6668TExPDmWeeyfr1631YbcNceOGFvPbaa8yaNYt//vOfLFq0iHPOOYfi4uITPicYPttXXnmFxMRERo8eXetxgfzZNpRf7757qo79y9FxnFr/mqzp+Joe91eTJk3ixx9/5Ouvv671uM6dO9O5c+fKfw8aNIisrCwefvhhzjrrLG+X2WAXXnhhZbtHjx4MGjSI9u3b88orrzB58uQanxPon6nb1KlTufDCC0lLSzvhMYH6uZ5Ifb9/G/ocf1FaWsqYMWOoqKjg6aefrvXYgQMHVhvgeeaZZ9KnTx+eeOIJHn/8cW+Xekquuuqqynb37t3p168fbdq04eOPP671l3Qgf7YAL774Itdcc81Jx3oE8mfbUEHZI9K0aVPCw8OPS8t79uw5LlW7paam1nh8REQETZo08VqtnnLrrbfywQcfMHv2bNLT0+v9/IEDBwZc4o6Pj6dHjx4nrDvQP1O3rVu38sUXX3DTTTfV+7mB+Lm6Z0LV5/vX/bz6PsdflJaWcuWVV7J582ZmzpxZ7+3hw8LC6N+/f8B91mB68tq0aVNr7YH82QJ89dVXrF27tkHfw4H82dZVUAaRqKgo+vbtWznLwG3mzJkMHjy4xucMGjTouONnzJhBv379iIyM9Fqtp8pxHCZNmsQ777zDrFmzaNu2bYNeZ+nSpbRs2dLD1XlXcXExq1evPmHdgfqZHuull16iefPmXHTRRfV+biB+rm3btiU1NbXaZ1dSUsLcuXNP+P0LJ/68a3uOP3CHkPXr1/PFF180KCQ7jsMPP/wQcJ81wL59+8jKyqq19kD9bN2mTp1K37596dmzZ72fG8ifbZ3ZGiXrbW+88YYTGRnpTJ061Vm1apVz++23O/Hx8c6WLVscx3Gcu+66yxk3blzl8Zs2bXLi4uKcO+64w1m1apUzdepUJzIy0nn77bdtvYU6+dWvfuUkJyc7c+bMcXbu3Fl5KywsrDzm2Pf66KOPOu+++66zbt06Z8WKFc5dd93lAM706dNtvIU6u/POO505c+Y4mzZtchYuXOhcfPHFTmJiYtB9pkcrLy93Wrdu7fz+978/7muB/Lnm5+c7S5cudZYuXeoAziOPPOIsXbq0cqbIgw8+6CQnJzvvvPOOs3z5cufqq692WrZs6eTl5VW+xrhx46rNgps/f74THh7uPPjgg87q1audBx980ImIiHAWLlzo8/d3tNrea2lpqXPJJZc46enpzg8//FDte7i4uLjyNY59r/fee6/z2WefORs3bnSWLl3q3HDDDU5ERITz7bff2niL1dT2fvPz850777zTWbBggbN582Zn9uzZzqBBg5xWrVoF3Wfrlpub68TFxTnPPPNMja8RSJ+ttwRtEHEcx3nqqaecNm3aOFFRUU6fPn2qTWm97rrrnGHDhlU7fs6cOU7v3r2dqKgoJzMz84T/4/gToMbbSy+9VHnMse/173//u9O+fXsnJibGSUlJcYYMGeJ8/PHHvi++nq666iqnZcuWTmRkpJOWluaMHj3aWblyZeXXg+UzPdrnn3/uAM7atWuP+1ogf67uqcbH3q677jrHccwU3nvuucdJTU11oqOjnbPOOstZvnx5tdcYNmxY5fFub731ltO5c2cnMjLS6dKli1+EsNre6+bNm0/4PTx79uzK1zj2vd5+++1O69atnaioKKdZs2bOiBEjnAULFvj+zdWgtvdbWFjojBgxwmnWrJkTGRnptG7d2rnuuuucbdu2VXuNYPhs3Z577jknNjbWOXjwYI2vEUifrbe4HOfI6D0RERERHwvKMSIiIiISGBRERERExBoFEREREbFGQURERESsURARERERaxRERERExBoFEREREbFGQURERESsURARERERaxRERERExBoFEREREbFGQURERESs+X8Eavm372QE9AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "D_vals_rand_from_ind_FIM = []\n", + "running_FIM = np.zeros((n_para, n_para))\n", + "print(FIM_rand)\n", + "for i in range(20):\n", + " running_FIM += FIM_rand[i]\n", + " D_vals_rand_from_ind_FIM.append(np.log10(np.linalg.det(running_FIM)))\n", + "\n", + "plt.plot(range(20), D_vals_rand_from_ind_FIM, color='green')\n", + "plt.plot(range(20), D_vals_rand, color='orange')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d0bf5a03-4f8a-4c7b-9ee3-57577550689e", + "metadata": {}, + "outputs": [], + "source": [ + "# mobel based design" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "id": "be09a59b-5783-4cdd-a023-380be8f2935a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.47e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 2.64e+01 3.85e+02 -1.0 1.47e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.71e+00 5.99e+01 -1.0 3.11e+01 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 3.98e-02 2.06e+00 -1.0 3.19e+00 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 7.87e-07 2.39e-04 -1.0 2.80e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (287125)\n", + " 5 0.0000000e+00 2.27e-13 1.50e-09 -3.8 5.42e-07 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.3691704763652764e-13 2.2737367544323206e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.3691704763652764e-13 2.2737367544323206e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.078\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 8.41e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 5.97e+02 3.85e+02 -1.0 8.40e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 9.58e+01 5.99e+01 -1.0 8.73e+02 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.25e+00 2.06e+00 -1.0 7.86e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.23e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (394005)\n", + " 5 0.0000000e+00 2.52e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.3691704763652764e-13 2.5224267119483557e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.3691704763652764e-13 2.5224267119483557e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.097\n", + "Total CPU secs in NLP function evaluations = 0.015\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -7.7248744e+00 8.42e+02 3.03e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303416)\n", + " 1 -9.5185054e+00 3.55e+02 1.97e+00 -1.0 2.49e+01 - 6.64e-01 5.10e-01h 1\n", + " 2 -1.0459243e+01 2.21e+01 1.06e+00 -1.0 1.03e+01 - 9.89e-01 1.00e+00f 1\n", + " 3 -1.0005982e+01 2.37e+00 1.82e+01 -1.0 6.69e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -9.4350217e+00 6.84e+00 2.90e+01 -1.0 1.66e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -9.9270718e+00 3.91e+00 4.23e+00 -1.0 7.85e+01 - 1.00e+00 1.00e+00h 1\n", + " 6 -9.8988295e+00 8.63e-02 7.95e-01 -1.0 4.47e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -9.9256371e+00 1.12e-02 8.03e-02 -1.7 1.69e+00 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.0115145e+01 6.09e-01 3.86e+00 -2.5 1.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.0716463e+01 1.17e+01 7.10e+01 -2.5 4.55e+02 - 2.86e-01 2.24e-01h 2\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.1139383e+01 3.90e+00 1.50e+01 -2.5 3.96e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (326891)\n", + " 11 -1.1160539e+01 7.96e-02 1.12e-01 -2.5 2.01e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 -1.1161798e+01 1.04e-03 2.28e-03 -2.5 3.39e+00 - 1.00e+00 1.00e+00h 1\n", + " 13 -1.1804938e+01 5.61e+00 3.57e+00 -3.8 7.07e+01 - 7.08e-01 1.00e+00f 1\n", + " 14 -1.2138004e+01 2.90e+00 2.94e+00 -3.8 6.85e+01 - 9.69e-01 1.00e+00h 1\n", + " 15 -1.2260171e+01 8.52e-01 5.77e-01 -3.8 3.63e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 -1.2249771e+01 6.32e-03 2.20e-02 -3.8 9.24e+00 - 1.00e+00 1.00e+00h 1\n", + " 17 -1.2249799e+01 6.45e-06 1.24e-05 -3.8 3.70e-01 - 1.00e+00 1.00e+00h 1\n", + " 18 -1.2341110e+01 2.89e-01 1.08e-01 -5.7 2.25e+01 - 9.19e-01 9.86e-01f 1\n", + " 19 -1.2347950e+01 6.26e-03 1.40e-03 -5.7 2.74e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2348059e+01 2.15e-06 1.44e-06 -5.7 4.38e-02 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.2349341e+01 7.29e-05 2.04e-05 -8.6 3.46e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (355282)\n", + " 22 -1.2349342e+01 2.92e-10 5.48e-08 -8.6 5.48e-04 -4.0 1.00e+00 1.00e+00h 1\n", + " 23 -1.2349342e+01 4.55e-13 2.15e-11 -8.6 6.44e-07 -4.5 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 23\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2349342292918536e+01 -1.2349342292918536e+01\n", + "Dual infeasibility......: 2.1473493827409733e-11 2.1473493827409733e-11\n", + "Constraint violation....: 1.7053025658242404e-13 4.5474735088646412e-13\n", + "Complementarity.........: 2.5059035849180921e-09 2.5059035849180921e-09\n", + "Overall NLP error.......: 2.5059035849180921e-09 2.5059035849180921e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 27\n", + "Number of objective gradient evaluations = 24\n", + "Number of equality constraint evaluations = 27\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 24\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 23\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.487\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.83e+01 4.31e+01 -1.0 4.78e+01 - 4.76e-01 9.84e-01h 1\n", + " 3 0.0000000e+00 2.63e-01 4.48e+02 -1.0 2.89e+01 - 4.02e-02 9.90e-01h 1\n", + " 4 0.0000000e+00 5.47e-04 1.17e+02 -1.0 1.35e-01 - 9.90e-01 9.98e-01h 1\n", + "Reallocating memory for MA57: lfact (284905)\n", + " 5 0.0000000e+00 6.26e-11 1.00e-06 -1.0 2.79e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 6.2641447584610432e-11 6.2641447584610432e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 6.2641447584610432e-11 6.2641447584610432e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.078\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.19e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 6.10e+02 3.85e+02 -1.0 2.19e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 9.60e+01 5.99e+01 -1.0 8.86e+02 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.25e+00 2.06e+00 -1.0 7.87e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.23e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (394385)\n", + " 5 0.0000000e+00 2.27e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.5474735088646412e-13 2.2737367544323206e-12\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.5474735088646412e-13 2.2737367544323206e-12\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.113\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.3841270e+01 8.42e+02 1.61e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303016)\n", + " 1 -1.4404335e+01 3.97e+02 3.77e+00 -1.0 2.54e+01 - 8.41e-01 5.01e-01h 1\n", + " 2 -1.4812683e+01 1.50e+01 5.74e-01 -1.0 7.17e+00 - 9.88e-01 1.00e+00f 1\n", + " 3 -1.4522399e+01 4.44e+00 1.61e+01 -1.0 8.94e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -1.4388879e+01 1.20e+01 1.37e+01 -1.0 1.49e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.4491792e+01 1.25e+00 1.12e+00 -1.0 3.05e+01 - 1.00e+00 1.00e+00h 1\n", + " 6 -1.4495171e+01 5.96e-04 9.48e-03 -1.0 1.09e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -1.4495521e+01 8.41e-05 5.34e-03 -2.5 3.10e-01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.4516522e+01 7.21e-01 1.81e+00 -3.8 1.75e+01 - 7.92e-01 1.00e+00h 1\n", + " 9 -1.4530830e+01 4.10e-03 1.85e-02 -3.8 1.06e+00 -4.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.4533751e+01 1.58e-03 4.43e-03 -3.8 1.26e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 11 -1.4540008e+01 1.21e-02 4.52e-02 -3.8 2.29e+00 -5.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.4566257e+01 2.27e-01 7.87e-01 -3.8 9.29e+00 -5.4 1.00e+00 1.00e+00h 1\n", + " 13 -1.4585780e+01 3.91e-02 1.61e-01 -3.8 3.90e+00 -5.0 1.00e+00 1.00e+00h 1\n", + " 14 -1.4657627e+01 8.05e-01 2.88e+00 -3.8 1.70e+01 -5.5 1.00e+00 1.00e+00h 1\n", + " 15 -1.5563505e+01 8.18e+01 2.82e+02 -3.8 4.19e+02 -6.0 2.05e-01 5.14e-01h 1\n", + " 16 -1.5523849e+01 2.68e+01 2.80e+01 -3.8 6.91e+01 -5.5 1.00e+00 1.00e+00h 1\n", + " 17 -1.5802664e+01 2.51e+01 5.48e+00 -3.8 1.72e+02 - 3.49e-01 4.82e-01h 1\n", + " 18 -1.5795220e+01 1.64e+01 1.24e+01 -3.8 1.44e+02 - 1.00e+00 1.00e+00f 1\n", + " 19 -1.5802973e+01 1.78e+00 6.66e-01 -3.8 5.80e+01 - 9.66e-01 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.5792518e+01 6.29e-02 1.87e-02 -3.8 2.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.5792562e+01 6.62e-05 7.16e-05 -3.8 6.47e-01 - 1.00e+00 1.00e+00h 1\n", + " 22 -1.5863869e+01 1.39e+00 8.36e-01 -5.7 8.31e+01 - 7.11e-01 1.00e+00f 1\n", + " 23 -1.5877663e+01 1.08e-01 5.90e-02 -5.7 2.81e+01 - 9.75e-01 1.00e+00h 1\n", + " 24 -1.5878910e+01 9.88e-03 7.73e-04 -5.7 8.80e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (330048)\n", + " 25 -1.5878920e+01 2.19e-04 2.60e-06 -5.7 1.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.5878920e+01 4.59e-08 3.36e-10 -5.7 1.93e-02 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.5880196e+01 1.15e-03 2.24e-04 -8.6 3.06e+00 - 9.93e-01 1.00e+00f 1\n", + "Reallocating memory for MA57: lfact (362150)\n", + " 28 -1.5880200e+01 1.55e-06 3.86e-08 -8.6 1.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 29 -1.5880200e+01 4.40e-12 1.85e-10 -8.6 1.90e-04 -6.0 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.5880200473415972e+01 -1.5880200473415972e+01\n", + "Dual infeasibility......: 1.8546108990308775e-10 1.8546108990308775e-10\n", + "Constraint violation....: 4.3998138465894954e-12 4.3998138465894954e-12\n", + "Complementarity.........: 2.5059390926675284e-09 2.5059390926675284e-09\n", + "Overall NLP error.......: 2.5059390926675284e-09 2.5059390926675284e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 30\n", + "Number of objective gradient evaluations = 30\n", + "Number of equality constraint evaluations = 30\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 30\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.620\n", + "Total CPU secs in NLP function evaluations = 0.028\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.4\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.19e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 5.67e+01 3.85e+02 -1.0 3.19e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 2.60e+01 4.39e+02 -1.0 7.08e+01 - 5.65e-02 9.90e-01h 1\n", + " 3 0.0000000e+00 1.79e-01 1.22e+02 -1.0 1.49e+01 - 5.20e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 7.30e-06 2.37e+02 -1.0 1.13e-01 - 9.91e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 3.41e-13 1.00e-06 -1.0 4.00e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.7701825750354685e-13 3.4106051316484809e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.7701825750354685e-13 3.4106051316484809e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.065\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 4.70e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 6.35e+02 3.85e+02 -1.0 4.70e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 9.62e+01 5.99e+01 -1.0 9.11e+02 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.26e+00 2.06e+00 -1.0 7.87e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.24e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393774)\n", + " 5 0.0000000e+00 4.55e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.3691704763652764e-13 4.5474735088646412e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.3691704763652764e-13 4.5474735088646412e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.119\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.7948727e+01 8.42e+02 1.33e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303016)\n", + " 1 -1.8165832e+01 4.09e+02 4.51e+00 -1.0 2.53e+01 - 9.19e-01 5.02e-01h 1\n", + " 2 -1.8347575e+01 8.18e+00 2.41e-01 -1.0 3.98e+00 - 9.87e-01 1.00e+00f 1\n", + " 3 -1.8279037e+01 6.26e+00 5.74e+00 -1.0 1.03e+02 - 1.00e+00 1.00e+00f 1\n", + " 4 -1.8238859e+01 1.69e+01 3.91e+00 -1.0 1.64e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.8269310e+01 2.31e-01 2.75e-01 -1.0 2.89e+00 - 1.00e+00 1.00e+00h 1\n", + " 6 -1.8270555e+01 5.19e-04 4.57e-04 -1.7 6.60e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 -1.8270805e+01 7.88e-04 6.63e-04 -3.8 5.00e-01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.8271500e+01 9.45e-04 5.28e-04 -5.7 1.71e+00 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -1.8273229e+01 5.92e-03 1.56e-04 -5.7 4.65e+00 -4.5 1.00e+00 9.14e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.8273631e+01 2.13e-03 1.40e-03 -5.7 3.86e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 11 -1.8275013e+01 2.11e-02 2.82e-03 -5.7 1.28e+00 -5.4 1.00e+00 1.00e+00h 1\n", + " 12 -1.8275591e+01 3.07e-03 4.00e-04 -5.7 5.07e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 13 -1.8277354e+01 3.13e-02 4.47e-03 -5.7 1.63e+00 -5.5 1.00e+00 1.00e+00h 1\n", + " 14 -1.8284188e+01 4.35e-01 7.97e-02 -5.7 6.56e+00 -6.0 1.00e+00 1.00e+00h 1\n", + " 15 -1.8339799e+01 2.22e+01 6.67e+00 -5.7 9.02e+01 -6.4 9.31e-01 6.26e-01h 1\n", + "Reallocating memory for MA57: lfact (332105)\n", + " 16 -1.8410872e+01 1.03e+01 2.06e+00 -5.7 1.03e+02 -6.0 1.00e+00 7.09e-01f 1\n", + " 17 -1.8453249e+01 9.48e+00 2.01e+00 -5.7 1.70e+02 -6.5 1.00e+00 1.89e-01f 1\n", + " 18 -1.8469379e+01 8.31e+00 1.68e+00 -5.7 8.57e+01 -7.0 4.45e-01 1.63e-01h 1\n", + " 19 -1.8493566e+01 3.77e+00 6.76e-01 -5.7 3.26e+01 -6.5 1.00e+00 5.98e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.8501400e+01 3.15e+00 5.56e-01 -5.7 5.39e+01 -7.0 1.00e+00 1.78e-01h 1\n", + " 21 -1.8519701e+01 2.67e-01 7.89e-02 -5.7 2.04e+01 -6.6 1.00e+00 1.00e+00f 1\n", + " 22 -1.8524363e+01 3.95e-01 2.25e-01 -5.7 6.41e+01 -7.1 1.00e+00 2.07e-01h 1\n", + " 23 -1.8531234e+01 2.84e-01 2.21e-01 -5.7 1.59e+01 -6.6 1.00e+00 1.00e+00f 1\n", + " 24 -1.8538783e+01 6.75e-01 4.74e-01 -5.7 5.12e+01 -7.1 1.00e+00 3.67e-01h 1\n", + " 25 -1.8551386e+01 4.55e+00 1.63e+00 -5.7 8.00e+01 -7.6 1.00e+00 1.00e+00f 1\n", + " 26 -1.8545090e+01 1.46e-01 1.88e-01 -5.7 2.34e+01 -7.2 1.00e+00 1.00e+00h 1\n", + " 27 -1.8546477e+01 1.85e-01 1.29e-01 -5.7 9.39e+01 -7.6 1.00e+00 5.95e-01h 1\n", + " 28 -1.8546576e+01 2.34e-02 6.92e-03 -5.7 2.28e+01 - 1.00e+00 1.00e+00f 1\n", + " 29 -1.8546954e+01 2.55e-02 9.41e-03 -5.7 2.37e+01 - 1.00e+00 9.61e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -1.8546953e+01 3.64e-05 1.38e-05 -5.7 9.21e-01 - 1.00e+00 1.00e+00h 1\n", + " 31 -1.8546953e+01 3.38e-09 1.41e-09 -5.7 8.86e-03 - 1.00e+00 1.00e+00h 1\n", + " 32 -1.8548230e+01 1.41e-03 1.43e-04 -8.6 1.62e+00 - 9.94e-01 9.96e-01f 1\n", + " 33 -1.8548236e+01 9.75e-08 1.46e-08 -8.6 9.43e-03 - 1.00e+00 1.00e+00h 1\n", + " 34 -1.8548236e+01 9.09e-13 1.54e-13 -8.6 8.26e-07 -8.1 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.8548235998334103e+01 -1.8548235998334103e+01\n", + "Dual infeasibility......: 1.5371362792196526e-13 1.5371362792196526e-13\n", + "Constraint violation....: 9.0949470177292824e-13 9.0949470177292824e-13\n", + "Complementarity.........: 2.5059035679086560e-09 2.5059035679086560e-09\n", + "Overall NLP error.......: 2.5059035679086560e-09 2.5059035679086560e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 35\n", + "Number of objective gradient evaluations = 35\n", + "Number of equality constraint evaluations = 35\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 35\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.987\n", + "Total CPU secs in NLP function evaluations = 0.017\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.54e+01 4.20e+01 -1.0 4.92e+01 - 4.94e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 3.23e-01 3.50e+02 -1.0 2.84e+01 - 2.68e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 9.11e-06 2.34e+02 -1.0 1.90e-01 - 9.91e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 3.13e-13 1.00e-06 -1.0 6.34e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.2971319830862150e-13 3.1263880373444408e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.2971319830862150e-13 3.1263880373444408e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.056\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 9.91e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 6.88e+02 3.85e+02 -1.0 9.91e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 9.67e+01 5.99e+01 -1.0 9.63e+02 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.26e+00 2.06e+00 -1.0 7.88e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.24e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393643)\n", + " 5 0.0000000e+00 1.82e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8189894035458565e-12 1.8189894035458565e-12\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8189894035458565e-12 1.8189894035458565e-12\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -2.1041036e+01 8.42e+02 1.22e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303234)\n", + " 1 -2.1145524e+01 4.14e+02 4.86e+00 -1.0 2.53e+01 - 9.57e-01 5.02e-01h 1\n", + " 2 -2.1235982e+01 4.29e+00 1.97e-01 -1.0 3.69e+00 - 9.85e-01 1.00e+00f 1\n", + " 3 -2.1196637e+01 7.15e+00 3.48e+00 -1.0 1.06e+02 - 1.00e+00 1.00e+00f 1\n", + " 4 -2.1182737e+01 1.81e+01 1.49e+00 -1.0 1.80e+02 - 1.00e+00 1.00e+00h 1\n", + " 5 -2.1196659e+01 9.63e-02 8.45e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 6 -2.1196935e+01 1.22e-04 1.64e-03 -2.5 3.09e-01 - 1.00e+00 1.00e+00h 1\n", + " 7 -2.1197254e+01 5.64e-03 3.71e-04 -3.8 1.98e+00 - 1.00e+00 1.00e+00h 1\n", + " 8 -2.1197442e+01 2.71e-04 1.49e-04 -3.8 9.31e-01 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -2.1197814e+01 1.12e-03 1.02e-04 -5.7 1.87e+00 -4.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -2.1198435e+01 3.31e-03 1.47e-04 -5.7 3.66e+00 -5.0 1.00e+00 8.46e-01h 1\n", + " 11 -2.1198609e+01 2.27e-03 4.45e-04 -5.7 5.23e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 12 -2.1199224e+01 2.27e-02 1.60e-03 -5.7 1.87e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 13 -2.1201389e+01 2.97e-01 1.99e-02 -5.7 4.95e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 14 -2.1215482e+01 2.18e+01 3.79e+00 -5.7 1.77e+02 -6.9 4.71e-01 3.13e-01h 1\n", + " 15r-2.1215482e+01 2.18e+01 9.99e+02 1.3 0.00e+00 -7.3 0.00e+00 2.37e-07R 5\n", + " 16r-2.1215529e+01 2.18e+01 9.65e+03 1.3 7.99e+05 - 1.23e-05 4.88e-07f 1\n", + " 17r-2.1332007e+01 5.50e+00 9.67e+03 1.3 2.14e+04 - 7.52e-05 1.01e-03f 1\n", + " 18 -2.1341179e+01 6.06e+00 2.11e-01 -5.7 1.51e+03 - 9.35e-02 1.40e-02h 1\n", + " 19 -2.1348895e+01 6.45e+00 1.98e-01 -5.7 2.96e+03 - 8.78e-02 6.18e-02h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -2.1348057e+01 6.10e+00 1.44e+00 -5.7 3.35e+02 -7.8 1.00e+00 8.82e-02h 1\n", + " 21 -2.1337687e+01 5.02e+00 8.30e-01 -5.7 2.16e+02 -8.3 1.00e+00 3.48e-01h 1\n", + " 22 -2.1256596e+01 2.16e+01 7.80e+03 -5.7 6.01e+02 -7.9 7.05e-05 3.63e-01h 1\n", + " 23 -2.1229440e+01 6.42e+00 1.69e+03 -5.7 5.09e+01 -3.8 3.31e-01 7.83e-01h 1\n", + " 24 -2.1225416e+01 7.91e-02 1.07e+00 -5.7 4.92e+00 -4.3 1.85e-04 1.00e+00h 1\n", + " 25 -2.1234904e+01 2.01e-01 1.93e-02 -5.7 1.80e+01 -4.8 1.00e+00 1.00e+00h 1\n", + " 26 -2.1254412e+01 9.46e-01 1.46e-02 -5.7 5.59e+01 -5.3 1.00e+00 6.93e-01h 1\n", + " 27 -2.1288915e+01 3.38e+00 4.31e-02 -5.7 1.68e+02 -5.7 1.00e+00 4.35e-01f 1\n", + " 28 -2.1310182e+01 3.91e+00 4.77e-02 -5.7 3.62e+02 -6.2 1.00e+00 1.26e-01f 1\n", + " 29 -2.1313014e+01 6.05e-02 3.51e-02 -5.7 7.03e+00 -6.7 8.65e-02 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (332877)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -2.1314539e+01 1.81e-01 7.17e-02 -5.7 2.17e+01 -7.2 1.00e+00 4.80e-01h 1\n", + " 31 -2.1322536e+01 5.42e+00 6.40e+01 -5.7 1.14e+03 - 4.87e-05 5.01e-02h 2\n", + " 32 -2.1318925e+01 6.40e-02 1.01e+00 -5.7 1.52e+00 - 6.09e-02 1.00e+00h 1\n", + " 33 -2.1319551e+01 1.97e-03 3.61e-04 -5.7 1.05e+00 - 1.00e+00 1.00e+00h 1\n", + " 34 -2.1319541e+01 3.42e-06 6.83e-07 -5.7 2.81e-01 - 1.00e+00 1.00e+00h 1\n", + " 35 -2.1320810e+01 5.55e-03 3.24e-04 -8.6 3.28e+00 - 9.87e-01 9.90e-01h 1\n", + " 36 -2.1320824e+01 1.71e-06 1.42e-07 -8.6 4.12e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (355912)\n", + "Reallocating memory for MA57: lfact (403977)\n", + " 37 -2.1320824e+01 4.55e-13 1.22e-13 -8.6 1.29e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 37\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -2.1320823847268578e+01 -2.1320823847268578e+01\n", + "Dual infeasibility......: 1.2172728103276853e-13 1.2172728103276853e-13\n", + "Constraint violation....: 4.5474735088646412e-13 4.5474735088646412e-13\n", + "Complementarity.........: 2.5059035644843673e-09 2.5059035644843673e-09\n", + "Overall NLP error.......: 2.5059035644843673e-09 2.5059035644843673e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 45\n", + "Number of objective gradient evaluations = 37\n", + "Number of equality constraint evaluations = 45\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 39\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 37\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.000\n", + "Total CPU secs in NLP function evaluations = 0.051\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.54e+01 4.20e+01 -1.0 4.92e+01 - 4.94e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 3.11e-01 3.50e+02 -1.0 2.84e+01 - 2.68e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 8.56e-06 2.34e+02 -1.0 1.82e-01 - 9.91e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 2.97e-13 1.00e-06 -1.0 5.95e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.2308013703147609e-13 2.9665159217984183e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.2308013703147609e-13 2.9665159217984183e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.069\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.03e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 7.92e+02 3.85e+02 -1.0 2.03e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 9.78e+01 5.99e+01 -1.0 1.07e+03 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.27e+00 2.06e+00 -1.0 7.91e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.25e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393908)\n", + " 5 0.0000000e+00 4.55e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.2737367544323206e-13 4.5474735088646412e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.2737367544323206e-13 4.5474735088646412e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.118\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -2.3957786e+01 8.42e+02 1.15e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303016)\n", + " 1 -2.4009165e+01 4.16e+02 5.03e+00 -1.0 2.52e+01 - 9.74e-01 5.03e-01h 1\n", + " 2 -2.4053676e+01 2.23e+00 1.57e-01 -1.0 6.82e+00 - 9.83e-01 1.00e+00f 1\n", + " 3 -2.4049598e+01 2.63e-01 1.04e-01 -1.7 2.03e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -2.4031404e+01 5.51e+00 8.43e-01 -1.7 1.66e+02 - 1.00e+00 9.62e-01f 1\n", + " 5 -2.4031794e+01 9.63e+00 1.11e-01 -1.7 1.31e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -2.4034753e+01 9.12e-03 4.93e-03 -1.7 9.57e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -2.4034764e+01 5.23e-06 2.40e-04 -3.8 5.16e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (320596)\n", + " 8 -2.4036325e+01 4.61e-01 4.50e-02 -5.7 2.11e+01 - 8.48e-01 1.00e+00h 1\n", + " 9 -2.4036710e+01 3.52e-04 5.33e-04 -5.7 3.85e-01 -4.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -2.4036850e+01 6.00e-04 7.85e-05 -5.7 1.39e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 11 -2.4036956e+01 2.95e-04 4.05e-04 -5.7 1.52e+00 -5.0 1.00e+00 6.87e-01H 1\n", + " 12 -2.4036981e+01 2.11e-04 1.51e-04 -5.7 1.55e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 13 -2.4037122e+01 2.08e-03 9.42e-05 -5.7 8.97e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 14 -2.4037545e+01 1.84e-02 9.37e-04 -5.7 2.52e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 15 -2.4038911e+01 1.53e-01 1.30e-02 -5.7 7.03e+00 -6.9 1.00e+00 1.00e+00h 1\n", + " 16 -2.4039513e+01 1.71e-02 2.17e-03 -5.7 2.31e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 17 -2.4041456e+01 2.25e-01 5.40e-02 -5.7 1.12e+01 -6.9 1.00e+00 1.00e+00h 1\n", + " 18 -2.4042770e+01 5.07e-02 2.20e-02 -5.7 5.24e+00 -6.5 1.00e+00 1.00e+00h 1\n", + " 19 -2.4050544e+01 4.39e+00 1.42e+00 -5.7 4.13e+01 -7.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -2.4066468e+01 2.01e+00 5.80e-01 -5.7 6.98e+01 -6.5 1.00e+00 1.00e+00h 1\n", + " 21 -2.4093450e+01 6.18e+00 2.10e+00 -5.7 3.11e+02 -7.0 6.69e-01 3.36e-01h 1\n", + " 22 -2.4106017e+01 6.61e+00 2.16e+00 -5.7 7.31e+02 -7.5 1.00e+00 5.80e-02h 1\n", + " 23 -2.4143250e+01 1.35e+01 2.72e+00 -5.7 4.43e+02 -8.0 6.35e-01 3.17e-01h 1\n", + " 24 -2.4148932e+01 1.23e+01 2.04e+00 -5.7 2.31e+02 -8.4 7.03e-01 2.32e-01h 1\n", + " 25 -2.4151239e+01 1.14e+01 1.84e+00 -5.7 1.07e+03 -8.9 2.31e-01 9.52e-02h 1\n", + " 26 -2.4155618e+01 9.19e+00 6.95e-01 -5.7 1.24e+02 - 1.00e+00 7.89e-01f 1\n", + " 27 -2.4153220e+01 4.92e-01 8.71e-02 -5.7 2.88e+01 - 1.00e+00 1.00e+00h 1\n", + " 28 -2.4153102e+01 1.90e-02 1.51e-04 -5.7 1.19e+01 - 1.00e+00 1.00e+00h 1\n", + " 29 -2.4153101e+01 3.02e-05 6.13e-08 -5.7 4.80e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -2.4153101e+01 6.65e-10 1.93e-11 -5.7 2.26e-03 - 1.00e+00 1.00e+00h 1\n", + " 31 -2.4154362e+01 2.69e-02 4.53e-03 -8.6 1.45e+01 - 9.56e-01 1.00e+00f 1\n", + "Reallocating memory for MA57: lfact (345644)\n", + " 32 -2.4154374e+01 4.15e-04 2.66e-06 -8.6 1.84e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (384901)\n", + " 33 -2.4154374e+01 4.16e-07 6.54e-10 -8.6 5.84e-02 - 1.00e+00 1.00e+00h 1\n", + " 34 -2.4154374e+01 9.09e-13 1.27e-13 -8.6 3.70e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -2.4154373723270826e+01 -2.4154373723270826e+01\n", + "Dual infeasibility......: 1.2724980870831129e-13 1.2724980870831129e-13\n", + "Constraint violation....: 6.9129384604076763e-13 9.0949470177292824e-13\n", + "Complementarity.........: 2.5059035618469615e-09 2.5059035618469615e-09\n", + "Overall NLP error.......: 2.5059035618469615e-09 2.5059035618469615e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 36\n", + "Number of objective gradient evaluations = 35\n", + "Number of equality constraint evaluations = 36\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 35\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.007\n", + "Total CPU secs in NLP function evaluations = 0.010\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.24e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 5.76e+01 3.85e+02 -1.0 3.24e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 2.68e+01 4.57e+02 -1.0 7.19e+01 - 5.57e-02 9.90e-01h 1\n", + " 3 0.0000000e+00 1.69e-01 1.26e+02 -1.0 1.53e+01 - 4.90e-01 9.91e-01f 1\n", + " 4 0.0000000e+00 6.46e-06 2.38e+02 -1.0 1.08e-01 - 9.91e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 4.55e-13 1.00e-06 -1.0 3.54e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.9311082636750565e-13 4.5474735088646412e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.9311082636750565e-13 4.5474735088646412e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.071\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 4.10e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 9.98e+02 3.85e+02 -1.0 4.10e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 9.98e+01 5.99e+01 -1.0 1.27e+03 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.29e+00 2.06e+00 -1.0 7.95e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.27e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393985)\n", + " 5 0.0000000e+00 7.28e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.2759576141834259e-12 7.2759576141834259e-12\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.2759576141834259e-12 7.2759576141834259e-12\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -2.6831720e+01 8.42e+02 1.11e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303196)\n", + " 1 -2.6856995e+01 4.17e+02 5.11e+00 -1.0 2.52e+01 - 9.83e-01 5.03e-01h 1\n", + " 2 -2.6878754e+01 1.15e+00 1.70e-01 -1.0 1.35e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -2.6876993e+01 2.41e-01 8.47e-02 -1.7 2.32e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -2.6868640e+01 5.70e+00 3.70e-01 -1.7 1.61e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -2.6869023e+01 8.10e+00 4.89e-02 -1.7 1.19e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -2.6870266e+01 5.51e-03 2.48e-03 -1.7 8.49e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -2.6870267e+01 1.82e-06 9.94e-05 -3.8 3.28e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -2.6870637e+01 1.33e-01 5.56e-03 -5.7 1.03e+01 - 9.45e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (320847)\n", + " 9 -2.6870673e+01 2.67e-05 3.18e-05 -5.7 3.18e-01 -4.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -2.6870728e+01 3.86e-04 3.70e-05 -5.7 1.11e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 11 -2.6870877e+01 2.81e-03 3.33e-05 -5.7 3.00e+00 -5.0 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (337659)\n", + " 12 -2.6870878e+01 1.08e-04 7.14e-05 -5.7 8.84e-02 -5.4 1.00e+00 1.00e+00h 1\n", + " 13 -2.6870919e+01 1.06e-03 1.84e-05 -5.7 6.15e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 14 -2.6871022e+01 9.59e-03 1.61e-04 -5.7 1.37e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 15 -2.6871350e+01 1.01e-01 1.67e-03 -5.7 3.88e+00 -6.9 1.00e+00 1.00e+00h 1\n", + " 16 -2.6872711e+01 2.39e+00 4.78e-02 -5.7 1.44e+01 -7.3 1.00e+00 1.00e+00h 1\n", + " 17 -2.6874054e+01 5.83e-01 1.31e-02 -5.7 1.62e+01 -6.9 1.00e+00 1.00e+00h 1\n", + " 18 -2.6879134e+01 1.19e+01 4.46e-01 -5.7 1.13e+02 -7.4 1.00e+00 5.07e-01h 1\n", + " 19 -2.6887284e+01 4.11e+00 1.69e-01 -5.7 7.00e+01 -7.0 1.00e+00 9.59e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -2.6892052e+01 4.46e+00 1.97e-01 -5.7 1.88e+02 -7.4 1.00e+00 1.65e-01f 1\n", + " 21 -2.6894657e+01 1.59e+00 4.78e-02 -5.7 2.29e+01 -7.9 9.98e-01 8.13e-01f 1\n", + " 22 -2.6895685e+01 1.03e-01 2.03e-03 -5.7 1.09e+01 -7.5 1.00e+00 1.00e+00f 1\n", + " 23 -2.6896013e+01 3.73e-02 4.31e-03 -5.7 8.81e+00 -8.0 1.00e+00 1.00e+00h 1\n", + " 24 -2.6896032e+01 1.65e-03 4.30e-04 -5.7 1.77e+00 -7.5 1.00e+00 1.00e+00h 1\n", + " 25 -2.6896510e+01 5.88e+00 1.25e+00 -5.7 9.18e+01 -8.0 1.00e+00 1.00e+00h 1\n", + " 26 -2.6897324e+01 2.35e+00 1.70e-01 -5.7 8.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 27 -2.6899093e+01 2.49e-01 4.48e-02 -5.7 3.94e+01 - 1.00e+00 9.34e-01h 1\n", + " 28 -2.6898971e+01 7.46e-02 2.34e-03 -5.7 2.43e+01 - 1.00e+00 1.00e+00f 1\n", + " 29 -2.6898969e+01 4.09e-03 9.27e-06 -5.7 5.54e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -2.6898969e+01 2.54e-05 4.67e-08 -5.7 4.39e-01 - 1.00e+00 1.00e+00h 1\n", + " 31 -2.6898969e+01 8.92e-10 1.97e-11 -5.7 2.60e-03 - 1.00e+00 1.00e+00h 1\n", + " 32 -2.6900308e+01 1.16e-01 2.77e-03 -8.6 1.79e+01 - 9.13e-01 9.53e-01f 1\n", + " 33 -2.6900393e+01 3.09e-03 1.29e-04 -8.6 4.98e+00 - 1.00e+00 1.00e+00h 1\n", + " 34 -2.6900395e+01 2.18e-04 1.36e-06 -8.6 1.34e+00 - 1.00e+00 1.00e+00h 1\n", + " 35 -2.6900395e+01 9.33e-07 2.55e-09 -8.6 8.75e-02 - 1.00e+00 1.00e+00h 1\n", + " 36 -2.6900395e+01 1.48e-11 5.99e-14 -8.6 3.48e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 36\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -2.6900395275199973e+01 -2.6900395275199973e+01\n", + "Dual infeasibility......: 5.9903245874163696e-14 5.9903245874163696e-14\n", + "Constraint violation....: 1.4777956636180534e-11 1.4777956636180534e-11\n", + "Complementarity.........: 2.5059038382096498e-09 2.5059038382096498e-09\n", + "Overall NLP error.......: 2.5059038382096498e-09 2.5059038382096498e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 37\n", + "Number of objective gradient evaluations = 37\n", + "Number of equality constraint evaluations = 37\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 37\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 36\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.085\n", + "Total CPU secs in NLP function evaluations = 0.056\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.53e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.54e-02 3.84e+00 -1.0 1.38e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.22e-04 3.52e+00 -1.0 1.38e-02 - 1.00e+00 9.92e-01h 1\n", + " 4 0.0000000e+00 7.74e-13 1.01e-06 -1.0 1.10e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.7449158197850920e-13 7.7449158197850920e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.7449158197850920e-13 7.7449158197850920e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.049\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 8.26e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 1.41e+03 3.85e+02 -1.0 8.26e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.04e+02 5.99e+01 -1.0 1.69e+03 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.33e+00 2.06e+00 -1.0 8.05e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.31e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393607)\n", + " 5 0.0000000e+00 9.09e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0949470177292824e-13 9.0949470177292824e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0949470177292824e-13 9.0949470177292824e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -2.9638946e+01 8.42e+02 1.08e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303234)\n", + " 1 -2.9651536e+01 4.17e+02 5.15e+00 -1.0 2.52e+01 - 9.87e-01 5.03e-01h 1\n", + " 2 -2.9662204e+01 5.88e-01 1.69e-01 -1.0 1.90e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -2.9661372e+01 2.28e-01 8.72e-02 -1.7 2.54e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -2.9657366e+01 5.59e+00 1.74e-01 -1.7 1.57e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -2.9657597e+01 7.45e+00 2.43e-02 -1.7 1.12e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -2.9658155e+01 9.80e-03 5.94e-04 -1.7 9.51e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -2.9658157e+01 2.42e-07 4.73e-05 -3.8 1.06e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (324542)\n", + " 8 -2.9658248e+01 2.96e-02 2.07e-03 -5.7 5.06e+00 - 9.80e-01 1.00e+00h 1\n", + " 9 -2.9658255e+01 8.09e-06 1.82e-05 -5.7 1.82e-01 -4.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -2.9658269e+01 1.10e-04 1.97e-05 -8.6 5.90e-01 -4.5 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (353780)\n", + " 11 -2.9658314e+01 1.01e-03 1.99e-05 -8.6 1.79e+00 -5.0 1.00e+00 1.00e+00h 1\n", + " 12 -2.9658384e+01 2.94e-03 1.98e-05 -8.6 5.34e+00 -5.4 1.00e+00 5.24e-01h 1\n", + " 13 -2.9658390e+01 2.14e-04 6.05e-05 -8.6 1.92e-01 -5.9 1.00e+00 1.00e+00f 1\n", + " 14 -2.9658414e+01 2.03e-03 1.72e-05 -8.6 7.84e-01 -6.4 1.00e+00 1.00e+00h 1\n", + " 15 -2.9658485e+01 1.95e-02 1.65e-04 -8.6 2.16e+00 -6.9 1.00e+00 1.00e+00h 1\n", + " 16 -2.9658723e+01 2.33e-01 1.94e-03 -8.6 6.13e+00 -7.3 1.00e+00 1.00e+00h 1\n", + " 17 -2.9659707e+01 2.00e+01 4.71e-01 -8.6 4.15e+02 -7.8 2.10e-01 1.32e-01h 1\n", + " 18 -2.9661723e+01 1.08e+01 6.12e+00 -8.6 7.98e+01 -7.4 1.00e+00 5.36e-01h 1\n", + " 19 -2.9662944e+01 1.03e+01 8.86e+00 -8.6 2.03e+02 -7.9 7.79e-01 1.08e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -2.9664685e+01 1.03e+01 1.59e+01 -8.6 1.87e+02 -8.3 1.00e+00 1.08e-01h 1\n", + " 21 -2.9668199e+01 7.67e+00 4.66e+00 -8.6 1.09e+02 -7.9 1.00e+00 5.18e-01h 1\n", + " 22 -2.9669825e+01 7.05e+00 2.58e+01 -8.6 2.15e+02 -8.4 1.00e+00 1.50e-01h 1\n", + " 23 -2.9670730e+01 3.22e+00 2.25e+01 -8.6 3.00e+01 -8.0 4.59e-01 5.76e-01h 1\n", + " 24 -2.9672420e+01 2.48e+01 1.63e+01 -8.6 4.62e+02 -8.4 3.30e-01 2.77e-01f 1\n", + " 25 -2.9671141e+01 6.69e+00 4.35e+00 -8.6 2.59e+01 -8.0 1.00e+00 7.33e-01h 1\n", + " 26 -2.9672562e+01 4.65e-01 2.66e-02 -8.6 2.69e+01 -8.5 1.00e+00 1.00e+00h 1\n", + " 27 -2.9672664e+01 4.46e-01 1.65e-02 -8.6 1.35e+02 -9.0 1.00e+00 4.39e-01h 1\n", + " 28 -2.9672722e+01 1.68e-01 1.61e-03 -8.6 1.93e+01 - 1.00e+00 1.00e+00h 1\n", + " 29 -2.9672724e+01 1.86e-02 5.75e-04 -8.6 2.08e+01 - 1.00e+00 9.29e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -2.9672723e+01 3.34e-06 7.50e-08 -8.6 2.03e-02 - 1.00e+00 1.00e+00h 1\n", + " 31 -2.9672723e+01 1.46e-11 9.19e-14 -8.6 1.60e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 31\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -2.9672723137182857e+01 -2.9672723137182857e+01\n", + "Dual infeasibility......: 9.1912354482113998e-14 9.1912354482113998e-14\n", + "Constraint violation....: 3.6379788070917130e-12 1.4551915228366852e-11\n", + "Complementarity.........: 2.5059038164605147e-09 2.5059038164605147e-09\n", + "Overall NLP error.......: 2.5059038164605147e-09 2.5059038164605147e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 32\n", + "Number of objective gradient evaluations = 32\n", + "Number of equality constraint evaluations = 32\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 32\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 31\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.978\n", + "Total CPU secs in NLP function evaluations = 0.022\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.44e-01 3.41e+02 -1.0 2.83e+01 - 2.90e-01 9.94e-01h 1\n", + " 4 0.0000000e+00 2.63e-06 2.33e+02 -1.0 7.93e-02 - 9.91e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 2.49e-13 1.00e-06 -1.0 1.80e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.0318095320003983e-13 2.4868995751603507e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.0318095320003983e-13 2.4868995751603507e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.056\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.66e+05 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 2.25e+03 3.85e+02 -1.0 1.66e+05 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.12e+02 5.99e+01 -1.0 2.52e+03 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.41e+00 2.06e+00 -1.0 8.23e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.39e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393985)\n", + " 5 0.0000000e+00 2.91e-11 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.9103830456733704e-11 2.9103830456733704e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.9103830456733704e-11 2.9103830456733704e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.109\n", + "Total CPU secs in NLP function evaluations = 0.010\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -3.2428486e+01 8.42e+02 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303234)\n", + " 1 -3.2434768e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", + " 2 -3.2440069e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -3.2439664e+01 2.27e-01 8.67e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -3.2437689e+01 5.57e+00 1.18e-01 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -3.2437810e+01 7.15e+00 1.20e-02 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -3.2438076e+01 1.07e-02 4.29e-04 -1.7 9.35e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -3.2438077e+01 3.69e-07 2.81e-05 -3.8 6.32e-03 - 1.00e+00 1.00e+00h 1\n", + " 8 -3.2438078e+01 1.83e-06 7.60e-06 -5.7 7.60e-02 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -3.2438082e+01 2.75e-05 9.82e-06 -8.6 2.95e-01 -4.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -3.2438093e+01 2.57e-04 1.00e-05 -8.6 9.02e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 11 -3.2438127e+01 2.32e-03 1.00e-05 -8.6 2.71e+00 -5.4 1.00e+00 1.00e+00h 1\n", + " 12 -3.2438152e+01 3.01e-03 1.00e-05 -8.6 8.06e+00 -5.9 1.00e+00 2.49e-01h 1\n", + " 13 -3.2438155e+01 4.60e-04 4.53e-05 -8.6 2.32e-01 -6.4 1.00e+00 1.00e+00f 1\n", + " 14 -3.2438173e+01 4.53e-03 1.89e-05 -8.6 1.27e+00 -6.9 1.00e+00 1.00e+00h 1\n", + " 15 -3.2438225e+01 4.49e-02 1.89e-04 -8.6 3.33e+00 -7.3 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (333035)\n", + " 16 -3.2438415e+01 6.88e-01 2.78e-03 -8.6 9.07e+00 -7.8 1.00e+00 1.00e+00h 1\n", + " 17 -3.2438526e+01 1.13e-01 3.98e-04 -8.6 3.08e+00 -7.4 1.00e+00 1.00e+00h 1\n", + " 18 -3.2438959e+01 3.03e+00 2.02e-02 -8.6 1.89e+01 -7.9 1.00e+00 1.00e+00h 1\n", + " 19 -3.2439451e+01 9.31e-01 4.43e-03 -8.6 2.65e+01 -7.4 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -3.2440256e+01 3.61e+00 2.46e-02 -8.6 2.05e+02 -7.9 9.03e-01 1.92e-01h 1\n", + " 21 -3.2440820e+01 2.54e+00 1.86e-02 -8.6 4.61e+01 -7.5 1.00e+00 4.20e-01f 1\n", + " 22 -3.2443038e+01 8.60e+00 1.12e-01 -8.6 2.61e+02 -8.0 8.80e-01 2.74e-01f 1\n", + " 23 -3.2443317e+01 8.60e+00 1.12e-01 -8.6 1.27e+03 -8.4 5.04e-01 5.61e-03h 1\n", + " 24 -3.2444082e+01 2.43e+00 2.51e-02 -8.6 1.87e+01 -8.0 1.42e-01 7.76e-01h 1\n", + " 25 -3.2444206e+01 2.00e+00 2.04e-02 -8.6 2.84e+01 -8.5 8.77e-01 1.87e-01f 1\n", + " 26 -3.2444524e+01 1.50e-01 2.01e-03 -8.6 1.06e+01 -8.1 1.00e+00 1.00e+00h 1\n", + " 27 -3.2444530e+01 1.48e-01 1.97e-03 -8.6 3.53e+01 -8.5 1.00e+00 1.95e-02h 1\n", + " 28 -3.2444603e+01 2.35e-02 9.67e-04 -8.6 9.31e+00 -8.1 1.00e+00 1.00e+00f 1\n", + " 29 -3.2444869e+01 3.57e+00 1.39e-01 -8.6 8.64e+01 -8.6 1.00e+00 6.85e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -3.2445180e+01 2.78e+00 5.43e-02 -8.6 2.44e+02 -9.1 1.00e+00 6.18e-01f 1\n", + " 31 -3.2445337e+01 1.07e+00 1.03e-02 -8.6 5.66e+01 - 1.00e+00 1.00e+00h 1\n", + " 32 -3.2445329e+01 4.67e-01 4.82e-03 -8.6 9.94e+01 - 1.00e+00 5.69e-01h 1\n", + " 33 -3.2445311e+01 1.99e-03 3.70e-05 -8.6 9.19e-01 - 1.00e+00 1.00e+00h 1\n", + " 34 -3.2445311e+01 1.62e-07 1.29e-09 -8.6 1.08e-02 - 1.00e+00 1.00e+00h 1\n", + " 35 -3.2445311e+01 5.82e-11 2.86e-14 -8.6 7.59e-07 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 35\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -3.2445310986118486e+01 -3.2445310986118486e+01\n", + "Dual infeasibility......: 2.8629516867220174e-14 2.8629516867220174e-14\n", + "Constraint violation....: 2.9103830456733704e-11 5.8207660913467407e-11\n", + "Complementarity.........: 2.5059035597432385e-09 2.5059035597432385e-09\n", + "Overall NLP error.......: 2.5059035597432385e-09 2.5059035597432385e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 36\n", + "Number of objective gradient evaluations = 36\n", + "Number of equality constraint evaluations = 36\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 36\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 35\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.090\n", + "Total CPU secs in NLP function evaluations = 0.019\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.70e-02 3.43e+02 -1.0 2.83e+01 - 2.90e-01 9.98e-01h 1\n", + " 4 0.0000000e+00 7.99e-08 2.33e+02 -1.0 4.00e-02 - 9.91e-01 1.00e+00h 1\n", + " 5 0.0000000e+00 2.63e-13 1.00e-06 -1.0 7.80e-08 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.2874055091167042e-13 2.6290081223123707e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.2874055091167042e-13 2.6290081223123707e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.048\n", + "Total CPU secs in NLP function evaluations = 0.031\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.32e+05 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 3.91e+03 3.85e+02 -1.0 3.32e+05 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.29e+02 5.99e+01 -1.0 4.18e+03 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.58e+00 2.06e+00 -1.0 8.61e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.56e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393774)\n", + " 5 0.0000000e+00 1.82e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8189894035458565e-12 1.8189894035458565e-12\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8189894035458565e-12 1.8189894035458565e-12\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", + "Total CPU secs in NLP function evaluations = 0.017\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -3.5209502e+01 8.42e+02 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303016)\n", + " 1 -3.5212641e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", + " 2 -3.5215292e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -3.5215089e+01 2.27e-01 8.53e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -3.5214101e+01 5.57e+00 9.59e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -3.5214161e+01 7.15e+00 6.15e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -3.5214294e+01 1.06e-02 4.14e-04 -1.7 9.34e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -3.5214295e+01 7.51e-07 1.89e-05 -3.8 1.17e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -3.5214300e+01 1.80e-03 1.13e-05 -5.7 1.27e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (327848)\n", + " 9 -3.5214301e+01 6.97e-07 4.87e-06 -5.7 4.87e-02 -4.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -3.5214302e+01 7.02e-06 4.97e-06 -8.6 1.49e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 11 -3.5214305e+01 6.46e-05 5.02e-06 -8.6 4.52e-01 -5.0 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (348486)\n", + " 12 -3.5214313e+01 5.82e-04 5.03e-06 -8.6 1.36e+00 -5.4 1.00e+00 1.00e+00h 1\n", + " 13 -3.5214337e+01 4.65e-03 5.02e-06 -8.6 4.07e+00 -5.9 1.00e+00 9.40e-01h 1\n", + " 14 -3.5214337e+01 4.50e-03 2.33e-04 -8.6 1.47e+00 -6.4 1.00e+00 3.12e-02f 6\n", + " 15 -3.5214341e+01 1.09e-03 3.28e-05 -8.6 6.15e-01 -6.9 1.00e+00 1.00e+00h 1\n", + " 16 -3.5214353e+01 9.95e-03 2.09e-05 -8.6 1.69e+00 -7.3 1.00e+00 1.00e+00h 1\n", + " 17 -3.5214394e+01 1.07e-01 2.26e-04 -8.6 4.92e+00 -7.8 1.00e+00 1.00e+00h 1\n", + " 18 -3.5214572e+01 3.42e+00 7.71e-03 -8.6 1.68e+01 -8.3 1.00e+00 1.00e+00h 1\n", + " 19 -3.5214789e+01 1.03e+00 2.63e-03 -8.6 2.34e+01 -7.9 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -3.5215305e+01 8.47e+00 3.52e-02 -8.6 5.34e+02 -8.3 2.91e-01 1.01e-01h 1\n", + " 21 -3.5215730e+01 6.31e+00 2.51e-02 -8.6 7.99e+01 -7.9 1.00e+00 3.57e-01f 1\n", + " 22 -3.5216694e+01 1.02e+01 5.63e-02 -8.6 7.73e+02 -8.4 3.55e-01 7.78e-02h 1\n", + " 23 -3.5216797e+01 9.76e+00 5.36e-02 -8.6 1.42e+02 -8.9 1.04e-01 4.84e-02h 1\n", + " 24 -3.5216885e+01 8.53e+00 4.68e-02 -8.6 2.74e+01 -8.4 5.30e-01 1.28e-01h 1\n", + " 25 -3.5217124e+01 6.99e+00 3.66e-02 -8.6 5.63e+01 -8.9 3.25e-01 2.16e-01h 1\n", + " 26 -3.5217494e+01 4.51e-01 1.53e-03 -8.6 1.69e+01 -8.5 1.00e+00 9.89e-01f 1\n", + " 27 -3.5217762e+01 3.34e+01 5.83e-01 -8.6 2.98e+02 -9.0 3.79e-01 5.84e-01f 1\n", + " 28 -3.5217782e+01 3.08e+01 5.37e-01 -8.6 9.68e+01 -8.5 5.35e-01 8.04e-02h 1\n", + " 29 -3.5215828e+01 2.37e+01 4.05e-01 -8.6 4.07e+01 -8.1 2.51e-02 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -3.5216161e+01 1.84e+01 3.12e-01 -8.6 2.64e+01 -8.6 8.03e-01 2.30e-01h 1\n", + " 31 -3.5217419e+01 3.16e+00 2.96e-02 -8.6 2.66e+01 -9.1 1.20e-04 1.00e+00f 1\n", + " 32 -3.5217481e+01 3.12e+00 2.90e-02 -8.6 1.92e+02 -9.6 4.18e-01 3.25e-02h 1\n", + " 33 -3.5217730e+01 3.96e+00 6.86e-02 -8.6 1.96e+02 -10.0 2.65e-07 1.67e-01h 1\n", + " 34 -3.5218174e+01 1.05e+01 5.09e-02 -8.6 6.76e+01 - 4.79e-01 1.00e+00f 1\n", + " 35 -3.5218144e+01 9.56e+00 4.62e-02 -8.6 5.60e+02 - 6.27e-01 9.14e-02h 1\n", + " 36 -3.5217875e+01 1.29e-01 6.80e-03 -8.6 1.14e+01 - 1.00e+00 1.00e+00h 1\n", + " 37 -3.5217899e+01 1.43e-02 9.14e-05 -8.6 2.93e+00 - 1.00e+00 1.00e+00h 1\n", + " 38 -3.5217899e+01 1.12e-05 9.11e-08 -8.6 7.12e-02 - 1.00e+00 1.00e+00h 1\n", + " 39 -3.5217899e+01 5.82e-11 8.02e-14 -8.6 6.30e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 39\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -3.5217898835055578e+01 -3.5217898835055578e+01\n", + "Dual infeasibility......: 8.0154814536833473e-14 8.0154814536833473e-14\n", + "Constraint violation....: 5.8207660913467407e-11 5.8207660913467407e-11\n", + "Complementarity.........: 2.5059035610674620e-09 2.5059035610674620e-09\n", + "Overall NLP error.......: 2.5059035610674620e-09 2.5059035610674620e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 45\n", + "Number of objective gradient evaluations = 40\n", + "Number of equality constraint evaluations = 45\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 40\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 39\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.271\n", + "Total CPU secs in NLP function evaluations = 0.044\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 4.2\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.93e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.18e-01 3.44e+02 -1.0 2.83e+01 - 2.89e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 7.85e-11 1.38e+02 -1.0 8.41e-02 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.8493656019418268e-11 7.8493656019418268e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.8493656019418268e-11 7.8493656019418268e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.062\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.64e+05 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 7.23e+03 3.85e+02 -1.0 6.64e+05 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.62e+02 5.99e+01 -1.0 7.51e+03 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.91e+00 2.06e+00 -1.0 9.36e+01 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.89e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393697)\n", + " 5 0.0000000e+00 7.28e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.2759576141834259e-12 7.2759576141834259e-12\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.2759576141834259e-12 7.2759576141834259e-12\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -3.7986293e+01 8.42e+02 1.03e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303122)\n", + " 1 -3.7987862e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", + " 2 -3.7989187e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -3.7989086e+01 2.27e-01 8.49e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -3.7988591e+01 5.57e+00 8.46e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -3.7988622e+01 7.15e+00 3.66e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -3.7988688e+01 1.06e-02 4.07e-04 -1.7 9.34e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -3.7988689e+01 1.02e-06 1.41e-05 -3.8 1.65e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -3.7988690e+01 4.48e-04 5.42e-06 -5.7 6.35e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (324149)\n", + " 9 -3.7988690e+01 1.84e-07 2.46e-06 -5.7 2.46e-02 -4.0 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -3.7988690e+01 1.76e-06 2.49e-06 -8.6 7.46e-02 -4.5 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (343489)\n", + " 11 -3.7988691e+01 1.62e-05 2.51e-06 -8.6 2.26e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 12 -3.7988693e+01 1.46e-04 2.51e-06 -8.6 6.79e-01 -5.4 1.00e+00 1.00e+00h 1\n", + " 13 -3.7988699e+01 1.31e-03 2.51e-06 -8.6 2.04e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 14 -3.7988708e+01 3.29e-03 2.51e-06 -8.6 6.08e+00 -6.4 1.00e+00 4.72e-01h 1\n", + " 15 -3.7988708e+01 2.88e-03 9.75e-05 -8.6 7.36e-01 -6.9 1.00e+00 1.25e-01f 4\n", + " 16 -3.7988711e+01 2.52e-03 2.24e-05 -8.6 9.76e-01 -7.3 1.00e+00 1.00e+00h 1\n", + " 17 -3.7988721e+01 2.30e-02 2.42e-05 -8.6 2.53e+00 -7.8 1.00e+00 1.00e+00h 1\n", + " 18 -3.7988753e+01 2.83e-01 2.94e-04 -8.6 7.23e+00 -8.3 1.00e+00 1.00e+00h 1\n", + " 19 -3.7988768e+01 4.05e-02 4.12e-05 -8.6 1.67e+00 -7.9 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -3.7988818e+01 6.38e-01 6.02e-04 -8.6 6.87e+00 -8.3 1.00e+00 1.00e+00h 1\n", + " 21 -3.7988847e+01 1.12e-01 1.12e-04 -8.6 4.05e+00 -7.9 1.00e+00 1.00e+00h 1\n", + " 22 -3.7988962e+01 2.54e+00 4.68e-03 -8.6 1.86e+01 -8.4 1.00e+00 1.00e+00h 1\n", + " 23 -3.7989078e+01 7.34e-01 8.67e-04 -8.6 2.48e+01 -8.0 1.00e+00 1.00e+00h 1\n", + " 24 -3.7989232e+01 2.08e+00 3.41e-03 -8.6 1.45e+02 -8.4 1.00e+00 2.09e-01h 1\n", + " 25 -3.7989337e+01 1.43e+00 2.58e-03 -8.6 3.34e+01 -8.0 1.00e+00 4.49e-01f 1\n", + " 26 -3.7989784e+01 5.92e+00 1.95e-02 -8.6 1.61e+02 -8.5 1.00e+00 3.75e-01f 1\n", + " 27 -3.7990124e+01 2.81e+00 9.84e-03 -8.6 4.53e+01 -8.1 1.00e+00 6.70e-01f 1\n", + " 28 -3.7990143e+01 1.18e+00 3.83e-03 -8.6 1.17e+01 -8.5 1.00e+00 6.36e-01f 1\n", + " 29 -3.7990260e+01 5.81e-01 1.51e-03 -8.6 2.24e+01 -9.0 1.00e+00 6.81e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -3.7990293e+01 3.41e-02 1.10e-04 -8.6 6.65e+00 -8.6 1.00e+00 1.00e+00f 1\n", + " 31 -3.7990329e+01 1.38e-01 1.24e-03 -8.6 1.50e+01 -9.1 1.00e+00 1.00e+00h 1\n", + " 32 -3.7990335e+01 1.01e-01 8.90e-04 -8.6 9.80e+00 -8.7 1.00e+00 3.33e-01h 1\n", + " 33 -3.7990393e+01 2.39e+00 2.02e-02 -8.6 5.51e+01 -9.1 1.00e+00 7.80e-01f 1\n", + " 34 -3.7990507e+01 4.27e+00 1.27e-02 -8.6 7.38e+01 -9.6 1.00e+00 7.82e-01h 1\n", + " 35 -3.7990474e+01 4.87e-02 8.37e-04 -8.6 1.92e+01 -9.2 1.00e+00 1.00e+00h 1\n", + " 36 -3.7990485e+01 2.85e-01 3.77e-04 -8.6 6.89e+01 -9.7 1.00e+00 1.00e+00h 1\n", + " 37 -3.7990486e+01 2.82e-01 3.75e-04 -8.6 4.06e+02 -10.1 1.00e+00 1.75e-02h 1\n", + " 38 -3.7990487e+01 5.77e-04 7.14e-07 -8.6 6.52e-01 - 1.00e+00 1.00e+00h 1\n", + " 39 -3.7990487e+01 1.03e-05 3.01e-08 -8.6 4.89e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 -3.7990487e+01 1.16e-10 1.03e-13 -8.6 7.76e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 40\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -3.7990486683995655e+01 -3.7990486683995655e+01\n", + "Dual infeasibility......: 1.0349462628516265e-13 1.0349462628516265e-13\n", + "Constraint violation....: 2.5821123017522041e-11 1.1641532182693481e-10\n", + "Complementarity.........: 2.5059035596820578e-09 2.5059035596820578e-09\n", + "Overall NLP error.......: 2.5059035596820578e-09 2.5059035596820578e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 44\n", + "Number of objective gradient evaluations = 41\n", + "Number of equality constraint evaluations = 44\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 41\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 40\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.453\n", + "Total CPU secs in NLP function evaluations = 0.019\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 4.5\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.93e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.16e-01 3.45e+02 -1.0 2.83e+01 - 2.89e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 7.46e-11 6.85e+01 -1.0 8.27e-02 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 7.4614092682168121e-11 7.4614092682168121e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 7.4614092682168121e-11 7.4614092682168121e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.064\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.33e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 1.39e+04 3.85e+02 -1.0 1.33e+06 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 2.29e+02 5.99e+01 -1.0 1.42e+04 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 5.56e+00 2.06e+00 -1.0 1.16e+02 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 4.54e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (394246)\n", + " 5 0.0000000e+00 2.33e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.3283064365386963e-10 2.3283064365386963e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.3283064365386963e-10 2.3283064365386963e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.108\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -4.0760980e+01 8.42e+02 1.02e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303234)\n", + " 1 -4.0761764e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", + " 2 -4.0762427e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -4.0762376e+01 2.27e-01 8.49e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -4.0762129e+01 5.57e+00 7.90e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -4.0762144e+01 7.15e+00 3.34e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -4.0762177e+01 1.06e-02 4.09e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -4.0762177e+01 1.17e-06 1.27e-05 -3.8 1.89e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -4.0762177e+01 1.11e-04 2.70e-06 -5.7 3.17e-01 - 1.00e+00 1.00e+00h 1\n", + " 9 -4.0762222e+01 5.53e-01 1.52e-03 -5.7 2.86e+01 - 1.00e+00 1.00e+00H 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -4.0762239e+01 1.77e-01 2.60e-03 -5.7 5.61e+01 - 1.00e+00 2.50e-01h 3\n", + " 11 -4.0762241e+01 3.40e-04 3.60e-05 -5.7 3.60e-01 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -4.0762241e+01 2.26e-07 8.96e-07 -5.7 2.69e-02 -4.5 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319066)\n", + " 13 -4.0762540e+01 3.15e+01 1.26e-01 -8.6 1.14e+02 - 3.56e-01 1.00e+00h 1\n", + " 14 -4.0763467e+01 6.08e+01 2.43e-01 -8.6 1.29e+04 - 2.22e-02 2.26e-02h 1\n", + " 15 -4.0763784e+01 2.63e+01 3.51e-02 -8.6 1.44e+02 - 4.76e-01 1.00e+00h 1\n", + " 16 -4.0763958e+01 8.50e-01 4.67e-03 -8.6 7.67e+01 - 6.65e-01 1.00e+00h 1\n", + " 17 -4.0764005e+01 2.35e+00 2.00e-03 -8.6 1.84e+02 - 6.15e-01 6.58e-01h 1\n", + " 18 -4.0764023e+01 3.56e-02 1.49e-04 -8.6 5.80e+00 - 1.00e+00 1.00e+00h 1\n", + " 19 -4.0764023e+01 3.49e-05 5.34e-08 -8.6 5.34e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -4.0764023e+01 3.10e-09 4.31e-12 -8.6 5.03e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 20\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -4.0764023387128162e+01 -4.0764023387128162e+01\n", + "Dual infeasibility......: 4.3057665671855009e-12 4.3057665671855009e-12\n", + "Constraint violation....: 3.0985215504486519e-09 3.0985215504486519e-09\n", + "Complementarity.........: 2.5059046339081401e-09 2.5059046339081401e-09\n", + "Overall NLP error.......: 3.0985215504486519e-09 3.0985215504486519e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 25\n", + "Number of objective gradient evaluations = 21\n", + "Number of equality constraint evaluations = 25\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 21\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 20\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.467\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.4\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.25e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 5.78e+01 3.85e+02 -1.0 3.25e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 2.70e+01 4.60e+02 -1.0 7.21e+01 - 5.56e-02 9.90e-01h 1\n", + " 3 0.0000000e+00 1.18e-01 1.30e+02 -1.0 1.54e+01 - 4.83e-01 1.00e+00f 1\n", + " 4 0.0000000e+00 2.62e-10 5.01e+01 -1.0 5.82e-02 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.6183499812759692e-10 2.6183499812759692e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.6183499812759692e-10 2.6183499812759692e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.041\n", + "Total CPU secs in NLP function evaluations = 0.028\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.66e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 2.72e+04 3.85e+02 -1.0 2.66e+06 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 3.62e+02 5.99e+01 -1.0 2.75e+04 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 6.88e+00 2.06e+00 -1.0 2.49e+02 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 5.86e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393945)\n", + " 5 0.0000000e+00 4.66e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.6566128730773926e-10 4.6566128730773926e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.6566128730773926e-10 4.6566128730773926e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.118\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -4.3535091e+01 8.42e+02 1.01e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303234)\n", + " 1 -4.3535483e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -4.3535814e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -4.3535789e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -4.3535665e+01 5.57e+00 7.62e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -4.3535673e+01 7.15e+00 3.19e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -4.3535690e+01 1.06e-02 4.10e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -4.3535690e+01 1.25e-06 1.39e-05 -3.8 2.01e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -4.3535690e+01 7.45e-09 4.81e-07 -5.7 4.81e-03 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -4.3535690e+01 1.10e-07 6.22e-07 -8.6 1.86e-02 -4.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -4.3535690e+01 1.02e-06 6.29e-07 -8.6 5.66e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 11 -4.3535690e+01 9.13e-06 6.29e-07 -8.6 1.70e-01 -5.4 1.00e+00 1.00e+00h 1\n", + " 12 -4.3535690e+01 8.21e-05 6.29e-07 -8.6 5.09e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 13 -4.3535691e+01 7.36e-04 6.28e-07 -8.6 1.53e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 14 -4.3535694e+01 4.46e-03 6.23e-07 -8.6 4.53e+00 -6.9 1.00e+00 8.17e-01h 1\n", + " 15 -4.3535694e+01 3.40e-03 2.22e-05 -8.6 1.51e+00 -7.3 1.00e+00 2.50e-01f 3\n", + " 16 -4.3535694e+01 6.98e-05 3.89e-07 -8.6 4.14e-01 -6.9 1.00e+00 1.00e+00h 1\n", + " 17 -4.3535695e+01 1.95e-04 1.16e-07 -8.6 3.13e-01 -7.4 1.00e+00 1.00e+00h 1\n", + " 18 -4.3535695e+01 1.68e-03 4.37e-07 -8.6 7.09e-01 -7.9 1.00e+00 1.00e+00h 1\n", + " 19 -4.3535696e+01 2.35e-04 6.20e-08 -8.6 2.55e-01 -7.4 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (335313)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -4.3535696e+01 2.19e-03 5.77e-07 -8.6 7.85e-01 -7.9 1.00e+00 1.00e+00h 1\n", + " 21 -4.3535699e+01 2.12e-02 5.60e-06 -8.6 2.33e+00 -8.4 1.00e+00 1.00e+00h 1\n", + " 22 -4.3535706e+01 2.57e-01 6.66e-05 -8.6 6.62e+00 -8.9 1.00e+00 1.00e+00h 1\n", + " 23 -4.3535710e+01 3.67e-02 9.31e-06 -8.6 1.58e+00 -8.4 1.00e+00 1.00e+00h 1\n", + " 24 -4.3535722e+01 5.54e-01 1.31e-04 -8.6 6.37e+00 -8.9 1.00e+00 1.00e+00h 1\n", + " 25 -4.3535728e+01 9.45e-02 2.27e-05 -8.6 3.44e+00 -8.5 1.00e+00 1.00e+00h 1\n", + " 26 -4.3535753e+01 1.95e+00 8.61e-04 -8.6 1.60e+01 -9.0 1.00e+00 1.00e+00h 1\n", + " 27 -4.3535776e+01 5.09e-01 1.62e-04 -8.6 1.94e+01 -8.5 1.00e+00 1.00e+00h 1\n", + " 28 -4.3535823e+01 2.99e+00 1.35e-03 -8.6 9.76e+01 -9.0 1.00e+00 3.84e-01h 1\n", + " 29 -4.3535854e+01 1.72e+00 8.11e-04 -8.6 3.16e+01 -8.6 1.00e+00 5.32e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -4.3535966e+01 5.97e+00 4.83e-03 -8.6 1.46e+02 -9.1 1.00e+00 4.18e-01f 1\n", + " 31 -4.3536027e+01 6.62e+00 5.59e-03 -8.6 4.78e+03 -9.6 8.09e-02 5.49e-03h 1\n", + " 32 -4.3536055e+01 5.60e+00 4.51e-03 -8.6 8.68e+01 -10.0 3.39e-01 1.92e-01h 1\n", + " 33 -4.3536080e+01 2.83e+00 2.13e-03 -8.6 2.89e+01 -9.6 8.95e-01 5.28e-01h 1\n", + " 34 -4.3536087e+01 1.67e+00 1.24e-03 -8.6 1.23e+01 -9.2 1.00e+00 4.18e-01f 1\n", + " 35 -4.3536112e+01 1.12e+00 2.09e-03 -8.6 3.20e+01 -9.7 1.00e+00 1.00e+00f 1\n", + " 36 -4.3536116e+01 1.13e+00 2.04e-03 -8.6 9.56e+01 -10.1 1.00e+00 7.04e-02h 1\n", + " 37 -4.3536133e+01 1.45e+00 1.17e-03 -8.6 2.53e+01 -9.7 1.00e+00 1.00e+00f 1\n", + " 38 -4.3536137e+01 7.69e-01 2.36e-04 -8.6 5.00e+01 -10.2 1.00e+00 1.00e+00h 1\n", + " 39 -4.3536139e+01 6.87e-01 2.41e-04 -8.6 5.07e+02 -10.7 6.28e-01 1.78e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 -4.3536137e+01 4.16e-02 2.05e-05 -8.6 2.23e+01 - 1.00e+00 1.00e+00h 1\n", + " 41 -4.3536138e+01 2.47e-02 1.88e-05 -8.6 2.36e+01 - 1.00e+00 9.45e-01h 1\n", + " 42 -4.3536138e+01 1.80e-05 1.27e-08 -8.6 6.48e-01 - 1.00e+00 1.00e+00h 1\n", + " 43 -4.3536138e+01 1.79e-09 1.37e-12 -8.6 6.46e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 43\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -4.3536137623477664e+01 -4.3536137623477664e+01\n", + "Dual infeasibility......: 1.3656458789760815e-12 1.3656458789760815e-12\n", + "Constraint violation....: 1.7926176099081204e-09 1.7926176099081204e-09\n", + "Complementarity.........: 2.5060411067492794e-09 2.5060411067492794e-09\n", + "Overall NLP error.......: 2.5060411067492794e-09 2.5060411067492794e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 46\n", + "Number of objective gradient evaluations = 44\n", + "Number of equality constraint evaluations = 46\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 44\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 43\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.281\n", + "Total CPU secs in NLP function evaluations = 0.049\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 4.2\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.93e+01 3.85e+02 -1.0 3.96e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.51e+01 4.20e+01 -1.0 4.92e+01 - 4.96e-01 9.91e-01h 1\n", + " 3 0.0000000e+00 1.04e-01 3.48e+02 -1.0 2.82e+01 - 2.86e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 5.40e-11 1.66e+01 -1.0 7.42e-02 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.3969273494658410e-11 5.3969273494658410e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.3969273494658410e-11 5.3969273494658410e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.043\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.32e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 5.38e+04 3.85e+02 -1.0 5.32e+06 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 6.28e+02 5.99e+01 -1.0 5.40e+04 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 9.50e+00 2.06e+00 -1.0 5.15e+02 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 8.48e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393530)\n", + " 5 0.0000000e+00 1.16e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.1641532182693481e-10 1.1641532182693481e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.1641532182693481e-10 1.1641532182693481e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.016\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -4.6308203e+01 8.42e+02 1.01e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303016)\n", + " 1 -4.6308399e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -4.6308565e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -4.6308552e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -4.6308490e+01 5.57e+00 7.50e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -4.6308494e+01 7.15e+00 3.11e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -4.6308502e+01 1.06e-02 4.10e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -4.6308502e+01 1.29e-06 1.45e-05 -3.8 2.07e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -4.6308502e+01 2.79e-09 2.41e-07 -5.7 2.41e-03 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -4.6308502e+01 2.70e-08 3.11e-07 -8.6 9.33e-03 -4.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -4.6308502e+01 2.54e-07 3.15e-07 -8.6 2.83e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 11 -4.6308502e+01 2.28e-06 3.14e-07 -8.6 8.49e-02 -5.4 1.00e+00 1.00e+00h 1\n", + " 12 -4.6308503e+01 2.05e-05 3.14e-07 -8.6 2.55e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 13 -4.6308503e+01 1.84e-04 3.14e-07 -8.6 7.63e-01 -6.4 1.00e+00 1.00e+00h 1\n", + " 14 -4.6308504e+01 1.64e-03 3.12e-07 -8.6 2.28e+00 -6.9 1.00e+00 1.00e+00h 1\n", + " 15 -4.6308505e+01 3.08e-03 3.98e-07 -8.6 6.49e+00 -7.3 1.00e+00 3.96e-01h 1\n", + " 16 -4.6308505e+01 4.06e-04 1.16e-06 -8.6 5.34e-01 -7.8 1.00e+00 1.00e+00f 1\n", + "Reallocating memory for MA57: lfact (332229)\n", + " 17 -4.6308505e+01 3.58e-03 4.28e-07 -8.6 1.71e+00 -8.3 1.00e+00 1.00e+00h 1\n", + " 18 -4.6308507e+01 2.97e-02 3.87e-06 -8.6 2.87e+00 -8.8 1.00e+00 1.00e+00h 1\n", + " 19 -4.6308511e+01 3.82e-01 4.92e-05 -8.6 7.99e+00 -9.2 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -4.6308514e+01 5.59e-02 6.88e-06 -8.6 1.91e+00 -8.8 1.00e+00 1.00e+00h 1\n", + " 21 -4.6308521e+01 9.99e-01 1.26e-04 -8.6 9.30e+00 -9.3 1.00e+00 1.00e+00h 1\n", + " 22 -4.6308527e+01 1.97e-01 3.02e-05 -8.6 7.51e+00 -8.9 1.00e+00 1.00e+00h 1\n", + " 23 -4.6308550e+01 5.83e+00 1.53e-03 -8.6 3.22e+01 -9.4 1.00e+00 1.00e+00h 1\n", + " 24 -4.6308572e+01 3.03e+00 6.36e-04 -8.6 5.12e+01 -8.9 1.00e+00 6.43e-01h 1\n", + " 25 -4.6308591e+01 3.33e+00 7.08e-04 -8.6 1.77e+02 -9.4 1.00e+00 1.29e-01f 1\n", + " 26 -4.6308634e+01 1.98e+00 7.94e-04 -8.6 4.29e+01 -9.0 1.00e+00 1.00e+00f 1\n", + " 27 -4.6308670e+01 2.73e+00 1.19e-03 -8.6 1.96e+02 -9.5 1.00e+00 1.61e-01h 1\n", + " 28 -4.6308683e+01 2.71e+00 1.18e-03 -8.6 2.33e+02 -9.9 1.00e+00 4.70e-02h 1\n", + " 29 -4.6308696e+01 2.50e-01 9.00e-05 -8.6 9.45e+00 -9.5 8.17e-01 9.93e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -4.6308703e+01 2.04e-01 1.41e-04 -8.6 2.34e+01 -10.0 1.00e+00 5.79e-01f 1\n", + " 31 -4.6308703e+01 2.45e-02 1.55e-05 -8.6 6.94e+00 -9.6 1.00e+00 1.00e+00f 1\n", + " 32 -4.6308709e+01 8.74e-01 1.10e-03 -8.6 3.06e+01 -10.0 1.00e+00 9.86e-01h 1\n", + " 33 -4.6308713e+01 4.19e-01 1.63e-04 -8.6 1.23e+01 -9.6 1.00e+00 1.00e+00f 1\n", + " 34 -4.6308722e+01 1.83e+00 9.77e-04 -8.6 3.09e+01 -10.1 1.00e+00 1.00e+00h 1\n", + " 35 -4.6308726e+01 9.33e-01 1.76e-04 -8.6 6.82e+01 -10.6 1.00e+00 1.00e+00h 1\n", + " 36 -4.6308726e+01 8.58e-01 1.24e-04 -8.6 8.39e+02 -11.0 4.07e-01 8.08e-02h 1\n", + " 37 -4.6308725e+01 2.75e-02 9.18e-06 -8.6 1.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 38 -4.6308725e+01 9.21e-03 3.64e-06 -8.6 1.42e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 -4.6308725e+01 2.12e-05 8.21e-09 -8.6 7.01e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 -4.6308725e+01 1.86e-09 1.31e-13 -8.6 2.53e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 40\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -4.6308725472442092e+01 -4.6308725472442092e+01\n", + "Dual infeasibility......: 1.3063844228700835e-13 1.3063844228700835e-13\n", + "Constraint violation....: 9.3132257461547852e-10 1.8626451492309570e-09\n", + "Complementarity.........: 2.5059035596850455e-09 2.5059035596850455e-09\n", + "Overall NLP error.......: 2.5059035596850455e-09 2.5059035596850455e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 41\n", + "Number of objective gradient evaluations = 41\n", + "Number of equality constraint evaluations = 41\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 41\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 40\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.242\n", + "Total CPU secs in NLP function evaluations = 0.010\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 4.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.92e+01 3.85e+02 -1.0 3.96e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.51e+01 4.22e+01 -1.0 4.90e+01 - 4.96e-01 9.93e-01h 1\n", + " 3 0.0000000e+00 8.83e-02 3.52e+02 -1.0 2.82e+01 - 2.81e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 3.29e-11 8.00e+00 -1.0 6.29e-02 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 3.2869706956262235e-11 3.2869706956262235e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 3.2869706956262235e-11 3.2869706956262235e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.046\n", + "Total CPU secs in NLP function evaluations = 0.016\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.8\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.06e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 1.07e+05 3.85e+02 -1.0 1.06e+07 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.16e+03 5.99e+01 -1.0 1.07e+05 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.48e+01 2.06e+00 -1.0 1.05e+03 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 1.37e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393774)\n", + " 5 0.0000000e+00 2.33e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.3283064365386963e-10 2.3283064365386963e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.3283064365386963e-10 2.3283064365386963e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -4.9081053e+01 8.42e+02 1.01e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303140)\n", + " 1 -4.9081151e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -4.9081234e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -4.9081228e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -4.9081197e+01 5.57e+00 7.50e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -4.9081199e+01 7.15e+00 3.08e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -4.9081203e+01 1.06e-02 4.10e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -4.9081203e+01 1.31e-06 1.47e-05 -3.8 2.10e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -4.9081203e+01 1.70e-06 3.33e-07 -5.7 3.92e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (322057)\n", + " 9 -4.9081203e+01 1.16e-02 2.45e-05 -8.6 3.24e+00 - 9.81e-01 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -4.9081203e+01 2.03e-07 2.70e-07 -8.6 2.70e-03 -4.0 1.00e+00 1.00e+00h 1\n", + " 11 -4.9081203e+01 7.45e-09 1.57e-07 -8.6 4.71e-03 -4.5 1.00e+00 1.00e+00h 1\n", + " 12 -4.9081203e+01 6.33e-08 1.57e-07 -8.6 1.41e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 13 -4.9081203e+01 5.66e-07 1.57e-07 -8.6 4.24e-02 -5.4 1.00e+00 1.00e+00h 1\n", + " 14 -4.9081203e+01 5.09e-06 1.57e-07 -8.6 1.27e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 15 -4.9081203e+01 4.57e-05 1.57e-07 -8.6 3.81e-01 -6.4 1.00e+00 1.00e+00h 1\n", + " 16 -4.9081203e+01 4.07e-04 1.56e-07 -8.6 1.14e+00 -6.9 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (342868)\n", + " 17 -4.9081204e+01 3.47e-03 1.52e-07 -8.6 3.32e+00 -7.3 1.00e+00 1.00e+00h 1\n", + " 18 -4.9081204e+01 3.11e-03 3.19e-06 -8.6 4.30e+00 -7.8 1.00e+00 1.35e-01h 1\n", + " 19 -4.9081204e+01 7.01e-04 7.88e-07 -8.6 2.87e-01 -8.3 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -4.9081205e+01 6.81e-03 4.46e-07 -8.6 1.48e+00 -8.8 1.00e+00 1.00e+00h 1\n", + " 21 -4.9081206e+01 6.91e-02 4.53e-06 -8.6 4.12e+00 -9.2 1.00e+00 1.00e+00h 1\n", + " 22 -4.9081210e+01 1.25e+00 7.64e-05 -8.6 1.05e+01 -9.7 1.00e+00 1.00e+00h 1\n", + " 23 -4.9081212e+01 2.32e-01 1.39e-05 -8.6 6.13e+00 -9.3 1.00e+00 1.00e+00h 1\n", + " 24 -4.9081226e+01 1.28e+01 1.87e-03 -8.6 4.40e+01 -9.8 1.00e+00 1.00e+00h 1\n", + " 25 -4.9081236e+01 9.38e+00 1.30e-03 -8.6 9.23e+01 -9.4 1.00e+00 3.14e-01h 1\n", + " 26 -4.9081256e+01 1.10e+01 1.39e-03 -8.6 4.30e+02 -9.8 6.97e-01 1.11e-01f 1\n", + " 27 -4.9081286e+01 6.05e+00 8.65e-04 -8.6 8.29e+01 -9.4 1.00e+00 6.91e-01f 1\n", + " 28 -4.9081293e+01 1.88e+00 2.33e-04 -8.6 1.25e+01 -9.9 8.83e-01 7.46e-01f 1\n", + " 29 -4.9081301e+01 8.63e-01 1.23e-04 -8.6 2.66e+01 -10.4 1.00e+00 6.71e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -4.9081302e+01 4.34e-02 7.27e-06 -8.6 6.80e+00 -9.9 1.00e+00 1.00e+00f 1\n", + " 31 -4.9081305e+01 2.53e+00 1.66e-03 -8.6 5.25e+01 -10.4 1.00e+00 1.00e+00h 1\n", + " 32 -4.9081319e+01 1.27e+01 2.66e-03 -8.6 1.00e+02 -10.9 1.00e+00 8.30e-01h 1\n", + " 33 -4.9081310e+01 4.58e-01 2.81e-04 -8.6 2.59e+01 -10.5 1.00e+00 1.00e+00h 1\n", + " 34 -4.9081312e+01 3.50e-01 1.29e-04 -8.6 7.29e+01 -10.9 1.00e+00 6.14e-01h 1\n", + " 35 -4.9081313e+01 1.07e-01 8.13e-06 -8.6 1.93e+01 - 1.00e+00 1.00e+00f 1\n", + " 36 -4.9081313e+01 1.48e-02 3.65e-06 -8.6 1.78e+01 - 1.00e+00 1.00e+00h 1\n", + " 37 -4.9081313e+01 5.02e-05 1.04e-08 -8.6 1.08e+00 - 1.00e+00 1.00e+00h 1\n", + " 38 -4.9081313e+01 1.86e-09 3.39e-13 -8.6 6.17e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 38\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -4.9081313321398035e+01 -4.9081313321398035e+01\n", + "Dual infeasibility......: 3.3870588295113704e-13 3.3870588295113704e-13\n", + "Constraint violation....: 1.6578169947933930e-09 1.8626451492309570e-09\n", + "Complementarity.........: 2.5059035596847262e-09 2.5059035596847262e-09\n", + "Overall NLP error.......: 2.5059035596847262e-09 2.5059035596847262e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 39\n", + "Number of objective gradient evaluations = 39\n", + "Number of equality constraint evaluations = 39\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 39\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 38\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.199\n", + "Total CPU secs in NLP function evaluations = 0.015\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 4.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.94e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.91e+01 3.85e+02 -1.0 3.94e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.52e+01 4.24e+01 -1.0 4.87e+01 - 4.96e-01 9.95e-01h 1\n", + " 3 0.0000000e+00 5.64e-02 3.60e+02 -1.0 2.82e+01 - 2.71e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 8.55e-12 3.70e+00 -1.0 4.01e-02 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 8.5549345385516062e-12 8.5549345385516062e-12\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 8.5549345385516062e-12 8.5549345385516062e-12\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.053\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.13e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 2.13e+05 3.85e+02 -1.0 2.13e+07 - 2.54e-03 9.90e-01h 1\n", + " 2 0.0000000e+00 2.22e+03 5.99e+01 -1.0 2.14e+05 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 2.53e+01 2.06e+00 -1.0 2.11e+03 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 2.42e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393985)\n", + " 5 0.0000000e+00 4.66e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.6566128730773926e-10 4.6566128730773926e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.6566128730773926e-10 4.6566128730773926e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.110\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -5.1853772e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303252)\n", + " 1 -5.1853821e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -5.1853862e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -5.1853859e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -5.1853844e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -5.1853845e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -5.1853847e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -5.1853847e+01 1.32e-06 1.49e-05 -3.8 2.12e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -5.1853847e+01 7.45e-09 6.02e-08 -5.7 6.02e-04 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -5.1853847e+01 7.45e-09 7.78e-08 -8.6 2.33e-03 -4.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -5.1853847e+01 1.86e-08 7.86e-08 -8.6 7.08e-03 -5.0 1.00e+00 1.00e+00h 1\n", + " 11 -5.1853847e+01 1.42e-07 7.86e-08 -8.6 2.12e-02 -5.4 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (327115)\n", + " 12 -5.1853847e+01 1.28e-06 7.86e-08 -8.6 6.37e-02 -5.9 1.00e+00 1.00e+00h 1\n", + " 13 -5.1853847e+01 1.15e-05 7.85e-08 -8.6 1.91e-01 -6.4 1.00e+00 1.00e+00h 1\n", + " 14 -5.1853847e+01 1.03e-04 7.82e-08 -8.6 5.70e-01 -6.9 1.00e+00 1.00e+00h 1\n", + " 15 -5.1853847e+01 8.97e-04 7.70e-08 -8.6 1.68e+00 -7.3 1.00e+00 1.00e+00h 1\n", + " 16 -5.1853847e+01 1.50e-03 1.82e-07 -8.6 4.60e+00 -7.8 1.00e+00 3.75e-01h 2\n", + " 17 -5.1853847e+01 1.53e-03 1.58e-06 -8.6 6.12e+00 -8.3 1.00e+00 1.44e-01h 2\n", + " 18 -5.1853847e+01 1.32e-03 1.57e-06 -8.6 1.69e+00 -8.8 1.00e+00 4.38e-01h 2\n", + "Reallocating memory for MA57: lfact (345657)\n", + " 19 -5.1853848e+01 1.70e-02 1.12e-06 -8.6 2.40e+00 -9.2 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -5.1853848e+01 1.75e-01 5.67e-06 -8.6 6.21e+00 -9.7 1.00e+00 1.00e+00h 1\n", + " 21 -5.1853853e+01 1.96e+01 1.30e-03 -8.6 4.77e+01 -10.2 1.00e+00 1.00e+00h 1\n", + " 22 -5.1853862e+01 1.44e+01 8.05e-04 -8.6 1.50e+02 -9.8 1.00e+00 4.12e-01h 1\n", + " 23 -5.1853873e+01 1.77e+01 9.19e-04 -8.6 4.63e+03 -10.3 6.40e-02 1.19e-02h 1\n", + " 24 -5.1853883e+01 1.46e+01 4.64e-02 -8.6 1.25e+02 -10.7 1.00e+00 2.45e-01h 1\n", + " 25 -5.1853894e+01 1.55e+00 9.50e-01 -8.6 3.86e+01 -10.3 6.08e-02 1.00e+00h 1\n", + " 26 -5.1853897e+01 3.12e-01 2.79e-01 -8.6 5.18e+01 -10.8 1.00e+00 7.06e-01H 1\n", + " 27 -5.1853898e+01 3.16e-01 5.81e-05 -8.6 1.47e+01 -10.4 1.00e+00 1.00e+00f 1\n", + " 28 -5.1853901e+01 2.65e+00 3.38e-04 -8.6 3.87e+01 -10.8 1.00e+00 1.00e+00h 1\n", + " 29 -5.1853901e+01 1.04e+00 9.14e-05 -8.6 1.20e+02 -11.3 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -5.1853901e+01 1.15e-02 1.39e-06 -8.6 1.55e+00 - 1.00e+00 1.00e+00h 1\n", + " 31 -5.1853901e+01 4.45e-06 6.79e-10 -8.6 1.25e-01 - 1.00e+00 1.00e+00h 1\n", + " 32 -5.1853901e+01 3.73e-09 2.52e-14 -8.6 2.14e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 32\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -5.1853901170234600e+01 -5.1853901170234600e+01\n", + "Dual infeasibility......: 2.5166233628543340e-14 2.5166233628543340e-14\n", + "Constraint violation....: 4.6566128730773926e-10 3.7252902984619141e-09\n", + "Complementarity.........: 2.5059035596808703e-09 2.5059035596808703e-09\n", + "Overall NLP error.......: 2.5059035596808703e-09 3.7252902984619141e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 44\n", + "Number of objective gradient evaluations = 33\n", + "Number of equality constraint evaluations = 44\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 33\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 32\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.946\n", + "Total CPU secs in NLP function evaluations = 0.023\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.8\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.89e+01 3.85e+02 -1.0 3.92e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.52e+01 4.30e+01 -1.0 4.82e+01 - 4.96e-01 1.00e+00h 1\n", + " 3 0.0000000e+00 4.26e-04 3.75e+02 -1.0 2.80e+01 - 2.55e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 2.52e-13 3.50e+00 -1.0 1.87e-04 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.0465496681718326e-13 2.5224267119483557e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.0465496681718326e-13 2.5224267119483557e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.047\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.8\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 4.26e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 4.26e+05 3.85e+02 -1.0 4.26e+07 - 2.54e-03 9.90e-01h 1\n", + " 2 0.0000000e+00 4.35e+03 5.99e+01 -1.0 4.26e+05 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.63e+01 2.06e+00 -1.0 4.24e+03 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 4.52e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393567)\n", + " 5 0.0000000e+00 9.31e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.3132257461547852e-10 9.3132257461547852e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.3132257461547852e-10 9.3132257461547852e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.113\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -5.4626425e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303140)\n", + " 1 -5.4626450e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -5.4626470e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -5.4626469e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -5.4626461e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -5.4626462e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -5.4626463e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -5.4626463e+01 1.33e-06 1.50e-05 -3.8 2.12e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -5.4626463e+01 7.45e-09 3.01e-08 -5.7 3.01e-04 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -5.4626463e+01 7.31e-04 4.97e-06 -8.6 8.12e-01 - 9.96e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (323556)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -5.4626463e+01 7.45e-09 3.51e-08 -8.6 1.05e-03 -4.5 1.00e+00 1.00e+00h 1\n", + " 11 -5.4626463e+01 7.45e-09 3.93e-08 -8.6 3.53e-03 -5.0 1.00e+00 1.00e+00h 1\n", + " 12 -5.4626463e+01 3.73e-08 3.93e-08 -8.6 1.06e-02 -5.4 1.00e+00 1.00e+00h 1\n", + " 13 -5.4626463e+01 3.20e-07 3.92e-08 -8.6 3.18e-02 -5.9 1.00e+00 1.00e+00h 1\n", + " 14 -5.4626463e+01 2.87e-06 3.92e-08 -8.6 9.52e-02 -6.4 1.00e+00 1.00e+00h 1\n", + " 15 -5.4626463e+01 2.56e-05 3.90e-08 -8.6 2.84e-01 -6.9 1.00e+00 1.00e+00h 1\n", + " 16 -5.4626463e+01 2.24e-04 3.85e-08 -8.6 8.42e-01 -7.3 1.00e+00 1.00e+00h 1\n", + " 17 -5.4626463e+01 1.80e-03 3.64e-08 -8.6 2.39e+00 -7.8 1.00e+00 1.00e+00h 1\n", + " 18 -5.4626463e+01 1.75e-03 4.42e-07 -8.6 4.44e+00 -8.3 1.00e+00 2.55e-01h 2\n", + " 19 -5.4626463e+01 1.22e-03 7.37e-07 -8.6 1.65e+00 -8.8 1.00e+00 4.26e-01h 2\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -5.4626463e+01 3.93e-03 2.60e-07 -8.6 1.20e+00 -9.2 1.00e+00 1.00e+00h 1\n", + " 21 -5.4626463e+01 3.61e-02 5.90e-07 -8.6 3.14e+00 -9.7 1.00e+00 1.00e+00h 1\n", + " 22 -5.4626464e+01 4.44e-01 7.03e-06 -8.6 8.61e+00 -10.2 1.00e+00 1.00e+00h 1\n", + " 23 -5.4626464e+01 6.25e-02 9.33e-07 -8.6 2.01e+00 -9.8 1.00e+00 1.00e+00h 1\n", + " 24 -5.4626465e+01 1.08e+00 1.99e-05 -8.6 9.96e+00 -10.3 1.00e+00 1.00e+00h 1\n", + " 25 -5.4626466e+01 2.09e-01 4.63e-06 -8.6 8.06e+00 -9.8 1.00e+00 1.00e+00h 1\n", + " 26 -5.4626469e+01 6.30e+00 2.33e-04 -8.6 3.45e+01 -10.3 1.00e+00 1.00e+00h 1\n", + " 27 -5.4626473e+01 1.97e+00 5.73e-05 -8.6 4.80e+01 -9.9 1.00e+00 1.00e+00h 1\n", + " 28 -5.4626482e+01 8.48e+00 4.36e-04 -8.6 1.83e+02 -10.4 1.00e+00 4.10e-01h 1\n", + " 29 -5.4626483e+01 7.19e+00 3.68e-04 -8.6 3.53e+01 -10.8 1.00e+00 1.56e-01f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -5.4626486e+01 2.22e-01 2.33e-05 -8.6 6.24e+00 -10.4 5.58e-01 1.00e+00f 1\n", + " 31 -5.4626486e+01 1.20e-01 1.81e-05 -8.6 1.55e+01 -10.9 1.00e+00 1.00e+00h 1\n", + " 32 -5.4626486e+01 1.29e-02 4.92e-07 -8.6 3.51e+00 -10.5 1.00e+00 1.00e+00h 1\n", + " 33 -5.4626487e+01 2.08e-01 3.17e-05 -8.6 1.49e+01 -10.9 1.00e+00 1.00e+00h 1\n", + " 34 -5.4626487e+01 8.32e-02 7.55e-06 -8.6 7.39e+00 -10.5 1.00e+00 1.00e+00h 1\n", + " 35 -5.4626488e+01 2.61e+00 2.60e-04 -8.6 4.11e+01 -11.0 1.00e+00 1.00e+00h 1\n", + " 36 -5.4626489e+01 2.50e+00 5.32e-05 -8.6 7.17e+01 -11.5 1.00e+00 1.00e+00h 1\n", + " 37 -5.4626489e+01 1.89e+00 4.09e-05 -8.6 2.88e+02 -11.9 1.00e+00 2.43e-01h 1\n", + " 38 -5.4626489e+01 1.35e-02 1.91e-06 -8.6 1.74e+01 - 1.00e+00 1.00e+00h 1\n", + " 39 -5.4626489e+01 2.25e-03 9.41e-08 -8.6 6.88e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 40 -5.4626489e+01 1.34e-06 5.72e-11 -8.6 1.71e-01 - 1.00e+00 1.00e+00h 1\n", + " 41 -5.4626489e+01 1.49e-08 2.51e-14 -8.6 1.61e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 41\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -5.4626489018506717e+01 -5.4626489018506717e+01\n", + "Dual infeasibility......: 2.5104508813183050e-14 2.5104508813183050e-14\n", + "Constraint violation....: 9.3132257461547852e-10 1.4901161193847656e-08\n", + "Complementarity.........: 2.5059035596801395e-09 2.5059035596801395e-09\n", + "Overall NLP error.......: 2.5059035596801395e-09 1.4901161193847656e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 48\n", + "Number of objective gradient evaluations = 42\n", + "Number of equality constraint evaluations = 48\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 42\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 41\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.229\n", + "Total CPU secs in NLP function evaluations = 0.069\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.5\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.86e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.85e+01 3.85e+02 -1.0 3.86e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.41e+01 4.32e+01 -1.0 4.70e+01 - 4.96e-01 1.00e+00h 1\n", + " 3 0.0000000e+00 4.19e-04 3.70e+02 -1.0 2.74e+01 - 2.54e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 3.41e-13 3.45e+00 -1.0 1.89e-04 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.4150530724576891e-13 3.4106051316484809e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.4150530724576891e-13 3.4106051316484809e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.047\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.0\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 8.51e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 8.52e+05 3.85e+02 -1.0 8.51e+07 - 2.54e-03 9.90e-01h 1\n", + " 2 0.0000000e+00 8.61e+03 5.99e+01 -1.0 8.52e+05 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 8.83e+01 2.06e+00 -1.0 8.49e+03 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 8.73e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (394288)\n", + " 5 0.0000000e+00 4.66e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 4.6566128730773926e-10 4.6566128730773926e-10\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 4.6566128730773926e-10 4.6566128730773926e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.090\n", + "Total CPU secs in NLP function evaluations = 0.015\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -5.7399046e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303434)\n", + " 1 -5.7399058e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -5.7399068e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -5.7399068e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -5.7399064e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -5.7399064e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -5.7399065e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -5.7399065e+01 1.33e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -5.7399065e+01 1.49e-08 1.51e-08 -5.7 1.51e-04 -4.0 1.00e+00 1.00e+00h 1\n", + " 9 -5.7399065e+01 2.98e-08 1.94e-08 -8.6 5.83e-04 -4.5 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -5.7399065e+01 1.49e-08 1.97e-08 -9.0 1.77e-03 -5.0 1.00e+00 1.00e+00h 1\n", + " 11 -5.7399065e+01 2.98e-08 1.97e-08 -9.0 5.31e-03 -5.4 1.00e+00 1.00e+00h 1\n", + " 12 -5.7399065e+01 8.94e-08 1.97e-08 -9.0 1.59e-02 -5.9 1.00e+00 1.00e+00h 1\n", + " 13 -5.7399065e+01 7.15e-07 1.96e-08 -9.0 4.77e-02 -6.4 1.00e+00 1.00e+00h 1\n", + " 14 -5.7399065e+01 6.48e-06 1.96e-08 -9.0 1.43e-01 -6.9 1.00e+00 1.00e+00h 1\n", + " 15 -5.7399065e+01 5.78e-05 1.95e-08 -9.0 4.27e-01 -7.3 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (333906)\n", + " 16 -5.7399065e+01 5.04e-04 1.92e-08 -9.0 1.26e+00 -7.8 1.00e+00 1.00e+00h 1\n", + " 17 -5.7399065e+01 3.89e-03 1.78e-08 -9.0 3.51e+00 -8.3 1.00e+00 1.00e+00h 1\n", + " 18 -5.7399065e+01 3.09e-03 5.12e-07 -9.0 1.50e+00 -8.8 1.00e+00 2.16e-01h 2\n", + " 19 -5.7399065e+01 9.36e-04 9.20e-08 -9.0 5.07e-01 -9.2 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -5.7399065e+01 8.67e-03 7.11e-08 -9.0 1.60e+00 -9.7 1.00e+00 1.00e+00h 1\n", + " 21 -5.7399065e+01 8.90e-02 7.27e-07 -9.0 4.66e+00 -10.2 1.00e+00 1.00e+00h 1\n", + " 22 -5.7399065e+01 1.83e+00 1.34e-05 -9.0 1.12e+01 -10.7 1.00e+00 1.00e+00h 1\n", + " 23 -5.7399066e+01 3.81e-01 3.61e-06 -9.0 1.00e+01 -10.3 1.00e+00 1.00e+00h 1\n", + " 24 -5.7399069e+01 8.09e+00 2.59e-04 -9.0 7.69e+01 -10.7 9.52e-01 6.16e-01H 1\n", + " 25 -5.7399072e+01 3.81e+00 1.19e-04 -9.0 5.43e+01 -10.3 1.00e+00 7.55e-01f 1\n", + " 26 -5.7399075e+01 4.33e+00 1.32e-04 -9.0 2.22e+02 -10.8 1.00e+00 1.41e-01f 1\n", + " 27 -5.7399076e+01 1.97e+00 3.29e-05 -9.0 2.73e+01 -11.3 8.89e-01 7.54e-01f 1\n", + " 28 -5.7399077e+01 1.75e-01 1.41e-06 -9.0 1.54e+01 -10.8 1.00e+00 1.00e+00f 1\n", + " 29 -5.7399077e+01 9.22e-01 7.02e-05 -9.0 3.11e+01 -11.3 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -5.7399077e+01 4.41e-01 1.26e-05 -9.0 1.65e+01 -10.9 1.00e+00 1.00e+00h 1\n", + " 31 -5.7399078e+01 2.23e+00 7.37e-05 -9.0 3.40e+01 -11.4 1.00e+00 1.00e+00h 1\n", + " 32 -5.7399078e+01 6.05e-01 8.47e-06 -9.0 8.14e+01 -11.8 1.00e+00 1.00e+00h 1\n", + " 33 -5.7399078e+01 5.73e-01 8.79e-06 -9.0 3.08e+02 -12.3 1.00e+00 1.64e-01h 1\n", + " 34 -5.7399078e+01 1.59e-02 1.89e-07 -9.0 1.07e+01 - 1.00e+00 1.00e+00h 1\n", + " 35 -5.7399078e+01 4.00e-04 1.26e-08 -9.0 2.96e+00 - 1.00e+00 1.00e+00h 1\n", + " 36 -5.7399078e+01 4.81e-08 1.16e-12 -9.0 3.27e-02 - 1.00e+00 1.00e+00h 1\n", + " 37 -5.7399078e+01 1.49e-08 9.10e-15 -9.0 5.66e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 37\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -5.7399077980658021e+01 -5.7399077980658021e+01\n", + "Dual infeasibility......: 9.1002942970123576e-15 9.1002942970123576e-15\n", + "Constraint violation....: 1.8626451492309570e-09 1.4901161193847656e-08\n", + "Complementarity.........: 9.0909090909093753e-10 9.0909090909093753e-10\n", + "Overall NLP error.......: 1.8626451492309570e-09 1.4901161193847656e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 40\n", + "Number of objective gradient evaluations = 38\n", + "Number of equality constraint evaluations = 40\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 38\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 37\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.064\n", + "Total CPU secs in NLP function evaluations = 0.031\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.8\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.89e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.87e+01 3.85e+02 -1.0 3.89e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.47e+01 4.31e+01 -1.0 4.76e+01 - 4.96e-01 1.00e+00h 1\n", + " 3 0.0000000e+00 4.23e-04 3.73e+02 -1.0 2.77e+01 - 2.54e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 2.79e-13 3.48e+00 -1.0 1.88e-04 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.2337636129035084e-13 2.7888802378583932e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.2337636129035084e-13 2.7888802378583932e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.063\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.8\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.70e+08 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 1.70e+06 3.85e+02 -1.0 1.70e+08 - 2.54e-03 9.90e-01h 1\n", + " 2 0.0000000e+00 1.71e+04 5.99e+01 -1.0 1.70e+06 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.72e+02 2.06e+00 -1.0 1.70e+04 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 1.71e+02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393530)\n", + " 5 0.0000000e+00 4.55e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 5\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.3691704763652764e-13 4.5474735088646412e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.3691704763652764e-13 4.5474735088646412e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 6\n", + "Number of objective gradient evaluations = 6\n", + "Number of equality constraint evaluations = 6\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 6\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 5\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.115\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -6.0171651e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303252)\n", + " 1 -6.0171657e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -6.0171662e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -6.0171662e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -6.0171660e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -6.0171660e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -6.0171660e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -6.0171660e+01 1.34e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -6.0171660e+01 2.98e-08 2.02e-08 -5.7 1.92e-03 - 1.00e+00 1.00e+00h 1\n", + " 9 -6.0171660e+01 4.53e-05 2.16e-08 -8.6 2.02e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (326464)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -6.0171660e+01 2.98e-08 9.06e-09 -8.6 9.06e-05 -4.0 1.00e+00 1.00e+00h 1\n", + " 11 -6.0171660e+01 3.73e-09 9.82e-09 -8.6 2.94e-04 -4.5 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 11\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -6.0171659998267266e+01 -6.0171659998267266e+01\n", + "Dual infeasibility......: 9.8158985796691289e-09 9.8158985796691289e-09\n", + "Constraint violation....: 3.7252902984619141e-09 3.7252902984619141e-09\n", + "Complementarity.........: 2.5059035655454891e-09 2.5059035655454891e-09\n", + "Overall NLP error.......: 9.8158985796691289e-09 9.8158985796691289e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 12\n", + "Number of objective gradient evaluations = 12\n", + "Number of equality constraint evaluations = 12\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 12\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 11\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.265\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.55e+01 3.85e+02 -1.0 1.92e+02 - 2.55e-03 9.95e-01f 1\n", + " 2 0.0000000e+00 1.07e+01 4.90e+01 -1.0 1.71e+01 - 2.60e-01 1.00e+00h 1\n", + " 3 0.0000000e+00 4.19e-05 2.46e+01 -1.0 7.37e+00 - 5.90e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 2.27e-13 1.48e-01 -1.0 3.16e-05 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.1202303897534080e-13 2.2737367544323206e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.1202303897534080e-13 2.2737367544323206e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.057\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.9\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.40e+08 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 3.40e+06 3.85e+02 -1.0 3.40e+08 - 2.54e-03 9.90e-01h 1\n", + " 2 0.0000000e+00 3.41e+04 5.99e+01 -1.0 3.41e+06 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 3.40e+02 2.06e+00 -1.0 3.40e+04 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.39e+02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393908)\n", + " 5 0.0000000e+00 1.49e-08 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", + " 6 0.0000000e+00 4.55e-13 1.84e-11 -5.7 1.49e-08 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.8851038199681022e-14 4.5474735088646412e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.8851038199681022e-14 4.5474735088646412e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.120\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -6.2944244e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303034)\n", + " 1 -6.2944247e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -6.2944250e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -6.2944249e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -6.2944249e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -6.2944249e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -6.2944249e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -6.2944249e+01 1.31e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -6.2944249e+01 5.96e-08 1.04e-08 -5.7 6.73e-04 - 1.00e+00 1.00e+00h 1\n", + " 9 -6.2944249e+01 1.13e-05 1.08e-08 -8.6 1.01e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (326761)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -6.2944249e+01 5.96e-08 4.72e-09 -8.6 4.72e-05 -4.0 1.00e+00 1.00e+00h 1\n", + " 11 -6.2944249e+01 5.96e-08 4.91e-09 -9.0 1.47e-04 -4.5 1.00e+00 1.00e+00h 1\n", + " 12 -6.2944249e+01 1.49e-08 4.91e-09 -9.0 4.42e-04 -5.0 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 12\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -6.2944248720059186e+01 -6.2944248720059186e+01\n", + "Dual infeasibility......: 4.9123733168040214e-09 4.9123733168040214e-09\n", + "Constraint violation....: 7.4505805969238281e-09 1.4901161193847656e-08\n", + "Complementarity.........: 9.0909090909090920e-10 9.0909090909090920e-10\n", + "Overall NLP error.......: 7.4505805969238281e-09 1.4901161193847656e-08\n", + "\n", + "\n", + "Number of objective function evaluations = 13\n", + "Number of objective gradient evaluations = 13\n", + "Number of equality constraint evaluations = 13\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 13\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 12\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.286\n", + "Total CPU secs in NLP function evaluations = 0.017\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.55e+01 3.85e+02 -1.0 1.92e+02 - 2.55e-03 9.95e-01f 1\n", + " 2 0.0000000e+00 1.07e+01 4.90e+01 -1.0 1.71e+01 - 2.60e-01 1.00e+00h 1\n", + " 3 0.0000000e+00 4.17e-05 2.47e+01 -1.0 7.37e+00 - 5.89e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 3.41e-13 1.49e-01 -1.0 3.15e-05 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.6092568863958805e-13 3.4106051316484809e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.6092568863958805e-13 3.4106051316484809e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.064\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26424\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7092\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7092\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.81e+08 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (295725)\n", + " 1 0.0000000e+00 6.81e+06 3.85e+02 -1.0 6.81e+08 - 2.54e-03 9.90e-01h 1\n", + " 2 0.0000000e+00 6.82e+04 5.99e+01 -1.0 6.81e+06 - 1.29e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 6.77e+02 2.06e+00 -1.0 6.81e+04 - 9.84e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 3.11e-04 2.39e-04 -1.0 6.76e+02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (393607)\n", + " 5 0.0000000e+00 2.98e-08 1.50e-09 -3.8 3.15e-04 - 1.00e+00 1.00e+00h 1\n", + " 6 0.0000000e+00 4.55e-13 1.84e-11 -5.7 2.98e-08 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 6\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.7123678492091068e-14 4.5474735088646412e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.7123678492091068e-14 4.5474735088646412e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 7\n", + "Number of objective gradient evaluations = 7\n", + "Number of equality constraint evaluations = 7\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 7\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 6\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26544\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (273960)\n", + "Total number of variables............................: 7112\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7102\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -6.5716835e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303450)\n", + " 1 -6.5716837e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", + " 2 -6.5716838e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", + " 3 -6.5716838e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", + " 4 -6.5716837e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -6.5716837e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", + " 6 -6.5716837e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 7 -6.5716837e+01 1.43e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", + " 8 -6.5716837e+01 1.19e-07 6.81e-09 -5.7 2.30e-04 - 1.00e+00 1.00e+00h 1\n", + " 9 -6.5716837e+01 2.74e-06 5.39e-09 -8.6 5.05e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (321428)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -6.5716837e+01 1.19e-07 2.41e-09 -8.6 2.41e-05 -4.0 1.00e+00 1.00e+00h 1\n", + " 11 -6.5716837e+01 1.19e-07 2.45e-09 -8.6 7.36e-05 -4.5 1.00e+00 1.00e+00h 1\n", + " 12 -6.5716837e+01 1.19e-07 2.45e-09 -8.6 2.21e-04 -5.0 1.00e+00 1.00e+00h 1\n", + " 13 -6.5716837e+01 1.49e-08 2.45e-09 -8.6 6.62e-04 -5.4 1.00e+00 1.00e+00h 1\n", + " 14 -6.5716837e+01 1.19e-07 2.45e-09 -9.0 1.99e-03 -5.9 1.00e+00 1.00e+00h 1\n", + " 15 -6.5716837e+01 1.19e-07 2.45e-09 -9.0 5.96e-03 -6.4 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 15\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -6.5716837442211869e+01 -6.5716837442211869e+01\n", + "Dual infeasibility......: 2.4545255939761519e-09 2.4545255939761519e-09\n", + "Constraint violation....: 2.4652589872487225e-10 1.1920928955078125e-07\n", + "Complementarity.........: 9.0909090909090920e-10 9.0909090909090920e-10\n", + "Overall NLP error.......: 2.4545255939761519e-09 1.1920928955078125e-07\n", + "\n", + "\n", + "Number of objective function evaluations = 16\n", + "Number of objective gradient evaluations = 16\n", + "Number of equality constraint evaluations = 16\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 16\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 15\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.401\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 1.55e+01 3.85e+02 -1.0 1.92e+02 - 2.55e-03 9.95e-01f 1\n", + " 2 0.0000000e+00 1.07e+01 4.90e+01 -1.0 1.71e+01 - 2.60e-01 1.00e+00h 1\n", + " 3 0.0000000e+00 4.18e-05 2.47e+01 -1.0 7.37e+00 - 5.89e-01 1.00e+00h 1\n", + " 4 0.0000000e+00 2.57e-13 1.49e-01 -1.0 3.16e-05 - 9.91e-01 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.0672779846629121e-13 2.5723867480564877e-13\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.0672779846629121e-13 2.5723867480564877e-13\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.067\n", + "Total CPU secs in NLP function evaluations = 0.000\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.9\n" + ] + } + ], + "source": [ + "n_para = len(parameter_dict)\n", + "\n", + "t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", + "parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", + " \n", + "measurements = MeasurementVariables()\n", + "measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", + " \n", + "exp_design = DesignVariables()\n", + "exp_design.add_variables(\n", + " \"CA0\",\n", + " indices={0: [0]},\n", + " time_index_position=0,\n", + " lower_bounds=1,\n", + " upper_bounds=5,\n", + " )\n", + "exp_design.add_variables(\n", + " \"T\",\n", + " indices={0: t_control},\n", + " time_index_position=0,\n", + " lower_bounds=300,\n", + " upper_bounds=700,\n", + " )\n", + "\n", + "exp_design.update_values({\"CA0[0]\": 5, \"T[0]\": 450, \"T[0.125]\": 300, \"T[0.25]\": 300, \"T[0.375]\": 300, \"T[0.5]\": 300, \"T[0.625]\": 300,\n", + " \"T[0.75]\": 300, \"T[0.875]\": 300, \"T[1]\": 300})\n", + " \n", + "doe_object = DesignOfExperiments(\n", + " parameter_dict,\n", + " exp_design, \n", + " measurements, \n", + " create_model,\n", + " discretize_model=disc_for_measure,\n", + " )\n", + "\n", + "result = doe_object.compute_FIM(\n", + " mode=\"sequential_finite\",\n", + " scale_nominal_param_value=True,\n", + " formula=\"central\",\n", + " )\n", + "\n", + "result.result_analysis()\n", + "\n", + "FIM_prior = result.FIM\n", + "FIM_new = np.zeros((n_para, n_para))\n", + "A_vals = []\n", + "D_vals = []\n", + "exp_conds = []\n", + "FIM_opt = None\n", + "\n", + "def get_exp_conds(m):\n", + " return [pyo.value(m.CA0[0]), pyo.value(m.T[0]), pyo.value(m.T[0.125]), pyo.value(m.T[0.25]), pyo.value(m.T[0.375]), pyo.value(m.T[0.5]), pyo.value(m.T[0.625]), pyo.value(m.T[0.75]), pyo.value(m.T[0.875]), pyo.value(m.T[1])]\n", + "\n", + "for i in range(20):\n", + " FIM_prior += FIM_new\n", + " \n", + " doe_object = DesignOfExperiments(\n", + " parameter_dict,\n", + " exp_design, \n", + " measurements, \n", + " create_model,\n", + " prior_FIM=FIM_prior,\n", + " discretize_model=disc_for_measure,\n", + " )\n", + " \n", + " square_result, optimize_result = doe_object.stochastic_program(\n", + " if_optimize=True,\n", + " if_Cholesky=True,\n", + " scale_nominal_param_value=True,\n", + " objective_option=\"det\",\n", + " L_initial=np.linalg.cholesky(FIM_prior),\n", + " )\n", + " FIM_new = optimize_result.FIM\n", + " \n", + " new_exp_conds = get_exp_conds(optimize_result.model)\n", + " result = new_doe_object2(new_exp_conds[0], new_exp_conds[1:], FIM_new)\n", + "\n", + " if FIM_opt is None:\n", + " FIM_opt = [result.FIM, ]\n", + " else:\n", + " FIM_opt.append(result.FIM)\n", + " \n", + " D_opt = np.linalg.det(FIM_new)\n", + " # A_vals.append(np.log10(A_opt))\n", + " D_vals.append(np.log10(D_opt))\n", + " exp_conds.append(new_exp_conds)" + ] + }, + { + "cell_type": "code", + "execution_count": 109, + "id": "8d7175ef-92b3-44f4-8bbb-5af12527e668", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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d3V1xdvbu8ggIiIi1VeF3F595MiRPP3009x+++107tyZjz76iEOHDjFkyJCK+DoRERGxIRUSPh5//HFSUlJ49913OX78OK1atWLJkiUEBQVVxNeJiIiIDamQ+3zcCN3nQ0RExPaU5fe7yj3V9mIW0iW3IiIituPi7/a19DSqXPhIT08H0CW3IiIiNig9PR0fH58rLlPlDrsUFBRw7NgxvLy8SrwvyI1IS0ujYcOGHD58uNof0rGnbQX72l5ta/VlT9urba1+DMMgPT2dwMBAHByufDFtlet8ODg40KBBgwr9Dnu6pNeethXsa3u1rdWXPW2vtrV6uVrH46IKu8OpiIiISEkUPkRERKRS2VX4cHV15e2338bV1dXapVQ4e9pWsK/t1bZWX/a0vdpW+1blTjgVERGR6s2uOh8iIiJifQofIiIiUqkUPkRERKRSKXyIiIhIpap24SMqKorg4GDc3Nxo3749q1evvuLysbGxtG/fHjc3N26++WZiYmIqqdLrN378eDp06ICXlxe+vr48/PDDJCYmXvEzK1euxGQyFRsSEhIqqerrN3bs2GJ1+/v7X/EztrhfAW666aYS91NERESJy9vSfl21ahV9+vQhMDAQk8nEokWLisw3DIOxY8cSGBiIu7s7d911Fzt27Ljqer///ntatGiBq6srLVq0YOHChRW0BWVzpe3Nzc3l1VdfpXXr1nh6ehIYGMgzzzzDsWPHrrjOTz/9tMT9ff78+Qremiu72r4dNGhQsZpDQ0Ovut6quG+vtq0l7R+TycTkyZNLXWdV3a8VqVqFj/nz5zN8+HDeeOMN4uPj6dq1K7179+bQoUMlLn/gwAHuv/9+unbtSnx8PK+//jovvfQS33//fSVXXjaxsbFERESwfv16li5dSl5eHj179iQjI+Oqn01MTOT48eOWoUmTJpVQ8Y1r2bJlkbq3bdtW6rK2ul8BNm3aVGQ7ly5dCsDf//73K37OFvZrRkYGbdq0YdasWSXOnzRpEtOmTWPWrFls2rQJf39/7r33Xsvznkqybt06Hn/8cZ5++mn+/PNPnn76afr168eGDRsqajOu2ZW2NzMzkz/++IO33nqLP/74gwULFrB7924efPDBq67X29u7yL4+fvw4bm5uFbEJ1+xq+xagV69eRWpesmTJFddZVfft1bb18n3zySefYDKZePTRR6+43qq4XyuUUY107NjRGDJkSJFpISEhxmuvvVbi8qNHjzZCQkKKTBs8eLARGhpaYTVWhOTkZAMwYmNjS11mxYoVBmCcOXOm8gorJ2+//bbRpk2ba16+uuxXwzCMYcOGGY0bNzYKCgpKnG+r+xUwFi5caHlfUFBg+Pv7GxMmTLBMO3/+vOHj42PExMSUup5+/foZvXr1KjLtvvvuM5544olyr/lGXL69Jdm4caMBGAcPHix1mTlz5hg+Pj7lW1w5K2lbBw4caDz00ENlWo8t7Ntr2a8PPfSQcc8991xxGVvYr+Wt2nQ+cnJy2Lx5Mz179iwyvWfPnqxdu7bEz6xbt67Y8vfddx9xcXHk5uZWWK3lLTU1FYDatWtfddm2bdsSEBBAjx49WLFiRUWXVm727NlDYGAgwcHBPPHEE+zfv7/UZavLfs3JyeHLL7/kH//4x1Ufsmir+/WiAwcOkJSUVGS/ubq60r1791L/fqH0fX2lz1RVqampmEwmatasecXlzp07R1BQEA0aNOCBBx4gPj6+cgq8QStXrsTX15emTZvywgsvkJycfMXlq8O+PXHiBIsXL+a555676rK2ul+vV7UJH6dOnSI/Px8/P78i0/38/EhKSirxM0lJSSUun5eXx6lTpyqs1vJkGAYjR47kzjvvpFWrVqUuFxAQwEcffcT333/PggULaNasGT169GDVqlWVWO316dSpE59//jm//PIL//nPf0hKSqJLly6kpKSUuHx12K8AixYt4uzZswwaNKjUZWx5vxZ28W+0LH+/Fz9X1s9URefPn+e1115jwIABV3zwWEhICJ9++ik//vgjX3/9NW5ubtxxxx3s2bOnEqstu969ezN37lyWL1/O1KlT2bRpE/fccw/Z2dmlfqY67NvPPvsMLy8v+vbte8XlbHW/3ogq91TbG3X5/yEahnHF/2ssafmSpldVkZGRbN26ld9///2KyzVr1oxmzZpZ3nfu3JnDhw8zZcoUunXrVtFl3pDevXtbXrdu3ZrOnTvTuHFjPvvsM0aOHFniZ2x9vwJ8/PHH9O7dm8DAwFKXseX9WpKy/v1e72eqktzcXJ544gkKCgqIioq64rKhoaFFTtS84447aNeuHTNnzmTGjBkVXep1e/zxxy2vW7Vqxe23305QUBCLFy++4g+zre/bTz75hCeffPKq527Y6n69EdWm81G3bl0cHR2LpeLk5ORi6fkif3//Epd3cnKiTp06FVZreRk6dCg//vgjK1asoEGDBmX+fGhoqE0ma09PT1q3bl1q7ba+XwEOHjzIb7/9xvPPP1/mz9rifr149VJZ/n4vfq6sn6lKcnNz6devHwcOHGDp0qVlfty6g4MDHTp0sLn9HRAQQFBQ0BXrtvV9u3r1ahITE6/rb9hW92tZVJvw4eLiQvv27S1XB1y0dOlSunTpUuJnOnfuXGz5X3/9ldtvvx1nZ+cKq/VGGYZBZGQkCxYsYPny5QQHB1/XeuLj4wkICCjn6ipednY2u3btKrV2W92vhc2ZMwdfX1/+3//7f2X+rC3u1+DgYPz9/Yvst5ycHGJjY0v9+4XS9/WVPlNVXAwee/bs4bfffruuYGwYBlu2bLG5/Z2SksLhw4evWLct71swdy7bt29PmzZtyvxZW92vZWKtM10rwrx58wxnZ2fj448/Nnbu3GkMHz7c8PT0NP766y/DMAzjtddeM55++mnL8vv37zc8PDyMESNGGDt37jQ+/vhjw9nZ2fjuu++stQnXJCwszPDx8TFWrlxpHD9+3DJkZmZalrl8Wz/44ANj4cKFxu7du43t27cbr732mgEY33//vTU2oUxGjRplrFy50ti/f7+xfv1644EHHjC8vLyq3X69KD8/32jUqJHx6quvFptny/s1PT3diI+PN+Lj4w3AmDZtmhEfH2+5umPChAmGj4+PsWDBAmPbtm1G//79jYCAACMtLc2yjqeffrrI1Wtr1qwxHB0djQkTJhi7du0yJkyYYDg5ORnr16+v9O273JW2Nzc313jwwQeNBg0aGFu2bCnyd5ydnW1Zx+XbO3bsWOPnn3829u3bZ8THxxvPPvus4eTkZGzYsMEam2hxpW1NT083Ro0aZaxdu9Y4cOCAsWLFCqNz585G/fr1bXLfXu3fY8MwjNTUVMPDw8OIjo4ucR22sl8rUrUKH4ZhGLNnzzaCgoIMFxcXo127dkUuPx04cKDRvXv3IsuvXLnSaNu2reHi4mLcdNNNpf7LUpUAJQ5z5syxLHP5tk6cONFo3Lix4ebmZtSqVcu48847jcWLF1d+8dfh8ccfNwICAgxnZ2cjMDDQ6Nu3r7Fjxw7L/OqyXy/65ZdfDMBITEwsNs+W9+vFy4IvHwYOHGgYhvly27ffftvw9/c3XF1djW7duhnbtm0rso7u3btblr/o22+/NZo1a2Y4OzsbISEhVSZ4XWl7Dxw4UOrf8YoVKyzruHx7hw8fbjRq1MhwcXEx6tWrZ/Ts2dNYu3Zt5W/cZa60rZmZmUbPnj2NevXqGc7OzkajRo2MgQMHGocOHSqyDlvZt1f799gwDOPf//634e7ubpw9e7bEddjKfq1IJsO4cCaeiIiISCWoNud8iIiIiG1Q+BAREZFKpfAhIiIilUrhQ0RERCqVwoeIiIhUKoUPERERqVQKHyIiIlKpFD5ERESkUil8iIiISKVS+BAREZFKpfAhIiIilUrhQ0RERCrV/wc5yL1dz4H6RAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "D_vals_opt_from_ind_FIM = []\n", + "running_FIM = np.zeros((n_para, n_para))\n", + "for i in range(20):\n", + " running_FIM += FIM_opt[i]\n", + " D_vals_opt_from_ind_FIM.append(np.log10(np.linalg.det(running_FIM)))\n", + "\n", + "plt.plot(range(20), D_vals, color='black')\n", + "plt.plot(range(20), D_vals_opt_from_ind_FIM, color='green')\n", + "plt.plot(range(20), D_vals_rand_from_ind_FIM, color='orange')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "id": "2e53d948-0c13-41be-b417-3a771e09b3c4", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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k9i9e/eovSfDKSkpwde//nXpjnddXR0aGxtH3W/Zj+1vf/tbfPDBB3n9hmU9rrkoqgDF6/Vi1qxZetWDZvfu3Zg3b96wfzN37twLtn/jjTcwe/ZseDwe0/a1UKqq4q//+q/xyiuv4M0338S0adPyep4jR46grq7O4L0zXzQaxfvvvz/ivst6XDM9++yzmDJlCm644Yac/1bG4zpt2jQEg8Gs4xaLxbBv374Rf7/AyMd6tL8RhRacHD9+HHv27MkreFZVFe+++650x/v8+fM4c+bMqPst87EFBnpAZ82aha985Ss5/62sxzUndmXn2mXHjh2qx+NRt2zZor733ntqc3OzWl5erp46dUpVVVX94Q9/qN5111369idOnFDLysrU73//++p7772nbtmyRfV4POr/+T//x663MC7/43/8DzUQCKh79+5V29ra9Ftvb6++zdD3umnTJnXnzp3qhx9+qB49elT94Q9/qAJQX375ZTveQk7WrFmj7t27Vz1x4oR68OBBdcmSJWpFRYXjjqsmmUyqn//859Uf/OAHFzwm83Ht6upSjxw5oh45ckQFoD7++OPqkSNH9KqVRx55RA0EAuorr7yitra2qt/5znfUuro6NRKJ6M9x1113ZVXl/du//ZvqcrnURx55RH3//ffVRx55RHW73erBgwctf39DjfZ+4/G4unTpUvWiiy5S33333azfcTQa1Z9j6PttaWlRX3/9dfW//uu/1CNHjqh/8Rd/obrdbvV3v/udHW9RN9p77erqUtesWaMeOHBAPXnypPrWW2+pc+fOVT/3uc9JeWzH+h6rqqqGw2G1rKxMfeqpp4Z9DlmOq5mKLkBRVVX9x3/8R7WxsVH1er3q1772tazS2xUrVqjz58/P2n7v3r3qzJkzVa/Xq06dOnXEL5RIAAx7e/bZZ/Vthr7XRx99VL344otVv9+vVldXq9/4xjfUV1991fqdz8Ott96q1tXVqR6PR62vr1eXLVumHjt2TH/cKcdVs2vXLhWA+sEHH1zwmMzHVSuJHnpbsWKFqqoDpcY/+tGP1GAwqPp8PvVP/uRP1NbW1qznmD9/vr695l/+5V/USy+9VPV4POqXvvQlYYKz0d7vyZMnR/wdv/XWW/pzDH2/zc3N6uc//3nV6/WqkydPVhctWqQeOHDA+jc3xGjvtbe3V120aJE6efJk1ePxqJ///OfVFStWqB999FHWc8hybMf6Hquqqv7sZz9TS0tL1c7OzmGfQ5bjaiZFVQczA4mIiIgEUVQ5KERERCQHBihEREQkHAYoREREJBwGKERERCQcBihEREQkHAYoREREJBwGKERERCQcBihEREQkHAYoREREJBwGKERERCQcBihEREQkHAYoREREJJz/H0t8KKeI27v/AAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "exp_conds_array = np.array(exp_conds)\n", + "plt.plot(range(20), exp_conds_array[:, 9])\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "id": "a2243b52-d5fe-4a52-8280-fb0ce4436ed6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO: =======Iteration Number: 1 =====\n", + "INFO: elapsed time: 2.2\n", + "INFO: This is run 1 out of 9.\n", + "INFO: The code has run 2.19064669997897 seconds.\n", + "INFO: Estimated remaining time: 7.667263449926395 seconds\n", + "INFO: =======Iteration Number: 2 =====\n", + "INFO: elapsed time: 1.0\n", + "INFO: This is run 2 out of 9.\n", + "INFO: The code has run 3.2144447999307886 seconds.\n", + "INFO: Estimated remaining time: 6.428889599861577 seconds\n", + "INFO: =======Iteration Number: 3 =====\n", + "INFO: elapsed time: 1.3\n", + "INFO: This is run 3 out of 9.\n", + "INFO: The code has run 4.496953599969856 seconds.\n", + "INFO: Estimated remaining time: 5.6211919999623206 seconds\n", + "INFO: =======Iteration Number: 4 =====\n", + "INFO: elapsed time: 1.0\n", + "INFO: This is run 4 out of 9.\n", + "INFO: The code has run 5.520735299913213 seconds.\n", + "INFO: Estimated remaining time: 4.4165882399305705 seconds\n", + "INFO: =======Iteration Number: 5 =====\n", + "INFO: elapsed time: 1.2\n", + "INFO: This is run 5 out of 9.\n", + "INFO: The code has run 6.751729399897158 seconds.\n", + "INFO: Estimated remaining time: 3.375864699948579 seconds\n", + "INFO: =======Iteration Number: 6 =====\n", + "INFO: elapsed time: 1.2\n", + "INFO: This is run 6 out of 9.\n", + "INFO: The code has run 7.984732399811037 seconds.\n", + "INFO: Estimated remaining time: 2.281352114231725 seconds\n", + "INFO: =======Iteration Number: 7 =====\n", + "INFO: elapsed time: 1.1\n", + "INFO: This is run 7 out of 9.\n", + "INFO: The code has run 9.039862399804406 seconds.\n", + "INFO: Estimated remaining time: 1.1299827999755507 seconds\n", + "INFO: =======Iteration Number: 8 =====\n", + "INFO: elapsed time: 2.8\n", + "INFO: This is run 8 out of 9.\n", + "INFO: The code has run 11.875191299826838 seconds.\n", + "INFO: Estimated remaining time: 0.0 seconds\n", + "INFO: =======Iteration Number: 9 =====\n", + "INFO: elapsed time: 0.9\n", + "INFO: This is run 9 out of 9.\n", + "INFO: The code has run 12.811318899854086 seconds.\n", + "INFO: Estimated remaining time: -1.2811318899854087 seconds\n", + "INFO: Overall wall clock time [s]: 12.811318899854086\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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o23btjh8+LDiCcMnT55g9+7dqFOnDnr37i1yhEREZWMSRVSF5eTkAACsrKx0aqd3796QSCSlRnyel5CQgEGDBsHGxgb29vYYPXo0Hj58qFO/6hg9ejSKi4uxfft2AMD+/fuRmZkJf3//V3L0jYheHUyiiKow+XogXYpo3r9/H0eOHAFQ9pNwubm58PPzw927d7F9+3b8+OOPOHnyJN544w2UlJRo3bc6/P39YWxsrEjw5P+VP71HRFRV8Z95RFVY/fr1AQB37tzRuo1t27ahpKQEvXv3xuHDh5GSkgIHBwelc1avXo379+/j5MmTcHR0BPCsKKa3tzd+/fVXvPXWW9p/iJdwcHBAr169EBkZiWPHjuHgwYPw8PBA+/btK6xPIiJ94EgUURUmL1dw8uRJFBUVadXG5s2b0bp1ayxZskRp2ux5+/fvh5+fnyKBAp5VC2/atCn27dunXfAakC8gHz16NJ4+fcoF5URkEJhEEVVhr7/+OqytrZGWloY9e/ZofP2VK1cQFxeHkSNHwsvLC82bN1c5pXf16lW0aNGi1P4WLVrg2rVrWsWuibfeegvW1tZISkpSlD4gIqrqmEQRVWE1atTABx98AACYPn16ue+kA569oFheFgF4NgolkUjw7rvvAni2zuj8+fOlEqOMjAzUqFGjVHs1a9ZEenq6bh9CDZaWlvj444/Rs2dPvPfee3BxcanwPomIdMUkiqiKCw0NRefOnZGamorOnTtj8+bNKCgoUDrnxo0bmDJlCnx9fZGWlgbgWdXvbdu2wcfHBw0aNAAAjBw5EhKJROVolEQiKbWvMt9PHhoair/++gurVq2qtD6JiHTBJIqoijMzM8OhQ4cwdOhQpKSkYMyYMahZsyZatWoFb29vNGjQAO7u7vj+++/h4OCAJk2aAACioqKQnJyMQYMGITMzE5mZmbC1tUXHjh2xdetWpQTJ3t4eGRkZpfrOyMhAzZo1K+2zEhEZEiZRRAbA2toae/bswbFjxzBu3Dg4OTkhISEBcXFxEAQBb7zxBtatW4cbN26gZcuWAP5XzuCjjz6Cvb29Yjt9+jQSExNx4sQJRfstWrTA1atXS/V79epVNGvWrHI+JBGRgWGJAyID0r17d3Tv3v2l5xUUFGDPnj3o168fZs+erXSssLAQAwcOxJYtWxRtvfnmm5g3b55S+YO///4b//zzD8LCwvT6GV62rutFDRo0qNRpRSIidUkE/u1E9MrZtWsXhg8fjv379+ONN94odXz48OH4888/kZKSAjMzM+Tk5KB169aoXbs2QkJCUFBQgNmzZ6NWrVo4deoUjIxePmidkJCAhg0bQiqVKmo8BQUFISgoSO+fTy4wMBDx8fHIysrC5cuX4ePjg6ioqArrj4joeZzOI3oFbdmyBQ4ODujXr5/K44GBgcjIyMCBAwcAPKuMfuTIETg4OGD48OEYN24cOnXqhP3796uVQD3vyZMniImJQUxMDJKSknT+LOW5cOECYmJicPny5Qrth4hIFY5EEREREWmBI1FEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKSF/wOJlcL9geJOrwAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkEAAAHcCAYAAADRFH6tAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAABnP0lEQVR4nO3deVxU5f4H8M8AMiDLAKGiyCaKa+7iAopLuOSSmrnkTi6YmmW5ewUss7TVyDT3XPNa3lxyywQCNSWTG4oCpkgqGimLKPvz+8PfzHWcAYaZgQPM5/16zas85znn+Z7DMPPl2Y5MCCFAREREZGLMpA6AiIiISApMgoiIiMgkMQkiIiIik8QkiIiIiEwSkyAiIiIySUyCiIiIyCQxCSIiIiKTxCSIiIiITBKTICIiIjJJTIKIarCtW7dCJpNh0qRJatsjIiIgk8nQs2dPrcdFRESgV69esLe3h0wmg0wmw40bN3Djxg3IZDJ4enpWeOy6xElQ/XyqstDQUMhkMoSGhqpt58+XpMYkqIrx9PRUfagpX1ZWVvDy8sK4ceNw/vx5qUMst4yMDISGhuKzzz6TOhSjUiYEytfBgwdLLT9s2DBV2ar8oX/p0iX069cPERERcHZ2hp+fH/z8/GBlZSV1aDp79neopFdERITUoZZq69atCA0NxY0bN6QOpdKFhoZqJE1ExmYhdQCkXZMmTVC3bl0AQGZmJpKTk7Fz507s2bMHW7Zswfjx4yWOUHcZGRkICwuDh4cH3nzzTanDqTDbt2/H4MGDte578OABfvzxx0qOqGS1a9dG06ZN4e7urrFv06ZNyM/Px+zZs7FmzRq1fbdu3ULTpk3h6upaWaEapFWrVlAoFCXuL21fVbB161ZERkaiZ8+eJba+NW3atHKDMqLS3odhYWEAwESIKhSToCpq8eLFal0YDx48wLRp07Bv3z7MnDkTgwYNgqOjo3QBkoq5uTk8PT1x8OBBZGZmav1i/fbbb5Gfn4+mTZvi6tWrEkSpztfXF1euXNG6T7l9wIABGvtcXV1LPK4q+uKLL6p0q5sxVKefx7NKex8SVQZ2h1UTjo6O2LRpE2xsbJCdnY3jx49LHRI9Zdy4ccjNzcW+ffu07t+xYwdkMhnGjh1byZGV3+PHjwEA1tbWEkdCRFSxmARVI/b29vDx8QGAEscIHDt2DEOGDEG9evUgl8vRsGFDTJ48GdeuXdNa/uzZs5g/fz46duyIunXrQi6Xw83NDePHj8elS5dKjefq1auYNm0aGjduDGtrazz33HPo0KEDQkJCcOfOHQDApEmT4OXlBQBISUnRGJPxrMOHD6N///5wdnaGXC6Hl5cXXn/9daSmpmqNQTmG6saNGzh16hQGDBgAZ2fnSh/vMW7cOABPusSedf36dcTExMDPz091L0py8+ZNzJgxA15eXpDL5XB2dsaAAQNw5MiREo8RQmDjxo1o27YtrK2tUbduXYwePRrJycklHqNtQOqkSZPU7luvXr1UPydlq2RZA6MLCwuxbt06+Pv7w8HBAVZWVmjWrBmWLl2KrKysEuPZv38/unXrBhsbGzz33HMYNGgQYmNjSywvJSEEduzYgYCAADg4OMDa2hrNmjXDggULcP/+fa3HPP1+37VrF3x9fWFrawsnJycMHToU8fHxauWVP5/IyEgA6j8LmUyGrVu3aj33057+3YiMjMQLL7wABwcHODk5YdiwYUhKSlKVPXDgALp37w57e3s4OjpizJgxuH37ttZrOXHiBGbNmoU2bdrAyckJVlZW8Pb2xowZM3Dz5s1y3Utt70PlIOpnr+/pAfoLFy6ETCbD7NmzSzx3bGwsZDIZ6tevj6KionLFRSZEUJXi4eEhAIgtW7Zo3d+0aVMBQKxZs0Zj35w5cwQAAUDUrVtXtGvXTtjb2wsAwt7eXsTExGgc4+3tLQCI5557TrRq1Uq0adNGKBQKAUBYW1uLU6dOaY1jx44dwtLSUlWuffv2olmzZkIul6vFv2LFCtGxY0cBQMjlcuHn56f2etrChQtV8Tds2FB06NBB1K5dWwAQjo6O4vz58yXer/fff1+YmZkJR0dH0alTJ9GwYcMSYzeW69evCwDC3NxcCCFEly5dhEwmEykpKWrlli9fLgCI9evXi+3btwsAIiAgQON8Z8+eFQ4ODgKAsLGxER06dBANGzZU3ZN//etfWuOYMWOGqoynp6do3769kMvlwsHBQSxevFgAEBMnTlQ75tSpUxpxrFixQvj5+aneM61atVL9nFasWKF2zR4eHhpxZGZmih49eggAwszMTHh4eIhWrVqp3ifNmzcXd+/e1Tjuww8/VMVfv3590aFDB2Frayvkcrl49913S7xfpVGez9jvgeLiYvHqq6+qzt+oUSPRvn171TV6eHiIa9eulRiP8lpdXFxEx44dhZ2dnep36JdfflGVv3DhQok/Cz8/P/Hjjz9qnPtZyt+NTz75RJibm4u6deuK9u3bCxsbG9W9vnPnjvjkk09Uv3Nt2rRR/Q43bdpUPH78WOO85ubmQiaTibp164q2bduKVq1aqc753HPPiUuXLmkcExISIgCIkJAQte3a3oebNm0Sfn5+qut69jPjzp074urVq6r68vLytP6sZs2aJQCId955R+t+IiGEYBJUxZSWBCUmJgoLCwsBQERFRantW7dunQAgvLy81D74CwsLxXvvvaf6kHv2Q23btm0aH9oFBQVi48aNwsLCQjRq1EgUFRWp7T9//ryoVauWACDmz58vHj58qNqXn58vdu/erfaBXtoXp9LBgwcFAGFhYSF27Nih2p6ZmSmGDRum+oJ/9OiR1vtlbm4uwsLCREFBgRDiyZdVbm5uifUZw7NJ0JdffqlKyJ7m4+Mj5HK5uH//folJUE5OjnB3dxcAxMiRI0VWVpZq39atW4W5ubkAoPblJ4QQP/zwgyrB/O6771Tb7927J3r27Kn6OemSBCkFBASUmECU9rMcPXq0ACD69Omj9p66f/++GD58uAAgRowYoXbMhQsXVF+q4eHhori4WAghRHZ2thg1apQq/qqSBH3xxRcCgLCzsxPHjx9Xbb9z547qi7tz584lxlOrVi3x8ccfq36ncnJyxNixY1X39Nn3d2k/i2fP/Szl78azdT548EB06dJFABADBw4UtWvXFjt37lQdd/PmTdGoUSMBQKxdu1bjvOvXrxe3bt1S2/bo0SOxYsUKAUD07NlT45jyJEFlXZeS8n5///33Gvvy8/PFc889JwCI+Pj4Es9BxCSoitGWBGVmZooTJ06IFi1aqP4yelpeXp5wcXER5ubm4sKFC1rP+/LLLwsA4ptvvtE5lnHjxgkAGi1IL774ogAggoKCdDqPLkmQ8gNtzpw5GvtycnKEs7OzACA2bdqktk95vwYPHqxTLMb0bBKUnp4uatWqJZo3b64qc/bsWQFADB8+XAghSkyCNmzYIACIevXqaf3r+/XXXxcARPfu3dW2+/v7CwBi3rx5GsfcuXNH1UJR0UlQXFycavvTCZxSTk6OcHNzEzKZTNy4cUO1Xfkee+WVVzSOefz4sahbt65BSVBpL4VCUa5zFhcXCzc3NwFAfPrppxr7//rrL9X9PnnypNZ4hgwZonGc8vcXgNi8ebPaPmMkQS+99JLGvmPHjqmO0/Y7p/yjSlu8pVG+H//66y+17RWRBG3atKnE6/v+++8FANGxY8dyxU+mh2OCqqjJkyer+sAVCgUCAwNx5coVjBo1SmM9mjNnziAtLQ3t27dHu3bttJ5vyJAhAKAaY/C0K1euICQkBMOHD0fPnj3h7+8Pf39/Vdm4uDhV2cePH+PEiRMAgPnz5xvlWh8+fIgzZ84AgNY+/tq1a2Pq1KkAUOKA8AkTJhglFkM899xzGDBgABISEnDhwgUATwZEAyhzSQPldU2dOlXrejxz5swBAJw+fRo5OTkAnty306dPAwBmzJihcYyLiwuGDx+u59WUz/79+wEAI0eOhJ2dncb+2rVr44UXXoAQAr/88otqu/K6tcVvZWWFoKAgg+Jq1aqVap2jZ19du3Yt17kSEhKQmpoKKysr1fvxaa6urnj55ZcBlPw+nTlzpsY2S0tLTJkyBcCTMX3G9tprr2lsa9u2ban7lZ8jf/75p9ZzxsbGYuHChRgyZAgCAgJUnxmJiYkAgP/+979GiLx0I0eOhK2tLX788Uf8/fffavu2bdsGABqLhBI9i1PkqyjlOkFCCKSlpeHPP/9ErVq10KlTJ42p8X/88QeAJ4NW/f39tZ4vIyMDwJN1Xp62cuVKLF26FMXFxSXG8vRgz+TkZBQUFMDBwcFo65MkJyejuLgYcrkcjRo10lqmZcuWAKD6kH1W8+bNjRKLocaNG4cDBw5g+/btaN26Nb799ls4OTnhxRdfLPU45XW1aNFC6/4mTZrA0tIS+fn5uHbtGlq3bq26b8rFNLWprPuifA/u379flZg9KyUlBcD/3oMZGRm4d+8egJLjNDR+Y06RV/6M3N3dYWNjo7WMvu9T5faSjjOEt7e3xrY6derotP/hw4dq24UQmDVrFtauXVtqnSUNEDcmW1tbvPLKK9iyZQt2796NN954AwCQnp6OH3/8EZaWlhgzZkyFx0HVG5OgKurZdYJiYmIwdOhQvPPOO6hXr55qNhLwZDFFAPj77781/iJ6lnL6MwBERUVh8eLFMDc3x8qVKzFkyBB4eHigdu3akMlkWLp0KVasWIGCggLVMcoZPg4ODka4yieUH7R16tQpcfn/evXqAQCys7O17i/pS6k0R44cwYoVKzS2BwUF6d0CMXjwYCgUCuzevRsBAQH4+++/ERwcDEtLy1KPU94D5QKZz5LJZKhTpw5u3bqlugfKY5ydnUs8r/K+VTTlezA5ObnUWWnA/96DT3/BPv2l/LTKih+A1j8g6tevj3//+98Ayv4ZAWW/T0s6tqzjDFG7dm2NbU//npW2Xwihtn379u1Yu3YtbGxssHr1agQGBsLV1VW1nMK4ceOwc+dOtc+MihQUFIQtW7Zg27ZtqiRo165dKCgowIgRI+Dk5FQpcVD1xSSomvDz88OGDRswbNgwzJkzB0OGDIG9vT2AJ38RAcDYsWNV3S+62LlzJwBg3rx5WLhwocZ+bdPSlV0dypYlY1DG//fff0MIoTURunv3rlr9xnD37l3ExMRobH/hhRf0PqeVlRVeeeUVbNy4UdWFpcvq3sp7oGwZeZYQQpXgKu+B8pj09PQSz1vS+YxNGcuGDRtUXTu6HgM8+dm7uLholKms+AFofS94eHio/r+snxFQ9vv077//RsOGDTW2K89pzPd3RVB+Znz88ceYPn26xv6SlrKoKP7+/vDx8cGFCxcQHx+PVq1asSuMyoVjgqqRoUOHokuXLrh//z4++eQT1XZlF8qza42URbnWULdu3bTuf3oskJKyWyYjI0PnlY/Lerhj48aNYWZmhry8vBLHICjXLFKuk2QMkyZNgngyOUDtZegy/cpWups3b6JRo0Yl3t+nKa/r8uXLWvcnJSUhPz8f5ubmqu4L5X3Lzc0tcd2ohIQEPa6g/PR5Dzo4OKhaRkpaNbiy4geg9b3w9H1V/oxu3ryp0U2kVNb7tKTrUW5/9riq9mDU0j4zCgoKKvXnpTR58mQATx4xEh8fjwsXLsDFxQX9+/ev9Fio+mESVM0oW2zWrFmj+iDu3r07nJ2dERcXV64FApVN2Mq/Xp92/PhxrUmQtbU1+vbtCwD46KOPylXP011xT7O1tVV9qH7xxRca+x8/foyNGzcCAPr166dTnVLq0aMHhg8fjj59+mDevHk6HaO8rg0bNiA3N1djv/IZXn5+fqquP1tbW9Xg3nXr1mkcc/fuXXz//fd6XUN5DRs2DMCTgeD//POPzscFBgYC0B5/Xl4eNm/ebJwAjaB58+Zwd3dHbm6u6v34tNu3b+O7774DUPL7VNtYmvz8fGzatAkAVL9bSmX97lS20j4ztmzZUmZ3vD51lXXtEydOhLm5OXbu3Kn6uYwbNw7m5uZGi4VqLiZB1cyQIUPQvHlzPHjwAF999RWAJ10wy5cvBwC88sor2L9/v0Zffnx8PBYsWKDW5K8cA/HBBx/g+vXrqu3nz59HUFBQiU8NDwkJQa1atbBx40YsXrwYjx49Uu0rKCjAt99+i+joaNW2OnXqwM7ODvfu3SvxL8UFCxYAePIlsWvXLtX27OxsTJgwAX///Tc8PT0xevTosm+SxGQyGb777jv89NNPCA4O1umYMWPGwN3dHXfv3sWkSZPUWhp27NiB9evXA4BGt+U777wDAPj888/xn//8R7U9PT0dY8eOLXXAuzF17NgRI0eOxD///IPAwED8/vvvavuLiooQERGBsWPHIi8vT7X9rbfegpmZGfbu3Yt169ap3rc5OTkICgqqlAG2upLJZKqkNiQkBCdPnlTtu3v3LkaPHo38/Hx06dIFvXr10nqOw4cP4/PPP1dd5+PHjzF16lTcvn0bbm5uGu9v5UQBbbM6paD8zFi6dKlawnP06FHMmzevxM8Mfeh67fXr10f//v2RlpaGL7/8EgC7wqgcKnlKPpWhrBWjhfjf+hguLi5qa8o8veKyk5OT6NSpk2jfvr1wcnJSbT9y5IiqfGZmpmpRNEtLS/H888+rVqRu0aKFmDt3rta1PYR4st6NciG72rVri/bt24vmzZsLKysrrfEHBQUJAMLKykp07NhRBAQEaKwN8nT8bm5uomPHjqqVaB0dHcW5c+dKvF/Xr1/X5fYa1bPrBOmirBWjlat129jYiI4dO6rWpQEgli5dqvWc06ZNU5Xx8vISHTp0EFZWVuVeMVpJ38USs7OzRWBgoCoWd3d30blzZ/H8888La2tr1fZn10F6//33VfsaNGigWknZGCtGP7vS8rOvvXv3luu8z64Y3bhxY7UVo93d3XVeMbpTp06qFaGtrKxEZGSkxnFRUVGqY318fESPHj1EQECA2u+xcv+zyvrdKOk4IUr+OaekpKg+T6ytrUXbtm2Fp6enACB69eqlWvjx2d9/fdYJUq60bm5uLtq1a6f6zLhz545G2e+++051PVwbiMqDSVAVo0sSlJeXJxo0aCAAiC+//FJtX0xMjHj11VeFm5ubsLS0FE5OTqJ169YiKChIHD58WOTn56uVv337tpgwYYJwdnYWlpaWwsvLS8ydO1dkZmaW+MGldOnSJTF58mTh7u4uLC0thbOzs+jQoYMIDQ3V+KDKzs4Wc+bMEZ6enqrkSdsH8MGDB0VgYKBwdHQUlpaWwsPDQwQHB4ubN2+Wer9qQhIkhBA3btwQ06dPFx4eHsLS0lI4OjqKvn37isOHD5d4zuLiYrF+/XrRunVrIZfLRZ06dcTIkSNFUlKS2LJlS6UlQUIIUVRUJHbu3Cn69esnnJ2dRa1atUT9+vVF586dxYIFC7QmskIIsW/fPtG5c2dhbW0tHB0dxYsvvijOnz9fapylUb6/ynppW/SwLMXFxeKbb74R3bt3F/b29kIul4smTZqIefPmifT09FLjEUKInTt3ik6dOonatWsLhUIhhgwZIuLi4kqsb9euXcLX11f1B8Gznw+VmQQJIcTVq1fF8OHDhUKhEFZWVqJZs2YiLCxM5OXliYkTJxotCcrPzxchISGiadOmqkd5lHQ9+fn5qgVVw8PDtV4TkTYyIZ7pNyEiIqMqaco5GUdGRgZcXFwghMCdO3c4NZ50xjFBRERUre3cuRN5eXl46aWXmABRubAliIiogrElqOLcv38f7dq1w82bN3Hq1CmjrRBOpoEtQUREVO188MEH6N69O7y9vXHz5k307duXCRCVG5MgIiKqdq5cuYLo6GiYm5tj/PjxaktrUOm2bt2qekB3Sa8+ffqUeZ6IiIhSz3H27NlKuBrD8LEZREQVjN1gxrd161Zs3bpV6jCqpbZt2yIkJETrvn379uHSpUvlWpg2ICBAayuctkfEVDUcE0RERETIz89HgwYNkJmZib/++qvMBxhHRESgV69eCAkJMfhxQ1JhS5CRFRcX4/bt27Czs6tyz/0hIqKyCSGQnZ2NBg0awMys4kaN5ObmIj8/3+DzWFpaGmW17v379+Off/7B0KFDy0yAagomQUamXP6eiIiqt9TU1Arr0snNzUVta2sYoyvGxcUF169fNzgRUj7DbsqUKeU6LikpCWvWrMGjR4/g4eGBwMBAODs7GxRLZWF3mJFlZmbCwcEBqR8D9tZSR0MVbuzCsstQDbJI6gCoEmRlZcHNzQ0ZGRlQKBQVVodCoYA1AEP6DASAx3iSsNnb26u2y+VyyOVync+TkpKCRo0aoX79+khJSdHpAbTK7rBnWVtbIywsTOcHSEuJLUFGpuwCs7dmEmQS7I33wEiqDuzLLkI1RmUMaTCH4UkQAI0eiPKO09myZQuKi4sxefJknRIg4MnDsVevXo1BgwbB3d0dGRkZOHXqFBYsWID58+fD3t4e06dP1zkGKbAlyMiU2X3mWiZBJmFSqNQRUKXSPqOGahbV53hmplrrSkXUoYDhSVAmDGsJKi4uhpeXF1JTU3Ht2jV4eXkZEBEQHx+PDh06wNHREbdv367QcVWGqrqRERERkU7s7e3VXuXpCjtx4gRu3ryJ3r17G5wAAUCrVq3QuXNn3L17F8nJyQafryKxO4yIiEgiZjBOd5gh9B0QXRrlwOhHjx4Z7ZwVgUkQERGRRMxgWJdMsYH1//PPP/jhhx/g5OSEYcOGGXi2JwoLC3HhwgXIZDK4u7sb5ZwVhd1hREREEjE3wssQ27dvR35+PsaNG1diF1p6ejquXLmC9PR0te1nzpzRWA29sLAQ8+bNQ0pKCvr16wcnJycDI6xYbAkiIiIyUbp0hYWHhyMsLExjxtmYMWMgk8nQrVs3uLq6IiMjA1FRUbh69Src3d2xbt26ig7fYEyCiIiIJGJod5ghzp07h/j4ePj6+uL5558v9/EzZszA0aNHERERgfT0dFhYWKBx48ZYsmQJ3n77bTg6OlZA1MbFKfJGxinyJoZT5E0Mp8ibgsqcIu8Kw8cE3QIqNNaajGOCiIiIyCSxO4yIiEgi5jCsNYKP6TYMkyAiIiKJSDkmiHjviYiIyESxJYiIiEgiZjB8rR/SH5MgIiIiiRjaHcbp3YZhdxgRERGZJLYEERERScQYj74g/TEJIiIikgiTIGkxCSIiIpIIxwRJi2OCiIiIyCSxJYiIiEgi7A6TFpMgIiIiiTAJkha7w4iIiMgksSWIiIhIIjIY1hpRbKxATBSTICIiIokY2h3G2WGGYXcYERERmSS2BBEREUnE0HWC2JJhGCZBREREEmF3mLSYRBIREZFJYksQERGRRNgSJC0mQURERBLhmCBpMQkiIiKSCFuCpMUkkoiIiEwSW4KIiIgkYgbDWoK4YrRhmAQRERFJhGOCpMX7R0RERCaJLUFEREQSMXRgNLvDDMMkiIiISCLsDpMW7x8RERGZJLYEERERSYTdYdJiEkRERCQRJkHSYncYERERmSS2BBEREUmEA6OlxSSIiIhIIoauGF1krEBMFJMgIiIiiRg6JsiQY4ktaURERGSimAQRERFJxMwIr/LaunUrZDJZqa8+ffrodK7i4mKEh4ejdevWsLa2Rp06dTBy5EgkJSXpEVnlY3cYERGRRKToDmvbti1CQkK07tu3bx8uXbqEfv366XSu4OBgbNiwAS1atMDs2bNx9+5dfPvttzh+/DhOnz6NFi1a6BFh5WESREREZELatm2Ltm3bamzPz89HeHg4LCwsMHHixDLPc+rUKWzYsAHdu3fHiRMnIJfLAQATJkxAYGAgZsyYgcjISGOHb1TsDiMiIpKIFN1hJdm/fz/++ecfDBo0CPXq1Suz/IYNGwAA7733nioBAoA+ffqgX79+iIqKQmJiohEjND4mQURERBIxN8LLWDZt2gQAmDJlik7lIyIiYGNjAz8/P419yu40tgQRERFRlZaSkoKTJ0/C1dUV/fv3L7N8Tk4O7ty5Ay8vL5iba6ZiTZo0AYAqP0CaY4KIiIgkYqyB0VlZWWrb5XK5WhdVWbZs2YLi4mJMnjxZa1LzrMzMTACAQqHQut/e3l6tXFVV5VuCMjIy8MYbb6Br165wcXGBXC6Hq6srevfuje+++w5CCI1jsrKyMHfuXHh4eEAul8PDwwNz587VeJM8bdeuXfD19YWNjQ0cHR3x4osvIjY2tiIvjYiITJwMho0Hkv3/edzc3KBQKFSvlStX6hxDcXExtmzZAplMhqCgIONcWDVR5VuC0tPTsXnzZnTp0gVDhw6Fk5MT7t27h4MHD2LEiBGYOnUqvv76a1X5nJwcBAQE4OLFiwgMDMSYMWMQFxeHTz/9FKdOnUJ0dDRsbGzU6nj//fexZMkSuLu7Izg4GA8fPsSePXvg5+eHY8eOoWfPnpV81URERLpLTU1Vtb4AKFcr0IkTJ3Dz5k306dMHXl5eOh2jbAEqqaVH2ehQUktRVVHlkyAvLy9kZGTAwkI91OzsbHTp0gUbNmzAnDlz0LJlSwDAqlWrcPHiRcyfPx8ffvihqnxISAiWL1+OVatWISwsTLU9KSkJISEh8PHxwblz51Q/sDfeeAO+vr6YMmUKrly5olE/ERGRoYzVHWZvb6+WBJVHeQdEA4CNjQ3q16+P69evo6ioSKMLTTkWSDk2qKqq8t1h5ubmWhMQOzs71ejz5ORkAIAQAhs3boStrS2WLVumVn7RokVwdHTEpk2b1LrQtmzZgsLCQixZskQtY23ZsiUmTJiAa9eu4eeff66ISyMiIhMn9eywf/75Bz/88AOcnJwwbNiwch0bEBCAnJwcxMTEaOw7duyYqkxVVuWToJLk5ubi559/hkwmU61ImZSUhNu3b8PPz0+jy8vKygo9evTArVu3VEkT8GSKHwD07dtXo47qMsWPiIiqJ6nXCdq+fTvy8/Mxbty4ErvQ0tPTceXKFaSnp6ttnzZtGgBg6dKlyM/PV20/efIkjh07hh49esDHx8fACCtWtUmCMjIyEBoaimXLliE4OBg+Pj6Ii4vDsmXLNKbildT8pm3KXlJSEmxtbeHi4qJTeSIioppCl66w8PBwNG/eHOHh4Wrbe/XqhSlTpuCXX35Bu3btMH/+fEycOBEDBw6Evb09vvrqqwqN3RiqzUCXjIwMtbE8tWrVwurVq/H222+rtukzZS8zMxN169bVufyz8vLykJeXp/p3aTPQiIiInibFs8OUzp07h/j4ePj6+uL555/X6xzr169H69atsX79eqxZswa2trYYPHgwVqxYUeVbgYBqlAR5enpCCIGioiKkpqZiz549WLJkCU6fPo29e/dKNnB55cqVaskZERGRrgzt0jLkWF9fX63LzDwrNDQUoaGh2us3M8Ps2bMxe/ZsAyKRTrXpDlMyNzeHp6cnFi5ciPfeew/79+9XPb9Enyl7CoXCoCl+ixYtQmZmpuqVmppa/osiIiKiSlftkqCnKQczKwc3lzWGR9uYoSZNmuDhw4dIS0vTqfyz5HK5amqiIVMUiYjI9Eg9O8zUVesk6Pbt2wCg6gpr0qQJGjRogJiYGOTk5KiVzc3NRVRUFBo0aIDGjRurtiun7x0/flzj/NVlih8REVVPZjAsAarWX+JVQJW/fxcvXtTaXXX//n0sXrwYADBgwAAAgEwmw5QpU/Dw4UMsX75crfzKlSvx4MEDTJkyBTKZTLV98uTJsLCwwIoVK9TquXTpEr755ht4e3ujd+/eFXFpREREJKEqPzB669at2LhxI3r16gUPDw/Y2NggJSUFhw8fxsOHD/Hyyy/j1VdfVZWfP38+Dhw4gFWrVuH3339Hhw4dEBcXhyNHjqBt27aYP3++2vl9fHwQGhqKpUuXonXr1hgxYgRycnKwe/duFBQUYMOGDVwtmoiIKoSUA6OpGiRBI0aMQGZmJs6ePYuoqCg8evQITk5O8Pf3x4QJEzB69Gi1lh0bGxtEREQgLCwM+/btQ0REBFxcXPDWW28hJCREYxFFAFiyZAk8PT3x2Wef4auvvoKlpSW6deuG5cuXo1OnTpV5uUREZEKknCJPgEzoMj+OdJaVlfVkxtlawN5a6miowk0KlToCqlQhUgdAlUD1OZ6ZWWGTXZR1LANgZcB5cgEsByo01pqsyrcEERER1VRsCZIWkyAiIiKJcEyQtJgEERERSYQtQdJiEklEREQmiS1BREREEmF3mLSYBBEREUlEuWK0IceT/nj/iIiIyCSxJYiIiEgiHBgtLSZBREREEuGYIGnx/hEREZFJYksQERGRRNgdJi0mQURERBJhEiQtdocRERGRSWJLEBERkUQ4MFpaTIKIiIgkwu4waTEJIiIikogMhrXmyIwViIliSxoRERGZJLYEERERSYTdYdJiEkRERCQRJkHSYncYERERmSS2BBEREUmEU+SlxSSIiIhIIuwOkxaTSCIiIjJJbAkiIiKSCFuCpMUkiIiISCIcEyQt3j8iIiIySWwJIiIikogZDOvSquktGUIIpKen4++//8bjx4/h7OyMOnXqoHbt2kY5P5MgIiIiibA7TFNSUhK+/fZbREVF4cyZM3j06JFGmSZNmqB79+7o27cvhg4dilq1aulVF5MgIiIiiXBg9P/8+9//Rnh4OKKjowE8aQUCADMzMygUClhbW+P+/fvIzc1FYmIiEhMTsXnzZjg5OWHChAmYO3cuXF1dy1VnTUwiiYiIqJo4efIkOnXqhNGjR+OXX35B69atsXjxYvzwww+4ffs2CgoK8M8//+Cvv/7Co0eP8PjxY8TGxmLt2rUYM2YM8vPz8emnn8LHxweLFi1CZmamznWzJYiIiEgibAkCAgMDoVAosGDBAkycOBFNmzYttbxcLkf79u3Rvn17BAcHIy8vDwcPHsQXX3yBDz/8ENbW1li2bJlOdbMliIiISCJmRnjpa//+/QgMDMRzzz0Ha2treHl5YcyYMUhNTS3z2IiICMhkshJfZ8+e1TmOsLAw3LhxA++//36ZCZA2crkcI0aMQGRkJCIjI9GuXTudj2VLEBERkQkRQiA4OBhff/01vL29MXr0aNjZ2eH27duIjIxESkoK3NzcdDpXQEAAevbsqbG9YcOGOsfzr3/9S+eyZenevXu5yjMJIiIikogU3WFffPEFvv76a8ycOROff/45zM3Vz1JYWKjzuXr27InQ0FA9oqgamAQRERFJpLKToMePHyMsLAyNGjXCZ599ppEAAYCFhemkBqZzpURERCbuxIkTuH//PiZNmoSioiIcOHAAiYmJcHBwwAsvvIDGjRuX63xJSUlYs2YNHj16BA8PDwQGBsLZ2dkosd6+fRvR0dFISUnRWCyxffv26Nixo8EJG5MgIiIiichg2OBm2f//NysrS227XC6HXC7XKB8bGwvgSWtPmzZtcPXqVdU+MzMzvPXWW/joo490rn/Xrl3YtWuX6t/W1tYICwvDvHnzynEV//Pnn39i06ZN+Pbbb3H9+nXVduWaQTKZTLXNysoKvXr1QlBQEIYMGaJXQsQkiIiISCLG6g57diBzSEiI1rE69+7dAwB8/PHHaN++Pc6dO4fmzZvj999/x7Rp0/Dxxx/D29sbM2bMKLXeOnXqYPXq1Rg0aBDc3d2RkZGBU6dOYcGCBZg/fz7s7e0xffp0na8jLi4OixcvxrFjx1BcXAwAcHJyQseOHVG/fn04OTmpFku8f/8+Ll++jISEBPz44484cuQI6tSpg/nz52PWrFmwtLTUuV6ZUKZXZBRZWVlQKBTIXAvYW0sdDVW4SaFSR0CVKkTqAKgSqD7HMzNhb29foXVEArA14DwPAQQASE1NVYu1pJagadOmYcOGDbC2tkZycjIaNGig2nfp0iW0bt0aXl5eSE5O1iue+Ph4dOjQAY6Ojrh9+zbMzMpu55owYQJ27dqF4uJidO7cGaNHj8agQYPg7e1d6nGPHj3CmTNnsGfPHnz//fd48OABPDw8sHXrVgQEBOgUL9cJIiIikoix1gmyt7dXe2lLgABAoVAAADp27KiWAAFAy5Yt0ahRI1y7dg0ZGRl6XU+rVq3QuXNn3L17V+dEas+ePRg3bhwSEhJw5swZzJkzp8wECABq166NPn36YMOGDbh79y42bdqEWrVqITIyUud42R1GREQkkcqeHaZcjNDBwUHrfuX2x48fl1imLMqB0doefKrN1atX4eXlpVddShYWFpg8eTImTpyIW7du6X6cQbUSERGR3io7CerVqxcAICEhQWNfQUEBkpOTYWNjgzp16ugVT2FhIS5cuACZTAZ3d3edjjE0AXqamZmZzgs9AuwOIyIiMhne3t7o27cvkpOTsXHjRrV9H3zwATIyMjBs2DDVTKv09HRcuXIF6enpamXPnDmDZ4cUFxYWYt68eUhJSUG/fv3g5ORUsRdjBGwJIiIikoihz//S59i1a9eiW7dumDp1Kv7zn/+gWbNm+P333/Hzzz/Dw8MDq1evVpUNDw9HWFiYxmyzMWPGQCaToVu3bnB1dUVGRgaioqJw9epVuLu7Y926dQZcVeVhEkRERCQRKR6b4e3tjdjYWCxbtgxHjx7F8ePH4eLigpkzZ2LZsmWoW7dumeeYMWMGjh49ioiICKSnp8PCwgKNGzfGkiVL8Pbbb8PR0bFcMfXu3VuPK/kfmUyGkydPlv84TpE3Lk6RNzGcIm9iOEXeFFTmFPkLMHyKfHugQmOtDGZmZpDJZBpdbLqSyWQoKioq93FsCSIiIpKIGQxrCappA3ubNWuGsWPHwtPTs1LqYxJEREQkESnGBFVFL730Eo4cOYIrV64gJCQEfn5+GD9+PF555RXV2kYVoabcPyIiIqqm9u/fj7S0NKxduxZdunTBL7/8gunTp6N+/foYOXIkDh48iMLCQqPXyySIiIhIIuZGeNUUDg4OCA4ORnR0NP7880+EhobCzc0N+/btw9ChQ1G/fn3MmjULZ8+eNVqdTIKIiIgkYqzHZtQ0np6e+Ne//oWrV6/i7NmzeP3112FmZoa1a9fCz88PTZo0wddff21wPTX1/hEREVV5bAkqm6+vL7744gvcvn0b+/fvh5ubG/7880/s27fP4HNzYDQRERFVaRcvXsT27duxe/dupKWlAYBRBkwzCaogt18HsqUOgiqca0Go1CFQZRoVKnUEVBmyKq8qKRZLrC7++usv7Ny5E9u3b0dCQgKEEFAoFJgyZQrGjRuHHj16GFwHkyAiIiKJcIq8uuzsbOzbtw/bt29HVFQUiouLUatWLQwePBjjxo3D4MGDIZfLjVYfkyAiIiKS1OHDh7F9+3YcPHgQjx8/BgB06dIF48ePx6hRoyrsYaxMgoiIiCTCFaOfGDx4MGQyGby9vTFu3DiMGzcOjRo1qvB6+ewwI1M+DyYBgJ3UwVCFczV8hiZVJ6OkDoAqQ1YWoHCr2OdxKb8r/gJgSA1ZABqi5jw7zNxcv5RQJpMhLy+v3MexJYiIiIgkJ4SokFWhS8MkiIiISCIcGP3E9evXJamXSRAREZFEOEX+CQ8PD0nqrSlJJBEREVG5sCWIiIhIIuwOkxaTICIiIomwO+yJoKAgg46XyWTYtGlTuY9jEkRERCQRJkFPbN26FTKZDOVdtUd5DJMgIiIiqpYmTJgAmUxW6fUyCSIiIpKK7P9f+hL//6rmtm7dKkm9TIKIiIikYg7Dk6DKXV+wRuHAciIiIjJJTIKIiIikYm6EVw3g5OSEQYMGad0XFRWFuLi4CqmXSRAREZFUzIzwqgEyMjKQlZWldV/Pnj3xxhtvVEi9NeT2ERERUU1V3qnzuuLAaCIiIqkYY2A06Y1JEBERkVSYBEmK3WFERERkktgSREREJBUzsCVIQkyCiIiIpGLoDK9iYwUivdjYWDRq1Ehju0wmK3Hf02WuXbtW7jqZBBEREUmlBk1zN1Rubi5u3LhR7n0A9H7uGJMgIiIiktSWLVskqZdJEBERkVTMYVhLUOU/eL1CTJw4UZJ6mQQRERFJhUmQpNgTSURERCaJSRAREZFU+OwwrFq1Cjk5OUY519mzZ/Hjjz/qXL4G3D4iIqJqSsKnyO/fvx+BgYF47rnnYG1tDS8vL4wZMwapqak6HV9cXIzw8HC0bt0a1tbWqFOnDkaOHImkpKRyxbFw4UJ4enrivffeQ0pKSrmvo7CwEIcOHULfvn3h5+eH2NhYnY9lEkRERGRChBCYPn06hg8fjuvXr2P06NGYM2cOunfvjtOnT+uciAQHB2P27NkoKirC7Nmz8eKLL+LAgQPo1KkTLl++rHM8hw4dQv369bFs2TI0atQI/v7+eP/99/HTTz/hwYMHGuWLi4tx+fJlfPPNN5g2bRrq16+Pl156CVFRUZgzZw5mzZqlc90yUVGPZjVRWVlZUCgUSABgJ3UwVOFcv5Y6AqpUo6QOgCpDVhagcAMyMzNhb29fQXU8+a7IbATYG9Cak1UEKP4sX6xr1qzBnDlzMHPmTHz++ecwN1cPoLCwEBYWpc+bOnXqFHr37o3u3bvjxIkTkMvlAICTJ08iMDAQ3bt3R2RkpM7XIYTAjh07EB4ejvPnz6ut+2NpaQlHR0fI5XJkZGQgKytL7Th7e3uMHTsW8+bNg6enp851AkyCjI5JkGlhEmRimASZhEpNghobIQlK1j3Wx48fo2HDhnBwcMDVq1fLTHZK8uqrr2L37t2IjIxEjx491PYNGDAAR48exdWrV+Hj41Puc//xxx/YvXs3fvnlF8TGxiIvL0+jjLu7O/z9/dG3b1+88sorsLa21us6OEWeiIjIRJw4cQL379/HpEmTUFRUhAMHDiAxMREODg544YUX0LhxY53OExERARsbG/j5+Wns69evH44ePYrIyEi9kqDnn38ezz//PIAnrVJpaWlIT09Hbm4unJycULduXTg4OJT7vNowCSIiIpKKgYOby0s5aNjCwgJt2rTB1atXVfvMzMzw1ltv4aOPPir1HDk5Obhz5w5atWql0ZUGAE2aNAGAcg+Q1sbCwgINGzZEw4YNDT6XNhwYTUREJBUjTZHPyspSe2nrQgKAe/fuAQA+/vhj2Nvb49y5c8jOzkZUVBR8fHzw8ccf46uvvio15MzMTACAQqHQul/ZLacsV5UxCSIiIpKKkabIu7m5QaFQqF4rV67UWl1x8ZPHzltaWuI///kPOnXqBFtbW3Tv3h379u2DmZkZPv7444q62iqH3WFERETVXGpqqtrAaOVsrWcpW286duyIBg0aqO1r2bIlGjVqhOTkZGRkZJQ47kZ5jpJaepSzt0pqKXpWo0aNdCpXGplMhmvXrpX7OJ2SIGME+DR9gyUiIqpRjDQmyN7eXqfZYU2bNgWAEhMc5fbHjx+XWMbGxgb169fH9evXUVRUpDEuSDkWSDk2qCw3btzQqZw2MpkMQgi1KfXloVMSZEiA2ugbLBERUY1i6KMvyrnITa9evQAACQkJGvsKCgqQnJwMGxsb1KlTp9TzBAQEYM+ePYiJidGYIn/s2DFVGV1cv35d6/Zvv/0W//rXv9C8eXO8/vrraN68OerVq4d79+4hISEBa9euRUJCAt59912MHDlSp7qepXN3WKdOnbB37169KnnaK6+8gt9++83g8xAREVH5eHt7o2/fvjh+/Dg2btyIKVOmqPZ98MEHyMjIwLhx41TrB6WnpyM9PR3Ozs5wdnZWlZ02bRr27NmDpUuX4qeffoKlpSWAJ4slHjt2DD169NB5eryHh4fGtp9++glLlizBnDlzNGar+fj4wN/fH1OnTsW8efOwePFitG/fXut5yqLTYolmZmbw9/dHVFRUuSt4lnJZ7qKiIoPPVRVxsUTTwsUSTQwXSzQJlbpYYgfA3oDRuVmFgOK38sV67do1dOvWDffu3cPAgQPRrFkz/P777/j555/h4eGBs2fPwsXFBQAQGhqKsLAwhISEIDQ0VO08U6dOxcaNG9GiRQsMHDgQd+/exbfffgsrKyucPn0aLVq00Pu6evfujT/++ANpaWlap+ErFRYWwsXFBW3atMHJkyfLXY9OjXBDhgzRaO7SV/fu3TFkyBCjnIuIiKhak+ABqt7e3oiNjcWkSZPw22+/Yc2aNUhKSsLMmTNx7tw5VQJUlvXr12PNmjWQyWRYs2YNDh8+jMGDB+PcuXMGJUAAcOHCBTRq1KjUBAh4so6Qt7e33j1MfGyGkbElyLSwJcjEsCXIJFRqS5CvEVqCzlVsrFJQKBSQy+VIS0uDmVnJ7TVFRUWoX78+8vLy9FqXqNLWCUpMTKysqoiIiKoHIy2WWNN06tQJ//zzD5YtW1ZqubCwMKSnp6NTp0561aPz7StrGe3S/Pe//9V5lDgREZHJkKA7rDr417/+BZlMhpUrV6Jr167Ytm0bzp07h+vXr+PcuXP45ptv0K1bN6xYsQJmZmZlJksl0bkRbsGCBahVqxbmzJlTrgrOnTuHAQMGICMjo7yxERERkQkKCAjAjh07MG3aNPz66684d+6cRhkhBGxsbLB+/Xq9xy2Xqydy7ty5sLCwwMyZM3UqHxkZiSFDhiA7OxvdunXTK0AiIqIay9AurRraHQYAo0ePRo8ePfDVV1/h+PHjSExMxMOHD2FrawsfHx/07dsXwcHBcHV11bsOnZOgzZs347XXXsMbb7wBCwsLTJ8+vdTyR48excsvv4zHjx+jT58++OGHH/QOkoiIqEYytEurhk9tatCgAd599128++67FXJ+nXPIiRMn4uuvn0yFmTlzJjZu3Fhi2e+//x5Dhw7F48ePMXjwYBw6dAi1a9c2PFoiIqKahGOCJFWuhrSgoCCsX78eQggEBwdj69atGmW++eYbjB49Gvn5+Rg1ahS+++67Eh/kRkRERCSVcq9OMGXKFBQVFeH111/HlClTYG5ujvHjxwMAvvrqK8yePRvFxcUICgrChg0b+JwwIiKikshg2LieGvwVW1BQgC1btuDIkSP4888/8fDhQ5S0tGGFPkX+WdOnT0dxcTFmzpyJoKAgWFhYIDU1FYsWLYIQAm+88QY+++wzfU5NRERkOgzt0io2ViBVS3p6Onr37o1Lly6VmPg8rUKfIq/NjBkzUFRUhDfeeAPjx4+HEAJCCCxatAgrVqzQ97RERERk4hYuXIj4+Hg0bNgQ8+fPR6dOnVC3bt1SV4/WhwGLdQOzZs2CEAJz5sxRLWq0YMECY8VGRERUs7ElSKtDhw6hVq1a+Pnnn9G4ceMKq0fnlKpRo0ZaX59++ilq1aoFc3NzrF+/vsRy3t7eegfp6ekJmUym9RUcHKxRPisrC3PnzoWHhwfkcjk8PDwwd+5cZGVllVjHrl274OvrCxsbGzg6OuLFF19EbGys3jETERGViY/N0CozMxNNmzat0AQIKEdL0I0bNwwqY+gAaYVCgTfffFNje8eOHdX+nZOTg4CAAFy8eBGBgYEYM2YM4uLi8Omnn+LUqVOIjo6GjY2N2jHvv/8+lixZAnd3dwQHB+Phw4fYs2cP/Pz8cOzYMfTs2dOg2ImIiEh3jRs3Rn5+foXXo3MStGXLloqMo0wODg4IDQ0ts9yqVatw8eJFzJ8/Hx9++KFqe0hICJYvX45Vq1YhLCxMtT0pKQkhISHw8fHBuXPnoFAoAABvvPEGfH19MWXKFFy5cgUWFgb1HBIREWlid5hWU6ZMwdy5c/Hbb7+hQ4cOFVaPTOgy7Fpinp6eAMpujRJCoGHDhsjKykJaWppai09ubi4aNGiA2rVrIzU1VdUytXjxYqxcuRLbtm3DhAkT1M43Y8YMrFu3DseOHUPfvn11ijUrKwsKhQIJAOx0vkKqrly/ljoCqlSjpA6AKkNWFqBwe9IlY29vX0F1PPmuyBwG2Ncy4DwFgGJ/xcYqBSEExo8fj8jISISHh+Oll16qkHqqTfNGXl4etm3bhlu3bsHR0RHdunVDmzZt1MokJSXh9u3b6Nevn0aXl5WVFXr06IEffvgBycnJaNKkCQAgIiICALQmOf369cO6desQGRmpcxJEREREhunTpw8A4N69exg+fDgcHR3h7e2t8d2uJJPJcPLkyXLXU22SoLS0NEyaNEltW//+/bF9+3Y4OzsDeJIEAVAlOM9Sbk9KSlL7f1tbW7i4uJRaviR5eXnIy8tT/bu0wddERERq2B2mlbKBQun+/fu4f/9+ieUrdJ2gb775BvXq1UO/fv30quRpx44dw927dzW6nkoTFBSEgIAAtGzZEnK5HJcvX0ZYWBiOHDmCIUOGICYmBjKZDJmZmQCgGtfzLGVTobKc8v/r1q2rc/lnrVy5Um2MERERkc7MYFgSVGSsQKqWU6dOVUo9OiVBkyZNgr+/v1GSoPfeew+nT58uVxK0bNkytX937twZhw4dQkBAAKKjo/Hjjz9i4MCBBsemj0WLFmHu3Lmqf2dlZcHNzU2SWIiIqJoxdJp7DZ0iHxAQUCn1VNvbZ2ZmhsmTJwMAYmJiAPyvBaiklhtlV9XTLUUKhaJc5Z8ll8thb2+v9iIiIqKqT+cxQX/88Qd69+5tcIV//PGHwedQUo4FevToEYCyx/BoGzPUpEkTnDlzBmlpaRrjgsoaY0RERGQQQ8cEGXJsNZGTk4OYmBgkJiYiOzsbdnZ28PHxgZ+fX4kDpXWlcxKUmZmpMVBJX8Z6svyvv/4K4H9T6Js0aYIGDRogJiYGOTk5GlPko6Ki0KBBA7UVKAMCAnDmzBkcP35co4vu2LFjqjJERERGxySoRPn5+QgJCcGXX36JnJwcjf02NjaYPXs2QkJCYGlpqVcdOiVBlTVASZvLly+jQYMGcHBwUNseHR2NTz75BHK5HMOHDwfwJLmaMmUKli9fjuXLl6stlrhy5Uo8ePAAs2fPVkvCJk+ejI8++ggrVqzASy+9pOr6unTpEr755ht4e3sbpQWMiIiIdFNUVIQhQ4bgxIkTqjUAmzVrhnr16uHu3bu4cuUK/vrrL3zwwQf47bffcPjwYZiblz8j1CkJkrIlZO/evVi1ahX69OkDT09PyOVyxMfH4/jx4zAzM8O6devg7u6uKj9//nwcOHAAq1atwu+//44OHTogLi4OR44cQdu2bTF//ny18/v4+CA0NBRLly5F69atMWLECOTk5GD37t0oKCjAhg0buFo0ERFVDA6M1mr9+vU4fvw46tWrhy+++AIvv/yyWgOGEALfffcd5syZgxMnTuDrr7/GjBkzyl1PlV8xOjIyEmvXrsWFCxdw9+5d5Obmol69evD398dbb70FX19fjWMyMzMRFhaGffv2qcb6jBgxAiEhISUOct65cyc+++wzXLp0CZaWlujatSuWL1+OTp06lSterhhtWrhitInhitEmoVJXjH4NsNevJ+fJefIBxaaat2J0ly5dcP78eZw/fx7t27cvsdyFCxfQsWNH+Pr64uzZs+Wup8onQdUNkyDTwiTIxDAJMglMgqSnUCjg5uaG+Pj4Msu2atUKN2/e1GuxYvbzEBERSYXdYVoVFRWhVi3dHqpWq1YtFBfrt3R2Db19RERE1YByxWh9XzX0W9zb2xvx8fFlPjj9+vXriI+Ph7e3t1711NDbR0RERNXVK6+8gqKiIrz00kv473//q7VMXFwchg4diuLiYowcOVKvetgdRkREJBWuE6TV3LlzsXfvXvzxxx9o164d/P390aJFC9StWxf37t3D5cuXER0dDSEEWrdurfb4qvJgEkRERCQVjgnSqnbt2vj5558RHByM/fv345dffsEvv/wCmUwG5XwumUyGl19+GV999RWsra31qkfnJKh3795o3bo1PvvsM70qIiIiomewJahEzs7O2LdvH5KTk3HixAkkJibi4cOHsLW1hY+PD/r27av3WCAlnZOgiIgIFBYWGlQZERERUXk0btxY7XFXxsTuMCIiIqmwJUhSNbQ3kYiIqBowM8KrBoqKikLv3r2xfv36UsutW7cOvXv3RkxMjF711NDbR0RERNXVxo0bERkZia5du5ZarmvXroiIiMDmzZv1qofdYURERFJhd5hWZ8+ehZOTE1q3bl1quTZt2uC5557TuyWoXElQTEyMXo+qB55MZePAaiIioqfIYFifjKzsItXRrVu30KJFC53Kenp64sqVK3rVU65bL4Qw6EVERETS8/T0hEwm0/oKDg7W6RwRERElnkMmk+n1VHclS0tLZGdn61Q2OzsbZmb6ZZLlagl6/vnnsWbNGr0qIiIiomdI2B2mUCjw5ptvamzv2LFjuc4TEBCAnj17amxv2LChnpEBzZo1w7lz55CYmAgfH58SyyUmJiIxMREdOnTQq55yJUEKhQIBAQF6VURERETPkDAJcnBwQGhoqAGVP9GzZ0+jnOdpL7/8Mn799VdMmDABR48ehYODg0aZjIwMTJw4ETKZDK+88ope9XBgNBEREVUpM2fOxObNm3H+/Hk0b94cr732Gjp37gwHBwdkZGTg7Nmz2Lx5M+7evYtmzZph9uzZetXDJIiIiEgqEj47LC8vD9u2bcOtW7fg6OiIbt26oU2bNuU+T1JSEtasWYNHjx7Bw8MDgYGBcHZ21j8wANbW1jh27BiGDRuGCxcuYOXKlRplhBDo2LEjvvvuu4p/dhgREREZmZG6w7KystQ2y+VyyOXyUg9NS0vDpEmT1Lb1798f27dvL1cSs2vXLuzatUv1b2tra4SFhWHevHk6n0MbNzc3nDt3Dt9//z1++OEHJCQkICsrC3Z2dmjZsiWGDh2KoUOH6j0oGmASREREJB0jJUFubm5qm0NCQkodpxMUFISAgAC0bNkScrkcly9fRlhYGI4cOYIhQ4YgJiYGMlnp8+/r1KmD1atXY9CgQXB3d0dGRgZOnTqFBQsWYP78+bC3t8f06dMNuDjAzMwMI0aMwIgRIww6T0lkgnPXjSorKwsKhQIJAOykDoYqnOvXUkdAlWqU1AFQZcjKAhRuQGZmJuzt7SuojiffFZnvA/ZWBpwnF1AsBlJTU9Vi1aUl6FnFxcUICAhAdHQ0Dh06hIEDB+oVU3x8PDp06ABHR0fcvn3boJaailZ1IyMiIqrpjPTsMHt7e7VXeRMg4Emry+TJkwFA7xWYAaBVq1bo3Lkz7t69i+TkZL3PUxmYBBEREUnFDP/rEtPnZeRvceVYoEePHlXaeVq1aoVvv/3W4EWVb968ieDgYHz44Yc6H8MkiIiIiAAAv/76K4AnK0rrq7CwEBcuXIBMJoO7u3uZ5bOzs/Hqq6/Cx8cH7777LpKSknSuKz8/H/v378eIESPQpEkTbNy4EXXr1tX5eA6MJiIikooEU+QvX76MBg0aaCxAGB0djU8++QRyuRzDhw9XbU9PT0d6ejqcnZ3VZo2dOXMGXbp0URtAXVhYiHnz5iElJQX9+/eHk5NTmfEkJiZizZo1+OCDD1QDur29veHr64sOHTqgfv36cHJyglwuR0ZGBu7fv4+EhATExsYiNjYWOTk5EEIgMDAQH374Idq2bavzvWASREREJBUJVozeu3cvVq1ahT59+sDT0xNyuRzx8fE4fvw4zMzMsG7dOrUWnPDwcISFhWnMOBszZgxkMhm6desGV1dXZGRkICoqClevXoW7uzvWrVunUzxyuRzz5s1DcHAwduzYgQ0bNuDixYtITk7G7t27tR6j7DqzsbFBUFAQpk2bhk6dOpX7XjAJIiIiMiG9evVCQkICLly4gMjISOTm5qJevXoYNWoU3nrrLfj6+up0nhkzZuDo0aOIiIhAeno6LCws0LhxYyxZsgRvv/02HB0dyxWXnZ0dZsyYgRkzZiApKQlRUVE4ffo0UlJSkJ6ejtzcXDg5OaFu3bpo27Yt/P390a1bN9SuXVuf2wCAU+SNjlPkTQunyJsYTpE3CZU6RX4NYK/fYsdPzvMYULxRsbHWZGwJIiIikoqEj80g3j4iIiIyUWwJIiIikooEA6Orur///hs//PADfv31VyQlJeHBgwd4/PgxrK2t4ejoiCZNmqBz584YMmRIuabDa8MkiIiISCrsDlPJzc3F/Pnz8fXXX6OgoKDExROjoqKwefNmzJo1C1OnTsWqVav4FHkiIqJqR7litCHH1wB5eXno2bMnzp8/DyEEmjVrBj8/PzRq1AiOjo6Qy+XIy8vDgwcP8OeffyImJgZXrlzB2rVrce7cOfzyyy+wtLQsd71MgoiIiEhSq1evxrlz59C0aVNs3rwZXbt2LfOY06dPIygoCLGxsVi1ahWWLl1a7nprSA5JRERUDRny3DBDxxNVIbt374alpSWOHz+uUwIEAN26dcOxY8dgYWGBXbt26VUvW4KIiIikwjFBAIDr16+jVatWcHNzK9dxHh4eaNWqFRISEvSqt4bcPiIiIqqubG1tce/ePb2OvXfvHmxsbPQ6lkkQERGRVNgdBgDo2rUrbt26hU8++aRcx3300Ue4desWunXrple9TIKIiIikwiQIALBw4UKYmZlh3rx5ePHFF7Fv3z7cuXNHa9k7d+5g3759GDBgABYsWABzc3MsWrRIr3o5JoiIiIgk1bVrV2zduhVTpkzB0aNHcezYMQBPnjDv4OAAS0tL5OfnIyMjA3l5eQCePEne0tISGzZsQJcuXfSqly1BREREUjEzwquGGDt2LK5cuYIZM2bAxcUFQgjk5uYiLS0NN2/eRFpaGnJzcyGEQL169TBjxgxcuXIF48eP17tOtgQRERFJhY/NUOPh4YEvv/wSX375JW7evKl6bEZubi6srKxUj81wd3c3Sn1MgoiIiKjKcXd3N1qyUxImQURERFKRwbAuLZmxAjFNTIKIiIikwu4wg926dQtFRUV6tRoxCSIiIpIKkyCDtW3bFg8ePEBhYWG5j61B48qJiIjIFAkh9DqOLUFERERS4bPDJMUkiIiISCrsDgMAvP/++3of+/jxY72PZRJEREREklq6dClkMv2mugkh9D6WSRAREZFU2BIEADA3N0dxcTGGDx8OW1vbch27Z88e5Ofn61UvkyAiIiKpcEwQAKBly5b4448/MHXqVPTt27dcxx46dAj379/Xq94acvuIiIiouvL19QUAxMbGVmq9bAmqIO3BhTxNwcFpUkdAlan3YqkjoEpRXIl1mcGwLq0a0pTh6+uLjRs34tdffy33sfpOjweYBBEREUmH3WEAgBdeeAFz5syBs7NzuY89cOAACgoK9KqXSRARERFJytPTE59++qlex3br1k3vepkEERERSYWzwyTFJIiIiEgqTIIkxSSIiIhIKhwTJCkmQURERFSlmJvr3sRlZmYGOzs7eHp6wt/fH1OmTEHr1q11O1bfAImIiMhA5kZ41UBCCJ1fRUVFyMjIwMWLFxEeHo4OHTpg9erVOtXDJIiIiEgqTIK0Ki4uxieffAK5XI6JEyciIiIC9+/fR0FBAe7fv4/IyEhMmjQJcrkcn3zyCR4+fIjY2Fi8/vrrEEJg4cKFOHnyZJn1sDuMiIiIqpTvvvsOb7/9NsLDwzFjxgy1fQ4ODujevTu6d++OTp06YdasWXB1dcUrr7yC9u3bo1GjRnjnnXcQHh6OPn36lFqPTBiy1CJpyMrKgkKhgDW4YrQpOCh1AFSpepd/HTeqhrKKAcV9IDMzE/b29hVTx/9/V2T+DtjbGXCebEDRrmJjlULXrl2RmpqKv/76q8yyDRs2RMOGDXH27FkAQGFhIZydnWFtbY07d+6Ueiy7w4iIiKTC7jCt4uPj4erqqlNZV1dXXL58WfVvCwsL+Pj46PRQVSZBREREVKXUqlULiYmJyMvLK7VcXl4eEhMTYWGhPronKysLdnZlN7ExCSIiIpKKmRFeevD09IRMJtP6Cg4O1vk8xcXFCA8PR+vWrWFtbY06depg5MiRSEpK0i+w/+fn54esrCzMmjULxcXan2grhMDs2bORmZkJf39/1fb8/Hxcv34dDRo0KLMeDowmIiKSioQrRisUCrz55psa2zt27KjzOYKDg7Fhwwa0aNECs2fPxt27d/Htt9/i+PHjOH36NFq0aKFXbMuXL8dPP/2EzZs34/Tp0xg/fjxat24NOzs7PHz4EP/973+xY8cOXL58GXK5HMuXL1cdu3//fhQUFKBXr15l1sOB0UbGgdGmhQOjTQsHRpuGSh0YnWCEgdHNyx+rp6cnAODGjRt6133q1Cn07t0b3bt3x4kTJyCXywEAJ0+eRGBgILp3747IyEi9z//TTz9h/PjxuHv3LmQyzW9UIQRcXFywfft2tVlgERERSElJQffu3dGoUaNS62BLEBERkVSq8bPDNmzYAAB47733VAkQAPTp0wf9+vXD0aNHkZiYCB8fH73O/8ILLyApKQm7du3CiRMnkJSUhJycHNjY2MDHxweBgYEYM2YMbG1t1Y7r2bOnznUwCSIiIpKKhM8Oy8vLw7Zt23Dr1i04OjqiW7duaNOmjc7HR0REwMbGBn5+fhr7lElQZGSk3kkQANja2mLatGmYNm2a3ucoDZMgIiIiqRipJSgrK0tts1wuV2ud0SYtLQ2TJk1S29a/f39s374dzs6l9/3m5OTgzp07aNWqldbnfDVp0gQADB4gXdGYBBEREVVzbm5uav8OCQlBaGhoieWDgoIQEBCAli1bQi6X4/LlywgLC8ORI0cwZMgQxMTEaB2Ho5SZmQngyeBqbZTjk5TlDHH9+nWcOHECiYmJyM7Ohp2dnao7zMvLy6BzMwkiIiKSihkMawn6/+6w1NRUtYHRZbUCLVu2TO3fnTt3xqFDhxAQEIDo6Gj8+OOPGDhwoAGBGe7Bgwd4/fXX8e9//xvKOVxCCFVyJpPJMGrUKISHh8PR0VGvOpgEERERScVIY4Ls7e0NnslmZmaGyZMnIzo6GjExMaUmQcoWoJJaepTdcyW1FJXl8ePH6NOnD+Li4iCEQNeuXdGyZUvUq1cPd+/exaVLl3DmzBns2bMHV65cQUxMDKysrMpdD5MgIiIiAgDVWKBHjx6VWs7Gxgb169fH9evXUVRUpDEuSDkWSDk2qLw+/fRTXLx4Ec2aNcM333yjde2i2NhYTJw4ERcvXsRnn32GhQsXlrserhhNREQklSr27LBff/0VwP/WESpNQEAAcnJyEBMTo7Hv2LFjqjL62Lt3L8zNzXHo0KESF2/s2LEjDhw4ADMzM+zZs0evepgEERERSUWCx2ZcvnwZGRkZGtujo6PxySefQC6XY/jw4art6enpuHLlCtLT09XKK6etL126FPn5+artJ0+exLFjx9CjRw+9p8cnJyejVatWZS526O3tjVatWiE5OVmvepgEERERmZC9e/eiQYMGGDx4MGbPno133nkH/fv3R48ePVBQUIDw8HC4u7uryoeHh6N58+YIDw9XO0+vXr0wZcoU/PLLL2jXrh3mz5+PiRMnYuDAgbC3t8dXX32ld4zm5uYoKCjQqWxBQQHMzPRLZzgmiIiISCoSrBjdq1cvJCQk4MKFC4iMjERubi7q1auHUaNG4a233oKvr6/O51q/fj1at26N9evXY82aNbC1tcXgwYOxYsUKgxZJbNq0KX777TfExcWVuoDjxYsXcfnyZXTq1EmvevjsMCPjs8NMC58dZlr47DDTUKnPDrsPGFJFVhagcKrYWKXwxRdfYM6cOXB1dcXatWsxePBgjTIHDhzArFmzcOvWLXz++eeYNWtWuethSxARERFVKTNmzMB//vMfnDp1CkOHDoW7uzuaNWuGunXr4t69e0hISEBqaiqEEOjduzdmzJihVz1MgoiIiKQi4bPDqjILCwscPnwYS5cuxbp165CSkoKUlBS1MrVr18aMGTPw7rvvan10hy7YHWZk7A4zLewOMy3sDjMNldodlmkGe3v9vy2ysgQUiuIa1x32tOzsbERHRyMxMREPHz6Era0tfHx84O/vDzs7O4POzZYgIiIiyVjAsD+ZBYD8MktVZ3Z2dhgwYAAGDBhg9HMzCSIiIiLJ3Lx50yjneXpav66YBBEREUmGLUGenp6lPrFeFzKZDIWFheU+jkkQERGRZIyRBFVv7u7uBidB+mISRERERJK5ceOGZHUzCSIiIpKMOQyb515srEBMEpMgIiIiyViASZB0augyS0RERESlY0sQERGRZNgSJCUmQURERJJhEiQldocRERGRSWJLEBERkWQMnR3Gp1QagkkQERGRZMz//6WvImMFYpKYBBEREUnGAoYlQWwJMgTHBBEREZFJYksQERGRZNgSJCUmQURERJJhEiQldocRERGRSWJLEBERkWTYEiQlJkFERESSMQe/iqXD7jAiIiIySUw/iYiIJGMBfhVLh3eeiIhIMkyCpMTuMCIiIjJJTD+JiIgkw5YgKVX5lqCtW7dCJpOV+urTp4/aMVlZWZg7dy48PDwgl8vh4eGBuXPnIisrq8R6du3aBV9fX9jY2MDR0REvvvgiYmNjK/ryiIjIpClnh+n7MmR6PVX59LNt27YICQnRum/fvn24dOkS+vXrp9qWk5ODgIAAXLx4EYGBgRgzZgzi4uLw6aef4tSpU4iOjoaNjY3aed5//30sWbIE7u7uCA4OxsOHD7Fnzx74+fnh2LFj6NmzZ0VeIhERmSxDW4KEsQIxSTIhRLW8g/n5+WjQoAEyMzPx119/oV69egCAkJAQLF++HPPnz8eHH36oKq/cvmzZMoSFham2JyUloUWLFmjUqBHOnTsHhUIBALh06RJ8fX1Rv359XLlyBRYWur1Js7KyoFAoYA0uYWUKDkodAFWq3s5SR0CVIasYUNwHMjMzYW9vXzF1/P93RWbmANjb1zLgPAVQKI5UaKw1WZXvDivJ/v378c8//2DQoEGqBEgIgY0bN8LW1hbLli1TK79o0SI4Ojpi06ZNeDrv27JlCwoLC7FkyRJVAgQALVu2xIQJE3Dt2jX8/PPPlXNRRERkYgzpCuN4IkNV2yRo06ZNAIApU6aotiUlJeH27dvw8/PT6PKysrJCjx49cOvWLSQnJ6u2R0REAAD69u2rUYeymy0yMtLY4RMREYFJkLSqZRKUkpKCkydPwtXVFf3791dtT0pKAgA0adJE63HK7cpyyv+3tbWFi4uLTuWflZeXh6ysLLUXERERVX3VMgnasmULiouLMXnyZJib/29kfGZmJgCodWs9Tdlfqiyn/P/ylH/WypUroVAoVC83N7fyXQwREZkwtgRJqdolQcXFxdiyZQtkMhmCgoKkDgeLFi1CZmam6pWamip1SEREVG1wiryUql0KeeLECdy8eRN9+vSBl5eX2j5li05JLTfKrqqnW36ejM7Xvfyz5HI55HK57hdAREREVUK1awnSNiBaqawxPNrGDDVp0gQPHz5EWlqaTuWJiIiMx9wIL8OsWrVKtfjw2bNndT4uIiKi1IWMy3MuqVSrlqB//vkHP/zwA5ycnDBs2DCN/U2aNEGDBg0QExODnJwctRliubm5iIqKQoMGDdC4cWPV9oCAAJw5cwbHjx/HhAkT1M537NgxVRkiIiLjM3RcT7FBtSckJGDZsmWwsbFBTk6OXucICAjQuqhww4YNDYqtMlSrJGj79u3Iz8/HuHHjtHZByWQyTJkyBcuXL8fy5cvVFktcuXIlHjx4gNmzZ0Mm+98yhpMnT8ZHH32EFStW4KWXXlJbLPGbb76Bt7c3evfuXfEXR0REVImKioowceJEtGnTBj4+PtixY4de5+nZsydCQ0ONG1wlqVZJUGldYUrz58/HgQMHsGrVKvz+++/o0KED4uLicOTIEbRt2xbz589XK+/j44PQ0FAsXboUrVu3xogRI5CTk4Pdu3ejoKAAGzZs0Hm1aCIiovKRriXoww8/RFxcHC5cuIDVq1cbEEP1VW2+3c+dO4f4+Hj4+vri+eefL7GcjY0NIiIiEBYWhn379iEiIgIuLi546623EBISorGIIgAsWbIEnp6e+Oyzz/DVV1/B0tIS3bp1w/Lly9GpU6eKvCwiIjJp0iRB8fHxCAsLw9KlS9GyZUsD6n8yfnbNmjV49OgRPDw8EBgYCGfn6vGMmWr77LCqis8OMy18dphp4bPDTEPlPjvsddjb6z/DOCsrDwrFWqSmpqrFWtrM5cLCQnTp0gWFhYU4f/48atWqhUmTJmHbtm04c+YMunTpolPdERER6NWrl8Z2a2trhIWFYd68efpdVCWqdrPDiIiISJ2bm5vawr0rV64ssez777+PuLg4bN68GbVq6f/w1jp16mD16tVISEhATk4Obt26hR07dsDJyQnz58/H+vXr9T53Zak23WFEREQ1j6HdYUUAoLUlSJu4uDi89957eOedd9C+fXsD6n3yoPGnu9Jq166NsWPHok2bNujQoQNCQkIwdepUmJlV3faWqhsZERFRjWecx2bY29urvUpKgiZOnAhvb+8Knc3VqlUrdO7cGXfv3lV7YHlVxJYgIiIiExEXFwcAsLKy0rq/a9euAID9+/dj6NChetejHBj96NEjvc9RGZgEERERScY43WG6eu2117Ruj4qKQlJSEoYMGYI6derA09NT74gKCwtx4cIFyGQyuLu7632eysAkiIiISDLKB6jqq7BcpTdu3Kh1+6RJk5CUlIRFixZpzA5LT09Heno6nJ2d1aa+K2eSPb0AcWFhIebNm4eUlBT0798fTk5O5YqvsjEJIiIiohKFh4cjLCwMISEhamOJxowZA5lMhm7dusHV1RUZGRmIiorC1atX4e7ujnXr1kkXtI6YBBEREUnG0O4w6b7GZ8yYgaNHjyIiIgLp6emwsLBA48aNsWTJErz99ttwdHSULDZdcbFEI+NiiaaFiyWaFi6WaBoqd7HEMNjbax+krNt5cqFQhFRorDUZp8gTERGRSWJ3GBERkWSqb3dYTcC7R0REJBkmQVLi3SMiIpKMoVPkzY0ViEnimCAiIiIySWwJIiIikgy7w6TEu0dERCQZJkFSYncYERERmSSmkERERJIxh2GDmzkw2hBMgoiIiCTD2WFSYncYERERmSS2BBEREUmGA6OlxLtHREQkGSZBUmJ3GBEREZkkppBERESSYUuQlHj3iIiIJMMkSEq8e0RERJLhFHkpcUwQERERmSS2BBEREUmG3WFS4t0jIiKSDJMgKbE7jIiIiEwSU0giIiLJsCVISrx7REREkmESJCV2hxEREZFJYgpJREQkGa4TJCUmQURERJJhd5iUePeIiIgkwyRIShwTRERERCaJKSQREZFk2BIkJd49IiIiyXBgtJTYHUZEREQmiS1BREREkjGHYa05bAkyBJMgIiIiyXBMkJTYHUZEREQmiSkkERGRZNgSJCXePSIiIskwCZISu8OIiIjIJDGFJCIi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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "### Define inputs\n", + "# Control time set [h]\n", + "t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", + "# Define parameter nominal value\n", + "parameter_dict = {\"A1\": 85, \"A2\": 372, \"E1\": 8, \"E2\": 15}\n", + "\n", + "# measurement object\n", + "measurements = MeasurementVariables()\n", + "measurements.add_variables(\n", + " \"C\", # variable name\n", + " indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, # indices\n", + " time_index_position=1,\n", + ") # position of time index\n", + "\n", + "# design object\n", + "exp_design = DesignVariables()\n", + "\n", + "# add CAO as design variable\n", + "exp_design.add_variables(\n", + " \"CA0\", # variable name\n", + " indices={0: [0]}, # indices\n", + " time_index_position=0, # position of time index\n", + " values=[5], # nominal value\n", + " lower_bounds=1, # lower bound\n", + " upper_bounds=5, # upper bound\n", + ")\n", + "\n", + "# add T as design variable\n", + "exp_design.add_variables(\n", + " \"T\", # variable name\n", + " indices={0: t_control}, # indices\n", + " time_index_position=0, # position of time index\n", + " values=[470, 300, 300, 300, 300, 300, 300, 300, 300], # nominal value\n", + " lower_bounds=300, # lower bound\n", + " upper_bounds=700, # upper bound\n", + ")\n", + "\n", + "# For each variable, we define a list of possible values that are used\n", + "# in the sensitivity analysis\n", + "\n", + "design_ranges = {\n", + " \"CA0[0]\": [1, 3, 5],\n", + " (\n", + " \"T[0]\",\n", + " \"T[0.125]\",\n", + " \"T[0.25]\",\n", + " \"T[0.375]\",\n", + " \"T[0.5]\",\n", + " \"T[0.625]\",\n", + " \"T[0.75]\",\n", + " \"T[0.875]\",\n", + " \"T[1]\",\n", + " ): [300, 500, 700],\n", + "}\n", + "## choose from \"sequential_finite\", \"direct_kaug\"\n", + "sensi_opt = \"direct_kaug\"\n", + "\n", + "prior_pass = [\n", + " [22.52943024, 1.84034314, -70.23273336, -11.09432962],\n", + " [1.84034314, 18.09848116, -5.73565034, -109.15866135],\n", + " [-70.23273336, -5.73565034, 218.94192843, 34.57680848],\n", + " [-11.09432962, -109.15866135, 34.57680848, 658.37644634],\n", + "]\n", + "\n", + "doe_object = DesignOfExperiments(\n", + " parameter_dict, # parameter dictionary\n", + " exp_design, # design variables\n", + " measurements, # measurement variables\n", + " create_model, # model function\n", + " prior_FIM = prior_pass, \n", + " discretize_model=disc_for_measure, # discretization function\n", + ")\n", + "# run full factorial grid search\n", + "all_fim = doe_object.run_grid_search(design_ranges, mode=sensi_opt)\n", + "\n", + "all_fim.extract_criteria()\n", + "\n", + "for i in all_fim.store_all_results_dataframe.columns:\n", + " all_fim.store_all_results_dataframe[i] = all_fim.store_all_results_dataframe[i].values.real\n", + "\n", + "\n", + "fixed = {}\n", + "all_fim.figure_drawing(\n", + " fixed, \n", + " [\"CA0[0]\",\"T[0]\"],\n", + " \"Reactor\",\n", + " \"$C_{A0}$ [M]\",\n", + " \"T [K]\"\n", + ")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "b805fb89-45a9-4ca2-8c72-325747d3fd25", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO: =======Iteration Number: 1 =====\n", + "INFO: elapsed time: 0.7\n", + "INFO: This is run 1 out of 8.\n", + "INFO: The code has run 0.7312748000040301 seconds.\n", + "INFO: Estimated remaining time: 2.1938244000120903 seconds\n", + "INFO: =======Iteration Number: 2 =====\n", + "INFO: elapsed time: 0.8\n", + "INFO: This is run 2 out of 8.\n", + "INFO: The code has run 1.5368452000038815 seconds.\n", + "INFO: Estimated remaining time: 2.5614086666731355 seconds\n", + "INFO: =======Iteration Number: 3 =====\n", + "INFO: elapsed time: 0.8\n", + "INFO: This is run 3 out of 8.\n", + "INFO: The code has run 2.300336200009042 seconds.\n", + "INFO: Estimated remaining time: 2.300336200009042 seconds\n", + "INFO: =======Iteration Number: 4 =====\n", + "INFO: elapsed time: 1.0\n", + "INFO: This is run 4 out of 8.\n", + "INFO: The code has run 3.2964527000076487 seconds.\n", + "INFO: Estimated remaining time: 1.9778716200045894 seconds\n", + "INFO: =======Iteration Number: 5 =====\n", + "INFO: elapsed time: 0.7\n", + "INFO: This is run 5 out of 8.\n", + "INFO: The code has run 3.9811715000105323 seconds.\n", + "INFO: Estimated remaining time: 1.3270571666701774 seconds\n", + "INFO: =======Iteration Number: 6 =====\n", + "INFO: elapsed time: 0.7\n", + "INFO: This is run 6 out of 8.\n", + "INFO: The code has run 4.726026500014996 seconds.\n", + "INFO: Estimated remaining time: 0.675146642859285 seconds\n", + "INFO: =======Iteration Number: 7 =====\n", + "INFO: elapsed time: 0.8\n", + "INFO: This is run 7 out of 8.\n", + "INFO: The code has run 5.568790400015132 seconds.\n", + "INFO: Estimated remaining time: 0.0 seconds\n", + "INFO: =======Iteration Number: 8 =====\n", + "INFO: elapsed time: 0.7\n", + "INFO: This is run 8 out of 8.\n", + "INFO: The code has run 6.320087100015371 seconds.\n", + "INFO: Estimated remaining time: -0.7022319000017079 seconds\n", + "INFO: Overall wall clock time [s]: 6.320087100015371\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnwAAAHZCAYAAAAc1OaWAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB4J0lEQVR4nO3de1zOd/8H8NdV6XxQSKKzcogKsVEtoYzdM3O2OUUZcxpzuxlTGXOa5jRnk2nYzWiMiY2EkFPMIaqpHEvSiUrp+/vD77pul+uqrupK9fV6Ph7fx0/f7+d0HX673vfnKBEEQQARERERiZZGTTeAiIiIiKoXAz4iIiIikWPAR0RERCRyDPiIiIiIRI4BHxEREZHIMeAjIiIiEjkGfEREREQix4CPiIiISOQY8BERERGJHAM+IqIqioqKgkQiQdeuXWu6KWXq2rUrJBIJoqKi5O4HBwdDIpEgODi4RtpFRNWPAR/VKba2tpBIJHKXrq4u7OzsMGzYMJw7d66mm1hhWVlZCA4OxvLly2u6KdUqLS0N9erVg0QigYeHR003p0KCg4PfymAoOTkZwcHBCAsLq+mmEFEVMeCjOsnR0REeHh7w8PCAo6MjHj58iJ9//hmdO3fGtm3barp5FZKVlYWQkBDRB3w7duxAcXExACAmJgZJSUk13CLVhYSEICQkpNTn+vr6aNGiBaytrd9gq9SnYcOGaNGiBRo2bCh3Pzk5GSEhIQz4iESAAR/VSV999RVOnjyJkydP4u+//8b9+/cxYMAAvHjxAhMmTMCTJ09quon0GmkgXr9+fQBAeHh4DbZGvTp16oT4+Hj89NNPNd2USpk4cSLi4+MxceLEmm4KEVUTBnwkCqampti8eTMMDAyQm5uLw4cP13ST6BXXr1/HxYsXoaenh2XLlgFAneuJJSKqyxjwkWgYGxvDyckJwMuhKGUiIyPRp08fNG7cGDo6OmjWrBn8/f1LHV48c+YMZsyYAXd3d5ibm0NHRwdWVlYYPnw4rl27VmZ7bt68ibFjx6J58+bQ09NDgwYN0KFDBwQFBeHBgwcAgFGjRsHOzg4AkJKSojA/8XUHDhzA+++/j4YNG0JHRwd2dnb4/PPPcefOHaVtkM55TE5OxrFjx9CrVy80bNhQ6cT96iQN7v71r3/hk08+gbGxMZKSknD69OlKl/n06VPMnz8fLi4uMDAwgLGxMd555x388MMPsqHjV726sKKoqAghISFwcnKCrq4umjZtigkTJiAzM1Muj3Qxg9Trn4/0e1baoo3k5GRIJBLY2toCADZt2oR27dpBX18fTZs2xeTJk5GbmwsAePHiBZYtWwZnZ2fo6emhWbNmmDlzJp4/f67wWvLz87Fjxw4MGTIELVq0gKGhIQwNDeHm5ob58+fj6dOnFXovlS3a6Nq1K3x8fAAAx48fl3vd0tfz7rvvQiKR4Ndffy217O+++w4SiQQDBw6sUJuISM0EojrExsZGACBs2bJF6fMWLVoIAISVK1cqPJsyZYoAQAAgmJubC+3atROMjY0FAIKxsbFw6tQphTwODg4CAKFBgwZCmzZtBFdXV8HExEQAIOjp6QnHjh1T2o7w8HBBW1tblq59+/ZCy5YtBR0dHbn2L1iwQHB3dxcACDo6OoKHh4fc9aqZM2fK2t+sWTOhQ4cOgr6+vgBAMDU1Fc6dO1fq+/Xtt98KGhoagqmpqdCxY0ehWbNmpbZd3V68eCFYWVkJAIS9e/cKgiAIo0aNEgAI48ePr1SZ6enpQtu2bQUAgoaGhuDi4iK0atVK9v74+voK+fn5cnmOHTsmABDee+894YMPPhAACI6OjoKbm5ugpaUlABCaN28upKWlyfJs3rxZ8PDwkJX7+ufz4MEDubK9vb3l6rx9+7YAQLCxsRGmTZsmABAcHByENm3ayOrs1q2b8OLFC6Fv374CAKFVq1ZCixYtBIlEIgAQRowYofD6T5w4IQAQtLS0hGbNmgnu7u6Co6OjrMz27dsLz549U8jn7e0tAFD47IOCggQAQlBQkOzexIkThTZt2sj+/+PV1z1gwABBEARh/fr1AgDhww8/LPWzkpbx+++/l5qGiKofAz6qU8oK+G7duiX7wYuOjpZ7tm7dOgGAYGdnJ/djV1xcLMyfP18WRL0eJGzdulVISkqSu1dUVCRs2rRJ0NLSEuzt7YUXL17IPT937pxQr149AYAwY8YMIS8vT/bs+fPnwo4dO4QTJ07I7r0aFJRm//79sh/48PBw2f3s7Gzh448/FgAItra2Cj/y0vdLU1NTCAkJEYqKigRBEISSkhKhoKCg1PrU6a+//pIFpYWFhYIgCMKRI0cEAIKZmZnsXkX0799fACA4OzsLiYmJsvvnzp0TGjduLHvvXyUNyrS0tARjY2Ph6NGjsmcpKSmCq6urAEAWzLxKGvCVpryAT0tLSzAxMRH+/PNP2bO///5baNCggQBA6Nu3r9CsWTPh0qVLcmVK/0fDtWvX5MpNTk4W/vvf/wq5ubly9x88eCAMGDBAACAEBwcrtLMiAV9Zr0sqOztb0NfXF7S0tOQCZakLFy4IAAQLCwuhuLhYaRlE9GYw4KM6RVnAl52dLRw5ckRo3bq1rBfmVYWFhYKFhYWgqakpXLx4UWm50gDip59+Urktw4YNEwAo9Az27t1bACCMHj1apXJUCfikvUxTpkxRePb06VOhYcOGAgBh8+bNcs+k71dZPTDVTdqbFxAQILv34sULwcLCQq7XT1W3bt2S9X4p+zz/+9//CgAEAwMDIScnR3ZfGrwAEEJDQxXyXb58WQAgSCQShSC/qgEfAOH7779XyDdr1izZc2Xvw5AhQ0ptb2mePXsmaGtrC46OjgrP1B3wCYIgDB8+vNTXN3nyZAGAMH36dJXbT0TVg3P4qE7y9/eXzScyMTGBr68v4uPjMXjwYOzfv18u7enTp/Hw4UO0b98e7dq1U1penz59ALycq/S6+Ph4BAUFoV+/fujatSs8PT3h6ekpS3v58mVZ2vz8fBw5cgQAMGPGDLW81ry8PNlct0mTJik819fXR2BgIACUulhlxIgRamlLReXn58vmd33yySey+xoaGhgyZAiAii/eOHLkCARBgKenp9LPs3///mjWrBmePn2KU6dOKTzX1tZGQECAwn0XFxd4enpCEIRqWfQzevRohXtubm4AADMzM/Tt21fhufT1/fPPPwrPSkpK8Ntvv2HChAno1asXvLy84OnpCV9fX0gkEiQkJODZs2dqfQ3KSF/X1q1b5e4XFRVhx44dAF7OVSWimqVV0w0gqgxHR0eYm5tDEAQ8fPgQ//zzD+rVq4eOHTvC1NRULu3ff/8N4OUEek9PT6XlZWVlAQDu3bsnd3/hwoWYM2cOSkpKSm3LqxP9ExMTUVRUhPr166NFixaVeWkKEhMTUVJSAh0dHdjb2ytN4+zsDAC4deuW0uetWrVSS1sqKiIiArm5ubC0tIS3t7fcs08//RTLly/H77//jidPnih8bqWRvsbWrVsrfa6hoYGWLVvi7t27uHXrFt5//325582aNYORkZHSvK1atcLJkydLfR8rq1GjRjA2NlZ6HwAcHBxKzQe8DPpflZWVhd69e5e76OXJkyfQ19evTJNV5u3tDQcHB8TFxeHKlStwcXEBABw8eBCPHj2Cu7u77PtJRDWHPXxUJ0n34Tt16hSSkpJw8uRJGBkZYfr06Qr7u2VnZwMAHj16hFOnTim9pCtu8/PzZfmio6Px1VdfQSKRYOHChbh27Rry8vJQUlICQRAwe/ZsAC97MqRycnIA/G+vOXWQ/tg3atRI6cpdAGjcuDEAyFZ8vs7AwKDC9f7xxx+y3sxXrx9//FHlMqS9d0OGDIGGhvx/btzd3eHk5ITnz5/jv//9r8plSt8Pc3PzUtOU9X5UNl9VlBZ0ST/P8p4LgiB3f9q0aTh9+jRatGiBX3/9Fffu3UNhYSGEl9N00LRpUwDy383qIpFIZD14r/bySf/N3j2i2oEBH4mCh4cHNm7cCACYMmWKLPACAENDQwAve5SkP4ilXa9uVfLzzz8DAP79739j5syZaN26NQwMDGQ/wsq2QpH2HEl7DNVB2v5Hjx4p/PBLpaWlydWvDmlpaUqD49TUVJXzS4dGQ0NDFbY0kUgksp60igzrSt+P9PT0MusGlL8fjx49KjWftEx1vo/qVlxcLAuQf/vtN/Tr1w+WlpbQ1taWPX/48OEbbdOoUaOgoaGBn3/+GcXFxXj8+DEOHDgAbW1tDB069I22hYiUY8BHotG3b1+8++67yMzMRGhoqOy+dOjv6tWrFSpPusdaly5dlD5/de6elKOjI7S1tZGVlYWbN2+qVE9pvXZSzZs3h4aGBgoLC5XO5QIg66GU7kOoDqNGjVIaFKt6puz27dvx4sUL6OjooHHjxqVeAHDq1KlSX9vrpK/x+vXrSp+XlJQgPj5eLu2r7ty5ozBEKnXjxo1S89UWjx49wtOnT2FmZqZ02sDVq1fx4sULtdRV3ndTqlmzZvD19UVaWhoOHTqE7du34/nz5+jTpw/MzMzU0hYiqhoGfCQqM2fOBACsXLlS9qPu5eWFhg0b4vLlyxXabFhPTw/A/3qLXnX48GGlAZ+enh78/PwAvNxwtiL1vDqc/CpDQ0NZ0Llq1SqF5/n5+di0aRMAoGfPnirV+SZIe+1mzpyJhw8flnp17twZgOpHrfn5+UEikeDkyZO4dOmSwvM9e/bg7t27MDAwgIeHh8Lz58+fY/PmzQr3r169ihMnTkAikcDX11fuWXmf0ZskbUtOTo7S9ixZskTtdanyul9dvMHhXKLahwEfiUqfPn3QqlUrPHnyBGvXrgUA6OrqYt68eQCAgQMHYu/evQpDo1evXsV//vMfuVWd0gUeixYtwu3bt2X3z507h9GjR0NXV1dpG4KCglCvXj1s2rQJX331ldxKyaKiIvzyyy84efKk7F6jRo1gZGSE9PR0WQ/T6/7zn/8AANasWYPt27fL7ufm5mLEiBF49OgRbG1tZStfa9q1a9dkwdiwYcPKTCt9rmrA17x5c/Tr1w/Ay9XHr/YMXrx4EZMnTwbw8nxYZUOzWlpaCAoKkluRfffuXdlK5n79+iksopAullG2ivtNq1+/PpydnVFcXIypU6fKTuJ48eIFFi9ejF9++UU2vFtV0lNgrl+/XuZQOPCyh71BgwaIiIjAhQsXYGFhobBghohq0JvcA4aoqso7aUMQXp6OgP/f7PXVjZRfPanCzMxM6Nixo9C+fXvBzMxMdv+PP/6Qpc/Ozhbs7e0FAIK2trbQtm1b2UkerVu3lp2c8PreZYIgCNu2bZNtvqyvry+0b99eaNWqlaCrq6u0/aNHjxYACLq6uoK7u7vg7e2tsPfZq+23srIS3N3dBQMDA9mmxrGxsaW+X7dv31bl7VWb//znPwIAoXPnzuWmzcjIkL1Xp0+fVqn8V0/a0NTUFFxdXWX7MAIQevToodJJG05OTkK7du1kG3bb29vLTs941bx582R1tWvXTvb5VOSkDWXK2+duy5YtAgBh5MiRcvf37dsn24vQzMxMcHd3l+3F+PXXX5f6uVd0Hz5BEIRu3boJAAQjIyPhnXfeEby9vYXBgwcrbe+kSZNknwH33iOqXdjDR6IzbNgwWFpa4uHDh3IrShcuXIhTp07hk08+gYGBAS5fvozk5GQ0a9YMo0ePxoEDB9C9e3dZemNjY5w8eRIjRoyAsbExbt68iefPn8tWSJY1sX/YsGGIi4uDv78/GjZsiKtXr+LRo0dwdnZGcHCwQs/HihUrMGXKFFhYWODy5cs4fvy4Qm/SwoULsX//fvj6+iIvLw9XrlxBw4YNMW7cOFy+fBkdO3ZU0ztYNSUlJbIFL+X17gFAgwYNZO+Hqos3GjVqhNOnT2PevHlo1aoVbt26hZSUFHTs2BGrVq3CwYMHS+2BlUgk2Lt3L4KDg1FSUoLr16+jUaNGGD9+PM6ePQsLCwuFPDNnzkRQUBCaN2+O69evyz6fgoICldqrbh9++CH++OMPdOnSBfn5+bh58yaaN2+O8PBwWW+2umzfvh2jRo2CsbExLly4gOPHj+PMmTNK0/r7+8v+zeFcotpFIgilLPsjIhKRqKgo+Pj4wNvbu0JzOUl1hw4dQq9eveDu7o5z587VdHOI6BXs4SMiIrWQLoZ5taePiGoHBnxERFRlZ8+exd69e2FsbIxPP/20pptDRK/h0WpERFRpQ4YMQXJyMi5evIgXL15g5syZMDExqelmEdFrGPAREVGlnTlzBqmpqWjWrBkCAgJkWwgRUe3CRRtEREREIsc5fEREREQixyHdOqKkpAT379+HkZGRyudbEhFR7SEIAnJzc2FpaQkNjerpbykoKJCdvlJV2trape5nSXUPA7464v79+7CysqrpZhARURXduXMHzZo1U3u5BQUF0NfTg7rmaVlYWOD27dsM+kSCAV8dIT3V4c6dGBgbG9Zwa4iqh4WJS003gajaCAAKgDJP6amK58+fQwCgB6Cq40ACgIcPH+L58+cM+ESCAV8dIR3GNTY2hLFx9fzHgqimcbICvQ2qe1qOJtQT8JG4MOAjIiISEQZ8pAwDPiIiIhHRAAM+UsRtWYiIiIhEjj18REREIqKBqvfmlKijIVSrMOAjIiISEU1UPeDjAirx4ZAuERERkcixh4+IiEhE1DGkS+LDgI+IiEhEOKRLyvB/BBARERGJHHv4iIiIRIQ9fKQMAz4iIiIR4Rw+UobfCSIiIiKRYw8fERGRiGjg5bAu0asY8BEREYmIOoZ0eZau+DDgIyIiEhFNsIePFHEOHxEREZHIsYePiIhIRNjDR8ow4CMiIhIRzuEjZTikS0RERCRy7OEjIiISEQ7pkjIM+IiIiESEAR8pwyFdIiIiIpFjDx8REZGISFD13pwSdTSEahUGfERERCKijiFdrtIVHw7pEhEREYkce/iIiIhERB378LE3SHwY8BEREYkIh3RJGQZ8REREIsKAj5Rhry0RERGRyLGHj4iISEQ4h4+UYcBHREQkIhzSJWUYxBMRERGJHHv4iIiIREQDVe/h40kb4sOAj4iISEQ4h4+U4WdKREREJHLs4SMiIhIRdSza4JCu+DDgIyIiEhEO6ZIy/EyJiIiIRI49fERERCLCIV1ShgEfERGRiDDgI2UY8BEREYkI5/CRMvxMiYiIiESOPXxEREQioo6TNl6ooyFUqzDgIyIiEhF1zOGran6qfTikS0RERCRyDPiIiIhERENNV0Xcu3cPy5cvh5+fH6ytraGtrQ0LCwv0798fZ8+erVBZd+/exWeffSYrx9LSEv7+/rhz506Z+fbu3QtfX180aNAAenp6sLOzw9ChQxXyBQcHQyKRKL10dXUVyk1OTi41vUQiwc6dOyv0+moKh3SJiIhEpCaGdFetWoXFixfDwcEBvr6+MDc3R0JCAiIiIhAREYEdO3Zg0KBB5ZaTlJSELl26ID09Hb6+vhg8eDASEhKwdetWHDx4EDExMXBwcJDLIwgCxo0bhw0bNsDBwQFDhgyBkZER7t+/j+PHjyMlJQVWVlYKdY0cORK2trZy97S0Sg+LXF1d0bdvX4X7bdq0Kfd11QYM+IiIiKhKOnXqhOjoaHh5ecndP3HiBLp3747x48fjo48+go6OTpnlTJkyBenp6VixYgUmT54su79r1y4MGjQIEyZMwKFDh+TyrFq1Chs2bMCECROwYsUKaGrKh6vFxcVK6xo1ahS6du2q8mt0c3NDcHCwyulrGw7pEhERiUhNDOn269dPIdgDAC8vL/j4+CAzMxN///13mWUUFBQgMjISjRs3xqRJk+SeDRw4EG5uboiMjMQ///wju5+fn4+QkBDY29tj+fLlCsEeUHav3duE7wIREZGI1LZVuvXq1QNQfuD1+PFjFBcXw8bGBhKJROG5nZ0d4uLicOzYMdjb2wMAjhw5gszMTIwaNQovXrzAvn37cOvWLdSvXx89evRA8+bNS63vxIkTiI2NhaamJlq2bIkePXqU2QN5//59rF27FllZWbC0tET37t3RrFkzVd6CWoEBHxERESmVk5Mj97eOjk65w7KvSk1NxZ9//gkLCwu0bdu2zLSmpqbQ1NRESkoKBEFQCPpu374NALh165bs3vnz5wG8DCZdXV1x8+ZN2TMNDQ1MnToV3333ndL65s6dK/d3kyZNsHXrVvj6+ipNf+TIERw5ckT2t5aWFiZPnoylS5dCQ6P2D5jW/hYSERGRyjTVdAGAlZUVTExMZNfChQtVbkdRURGGDx+OwsJCLFmyROlw66v09fXh7e2NtLQ0rFmzRu7Znj17EBcXBwDIysqS3U9PTwcALFu2DMbGxoiNjUVubi6io6Ph5OSEZcuWYe3atXJlubm5YevWrUhOTkZ+fj4SEhLwzTffICsrC3369MHly5cV2hUUFIS4uDjk5OQgPT0d+/btg6OjI0JDQzF79myV35OaJBEEQajpRlD5cnJyYGJiguzsKzA2Nqrp5hBVCwOJXU03gajaCADyAWRnZ8PY2Fjt5Ut/Jz4DoHofnHKFANYDuHPnjlxbVe3hKykpwciRIxEeHo7AwEBs2LBBpXovX74MT09P5OXloWfPnnBxcUFiYiJ+++03tGnTBleuXMH48eNlAeHYsWOxceNG6OnpITExEZaWlrKyrl27BhcXF9jZ2SExMbHcujdu3IixY8diwIAB2LVrV7npHz58iDZt2iA3NxcPHz6EqampSq+xprCHj4iISETU2cNnbGwsd6kS7AmCgMDAQISHh2PYsGFYt26dym13dXXFuXPnMGjQIFy8eBErVqzAzZs3sX79egwfPhwA0KhRI1l6ExMTAIC7u7tcsAcAzs7OsLe3R1JSklyvYGlGjhwJLS0tnDp1SqW2WlhYoHfv3nj+/DnOnTun4iusOZzDR0RERGpRUlKCgIAAbNmyBUOHDkVYWFiF57e1bNkSv/zyi8L9UaNGAXgZ3Em1aNECAFC/fn2lZUnv5+fnl5pGSltbG0ZGRnj27JnKbW3YsCEAVChPTWEPHxERkYios4evIl4N9gYPHoxt27aVO29PVbm5udi/fz/MzMzkFlX4+PgAAG7cuKGQp6ioCImJiTAwMJDrFSxNQkICnjx5orAZc1liY2MBoEJ5agoDPiIiIhGpiX34SkpKMGbMGGzZsgUDBw5EeHh4mcFeRkYG4uPjkZGRIXc/Pz9fYaPkwsJCjBkzBpmZmQgKCpI7/szBwQF+fn5ITEzEpk2b5PItWrQIWVlZ+Pjjj2VbwuTm5uLKlSsK7Xny5AnGjBkDABg6dKjcs9jYWBQVFSnkCQ0NxalTp9C6dWu4urqW+lprCw7pEhERUZXMmzcPYWFhMDQ0hJOTE+bPn6+Qpm/fvnBzcwMArF69GiEhIQgKCpI7veLChQvo168ffH19YWVlhZycHBw4cACpqakIDAxU2JAZANasWYMuXbogMDAQERERaNmyJS5duoSjR4/CxsYGS5culaV9/PgxXF1d4e7ujrZt28Lc3Bz37t3DH3/8gcePH8PX1xdTp06VK3/GjBmIj4+Ht7c3rKyskJ+fj9OnT+PSpUswNTXFtm3blO4bWNsw4CMiIhKRmth4OTk5GQCQl5eHBQsWKE1ja2srC/hKY21tja5du+LEiRNIS0uDvr4+2rdvj9DQUPTv319pHgcHB5w/fx5z587FoUOHcPjwYVhYWGDChAmYO3cuzM3NZWnNzMwwYcIEnDlzBvv370dWVhYMDAzQtm1bDBs2DAEBAQo9k8OGDcOvv/6KmJgYWY+kjY0NpkyZgunTp9eZzZe5LUsdwW1Z6G3AbVlIzN7UtizToZ5tWb5D9bWV3jzO4SMiIiISOQ7pEhERiUhtO0uXagcGfERERCKigaoHbBz+Ex9+pkREREQixx4+IiIiEanMPnrKyiBxYcBHREQkIpzDR8ow4CMiIhIRBnykDHttiYiIiESOPXxEREQiwjl8pAwDPiIiIhHhkC4pwyCeiIiISOTYw0dERCQiHNIlZRjwERERiQhP2iBl+JkSERERiRx7+IiIiESEizZIGQZ8REREIsI5fKQMP1MiIiIikWMPHxERkYhwSJeUYcBHREQkIgz4SBkGfERERCLCOXykDD9TIiIiIpFjDx8REZGIcEiXlGHAR0REJCISVH34TqKOhlCtUqeGdLOysjB58mR07twZFhYW0NHRQdOmTdGtWzf8+uuvEARBIU9OTg6mTZsGGxsb6OjowMbGBtOmTUNOTk6p9Wzfvh2dOnWCgYEBTE1N0bt3b5w/f77C7a1M3URERETqJhGURUm1VGJiItzc3PDuu++iefPmMDMzQ3p6Ovbv34/09HQEBgZiw4YNsvRPnz6Fp6cn4uLi4Ovri/bt2+Py5cs4dOgQ3NzccPLkSRgYGMjV8e2332L27NmwtrbGgAEDkJeXh507d6KgoACRkZHo2rWrSm2tTN1lycnJgYmJCbKzr8DY2EjlfER1iYHErqabQFRtBAD5ALKzs2FsbKz28qW/Ez8C0K9iWc8AjEb1tZXevDo1pGtnZ4esrCxoack3Ozc3F++++y42btyIKVOmwNnZGQCwZMkSxMXFYcaMGVi8eLEsfVBQEObNm4clS5YgJCREdj8hIQFBQUFwcnJCbGwsTExMAACTJ09Gp06dEBAQgPj4eIX6lalo3UREROrAOXykTJ0a0tXU1FQabBkZGaFnz54AXvYCAoAgCNi0aRMMDQ0xd+5cufSzZs2CqakpNm/eLDcMvGXLFhQXF2P27NmyYA8AnJ2dMWLECCQlJeHo0aPltrMydRMRERFVlzoV8JWmoKAAR48ehUQiQevWrQG87K27f/8+PDw8FIZOdXV18d577+HevXuyABEAoqKiAAB+fn4KdUgDyuPHj5fbnsrUTUREpA4aarpIXOrUkK5UVlYWli9fjpKSEqSnp+PgwYO4c+cOgoKC4OjoCOBl0AVA9vfrXk336r8NDQ1hYWFRZvryVKZuIiIideCQLilTZwO+V+e/1atXD0uXLsWXX34pu5ednQ0AckOzr5JOQpWmk/7b3Nxc5fSlqUzdryssLERhYaHsb67sJSIiosqqk722tra2EAQBxcXFuH37NubNm4fZs2ejf//+KC4urunmqcXChQthYmIiu6ysrGq6SUREVAdoqukicamTPXxSmpqasLW1xcyZM6GpqYkZM2Zg48aNGD9+vKx3rbReNGmP2au9cC+3PVE9fWkqU/frZs2ahWnTpsnlYdBHRETl4Vm6dUdRURHOnTuHkydPIiUlBY8ePUJ+fj4aNmyIRo0aoX379vDy8kLTpk2rXFedDvhe5efnhxkzZiAqKgrjx48vd86dsnl2jo6OOH36NB4+fKgwj6+8eXmvqkzdr9PR0YGOjk65dREREb1KA1XvoWPAV72OHTuGTZs2ISIiAgUFBQCgdOcOieTlmSetWrXC6NGjMWLECDRs2LBSdYom4Lt//z4AyLZtcXR0hKWlJU6dOoWnT5/KrZYtKChAdHQ0LC0t0bx5c9l9b29vnD59GocPH8aIESPkyo+MjJSlKU9l6iYiIiJx279/P2bNmoUbN25AEARoaWnBzc0NHTt2RJMmTWBmZgY9PT1kZmYiMzMT169fx7lz53D9+nVMnz4dX331FcaOHYuvv/4ajRo1qlDddSqIj4uLUzpMmpmZia+++goA0KtXLwAvo+KAgADk5eVh3rx5cukXLlyIJ0+eICAgQBY9A4C/vz+0tLSwYMECuXquXbuGn376CQ4ODujWrZtcWampqYiPj8ezZ89k9ypTNxERkTpwW5ba6b333kPfvn2RnJyMQYMGYe/evcjJycGFCxewbt06BAUFYdKkSQgICMCMGTOwaNEi7Nu3Dw8ePEBCQgK++eYbNG/eHKtXr0bz5s3x22+/Vaj+OnW02hdffIFNmzbBx8cHNjY2MDAwQEpKCg4cOIC8vDz0798f//3vf6Gh8fKr+vrxZh06dMDly5fxxx9/lHq82YIFCzBnzhzZ0WpPnz7Fjh07kJ+fj8jISPj4+Mil79q1K44fP45jx47JHbtWmbrLwqPV6G3Ao9VIzN7U0Wr7AKj+66LcUwB9wKPV1MnMzAyTJ0/GF198gfr161e6nGPHjuGbb76Bj48Pvv76a5Xz1amA7+TJk9i8eTPOnDmD+/fv49mzZzAzM0P79u0xYsQIDBkyRKHXLDs7GyEhIdi9e7dsbt6AAQMQFBRU6qKJn3/+GcuXL8e1a9egra2Nzp07Y968eejYsaNC2tICvsrWXRoGfPQ2YMBHYsaA7+2Wm5sLIyP1/X5XtLw6FfC9zRjw0duAAR+J2ZsK+A5APQHfB2DAJyaiWbRBRERE3JaFlONnSkRERFQLPHv2DI8fP1a6RUtVsYePiIhIRHiWbt2Qk5ODffv2ITo6WrbxsnRPPolEIluj4OXlBT8/P6XrCCqCc/jqCM7ho7cB5/CRmL2pOXx/QT1z+LqDc/iqQ2xsLH744Qf8+uuvyM/PL7c3T7oYtU2bNggICMCYMWOgr69f4XrZw0dERERUzW7duoVZs2YhIiICgiCgYcOG+Pjjj9GpU6cyN16OjY3FqVOnEBMTgy+++ALffvstgoODERgYKNuGThUM+IiIiEREgqpP0OexAOrn7OwMABg8eDBGjhyJHj16QFNT+eC5ubk5zM3N0bJlS/Tr1w8AcO/ePezYsQNr167F559/jsePH8sOnVAFF20QERGJiKaaroq4d+8eli9fDj8/P1hbW0NbWxsWFhbo378/zp49W6Gy7t69i88++0xWjqWlJfz9/XHnzp0y8+3duxe+vr5o0KAB9PT0YGdnh6FDhyrkCw4OhkQiUXrp6uqWWv727dvRqVMnGBgYwNTUFL1798b58+dVfl0jRoxAfHw8tm/fjp49e5Ya7JWmadOmmD59Om7duoUtW7bAysqqQvnZw0dERCQiNbEty6pVq7B48WI4ODjA19cX5ubmSEhIQEREBCIiIrBjxw4MGjSo3HKSkpLQpUsXpKenw9fXF4MHD0ZCQgK2bt2KgwcPIiYmBg4ODnJ5BEHAuHHjsGHDBjg4OGDIkCEwMjLC/fv3cfz4caSkpCgNjkaOHAlbW1u5e1paysOib7/9FrNnz4a1tTXGjRuHvLw87Ny5Ex4eHoiMjFQ4eEGZzZs3l5tGFZqamhgxYkSF8zHgIyIioirp1KkToqOj4eXlJXf/xIkT6N69O8aPH4+PPvoIOjo6ZZYzZcoUpKenY8WKFZg8ebLs/q5duzBo0CBMmDABhw4dksuzatUqbNiwARMmTMCKFSsUes6Ki4uV1jVq1CiVArWEhAQEBQXByckJsbGxspOyJk+ejE6dOiEgIADx8fGlBou1BYd0iYiIRKQmhnT79eunEOwBgJeXF3x8fJCZmYm///67zDIKCgoQGRmJxo0bY9KkSXLPBg4cCDc3N0RGRuKff/6R3c/Pz0dISAjs7e2xfPlypcOkVQ3EtmzZguLiYsyePVvuWFRnZ2eMGDECSUlJOHr0aJXqeBNqdzhKREREFVLb9uGrV68egPIDr8ePH6O4uBg2NjayrUheZWdnh7i4OBw7dgz29vYAgCNHjiAzMxOjRo3CixcvsG/fPty6dQv169dHjx490Lx581LrO3HiBGJjY6GpqYmWLVuiR48eSnsgo6KiAAB+fn4Kz3r27Il169bh+PHjSp+/Ljo6utw05XnvvfcqlY8BHxERESmVk5Mj97eOjk65w7KvSk1NxZ9//gkLCwu0bdu2zLSmpqbQ1NRESkoKBEFQCPpu374N4OX2JlLSRRNaWlpwdXXFzZs3Zc80NDQwdepUfPfdd0rrmzt3rtzfTZo0wdatW+Hr6yt3PyEhAYaGhrCwsFAow9HRUZZGFV27dlUazKpKIpGUOkRdHg7pEhERiYiGmi4AsLKygomJiexauHChyu0oKirC8OHDUVhYiCVLlpS7KlVfXx/e3t5IS0vDmjVr5J7t2bMHcXFxAICsrCzZ/fT0dADAsmXLYGxsjNjYWOTm5iI6OhpOTk5YtmwZ1q5dK1eWm5sbtm7diuTkZOTn5yMhIQHffPMNsrKy0KdPH1y+fFkufXZ2ttxQ7qukm1JnZ2eX+368qkmTJrC3t6/wZWdX+c3p2cNHREQkIuoc0r1z547cSRuq9u6VlJRg9OjRiI6ORmBgIIYPH65SvtDQUHh6emLixInYv38/XFxckJiYiN9++w0uLi64cuWKXOBYUlICANDW1kZERAQsLS0BvJw7uHv3bri4uGDZsmUYP368LE/fvn3l6mzevDnmzJmDxo0bY+zYsZg/fz527dqlUnsrQxAE5OXloWfPnhg2bBh8fHyqra5XsYePiIiIlDI2Npa7VAn4BEFAYGAgwsPDMWzYMKxbt07l+lxdXXHu3DkMGjQIFy9exIoVK3Dz5k2sX79eFjQ2atRIll7a8+bu7i4L9qScnZ1hb2+PpKQkuV7B0owcORJaWlo4deqU3P2Xx5oq78GTDnmX1gP4usuXL+PLL7+EoaEhtmzZgh49esDGxgZfffUVrl+/rlIZlcWAj4iISEQ0UPUVupUNDkpKSjBmzBj8+OOPGDp0KMLCwip0/BcAtGzZEr/88gvS09NRWFiIa9euISAgAFevXgXwMriTatGiBQCgfv36SsuS3s/Pzy+3Xm1tbRgZGeHZs2dy9x0dHZGXl4eHDx8q5JHO3ZPO5StP27ZtsXTpUty5cweHDx/GsGHDkJWVhUWLFqFt27Zo3749vv/+e6V1VRUDPiIiIhFR5xy+iigpKUFAQAC2bNmCwYMHY9u2bRU+TaI0ubm52L9/P8zMzOQWVUiHQ2/cuKGQp6ioCImJiTAwMJDrFSxNQkICnjx5orAZs7e3NwDg8OHDCnkiIyPl0qhKIpGgR48e2Lp1Kx4+fIjw8HD4+fnh6tWr+PLLL2FlZYX3338fP//8s0IAWlkM+IiIiKhKpD17W7ZswcCBAxEeHl5msJeRkYH4+HhkZGTI3c/Pz1dYhVpYWIgxY8YgMzMTQUFBcsefOTg4wM/PD4mJidi0aZNcvkWLFiErKwsff/yxbEuY3NxcXLlyRaE9T548wZgxYwAAQ4cOlXvm7+8PLS0tLFiwQG5o99q1a/jpp5/g4OCAbt26lfX2lElPTw+ffPIJ/vjjD9y9exehoaFwc3PD4cOHMWLECAwYMKDSZb+KizaIiIhEpCb24Zs3bx7CwsJgaGgIJycnzJ8/XyFN37594ebmBgBYvXo1QkJCEBQUhODgYFmaCxcuoF+/fvD19YWVlRVycnJw4MABpKamIjAwUGFDZgBYs2YNunTpgsDAQERERKBly5a4dOkSjh49ChsbGyxdulSW9vHjx3B1dYW7uzvatm0Lc3Nz3Lt3D3/88QceP34MX19fTJ06Va58JycnBAcHY86cOXBxccGAAQPw9OlT7NixA0VFRdi4caPaTtkwNzfHiBEjoK2tjUePHiE1NbXS27C8jgEfERGRiNTEWbrJyckAgLy8PCxYsEBpGltbW1nAVxpra2t07doVJ06cQFpaGvT19dG+fXuEhoaif//+SvM4ODjg/PnzmDt3Lg4dOoTDhw/DwsICEyZMwNy5c2Fubi5La2ZmhgkTJuDMmTPYv38/srKyYGBggLZt22LYsGEICAhQ2jM5e/Zs2NraYvny5Vi7di20tbXRpUsXzJs3Dx07dlTtTSrD8+fPsW/fPoSHh+PQoUMoKioC8HLfvs8//7zK5QOARBAEQS0lUbXKycn5/5VCV2BsbFTTzSGqFgaSyu8xRVTbCQDy8XLPtle3OlEX6e/ELQBV/ZXIBeCE6msrvRQdHY3w8HDs3r0b2dnZEAQBzs7OGDZsGD799FM0a9ZMbXWxh4+IiIjoDYmPj8e2bduwfft2pKamQhAEWFhYwN/fH8OHDy+3F7SyGPARERGJSG07S5f+p2PHjrh48SKAlyeLfPLJJxg+fDh69OhR4e1rKooBHxERkYjUxBw+Us2FCxcgkUjQokULfPzxxzAwMMD58+dlZwKr4quvvqpU3ZzDV0dwDh+9DTiHj8TsTc3huw31zOGzA+fwqZuGhgYkEgkEQYBEIqlQXmmeFy9eVKpu9vARERGJiPSkjaqWQeo3cuTIGqubAR8REZGIcA5f7bVly5Yaq5tBPBEREZHIsYePiIhIRLhog5RhwEdERCQiHNKtvVJTU6tchrW1daXyMeAjIiIiegPs7Kq2E4FEIqn02boM+IiIiESEQ7q1V1V3wqtKfgZ8REREIsIh3drr9u3bNVY3Az4iIiIRYcBXe9nY2NRY3ey1JSIiIhI5BnxERERiIsH/JvJV9qrYqV+kopUrV+LXX3+tkboZ8BEREYmJppouUrsvvvgCK1asUPqsW7du+OKLL6qtbs7hIyIiIqphUVFRld5yRRUM+IiIiMREE1UfkhUAVF/sQTWAAR8REZGYqGMOXtW2i6NaiHP4iIiIiESOPXxERERioq4hXRIVBnxERERiwoCvVktPT8dPP/1U4WdSI0aMqFS9EqGqB7vRG5GTkwMTExNkZ1+BsbFRTTeHqFoYSKp2sDhRbSYAyAeQnZ0NY2NjtZcv+50wBYyrGPDlCIDJk+pr69tKQ0MDEknlPxyJRFLplbzs4SMiIiJ6A6ytrasU8FUFAz4iIiIxkZ6WURUl6mgIvS45ObnG6q5QwNetWze1Vi6RSPDXX3+ptUwiIqK3mjoCPhKdCgV8UVFRkEgkUNe0v5rq1iQiIiJ6m1R4SLdNmzZYuXJllSueNGkSrl27VuVyiIiI6BWaqHoPH/tj1O7Zs2fQ19evsfIqHPCZmJjA29u7otmUlkNERERqxoCvVrK1tcWXX36JCRMmwNDQsNLlxMTEYN68efDw8MDXX3+tcr4KfSVcXFzg6OhY4cYp07x5c7i4uKilLCIiIqLazN7eHrNmzYKVlRXGjBmDI0eO4MWLFyrlvX//Pr7//nu4u7vDy8sLJ0+eRJs2bSpUP/fhqyO4Dx+9DbgPH4nZG9uHzwowrmIPX04JYHKH+/Cp265duzB79mwkJiZCIpFAV1cX7dq1Q4cOHdCkSROYmZlBR0cHWVlZyMzMxI0bN3D+/HmkpKRAEARoaWnB398fISEhsLCwqFDdDPjqCAZ89DZgwEdi9sYCPls1BXzJDPiqgyAIOHToEDZs2ICDBw+iqKgIgPKFrNIQzc7ODqNHj8bo0aPRpEmTStXLffiIiIiI3hCJRIJevXqhV69eePbsGU6fPo2YmBikpKQgIyMDBQUFMDMzg7m5Odzc3ODp6YnmzZtXuV4GfERERGKigZcLN6jW09fXR/fu3dG9e/dqr6vCAZ+mZtW+RVU5B46IiIjKoY6NlznZS3QqHPBVdcofpwwSERFVI02wh6+Oun//Pu7du4f8/Hy89957ai27UkO6EokELVq0wPDhw9GvX78q7SdDRERE9DZbu3YtQkND8c8//wBQHA398ssvcfr0aezcuRPW1taVqqPCnb7ff/89OnTogPj4eMyZMwcdOnTAzJkzce3aNTRp0gRNmzYt9yIiIqJqoqGmi6qdIAgYPHgwJk6ciH/++Qe2trYwNDRUGA195513cObMGezZs6fSdVX4I50yZQpiY2MRHx+PWbNmwdzcHD///DN69eqFpk2b4ssvv8TFixcr3SAiIiKqAk01XVTtNm/ejF27dqF169aIi4tDUlKS0kMpPvjgA2hqauLAgQOVrqvSMbyTkxPmz5+Pf/75B9HR0RgzZgwKCwvx/fffo2PHjnB2dsbixYtx586dSjeOiIiISKw2b94MDQ0N7Nq1C23bti01nYGBARwcHGRDvpWhlk5bT09PbNiwAQ8fPsSuXbvw4YcfIikpCV999RXs7OwwceJEdVRDRERE5WEPX51x7do12Nvbo2XLluWmNTU1xYMHDypdl1pH6bW1tdG/f39ERETgyJEjsLKyQklJCW7duqXOaoiIiKg0nMNXZ5SUlEBHR0eltDk5OSqnVUatGy+npaVhx44d2LZtG+Li4iAIAgwNDeHp6anOaoiIiIjqPDs7OyQmJiIvL6/MHU8ePnyImzdvolOnTpWuq8oxfH5+PrZv345evXrBysoK06ZNw5UrV+Dn54fw8HCkpaVh7ty5Va2GiIiIVCE9aaMqF3v43og+ffqgsLCw3Djpyy+/hCAI+PjjjytdV6U+UkEQcOTIEYwcORKNGzfG8OHDERkZibZt2yI0NBR3797FH3/8gU8++QR6enqVbhwRERFVUA3M4bt37x6WL18OPz8/WFtbQ1tbGxYWFujfvz/Onj1bobLu3r2Lzz77TFaOpaUl/P39y10EunfvXvj6+qJBgwbQ09ODnZ0dhg4dWm6+27dvw9DQEBKJBOPGjVN4npycDIlEUuq1c+fOCr2+V02fPh2WlpZYsWIFBg4ciEOHDqGgoEDWrn379qFHjx7YsWMH7Ozs8Pnnn1e6rgoP6f773//G9u3b8fDhQwiCACsrK0ycOBHDhw9Hq1atKt0QIiIiqptWrVqFxYsXw8HBAb6+vjA3N0dCQgIiIiIQERGBHTt2YNCgQeWWk5SUhC5duiA9PR2+vr4YPHgwEhISsHXrVhw8eBAxMTFwcHCQyyMIAsaNG4cNGzbAwcEBQ4YMgZGREe7fv4/jx48jJSUFVlZWSusTBAH+/v4qvUZXV1f07dtX4X6bNm1Uyq+MqakpIiMj8dFHH+HXX3+V22evefPmsjba29vjwIEDMDAwqHRdFQ74li1bJjtpY9iwYfD29oZEIsGTJ08QExOjUhldunSpcEOJiIhIBepYdFHB/J06dUJ0dDS8vLzk7p84cQLdu3fH+PHj8dFHH5W76GDKlClIT0/HihUrMHnyZNn9Xbt2YdCgQZgwYQIOHTokl2fVqlXYsGEDJkyYgBUrVkBTU7578tUTK163atUqnDp1CkuWLMG0adPKbJubmxuCg4PLTFMZzs7OuHLlCjZv3oy9e/fi77//RnZ2NgwNDdG6dWv069cPn332WZWCPQCQCBU83FZDQwMSiaTyFb52XAipJicnByYmJsjOvgJjY6Oabg5RtTCQ2NV0E4iqjQAgH0B2djaMjY3VXr7sd8IDMK7iksycYsDklHra2rNnTxw+fBjnzp2Du7t7qekKCgpgZGSEBg0a4MGDBwqxRrt27WSbE9vb2wN4uY6gWbNmqF+/Pm7evAktLdVfeGJiIlxdXfHFF1/A19cXPj4++Oyzz7Bu3Tq5dMnJybCzs8PIkSMRFham+guvZSr8lbC2tq5SwEdERETVqAZ6+MpSr149ACg3GHv8+DGKi4thY2OjNM6ws7NDXFwcjh07Jgv4jhw5gszMTIwaNQovXrzAvn37cOvWLdSvXx89evSQDYu+rqSkBP7+/rCxscHcuXNx+vTpcl/H/fv3sXbtWmRlZcHS0hLdu3dHs2bNys1XW1Q44EtOTq6GZhAREZHYpKam4s8//4SFhUWZJ0kAL+ezaWpqIiUlBYIgKAR9t2/fBgC5vX3Pnz8P4GUw6erqips3b8qeaWhoYOrUqfjuu+8U6lq+fDliYmJw8uRJlfe2O3LkCI4cOSL7W0tLC5MnT8bSpUuhoVG5CDktLQ2RkZFo3rx5mdPdTp06haSkJLz//vswNzevVF1ceE1ERCQmalylm5OTI3cVFhaq3IyioiIMHz4chYWFWLJkicLcutfp6+vD29sbaWlpWLNmjdyzPXv2IC4uDgCQlZUlu5+eng7g5foCY2NjxMbGIjc3F9HR0XBycsKyZcuwdu1aubJu3bqFOXPmYMqUKejcuXO5r0NfXx9BQUGIi4tDTk4O0tPTsW/fPjg6OiI0NBSzZ89W4d1Qbu3atfD398fdu3fLTHfv3j34+/tjw4YNla6LAR8REZGYqDHgs7KygomJiexauHChSk0oKSnB6NGjER0djcDAQAwfPlylfKGhoTA0NMTEiRPx/vvvY8aMGejXrx8GDhwIFxeXly/vlcCxpKQEwMuTviIiItCxY0cYGhrCy8sLu3fvhoaGBpYtWyaXftSoUbC0tMT8+fNVapO5uTmCg4Ph6uoKIyMjNGrUCB9++CGOHj2KBg0aIDQ0FE+ePFGprNf9/vvv0NHRQf/+/ctM169fP+jo6GDfvn2VqgdgwEdERESluHPnDrKzs2XXrFmzys0jCAICAwMRHh6OYcOGKSyCKIurqyvOnTuHQYMG4eLFi1ixYgVu3ryJ9evXy4LGRo0aydKbmJgAANzd3WFpaSlXlrOzM+zt7ZGUlCTrFVy5ciXOnDmDTZs2QV9fX+V2KWNhYYHevXvj+fPnOHfuXKXKkC4IKa/3U0tLC3Z2dkhJSalUPUAFA7558+apbYVKWFgY5s2bp5ayiIiI6P9JUPVzdP9/+pyxsbHcVd58t5KSEowZMwY//vgjhg4dirCwsArPb2vZsiV++eUXpKeno7CwENeuXUNAQACuXr0KAHIrfVu0aAEAqF+/vtKypPfz8/MBQHbsq4+Pj9zmyT4+PgCA9evXQyKRKN1vT5mGDRsCAJ49e1ah1yj17NkzlQNPPT095OTkVKoeoIKLNoKDg+Hp6YlRo0ZVukKpzZs3IyYmhseuERERqVMlTspQUFKJLCUlCAgIwJYtWzB48GBs27at3J4rVeXm5mL//v0wMzODr6+v7L40ULtx44ZCnqKiIiQmJsLAwEDWK+jt7a10tfCDBw9w8OBBtGzZEh4eHmjXrp1K7YqNjQUA2NraVvQlAQCaNm2KGzduID8/v8yTyfLz8xEfHw8LC4tK1QNUYpUuERER0aukPXthYWEYOHAgwsPDywz2MjIykJGRgYYNG8p6yYCXgU29evXkgrLCwkKMGTMGmZmZWLFiBXR1dWXPHBwc4Ofnh8OHD2PTpk0ICAiQPVu0aBGysrIwbNgwWXn+/v5KT9aIiorCwYMH4e3trTAEHRsbi3bt2sm2l5EKDQ3FqVOn0Lp1a7i6uqr4Tsnz8fHB5s2b8c033+Dbb78tNd38+fPx7NkzdO/evVL1AJUI+M6fPy/b/6YqHj58WOUyiIiI6DU10MMnnfJlaGgIJycnpQsi+vbtCzc3NwDA6tWrERISgqCgILnTKy5cuIB+/frB19cXVlZWyMnJwYEDB5CamorAwEBMmjRJodw1a9agS5cuCAwMREREBFq2bIlLly7h6NGjsLGxwdKlSyv2Yl4zY8YMxMfHw9vbG1ZWVsjPz8fp06dx6dIlmJqaYtu2bZXen3j69On46aefsHjxYmRkZODf//43HB0dZc8TEhLw3XffYdOmTdDW1sb06dMr/ToqHPAVFBSobS8+buBMRESkZjWw8bI0LsjLy8OCBQuUprG1tZUFfKWxtrZG165dceLECaSlpUFfXx/t27dHaGhoqStZHRwccP78ecydOxeHDh3C4cOHYWFhgQkTJmDu3LmV3rdOatiwYfj1118RExODjIwMAICNjQ2mTJmC6dOnV2nzZScnJ2zevBmjR4/G5s2bsXnzZtSvXx/169dHVlYWsrKyIAgC6tWrh82bN6Nly5aVrqtCR6tVZXVIaWxsbNRephjxaDV6G/BoNRKzN3a02r8A43rlpy+zrCLA5PfqayvJO3/+PIKCgvDnn3+iqKhIdl9bWxt+fn4ICgpChw4dqlRHhXr4GJwRERHVcjW0aIMqz93dHQcOHEBBQQESExORk5MDIyMjODo6ys1ZrAou2iAiIhKTWnaWLqlOV1cXbdq0qZayGfARERGJCXv4SAkGfEREREQ17MyZM7h8+TIyMzPl5vG9SiKR4Ouvv65U+Qz46hwbAJxAS+L0VAis6SYQVZucnOcwMdla/RVpoOo9fC/U0RBSRXR0NMaMGYN//vmnzHSCIDDgIyIiov/HOXx1xvXr19GrVy8UFRXh008/xfHjx3H37l189dVXuHPnDi5fvozLly9DT08P48ePh5FR5XfpYMBHREREVAMWLVqEgoICbNq0Cf7+/vDy8sLdu3fxzTffyNIcPnwYY8aMQWRkJE6fPl3puhjDExERiYmmmi6qdlFRUTAxMcHIkSNLTePn54c9e/bg2rVrmDdvXqXrYsBHREQkJgz46oz09HTY2tpCQ+NlOCY98zc/P18uXceOHdGiRQvs2bOn0nVV25Dub7/9hv379+PGjRvIzMwEAJiZmaFVq1bo06cP+vTpU11VExEREdV6JiYmePHifytkzMzMALw82ez1Y9S0tbWrdLSt2nv4Hj9+jM6dO+Pjjz/GyZMnYWFhAU9PT3h4eMDCwgKnTp1C37590aVLFzx+/Fjd1RMREb3dNNR0UbWztrbGgwcPZH+3bdsWALB//365dMnJybh582aVjrlTew/f1KlT8ejRI8TGxsLd3V1pmgsXLmDIkCGYNm0atm59A0vUiYiI3hbqGJLlkO4b4ePjg2XLliE5ORm2trYYOnQo5s+fj9mzZyM7OxudO3dGWloaFi1ahKKiIvTu3bvSdak94Pv999+xcePGUoM9AOjQoQMWLVqEwEDuuUVERERvp/79+2Pv3r04efIkbG1t0aJFC3zzzTeYPXs2Fi5cKEsnCALs7e2xaNGiStel9oCvuLgY+vr65abT09NDcXGxuqsnIiJ6u3EfvjrjnXfeQUJCgty9WbNmwdPTEz///DOSk5Ohp6cHT09PjB07tnbtw+fj44OgoCB06NAB5ubmStOkp6cjJCQE3bp1U3f1REREbzd1nLTBgK9GeXl5wcvLS61lqj3gW7lyJbp27QpbW1v4+PjA2dkZ9evXh0QiwZMnT3D9+nUcO3YMFhYW+O9//6vu6omIiN5unMNXZ3Tr1g26urqIiIiAtrZ2tdal9oDPxsYGV69exbp163DgwAH89NNPePLkCQDA1NQUzs7OmD9/PgIDA2FoaKju6omIiIjqhNOnT8PZ2bnagz2gmvbhMzAwwJdffokvv/yyOoonIiKi0nAOX51hbW2NgoKCN1JXjX2kxcXF+O2332qqeiIiInHiSRt1Rv/+/REfH49bt25Ve11vPOA7deoUxo8fDwsLC/Tr1+9NV09ERERUK8yZMwdubm746KOPcPny5Wqtq9qOVnvVzZs3ER4ejp9//hkpKSnQ0dFBnz594O/v/yaqJyIientw0UadMXHiRDg6OmL37t1o3749nJ2d0apVKxgYGChNL5FIsHnz5krVVW0BX3p6Onbs2IHw8HBcvHgRwMv9ZlJSUrB//3507969uqomIiJ6e3EOX50RFhYGiUQCQRAAAFevXsXVq1dLTV+rAr6ff/4Z4eHh+Ouvv1BcXIzWrVtjwYIF+PTTT2FkZAQzMzPUq1dP3dUSERER1Slbtmx5Y3WpPeAbPnw4JBIJfH19sWjRIri5ucmeZWdnq7s6IiIiehWHdOuMkSNHvrG61N5p2717d0gkEhw5cgT+/v5YtmwZ7t+/r+5qiIiISBkJ/jesW9lL8sZb/VZKTU1Fenq6SmnT09ORmppa6brUHvAdOXIEd+/exZIlSwAA//73v2FtbY0ePXpg69atkEj4LSIiIiKytbXFwIEDVUo7ePBg2NvbV7quapmWaWFhgS+//BKXLl3C1atXMX36dCQkJOCLL76AIAhYvHgxDh06JJukSERERGrCffjqlIrEQlWJm6p9HU7r1q2xaNEipKSk4K+//oK/vz9OnTqF3r17w8rKqrqrJyIiersw4BOlnJwc6OjoVDr/G1147ePjg82bNyMtLQ07d+5Ehw4d3mT1RERE4lfV+Xvq2NaF1KawsBCHDx/GlStXYGtrW+lyKrVK99q1a0hKSoK5uTnefffdctOfPn0ajx49QvPmzdG6dWvo6Ohg0KBBGDRoUGWqJyIiIqpzQkJCMG/ePLl7p06dgqZm+V2qgiBgyJAhla67wgHfs2fP4Ofnh4yMDBw7dkylPIIgYMCAAbC0tMTNmzer1CVJREREZeC2LLWWIAhy8/Be3XS5NHp6erC3t8fgwYMxc+bMStdd4U7bHTt24MGDBxgzZgy6dOmiUp4uXbogMDAQd+7cwc6dOyvcSCIiIlIR5/DVWsHBwSgpKZFdgiDA09NT7t7r19OnT/H3339jzpw50NKq/PbJFQ74IiIiIJFIMHny5Arlk67Q/fXXXytaJREREZHoBAUFwd/f/43UVeFQ8dKlS2jSpAlatmxZoXyOjo5o2rQpLl26VNEqiYiISFU8S7fOCAoKemN1VfgjzcjIQNOmTStVmaWlJTIyMiqVl4iIiFSggaoP5zLgE50Kf6S6urrIz8+vVGX5+fnQ1tauVF4iIiKiuqpNmzb45ZdfqnzoRGpqKsaNG4fFixdXKF+FA74mTZogKSkJhYWFFcpXWFiIpKQkWFpaVrRKIiIiUhX34auVcnNz8cknn8DJyQnffPMNEhISVM77/Plz7N27FwMGDICjoyM2bdoEc3PzCtVf4Tl8Xl5e2Lx5M3bv3o1PP/1U5Xy7du1Cfn4+vLy8KlolERERqYrbstRKt27dwsqVK7Fo0SIEBQUhODgYDg4O6NSpEzp06IAmTZrAzMwMOjo6yMrKQmZmJm7cuIHz58/j/PnzePr0KQRBgK+vLxYvXgw3N7cK1S8RKti3GBMTA09PT1haWuL06dMqHY+WmpqKd999F2lpaYiOjoaHh0eFGkkvj1QxMTFBdnY2jI2Na7o5RNVkbE03gKja5OQ8h4nJ1mr777jsd+J7wFivimXlAyZTwd+capCbm4vw8HBs3LgRcXFxAF7ux6eMNEQzMDDAkCFDMHbsWHTs2LFS9Va4h69Lly4YOHAgdu3ahXfeeQcrVqxA//79oaGh2P9bUlKC3bt344svvkBaWhr69+/PYI+IiKg6sYevVjMyMsL48eMxfvx4JCQkIDo6GjExMUhJSUFGRgYKCgpgZmYGc3NzuLm5wdPTE126dIG+vn6V6q3UDn5hYWG4d+8eYmJiMGTIEDRq1AgeHh6ws7ODgYEBnj59itu3byMmJgbp6ekQBAGdO3dGWFhYlRpLRERE5eC2LHWGo6MjHB0dMWbMmGqvq1IBn56eHqKiohAcHIxVq1YhPT0de/fuleuSlHZDGhoaYtKkSQgODka9evXU02oiIiJSjj18pESlz+jQ0tLC/PnzMWPGDBw4cAAxMTG4d+8ecnNzYWRkhKZNm6JLly7o3bs3TExM1NlmIiIiIqqAyh/K9v+MjY0xdOhQDB06VB3tISIioqrgkG6d8OjRI/z22284e/YsEhIS8OTJE+Tn50NPTw+mpqZwdHTEO++8gz59+lR4CxZlqhzwERERUS0iPWmjqmVQtSgoKMCMGTOwYcMGFBUVlboRc3R0NH788UdMnDgRgYGBWLJkCfT0Kr/8mh8pERERVcm9e/ewfPly+Pn5wdraGtra2rCwsED//v1x9uzZCpV19+5dfPbZZ7JyLC0t4e/vjzt37pSZb+/evfD19UWDBg2gp6cHOzs7DB06tNx8t2/fhqGhISQSCcaNG1dquu3bt6NTp04wMDCAqakpevfujfPnz1fotRUWFqJr16744Ycf8Pz5c7Ro0QJjxozBggULsGbNGmzevBlr1qzBggULMGbMGLRo0QLPnz/HmjVr0LVrVzx//rxC9b2KPXxERERiUgOLNlatWoXFixfDwcEBvr6+MDc3R0JCAiIiIhAREYEdO3Zg0KBB5ZaTlJSELl26ID09Hb6+vhg8eDASEhKwdetWHDx4EDExMXBwcJDLIwgCxo0bhw0bNsDBwQFDhgyBkZER7t+/j+PHjyMlJaXUPYMFQYC/v3+57fr2228xe/ZsWFtbY9y4ccjLy8POnTvh4eGByMhIdO3aVaX3aenSpYiNjUWLFi3w448/onPnzuXmiYmJwejRo3H+/HksWbIEc+bMUamu11V442WqGdx4md4O3HiZxOuNbbwcBhhXbcs25DwDTEapvvHynj170KhRI4XTtE6cOIHu3bvLAjAdHZ0yy/nXv/6FAwcOYMWKFZg8ebLs/q5duzBo0CD07NkThw4dksuzcuVKTJkyBRMmTMCKFSugqSkfrRYXF0NLS3n/1sqVK/Hll19iyZIlmDZtGj777DOsW7dOLk1CQgJat24Ne3t7xMbGyhaiXrt2DZ06dUKTJk0QHx9fah2vcnZ2RlJSEhISElQ6uEIqJSUFTk5OcHBwwPXr11XO9yoO6RIREVGV9OvXT+nRqV5eXvDx8UFmZib+/vvvMssoKChAZGQkGjdujEmTJsk9GzhwINzc3BAZGYl//vlHdj8/Px8hISGwt7fH8uXLFYI9AKUGYomJiZg1axZmzJiBdu3aldquLVu2oLi4GLNnz5bbdcTZ2RkjRoxAUlISjh49WuZrk7p9+zbatGlToWAPAGxsbNCmTRskJydXKN+rGPARERGJiaaaLjWR7sFbXg/Y48ePUVxcDBsbG6VHjdnZ2QEAjh07Jrt35MgRZGZmom/fvnjx4gX27NmDRYsWYd26dUhMTCy1rpKSEvj7+8PGxgZz584ts11RUVEAAD8/P4VnPXv2BAAcP368zDKkDA0NkZ6erlLa16Wnp8PAwKBSeQHO4SMiIhIXNc7hy8nJkbuto6NT7rDsq1JTU/Hnn3/CwsICbdu2LTOtqakpNDU1kZKSAkEQFIK+27dvAwBu3boluyddNKGlpQVXV1fcvHlT9kxDQwNTp07Fd999p1DX8uXLERMTg5MnT5b7ehISEmBoaAgLCwuFZ46OjrI0qujcuTN+//13hIaGYtq0aSrlAYDvvvsO9+7dw4cffqhyntexh4+IiIiUsrKygomJiexauHChynmLioowfPhwFBYWYsmSJUqHW1+lr68Pb29vpKWlYc2aNXLP9uzZg7i4OABAVlaW7L60t2zZsmUwNjZGbGwscnNzER0dDScnJyxbtgxr166VK+vWrVuYM2cOpkyZotKiiezs7FIPkJDOb8zOzi63HACYOXMmNDQ08O9//xu9e/fG7t278eDBA6VpHzx4gN27d6NXr174z3/+A01NTcyaNUulepRhDx8REZGYqHHj5Tt37sgt2lC1d6+kpASjR49GdHQ0AgMDMXz4cJXyhYaGwtPTExMnTsT+/fvh4uKCxMRE/Pbbb3BxccGVK1fkAseSkhIAgLa2NiIiImBpaQng5dzB3bt3w8XFBcuWLcP48eNl6UeNGgVLS0vMnz9fpTapU+fOnREWFoaAgAAcOnQIkZGRAF6+r/Xr14e2tjaeP3+OrKwsFBYWAni5klhbWxsbN27Eu+++W+m62cNHREQkJmqcw2dsbCx3qRLwCYKAwMBAhIeHY9iwYQqrXsvi6uqKc+fOYdCgQbh48SJWrFiBmzdvYv369bKgsVGjRrL00p43d3d3WbAn5ezsDHt7eyQlJcl6BVeuXIkzZ85g06ZN0NdXbSmzdIcMZaRD3hU5QvbTTz9FfHw8xo8fDwsLCwiCgIKCAjx8+BCpqal4+PAhCgoKIAgCGjdujPHjxyM+Pl7loLk07OEjIiISEwmq3p2juGZCJSUlJQgICMCWLVswdOhQhIWFQUOjYo1p2bIlfvnlF4X7o0aNAvAyuJNq0aIFAKB+/fpKy5Lez8/PR/369REXFwdBEODj46M0/fr167F+/Xp89NFHiIiIAPBynt7p06fx8OFDhXl80rl70rl8qrKxscEPP/yAH374AampqbKj1QoKCqCrqys7Ws3a2rpC5ZaFAR8RERFV2avB3uDBg7Ft27Zy5+2pKjc3F/v374eZmRl8fX1l96WB240bNxTyFBUVITExEQYGBrJeQW9vb6WrhR88eICDBw+iZcuW8PDwkNumxdvbG6dPn8bhw4cxYsQIuXzSIVlvb+9KvzZra2u1BnalYcBHREQkJjVw0kZJSQnGjBmDsLAwDBw4EOHh4WUGexkZGcjIyEDDhg3RsGFD2f38/HzUq1dPLigrLCzEmDFjkJmZiRUrVkBXV1f2zMHBAX5+fjh8+DA2bdqEgIAA2bNFixYhKysLw4YNk5Xn7++v9GSNqKgoHDx4EN7e3gpD0P7+/vjuu++wYMECfPTRR3IbL//0009wcHBAt27dKvaG1QAGfERERGJSAwHfvHnzEBYWBkNDQzg5OSldENG3b1+4ubkBAFavXo2QkBAEBQUhODhYlubChQvo168ffH19YWVlhZycHBw4cACpqakIDAxU2JAZANasWYMuXbogMDAQERERaNmyJS5duoSjR4/CxsYGS5curdiLeY2TkxOCg4MxZ84cuLi4YMCAAXj69Cl27NiBoqIibNy4UaVTNqrq3r17ePHiRaV7AxnwERERUZVIT4DIy8vDggULlKaxtbWVBXylsba2RteuXXHixAmkpaVBX18f7du3R2hoKPr37680j4ODA86fP4+5c+fi0KFDOHz4MCwsLDBhwgTMnTsX5ubmVXlpAIDZs2fD1tYWy5cvx9q1a6GtrY0uXbpg3rx56NixY5XLV4WbmxuePHmC4uLiSuXnWbp1BM/SpbcDz9Il8XpjZ+n+DhhX/kCGl2U9BUz+pfpZulT9GjVqhMzMTLx48aJS+dnDR0REJCY1MKRLtR8DPiIiIqI34Ntvv6103vz8/CrVzYCPiIhITNjDV2vNmTNH4YxgVSk7X7giGPARERGJiRqPViP10tTURElJCfr16wdDQ8MK5d25cyeeP39e6boZ8BERERG9Ac7Ozvj7778RGBgIPz+/CuX9/fffkZmZWem6GcMTERGJiQaqfo4uo4Nq0alTJwDA+fPn33jd/EiJiIjERENNF6ldp06dIAgCzp49W+G8Vd1Fj0O6REREYsJFG7VWjx49MGXKFLnj5FS1b98+FBUVVbpuBnxEREREb4CtrS2+//77SuXt0qVLlepmwEdERCQm7OEjJRjwERERiQm3ZSEl+JESERERiRx7+IiIiMSEQ7p1hqam6m+0hoYGjIyMYGtrC09PTwQEBMDFxUX1/JVpIBEREdVSVd2DTx0BI6lEEASVrxcvXiArKwtxcXFYvXo1OnTogKVLl6pcFwM+IiIiohpQUlKC0NBQ6OjoYOTIkYiKikJmZiaKioqQmZmJ48ePY9SoUdDR0UFoaCjy8vJw/vx5fP755xAEATNnzsRff/2lUl0c0iUiIhITCarenSNRR0OoPL/++iu+/PJLrF69GuPHj5d7Vr9+fXh5ecHLywsdO3bExIkT0bRpUwwcOBDt27eHvb09pk+fjtWrV6N79+7l1iURqrp1M70ROTk5MDExQXZ2NoyNjWu6OUTVZGxNN4Co2uTkPIeJydZq+++47HfiCmBsVMWycgETF/A3p5p17twZd+7cwd27d8tN26xZMzRr1gxnzpwBABQXF6Nhw4bQ09PDgwcPys3PIV0iIiKiGnD16lU0bdpUpbRNmzbF9evXZX9raWnByckJmZmZKuXnkC4REZGYcB++OqNevXq4desWCgsLoaOjU2q6wsJC3Lp1C1pa8mFbTk4OjIxU687lR0pERCQmXKVbZ3h4eCAnJwcTJ05ESUmJ0jSCIGDSpEnIzs6Gp6en7P7z589x+/ZtWFpaqlQXe/iIiIjEhPvw1Rnz5s3Dn3/+iR9//BExMTEYPnw4XFxcYGRkhLy8PFy5cgXh4eG4fv06dHR0MG/ePFnevXv3oqioCD4+PirVxYCPiIiIqAa0a9cO+/fvx/Dhw3Hjxg3Mnj1bIY0gCLCwsMC2bdvg5uYmu9+4cWNs2bIFXl5eKtXFgI+IiEhMOIevTunRowcSEhKwfft2HDlyBAkJCXj69CkMDAzg5OQEX19fDB06FIaGhnL5unbtWqF6GPARERGJCYd06xxDQ0OMHTsWY8dW39ZUjOGJiIiIRI49fERERGKigar30LE76I27ffs2jhw5glu3biE3NxdGRkayIV07O7sql8+Aj4iISEw4h69OefLkCT7//HPs2rUL0sPPBEGARPLyfDuJRILBgwdj9erVMDU1rXQ9DPiIiIiIakB+fj66d++Oy5cvQxAEdO7cGc7OzmjcuDHS0tJw7do1nD59Gjt37kR8fDxOnToFXV3dStXFgI+IiEhMuGijzvj+++8RFxeHli1b4qeffoK7u7tCmvPnz2PkyJGIi4vD8uXLMXPmzErVxU5bIiIiMdFQ00XV7r///S80NTXx+++/Kw32AMDd3R379u2DhoYGdu7cWem66tRHGhYWBolEUubVvXt3uTw5OTmYNm0abGxsoKOjAxsbG0ybNg05OTml1rN9+3Z06tQJBgYGMDU1Re/evXH+/PkKt7cydRMREdHbITExEW3atIG9vX2Z6RwcHNCmTRskJiZWuq46NaTr5uaGoKAgpc92796Na9euoWfPnrJ7T58+hbe3N+Li4mQbF16+fBnff/89jh07hpMnT8LAwECunG+//RazZ8+GtbU1xo0bh7y8POzcuRMeHh6IjIxUeaPDytRNRERUZRzSrTM0NTVRVFSkUtqioiJoaFS+n67OBXyvHisi9fz5c6xevRpaWloYOXKk7P6SJUsQFxeHGTNmYPHixbL7QUFBmDdvHpYsWYKQkBDZ/YSEBAQFBcHJyQmxsbEwMTEBAEyePBmdOnVCQEAA4uPjoaVV/ttW0bqJiIjUggFfndGiRQtcuHABly9fhqura6np4uLicP36dXTs2LHSddWpId3S7N27F48fP8a//vUvNG7cGMDLJc2bNm2CoaEh5s6dK5d+1qxZMDU1xebNm2VLoAFgy5YtKC4uxuzZs2XBHgA4OztjxIgRSEpKwtGjR8ttT2XqJiIiUgvO4aszhg8fDkEQ8K9//Qv79+9Xmmbfvn3o06cPJBIJhg8fXum6RPGRbt68GQAQEBAgu5eQkID79+/Dw8NDYehUV1cX7733Hu7duyc3Hh4VFQUA8PPzU6hDOlR8/PjxcttTmbqJiIjo7TJ+/Hj4+Pjg3r176Nu3L+zs7NCrVy+MHDkSvXr1gq2tLT7++GPcvXsXPj4+GD9+fKXrqlNDusqkpKTgr7/+QtOmTfH+++/L7ickJAAAHB0dleaT3k9ISJD7t6GhISwsLMpMX57K1P26wsJCFBYWyv7mQg8iIlKJRAP4/017K1+GAKBELc2h0mlpaeHAgQOYM2cO1q1bh5SUFKSkpMil0dfXx/jx4/HNN99AU7PyY+11PuDbsmULSkpK4O/vL/dGZGdnA4Dc0OyrjI2N5dJJ/21ubq5y+tJUpu7XLVy4kHP8iIioErQAVDHggwDguRraQuXR1dXFd999h6CgIJw8eRK3bt1CXl4eDA0N4eTkBE9PTxgZGVW5njod8JWUlGDLli2QSCQYPXp0TTdHrWbNmoVp06bJ/s7JyYGVlVUNtoiIiIiqi5GREXr16oVevXpVS/l1OuA7cuQIUlNT0b17d4WDhaW9a6X1okmHSF/thTMxMalQ+tJUpu7X6ejoQEdHp9y6iIiI5LGHrzZKTU1VSznW1taVylenAz5lizWkyptzp2yenaOjI06fPo2HDx8qzOMrb15eVesmIiJSD3UFfKROtra2kFRxbqVEIkFxcXGl8tbZgO/x48f47bffYGZmho8//ljhuaOjIywtLXHq1Ck8ffpUbrVsQUEBoqOjYWlpiebNm8vue3t74/Tp0zh8+DBGjBghV15kZKQsTXkqUzcRERGJl7W1dZUDvqqos9uybNu2Dc+fP8ewYcOUDn1KJBIEBAQgLy8P8+bNk3u2cOFCPHnyBAEBAXJvvr+/P7S0tLBgwQK54dhr167hp59+goODA7p16yZXVmpqKuLj4/Hs2bMq1U1ERKQemnjZn1OVizsvq1tycjJu375d5auyJEId3f23bdu2uHr1Kq5cuYK2bdsqTfP06VN4enrKjjfr0KEDLl++jD/++ANubm5KjzdbsGAB5syZA2trawwYMABPnz7Fjh07kJ+fj8jISPj4+Mil79q1K44fP45jx47JHbtWmbrLkpOTI5tjKF3lSyQ+Y2u6AUTVJifnOUxMtlbbf8f/9zvRCMbGVevPyckpgYnJI/7miEid7OGLjY3F1atX0alTp1KDPQAwMDBAVFQUpk6divj4eCxbtgxXr17F1KlTERUVpTTgmj17NsLDw2Fubo61a9di586d6NKlC06dOqUQ7JWlMnUTERERVYc628P3tmEPH70d2MNH4vXmeviaqKmH74HKbb137x527dqFgwcPIj4+Hg8fPoSZmRk8PDwwY8YMvPPOOyrXfffuXXzzzTf4448/8PDhQzRs2BA9e/bEvHnzytyebO/evVizZg0uXryIZ8+ewcLCAu+++y6WLFkil2/jxo3Yt28frl69ivT0dGhpacHW1hYfffQRvvjiC5iZmcmVm5ycrLATyKt27NiBIUOGqPz6akqdXbRBREREymih6gN4FTtlY9WqVVi8eDEcHBzg6+sLc3NzJCQkICIiAhEREdixYwcGDRpUbjlJSUno0qUL0tPT4evri8GDByMhIQFbt27FwYMH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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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1aVLF8XExCgkJETp6en6/PPPlZOTo7vvvlv/+te/5Od36avw++1fWrVqpS1btujLL78sdfuXqVOn6rnnnrNtPXP27FktWrRIubm5WrFihbp06WJ3fefOnbVmzRqtXr3ablsaV+q+EraeQUXA1jMws/LaeuZTSY7/dinZWUl9xNYzzvCpZRP69eunzMxMff/991q7dq3OnTunyMhIJSYmavDgwerfv79dr09ISIhSUlI0efJkffTRR0pJSVFUVJSefvppJSUllRhoJk6cqNjYWL355pt67733FBgYqPbt22vKlClq3bq1w211pW4AAOCbfKqHqiKjhwoVAT1UMLPy6qH6XJ7pofqj6KFyhk/1UAEAgCvzxBwo5lA5j88MAADATfRQAQBgIuzl5x0EKgAATIRA5R0EKgAA4JbDhw9ryZIl+uKLL7Rz504dPXpUkZGRSkhI0NixY3XLLbd4rW0XLlzQpk2btG7dOqWnp+vEiRPKzc1V1apVdcMNN6hly5bq0KGDatas6VY9BCoAAEzEIvcnSDu77PTf/vY3vfLKK6pXr5569OihatWqac+ePfr444/18ccfa9GiRbr33nvdbJVzVq9erZkzZ+rjjz9WXl6eJKmkhQ2Klltq3Lixhg0bpsGDB6tq1apO18eyCT6CZRNQEbBsAsysvJZNWCMp1M2yciR1kuNt/fe//60bbrhBHTp0sDv+3XffqVu3bgoLC9ORI0dktVrdbNnVLV++XOPHj9eOHTtkGIYCAgLUvHlztW7dWtWrV1dkZKSCg4N16tQpnTp1Stu3b9emTZt07NgxSVJgYKAefvhhPf/887rhhhscrpdA5SMIVKgICFQws/IKVN/JM4GqgzzT1l69emnlypXatGmT4uPj3WzZlXXs2FGpqakKDg7WHXfcof79+6tXr14KCrr6L859+/Zp8eLFWrRokbZv366wsDB98MEH+tOf/uRQ3SybAAAAykylSpUkSQEBZT/LaOvWrXr++ed16NAhLVq0SH/6058cClOSVK9ePU2cOFFbt27VN998o1atWunnn392uG7mUAEAYCLX0lN+Bw8e1Ndff62oqCg1b97cQ6WWLj09XWFhYW6X06VLF3Xp0kXZ2dkO30OgAgDARDwZqLKysuyOW61Wh+dBXbhwQYMGDVJ+fr6mT58uf/+yX4zBE2HK1fIY8gMAACWKjo5WRESE7TVt2jSH7issLNSwYcO0du1ajRgxQoMGDSrjlnofPVQAAJiIJ/fyy8jIsJuU7kjvlGEYGjFihJKTkzVw4EC9//77brbGs86dO6fc3FxFRkbalkzwBAIVAAAm4skhv/DwcKee8issLNTw4cM1Z84cDRgwQHPnzpWfn/cGw7KysvTpp59q7dq1toU9i9akslgsioyMtC3s2bNnT7Vu3drlulg2wUewbAIqApZNgJmV17IJP8ozyya0lHNtvTxM3XfffVqwYEG5zJsqycaNG/Xuu+9q6dKlys3NLXFBz8sV9VQ1a9ZMw4cP10MPPaTKlSs7VSc9VAAAmIif3O+hcrZPqbCwUA899JDmzp2re+65R8nJyV4JU7t379b48eP18ccfyzAMVa1aVX379lWbNm2uuLDnxo0blZqaqvXr1+upp57SSy+9pEmTJmnEiBEO97ARqAAAMBFPzqFy1JQpUzR37lyFhoaqQYMGevHFF4tdc+edd6pFixZutuzKmjZtKkm677779OCDD6p79+6lBrtq1aqpWrVqatSoke666y5Jl/YkXLRokd577z099thj+u233zRhwgSH6iZQAQAAtxw4cECSlJOTo6lTp5Z4TWxsbJkHqsGDB2vChAmqV6+eS/fXrFlTzzzzjJ5++mktWLDAqUnrzKHyEcyhQkXAHCqYWXnNodomyd3VmLIlNVXZtdWM6KECAMBEvDHkBwIVAACmci1tPVOREKgAAIBprF271u0yOnbs6PQ9BCoAAEykovdQde7c2a0V0C0WiwoKCpy+j0AFAICJMIfqkurVqys4OLjc6iNQAQAAUzEMQzk5OerVq5cGDhyoLl26lHmdZgihAADg/xStlO7Oy5fDwZYtWzRmzBiFhoZqzpw56t69u2JiYjRhwgRt3769zOr15c8MAAD8jrthyhNzsLypefPmevXVV5WRkaGVK1dq4MCBOnPmjF5++WU1b95cLVu21BtvvKGjR496tF4CFQAAMB2LxaLu3btr3rx5Onr0qJKTk9WzZ09t3bpVY8aMUXR0tG699VYtWLBA586dc7s+AhUAACbi56GXmQQHB+v+++/Xl19+qUOHDun1119XixYttHLlSg0ePFj9+vVzuw4mpQMAYCIVfdmEq6lWrZoGDx6swMBAnThxQgcPHnRpmYTfI1ABAADTO3/+vD799FMlJyfrq6++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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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aYIaNWqovF4QBISHh2tVJ5MzIiIiY8LZmpLKycnBG2+8gZMnT0IURTx+/BiPHz8u83oplthgckZERGRMmJxJatGiRQgPD0ft2rUxdepUtG/fnuucEREREenKd999B3Nzc0RGRqJly5ZVUieTMyIiImPCpTQklZ6eDk9PzypLzAAmZ0RERMaF3ZqSat68OXJycqq0TubGREREpFMrV65Ev3794OLiAmtra9SuXRve3t5YvXo18vLyNC4vLCwM/v7+kMlksLOzg7+/P8LCwioU2zvvvIObN28iIiKiQvdXBJMzIiIiY2KAi9Bu3LgR6enp6Nu3L2bNmoWAgADk5+fj/fffR/fu3TVK0Hbt2oUBAwbg6tWrGDduHCZMmIC4uDgMGDAAu3bt0ji2yZMnY86cORg6dCjWrVtXJa1ogiiKYqXXQlrLysqCvb09MjMzIZPJdB0OUeUYypUvyXhlFQL2R1Bp/x1X/E78CshstCwrF7DvU3mxvig/Px9WVlaljo8dOxY7d+7E+vXr8e677760nPT0dDRu3BhmZma4ePEiXFxcAAD379+Hl5cX8vPzcfv2bTg4OKgdm3z7prt376K4uBgA4OTkVO46Z7du3VK7fFXYckZEREQ6pSoxA4Dhw4cDAG7evKlWOQcOHEBGRgZmzpypSMwAoF69epg9ezYyMjJw4MABjWJLSEhAQkICioqKIIoiRFFEamqq4riql7Y4IYCIiMiYmED7bkk9abo5evQoAKB169ZqXS8fF9avX79S5/r374/58+cjMjISU6dOVTuGO3fuqH2tVJicERERGRMDXkpjzZo1yMjIQEZGBqKjo3HhwgX069cPY8eOVev++Ph4AICHh0epc/Jj8mvU5ebmptH1UmByRkREZEwkXEojKytL6bClpSUsLS21LLxsa9asQWJiouL9mDFjsGHDBpibm6t1f2ZmJgDA3t6+1DkbGxuYmpoqrtFnetJwSURERPrGxcUF9vb2iteKFSvKvNbR0RGCIKj9UrU0RUJCAkRRxP3797F7925ERESgS5cuuHv3biV+Sv3DljMiIiJjImHLWXJystJszfJazQICApCdna12Fc7OzuWeCwgIQNOmTdG5c2e8//772Ldv30vLlLeYZWZmonbt2krncnNzUVxcrLJVTa5169b46KOPMHLkSK32zkxKSsLy5cvRqFEjfPjhhxrfz+SMiIjImEg45kwmk6m9lMa6deu0rLS0Tp06wcHBQe0FYD08PHDhwgXEx8eXSs7KG48ml52djbfeeguLFy/G2LFjMWrUqHKvf15BQQGOHj2KXbt24fDhwyguLsamTZvUuvdFTM6IiIhIL+Xk5CAzM7PcVrbn+fn5Yc+ePTh+/Di6du2qdE6+Q4Cfn1+Z99+4cQNr167FypUrERQUhODgYDRp0gSdO3dGx44dUa9ePdSqVQuWlpbIyMhAWloarl+/jgsXLuDChQvIzc2FKIro27cvPvvsM7Rv375Cn5uL0BoILkJL1QIXoSUjVmWL0J4HZLZalpUD2HeqmkVoExMTIYoi3N3dlY4XFhZi+vTp2LJlCyZNmoTNmzcrzuXl5SEpKQk1atSAq6ur4nh6ejoaNWoEc3NzrRahzc7ORmhoKDZt2oTLly8DQJndnPI0ysbGBqNGjcLUqVPRqVMnTR+DEracERERGRMD2/j80qVLGDZsGHr06AEPDw84OjoiJSUFv/76K5KTk9G8eXMsW7ZM6Z6YmBj07NkTfn5+Sl2eDg4OWL9+PQIDA+Hl5YVRo0bBxMQE+/btQ0pKCnbu3KnW7gB2dnaYPn06pk+fjvj4eJw+fRpnz55FYmIiHj16hPz8fNSqVQt16tRB+/bt4evri+7du5e5a4CmmJwRERGRznh5eWHWrFk4ffo0Dh06hIyMDNja2qJFixaYMWMG3n33XdjYqL8f1ZgxY+Do6IgVK1Zg+/btijpCQkLQv39/jePz8PCAh4cHJk2apPG9FcVuTQPBbk2qFtitSUasyro1LwEyOy3LygbsO1Td3pqkjC1nRERExsTAujWpNCZnRERERCo8fPgQP/74I86dO4f4+Hikp6fjyZMnsLa2hoODAzw8PNClSxcMHjwYderUkaxeJmdERETGxID31tQX+fn5mDdvHv7zn/+gsLAQZY0AO336NLZu3YoZM2ZgypQp+Pzzz2Ftba11/UzOiIiIjAm7NbXy9OlT+Pv74/z58xBFEZ6envDx8UHjxo3h4OAAS0tLPH36FOnp6bh9+zaio6MRFxeHb7/9FjExMThz5gwsLCy0ioHJGRERkTFhcqaVL774AjExMWjevDm2bt2Kbt26vfSes2fPYuLEibhw4QI+//xzLF68WKsYqnnDJREREdH/7NmzBxYWFjh+/LhaiRkAdO/eHWFhYTAzM8Pu3bu1joEtZ0RERMaEY860cufOHbRu3Vqxu4C63Nzc0Lp1a1y/fl3rGJicERERGRN2a2rF1tYWqampFbo3NTVVowVzy1KNc2MiIiIiZd26dcO9e/ewevVqje778ssvce/ePXTv3l3rGJicERERGRMT/K/1rKKvapwdzJ8/HyYmJvjggw/w6quv4uDBg7h//77Ka+/fv4+DBw9i4MCB+PDDD2FqaooFCxZoHQO7NYmIiIwJx5xppVu3bti+fTsmT56MY8eOISwsDABgaWmJmjVrwsLCAgUFBcjIyMDTp08BAKIowsLCAps2bULXrl21jqEaP34iIiKi0kaPHo24uDhMnz4dzs7OEEUR+fn5ePDgAZKSkvDgwQPk5+dDFEXUrVsX06dPR1xcHAIDAyWpny1nRERExoQTAiTh5uaGb775Bt988w2SkpIU2zfl5+fDyspKsX2Tq6ur5HUzOSMiIjIm7NaUnKura6UkYWUxqMe/fft2CIJQ7qt3795K92RlZWHOnDlwc3ODpaUl3NzcMGfOHGRlZZVZz+7du9G5c2fY2NjAwcEBr776Ki5cuKBxvBWpm4iIiKo3g2o5a9++PYKCglSeO3jwIK5evYr+/fsrjuXm5sLPzw+XL19G3759ERAQgNjYWHz11Vc4deoUoqKiSq1Hsnz5cixatAiurq6YNm0acnJysHfvXvj4+CAsLAz+/v5qxVqRuomIiLTGbk2duXfvHoqLi7VuZRPEsrZaNyAFBQWoX78+MjMzcffuXdStWxcAEBQUhKVLl2LevHn47LPPFNfLj3/88cdYsmSJ4nh8fDxatmyJxo0bIyYmBvb29gCAq1evonPnzqhXrx7i4uJgZvbynFbTul8mKysL9vb2yMzMhEwmU/s+IoMyVNB1BESVJqsQsD+CSvvvuOJ3Ig3QtvisLMC+VuXFaqycnJyQnp6OoqIircoxqG7Nshw6dAiPHz/GoEGDFImZKIrYvHkzbG1t8fHHHytdv2DBAjg4OGDLli14Pjfdtm0bioqKsGjRIkViBgCtWrXC2LFjcevWLZw8efKl8VSkbiIiIkmYSPSiCpHit90oHv+WLVsAAJMnT1Yci4+Pxz///AMfH59S3YdWVlZ45ZVXcO/ePdy8eVNxPCIiAgDQr1+/UnXIu0sjIyNfGk9F6iYiIiICDGzMmSqJiYkIDw9HgwYNMGDAAMXx+Ph4AICHh4fK++TH4+Pjlf5ta2sLZ2fncq9/mYrU/aKnT58qFrcDwEkERESkHsEEELQcIiCIAEokCcfQLF++vML3PnnyRJIYDD4527ZtG0pKSjBhwgSYmv5vBGNmZiYAKHVPPk/ehy6/Tv7vOnXqqH19WSpS94tWrFih0Zg0IiKiZ8wAaDt+UwRQIEEshmfx4sUQKpjciqJY4XufZ9DJWUlJCbZt2wZBEDBx4kRdhyOpBQsWYM6cOYr3WVlZcHFx0WFERERExs/U1BQlJSUYOnQobG1tNbp37969KCjQPqk16OTsxIkTSEpKQu/evdGoUSOlc/JWq7Jap+TdhM+3bslnQ6p7fVkqUveLLC0tYWlp+dK6iIiIlLHlTButWrXCX3/9hSlTpqgcg16eI0eOIC0tTesYDHpCgKqJAHIvGyOmalyYh4cHcnJy8ODBA7WuL0tF6iYiIpKGmUSv6qlz584AUKHF56VisMnZ48eP8eOPP6JWrVp44403Sp338PBA/fr1ER0djdzcXKVz+fn5OH36NOrXr4+mTZsqjvv5+QEAjh8/Xqo8+a708mvKU5G6iYiISPc6d+4MURRx7tw5je+Vaoksg03Odu7ciYKCAowZM0Zl958gCJg8eTJycnKwdOlSpXMrVqxAeno6Jk+erDRwb8KECTAzM8OyZcuUuiSvXr2KHTt2oEmTJujVq5dSWUlJSYiLi0NeXp5WdRMREUnDFNq3mlXfLQL69OmDWbNmKVrQNPHTTz+ptR7qyxjsDgFt2rTBlStX8Oeff6JNmzYqr8nNzYWvr69iC6WOHTsiNjYWv/zyC9q3b69yC6Vly5Zh8eLFcHV1xfDhw5Gbm4s9e/bgyZMnCAsLQ8+ePZWu9/f3R2RkJE6dOqW0tVNF6i4PdwigaoE7BJARq7IdAjKdIJNp1/aSlVUCe/uH/M3REYNsOYuJicGVK1fQuXPnMhMzALCxsUFERATee+89xMXFYdWqVbhy5Qree+89REREqEyOFi1ahNDQUNSpUwcbNmzA3r170b17d0RHR5dKzMpTkbqJiIiIDLblrLphyxlVC2w5IyNWdS1n9SRqObvP3xwdqb7TMYiIiIySGbTvGKueuwPoCyZnRERERsUU2idnbMWWe373oZcxMTGBnZ0d3N3d4evri8mTJ6Nt27Ya12mQY86IiIiIqoIoimq/iouLkZGRgcuXL2P9+vXo2LEjvvjiC43rZHJGRERkVLiUhpRKSkqwevVqWFpaYty4cYiIiEBaWhoKCwuRlpaGyMhIjB8/HpaWlli9ejVycnJw4cIFvPPOOxBFEfPnz0d4eLhGdbJbk4iIyKhIkVyxW1Puu+++w/vvv4/169dj+vTpSudq1qyJHj16oEePHujUqRNmzJiBBg0aYMSIEfDy8kLjxo0xd+5crF+/Hr1791a7Ts7WNBCcrUnVAmdrkhGrutmazSGTaZecZWUVw97+b/7mAOjWrRuSk5Nx9+7dl17bsGFDNGzYEL///jsAoKioCI6OjrC2tsb9+/fVrpPdmkREREaFe2tK6cqVK2jQoIFa1zZo0ADXrl1TvDczM0OzZs003gydT5+IiMiosFtTSubm5rhx4waePn2qcrtIuadPn+LGjRswM1NOrbKysmBnZ6dRnWw5IyIiIiqDj48PsrKyMGPGDJSUqF7/TRRFzJw5E5mZmfD19VUcLygowJ07d1C/fn2N6mTLGRERkVFhy5mUli5dil9//RVbt27F2bNnERgYiLZt28LOzg45OTn4888/ERoaimvXrsHS0hJLly5V3Hvo0CEUFhZqtP0jwOSMiIjIyMiX0iApdOjQAYcPH0ZgYCCuX7+ORYsWlbpGFEU4Oztj586daN++veJ43bp1sW3bNvTo0UOjOvnXIyIiIipHnz59EB8fj927d+PEiROIj49Hbm4ubGxs0KxZM/Tt2xcBAQGwtbVVus/f379C9TE5IyIiMiqcbVkZbG1tMXXqVEydOrXS6+Jfj4iIyKgwOTN0/OsREREZFSZnleXOnTs4ceIEbty4gezsbNjZ2Sm6NRs1aiRZPfzrEREREZUjPT0d77zzDg4cOAD5xkqiKEIQns1qFQQBb775JtavXw8HBwet62NyRkREZFSkmK3JnR3lnjx5gt69eyM2NhaiKKJbt25o1aoV6tati5SUFFy9ehW//fYb9u7di7i4OERHR8PKykqrOpmcERERGRUpujWZnMl99dVXuHz5Mjw9PbFjxw54e3uXuubChQsYN24cLl++jDVr1mD+/Pla1ckdAoiIiIjKsH//fpiamuLIkSMqEzMA8Pb2xk8//QQTExPs3btX6zrZckZERGRU2HImpZs3b6J169Zo3Lhxudc1adIErVu3Rnx8vNZ1MjkjIiIyKkzOpGRqaorCwkK1ri0sLISJifadkuzWJCIiIipD8+bNcf36dcTGxpZ73eXLl3Ht2jW0aNFC6zqZnBERERkVM4leBACBgYEQRRGDBg3C4cOHVV7z008/YfDgwRAEAYGBgVrXyadPRERkVKRYSqNEikCMwvTp0/HDDz/g1KlTGDJkCFxdXeHp6Yk6deogNTUV169fR3JyMkRRRK9evTB9+nSt62TLGREREenUypUr0a9fP7i4uMDa2hq1a9eGt7c3Vq9ejby8PI3KEgShzNfKlSs1js3MzAxHjx7FnDlzYG1tjcTERISFhWHnzp0ICwtDUlISrK2t8f777+PIkSMwNTXVuI5Sn0GUL3VLei0rKwv29vbIzMyETCbTdThElWOooOsIiCpNViFgfwSV9t/x//1OjIZMZqFlWQWwt99VZb85jRo1gqOjI9q0aYM6deogJycHERERuHr1Ktq1a4ezZ8+iRo0aapUlCALc3Nwwfvz4Uuf69OkDX1/fCseZnZ2NqKgo3LhxAzk5ObC1tUWzZs3g6+sLOzu7Cpf7InZrEhERGRUpxoxVbbfm9evXVa6qP3bsWOzcuRPbtm3Du+++q3Z57u7uCA4OljDCZ+zs7DBw4EAMHDhQ8rKfx25NIiIio2J4EwLK2u5o+PDhAJ6tNVadsOWMiIiI9NLRo0cBAK1bt9bovoyMDGzevBmpqalwcnKCv78/PDw8XnpfUlJSheJ8kaurq1b3MzkjIiIyKobXrSm3Zs0aZGRkICMjA9HR0bhw4QL69euHsWPHalRObGwspkyZongvCAJGjx6NjRs3ljt2zd3dHYKg3dhXQRBQVFSkVRlMzoiIiIyKFEtpFAN4NsngeZaWlrC0tNSy7LKtWbMGiYmJivdjxozBhg0bYG5urnYZc+fOxYgRI+Dh4QFBEHDp0iUsXLgQoaGhKCoqwp49e8q819XVVevkTAqcrWkgOFuTqgXO1iQjVnWzNd+BTKZdApWV9RT29t+WOh4UFFTmQHtHR0c8fvxY7TpOnToFf39/lecePHiAU6dOYd68eZDJZAgLC0PDhg3VLvtFeXl5aNeuHW7evIkrV66gVatWFS6rKrDljIiIyKhI0a35rOUsOTlZKZEsr9UsICAA2dnZatfg7Oxc7rmAgAA0bdoUnTt3xvvvv499+/apXfaLatSogYCAAHzyySeIjo5mckZERERVSbrkTCaTqd3Kt27dOi3rLK1Tp05wcHBARESE1mU5OjoCgMaL2uoCl9IgIiIivZSTk4PMzEyYmWnflnTu3DkAzwb96zsmZ0REREbFsNY5S0xMREJCQqnjhYWFmD17NkpKSkot+pqXl4e4uLhSS19cunRJZcvYgQMHsGfPHjg6OqJPnz6Sxl8Z2K1JRERkVKSYrandUhCauHTpEoYNG4YePXrAw8MDjo6OSElJwa+//ork5GQ0b94cy5YtU7onJiYGPXv2hJ+fn1KX59dff40ffvgBvXv3hqurK0RRxMWLF3HmzBlYWVkhJCQEtra2VfbZKorJGREREemMl5cXZs2ahdOnT+PQoUPIyMiAra0tWrRogRkzZuDdd9+FjY2NWmW9/vrryMjIwMWLF3Hs2DEUFRWhQYMGmDRpEubOnQtPT89K/jTS4FIaBoJLaVC1wKU0yIhV3VIaH0EmU70dkvpl5cPe/hP+5ugIW86IiIiMihRjxpge6BKfPhERkVFhcmboOFuTiIiISI8wNSYiIjIqbDkzdHz6RERERkWKpTRMpQiEKojdmkRERER6hC1nRERERoXdmoaOT5+IiMioMDkzdOzWJCIiItIjTI2JiIiMiim0H9DPCQG6xOSMiIjIqHC2pqFjtyYRERGRHmHLGRERkVHhhABDx6dPRERkVJicGTo+fSIiIqPC5MzQccwZERERkR5hakxERGRU2HJm6Pj0iYiIjAqX0jB07NYkIiIi0iNsOSMiIjIq7NY0dHz6RERERoXJmaFjtyYRERGRHmFqTEREZFTYcmbo+PSJiIiMCpMzQ8duTSIiIiI9wtSYiIjIqHCdM0PH5IyIiMiosFvT0PHpExERGRUmZ4aOY86IiIiI9AhTYyIiIqPCljNDx6dPRERkVDghwNCxW5OIiIhIj7DljIiIyKiYQvuWL7ac6RKTMyIiIqPCMWeGjt2aRERERHqEqTEREZFRYcuZoePTJyIiMipMzgwduzWJiIiI9AhTYyIiIqPCdc4MHZMzIiIio8JuTUPHp09ERGRUmJwZOo45IyIiItIjTI2JiIiMClvODB2fPhERkVFhcmbo+PQNhCiKAICsrCwdR0JUiQp1HQBR5cn67/db/t/zSqtHgt8J/tboFpMzA5GdnQ0AcHFx0XEkRESkjezsbNjb20teroWFBZydnSX7nXB2doaFhYUkZZFmBLGyU3iSRElJCf755x/Y2dlBEARdh2P0srKy4OLiguTkZMhkMl2HQyQ5fserniiKyM7ORv369WFiUjnz8fLz81FQUCBJWRYWFrCyspKkLNIMW84MhImJCRo2bKjrMKodmUzGHy4yavyOV63KaDF7npWVFRMqI8ClNIiIiIj0CJMzIiIiIj3C5IxIBUtLSwQFBcHS0lLXoRBVCn7HifQXJwQQERER6RG2nBERERHpESZnRERERHqEyRkRERGRHmFyRkRERKRHmJxRtRAaGoq3334b3t7esLS0hCAI2L59u8bllJSUYP369Wjbti2sra3h5OSEkSNHIj4+XvqgiTTg7u4OQRBUvqZNm6Z2OfyOE+kedwigamHx4sVITEyEo6Mj6tWrh8TExAqVM23aNGzatAktW7bEzJkzkZKSgn379uH48eM4e/YsWrZsKXHkROqzt7fH7NmzSx339vZWuwx+x4l0j0tpULXw66+/wsPDA25ubli5ciUWLFiAbdu2Yfz48WqXcerUKfTq1Qs9evTAiRMnFOtDhYeHo2/fvujRowciIyMr6RMQlc/d3R0AkJCQUOEy+B0n0g/s1qRqoU+fPnBzc9OqjE2bNgEAPv30U6WFO3v37o3+/fvj9OnTuHHjhlZ1EOkSv+NE+oHJGZGaIiIiYGNjAx8fn1Ln+vfvDwBsVSCdevr0KUJCQrB8+XJs2LABsbGxGt3P7ziRfuCYMyI15Obm4v79+2jdujVMTU1Lnffw8AAADpomnXrw4EGprvoBAwZg586dcHR0LPdefseJ9AdbzojUkJmZCeDZgGtVZDKZ0nVEVW3ixImIiIjAw4cPkZWVhd9//x0DBw7EsWPHMHjwYLxseDG/40T6gy1nRERG4OOPP1Z636VLFxw5cgR+fn6IiorCzz//jP/7v//TUXREpAm2nBGpQd6aUFarQVZWltJ1RPrAxMQEEyZMAABER0eXey2/40T6g8kZkRpsbGxQr1493LlzB8XFxaXOy8fhyMflEOkL+VizvLy8cq/jd5xIfzA5I1KTn58fcnNzVbZAhIWFKa4h0ifnzp0D8L910MrD7ziRfmByRvSCR48eIS4uDo8ePVI6PnXqVADPdhsoKChQHA8PD0dYWBheeeUVNGvWrEpjJQKAa9euISMjo9TxqKgorF69GpaWlhg6dKjiOL/jRPqNOwRQtbB582ZERUUBAP766y9cvHgRPj4+aNq0KQBgyJAhGDJkCAAgODgYS5YsQVBQEIKDg5XKmTJlCjZv3oyWLVvi//7v/xRb21hZWXFrG9KZ4OBgfP755+jduzfc3d1haWmJK1eu4Pjx4zAxMcG///1vTJ48Wel6fseJ9Bdna1K1EBUVhZCQEKVj0dHRiu4bd3d3RXJWno0bN6Jt27bYuHEj1q5dC1tbW7z22mtYtmwZWxRIZ3r27Inr16/j4sWLiIyMRH5+PurWrYs333wT7733Hjp37qx2WfyOE+keW86IiIiI9AjHnBERERHpESZnRERERHqEyRkRERGRHmFyRkRERKRHmJwRERER6REmZ0RERER6hMkZERERkR5hckZERESkR5icEZFOREREQBAEpdf27dslK3/IkCFKZauz8TcRkT5gckZE5XoxgVLn5e/vr3b5MpkMPj4+8PHxQd26dZXObd++/aWJVUhICExNTSEIAj7//HPF8ZYtW8LHxwfe3t6afmQiIp3i3ppEVC4fH59SxzIzM3HlypUyz7dp00bt8jt06ICIiIgKxbZ161ZMmTIFJSUlWLVqFebMmaM4t3z5cgBAQkICGjVqVKHyiYh0gckZEZUrKiqq1LGIiAj07NmzzPNVYfPmzZg6dSpEUcTXX3+Nf/3rXzqJg4hIakzOiMjgbNy4EdOnTwcAfPPNN3jnnXd0HBERkXSYnBGRQdmwYQPeffddxb/ffvttHUdERCQtTgggIoOxfv16RSvZpk2bmJgRkVFickZEBmHt2rWYOXMmTExMsHXrVkyaNEnXIRERVQp2axKR3rt37x5mzZoFQRAQEhKCMWPG6DokIqJKw5YzItJ7oigq/vfu3bs6joaIqHIxOSMivdewYUPFumULFizAN998o+OIiIgqD5MzIjIICxYswIIFCwAAM2fOlHSrJyIifcLkjIgMxvLlyzFz5kyIoojJkyfj4MGDug6JiEhyTM6IyKB8/fXXmDBhAoqLi/HWW2/h559/1nVIRESSYnJGRAZFEARs3rwZI0eORGFhIYYNG4ZTp07pOiwiIskwOSMig2NiYoLQ0FAMGjQI+fn5GDx4MH7//Xddh0VEJAkmZ0RkkMzNzXHgwAH06tULOTk5ePXVVxEbG6vrsIiItMbkjIgMlpWVFX766Sd069YN6enp6NevH+Li4nQdFhGRVrhDABFpzN/fX7EwbGUaP348xo8fX+41NjY2OHv2bKXHQkRUVZicEZFOXbp0Cb6+vgCARYsWYeDAgZKUu3DhQpw+fRpPnz6VpDwioqrC5IyIdCorKwvR0dEAgJSUFMnKvXbtmqJcIiJDIohV0TdBRERERGrhhAAiIiIiPcLkjIiIiEiPMDkjIiIi0iNMzoiIiIj0CJMzIiIiIj3C5IyIiIhIjzA5IyIiItIjTM6IiIiI9AiTMyIiIiI9wuSMiIiISI8wOSMiIiLSI/8PtrLlxttvSjsAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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iMomC5leChMZGYmOHTtizZo1RR63evVqdOzYEdHR0Ua3Jfvp27p1K3r06IEaNWpg2rRpyMjIwMKFC3HlyhXs27cPQgi9k3gRERERyWHdunU4duwYWrduXeRxrVu3RkREBDZs2GB0W7JPC44YMQKSJKFLly5YsmQJmjRpotmXmpoqd3NERET0NE4L6nTq1Ck4OzvrzG/1tMaNG6NSpUov1shVp06dIEkSDh8+jDFjxmDZsmW4efOm3M0QERGRLhJMnxJUYM6fGzduwMvLS69jvby8cOPGDaPbkj24Onz4MP79918sXboUABAUFAQPDw907twZmzdvhiQp8BMjIiKiF5q1tTUePnyo17EPHz6EhYXxIVKxLFlzc3PDe++9h7/++guxsbGYMWMGEhMT8e6770IIgY8//hgHDhwA85cSERHJzNTnCsoxrfgCqlu3LhITE5GQkFDkcQkJCUhISICvr6/RbRX7/QD169fHkiVLcPXqVRw5cgRjxoxBdHQ0evbsCXd39+JunoiIqGxhcKXTgAEDIITAyJEjkZKSovOYlJQUjBo1CpIkYdCgQUa3ZZbH32RlZeHnn3/G1q1b8fPPP5d086USH39DZQEff0NKVmKPvwkBHGxMrCsTcAxR1uNvMjIy0KxZM1y8eBGurq5444030LJlS1SsWBEpKSk4deoUNmzYgDt37qBu3br4888/S/bZgufPn8elS5fg6uqKVq1aPff4kydP4t69e6hVqxbq169vVEfLOgZXVBYwuCIlY3BlftevX0e/fv1w5swZnWvAhRDw8/PDDz/8YNLsmsGpGB4/foyuXbsiOTkZR48e1auMEAIDBw5EtWrVcPHiRahUJj5RkoiIiHRjKoZCubu74/Tp0/jxxx/x888/Iy4uDmlpaahQoQIaNGiAvn37om/fviYtZgeMCK62b9+OW7duYeLEiWjTpo1eZdq0aYPx48dj9erV2LFjB0aNGmVwR4mIiEgPDK6KZGFhgYEDB2LgwIHF14ahBX766SdIkoQpU6YYVE59p+APP/xgaJNEREREpYbBI1d//fUXqlatirp16xpUrnbt2qhevTr++usvQ5skIiIifcnxbEAFPluwJBl8+pKTk1G9enWjGqtWrRqSk5ONKktERER6sIDpaRhKeXDVsGFDfPvttybn07x27RomTpyIjz/+2KByBp8+GxsbZGRkGFoMwJPbIK2trY0qS0RERKSPhw8f4vXXX4evry8++ugjJCYm6l02Ozsbu3btwsCBA1G7dm2sW7cOrq6uBrVv8LRg1apVcenSJWRlZRl0119WVhYuXboEDw8PQ5skIiIifXFaEAkJCVixYgWWLFmC4OBghISEwMfHBy1atECzZs1QtWpVODs7Q6VSISUlBffv30dcXBxiYmIQExOD9PR0CCHQpUsXfPzxx2jSpIlB7RscXLVt2xbr16/Hzp07MWzYML3Lff/998jIyEDbtm0NbZKIiIj0xbsFoVKpEBQUhIkTJ2LLli1Yu3Ytzp49i6SkJGzfvl1nGfUUop2dHcaOHYsJEyagefPmRrVvcBLREydOICAgANWqVcPJkyf1SrJ17do1tGrVCnfu3EFkZCT8/f2N6mxZxiSiVBYwiSgpWYklEf0McDAusfj/6soAHKcpK4loYmIiIiMjceLECVy9ehXJycnIzMyEs7MzXF1d0aRJEwQEBKBNmzYoX768SW0ZPHLVpk0bDBo0CN9//z1atmyJL774AgMGDNCZcCs/Px87d+7Eu+++izt37mDAgAEMrIiIiIoTR650ql27NmrXro033ij+v+IMDq4AYNOmTbhx4wZOnDiBIUOGoHLlyvD390fNmjVhZ2eH9PR0XL58GSdOnMDdu3chhEDr1q2xadMmmbtPREREWrjmyuyMCq5sbW0RERGBkJAQrFy5Enfv3sWuXbu0ntOjnm20t7fH5MmTERISAisrK3l6TURERLpx5MrsjAquAKBcuXJYsGABZs6cib179+LEiRO4ceMGHj58iAoVKqB69epo06YNevbsCUdHRzn7TERERKS3e/fu4eeff8bvv/+OxMREPHjwABkZGbC1tYWTkxNq166Nli1bok+fPganXdDF4AXtZB5c0E5lARe0k5KV2IL2NTItaH+z9C9oz8zMxMyZM/H1118jJyenyKSikiTBysoK48ePx9KlS2Fra/xJNHrkioiIiF5A6gztptZRymVlZaF9+/b4448/IIRA3bp14e/vD29vbzg5OUGlUiErKwsPHjzAP//8g+joaMTHx+Orr77C6dOncfz4caMTnzO4IiIiIsX55JNPcPr0adSpUwcbNmxA69atn1vmxIkTGDt2LGJiYrB06VLMnTvXqLYVEJsSERGRhqnPFZRjQfwLYPv27bC2tsahQ4f0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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + " ### 3 design variable example\n", + "# Define design ranges\n", + "design_ranges = {\n", + " \"CA0[0]\": list(np.linspace(1, 5, 2)),\n", + " \"T[0]\": list(np.linspace(300, 700, 2)),\n", + " (\n", + " \"T[0.125]\",\n", + " \"T[0.25]\",\n", + " \"T[0.375]\",\n", + " \"T[0.5]\",\n", + " \"T[0.625]\",\n", + " \"T[0.75]\",\n", + " \"T[0.875]\",\n", + " \"T[1]\",\n", + " ): [300, 500],\n", + "}\n", + "\n", + "sensi_opt = \"direct_kaug\"\n", + "\n", + "doe_object = DesignOfExperiments(\n", + " parameter_dict, # parameter dictionary\n", + " exp_design, # design variables\n", + " measurements, # measurement variables\n", + " create_model, # model function\n", + " prior_FIM = prior_pass, \n", + " discretize_model=disc_for_measure, # discretization function\n", + ")\n", + "# run the grid search for 3 dimensional case\n", + "all_fim = doe_object.run_grid_search(design_ranges, mode=sensi_opt)\n", + "\n", + "all_fim.extract_criteria()\n", + "\n", + "# see the criteria values\n", + "all_fim.store_all_results_dataframe\n", + "\n", + "\n", + "\n", + "fixed = {\"('T[0.125]', 'T[0.25]', 'T[0.375]', 'T[0.5]', 'T[0.625]', 'T[0.75]', 'T[0.875]','T[1]')\": 300}\n", + "\n", + "all_fim.figure_drawing(\n", + " fixed, \n", + " [\"CA0[0]\",\"T[0]\"],\n", + " \"Reactor\", \n", + " \"T [K]\", \n", + " \"$C_{A0}$ [M]\"\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10c928cf-bc40-4a62-a176-3e3eb19ec78e", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb b/pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb new file mode 100644 index 00000000000..1c2f5383e58 --- /dev/null +++ b/pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb @@ -0,0 +1,10011 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "59659c7f-5ced-42da-b7dd-de22f614db9f", + "metadata": {}, + "source": [ + "# Imports" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "f875a1ff-c70d-4f94-a65c-495fbf8faa0c", + "metadata": {}, + "outputs": [], + "source": [ + "import pyomo.environ as pyo\n", + "from pyomo.dae import ContinuousSet, DerivativeVar\n", + "from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables, ModelOptionLib\n", + "import copy\n", + "import numpy as np\n", + "from random import sample\n", + "from matplotlib import pyplot as plt" + ] + }, + { + "cell_type": "markdown", + "id": "3b4d475b-bcf6-4e73-ba3b-0393bb65da30", + "metadata": {}, + "source": [ + "## Model function" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "7cf05f64-c3b1-4905-b5c1-b54dcb3aacea", + "metadata": {}, + "outputs": [], + "source": [ + "def create_model(\n", + " mod=None,\n", + " model_option=\"stage2\",\n", + " control_time=[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],\n", + " control_val=None,\n", + " t_range=[0.0, 1],\n", + " CA_init=1,\n", + " C_init=0.1,\n", + "):\n", + " \"\"\"\n", + " This is an example user model provided to DoE library.\n", + " It is a dynamic problem solved by Pyomo.DAE.\n", + "\n", + " Arguments\n", + " ---------\n", + " mod: Pyomo model. If None, a Pyomo concrete model is created\n", + " model_option: choose from the 3 options in model_option\n", + " if ModelOptionLib.parmest, create a process model.\n", + " if ModelOptionLib.stage1, create the global model.\n", + " if ModelOptionLib.stage2, add model variables and constraints for block.\n", + " control_time: a list of control timepoints\n", + " control_val: control design variable values T at corresponding timepoints\n", + " t_range: time range, h\n", + " CA_init: time-independent design (control) variable, an initial value for CA\n", + " C_init: An initial value for C\n", + "\n", + " Return\n", + " ------\n", + " m: a Pyomo.DAE model\n", + " \"\"\"\n", + "\n", + " theta = {\"A1\": 84.79, \"A2\": 371.72, \"E1\": 7.78, \"E2\": 15.05}\n", + "\n", + " model_option = ModelOptionLib(model_option)\n", + "\n", + " if model_option == ModelOptionLib.parmest:\n", + " mod = pyo.ConcreteModel()\n", + " return_m = True\n", + " elif model_option == ModelOptionLib.stage1 or model_option == ModelOptionLib.stage2:\n", + " if not mod:\n", + " raise ValueError(\n", + " \"If model option is stage1 or stage2, a created model needs to be provided.\"\n", + " )\n", + " return_m = False\n", + " else:\n", + " raise ValueError(\n", + " \"model_option needs to be defined as parmest,stage1, or stage2.\"\n", + " )\n", + "\n", + " if not control_val:\n", + " control_val = [300] * 9\n", + "\n", + " controls = {}\n", + " for i, t in enumerate(control_time):\n", + " controls[t] = control_val[i]\n", + "\n", + " mod.t0 = pyo.Set(initialize=[0])\n", + " mod.t_con = pyo.Set(initialize=control_time)\n", + " mod.CA0 = pyo.Var(\n", + " mod.t0, initialize=CA_init, bounds=(1.0, 5.0), within=pyo.NonNegativeReals\n", + " ) # mol/L\n", + "\n", + " # check if control_time is in time range\n", + " assert (\n", + " control_time[0] >= t_range[0] and control_time[-1] <= t_range[1]\n", + " ), \"control time is outside time range.\"\n", + "\n", + " if model_option == ModelOptionLib.stage1:\n", + " mod.T = pyo.Var(\n", + " mod.t_con,\n", + " initialize=controls,\n", + " bounds=(300, 700),\n", + " within=pyo.NonNegativeReals,\n", + " )\n", + " return\n", + "\n", + " else:\n", + " para_list = [\"A1\", \"A2\", \"E1\", \"E2\"]\n", + "\n", + " ### Add variables\n", + " mod.CA_init = CA_init\n", + " mod.para_list = para_list\n", + "\n", + " # timepoints\n", + " mod.t = ContinuousSet(bounds=t_range, initialize=control_time)\n", + "\n", + " # time-dependent design variable, initialized with the first control value\n", + " def T_initial(m, t):\n", + " if t in m.t_con:\n", + " return controls[t]\n", + " else:\n", + " # count how many control points are before the current t;\n", + " # locate the nearest neighbouring control point before this t\n", + " neighbour_t = max(tc for tc in control_time if tc < t)\n", + " return controls[neighbour_t]\n", + "\n", + " mod.T = pyo.Var(\n", + " mod.t, initialize=T_initial, bounds=(300, 700), within=pyo.NonNegativeReals\n", + " )\n", + "\n", + " mod.R = 8.31446261815324 # J / K / mole\n", + "\n", + " # Define parameters as Param\n", + " mod.A1 = pyo.Var(initialize=theta[\"A1\"])\n", + " mod.A2 = pyo.Var(initialize=theta[\"A2\"])\n", + " mod.E1 = pyo.Var(initialize=theta[\"E1\"])\n", + " mod.E2 = pyo.Var(initialize=theta[\"E2\"])\n", + "\n", + " # Concentration variables under perturbation\n", + " mod.C_set = pyo.Set(initialize=[\"CA\", \"CB\", \"CC\"])\n", + " mod.C = pyo.Var(\n", + " mod.C_set, mod.t, initialize=C_init, within=pyo.NonNegativeReals\n", + " )\n", + "\n", + " # time derivative of C\n", + " mod.dCdt = DerivativeVar(mod.C, wrt=mod.t)\n", + "\n", + " # kinetic parameters\n", + " def kp1_init(m, t):\n", + " return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", + "\n", + " def kp2_init(m, t):\n", + " return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", + "\n", + " mod.kp1 = pyo.Var(mod.t, initialize=kp1_init)\n", + " mod.kp2 = pyo.Var(mod.t, initialize=kp2_init)\n", + "\n", + " def T_control(m, t):\n", + " \"\"\"\n", + " T at interval timepoint equal to the T of the control time point at the beginning of this interval\n", + " Count how many control points are before the current t;\n", + " locate the nearest neighbouring control point before this t\n", + " \"\"\"\n", + " if t in m.t_con:\n", + " return pyo.Constraint.Skip\n", + " else:\n", + " neighbour_t = max(tc for tc in control_time if tc < t)\n", + " return m.T[t] == m.T[neighbour_t]\n", + "\n", + " def cal_kp1(m, t):\n", + " \"\"\"\n", + " Create the perturbation parameter sets\n", + " m: model\n", + " t: time\n", + " \"\"\"\n", + " # LHS: 1/h\n", + " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", + " return m.kp1[t] == m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", + "\n", + " def cal_kp2(m, t):\n", + " \"\"\"\n", + " Create the perturbation parameter sets\n", + " m: model\n", + " t: time\n", + " \"\"\"\n", + " # LHS: 1/h\n", + " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", + " return m.kp2[t] == m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", + "\n", + " def dCdt_control(m, y, t):\n", + " \"\"\"\n", + " Calculate CA in Jacobian matrix analytically\n", + " y: CA, CB, CC\n", + " t: timepoints\n", + " \"\"\"\n", + " if y == \"CA\":\n", + " return m.dCdt[y, t] == -m.kp1[t] * m.C[\"CA\", t]\n", + " elif y == \"CB\":\n", + " return m.dCdt[y, t] == m.kp1[t] * m.C[\"CA\", t] - m.kp2[t] * m.C[\"CB\", t]\n", + " elif y == \"CC\":\n", + " return pyo.Constraint.Skip\n", + "\n", + " def alge(m, t):\n", + " \"\"\"\n", + " The algebraic equation for mole balance\n", + " z: m.pert\n", + " t: time\n", + " \"\"\"\n", + " return m.C[\"CA\", t] + m.C[\"CB\", t] + m.C[\"CC\", t] == m.CA0[0]\n", + "\n", + " # Control time\n", + " mod.T_rule = pyo.Constraint(mod.t, rule=T_control)\n", + "\n", + " # calculating C, Jacobian, FIM\n", + " mod.k1_pert_rule = pyo.Constraint(mod.t, rule=cal_kp1)\n", + " mod.k2_pert_rule = pyo.Constraint(mod.t, rule=cal_kp2)\n", + " mod.dCdt_rule = pyo.Constraint(mod.C_set, mod.t, rule=dCdt_control)\n", + "\n", + " mod.alge_rule = pyo.Constraint(mod.t, rule=alge)\n", + "\n", + " # B.C.\n", + " mod.C[\"CB\", 0.0].fix(0.0)\n", + " mod.C[\"CC\", 0.0].fix(0.0)\n", + "\n", + " if return_m:\n", + " return mod\n", + "\n", + "\n", + "def disc_for_measure(m, nfe=32, block=True):\n", + " \"\"\"Pyomo.DAE discretization\n", + "\n", + " Arguments\n", + " ---------\n", + " m: Pyomo model\n", + " nfe: number of finite elements b\n", + " block: if True, the input model has blocks\n", + " \"\"\"\n", + " discretizer = pyo.TransformationFactory(\"dae.collocation\")\n", + " if block:\n", + " for s in range(len(m.block)):\n", + " discretizer.apply_to(m.block[s], nfe=nfe, ncp=3, wrt=m.block[s].t)\n", + " else:\n", + " discretizer.apply_to(m, nfe=nfe, ncp=3, wrt=m.t)\n", + " return m" + ] + }, + { + "cell_type": "markdown", + "id": "ac9e76cb-cbf5-44fb-aa53-bbb5dca1bcb0", + "metadata": {}, + "source": [ + "## Helper Functions" + ] + }, + { + "cell_type": "markdown", + "id": "2814a5e6-e4b0-4fa1-948c-a8671c52fb4b", + "metadata": {}, + "source": [ + "### Create a doe object" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "24628fdb-317d-4121-b4ea-9909298a757e", + "metadata": {}, + "outputs": [], + "source": [ + "def create_doe_object(Ca_val, T_vals, prior_FIM=None):\n", + " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", + " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", + " \n", + " measurements = MeasurementVariables()\n", + " measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", + " \n", + " exp_design = DesignVariables()\n", + " exp_design.add_variables(\n", + " \"CA0\",\n", + " time_index_position=0,\n", + " values=[Ca_val, ],\n", + " lower_bounds=1,\n", + " indices={0: [0]},\n", + " upper_bounds=5,\n", + " )\n", + " exp_design.add_variables(\n", + " \"T\",\n", + " indices={0: t_control},\n", + " time_index_position=0,\n", + " values=T_vals,\n", + " lower_bounds=300,\n", + " upper_bounds=700,\n", + " )\n", + " \n", + " doe_object = DesignOfExperiments(\n", + " parameter_dict,\n", + " exp_design, \n", + " measurements, \n", + " create_model,\n", + " prior_FIM=prior_FIM,\n", + " discretize_model=disc_for_measure,\n", + " )\n", + " return doe_object" + ] + }, + { + "cell_type": "markdown", + "id": "35346c15-408b-4f32-bbfa-b4de9da2eaae", + "metadata": {}, + "source": [ + "### Compute FIM using the compute_FIM function" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "0a2d84d7-9989-43d3-84d0-df01a95c5a66", + "metadata": {}, + "outputs": [], + "source": [ + "def compute_specific_FIM(Ca_val, T_vals, prior_FIM=None, scale_param=True):\n", + " doe_object = create_doe_object(Ca_val, T_vals, prior_FIM)\n", + "\n", + " result = doe_object.compute_FIM(\n", + " mode=\"sequential_finite\",\n", + " scale_nominal_param_value=scale_param,\n", + " formula=\"central\",\n", + " )\n", + " result.result_analysis()\n", + " \n", + " return result" + ] + }, + { + "cell_type": "markdown", + "id": "1a6f71b5-f09c-40d3-9793-b830f05aae54", + "metadata": {}, + "source": [ + "### Rescale FIM" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "d000abc6-9140-4634-a180-d1c2b6df9e0c", + "metadata": {}, + "outputs": [], + "source": [ + "def rescale_FIM(FIM, param_vals):\n", + " param_scaling_mat = (1 / param_vals).transpose().dot(1 / param_vals)\n", + " unscaled_FIM = np.multiply(FIM, param_scaling_mat)\n", + " return unscaled_FIM" + ] + }, + { + "cell_type": "markdown", + "id": "679466b7-5299-4489-a3fb-cbfdd74cfc27", + "metadata": {}, + "source": [ + "### Translate Jacobian to numpy array" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "dff13661-d577-44a3-a171-b3fa1e6ff367", + "metadata": {}, + "outputs": [], + "source": [ + "def translate_jac(jac_dict):\n", + " param_names = ['A1', 'A2', 'E1', 'E2']\n", + " Q_all = np.array(list(jac_dict for p in param_names)).T\n", + " return Q_all" + ] + }, + { + "cell_type": "markdown", + "id": "60fcc29c-dad9-4d85-8d2c-81daeb08deb3", + "metadata": {}, + "source": [ + "### Get experimental conditions from solved model" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d6923520-83b5-4a64-9040-f19e1fa663f2", + "metadata": {}, + "outputs": [], + "source": [ + "def get_exp_conds(m):\n", + " return [pyo.value(m.CA0[0]),\n", + " pyo.value(m.T[0]),\n", + " pyo.value(m.T[0.125]),\n", + " pyo.value(m.T[0.25]),\n", + " pyo.value(m.T[0.375]),\n", + " pyo.value(m.T[0.5]),\n", + " pyo.value(m.T[0.625]),\n", + " pyo.value(m.T[0.75]),\n", + " pyo.value(m.T[0.875]),\n", + " pyo.value(m.T[1])]" + ] + }, + { + "cell_type": "markdown", + "id": "ed69f2f3-0517-4bdd-ae43-9566560e7e73", + "metadata": {}, + "source": [ + "### Run optimal experiment" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "989b0b0d-6cca-4c56-8088-8c95c9c1773a", + "metadata": {}, + "outputs": [], + "source": [ + "def run_optimal_exp(Ca, Ta_vals, prior_FIM=None, scale_param=True):\n", + " doe_object = create_doe_object(Ca, Ta_vals, prior_FIM)\n", + "\n", + " if prior_FIM is None:\n", + " prior_FIM = np.eye(4)\n", + " \n", + " square_result, optimize_result = doe_object.stochastic_program(\n", + " if_optimize=True,\n", + " if_Cholesky=True,\n", + " scale_nominal_param_value=scale_param,\n", + " objective_option=\"det\",\n", + " L_initial=np.linalg.cholesky(prior_FIM),\n", + " )\n", + " \n", + " return optimize_result" + ] + }, + { + "cell_type": "markdown", + "id": "950f0e98-74b7-42bb-8781-a94da863eac6", + "metadata": {}, + "source": [ + "# Perform the analysis" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "e5013f1e-0e77-4697-a9de-8c137d930452", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 5.77e+02 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 6.70e+00 3.85e+00 -1.0 6.23e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 6.62e-02 4.39e+00 -1.0 7.18e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.10e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -7.8073036e+00 1.25e+00 1.21e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -7.8354856e+00 6.29e-01 5.10e+00 -1.0 4.68e+01 - 9.58e-01 4.97e-01h 1\n", + " 2 -7.8368689e+00 8.10e-01 1.42e+00 -1.0 3.23e+01 - 9.25e-01 1.00e+00f 1\n", + " 3 -7.9348649e+00 7.30e+01 1.59e+02 -1.0 4.72e+02 - 2.16e-01 7.26e-01f 1\n", + " 4 -7.7429992e+00 1.53e+01 2.05e+00 -1.0 1.61e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -7.7606510e+00 3.51e+00 2.02e+00 -1.0 1.39e+02 - 1.00e+00 1.00e+00f 1\n", + " 6 -7.6711598e+00 5.13e+00 3.33e-01 -1.0 4.03e+01 - 1.00e+00 1.00e+00h 1\n", + " 7 -7.6659485e+00 4.95e-02 7.71e-03 -1.0 2.74e+00 - 1.00e+00 1.00e+00h 1\n", + " 8 -7.6685762e+00 2.86e-03 1.24e-02 -2.5 8.68e-01 - 1.00e+00 1.00e+00h 1\n", + " 9 -7.7508739e+00 3.08e+00 3.55e-01 -3.8 3.14e+01 - 8.03e-01 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -7.8600596e+00 6.29e+00 2.01e-01 -3.8 6.87e+01 - 1.00e+00 1.00e+00h 1\n", + " 11 -7.9182984e+00 4.14e+00 1.52e-01 -3.8 2.68e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 -7.9098461e+00 6.13e-02 2.12e-03 -3.8 8.74e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (325287)\n", + " 13 -7.9098458e+00 4.63e-05 4.17e-06 -3.8 2.49e-01 - 1.00e+00 1.00e+00h 1\n", + " 14 -7.9395810e+00 1.47e+00 5.37e-02 -5.7 2.73e+01 - 7.73e-01 1.00e+00h 1\n", + " 15 -7.9504201e+00 6.12e-01 7.82e-02 -5.7 2.47e+01 - 9.84e-01 1.00e+00h 1\n", + " 16 -7.9503130e+00 1.96e-02 5.10e-03 -5.7 1.22e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (347931)\n", + " 17 -7.9503760e+00 2.90e-03 7.32e-04 -5.7 4.78e+00 - 1.00e+00 1.00e+00h 1\n", + " 18 -7.9503861e+00 5.47e-05 1.53e-05 -5.7 6.60e-01 - 1.00e+00 1.00e+00h 1\n", + " 19 -7.9503862e+00 1.43e-08 5.92e-09 -5.7 1.07e-02 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -7.9510641e+00 2.59e-03 7.06e-04 -8.6 4.57e+00 - 9.84e-01 1.00e+00h 1\n", + " 21 -7.9510903e+00 1.70e-04 5.47e-05 -8.6 1.18e+00 - 1.00e+00 1.00e+00h 1\n", + " 22 -7.9510917e+00 4.69e-07 2.65e-07 -8.6 6.21e-02 - 1.00e+00 1.00e+00h 1\n", + " 23 -7.9510917e+00 4.83e-12 5.34e-12 -8.6 1.99e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 23\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -7.9510917256426819e+00 -7.9510917256426819e+00\n", + "Dual infeasibility......: 5.3406483518369473e-12 5.3406483518369473e-12\n", + "Constraint violation....: 4.8324677592859189e-12 4.8324677592859189e-12\n", + "Complementarity.........: 2.5059057458010459e-09 2.5059057458010459e-09\n", + "Overall NLP error.......: 2.5059057458010459e-09 2.5059057458010459e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 24\n", + "Number of objective gradient evaluations = 24\n", + "Number of equality constraint evaluations = 24\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 24\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 23\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.827\n", + "Total CPU secs in NLP function evaluations = 0.027\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.5 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 3.83e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.42e-02 3.85e+00 -1.0 4.12e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.37e-04 4.39e+00 -1.0 4.72e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.67e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8338667230373176e-11 5.8338667230373176e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8338667230373176e-11 5.8338667230373176e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.3463002e+00 1.25e+00 7.84e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 5.3181206e+00 6.32e-01 4.24e+01 -1.0 7.13e-01 - 9.72e-01 4.95e-01h 1\n", + " 2 5.3083839e+00 2.63e-02 1.90e+00 -1.0 3.89e+00 - 9.00e-01 1.00e+00f 1\n", + " 3 5.2237497e+00 1.10e+01 1.32e+02 -1.0 1.82e+02 - 1.89e-01 6.62e-01f 1\n", + " 4 5.4304758e+00 5.04e-01 2.27e+00 -1.0 3.13e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 5.3767095e+00 5.59e-01 3.10e+01 -1.0 1.35e+02 - 1.00e+00 4.26e-01f 2\n", + " 6 5.4552152e+00 8.41e-01 3.31e+00 -1.0 8.84e+01 - 9.40e-01 3.64e-01f 2\n", + " 7 5.5170724e+00 4.57e-01 4.85e-01 -1.0 4.86e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 5.5110643e+00 5.10e-03 2.84e-02 -1.7 1.44e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 5.4931986e+00 9.03e-03 1.34e-02 -2.5 4.22e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.4082326e+00 3.49e-01 3.95e-01 -3.8 2.69e+01 - 7.84e-01 1.00e+00h 1\n", + " 11 5.3009072e+00 1.28e+00 1.94e-01 -3.8 6.45e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 5.2328311e+00 3.94e-01 2.25e-01 -3.8 2.80e+01 - 1.00e+00 1.00e+00h 1\n", + " 13 5.2437917e+00 5.42e-03 2.96e-03 -3.8 2.67e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (320786)\n", + " 14 5.2437575e+00 2.67e-05 8.17e-06 -3.8 2.13e-01 - 1.00e+00 1.00e+00h 1\n", + " 15 5.2424530e+00 7.65e-06 1.35e-05 -5.7 9.87e-02 -4.0 1.00e+00 1.00e+00h 1\n", + " 16 5.2417146e+00 5.83e-05 6.61e-05 -8.6 3.00e-01 -4.5 9.97e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (344430)\n", + " 17 5.2399653e+00 4.96e-04 6.20e-04 -8.6 8.80e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 18 5.2353444e+00 3.84e-03 4.47e-03 -8.6 2.48e+00 -5.4 1.00e+00 1.00e+00h 1\n", + " 19 5.2251746e+00 2.39e-02 2.25e-02 -8.6 6.35e+00 -5.9 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 5.2221058e+00 2.25e-02 2.03e-02 -8.6 1.32e+01 -6.4 1.00e+00 1.69e-01h 1\n", + " 21 5.2103493e+00 7.19e-02 5.06e-02 -8.6 2.54e+01 -6.9 1.00e+00 6.04e-01f 1\n", + " 22 5.1989953e+00 2.17e-01 1.44e-01 -8.6 5.35e+01 - 1.00e+00 7.30e-01f 1\n", + " 23 5.1994362e+00 1.93e-01 1.25e-01 -8.6 4.05e+01 - 1.00e+00 1.27e-01h 1\n", + " 24 5.2008740e+00 1.40e-01 6.63e-02 -8.6 3.68e+01 - 1.00e+00 4.77e-01h 1\n", + " 25 5.2025347e+00 1.75e-03 2.05e-03 -8.6 3.78e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (363451)\n", + " 26 5.2025125e+00 1.38e-03 1.06e-05 -8.6 3.34e+00 - 1.00e+00 1.00e+00h 1\n", + " 27 5.2025121e+00 2.22e-05 1.37e-07 -8.6 4.27e-01 - 1.00e+00 1.00e+00h 1\n", + " 28 5.2025121e+00 3.85e-09 2.27e-11 -8.6 5.62e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 28\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 5.2025120660150401e+00 5.2025120660150401e+00\n", + "Dual infeasibility......: 2.2651314864147046e-11 2.2651314864147046e-11\n", + "Constraint violation....: 3.8472891539242937e-09 3.8472891539242937e-09\n", + "Complementarity.........: 2.5061201652512559e-09 2.5061201652512559e-09\n", + "Overall NLP error.......: 3.8472891539242937e-09 3.8472891539242937e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 35\n", + "Number of objective gradient evaluations = 29\n", + "Number of equality constraint evaluations = 35\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 29\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 28\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.155\n", + "Total CPU secs in NLP function evaluations = 0.043\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.9 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.43e-03 1.52e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.33e-09 1.52e-06 -1.0 1.82e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.3276043314979233e-09 2.3276043314979233e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.3276043314979233e-09 2.3276043314979233e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.43e-03 1.52e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.33e-09 1.52e-06 -1.0 1.82e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.3276034433195036e-09 2.3276034433195036e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.3276034433195036e-09 2.3276034433195036e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 7.65e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 5.84e+02 3.85e+02 -1.0 7.65e+02 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 6.77e+00 3.85e+00 -1.0 6.31e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 6.70e-02 4.39e+00 -1.0 7.25e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.17e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0383309725439176e-09 9.0383309725439176e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0383309725439176e-09 9.0383309725439176e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -9.0980672e+00 1.25e+00 1.13e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -9.1088823e+00 6.23e-01 5.20e+00 -1.0 4.67e+01 - 9.73e-01 5.02e-01h 1\n", + " 2 -9.1070281e+00 1.28e+00 1.94e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -9.1458221e+00 7.33e+01 1.31e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -9.0628162e+00 1.67e+01 2.33e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -9.0789051e+00 1.17e+01 3.14e+01 -1.0 1.36e+02 - 1.00e+00 4.20e-01f 2\n", + " 6 -9.0469561e+00 1.20e+01 3.32e+00 -1.0 9.02e+01 - 9.08e-01 3.50e-01f 2\n", + " 7 -9.0194008e+00 3.33e+00 5.06e-01 -1.0 5.04e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -9.0315738e+00 3.90e-01 6.40e-02 -1.0 9.89e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 -9.0319624e+00 5.08e-04 4.68e-03 -1.7 3.22e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -9.0344881e+00 1.57e-02 2.20e-01 -3.8 2.67e+00 - 9.84e-01 1.00e+00h 1\n", + " 11 -9.0929490e+00 9.49e+00 2.02e-01 -3.8 7.71e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 -9.1265794e+00 4.04e+00 1.08e-01 -3.8 2.61e+01 - 1.00e+00 1.00e+00h 1\n", + " 13 -9.1216817e+00 7.85e-02 1.20e-03 -3.8 1.12e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (325095)\n", + " 14 -9.1216910e+00 9.57e-05 3.07e-06 -3.8 2.80e-01 - 1.00e+00 1.00e+00h 1\n", + " 15 -9.1419843e+00 2.21e+00 4.13e-02 -5.7 3.31e+01 - 7.83e-01 1.00e+00h 1\n", + " 16 -9.1523277e+00 3.23e+00 1.07e-01 -5.7 5.50e+01 - 5.77e-01 8.28e-01h 1\n", + " 17 -9.1542206e+00 1.66e-01 4.37e-03 -5.7 1.73e+01 - 1.00e+00 1.00e+00h 1\n", + " 18 -9.1545142e+00 1.36e-02 1.84e-03 -5.7 1.01e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -9.1545212e+00 1.02e-03 1.25e-04 -5.7 2.81e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (343319)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -9.1545223e+00 4.18e-06 5.47e-07 -5.7 1.81e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -9.1551820e+00 9.84e-03 7.80e-04 -8.6 6.83e+00 - 9.73e-01 1.00e+00h 1\n", + " 22 -9.1552078e+00 8.18e-04 1.19e-04 -8.6 2.58e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (362498)\n", + " 23 -9.1552112e+00 1.16e-05 2.50e-06 -8.6 3.08e-01 - 1.00e+00 1.00e+00h 1\n", + " 24 -9.1552112e+00 1.62e-09 9.16e-10 -8.6 3.65e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 24\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -9.1552111997823289e+00 -9.1552111997823289e+00\n", + "Dual infeasibility......: 9.1614693867759918e-10 9.1614693867759918e-10\n", + "Constraint violation....: 1.6240718769822138e-09 1.6240718769822138e-09\n", + "Complementarity.........: 2.5062713088537995e-09 2.5062713088537995e-09\n", + "Overall NLP error.......: 2.5062713088537995e-09 2.5062713088537995e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 31\n", + "Number of objective gradient evaluations = 25\n", + "Number of equality constraint evaluations = 31\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 25\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 24\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.818\n", + "Total CPU secs in NLP function evaluations = 0.029\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.3 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 3.86e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.45e-02 3.85e+00 -1.0 4.15e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.40e-04 4.39e+00 -1.0 4.75e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.70e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8336890873533775e-11 5.8336890873533775e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8336890873533775e-11 5.8336890873533775e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", + "Total CPU secs in NLP function evaluations = 0.007\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 4.0555365e+00 1.25e+00 4.96e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 4.0447179e+00 6.24e-01 2.67e+01 -1.0 7.09e-01 - 9.72e-01 5.01e-01h 1\n", + " 2 4.0465757e+00 2.64e-02 1.93e+00 -1.0 3.91e+00 - 8.99e-01 1.00e+00f 1\n", + " 3 4.0077802e+00 1.10e+01 1.31e+02 -1.0 1.82e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 4.0907795e+00 5.11e-01 2.33e+00 -1.0 3.13e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 4.0746958e+00 5.49e-01 3.14e+01 -1.0 1.36e+02 - 1.00e+00 4.20e-01f 2\n", + " 6 4.1066414e+00 8.29e-01 3.32e+00 -1.0 9.02e+01 - 9.08e-01 3.50e-01f 2\n", + " 7 4.1341891e+00 4.99e-01 5.06e-01 -1.0 5.03e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 4.1322707e+00 5.59e-03 2.41e-02 -1.7 1.21e+00 - 1.00e+00 1.00e+00h 1\n", + " 9 4.1294448e+00 1.74e-03 1.90e-01 -3.8 1.80e+00 - 9.85e-01 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 4.0577304e+00 2.51e+00 3.18e-01 -3.8 8.71e+01 - 1.00e+00 1.00e+00h 1\n", + " 11 4.0619968e+00 6.23e-02 7.22e-03 -3.8 1.27e+00 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 4.0610820e+00 2.11e-05 1.57e-05 -3.8 1.71e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 4.0025145e+00 1.12e+00 2.83e-01 -5.7 5.61e+01 - 6.15e-01 1.00e+00h 1\n", + " 14 4.0028658e+00 3.34e-01 8.43e-02 -5.7 2.46e+01 - 6.14e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (328499)\n", + " 15 3.9993729e+00 8.26e-02 2.36e-02 -5.7 1.29e+01 - 1.00e+00 8.29e-01h 1\n", + " 16 3.9990307e+00 1.69e-02 2.80e-03 -5.7 1.13e+01 - 1.00e+00 1.00e+00f 1\n", + " 17 3.9990819e+00 1.12e-03 1.43e-04 -5.7 2.96e+00 - 1.00e+00 1.00e+00h 1\n", + " 18 3.9990815e+00 4.62e-06 7.31e-07 -5.7 1.90e-01 - 1.00e+00 1.00e+00h 1\n", + " 19 3.9984217e+00 5.89e-03 7.80e-04 -8.6 6.83e+00 - 9.73e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (356713)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 3.9983959e+00 8.18e-04 1.19e-04 -8.6 2.58e+00 - 1.00e+00 1.00e+00h 1\n", + " 21 3.9983926e+00 1.16e-05 2.50e-06 -8.6 3.08e-01 - 1.00e+00 1.00e+00h 1\n", + " 22 3.9983926e+00 1.62e-09 9.16e-10 -8.6 3.65e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 22\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 3.9983925918754277e+00 3.9983925918754277e+00\n", + "Dual infeasibility......: 9.1638497048149078e-10 9.1638497048149078e-10\n", + "Constraint violation....: 1.6245825795735414e-09 1.6245825795735414e-09\n", + "Complementarity.........: 2.5062714319510496e-09 2.5062714319510496e-09\n", + "Overall NLP error.......: 2.5062714319510496e-09 2.5062714319510496e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 29\n", + "Number of objective gradient evaluations = 23\n", + "Number of equality constraint evaluations = 29\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 23\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 22\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.757\n", + "Total CPU secs in NLP function evaluations = 0.035\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.5 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.43e-03 1.62e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.31e-09 1.52e-06 -1.0 1.81e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.3096600187955119e-09 2.3096600187955119e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.3096600187955119e-09 2.3096600187955119e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.43e-03 1.62e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.31e-09 1.52e-06 -1.0 1.81e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.3096582424386725e-09 2.3096582424386725e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.3096582424386725e-09 2.3096582424386725e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.53e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 5.92e+02 3.85e+02 -1.0 1.53e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 6.85e+00 3.85e+00 -1.0 6.39e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 6.78e-02 4.39e+00 -1.0 7.33e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.25e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0381035988684744e-09 9.0381035988684744e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0381035988684744e-09 9.0381035988684744e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -9.8243678e+00 1.25e+00 1.11e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -9.8309752e+00 6.21e-01 5.18e+00 -1.0 4.66e+01 - 9.73e-01 5.03e-01h 1\n", + " 2 -9.8284057e+00 1.28e+00 1.94e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -9.8536224e+00 7.33e+01 1.31e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -9.8018928e+00 1.67e+01 2.30e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -9.8108490e+00 1.17e+01 3.16e+01 -1.0 1.36e+02 - 1.00e+00 4.18e-01f 2\n", + " 6 -9.7907700e+00 1.21e+01 3.32e+00 -1.0 9.09e+01 - 8.96e-01 3.45e-01f 2\n", + " 7 -9.7727931e+00 3.44e+00 5.16e-01 -1.0 5.11e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -9.7806557e+00 4.10e-01 6.89e-02 -1.0 1.03e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -9.7808078e+00 3.15e-04 3.35e-03 -1.7 2.38e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -9.7818625e+00 6.70e-03 1.10e-01 -3.8 1.81e+00 - 9.92e-01 1.00e+00h 1\n", + " 11 -9.8219871e+00 1.08e+01 1.59e-01 -3.8 8.04e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 -9.8318869e+00 1.12e+00 2.36e-02 -3.8 1.46e+01 - 1.00e+00 1.00e+00h 1\n", + " 13 -9.8315331e+00 8.02e-03 5.09e-05 -3.8 3.56e+00 - 1.00e+00 1.00e+00h 1\n", + " 14 -9.8315167e+00 4.91e-06 6.23e-08 -3.8 2.45e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319727)\n", + " 15 -9.8470261e+00 2.31e+00 2.95e-02 -5.7 3.68e+01 - 7.66e-01 1.00e+00f 1\n", + " 16 -9.8550043e+00 3.01e+00 3.76e-02 -5.7 4.15e+01 - 6.44e-01 1.00e+00h 1\n", + " 17 -9.8580603e+00 2.13e+00 3.03e-02 -5.7 5.38e+01 - 9.08e-01 5.97e-01h 1\n", + "Reallocating memory for MA57: lfact (343560)\n", + " 18 -9.8590178e+00 5.44e-02 3.07e-03 -5.7 1.49e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -9.8588956e+00 2.88e-03 2.14e-04 -5.7 4.70e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -9.8588964e+00 2.30e-05 1.59e-06 -5.7 4.22e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -9.8588964e+00 1.08e-09 9.88e-11 -5.7 2.90e-03 - 1.00e+00 1.00e+00h 1\n", + " 22 -9.8595479e+00 2.23e-02 7.77e-04 -8.6 8.37e+00 - 9.64e-01 1.00e+00f 1\n", + " 23 -9.8595710e+00 1.73e-03 1.60e-04 -8.6 3.74e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 -9.8595756e+00 5.35e-05 6.70e-06 -8.6 6.62e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (362351)\n", + " 25 -9.8595757e+00 3.41e-08 9.69e-09 -8.6 1.67e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 -9.8595757e+00 4.55e-13 5.52e-14 -8.6 2.20e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -9.8595757275986511e+00 -9.8595757275986511e+00\n", + "Dual infeasibility......: 5.5219338836918813e-14 5.5219338836918813e-14\n", + "Constraint violation....: 1.1824654114063750e-13 4.5474735088646412e-13\n", + "Complementarity.........: 2.5059035684619852e-09 2.5059035684619852e-09\n", + "Overall NLP error.......: 2.5059035684619852e-09 2.5059035684619852e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.850\n", + "Total CPU secs in NLP function evaluations = 0.040\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.5 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 3.89e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.48e-02 3.85e+00 -1.0 4.18e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.43e-04 4.39e+00 -1.0 4.79e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.73e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8336446784323925e-11 5.8336446784323925e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8336446784323925e-11 5.8336446784323925e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 3.3292360e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 3.3241914e+00 1.69e-01 1.13e+00 -1.0 5.96e-01 - 9.79e-01 8.65e-01h 1\n", + " 2 3.3248864e+00 3.48e-02 1.06e+01 -1.0 6.02e+00 - 8.34e-01 1.00e+00f 1\n", + " 3 3.3013605e+00 1.26e+01 5.70e+01 -1.0 1.80e+02 - 1.92e-01 7.12e-01f 1\n", + " 4 3.3560475e+00 7.19e-01 2.65e+00 -1.0 2.65e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 3.3417261e+00 5.86e-01 4.46e+01 -1.0 3.82e+02 - 4.35e-01 8.06e-02f 2\n", + " 6 3.3757459e+00 1.35e-01 4.87e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", + " 7 3.3696371e+00 4.25e-01 3.04e-01 -1.0 5.43e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 3.3719932e+00 4.00e-02 5.66e-02 -1.7 1.71e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 3.3709820e+00 4.47e-03 3.86e-03 -2.5 5.77e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 3.3640190e+00 1.64e-02 7.98e-02 -3.8 6.30e+00 - 9.57e-01 1.00e+00h 1\n", + " 11 3.3273550e+00 8.10e-01 8.71e-02 -3.8 4.15e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 3.3219891e+00 1.09e-01 1.42e-02 -3.8 1.16e+01 - 1.00e+00 1.00e+00h 1\n", + " 13 3.3220787e+00 1.81e-04 1.97e-05 -3.8 5.23e-01 - 1.00e+00 1.00e+00h 1\n", + " 14 3.3065783e+00 3.88e-01 2.95e-02 -5.7 3.68e+01 - 7.66e-01 1.00e+00h 1\n", + " 15 3.3088038e+00 6.58e-04 2.85e-03 -5.7 1.95e-01 -4.5 9.73e-01 1.00e+00h 1\n", + " 16 3.3086408e+00 2.78e-05 4.37e-06 -5.7 2.06e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 17 3.3082900e+00 2.44e-04 3.75e-05 -5.7 6.13e-01 -5.4 1.00e+00 1.00e+00h 1\n", + " 18 3.3073216e+00 2.02e-03 3.10e-04 -5.7 1.78e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 19 3.3049420e+00 1.48e-02 2.24e-03 -5.7 4.93e+00 -6.4 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 3.3006609e+00 6.58e-02 9.79e-03 -5.7 1.19e+01 -6.9 1.00e+00 8.79e-01h 1\n", + " 21 3.2971545e+00 1.04e-01 2.91e-02 -5.7 1.96e+01 -7.3 1.00e+00 1.00e+00f 1\n", + " 22 3.2963467e+00 1.07e-01 2.86e-02 -5.7 9.98e+01 - 9.97e-01 5.49e-02h 1\n", + " 23 3.2940284e+00 2.58e-01 2.86e-02 -5.7 4.31e+01 - 1.00e+00 1.00e+00f 1\n", + "Reallocating memory for MA57: lfact (328243)\n", + " 24 3.2947114e+00 6.39e-03 2.75e-03 -5.7 5.48e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 3.2947076e+00 2.82e-04 1.21e-05 -5.7 1.48e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 3.2947074e+00 3.77e-07 7.87e-09 -5.7 5.41e-02 - 1.00e+00 1.00e+00h 1\n", + " 27 3.2940558e+00 8.94e-03 7.77e-04 -8.6 8.37e+00 - 9.64e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (351796)\n", + " 28 3.2940328e+00 1.73e-03 1.60e-04 -8.6 3.74e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 3.2940282e+00 5.35e-05 6.70e-06 -8.6 6.62e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 3.2940281e+00 3.41e-08 9.69e-09 -8.6 1.67e-02 - 1.00e+00 1.00e+00h 1\n", + " 31 3.2940281e+00 3.59e-13 6.26e-14 -8.6 2.20e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 31\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 3.2940280640592707e+00 3.2940280640592707e+00\n", + "Dual infeasibility......: 6.2616567740385095e-14 6.2616567740385095e-14\n", + "Constraint violation....: 1.5287940420760863e-13 3.5882408155885059e-13\n", + "Complementarity.........: 2.5059035684585384e-09 2.5059035684585384e-09\n", + "Overall NLP error.......: 2.5059035684585384e-09 2.5059035684585384e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 36\n", + "Number of objective gradient evaluations = 32\n", + "Number of equality constraint evaluations = 36\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 32\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 31\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.195\n", + "Total CPU secs in NLP function evaluations = 0.048\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.9 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.42e-03 1.85e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.27e-09 1.51e-06 -1.0 1.79e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.2713546599106849e-09 2.2713546599106849e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.2713546599106849e-09 2.2713546599106849e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.104\n", + "Total CPU secs in NLP function evaluations = 0.007\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.42e-03 1.85e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.27e-09 1.51e-06 -1.0 1.79e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.2713533276430553e-09 2.2713533276430553e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.2713533276430553e-09 2.2713533276430553e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.30e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.00e+02 3.85e+02 -1.0 2.30e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 6.93e+00 3.85e+00 -1.0 6.46e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 6.85e-02 4.39e+00 -1.0 7.41e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.33e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.0333966e+01 1.25e+00 1.09e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.0338708e+01 6.20e-01 5.17e+00 -1.0 4.65e+01 - 9.73e-01 5.04e-01h 1\n", + " 2 -1.0336296e+01 1.28e+00 1.95e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.0354984e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.0317441e+01 1.67e+01 2.27e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.0323555e+01 1.17e+01 3.18e+01 -1.0 1.36e+02 - 1.00e+00 4.16e-01f 2\n", + " 6 -1.0308913e+01 1.22e+01 3.32e+00 -1.0 9.13e+01 - 8.90e-01 3.42e-01f 2\n", + " 7 -1.0295537e+01 3.50e+00 5.22e-01 -1.0 5.14e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.0301363e+01 4.21e-01 7.17e-02 -1.0 1.05e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.0301441e+01 2.63e-04 2.69e-03 -1.7 2.08e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.0302019e+01 3.71e-03 5.57e-02 -3.8 1.37e+00 - 9.96e-01 1.00e+00h 1\n", + " 11 -1.0333647e+01 1.23e+01 1.35e-01 -3.8 8.29e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 -1.0334471e+01 3.28e-01 4.31e-03 -3.8 1.15e+01 - 1.00e+00 1.00e+00h 1\n", + " 13 -1.0335026e+01 4.18e-03 1.95e-05 -3.8 6.62e-01 - 1.00e+00 1.00e+00h 1\n", + " 14 -1.0335021e+01 3.25e-07 2.67e-09 -3.8 1.60e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (324090)\n", + " 15 -1.0347510e+01 2.31e+00 2.80e-02 -5.7 3.87e+01 - 7.60e-01 1.00e+00f 1\n", + " 16 -1.0354058e+01 2.41e+00 2.21e-02 -5.7 3.02e+01 - 7.30e-01 1.00e+00h 1\n", + " 17 -1.0356712e+01 3.68e+00 4.66e-02 -5.7 1.52e+02 - 5.86e-01 2.47e-01h 1\n", + " 18 -1.0358821e+01 2.88e-01 4.06e-03 -5.7 1.96e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.0358654e+01 8.94e-03 4.59e-04 -5.7 8.19e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.0358657e+01 2.20e-04 8.10e-06 -5.7 1.30e+00 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.0358657e+01 9.03e-08 2.32e-09 -5.7 2.63e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (347964)\n", + " 22 -1.0359304e+01 3.93e-02 7.56e-04 -8.6 9.55e+00 - 9.56e-01 1.00e+00h 1\n", + " 23 -1.0359325e+01 2.75e-03 1.87e-04 -8.6 4.70e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 -1.0359330e+01 1.37e-04 1.18e-05 -8.6 1.06e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.0359330e+01 2.28e-07 3.96e-08 -8.6 4.33e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.0359330e+01 1.70e-12 4.97e-13 -8.6 1.18e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.0359330165707208e+01 -1.0359330165707208e+01\n", + "Dual infeasibility......: 4.9706657073264839e-13 4.9706657073264839e-13\n", + "Constraint violation....: 1.7005286068183523e-12 1.7005286068183523e-12\n", + "Complementarity.........: 2.5059037505427129e-09 2.5059037505427129e-09\n", + "Overall NLP error.......: 2.5059037505427129e-09 2.5059037505427129e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.860\n", + "Total CPU secs in NLP function evaluations = 0.024\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.6 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 3.92e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.51e-02 3.85e+00 -1.0 4.21e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.46e-04 4.39e+00 -1.0 4.82e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.76e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8337334962743626e-11 5.8337334962743626e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8337334962743626e-11 5.8337334962743626e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.125\n", + "Total CPU secs in NLP function evaluations = 0.010\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 2.8196379e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 2.8162115e+00 1.65e-01 1.10e+00 -1.0 5.96e-01 - 9.79e-01 8.68e-01h 1\n", + " 2 2.8171449e+00 3.48e-02 1.08e+01 -1.0 6.03e+00 - 8.34e-01 1.00e+00f 1\n", + " 3 2.7994163e+00 1.25e+01 5.72e+01 -1.0 1.80e+02 - 1.92e-01 7.12e-01f 1\n", + " 4 2.8392046e+00 7.17e-01 2.60e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 2.8292019e+00 5.86e-01 4.54e+01 -1.0 3.71e+02 - 4.48e-01 8.32e-02f 2\n", + " 6 2.8540376e+00 1.35e-01 5.27e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", + " 7 2.8496419e+00 4.28e-01 2.99e-01 -1.0 5.45e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 2.8514802e+00 3.95e-02 5.69e-02 -1.7 1.69e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 2.8509342e+00 4.75e-03 3.32e-03 -2.5 5.95e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.8470769e+00 9.20e-03 3.76e-02 -3.8 4.69e+00 - 9.80e-01 1.00e+00h 1\n", + " 11 2.8179475e+00 8.07e-01 7.45e-02 -3.8 3.88e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 2.8189649e+00 2.78e-02 1.87e-03 -3.8 5.72e+00 - 1.00e+00 1.00e+00h 1\n", + " 13 2.8185808e+00 5.85e-05 6.97e-06 -3.8 3.19e-01 - 1.00e+00 1.00e+00h 1\n", + " 14 2.8060943e+00 4.50e-01 2.80e-02 -5.7 3.87e+01 - 7.60e-01 1.00e+00h 1\n", + " 15 2.8076988e+00 1.27e-03 1.40e-03 -5.7 2.15e-01 -4.5 9.84e-01 1.00e+00h 1\n", + " 16 2.8075717e+00 1.61e-05 2.02e-06 -5.7 1.49e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 17 2.8073034e+00 1.50e-04 2.56e-05 -8.6 4.56e-01 -5.4 9.91e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (332552)\n", + " 18 2.7996057e+00 1.17e+00 3.50e-01 -8.6 1.18e+02 - 2.14e-01 7.03e-01h 1\n", + " 19 2.7992999e+00 1.00e+00 2.99e-01 -8.6 1.21e+02 - 1.40e-01 1.38e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 2.7992903e+00 9.94e-01 2.96e-01 -8.6 3.79e+01 - 7.17e-01 9.13e-03h 1\n", + " 21 2.7990482e+00 6.68e-01 1.97e-01 -8.6 3.87e+01 - 9.68e-01 3.74e-01h 1\n", + " 22 2.7989147e+00 5.66e-01 1.67e-01 -8.6 3.55e+01 - 1.00e+00 1.65e-01f 1\n", + " 23 2.7981330e+00 2.94e-01 8.73e-02 -8.6 3.53e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (356955)\n", + " 24 2.7982525e+00 9.54e-03 2.30e-03 -8.6 6.04e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 25 2.7953817e+00 8.37e-01 2.60e-01 -8.6 8.53e+01 - 7.77e-02 6.80e-01h 1\n", + " 26 2.7970874e+00 5.84e-01 1.64e-01 -8.6 5.21e+01 - 1.00e+00 5.00e-01h 2\n", + " 27 2.7963533e+00 2.95e-02 5.91e-03 -8.6 2.18e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 28 2.7958325e+00 8.11e-03 1.49e-03 -8.6 5.48e+00 -6.9 1.00e+00 1.00e+00h 1\n", + " 29 2.7945535e+00 7.95e-02 1.40e-02 -8.6 1.74e+01 -7.3 6.23e-01 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 2.7944657e+00 7.83e-02 1.38e-02 -8.6 5.44e+01 -7.8 8.23e-01 1.76e-02h 1\n", + " 31 2.7944608e+00 7.71e-02 1.36e-02 -8.6 7.54e+00 - 8.32e-01 1.59e-02h 1\n", + " 32 2.7941818e+00 6.39e-03 2.32e-03 -8.6 7.11e+00 - 1.00e+00 1.00e+00f 1\n", + " 33 2.7942732e+00 7.14e-05 1.97e-05 -8.6 7.45e-01 - 1.00e+00 1.00e+00h 1\n", + " 34 2.7942736e+00 7.61e-09 1.93e-09 -8.6 7.70e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 34\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.7942736259106784e+00 2.7942736259106784e+00\n", + "Dual infeasibility......: 1.9311658899047611e-09 1.9311658899047611e-09\n", + "Constraint violation....: 7.6102699697599974e-09 7.6102699697599974e-09\n", + "Complementarity.........: 2.5060093311148399e-09 2.5060093311148399e-09\n", + "Overall NLP error.......: 7.6102699697599974e-09 7.6102699697599974e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 40\n", + "Number of objective gradient evaluations = 35\n", + "Number of equality constraint evaluations = 40\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 35\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 34\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.244\n", + "Total CPU secs in NLP function evaluations = 0.050\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.41e-03 2.08e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.23e-09 1.50e-06 -1.0 1.78e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.2333721538814189e-09 2.2333721538814189e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.2333721538814189e-09 2.2333721538814189e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.41e-03 2.08e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.23e-09 1.50e-06 -1.0 1.78e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.2333717097922090e-09 2.2333717097922090e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.2333717097922090e-09 2.2333717097922090e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 0.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.06e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.07e+02 3.85e+02 -1.0 3.06e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.00e+00 3.85e+00 -1.0 6.54e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 6.93e-02 4.39e+00 -1.0 7.48e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.40e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0381035988684744e-09 9.0381035988684744e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0381035988684744e-09 9.0381035988684744e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", + "Total CPU secs in NLP function evaluations = 0.007\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.0727169e+01 1.25e+00 1.08e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.0730862e+01 6.19e-01 5.16e+00 -1.0 4.65e+01 - 9.73e-01 5.05e-01h 1\n", + " 2 -1.0728705e+01 1.28e+00 1.95e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.0743551e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.0714096e+01 1.67e+01 2.25e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.0718710e+01 1.18e+01 3.18e+01 -1.0 1.36e+02 - 1.00e+00 4.15e-01f 2\n", + " 6 -1.0707188e+01 1.22e+01 3.32e+00 -1.0 9.16e+01 - 8.86e-01 3.40e-01f 2\n", + " 7 -1.0696529e+01 3.54e+00 5.25e-01 -1.0 5.17e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.0701162e+01 4.28e-01 7.36e-02 -1.0 1.06e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.0701207e+01 2.45e-04 2.30e-03 -1.7 2.53e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.0701573e+01 2.36e-03 2.36e-02 -3.8 1.10e+00 - 9.98e-01 1.00e+00h 1\n", + " 11 -1.0728466e+01 1.41e+01 1.22e-01 -3.8 8.53e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 -1.0724859e+01 5.12e-01 5.81e-03 -3.8 1.89e+01 - 1.00e+00 1.00e+00h 1\n", + " 13 -1.0725400e+01 2.98e-03 1.26e-05 -3.8 1.22e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319443)\n", + " 14 -1.0725400e+01 2.16e-08 1.65e-09 -3.8 6.85e-03 - 1.00e+00 1.00e+00h 1\n", + " 15 -1.0735769e+01 2.29e+00 2.70e-02 -5.7 3.95e+01 - 7.59e-01 1.00e+00f 1\n", + " 16 -1.0741697e+01 2.18e+00 1.82e-02 -5.7 3.17e+01 - 7.93e-01 1.00e+00h 1\n", + " 17 -1.0742738e+01 2.63e+00 1.88e-02 -5.7 3.36e+02 - 3.31e-01 5.69e-02h 2\n", + " 18 -1.0746014e+01 1.33e+00 1.30e-02 -5.7 3.62e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.0746312e+01 1.77e-01 1.01e-03 -5.7 1.56e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (336826)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.0746301e+01 6.01e-04 1.57e-05 -5.7 2.13e+00 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.0746301e+01 5.82e-07 8.09e-09 -5.7 6.66e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 -1.0746946e+01 6.09e-02 7.31e-04 -8.6 1.05e+01 - 9.50e-01 1.00e+00h 1\n", + " 23 -1.0746963e+01 3.80e-03 2.04e-04 -8.6 5.52e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (359506)\n", + " 24 -1.0746969e+01 2.64e-04 1.71e-05 -8.6 1.47e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.0746970e+01 8.56e-07 1.03e-07 -8.6 8.39e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.0746970e+01 1.75e-11 3.92e-12 -8.6 3.79e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.0746969709499885e+01 -1.0746969709499885e+01\n", + "Dual infeasibility......: 3.9211112624388169e-12 3.9211112624388169e-12\n", + "Constraint violation....: 1.7519652395492358e-11 1.7519652395492358e-11\n", + "Complementarity.........: 2.5059051337529310e-09 2.5059051337529310e-09\n", + "Overall NLP error.......: 2.5059051337529310e-09 2.5059051337529310e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 36\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 36\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.940\n", + "Total CPU secs in NLP function evaluations = 0.036\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 3.95e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.55e-02 3.85e+00 -1.0 4.25e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.50e-04 4.39e+00 -1.0 4.85e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.80e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 2.4264349e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 2.4238621e+00 1.63e-01 1.09e+00 -1.0 5.95e-01 - 9.79e-01 8.70e-01h 1\n", + " 2 2.4248028e+00 3.48e-02 1.10e+01 -1.0 6.03e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 2.4105783e+00 1.25e+01 5.73e+01 -1.0 1.80e+02 - 1.92e-01 7.12e-01f 1\n", + " 4 2.4418472e+00 7.15e-01 2.57e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 2.4341825e+00 5.85e-01 4.59e+01 -1.0 3.64e+02 - 4.56e-01 8.47e-02f 2\n", + " 6 2.4537211e+00 1.36e-01 5.47e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", + " 7 2.4503021e+00 4.30e-01 2.96e-01 -1.0 5.46e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 2.4518079e+00 3.92e-02 5.71e-02 -1.7 1.69e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 2.4514688e+00 4.92e-03 3.01e-03 -2.5 6.06e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.4490209e+00 5.79e-03 1.11e-02 -3.8 3.70e+00 - 9.94e-01 1.00e+00h 1\n", + " 11 2.4240878e+00 7.98e-01 6.68e-02 -3.8 3.99e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 2.4284887e+00 8.05e-03 3.01e-03 -3.8 7.54e+00 - 1.00e+00 1.00e+00h 1\n", + " 13 2.4282037e+00 3.91e-05 3.61e-06 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (321514)\n", + " 14 2.4178352e+00 4.81e-01 2.70e-02 -5.7 3.95e+01 - 7.59e-01 1.00e+00h 1\n", + " 15 2.4119071e+00 2.15e-01 1.82e-02 -5.7 3.17e+01 - 7.93e-01 1.00e+00h 1\n", + " 16 2.4108659e+00 2.12e-01 1.88e-02 -5.7 2.81e+02 - 3.31e-01 5.69e-02h 2\n", + " 17 2.4075899e+00 1.15e-01 1.30e-02 -5.7 2.13e+01 - 1.00e+00 1.00e+00h 1\n", + " 18 2.4072917e+00 1.38e-02 1.01e-03 -5.7 1.01e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (337602)\n", + " 19 2.4073026e+00 6.01e-04 1.57e-05 -5.7 2.13e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 2.4073027e+00 5.82e-07 8.09e-09 -5.7 6.66e-02 - 1.00e+00 1.00e+00h 1\n", + " 21 2.4066582e+00 1.43e-02 7.31e-04 -8.6 1.05e+01 - 9.50e-01 1.00e+00h 1\n", + " 22 2.4066404e+00 3.80e-03 2.04e-04 -8.6 5.52e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (360986)\n", + " 23 2.4066344e+00 2.64e-04 1.71e-05 -8.6 1.47e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 2.4066341e+00 8.56e-07 1.03e-07 -8.6 8.39e-02 - 1.00e+00 1.00e+00h 1\n", + " 25 2.4066341e+00 1.75e-11 3.92e-12 -8.6 3.79e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 25\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.4066340821203402e+00 2.4066340821203402e+00\n", + "Dual infeasibility......: 3.9211113364714817e-12 3.9211113364714817e-12\n", + "Constraint violation....: 1.7518986261677583e-11 1.7518986261677583e-11\n", + "Complementarity.........: 2.5059051337162099e-09 2.5059051337162099e-09\n", + "Overall NLP error.......: 2.5059051337162099e-09 2.5059051337162099e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 26\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 26\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 25\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.855\n", + "Total CPU secs in NLP function evaluations = 0.033\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.6 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.39e-03 2.31e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.20e-09 1.49e-06 -1.0 1.76e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1957125007077138e-09 2.1957125007077138e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1957125007077138e-09 2.1957125007077138e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.102\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.39e-03 2.31e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.20e-09 1.49e-06 -1.0 1.76e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1957116125292941e-09 2.1957116125292941e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1957116125292941e-09 2.1957116125292941e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.83e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.15e+02 3.85e+02 -1.0 3.83e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.08e+00 3.85e+00 -1.0 6.62e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.00e-02 4.39e+00 -1.0 7.56e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.48e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0390130935702473e-09 9.0390130935702473e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0390130935702473e-09 9.0390130935702473e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.1047463e+01 1.25e+00 1.08e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.1050486e+01 6.19e-01 5.16e+00 -1.0 4.65e+01 - 9.73e-01 5.05e-01h 1\n", + " 2 -1.1048562e+01 1.28e+00 1.95e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.1060878e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.1036646e+01 1.67e+01 2.24e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.1040342e+01 1.18e+01 3.19e+01 -1.0 1.36e+02 - 1.00e+00 4.15e-01f 2\n", + " 6 -1.1030843e+01 1.22e+01 3.32e+00 -1.0 9.18e+01 - 8.84e-01 3.39e-01f 2\n", + " 7 -1.1021982e+01 3.57e+00 5.28e-01 -1.0 5.19e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.1025828e+01 4.33e-01 7.49e-02 -1.0 1.07e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.1025857e+01 2.38e-04 2.03e-03 -1.7 2.83e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.1026109e+01 1.63e-03 2.25e-03 -3.8 9.21e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.1026632e+01 7.86e-04 4.02e-04 -3.8 1.57e+00 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.1027550e+01 2.46e-03 3.00e-04 -5.7 2.75e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 -1.1028272e+01 2.47e-03 5.48e-04 -5.7 2.72e+00 -5.0 1.00e+00 7.82e-01h 1\n", + " 14 -1.1028813e+01 8.65e-03 7.74e-04 -5.7 1.44e+00 -5.4 1.00e+00 1.00e+00f 1\n", + " 15r-1.1028813e+01 8.65e-03 9.99e+02 -2.1 0.00e+00 - 0.00e+00 3.69e-07R 16\n", + " 16r-1.1028744e+01 1.97e-03 2.91e+02 -2.1 2.14e+02 - 1.00e+00 9.90e-04f 1\n", + " 17 -1.1028797e+01 1.97e-03 7.77e-02 -5.7 7.31e+03 - 6.04e-02 2.22e-05h 2\n", + " 18 -1.1070945e+01 5.57e+01 7.49e-02 -5.7 4.61e+03 - 3.70e-02 3.66e-02h 1\n", + " 19 -1.1077425e+01 5.37e+01 7.00e-02 -5.7 7.35e+02 - 7.21e-02 6.45e-02h 1\n", + "Reallocating memory for MA57: lfact (323295)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.1075942e+01 4.63e+01 6.82e-02 -5.7 2.71e+02 - 1.00e+00 1.71e-01h 1\n", + " 21 -1.1056650e+01 7.71e+00 7.12e-01 -5.7 9.20e+01 - 7.89e-01 1.00e+00h 1\n", + " 22 -1.1061268e+01 4.91e-01 3.85e-02 -5.7 2.95e+01 -5.9 1.00e+00 1.00e+00h 1\n", + " 23 -1.1062198e+01 6.67e-01 2.40e-02 -5.7 3.95e+01 - 1.00e+00 3.17e-01h 2\n", + " 24 -1.1062691e+01 5.52e-01 1.59e-02 -5.7 1.91e+01 - 1.00e+00 3.26e-01h 2\n", + " 25 -1.1063214e+01 1.71e-01 4.96e-03 -5.7 7.52e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.1063041e+01 1.76e-02 8.52e-04 -5.7 4.14e+00 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.1063029e+01 1.30e-04 4.18e-06 -5.7 3.18e-01 - 1.00e+00 1.00e+00h 1\n", + " 28 -1.1063029e+01 3.22e-09 1.10e-10 -5.7 1.63e-03 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (352737)\n", + " 29 -1.1063672e+01 8.69e-02 7.05e-04 -8.6 1.13e+01 - 9.43e-01 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -1.1063687e+01 4.85e-03 2.15e-04 -8.6 6.22e+00 - 1.00e+00 1.00e+00h 1\n", + " 31 -1.1063694e+01 4.30e-04 2.22e-05 -8.6 1.87e+00 - 1.00e+00 1.00e+00h 1\n", + " 32 -1.1063694e+01 2.31e-06 2.07e-07 -8.6 1.38e-01 - 1.00e+00 1.00e+00h 1\n", + " 33 -1.1063694e+01 1.00e-10 1.87e-11 -8.6 9.08e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 33\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.1063694185536061e+01 -1.1063694185536061e+01\n", + "Dual infeasibility......: 1.8708625160522883e-11 1.8708625160522883e-11\n", + "Constraint violation....: 1.0035383635198514e-10 1.0035383635198514e-10\n", + "Complementarity.........: 2.5059110801775927e-09 2.5059110801775927e-09\n", + "Overall NLP error.......: 2.5059110801775927e-09 2.5059110801775927e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 66\n", + "Number of objective gradient evaluations = 34\n", + "Number of equality constraint evaluations = 66\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 35\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 33\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.097\n", + "Total CPU secs in NLP function evaluations = 0.054\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.63e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 3.99e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.58e-02 3.85e+00 -1.0 4.28e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.53e-04 4.39e+00 -1.0 4.88e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.83e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8337334962743626e-11 5.8337334962743626e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8337334962743626e-11 5.8337334962743626e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.135\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 2.1061408e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 2.1040894e+00 1.61e-01 1.07e+00 -1.0 5.95e-01 - 9.79e-01 8.71e-01h 1\n", + " 2 2.1049797e+00 3.48e-02 1.10e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 2.0931025e+00 1.25e+01 5.73e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 2.1188567e+00 7.15e-01 2.55e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 2.1126515e+00 5.85e-01 4.62e+01 -1.0 3.59e+02 - 4.61e-01 8.58e-02f 2\n", + " 6 2.1287303e+00 1.37e-01 5.55e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 2.1259503e+00 4.30e-01 2.96e-01 -1.0 5.46e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 2.1272270e+00 3.91e-02 5.74e-02 -1.7 1.69e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 2.1269980e+00 5.05e-03 3.05e-03 -2.5 6.14e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.1253079e+00 3.93e-03 1.72e-03 -3.8 3.02e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 2.1243236e+00 3.24e-05 7.52e-06 -3.8 8.12e-02 -4.5 1.00e+00 1.00e+00h 1\n", + " 12 2.1000010e+00 1.90e+00 1.12e-01 -5.7 6.66e+01 - 5.63e-01 1.00e+00h 1\n", + " 13 2.0975393e+00 2.59e-01 1.56e-02 -5.7 2.55e+01 - 7.81e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319517)\n", + " 14 2.0918091e+00 4.08e-01 3.59e-02 -5.7 2.58e+01 - 6.49e-01 9.22e-01h 1\n", + " 15 2.0912149e+00 4.07e-01 3.58e-02 -5.7 3.86e+03 - 3.37e-02 2.90e-03h 2\n", + " 16 2.0907195e+00 2.80e-02 2.35e-03 -5.7 1.32e+01 - 1.00e+00 1.00e+00h 1\n", + " 17 2.0905779e+00 7.03e-03 8.20e-04 -5.7 6.05e+00 - 1.00e+00 1.00e+00h 1\n", + " 18 2.0905748e+00 5.81e-05 1.08e-06 -5.7 6.63e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (342692)\n", + " 19 2.0905749e+00 3.67e-09 1.14e-10 -5.7 5.27e-03 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 2.0899322e+00 1.67e-02 7.05e-04 -8.6 1.13e+01 - 9.43e-01 1.00e+00h 1\n", + " 21 2.0899164e+00 4.85e-03 2.15e-04 -8.6 6.22e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (360246)\n", + " 22 2.0899101e+00 4.30e-04 2.22e-05 -8.6 1.87e+00 - 1.00e+00 1.00e+00h 1\n", + " 23 2.0899096e+00 2.31e-06 2.07e-07 -8.6 1.38e-01 - 1.00e+00 1.00e+00h 1\n", + " 24 2.0899096e+00 1.00e-10 1.87e-11 -8.6 9.08e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 24\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.0899096060902953e+00 2.0899096060902953e+00\n", + "Dual infeasibility......: 1.8708625206653092e-11 1.8708625206653092e-11\n", + "Constraint violation....: 1.0035450248579991e-10 1.0035450248579991e-10\n", + "Complementarity.........: 2.5059110801021708e-09 2.5059110801021708e-09\n", + "Overall NLP error.......: 2.5059110801021708e-09 2.5059110801021708e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 31\n", + "Number of objective gradient evaluations = 25\n", + "Number of equality constraint evaluations = 31\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 25\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 24\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.848\n", + "Total CPU secs in NLP function evaluations = 0.031\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.6 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.38e-03 2.54e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.16e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1583757003895698e-09 2.1583757003895698e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1583757003895698e-09 2.1583757003895698e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.2 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.38e-03 2.54e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.16e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1583757003895698e-09 2.1583757003895698e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1583757003895698e-09 2.1583757003895698e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 4.60e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.23e+02 3.85e+02 -1.0 4.60e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.16e+00 3.85e+00 -1.0 6.69e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.08e-02 4.39e+00 -1.0 7.64e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.55e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.122\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.1317732e+01 1.25e+00 1.07e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.1320290e+01 6.18e-01 5.16e+00 -1.0 4.65e+01 - 9.73e-01 5.05e-01h 1\n", + " 2 -1.1318564e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.1329088e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.1308507e+01 1.67e+01 2.23e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.1311584e+01 1.18e+01 3.19e+01 -1.0 1.36e+02 - 1.00e+00 4.14e-01f 2\n", + " 6 -1.1303505e+01 1.23e+01 3.32e+00 -1.0 9.19e+01 - 8.82e-01 3.38e-01f 2\n", + " 7 -1.1295920e+01 3.59e+00 5.30e-01 -1.0 5.20e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.1299210e+01 4.37e-01 7.59e-02 -1.0 1.08e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.1299229e+01 2.36e-04 1.85e-03 -1.7 3.04e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.1299413e+01 1.20e-03 1.91e-03 -3.8 7.92e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.1299812e+01 6.26e-04 3.20e-04 -3.8 1.40e+00 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.1322678e+01 1.98e+01 1.23e-01 -5.7 8.86e+01 - 5.46e-01 1.00e+00h 1\n", + " 13 -1.1325322e+01 1.20e+00 1.52e-02 -5.7 6.84e+01 - 7.61e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (323203)\n", + " 14 -1.1329152e+01 3.27e+00 1.89e-02 -5.7 3.81e+01 - 7.29e-01 1.00e+00h 1\n", + " 15 -1.1329720e+01 3.61e+00 1.87e-02 -5.7 8.73e+02 - 1.61e-01 1.97e-02h 2\n", + " 16 -1.1330564e+01 3.94e-01 2.15e-03 -5.7 2.39e+01 - 1.00e+00 1.00e+00h 1\n", + " 17 -1.1330828e+01 1.37e-01 1.02e-03 -5.7 1.22e+01 - 1.00e+00 1.00e+00h 1\n", + " 18 -1.1330818e+01 1.25e-04 4.23e-06 -5.7 5.25e-01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.1330818e+01 4.23e-09 1.18e-10 -5.7 2.97e-03 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.1330839e+01 4.74e-06 1.48e-06 -8.6 4.43e-02 -4.5 1.00e+00 1.00e+00h 1\n", + " 21 -1.1330851e+01 4.21e-05 2.23e-06 -8.6 1.69e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 22 -1.1330889e+01 3.75e-04 3.31e-06 -8.6 5.08e-01 -5.4 1.00e+00 1.00e+00h 1\n", + " 23 -1.1330999e+01 3.26e-03 2.88e-05 -8.6 1.52e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 24 -1.1331064e+01 3.74e-03 3.29e-05 -8.6 4.44e+00 -6.4 1.00e+00 2.10e-01h 1\n", + " 25 -1.1331228e+01 1.65e-02 2.12e-04 -8.6 4.71e+00 -6.9 1.00e+00 7.65e-01f 1\n", + " 26 -1.1331449e+01 1.71e-02 7.80e-04 -8.6 2.93e+01 - 1.00e+00 3.63e-01f 1\n", + " 27 -1.1331483e+01 1.98e-02 6.89e-04 -8.6 2.97e+01 - 1.00e+00 2.88e-01f 1\n", + " 28 -1.1331484e+01 1.83e-02 6.23e-04 -8.6 1.76e+01 - 1.00e+00 9.54e-02f 1\n", + " 29 -1.1331489e+01 7.02e-03 1.41e-04 -8.6 3.15e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (355308)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -1.1331481e+01 2.07e-06 4.96e-08 -8.6 1.21e-01 - 1.00e+00 1.00e+00h 1\n", + " 31 -1.1331481e+01 4.19e-11 6.10e-14 -8.6 5.87e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 31\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.1331480835989968e+01 -1.1331480835989968e+01\n", + "Dual infeasibility......: 6.1028774360629264e-14 6.1028774360629264e-14\n", + "Constraint violation....: 4.1914582915580922e-11 4.1914582915580922e-11\n", + "Complementarity.........: 2.5059039158044294e-09 2.5059039158044294e-09\n", + "Overall NLP error.......: 2.5059039158044294e-09 2.5059039158044294e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 41\n", + "Number of objective gradient evaluations = 32\n", + "Number of equality constraint evaluations = 41\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 32\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 31\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.143\n", + "Total CPU secs in NLP function evaluations = 0.040\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.97e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.02e+00 3.85e+02 -1.0 1.92e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.61e-02 3.85e+00 -1.0 4.31e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.56e-04 4.39e+00 -1.0 4.91e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.86e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8332005892225425e-11 5.8332005892225425e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8332005892225425e-11 5.8332005892225425e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 1.8358716e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 1.8341696e+00 1.60e-01 1.07e+00 -1.0 5.95e-01 - 9.79e-01 8.72e-01h 1\n", + " 2 1.8349973e+00 3.48e-02 1.11e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 1.8248024e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 1.8466954e+00 7.14e-01 2.53e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 1.8414860e+00 5.85e-01 4.65e+01 -1.0 3.56e+02 - 4.65e-01 8.65e-02f 2\n", + " 6 1.8551941e+00 1.36e-01 5.72e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", + " 7 1.8528188e+00 4.32e-01 2.96e-01 -1.0 5.47e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 1.8539217e+00 3.88e-02 5.74e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 1.8537565e+00 5.12e-03 3.24e-03 -2.5 6.19e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 1.8525196e+00 2.82e-03 1.42e-03 -3.8 2.54e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 1.8366692e+00 5.04e-01 3.65e-02 -3.8 3.44e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 1.8399503e+00 1.30e-02 1.92e-03 -3.8 6.01e+00 - 1.00e+00 1.00e+00h 1\n", + " 13 1.8398900e+00 1.11e-05 6.33e-07 -3.8 2.77e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (320183)\n", + " 14 1.8323517e+00 4.84e-01 2.54e-02 -5.7 3.88e+01 - 7.65e-01 1.00e+00h 1\n", + " 15 1.8270480e+00 3.24e-01 1.26e-02 -5.7 3.83e+01 - 8.75e-01 1.00e+00h 1\n", + " 16 1.8263301e+00 3.14e-01 1.52e-02 -5.7 5.98e+02 - 1.79e-01 2.87e-02h 2\n", + " 17 1.8227920e+00 2.59e-01 1.45e-02 -5.7 2.36e+01 - 1.00e+00 1.00e+00h 1\n", + " 18 1.8227886e+00 1.83e-02 5.07e-04 -5.7 1.16e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (338938)\n", + " 19 1.8227858e+00 8.79e-04 1.36e-05 -5.7 2.56e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 1.8227857e+00 9.53e-07 6.96e-09 -5.7 8.47e-02 - 1.00e+00 1.00e+00h 1\n", + " 21 1.8221441e+00 1.90e-02 6.81e-04 -8.6 1.20e+01 - 9.37e-01 1.00e+00h 1\n", + " 22 1.8221300e+00 5.89e-03 2.23e-04 -8.6 6.84e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (356229)\n", + " 23 1.8221235e+00 6.31e-04 2.70e-05 -8.6 2.27e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 1.8221230e+00 5.04e-06 3.54e-07 -8.6 2.03e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 1.8221230e+00 3.93e-10 6.30e-11 -8.6 1.80e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 25\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.8221229556418135e+00 1.8221229556418135e+00\n", + "Dual infeasibility......: 6.2966011365859705e-11 6.2966011365859705e-11\n", + "Constraint violation....: 3.9269965057542322e-10 3.9269965057542322e-10\n", + "Complementarity.........: 2.5059288062561410e-09 2.5059288062561410e-09\n", + "Overall NLP error.......: 2.5059288062561410e-09 2.5059288062561410e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 26\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 26\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 25\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.855\n", + "Total CPU secs in NLP function evaluations = 0.037\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.37e-03 2.77e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.12e-09 1.47e-06 -1.0 1.73e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1213626411054065e-09 2.1213626411054065e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1213626411054065e-09 2.1213626411054065e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", + "Total CPU secs in NLP function evaluations = 0.001\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.37e-03 2.77e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.12e-09 1.47e-06 -1.0 1.73e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1213617529269868e-09 2.1213617529269868e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1213617529269868e-09 2.1213617529269868e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.007\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 0.9 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.36e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.30e+02 3.85e+02 -1.0 5.36e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.23e+00 3.85e+00 -1.0 6.77e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.15e-02 4.39e+00 -1.0 7.71e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.63e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.1551525e+01 1.25e+00 1.07e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.1553742e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.1552181e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.1561368e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.1543482e+01 1.67e+01 2.22e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.1546117e+01 1.18e+01 3.19e+01 -1.0 1.36e+02 - 1.00e+00 4.14e-01f 2\n", + " 6 -1.1539087e+01 1.23e+01 3.32e+00 -1.0 9.20e+01 - 8.80e-01 3.37e-01f 2\n", + " 7 -1.1532457e+01 3.60e+00 5.31e-01 -1.0 5.21e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.1535331e+01 4.40e-01 7.66e-02 -1.0 1.08e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.1535344e+01 2.36e-04 1.71e-03 -1.7 3.20e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.1535485e+01 9.17e-04 1.68e-03 -3.8 6.95e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.1550192e+01 1.09e+01 5.80e-02 -3.8 6.98e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 -1.1547006e+01 6.44e-01 3.84e-03 -3.8 1.74e+01 - 1.00e+00 1.00e+00h 1\n", + " 13 -1.1547077e+01 6.58e-05 2.09e-06 -3.8 5.97e-01 - 1.00e+00 1.00e+00h 1\n", + " 14 -1.1553620e+01 2.12e+00 2.46e-02 -5.7 3.77e+01 - 7.69e-01 1.00e+00h 1\n", + " 15 -1.1558721e+01 2.04e+00 1.06e-02 -5.7 4.14e+01 - 9.03e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (322351)\n", + " 16 -1.1559371e+01 2.71e+00 1.30e-02 -5.7 6.60e+02 - 1.85e-01 3.02e-02h 2\n", + " 17 -1.1562122e+01 1.66e+00 1.35e-02 -5.7 6.81e+01 - 1.00e+00 7.45e-01H 1\n", + " 18 -1.1562895e+01 1.70e-01 1.76e-03 -5.7 1.75e+01 - 1.00e+00 1.00e+00f 1\n", + " 19 -1.1562787e+01 1.94e-03 2.65e-05 -5.7 3.56e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.1562787e+01 3.18e-06 1.64e-08 -5.7 1.32e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.1563428e+01 1.52e-01 7.00e-04 -8.6 1.27e+01 - 9.31e-01 9.99e-01h 1\n", + "Reallocating memory for MA57: lfact (365434)\n", + " 22 -1.1563441e+01 6.92e-03 2.29e-04 -8.6 7.40e+00 - 1.00e+00 1.00e+00h 1\n", + " 23 -1.1563447e+01 8.62e-04 3.14e-05 -8.6 2.65e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 -1.1563448e+01 9.50e-06 5.44e-07 -8.6 2.79e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.1563448e+01 1.19e-09 1.68e-10 -8.6 3.13e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 25\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.1563448115914573e+01 -1.1563448115914573e+01\n", + "Dual infeasibility......: 1.6756190666721757e-10 1.6756190666721757e-10\n", + "Constraint violation....: 1.1895755491764248e-09 1.1895755491764248e-09\n", + "Complementarity.........: 2.5059705354210223e-09 2.5059705354210223e-09\n", + "Overall NLP error.......: 2.5059705354210223e-09 2.5059705354210223e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 36\n", + "Number of objective gradient evaluations = 26\n", + "Number of equality constraint evaluations = 36\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 26\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 25\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.877\n", + "Total CPU secs in NLP function evaluations = 0.040\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.31e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.05e+00 3.85e+02 -1.0 2.26e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.64e-02 3.85e+00 -1.0 4.34e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.59e-04 4.39e+00 -1.0 4.95e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.89e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8339111319583026e-11 5.8339111319583026e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8339111319583026e-11 5.8339111319583026e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 1.6020788e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 1.6006263e+00 1.59e-01 1.06e+00 -1.0 5.95e-01 - 9.79e-01 8.73e-01h 1\n", + " 2 1.6013928e+00 3.48e-02 1.11e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 1.5924626e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 1.6115012e+00 7.14e-01 2.52e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 1.6070137e+00 5.85e-01 4.67e+01 -1.0 3.54e+02 - 4.67e-01 8.70e-02f 2\n", + " 6 1.6189485e+00 1.36e-01 5.81e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", + " 7 1.6168842e+00 4.32e-01 2.97e-01 -1.0 5.47e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 1.6178560e+00 3.87e-02 5.74e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 1.6177317e+00 5.19e-03 3.40e-03 -2.5 6.23e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 1.6167878e+00 2.10e-03 1.20e-03 -3.8 2.17e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 1.6042274e+00 4.07e-01 2.56e-02 -3.8 3.07e+01 - 1.00e+00 1.00e+00h 1\n", + " 12 1.6065666e+00 8.43e-03 1.13e-03 -3.8 4.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 13 1.6065263e+00 4.74e-06 3.38e-07 -3.8 1.65e-01 - 1.00e+00 1.00e+00h 1\n", + " 14 1.6002214e+00 9.01e-01 7.69e-02 -5.7 9.37e+03 - 1.90e-02 7.73e-03f 1\n", + "Reallocating memory for MA57: lfact (349533)\n", + " 15 1.5979843e+00 1.46e-01 1.53e-02 -5.7 3.06e+01 - 8.53e-01 1.00e+00h 1\n", + " 16 1.5934679e+00 3.30e-01 2.00e-02 -5.7 4.37e+01 - 8.47e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (378883)\n", + " 17 1.5941729e+00 2.50e-03 1.57e-04 -5.7 3.14e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 18 1.5941556e+00 1.90e-06 8.52e-07 -5.7 7.65e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 19 1.5941055e+00 2.45e-05 6.85e-06 -8.6 1.93e-01 -5.4 9.98e-01 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 1.5940068e+00 2.13e-04 1.22e-05 -8.6 5.73e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 21 1.5937364e+00 1.77e-03 1.01e-04 -8.6 1.67e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 22 1.5931017e+00 1.24e-02 7.08e-04 -8.6 4.73e+00 -6.9 1.00e+00 9.59e-01h 1\n", + " 23 1.5922166e+00 4.10e-02 2.42e-03 -8.6 1.30e+01 -7.3 1.00e+00 6.17e-01f 1\n", + " 24 1.5911477e+00 1.11e-01 1.25e-02 -8.6 1.93e+01 -7.8 1.00e+00 1.00e+00f 1\n", + " 25 1.5905350e+00 3.48e-02 2.72e-03 -8.6 9.72e+00 -7.4 1.00e+00 1.00e+00h 1\n", + " 26 1.5903800e+00 3.48e-02 2.76e-03 -8.6 4.21e+01 -7.9 1.00e+00 7.61e-02h 1\n", + " 27 1.5901978e+00 7.47e-02 1.56e-03 -8.6 5.28e+01 - 1.00e+00 4.36e-01f 1\n", + " 28 1.5901521e+00 1.15e-01 6.10e-04 -8.6 4.20e+01 - 1.00e+00 6.10e-01f 1\n", + " 29 1.5901546e+00 9.61e-03 5.06e-05 -8.6 8.82e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (415680)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 1.5901559e+00 6.03e-03 5.58e-06 -8.6 6.93e+00 - 1.00e+00 1.00e+00h 1\n", + " 31 1.5901557e+00 3.61e-04 2.83e-07 -8.6 1.72e+00 - 1.00e+00 1.00e+00h 1\n", + " 32 1.5901557e+00 1.01e-06 7.50e-10 -8.6 9.08e-02 - 1.00e+00 1.00e+00h 1\n", + " 33 1.5901557e+00 6.89e-12 4.35e-14 -8.6 2.38e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 33\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.5901556757175646e+00 1.5901556757175646e+00\n", + "Dual infeasibility......: 4.3539707029773698e-14 4.3539707029773698e-14\n", + "Constraint violation....: 6.8930416929902094e-12 6.8930416929902094e-12\n", + "Complementarity.........: 2.5059036071950574e-09 2.5059036071950574e-09\n", + "Overall NLP error.......: 2.5059036071950574e-09 2.5059036071950574e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 38\n", + "Number of objective gradient evaluations = 34\n", + "Number of equality constraint evaluations = 38\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 34\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 33\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.558\n", + "Total CPU secs in NLP function evaluations = 0.050\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.2 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.36e-03 3.00e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.08e-09 1.46e-06 -1.0 1.72e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.0846711024091746e-09 2.0846711024091746e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.0846711024091746e-09 2.0846711024091746e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.36e-03 3.00e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.08e-09 1.46e-06 -1.0 1.72e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.0846711024091746e-09 2.0846711024091746e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.0846711024091746e-09 2.0846711024091746e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.115\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.13e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.38e+02 3.85e+02 -1.0 6.13e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.31e+00 3.85e+00 -1.0 6.85e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.23e-02 4.39e+00 -1.0 7.79e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.70e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.1757533e+01 1.25e+00 1.06e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.1759489e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.1758067e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.1766218e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.1750403e+01 1.67e+01 2.21e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.1752706e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", + " 6 -1.1746485e+01 1.23e+01 3.32e+00 -1.0 9.21e+01 - 8.79e-01 3.37e-01f 2\n", + " 7 -1.1740596e+01 3.61e+00 5.32e-01 -1.0 5.22e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.1743147e+01 4.42e-01 7.72e-02 -1.0 1.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.1743157e+01 2.36e-04 1.60e-03 -1.7 3.33e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.1743267e+01 7.25e-04 1.49e-03 -3.8 6.20e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.1755095e+01 8.91e+00 4.24e-02 -5.7 6.38e+01 - 6.52e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (321581)\n", + " 12 -1.1761884e+01 2.85e+00 1.21e-02 -5.7 5.80e+01 - 8.37e-01 1.00e+00h 1\n", + " 13 -1.1766537e+01 6.45e+00 3.35e-02 -5.7 4.38e+01 - 7.40e-01 1.00e+00h 1\n", + " 14 -1.1766408e+01 5.42e+00 4.34e-02 -5.7 1.45e+01 -4.0 9.76e-01 1.60e-01h 1\n", + " 15 -1.1766359e+01 4.32e-01 3.46e-02 -5.7 2.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 -1.1766255e+01 4.65e-04 1.06e-04 -5.7 2.81e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 17 -1.1766639e+01 3.37e-01 3.56e-03 -5.7 2.92e+02 - 4.58e-01 5.22e-02h 2\n", + " 18 -1.1767572e+01 9.44e-02 2.21e-03 -5.7 1.59e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.1767397e+01 5.01e-03 9.03e-05 -5.7 3.57e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.1767399e+01 1.54e-05 1.56e-06 -5.7 2.76e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.1768035e+01 1.89e-01 7.56e-04 -8.6 1.38e+01 - 9.26e-01 9.95e-01h 1\n", + "Reallocating memory for MA57: lfact (343029)\n", + " 22 -1.1768050e+01 8.01e-03 2.35e-04 -8.6 7.95e+00 - 1.00e+00 1.00e+00h 1\n", + " 23 -1.1768057e+01 1.12e-03 3.57e-05 -8.6 3.02e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (360465)\n", + " 24 -1.1768058e+01 1.63e-05 7.80e-07 -8.6 3.65e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.1768058e+01 3.05e-09 3.84e-10 -8.6 5.01e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 25\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.1768057697799625e+01 -1.1768057697799625e+01\n", + "Dual infeasibility......: 3.8359587305625804e-10 3.8359587305625804e-10\n", + "Constraint violation....: 3.0509063053685281e-09 3.0509063053685281e-09\n", + "Complementarity.........: 2.5060563776015687e-09 2.5060563776015687e-09\n", + "Overall NLP error.......: 3.0509063053685281e-09 3.0509063053685281e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 35\n", + "Number of objective gradient evaluations = 26\n", + "Number of equality constraint evaluations = 35\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 26\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 25\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.901\n", + "Total CPU secs in NLP function evaluations = 0.037\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.65e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.08e+00 3.85e+02 -1.0 2.60e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.67e-02 3.85e+00 -1.0 4.37e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.62e-04 4.39e+00 -1.0 4.98e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.92e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.133\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 1.3960708e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 1.3948050e+00 1.58e-01 1.05e+00 -1.0 5.95e-01 - 9.79e-01 8.73e-01h 1\n", + " 2 1.3955154e+00 3.48e-02 1.12e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 1.3875708e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 1.4044133e+00 7.13e-01 2.51e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 1.4004729e+00 5.85e-01 4.68e+01 -1.0 3.52e+02 - 4.69e-01 8.75e-02f 2\n", + " 6 1.4110288e+00 1.36e-01 5.85e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", + " 7 1.4092120e+00 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 1.4100813e+00 3.86e-02 5.75e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 1.4099850e+00 5.24e-03 3.52e-03 -2.5 6.26e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 1.4092414e+00 1.61e-03 1.03e-03 -3.8 1.89e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 1.4087035e+00 1.89e-05 1.98e-06 -3.8 5.64e-02 -4.5 1.00e+00 1.00e+00h 1\n", + " 12 1.3969745e+00 9.17e-01 3.82e-02 -5.7 4.48e+01 - 6.43e-01 1.00e+00h 1\n", + " 13 1.3917215e+00 4.19e-01 9.20e-03 -5.7 3.84e+01 - 8.02e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (324236)\n", + " 14 1.3869756e+00 5.56e-01 3.16e-02 -5.7 2.67e+01 - 7.65e-01 1.00e+00h 1\n", + " 15 1.3879570e+00 9.86e-03 5.26e-04 -5.7 5.35e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 1.3879136e+00 3.18e-06 4.27e-07 -5.7 6.95e-02 -5.4 1.00e+00 1.00e+00h 1\n", + " 17 1.3878380e+00 9.80e-05 2.86e-05 -8.6 3.89e-01 -5.9 9.93e-01 1.00e+00h 1\n", + " 18 1.3876686e+00 9.18e-04 5.19e-05 -8.6 1.23e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 19 1.3875598e+00 9.24e-04 5.14e-05 -8.6 1.98e+00 -6.9 1.00e+00 3.25e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 1.3870548e+00 1.12e-02 6.48e-04 -8.6 4.76e+00 -7.3 1.00e+00 1.00e+00f 1\n", + " 21 1.3861210e+00 1.22e-01 1.05e-02 -8.6 2.04e+01 -7.8 1.00e+00 1.00e+00h 1\n", + " 22 1.3856832e+00 2.64e-02 2.12e-03 -8.6 9.07e+00 -7.4 1.00e+00 9.62e-01h 1\n", + " 23 1.3856413e+00 2.12e-02 1.73e-03 -8.6 3.86e+01 - 1.00e+00 2.02e-01f 1\n", + "Reallocating memory for MA57: lfact (344436)\n", + " 24 1.3856015e+00 1.68e-02 1.37e-03 -8.6 4.03e+01 - 1.00e+00 2.09e-01f 1\n", + " 25 1.3855581e+00 5.06e-02 6.97e-04 -8.6 3.68e+01 - 1.00e+00 4.94e-01f 1\n", + " 26 1.3855412e+00 1.19e-03 6.42e-05 -8.6 3.12e+00 - 1.00e+00 1.00e+00h 1\n", + " 27 1.3855461e+00 9.23e-04 7.59e-07 -8.6 2.74e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (362997)\n", + " 28 1.3855461e+00 9.77e-06 6.77e-09 -8.6 2.83e-01 - 1.00e+00 1.00e+00h 1\n", + " 29 1.3855461e+00 7.29e-10 5.06e-13 -8.6 2.45e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.3855460938286592e+00 1.3855460938286592e+00\n", + "Dual infeasibility......: 5.0636527904345562e-13 5.0636527904345562e-13\n", + "Constraint violation....: 7.2855699251306305e-10 7.2855699251306305e-10\n", + "Complementarity.........: 2.5059081084119374e-09 2.5059081084119374e-09\n", + "Overall NLP error.......: 2.5059081084119374e-09 2.5059081084119374e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 30\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 30\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.307\n", + "Total CPU secs in NLP function evaluations = 0.036\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.35e-03 3.23e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.05e-09 1.46e-06 -1.0 1.70e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.0483019724792939e-09 2.0483019724792939e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.0483019724792939e-09 2.0483019724792939e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.35e-03 3.23e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.05e-09 1.46e-06 -1.0 1.70e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.0483028606577136e-09 2.0483028606577136e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.0483028606577136e-09 2.0483028606577136e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.89e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.46e+02 3.85e+02 -1.0 6.89e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.39e+00 3.85e+00 -1.0 6.92e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.30e-02 4.39e+00 -1.0 7.87e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.78e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0394678409211338e-09 9.0394678409211338e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0394678409211338e-09 9.0394678409211338e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.126\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.1941668e+01 1.25e+00 1.06e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.1943417e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.1942113e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.1949438e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.1935265e+01 1.67e+01 2.21e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.1937309e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", + " 6 -1.1931730e+01 1.23e+01 3.32e+00 -1.0 9.21e+01 - 8.78e-01 3.37e-01f 2\n", + " 7 -1.1926433e+01 3.62e+00 5.33e-01 -1.0 5.22e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.1928727e+01 4.44e-01 7.77e-02 -1.0 1.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.1928733e+01 2.37e-04 1.51e-03 -1.7 3.43e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.1928823e+01 5.88e-04 1.35e-03 -3.8 5.59e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.1929034e+01 3.59e-04 1.83e-04 -5.7 1.06e+00 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.1929754e+01 4.19e-03 1.21e-04 -5.7 3.63e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 -1.1930039e+01 3.14e-03 1.97e-03 -5.7 3.45e+00 -5.0 1.00e+00 4.14e-01h 1\n", + " 14 -1.1930215e+01 3.02e-03 9.79e-04 -5.7 8.14e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 15 -1.1930791e+01 2.61e-02 4.88e-05 -5.7 2.66e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 16 -1.1939335e+01 1.10e+01 4.69e-02 -5.7 8.17e+03 - 1.91e-02 9.26e-03h 1\n", + " 17 -1.1943119e+01 1.42e+01 5.92e-02 -5.7 4.18e+02 - 4.56e-01 7.84e-02h 1\n", + " 18 -1.1956668e+01 1.38e+01 5.53e-02 -5.7 1.09e+02 - 1.00e+00 8.15e-01h 1\n", + " 19 -1.1949881e+01 3.43e+00 1.16e-02 -5.7 5.57e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (321695)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.1950414e+01 8.23e-03 6.43e-04 -5.7 6.89e+00 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.1950429e+01 3.89e-04 2.65e-05 -5.7 1.74e+00 - 1.00e+00 1.00e+00h 1\n", + " 22 -1.1950430e+01 6.41e-07 3.85e-08 -5.7 7.08e-02 - 1.00e+00 1.00e+00h 1\n", + " 23 -1.1951063e+01 2.31e-01 8.26e-04 -8.6 1.51e+01 - 9.21e-01 9.90e-01h 1\n", + "Reallocating memory for MA57: lfact (348619)\n", + " 24 -1.1951080e+01 9.09e-03 2.41e-04 -8.6 8.45e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.1951086e+01 1.41e-03 3.96e-05 -8.6 3.38e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.1951087e+01 2.57e-05 1.05e-06 -8.6 4.59e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (367172)\n", + " 27 -1.1951087e+01 7.10e-09 7.68e-10 -8.6 7.64e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.1951087152217010e+01 -1.1951087152217010e+01\n", + "Dual infeasibility......: 7.6785714050494160e-10 7.6785714050494160e-10\n", + "Constraint violation....: 7.1010632929358053e-09 7.1010632929358053e-09\n", + "Complementarity.........: 2.5062084307979245e-09 2.5062084307979245e-09\n", + "Overall NLP error.......: 7.1010632929358053e-09 7.1010632929358053e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 28\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 28\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.951\n", + "Total CPU secs in NLP function evaluations = 0.031\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 2.99e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.11e+00 3.85e+02 -1.0 2.94e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.71e-02 3.85e+00 -1.0 4.41e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.65e-04 4.39e+00 -1.0 5.01e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.95e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.135\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 1.2119360e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 1.2108149e+00 1.58e-01 1.05e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", + " 2 1.2114751e+00 3.48e-02 1.12e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 1.2043202e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 1.2194210e+00 7.13e-01 2.50e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 1.2159091e+00 5.85e-01 4.69e+01 -1.0 3.51e+02 - 4.71e-01 8.78e-02f 2\n", + " 6 1.2253787e+00 1.36e-01 5.90e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", + " 7 1.2237509e+00 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 1.2245368e+00 3.86e-02 5.75e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 1.2244603e+00 5.28e-03 3.61e-03 -2.5 6.28e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 1.2238595e+00 1.27e-03 8.99e-04 -3.8 1.66e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 1.2147814e+00 6.50e-01 3.09e-02 -5.7 3.86e+01 - 6.91e-01 1.00e+00h 1\n", + " 12 1.2082820e+00 6.40e-01 9.84e-03 -5.7 4.61e+01 - 8.50e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319971)\n", + " 13 1.2037280e+00 6.91e-01 3.73e-02 -5.7 2.97e+01 - 7.52e-01 9.98e-01h 1\n", + " 14 1.2048711e+00 1.91e-02 1.61e-03 -5.7 3.27e+00 -4.5 9.31e-01 1.00e+00h 1\n", + " 15 1.2048031e+00 2.24e-06 5.66e-07 -5.7 2.40e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 1.2047671e+00 1.36e-05 6.26e-06 -8.6 1.52e-01 -5.4 9.99e-01 1.00e+00h 1\n", + " 17 1.2047082e+00 1.26e-04 6.76e-06 -8.6 4.70e-01 -5.9 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (336051)\n", + " 18 1.2045445e+00 1.05e-03 5.65e-05 -8.6 1.37e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 19 1.2044052e+00 1.58e-03 8.51e-05 -8.6 3.73e+00 -6.9 1.00e+00 3.42e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 1.2039397e+00 9.51e-03 5.22e-04 -8.6 4.63e+00 -7.3 1.00e+00 1.00e+00f 1\n", + " 21 1.2031551e+00 8.32e-02 6.07e-03 -8.6 1.92e+01 -7.8 1.00e+00 8.71e-01h 1\n", + " 22 1.2028414e+00 1.08e-01 7.48e-03 -8.6 1.19e+03 -8.3 7.23e-02 8.23e-03h 1\n", + " 23 1.2025270e+00 5.89e-02 4.04e-03 -8.6 3.92e+01 - 1.00e+00 4.53e-01f 1\n", + " 24 1.2025096e+00 4.44e-02 3.04e-03 -8.6 3.68e+01 - 5.41e-01 2.48e-01f 1\n", + " 25 1.2025058e+00 4.33e-02 2.05e-03 -8.6 3.17e+01 - 1.00e+00 3.26e-01f 1\n", + " 26 1.2025106e+00 1.21e-03 1.32e-04 -8.6 2.37e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (356718)\n", + " 27 1.2025167e+00 5.23e-04 3.85e-07 -8.6 2.06e+00 - 1.00e+00 1.00e+00h 1\n", + " 28 1.2025166e+00 3.31e-06 2.06e-09 -8.6 1.65e-01 - 1.00e+00 1.00e+00h 1\n", + " 29 1.2025166e+00 8.35e-11 7.43e-14 -8.6 8.28e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.2025166394012419e+00 1.2025166394012419e+00\n", + "Dual infeasibility......: 7.4296667615744834e-14 7.4296667615744834e-14\n", + "Constraint violation....: 8.3521300986433289e-11 8.3521300986433289e-11\n", + "Complementarity.........: 2.5059040285569865e-09 2.5059040285569865e-09\n", + "Overall NLP error.......: 2.5059040285569865e-09 2.5059040285569865e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 30\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 30\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.243\n", + "Total CPU secs in NLP function evaluations = 0.037\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.33e-03 3.46e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.01e-09 1.45e-06 -1.0 1.69e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.0122556954049742e-09 2.0122556954049742e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.0122556954049742e-09 2.0122556954049742e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.2 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.33e-03 3.46e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.01e-09 1.45e-06 -1.0 1.69e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.0122561394941840e-09 2.0122561394941840e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.0122561394941840e-09 2.0122561394941840e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 0.9 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 7.66e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.53e+02 3.85e+02 -1.0 7.66e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.46e+00 3.85e+00 -1.0 7.00e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.38e-02 4.39e+00 -1.0 7.94e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.85e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2108134e+01 1.25e+00 1.06e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2109716e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2108512e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2115163e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2102323e+01 1.67e+01 2.21e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2104160e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", + " 6 -1.2099103e+01 1.23e+01 3.32e+00 -1.0 9.22e+01 - 8.77e-01 3.36e-01f 2\n", + " 7 -1.2094289e+01 3.63e+00 5.34e-01 -1.0 5.23e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2096373e+01 4.45e-01 7.81e-02 -1.0 1.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2096378e+01 2.38e-04 1.44e-03 -1.7 3.51e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2096452e+01 4.87e-04 1.23e-03 -3.8 5.09e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2104600e+01 6.30e+00 3.11e-02 -5.7 5.44e+01 - 6.88e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319533)\n", + " 12 -1.2111071e+01 3.68e+00 1.30e-02 -5.7 6.59e+01 - 8.37e-01 1.00e+00h 1\n", + " 13 -1.2115222e+01 6.14e+00 2.84e-02 -5.7 3.51e+01 - 8.03e-01 1.00e+00h 1\n", + " 14 -1.2115127e+01 5.38e+00 4.94e-02 -5.7 1.50e+01 -4.0 1.00e+00 1.24e-01h 1\n", + " 15 -1.2114999e+01 4.47e-01 2.64e-02 -5.7 2.58e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 -1.2114900e+01 4.96e-04 8.86e-05 -5.7 3.02e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 17 -1.2115229e+01 5.02e-01 4.88e-03 -5.7 6.65e+02 - 1.86e-01 2.67e-02h 2\n", + " 18 -1.2116201e+01 2.32e-01 2.86e-03 -5.7 1.63e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.2115996e+01 6.36e-03 8.56e-05 -5.7 2.06e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (337748)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2116001e+01 1.11e-05 1.53e-06 -5.7 2.94e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.2116631e+01 2.76e-01 8.95e-04 -8.6 1.65e+01 - 9.16e-01 9.85e-01h 1\n", + " 22 -1.2116650e+01 1.02e-02 2.45e-04 -8.6 8.93e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (355121)\n", + " 23 -1.2116656e+01 1.72e-03 4.32e-05 -8.6 3.73e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 -1.2116657e+01 3.81e-05 1.36e-06 -8.6 5.59e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.2116657e+01 1.56e-08 1.40e-09 -8.6 1.13e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (375561)\n", + " 26 -1.2116658e+01 6.53e-07 1.86e-08 -9.0 7.32e-02 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.2116658e+01 1.00e-11 4.32e-13 -9.0 2.87e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2116658032211422e+01 -1.2116658032211422e+01\n", + "Dual infeasibility......: 4.3248756227463823e-13 4.3248756227463823e-13\n", + "Constraint violation....: 9.9974473144470721e-12 9.9974473144470721e-12\n", + "Complementarity.........: 9.0909106880328588e-10 9.0909106880328588e-10\n", + "Overall NLP error.......: 9.0909106880328588e-10 9.0909106880328588e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 37\n", + "Number of objective gradient evaluations = 28\n", + "Number of equality constraint evaluations = 37\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 28\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.055\n", + "Total CPU secs in NLP function evaluations = 0.036\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.33e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.15e+00 3.85e+02 -1.0 3.28e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.74e-02 3.85e+00 -1.0 4.44e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.69e-04 4.39e+00 -1.0 5.04e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.98e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8339111319583026e-11 5.8339111319583026e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8339111319583026e-11 5.8339111319583026e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 1.0454702e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 1.0444646e+00 1.58e-01 1.05e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", + " 2 1.0450802e+00 3.48e-02 1.12e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 1.0385721e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 1.0522576e+00 7.13e-01 2.50e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 1.0490906e+00 5.85e-01 4.70e+01 -1.0 3.50e+02 - 4.73e-01 8.81e-02f 2\n", + " 6 1.0576821e+00 1.36e-01 5.97e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", + " 7 1.0562026e+00 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 1.0569195e+00 3.85e-02 5.75e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 1.0568573e+00 5.31e-03 3.69e-03 -2.5 6.30e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 1.0563619e+00 1.01e-03 7.93e-04 -3.8 1.47e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 1.0487134e+00 5.52e-01 2.96e-02 -5.7 3.53e+01 - 7.06e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319271)\n", + " 12 1.0424427e+00 7.03e-01 1.05e-02 -5.7 4.80e+01 - 8.51e-01 1.00e+00h 1\n", + " 13 1.0381157e+00 7.10e-01 3.48e-02 -5.7 3.01e+01 - 7.81e-01 1.00e+00h 1\n", + " 14 1.0390532e+00 1.28e-02 1.27e-03 -5.7 6.87e-01 -4.5 9.40e-01 1.00e+00h 1\n", + " 15 1.0390112e+00 4.50e-06 9.50e-07 -5.7 8.32e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 1.0389810e+00 7.21e-06 4.11e-06 -8.6 1.03e-01 -5.4 9.99e-01 1.00e+00h 1\n", + " 17 1.0389364e+00 8.39e-05 3.92e-06 -8.6 3.70e-01 -5.9 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (335399)\n", + " 18 1.0388452e+00 3.85e-04 1.79e-05 -8.6 1.04e+00 -6.4 1.00e+00 7.44e-01h 1\n", + " 19 1.0386655e+00 1.98e-03 6.30e-05 -8.6 1.81e+00 -6.9 1.00e+00 1.00e+00f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 1.0382979e+00 7.70e-03 3.44e-04 -8.6 3.97e+00 -7.3 1.00e+00 1.00e+00h 1\n", + " 21 1.0375873e+00 7.24e-02 5.06e-03 -8.6 1.56e+01 -7.8 1.00e+00 1.00e+00h 1\n", + " 22 1.0372258e+00 1.16e-01 7.43e-03 -8.6 5.45e+02 -8.3 1.62e-01 2.38e-02h 1\n", + " 23 1.0369759e+00 6.56e-02 4.17e-03 -8.6 3.95e+01 - 1.00e+00 4.33e-01f 1\n", + " 24 1.0369555e+00 5.05e-02 3.21e-03 -8.6 3.72e+01 - 1.00e+00 2.30e-01f 1\n", + " 25 1.0369460e+00 4.41e-02 2.04e-03 -8.6 3.24e+01 - 1.00e+00 3.64e-01f 1\n", + " 26 1.0369409e+00 1.26e-03 1.02e-04 -8.6 2.22e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (358185)\n", + " 27 1.0369464e+00 3.96e-04 2.65e-07 -8.6 1.80e+00 - 1.00e+00 1.00e+00h 1\n", + " 28 1.0369464e+00 1.87e-06 1.06e-09 -8.6 1.24e-01 - 1.00e+00 1.00e+00h 1\n", + " 29 1.0369464e+00 2.65e-11 3.91e-14 -8.6 4.66e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.0369464064985126e+00 1.0369464064985126e+00\n", + "Dual infeasibility......: 3.9074655964464579e-14 3.9074655964464579e-14\n", + "Constraint violation....: 2.6508573114369938e-11 2.6508573114369938e-11\n", + "Complementarity.........: 2.5059036949607426e-09 2.5059036949607426e-09\n", + "Overall NLP error.......: 2.5059036949607426e-09 2.5059036949607426e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 30\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 30\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.435\n", + "Total CPU secs in NLP function evaluations = 0.045\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.41e-03 2.08e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.23e-09 1.50e-06 -1.0 1.78e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.2337816041329006e-09 2.2337816041329006e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.2337816041329006e-09 2.2337816041329006e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.104\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.32e-03 3.69e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.98e-09 1.44e-06 -1.0 1.67e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.9765331593646351e-09 1.9765331593646351e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.9765331593646351e-09 1.9765331593646351e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.2 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 8.43e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.61e+02 3.85e+02 -1.0 8.43e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.54e+00 3.85e+00 -1.0 7.08e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.46e-02 4.39e+00 -1.0 8.02e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.93e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2260028e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2261473e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2260355e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2266446e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2254710e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2256378e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", + " 6 -1.2251753e+01 1.23e+01 3.32e+00 -1.0 9.22e+01 - 8.77e-01 3.36e-01f 2\n", + " 7 -1.2247342e+01 3.64e+00 5.35e-01 -1.0 5.23e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2249251e+01 4.47e-01 7.84e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2249255e+01 2.39e-04 1.38e-03 -1.7 3.57e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2249317e+01 4.10e-04 1.13e-03 -3.8 4.68e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2249467e+01 2.64e-04 1.34e-04 -5.7 9.10e-01 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.2250000e+01 3.31e-03 1.08e-04 -5.7 3.23e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 -1.2250322e+01 3.13e-03 1.32e-03 -5.7 4.61e+00 -5.0 1.00e+00 4.23e-01h 1\n", + " 14 -1.2250433e+01 2.06e-03 7.85e-04 -5.7 6.18e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 15 -1.2261629e+01 2.19e+01 8.47e-02 -5.7 6.04e+03 - 2.88e-02 2.27e-02h 1\n", + " 16 -1.2265527e+01 2.15e+01 6.31e-02 -5.7 1.28e+02 - 1.00e+00 2.59e-01f 1\n", + " 17 -1.2268702e+01 9.75e-01 1.54e-02 -5.7 2.61e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (320847)\n", + " 18 -1.2267146e+01 3.13e-01 1.00e-03 -5.7 1.77e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.2267156e+01 4.84e-04 4.02e-06 -5.7 5.89e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (338500)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2267156e+01 3.56e-08 2.75e-09 -5.7 1.30e-02 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.2267782e+01 3.24e-01 9.64e-04 -8.6 1.78e+01 - 9.11e-01 9.81e-01h 1\n", + " 22 -1.2267804e+01 1.12e-02 2.49e-04 -8.6 9.37e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (357003)\n", + " 23 -1.2267811e+01 2.04e-03 4.64e-05 -8.6 4.06e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 -1.2267812e+01 5.38e-05 1.69e-06 -8.6 6.64e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.2267812e+01 3.11e-08 2.34e-09 -8.6 1.60e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.2267812e+01 4.55e-13 3.29e-14 -8.6 2.09e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2267811714197844e+01 -1.2267811714197844e+01\n", + "Dual infeasibility......: 3.2899955311301634e-14 3.2899955311301634e-14\n", + "Constraint violation....: 1.2096124245683242e-13 4.5474735088646412e-13\n", + "Complementarity.........: 2.5059035616651650e-09 2.5059035616651650e-09\n", + "Overall NLP error.......: 2.5059035616651650e-09 2.5059035616651650e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.945\n", + "Total CPU secs in NLP function evaluations = 0.030\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 3.67e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.18e+00 3.85e+02 -1.0 3.62e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.77e-02 3.85e+00 -1.0 4.47e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.72e-04 4.39e+00 -1.0 5.07e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.02e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.132\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 8.9357618e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 8.9266467e-01 1.57e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", + " 2 8.9324077e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 8.8727234e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 8.9978503e-01 7.13e-01 2.49e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 8.9690135e-01 5.85e-01 4.71e+01 -1.0 3.49e+02 - 4.74e-01 8.83e-02f 2\n", + " 6 9.0474858e-01 1.37e-01 5.96e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 9.0340741e-01 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 9.0406676e-01 3.85e-02 5.76e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 9.0401537e-01 5.34e-03 3.76e-03 -2.5 6.32e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.0360000e-01 8.24e-04 7.04e-04 -3.8 1.31e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 8.9706762e-01 4.73e-01 2.82e-02 -5.7 3.26e+01 - 7.21e-01 1.00e+00h 1\n", + " 12 8.9104362e-01 7.55e-01 1.10e-02 -5.7 4.96e+01 - 8.53e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (326956)\n", + " 13 8.8691901e-01 7.24e-01 3.26e-02 -5.7 3.05e+01 - 8.07e-01 1.00e+00h 1\n", + " 14 8.8783634e-01 1.23e-02 9.48e-04 -5.7 7.02e-01 -4.5 9.51e-01 1.00e+00h 1\n", + " 15 8.8779529e-01 1.18e-06 3.71e-07 -5.7 3.26e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 8.8776642e-01 7.96e-06 3.75e-06 -8.6 1.12e-01 -5.4 9.99e-01 1.00e+00h 1\n", + " 17 8.8772695e-01 7.85e-05 3.35e-06 -8.6 3.61e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 18 8.8761634e-01 6.66e-04 2.84e-05 -8.6 1.06e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 19 8.8755498e-01 7.42e-04 3.16e-05 -8.6 2.76e+00 -6.9 1.00e+00 2.24e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 8.8717865e-01 9.48e-03 3.05e-04 -8.6 4.13e+00 -7.3 1.00e+00 1.00e+00f 1\n", + " 21 8.8657032e-01 4.66e-02 2.97e-03 -8.6 1.24e+01 -7.8 1.00e+00 9.75e-01h 1\n", + " 22 8.8612174e-01 1.44e-01 8.55e-03 -8.6 3.02e+02 -8.3 3.51e-01 6.41e-02h 1\n", + " 23 8.8583006e-01 7.53e-02 4.42e-03 -8.6 4.03e+01 - 1.00e+00 4.78e-01f 1\n", + " 24 8.8580769e-01 5.71e-02 3.34e-03 -8.6 3.65e+01 - 1.00e+00 2.44e-01f 1\n", + " 25 8.8579801e-01 4.72e-02 2.21e-03 -8.6 3.13e+01 - 1.00e+00 3.38e-01f 1\n", + "Reallocating memory for MA57: lfact (344590)\n", + " 26 8.8578794e-01 1.54e-03 9.57e-05 -8.6 2.23e+00 - 1.00e+00 1.00e+00h 1\n", + " 27 8.8579268e-01 3.27e-04 1.98e-07 -8.6 1.63e+00 - 1.00e+00 1.00e+00h 1\n", + " 28 8.8579267e-01 1.28e-06 6.66e-10 -8.6 1.03e-01 - 1.00e+00 1.00e+00h 1\n", + " 29 8.8579267e-01 4.37e-12 1.51e-10 -8.6 1.89e-04 -7.0 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 8.8579267060918165e-01 8.8579267060918165e-01\n", + "Dual infeasibility......: 1.5144484733052913e-10 1.5144484733052913e-10\n", + "Constraint violation....: 4.3728354270911041e-12 4.3728354270911041e-12\n", + "Complementarity.........: 2.5059074743708337e-09 2.5059074743708337e-09\n", + "Overall NLP error.......: 2.5059074743708337e-09 2.5059074743708337e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 30\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 30\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.345\n", + "Total CPU secs in NLP function evaluations = 0.035\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.31e-03 3.92e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.94e-09 1.43e-06 -1.0 1.66e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.9411232621280305e-09 1.9411232621280305e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.9411232621280305e-09 1.9411232621280305e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.31e-03 3.92e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.94e-09 1.43e-06 -1.0 1.66e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.9411330320906472e-09 1.9411330320906472e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.9411330320906472e-09 1.9411330320906472e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 9.19e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.69e+02 3.85e+02 -1.0 9.19e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.62e+00 3.85e+00 -1.0 7.15e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.53e-02 4.39e+00 -1.0 8.10e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.01e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2399698e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2401027e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2399984e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2405602e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2394795e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2396322e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", + " 6 -1.2392061e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.76e-01 3.36e-01f 2\n", + " 7 -1.2387991e+01 3.64e+00 5.35e-01 -1.0 5.23e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2389753e+01 4.48e-01 7.87e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2389755e+01 2.40e-04 1.33e-03 -1.7 3.63e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2389808e+01 3.50e-04 1.04e-03 -3.8 4.33e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2389937e+01 2.30e-04 1.17e-04 -5.7 8.50e-01 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.2390402e+01 2.96e-03 1.02e-04 -5.7 3.06e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 -1.2390734e+01 3.18e-03 1.06e-03 -5.7 4.98e+00 -5.0 1.00e+00 4.36e-01h 1\n", + " 14 -1.2390822e+01 1.73e-03 7.04e-04 -5.7 5.30e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 15 -1.2391170e+01 1.55e-02 2.13e-05 -5.7 2.13e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 16 -1.2392122e+01 1.25e-01 1.80e-04 -5.7 5.69e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 17 -1.2394535e+01 8.51e-01 1.24e-03 -5.7 1.34e+01 -6.9 1.00e+00 1.00e+00h 1\n", + " 18 -1.2399248e+01 3.83e+00 7.22e-03 -5.7 1.90e+01 -7.3 1.00e+00 1.00e+00h 1\n", + " 19 -1.2404443e+01 8.34e+00 2.26e-02 -5.7 3.55e+01 -7.8 1.00e+00 9.24e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2403887e+01 1.53e-01 1.60e-03 -5.7 1.03e+01 -7.4 1.00e+00 1.00e+00f 1\n", + " 21 -1.2405117e+01 4.79e-01 2.18e-03 -5.7 1.71e+01 -7.9 1.00e+00 1.00e+00h 1\n", + " 22 -1.2405374e+01 7.00e-02 1.88e-04 -5.7 8.45e+00 -7.4 1.00e+00 1.00e+00h 1\n", + " 23 -1.2405756e+01 2.12e-01 1.22e-03 -5.7 1.03e+02 - 1.00e+00 2.08e-01h 2\n", + " 24 -1.2406358e+01 1.03e+00 2.17e-03 -5.7 8.46e+01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (322545)\n", + " 25 -1.2406204e+01 1.75e-02 7.25e-05 -5.7 4.61e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.2406205e+01 2.37e-04 2.08e-07 -5.7 1.32e+00 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.2406205e+01 7.23e-08 5.15e-11 -5.7 2.30e-02 - 1.00e+00 1.00e+00h 1\n", + " 28 -1.2406828e+01 3.77e-01 1.03e-03 -8.6 1.92e+01 - 9.07e-01 9.76e-01h 1\n", + "Reallocating memory for MA57: lfact (354103)\n", + " 29 -1.2406852e+01 1.23e-02 2.52e-04 -8.6 9.79e+00 - 9.97e-01 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -1.2406858e+01 2.37e-03 4.93e-05 -8.6 4.37e+00 - 1.00e+00 1.00e+00h 1\n", + " 31 -1.2406860e+01 7.39e-05 2.07e-06 -8.6 7.78e-01 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (376176)\n", + " 32 -1.2406860e+01 5.90e-08 3.77e-09 -8.6 2.20e-02 - 1.00e+00 1.00e+00h 1\n", + " 33 -1.2406860e+01 1.82e-12 3.89e-14 -8.6 3.63e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 33\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2406859586044352e+01 -1.2406859586044352e+01\n", + "Dual infeasibility......: 3.8887996860705895e-14 3.8887996860705895e-14\n", + "Constraint violation....: 9.1789600112649688e-13 1.8189894035458565e-12\n", + "Complementarity.........: 2.5059035652168643e-09 2.5059035652168643e-09\n", + "Overall NLP error.......: 2.5059035652168643e-09 2.5059035652168643e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 43\n", + "Number of objective gradient evaluations = 34\n", + "Number of equality constraint evaluations = 43\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 34\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 33\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.368\n", + "Total CPU secs in NLP function evaluations = 0.051\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 4.01e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.21e+00 3.85e+02 -1.0 3.96e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.80e-02 3.85e+00 -1.0 4.50e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.75e-04 4.39e+00 -1.0 5.11e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.05e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 7.5390617e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 7.5307280e-01 1.57e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", + " 2 7.5361378e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 7.4810233e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 7.5962740e-01 7.12e-01 2.49e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 7.5698063e-01 5.85e-01 4.71e+01 -1.0 3.48e+02 - 4.75e-01 8.85e-02f 2\n", + " 6 7.6420980e-01 1.37e-01 5.99e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 7.6297451e-01 4.34e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 7.6358498e-01 3.85e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 7.6354212e-01 5.37e-03 3.81e-03 -2.5 6.34e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 7.6350175e-01 2.77e-06 2.26e-05 -3.8 3.72e-02 -4.5 1.00e+00 1.00e+00h 1\n", + " 11 7.5733271e-01 4.48e-01 2.29e-02 -5.7 3.01e+01 - 7.11e-01 1.00e+00h 1\n", + " 12 7.5196585e-01 6.78e-01 8.94e-03 -5.7 4.61e+01 - 8.18e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (327108)\n", + " 13 7.4797841e-01 6.41e-01 2.55e-02 -5.7 2.96e+01 - 8.64e-01 1.00e+00h 1\n", + " 14 7.4890109e-01 8.10e-03 4.06e-04 -5.7 6.20e-01 -5.0 1.00e+00 1.00e+00h 1\n", + " 15 7.4886319e-01 1.99e-06 2.82e-07 -5.7 5.38e-02 -5.4 1.00e+00 1.00e+00h 1\n", + " 16 7.4881137e-01 6.86e-05 1.98e-05 -8.6 3.31e-01 -5.9 9.95e-01 1.00e+00h 1\n", + " 17 7.4870952e-01 6.03e-04 2.31e-05 -8.6 9.93e-01 -6.4 1.00e+00 1.00e+00h 1\n", + " 18 7.4845170e-01 4.66e-03 1.77e-04 -8.6 2.80e+00 -6.9 1.00e+00 1.00e+00h 1\n", + " 19 7.4825676e-01 6.71e-03 2.55e-04 -8.6 7.30e+00 -7.3 1.00e+00 3.51e-01h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 7.4767097e-01 3.32e-02 1.65e-03 -8.6 8.46e+00 -7.8 1.00e+00 1.00e+00f 1\n", + " 21 7.4711216e-01 2.44e-01 1.54e-02 -8.6 1.14e+02 -8.3 9.80e-01 2.52e-01h 1\n", + " 22 7.4688518e-01 1.38e-01 8.67e-03 -8.6 4.16e+01 - 1.00e+00 4.39e-01f 1\n", + " 23 7.4683046e-01 1.02e-01 6.42e-03 -8.6 3.76e+01 - 1.00e+00 2.59e-01f 1\n", + " 24 7.4679078e-01 6.26e-02 3.91e-03 -8.6 3.27e+01 - 1.00e+00 3.90e-01f 1\n", + " 25 7.4674071e-01 1.91e-03 7.64e-05 -8.6 2.40e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (350967)\n", + " 26 7.4674477e-01 5.39e-04 3.03e-07 -8.6 2.09e+00 - 1.00e+00 1.00e+00h 1\n", + " 27 7.4674475e-01 3.40e-06 1.63e-09 -8.6 1.67e-01 - 1.00e+00 1.00e+00h 1\n", + " 28 7.4674475e-01 8.78e-11 6.54e-14 -8.6 8.49e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 28\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 7.4674475313131294e-01 7.4674475313131294e-01\n", + "Dual infeasibility......: 6.5380653010782577e-14 6.5380653010782577e-14\n", + "Constraint violation....: 8.7840845708342385e-11 8.7840845708342385e-11\n", + "Complementarity.........: 2.5059039393135571e-09 2.5059039393135571e-09\n", + "Overall NLP error.......: 2.5059039393135571e-09 2.5059039393135571e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 33\n", + "Number of objective gradient evaluations = 29\n", + "Number of equality constraint evaluations = 33\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 29\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 28\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.211\n", + "Total CPU secs in NLP function evaluations = 0.043\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.9 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.30e-03 4.15e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.91e-09 1.42e-06 -1.0 1.64e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.9060446554419741e-09 1.9060446554419741e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.9060446554419741e-09 1.9060446554419741e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.30e-03 4.15e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.91e-09 1.42e-06 -1.0 1.64e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.9060530931369613e-09 1.9060530931369613e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.9060530931369613e-09 1.9060530931369613e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 0.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 9.96e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.76e+02 3.85e+02 -1.0 9.96e+03 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.69e+00 3.85e+00 -1.0 7.23e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.61e-02 4.39e+00 -1.0 8.17e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.08e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0403773356229067e-09 9.0403773356229067e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0403773356229067e-09 9.0403773356229067e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.132\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2528966e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2530197e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2529220e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2534432e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2524418e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2525826e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", + " 6 -1.2521877e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.76e-01 3.35e-01f 2\n", + " 7 -1.2518098e+01 3.65e+00 5.36e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2519733e+01 4.49e-01 7.90e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2519735e+01 2.41e-04 1.29e-03 -1.7 3.68e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2519781e+01 3.02e-04 9.67e-04 -3.8 4.03e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2519893e+01 2.02e-04 1.02e-04 -5.7 7.97e-01 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.2520302e+01 2.66e-03 9.65e-05 -5.7 2.89e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 -1.2520638e+01 3.26e-03 8.46e-04 -5.7 5.24e+00 -5.0 1.00e+00 4.54e-01h 1\n", + " 14 -1.2520708e+01 1.48e-03 6.33e-04 -5.7 4.47e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 15 -1.2521012e+01 1.34e-02 1.66e-05 -5.7 2.02e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 16 -1.2521836e+01 1.09e-01 1.45e-04 -5.7 5.34e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 17 -1.2523945e+01 7.51e-01 9.99e-04 -5.7 1.28e+01 -6.9 1.00e+00 1.00e+00h 1\n", + " 18r-1.2523945e+01 7.51e-01 9.99e+02 -0.1 0.00e+00 - 0.00e+00 3.08e-07R 18\n", + " 19r-1.2523451e+01 1.72e-01 9.81e+02 -0.1 3.12e+03 - 1.04e-01 9.90e-04f 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2524823e+01 1.77e-01 5.03e-02 -5.7 1.23e+04 - 7.38e-02 7.99e-04h 1\n", + " 21 -1.2539231e+01 3.95e+01 4.75e-02 -5.7 2.75e+03 - 3.37e-04 5.44e-02h 1\n", + "Reallocating memory for MA57: lfact (323127)\n", + " 22 -1.2541247e+01 3.61e+01 4.11e-02 -5.7 3.01e+02 - 1.46e-01 1.36e-01f 1\n", + " 23 -1.2539740e+01 2.50e+01 3.16e-02 -5.7 1.12e+02 - 1.19e-01 3.51e-01h 1\n", + " 24 -1.2536325e+01 1.39e+01 5.47e-02 -5.7 9.93e+01 - 1.00e+00 5.51e-01h 1\n", + " 25 -1.2536505e+01 1.38e+01 2.22e-01 -5.7 5.62e+02 - 1.93e-03 4.60e-02h 1\n", + " 26 -1.2534286e+01 1.59e+00 1.76e-01 -5.7 3.49e+01 - 1.24e-01 1.00e+00f 1\n", + " 27 -1.2534443e+01 5.57e-02 3.13e-04 -5.7 1.15e+01 -7.3 1.00e+00 1.00e+00h 1\n", + " 28 -1.2534551e+01 9.81e-02 7.65e-04 -5.7 7.58e+00 -7.8 1.00e+00 1.00e+00h 1\n", + " 29 -1.2534950e+01 1.03e+00 6.91e-03 -5.7 2.80e+01 -8.3 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -1.2534831e+01 1.41e-01 1.08e-03 -5.7 8.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 31 -1.2534949e+01 4.97e-02 3.05e-04 -5.7 6.88e+00 - 1.00e+00 1.00e+00h 1\n", + " 32 -1.2534944e+01 2.69e-04 2.11e-06 -5.7 4.40e-01 - 1.00e+00 1.00e+00h 1\n", + " 33 -1.2534944e+01 1.07e-08 1.03e-10 -5.7 2.72e-03 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (344149)\n", + " 34 -1.2535563e+01 4.32e-01 1.10e-03 -8.6 2.06e+01 - 9.03e-01 9.71e-01h 1\n", + "Reallocating memory for MA57: lfact (363431)\n", + " 35 -1.2535591e+01 1.34e-02 2.54e-04 -8.6 1.02e+01 - 9.95e-01 1.00e+00h 1\n", + " 36 -1.2535597e+01 2.72e-03 5.20e-05 -8.6 4.68e+00 - 1.00e+00 1.00e+00h 1\n", + " 37 -1.2535598e+01 9.81e-05 2.47e-06 -8.6 8.96e-01 - 1.00e+00 1.00e+00h 1\n", + " 38 -1.2535598e+01 1.05e-07 5.76e-09 -8.6 2.93e-02 - 1.00e+00 1.00e+00h 1\n", + " 39 -1.2535598e+01 1.82e-12 5.88e-14 -8.6 5.95e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 39\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2535597772942342e+01 -1.2535597772942342e+01\n", + "Dual infeasibility......: 5.8821618000241020e-14 5.8821618000241020e-14\n", + "Constraint violation....: 1.8189894035458565e-12 1.8189894035458565e-12\n", + "Complementarity.........: 2.5059035734822043e-09 2.5059035734822043e-09\n", + "Overall NLP error.......: 2.5059035734822043e-09 2.5059035734822043e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 66\n", + "Number of objective gradient evaluations = 40\n", + "Number of equality constraint evaluations = 66\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 41\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 39\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.508\n", + "Total CPU secs in NLP function evaluations = 0.067\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.3 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 4.35e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.24e+00 3.85e+02 -1.0 4.30e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.83e-02 3.85e+00 -1.0 4.53e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.78e-04 4.39e+00 -1.0 5.14e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.08e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 6.2463783e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 6.2387037e-01 1.57e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.75e-01h 1\n", + " 2 6.2438002e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 6.1926056e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 6.2994249e-01 7.12e-01 2.48e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 6.2749675e-01 5.85e-01 4.72e+01 -1.0 3.48e+02 - 4.75e-01 8.87e-02f 2\n", + " 6 6.3421863e-01 1.35e-01 6.11e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", + " 7 6.3306025e-01 4.35e-01 2.98e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 6.3362659e-01 3.83e-02 5.75e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 6.3358982e-01 5.38e-03 3.85e-03 -2.5 6.34e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 6.3355519e-01 2.58e-06 2.12e-05 -3.8 3.51e-02 -4.5 1.00e+00 1.00e+00h 1\n", + " 11 6.3322338e-01 2.85e-05 3.51e-06 -5.7 9.23e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 12 6.3264654e-01 1.33e-04 5.05e-06 -5.7 2.72e-01 -5.4 1.00e+00 1.00e+00h 1\n", + " 13 6.3233614e-01 4.22e-04 2.05e-05 -5.7 7.80e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 14 6.3145086e-01 3.55e-03 1.66e-04 -5.7 2.26e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 15 6.2329402e-01 1.79e+00 4.47e-02 -5.7 7.85e+02 - 1.56e-01 9.99e-02h 1\n", + " 16 6.2001136e-01 1.37e+00 4.66e-02 -5.7 1.24e+02 - 1.00e+00 2.70e-01f 1\n", + " 17 6.1736350e-01 1.24e-01 1.13e-02 -5.7 2.91e+01 - 1.00e+00 1.00e+00f 1\n", + "Reallocating memory for MA57: lfact (322135)\n", + " 18 6.1867566e-01 7.27e-03 6.10e-04 -5.7 4.56e+00 - 1.00e+00 1.00e+00h 1\n", + " 19 6.1866009e-01 5.67e-05 3.42e-06 -5.7 6.62e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 6.1866005e-01 2.03e-08 1.12e-09 -5.7 1.25e-02 - 1.00e+00 1.00e+00h 1\n", + " 21 6.1804128e-01 3.11e-02 1.10e-03 -8.6 1.54e+01 - 9.03e-01 9.71e-01h 1\n", + "Reallocating memory for MA57: lfact (347921)\n", + " 22 6.1801354e-01 1.34e-02 2.54e-04 -8.6 1.02e+01 - 9.95e-01 1.00e+00h 1\n", + " 23 6.1800773e-01 2.72e-03 5.20e-05 -8.6 4.68e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 6.1800657e-01 9.81e-05 2.47e-06 -8.6 8.96e-01 - 1.00e+00 1.00e+00h 1\n", + " 25 6.1800653e-01 1.05e-07 5.76e-09 -8.6 2.93e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 6.1800653e-01 4.32e-13 5.93e-14 -8.6 5.95e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 6.1800652712078263e-01 6.1800652712078263e-01\n", + "Dual infeasibility......: 5.9277911925848335e-14 5.9277911925848335e-14\n", + "Constraint violation....: 4.3220982348657344e-13 4.3220982348657344e-13\n", + "Complementarity.........: 2.5059035734816410e-09 2.5059035734816410e-09\n", + "Overall NLP error.......: 2.5059035734816410e-09 2.5059035734816410e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 31\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 31\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.926\n", + "Total CPU secs in NLP function evaluations = 0.031\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.29e-03 4.38e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.87e-09 1.41e-06 -1.0 1.63e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8712897897898984e-09 1.8712897897898984e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8712897897898984e-09 1.8712897897898984e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", + "Total CPU secs in NLP function evaluations = 0.002\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.29e-03 4.38e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.87e-09 1.41e-06 -1.0 1.63e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8712982274848855e-09 1.8712982274848855e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8712982274848855e-09 1.8712982274848855e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.098\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.07e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.84e+02 3.85e+02 -1.0 1.07e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.77e+00 3.85e+00 -1.0 7.31e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.68e-02 4.39e+00 -1.0 8.25e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.16e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2649276e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2650421e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2649502e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2654364e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2645035e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2646341e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", + " 6 -1.2642660e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.75e-01 3.35e-01f 2\n", + " 7 -1.2639134e+01 3.65e+00 5.36e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2640660e+01 4.49e-01 7.92e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2640661e+01 2.42e-04 1.25e-03 -1.7 3.72e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2640701e+01 2.64e-04 9.04e-04 -3.8 3.77e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2645246e+01 3.62e+00 2.60e-02 -5.7 4.21e+01 - 7.44e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319822)\n", + " 12 -1.2650749e+01 4.98e+00 1.49e-02 -5.7 7.45e+01 - 8.19e-01 1.00e+00h 1\n", + " 13 -1.2654062e+01 5.16e+00 1.87e-02 -5.7 3.19e+01 - 9.04e-01 1.00e+00h 1\n", + " 14 -1.2654011e+01 4.69e+00 5.08e-02 -5.7 1.46e+01 -4.0 1.00e+00 9.14e-02h 1\n", + " 15 -1.2654035e+01 7.16e-01 2.01e-02 -5.7 3.14e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 -1.2653941e+01 1.00e-03 9.08e-05 -5.7 3.69e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 17 -1.2654241e+01 6.33e-01 5.16e-03 -5.7 1.06e+02 - 1.00e+00 1.70e-01h 2\n", + " 18 -1.2654880e+01 3.29e-01 2.15e-03 -5.7 1.63e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.2654796e+01 6.21e-03 3.76e-05 -5.7 1.47e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2654797e+01 9.53e-06 4.39e-08 -5.7 1.04e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.2655412e+01 4.92e-01 1.17e-03 -8.6 2.19e+01 - 8.97e-01 9.66e-01h 1\n", + "Reallocating memory for MA57: lfact (343005)\n", + " 22 -1.2655443e+01 1.44e-02 2.56e-04 -8.6 1.06e+01 - 9.92e-01 1.00e+00h 1\n", + " 23 -1.2655449e+01 3.08e-03 5.46e-05 -8.6 4.98e+00 - 1.00e+00 1.00e+00h 1\n", + " 24 -1.2655450e+01 1.28e-04 2.92e-06 -8.6 1.02e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (360209)\n", + " 25 -1.2655450e+01 1.79e-07 8.58e-09 -8.6 3.83e-02 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.2655450e+01 1.82e-12 1.06e-13 -8.6 9.45e-05 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 26\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2655450125163370e+01 -1.2655450125163370e+01\n", + "Dual infeasibility......: 1.0562293264999832e-13 1.0562293264999832e-13\n", + "Constraint violation....: 1.0876854972252659e-12 1.8189894035458565e-12\n", + "Complementarity.........: 2.5059035921766028e-09 2.5059035921766028e-09\n", + "Overall NLP error.......: 2.5059035921766028e-09 2.5059035921766028e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 37\n", + "Number of objective gradient evaluations = 27\n", + "Number of equality constraint evaluations = 37\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 27\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 26\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.992\n", + "Total CPU secs in NLP function evaluations = 0.043\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 4.69e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.27e+00 3.85e+02 -1.0 4.64e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.87e-02 3.85e+00 -1.0 4.57e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.81e-04 4.39e+00 -1.0 5.17e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.11e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 5.0432833e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 5.0361720e-01 1.56e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.75e-01h 1\n", + " 2 5.0409878e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 4.9931925e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 5.0927300e-01 7.12e-01 2.48e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 5.0699996e-01 5.85e-01 4.72e+01 -1.0 3.47e+02 - 4.76e-01 8.88e-02f 2\n", + " 6 5.1324183e-01 1.37e-01 6.01e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 5.1217900e-01 4.34e-01 2.96e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 5.1271052e-01 3.84e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 5.1267962e-01 5.41e-03 3.90e-03 -2.5 6.36e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 5.1241548e-01 5.08e-04 5.15e-04 -3.8 9.59e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 5.0807961e-01 3.17e-01 2.48e-02 -5.7 2.63e+01 - 7.57e-01 1.00e+00h 1\n", + " 12 5.0278293e-01 8.71e-01 1.15e-02 -5.7 5.29e+01 - 8.62e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (326106)\n", + " 13 4.9913241e-01 7.64e-01 2.78e-02 -5.7 3.15e+01 - 8.71e-01 1.00e+00h 1\n", + " 14 4.9997874e-01 1.14e-02 5.09e-04 -5.7 7.44e-01 -4.5 9.85e-01 1.00e+00h 1\n", + " 15 4.9994319e-01 6.15e-07 2.09e-07 -5.7 1.61e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 4.9991846e-01 5.82e-06 2.33e-06 -8.6 9.55e-02 -5.4 9.99e-01 1.00e+00h 1\n", + " 17 4.9989124e-01 5.24e-05 1.77e-06 -8.6 2.92e-01 -5.9 1.00e+00 1.00e+00h 1\n", + " 18 4.9981470e-01 4.48e-04 1.51e-05 -8.6 8.57e-01 -6.4 1.00e+00 1.00e+00h 1\n", + " 19 4.9961545e-01 3.50e-03 1.17e-04 -8.6 2.43e+00 -6.9 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 4.9957792e-01 3.35e-03 1.12e-04 -8.6 6.02e+00 -7.3 1.00e+00 8.63e-02h 1\n", + " 21 4.9902524e-01 3.02e-02 1.14e-03 -8.6 7.74e+00 -7.8 1.00e+00 1.00e+00f 1\n", + " 22 4.9848008e-01 2.40e-01 1.30e-02 -8.6 7.13e+01 -8.3 1.00e+00 4.02e-01h 1\n", + " 23 4.9828290e-01 1.29e-01 7.02e-03 -8.6 4.11e+01 - 1.00e+00 4.70e-01f 1\n", + " 24 4.9823261e-01 9.68e-02 5.22e-03 -8.6 3.63e+01 - 1.00e+00 2.57e-01f 1\n", + " 25 4.9820105e-01 6.31e-02 3.38e-03 -8.6 3.10e+01 - 1.00e+00 3.52e-01f 1\n", + " 26 4.9815087e-01 2.36e-03 6.18e-05 -8.6 2.04e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (361644)\n", + " 27 4.9815415e-01 3.57e-04 1.71e-07 -8.6 1.71e+00 - 1.00e+00 1.00e+00h 1\n", + " 28 4.9815414e-01 1.50e-06 6.26e-10 -8.6 1.11e-01 - 1.00e+00 1.00e+00h 1\n", + " 29 4.9815414e-01 1.71e-11 3.34e-14 -8.6 3.75e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 29\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 4.9815414100226940e-01 4.9815414100226940e-01\n", + "Dual infeasibility......: 3.3405414623680940e-14 3.3405414623680940e-14\n", + "Constraint violation....: 1.7140733277187792e-11 1.7140733277187792e-11\n", + "Complementarity.........: 2.5059036238671544e-09 2.5059036238671544e-09\n", + "Overall NLP error.......: 2.5059036238671544e-09 2.5059036238671544e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 30\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 30\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 29\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.235\n", + "Total CPU secs in NLP function evaluations = 0.038\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.27e-03 4.61e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.84e-09 1.40e-06 -1.0 1.61e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8368555565473343e-09 1.8368555565473343e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8368555565473343e-09 1.8368555565473343e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.27e-03 4.61e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.84e-09 1.40e-06 -1.0 1.61e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8368631060639018e-09 1.8368631060639018e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8368631060639018e-09 1.8368631060639018e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.102\n", + "Total CPU secs in NLP function evaluations = 0.003\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.15e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.92e+02 3.85e+02 -1.0 1.15e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.85e+00 3.85e+00 -1.0 7.38e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.76e-02 4.39e+00 -1.0 8.33e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.23e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0367393568158150e-09 9.0367393568158150e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0367393568158150e-09 9.0367393568158150e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.126\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2761788e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2762860e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2761992e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2766548e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2757815e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2759034e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", + " 6 -1.2755587e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.75e-01 3.35e-01f 2\n", + " 7 -1.2752282e+01 3.66e+00 5.36e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2753712e+01 4.50e-01 7.94e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2753713e+01 2.43e-04 1.22e-03 -1.7 3.76e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2753748e+01 2.32e-04 8.49e-04 -3.8 3.54e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2753835e+01 1.60e-04 8.09e-05 -5.7 7.08e-01 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.2754158e+01 2.17e-03 8.72e-05 -5.7 2.61e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 -1.2754496e+01 3.46e-03 5.33e-04 -5.7 5.48e+00 -5.0 1.00e+00 4.99e-01h 1\n", + " 14 -1.2754536e+01 1.11e-03 5.18e-04 -5.7 2.85e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 15 -1.2754778e+01 1.03e-02 2.28e-05 -5.7 1.85e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 16 -1.2755412e+01 8.41e-02 9.87e-05 -5.7 4.74e+00 -6.4 1.00e+00 1.00e+00h 1\n", + " 17 -1.2757064e+01 5.97e-01 6.84e-04 -5.7 1.17e+01 -6.9 1.00e+00 1.00e+00h 1\n", + " 18 -1.2760500e+01 2.94e+00 4.15e-03 -5.7 1.95e+01 -7.3 1.00e+00 1.00e+00h 1\n", + " 19 -1.2761019e+01 9.59e+00 2.25e-02 -5.7 6.29e+02 - 1.13e-01 1.41e-01h 2\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2764864e+01 1.90e+01 9.25e-02 -5.7 1.73e+02 - 3.33e-01 3.01e-01h 1\n", + " 21 -1.2764680e+01 1.16e+01 1.82e-01 -5.7 2.07e+02 - 3.79e-01 7.21e-01H 1\n", + " 22 -1.2767567e+01 1.81e+01 2.45e-01 -5.7 1.01e+02 - 1.00e+00 1.00e+00f 1\n", + " 23 -1.2767317e+01 1.23e+01 1.12e-01 -5.7 1.91e+02 - 1.00e+00 5.53e-01h 1\n", + "Reallocating memory for MA57: lfact (319005)\n", + " 24 -1.2767311e+01 8.83e+00 7.94e-02 -5.7 8.23e+01 - 8.73e-01 9.30e-01f 1\n", + " 25 -1.2766311e+01 1.99e+00 2.60e-02 -5.7 3.16e+01 - 1.00e+00 1.00e+00f 1\n", + " 26 -1.2766561e+01 2.73e-01 7.90e-04 -5.7 2.07e+01 -7.8 1.00e+00 1.00e+00h 1\n", + " 27 -1.2766765e+01 6.11e-01 2.75e-03 -5.7 3.40e+02 - 4.24e-01 4.80e-02h 2\n", + " 28 -1.2766866e+01 3.52e-02 1.15e-04 -5.7 5.75e+00 - 1.00e+00 1.00e+00h 1\n", + " 29 -1.2766913e+01 1.08e-02 5.42e-05 -5.7 3.27e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 30 -1.2766912e+01 5.95e-06 4.85e-08 -5.7 5.76e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (340818)\n", + " 31 -1.2767524e+01 5.55e-01 1.25e-03 -8.6 2.33e+01 - 8.91e-01 9.61e-01h 1\n", + " 32 -1.2767558e+01 1.54e-02 2.57e-04 -8.6 1.09e+01 - 9.90e-01 1.00e+00h 1\n", + " 33 -1.2767563e+01 3.45e-03 5.70e-05 -8.6 5.26e+00 - 1.00e+00 1.00e+00h 1\n", + " 34 -1.2767564e+01 1.62e-04 3.39e-06 -8.6 1.15e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (358770)\n", + " 35 -1.2767564e+01 2.90e-07 1.23e-08 -8.6 4.88e-02 - 1.00e+00 1.00e+00h 1\n", + " 36 -1.2767564e+01 2.51e-12 1.99e-13 -8.6 1.44e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 36\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2767564482596377e+01 -1.2767564482596377e+01\n", + "Dual infeasibility......: 1.9925310697126672e-13 1.9925310697126672e-13\n", + "Constraint violation....: 2.5131008385415043e-12 2.5131008385415043e-12\n", + "Complementarity.........: 2.5059036300337093e-09 2.5059036300337093e-09\n", + "Overall NLP error.......: 2.5059036300337093e-09 2.5059036300337093e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 51\n", + "Number of objective gradient evaluations = 37\n", + "Number of equality constraint evaluations = 51\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 37\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 36\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.271\n", + "Total CPU secs in NLP function evaluations = 0.053\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.03e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.31e+00 3.85e+02 -1.0 4.98e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.90e-02 3.85e+00 -1.0 4.60e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.84e-04 4.39e+00 -1.0 5.20e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.14e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8342664033261826e-11 5.8342664033261826e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8342664033261826e-11 5.8342664033261826e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 3.9181573e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 3.9115328e-01 1.56e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.75e-01h 1\n", + " 2 3.9160960e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 3.8712768e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 3.9644619e-01 7.12e-01 2.48e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 3.9432311e-01 5.85e-01 4.73e+01 -1.0 3.46e+02 - 4.77e-01 8.89e-02f 2\n", + " 6 4.0017008e-01 1.36e-01 6.05e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 3.9917425e-01 4.34e-01 2.97e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 3.9967295e-01 3.84e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 3.9964620e-01 5.42e-03 3.94e-03 -2.5 6.37e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 3.9941445e-01 5.23e-04 4.68e-04 -3.8 8.72e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 3.9556789e-01 2.81e-01 2.38e-02 -5.7 2.46e+01 - 7.68e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (320660)\n", + " 12 3.9049239e-01 8.99e-01 1.14e-02 -5.7 5.36e+01 - 8.66e-01 1.00e+00h 1\n", + " 13 3.8696936e-01 7.77e-01 2.66e-02 -5.7 3.18e+01 - 8.89e-01 1.00e+00h 1\n", + " 14 3.8779264e-01 1.12e-02 4.89e-04 -5.7 7.59e-01 -4.5 9.97e-01 1.00e+00h 1\n", + " 15 3.8775852e-01 6.21e-07 1.98e-07 -5.7 1.51e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 3.8730660e-01 3.80e-01 2.43e-02 -8.6 1.44e+04 - 7.13e-03 2.64e-03h 1\n", + " 17 3.8571434e-01 1.57e-01 4.82e-03 -8.6 3.21e+01 - 8.01e-01 1.00e+00h 1\n", + " 18 3.8604273e-01 1.97e-02 3.18e-04 -8.6 1.23e+01 - 9.78e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (352373)\n", + " 19 3.8603975e-01 2.68e-03 8.27e-06 -8.6 4.65e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 3.8603975e-01 4.52e-05 4.68e-08 -8.6 6.09e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 3.8603975e-01 1.34e-08 4.74e-12 -8.6 1.05e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 3.8603911e-01 1.37e-06 2.67e-08 -9.0 1.06e-01 - 1.00e+00 1.00e+00h 1\n", + " 23 3.8603911e-01 4.37e-11 1.28e-12 -9.0 5.99e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 23\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 3.8603910736158609e-01 3.8603910736158609e-01\n", + "Dual infeasibility......: 1.2773062897591488e-12 1.2773062897591488e-12\n", + "Constraint violation....: 4.3745562727792731e-11 4.3745562727792731e-11\n", + "Complementarity.........: 9.0909138582673236e-10 9.0909138582673236e-10\n", + "Overall NLP error.......: 9.0909138582673236e-10 9.0909138582673236e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 28\n", + "Number of objective gradient evaluations = 24\n", + "Number of equality constraint evaluations = 28\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 24\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 23\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.951\n", + "Total CPU secs in NLP function evaluations = 0.031\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.26e-03 4.84e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.80e-09 1.40e-06 -1.0 1.60e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.8027450643387510e-09 1.8027450643387510e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.8027450643387510e-09 1.8027450643387510e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.38e-03 2.49e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.17e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1657315940615263e-09 2.1657315940615263e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1657315940615263e-09 2.1657315940615263e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.106\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 0.9 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.23e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 6.99e+02 3.85e+02 -1.0 1.23e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 7.92e+00 3.85e+00 -1.0 7.46e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.83e-02 4.39e+00 -1.0 8.40e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.31e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", + "Total CPU secs in NLP function evaluations = 0.008\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2867454e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2868460e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2867639e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2871924e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2863717e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2864858e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", + " 6 -1.2861618e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", + " 7 -1.2858508e+01 3.66e+00 5.37e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2859854e+01 4.51e-01 7.96e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2859854e+01 2.44e-04 1.19e-03 -1.7 3.79e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2859885e+01 2.06e-04 8.00e-04 -3.8 3.33e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2863468e+01 2.88e+00 2.39e-02 -5.7 3.78e+01 - 7.65e-01 1.00e+00h 1\n", + " 12 -1.2868524e+01 5.45e+00 1.49e-02 -5.7 7.69e+01 - 8.12e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (324125)\n", + " 13 -1.2871542e+01 4.87e+00 1.57e-02 -5.7 3.27e+01 - 9.43e-01 1.00e+00h 1\n", + " 14 -1.2871505e+01 4.47e+00 5.03e-02 -5.7 1.42e+01 -4.0 1.00e+00 8.24e-02h 1\n", + " 15 -1.2871544e+01 7.88e-01 1.77e-02 -5.7 3.24e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 -1.2871459e+01 1.19e-03 1.13e-04 -5.7 4.55e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 17 -1.2871817e+01 6.63e-01 4.65e-03 -5.7 4.38e+01 - 1.00e+00 4.24e-01h 2\n", + " 18 -1.2872068e+01 6.22e-01 3.65e-03 -5.7 3.60e+01 - 1.00e+00 3.97e-01h 2\n", + " 19 -1.2872235e+01 1.80e-02 4.42e-04 -5.7 5.48e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2872228e+01 2.81e-04 1.04e-06 -5.7 7.92e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.2872228e+01 6.84e-09 4.81e-11 -5.7 2.27e-03 - 1.00e+00 1.00e+00h 1\n", + " 22 -1.2872836e+01 6.22e-01 1.32e-03 -8.6 2.46e+01 - 8.84e-01 9.57e-01h 1\n", + "Reallocating memory for MA57: lfact (352404)\n", + " 23 -1.2872873e+01 1.64e-02 2.58e-04 -8.6 1.12e+01 - 9.88e-01 1.00e+00h 1\n", + " 24 -1.2872878e+01 3.83e-03 5.93e-05 -8.6 5.54e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.2872880e+01 2.02e-04 3.88e-06 -8.6 1.28e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.2872880e+01 4.51e-07 1.70e-08 -8.6 6.08e-02 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.2872880e+01 5.38e-12 3.77e-13 -8.6 2.10e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2872879704090735e+01 -1.2872879704090735e+01\n", + "Dual infeasibility......: 3.7744241620007363e-13 3.7744241620007363e-13\n", + "Constraint violation....: 5.3804738442408961e-12 5.3804738442408961e-12\n", + "Complementarity.........: 2.5059037015571048e-09 2.5059037015571048e-09\n", + "Overall NLP error.......: 2.5059037015571048e-09 2.5059037015571048e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 43\n", + "Number of objective gradient evaluations = 28\n", + "Number of equality constraint evaluations = 43\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 28\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.074\n", + "Total CPU secs in NLP function evaluations = 0.067\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 3.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.38e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.34e+00 3.85e+02 -1.0 5.32e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.93e-02 3.85e+00 -1.0 4.63e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.87e-04 4.39e+00 -1.0 5.23e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.17e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", + "Total CPU secs in NLP function evaluations = 0.007\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 2.8614991e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 2.8552993e-01 1.56e-01 1.04e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", + " 2 2.8596341e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 2.8174414e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 2.9050364e-01 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 2.8851199e-01 5.85e-01 4.73e+01 -1.0 3.46e+02 - 4.77e-01 8.91e-02f 2\n", + " 6 2.9401108e-01 1.36e-01 6.08e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", + " 7 2.9307524e-01 4.34e-01 2.97e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 2.9354482e-01 3.83e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 2.9352137e-01 5.43e-03 3.97e-03 -2.5 6.38e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 2.9331638e-01 5.29e-04 4.27e-04 -3.8 8.79e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 2.8988055e-01 2.51e-01 2.28e-02 -5.7 2.32e+01 - 7.77e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319389)\n", + " 12 2.8501317e-01 9.24e-01 1.13e-02 -5.7 5.42e+01 - 8.69e-01 1.00e+00h 1\n", + " 13 2.8160648e-01 7.91e-01 2.55e-02 -5.7 3.22e+01 - 9.07e-01 1.00e+00h 1\n", + " 14 2.8240769e-01 1.11e-02 4.72e-04 -5.7 7.74e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 15 2.8237479e-01 6.27e-07 1.90e-07 -5.7 1.42e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 2.8187382e-01 3.93e-01 2.36e-02 -8.6 6.25e+02 - 1.42e-01 6.14e-02h 1\n", + " 17 2.8044338e-01 1.41e-01 4.08e-03 -8.6 3.11e+01 - 8.06e-01 1.00e+00h 1\n", + " 18 2.8072577e-01 1.89e-02 2.94e-04 -8.6 1.21e+01 - 9.80e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (348083)\n", + " 19 2.8072395e-01 2.58e-03 1.02e-05 -8.6 4.56e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 2.8072390e-01 4.67e-05 1.13e-07 -8.6 6.18e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 2.8072390e-01 1.53e-08 1.88e-11 -8.6 1.12e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 2.8072325e-01 1.54e-06 2.83e-08 -9.0 1.12e-01 - 1.00e+00 1.00e+00h 1\n", + " 23 2.8072325e-01 5.55e-11 1.52e-12 -9.0 6.75e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 23\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 2.8072325129350517e-01 2.8072325129350517e-01\n", + "Dual infeasibility......: 1.5217814371823493e-12 1.5217814371823493e-12\n", + "Constraint violation....: 5.5502491491665751e-11 5.5502491491665751e-11\n", + "Complementarity.........: 9.0909147761315399e-10 9.0909147761315399e-10\n", + "Overall NLP error.......: 9.0909147761315399e-10 9.0909147761315399e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 28\n", + "Number of objective gradient evaluations = 24\n", + "Number of equality constraint evaluations = 28\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 24\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 23\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.822\n", + "Total CPU secs in NLP function evaluations = 0.040\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.6 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.25e-03 5.07e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.77e-09 1.39e-06 -1.0 1.58e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.7689547604504696e-09 1.7689547604504696e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.7689547604504696e-09 1.7689547604504696e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.38e-03 2.57e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", + " 4 0.0000000e+00 2.15e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1522383875094420e-09 2.1522383875094420e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1522383875094420e-09 2.1522383875094420e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.0 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.30e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 7.07e+02 3.85e+02 -1.0 1.30e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 8.00e+00 3.85e+00 -1.0 7.54e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.91e-02 4.39e+00 -1.0 8.48e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.38e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.2967058e+01 1.25e+00 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.2968006e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", + " 2 -1.2967227e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.2971272e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.2963530e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.2964604e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", + " 6 -1.2961547e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", + " 7 -1.2958610e+01 3.66e+00 5.37e-01 -1.0 5.25e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.2959880e+01 4.51e-01 7.97e-02 -1.0 1.11e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.2959880e+01 2.45e-04 1.16e-03 -1.7 3.82e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.2959908e+01 1.85e-04 7.57e-04 -3.8 3.15e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.2963121e+01 2.60e+00 2.30e-02 -5.7 3.59e+01 - 7.75e-01 1.00e+00h 1\n", + " 12 -1.2967974e+01 5.66e+00 1.48e-02 -5.7 7.78e+01 - 8.10e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319946)\n", + " 13 -1.2970867e+01 4.77e+00 1.46e-02 -5.7 3.30e+01 - 9.60e-01 1.00e+00h 1\n", + " 14 -1.2970834e+01 4.39e+00 4.99e-02 -5.7 1.40e+01 -4.0 1.00e+00 7.87e-02h 1\n", + " 15 -1.2970871e+01 8.04e-01 1.66e-02 -5.7 3.26e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 -1.2970791e+01 1.23e-03 1.24e-04 -5.7 4.78e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 17 -1.2971470e+01 2.07e+00 1.31e-02 -5.7 3.26e+01 - 1.00e+00 1.00e+00h 1\n", + " 18 -1.2971390e+01 2.65e-01 2.02e-03 -5.7 1.09e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.2971539e+01 1.75e-01 7.49e-04 -5.7 1.26e+01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.2971523e+01 4.44e-03 2.61e-05 -5.7 1.85e+00 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.2971523e+01 2.35e-06 1.59e-08 -5.7 3.77e-02 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (342795)\n", + " 22 -1.2972127e+01 6.92e-01 1.39e-03 -8.6 2.60e+01 - 8.78e-01 9.52e-01h 1\n", + " 23 -1.2972167e+01 1.73e-02 2.59e-04 -8.6 1.15e+01 - 9.86e-01 1.00e+00h 1\n", + " 24 -1.2972172e+01 4.22e-03 6.14e-05 -8.6 5.81e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.2972173e+01 2.46e-04 4.38e-06 -8.6 1.42e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (361301)\n", + " 26 -1.2972174e+01 6.76e-07 2.28e-08 -8.6 7.45e-02 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.2972174e+01 1.08e-11 6.93e-13 -8.6 2.98e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.2972173508586897e+01 -1.2972173508586897e+01\n", + "Dual infeasibility......: 6.9302411901920606e-13 6.9302411901920606e-13\n", + "Constraint violation....: 1.0807355010911124e-11 1.0807355010911124e-11\n", + "Complementarity.........: 2.5059038289136340e-09 2.5059038289136340e-09\n", + "Overall NLP error.......: 2.5059038289136340e-09 2.5059038289136340e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 28\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 28\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.039\n", + "Total CPU secs in NLP function evaluations = 0.034\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.9 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 5.72e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.37e+00 3.85e+02 -1.0 5.66e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.96e-02 3.85e+00 -1.0 4.66e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.91e-04 4.39e+00 -1.0 5.27e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.21e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 1.8654549e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 1.8596289e-01 1.56e-01 1.03e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", + " 2 1.8637565e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 1.8238996e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 1.9065372e-01 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 1.8877820e-01 5.85e-01 4.73e+01 -1.0 3.46e+02 - 4.78e-01 8.92e-02f 2\n", + " 6 1.9396149e-01 1.37e-01 6.06e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 1.9308197e-01 4.34e-01 2.96e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 1.9352656e-01 3.83e-02 5.78e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 1.9350624e-01 5.45e-03 4.00e-03 -2.5 6.39e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 1.9332380e-01 5.30e-04 3.89e-04 -3.8 9.48e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 1.9023661e-01 2.26e-01 2.20e-02 -5.7 2.19e+01 - 7.86e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (320076)\n", + " 12 1.8556544e-01 9.45e-01 1.12e-02 -5.7 5.48e+01 - 8.73e-01 1.00e+00h 1\n", + " 13 1.8226712e-01 8.03e-01 2.46e-02 -5.7 3.25e+01 - 9.25e-01 1.00e+00h 1\n", + " 14 1.8304698e-01 1.11e-02 4.57e-04 -5.7 7.87e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 15 1.8301518e-01 6.34e-07 1.83e-07 -5.7 1.33e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 1.8246962e-01 4.04e-01 2.28e-02 -8.6 3.22e+02 - 2.45e-01 1.20e-01h 1\n", + " 17 1.8118955e-01 1.25e-01 3.47e-03 -8.6 2.99e+01 - 8.12e-01 1.00e+00h 1\n", + " 18 1.8143090e-01 1.83e-02 2.70e-04 -8.6 1.19e+01 - 9.83e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (352539)\n", + " 19 1.8142961e-01 2.51e-03 1.26e-05 -8.6 4.50e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 1.8142950e-01 4.81e-05 1.90e-07 -8.6 6.28e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 1.8142949e-01 1.74e-08 5.29e-11 -8.6 1.19e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 1.8142885e-01 1.72e-06 2.99e-08 -9.0 1.19e-01 - 1.00e+00 1.00e+00h 1\n", + " 23 1.8142885e-01 6.95e-11 1.80e-12 -9.0 7.55e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 23\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 1.8142884693002581e-01 1.8142884693002581e-01\n", + "Dual infeasibility......: 1.7962352785824499e-12 1.7962352785824499e-12\n", + "Constraint violation....: 6.9450334372334055e-11 6.9450334372334055e-11\n", + "Complementarity.........: 9.0909158006744088e-10 9.0909158006744088e-10\n", + "Overall NLP error.......: 9.0909158006744088e-10 9.0909158006744088e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 28\n", + "Number of objective gradient evaluations = 24\n", + "Number of equality constraint evaluations = 28\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 24\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 23\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.945\n", + "Total CPU secs in NLP function evaluations = 0.037\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.24e-03 5.30e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 1.74e-09 1.38e-06 -1.0 1.57e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.7354877535069591e-09 1.7354877535069591e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.7354877535069591e-09 1.7354877535069591e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.38e-03 2.66e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.14e-09 1.48e-06 -1.0 1.74e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1387873694322934e-09 2.1387873694322934e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1387873694322934e-09 2.1387873694322934e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.3 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.38e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 7.15e+02 3.85e+02 -1.0 1.38e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 8.08e+00 3.85e+00 -1.0 7.61e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 7.99e-02 4.39e+00 -1.0 8.56e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.46e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0367393568158150e-09 9.0367393568158150e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0367393568158150e-09 9.0367393568158150e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.3061258e+01 1.25e+00 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.3062155e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.07e-01h 1\n", + " 2 -1.3061413e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.3065245e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.3057918e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.3058931e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", + " 6 -1.3056038e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", + " 7 -1.3053256e+01 3.67e+00 5.37e-01 -1.0 5.25e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.3054459e+01 4.52e-01 7.98e-02 -1.0 1.11e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.3054459e+01 2.46e-04 1.14e-03 -1.7 3.85e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.3054484e+01 1.66e-04 7.18e-04 -3.8 2.99e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.3057381e+01 2.35e+00 2.21e-02 -5.7 3.43e+01 - 7.84e-01 1.00e+00h 1\n", + " 12 -1.3062042e+01 5.84e+00 1.46e-02 -5.7 7.86e+01 - 8.08e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (325047)\n", + " 13 -1.3064822e+01 4.69e+00 1.36e-02 -5.7 3.33e+01 - 9.76e-01 1.00e+00h 1\n", + " 14 -1.3064793e+01 4.33e+00 4.95e-02 -5.7 1.38e+01 -4.0 1.00e+00 7.55e-02h 1\n", + " 15 -1.3064825e+01 8.10e-01 1.55e-02 -5.7 3.27e+01 - 1.00e+00 1.00e+00h 1\n", + " 16 -1.3064750e+01 1.24e-03 1.35e-04 -5.7 4.92e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 17 -1.3065327e+01 1.32e+00 8.45e-03 -5.7 2.57e+01 - 1.00e+00 1.00e+00h 1\n", + " 18 -1.3065563e+01 3.66e-01 9.07e-04 -5.7 2.45e+01 - 1.00e+00 1.00e+00h 1\n", + " 19 -1.3065455e+01 8.75e-02 3.46e-04 -5.7 9.07e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.3065447e+01 1.22e-03 6.52e-06 -5.7 9.79e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.3065447e+01 1.73e-07 1.14e-09 -5.7 1.04e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 -1.3066047e+01 7.66e-01 1.47e-03 -8.6 2.73e+01 - 8.72e-01 9.48e-01h 1\n", + "Reallocating memory for MA57: lfact (349926)\n", + " 23 -1.3066091e+01 1.83e-02 2.59e-04 -8.6 1.18e+01 - 9.84e-01 1.00e+00h 1\n", + " 24 -1.3066096e+01 4.62e-03 6.34e-05 -8.6 6.08e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.3066097e+01 2.96e-04 4.89e-06 -8.6 1.55e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.3066097e+01 9.81e-07 2.99e-08 -8.6 8.97e-02 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.3066097e+01 2.05e-11 1.23e-12 -8.6 4.11e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.3066097364112752e+01 -1.3066097364112752e+01\n", + "Dual infeasibility......: 1.2294764961011457e-12 1.2294764961011457e-12\n", + "Constraint violation....: 2.0529578037553620e-11 2.0529578037553620e-11\n", + "Complementarity.........: 2.5059040443903054e-09 2.5059040443903054e-09\n", + "Overall NLP error.......: 2.5059040443903054e-09 2.5059040443903054e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 28\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 28\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.154\n", + "Total CPU secs in NLP function evaluations = 0.047\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.06e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.40e+00 3.85e+02 -1.0 6.00e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 4.99e-02 3.85e+00 -1.0 4.69e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.94e-04 4.39e+00 -1.0 5.30e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.24e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8342664033261826e-11 5.8342664033261826e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8342664033261826e-11 5.8342664033261826e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.145\n", + "Total CPU secs in NLP function evaluations = 0.007\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 9.2344539e-02 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 9.1795096e-02 1.56e-01 1.03e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", + " 2 9.2188972e-02 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 8.8412352e-02 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 9.6233482e-02 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 9.4461313e-02 5.85e-01 4.74e+01 -1.0 3.45e+02 - 4.78e-01 8.92e-02f 2\n", + " 6 9.9368726e-02 1.36e-01 6.08e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 9.8535727e-02 4.34e-01 2.97e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 9.8957264e-02 3.83e-02 5.78e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 9.8939356e-02 5.46e-03 4.02e-03 -2.5 6.39e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.8775901e-02 5.26e-04 3.62e-04 -3.8 1.01e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 9.5986597e-02 2.04e-01 2.11e-02 -5.7 2.08e+01 - 7.94e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319905)\n", + " 12 9.1498624e-02 9.64e-01 1.11e-02 -5.7 5.52e+01 - 8.77e-01 1.00e+00h 1\n", + " 13 8.8299544e-02 8.17e-01 2.37e-02 -5.7 3.28e+01 - 9.41e-01 1.00e+00h 1\n", + " 14 8.9059447e-02 1.11e-02 4.46e-04 -5.7 8.02e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 15 8.9028548e-02 6.44e-07 1.79e-07 -5.7 1.25e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 8.8442722e-02 4.14e-01 2.20e-02 -8.6 2.18e+02 - 3.15e-01 1.78e-01h 1\n", + " 17 8.7303204e-02 1.14e-01 2.94e-03 -8.6 2.87e+01 - 8.18e-01 1.00e+00h 1\n", + " 18 8.7506248e-02 1.77e-02 2.54e-04 -8.6 1.17e+01 - 9.86e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (349182)\n", + " 19 8.7505239e-02 2.49e-03 1.53e-05 -8.6 4.48e+00 - 1.00e+00 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (366797)\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 8.7505073e-02 5.20e-05 3.04e-07 -8.6 6.52e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 8.7505067e-02 2.17e-08 1.39e-10 -8.6 1.33e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 8.7504422e-02 1.91e-06 3.15e-08 -9.0 1.25e-01 - 1.00e+00 1.00e+00h 1\n", + " 23 8.7504422e-02 1.03e-12 3.41e-10 -9.0 9.20e-05 -5.4 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 23\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 8.7504422324047759e-02 8.7504422324047759e-02\n", + "Dual infeasibility......: 3.4067176250603508e-10 3.4067176250603508e-10\n", + "Constraint violation....: 1.0300649222472202e-12 1.0300649222472202e-12\n", + "Complementarity.........: 9.0912236625038064e-10 9.0912236625038064e-10\n", + "Overall NLP error.......: 9.0912236625038064e-10 9.0912236625038064e-10\n", + "\n", + "\n", + "Number of objective function evaluations = 28\n", + "Number of objective gradient evaluations = 24\n", + "Number of equality constraint evaluations = 28\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 24\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 23\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.014\n", + "Total CPU secs in NLP function evaluations = 0.041\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.7 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.23e-03 5.54e-01 -1.0 1.85e-01 - 9.91e-01 9.92e-01h 1\n", + " 4 0.0000000e+00 1.70e-09 1.37e-06 -1.0 1.55e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.7023418230621701e-09 1.7023418230621701e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.7023418230621701e-09 1.7023418230621701e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.118\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.4 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.37e-03 2.74e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", + " 4 0.0000000e+00 2.13e-09 1.47e-06 -1.0 1.73e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 2.1253634407969457e-09 2.1253634407969457e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 2.1253634407969457e-09 2.1253634407969457e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", + "Total CPU secs in NLP function evaluations = 0.005\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 1.46e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (298604)\n", + " 1 0.0000000e+00 7.22e+02 3.85e+02 -1.0 1.46e+04 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 8.15e+00 3.85e+00 -1.0 7.69e+02 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 8.06e-02 4.39e+00 -1.0 8.63e+00 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.54e-02 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", + "Total CPU secs in NLP function evaluations = 0.009\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 -1.3150611e+01 1.25e+00 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 -1.3151462e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.07e-01h 1\n", + " 2 -1.3150755e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", + " 3 -1.3154393e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", + " 4 -1.3147440e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", + " 5 -1.3148399e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", + " 6 -1.3145653e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", + " 7 -1.3143010e+01 3.67e+00 5.37e-01 -1.0 5.25e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 -1.3144153e+01 4.52e-01 8.00e-02 -1.0 1.11e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 -1.3144153e+01 2.47e-04 1.12e-03 -1.7 3.87e-01 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 -1.3144175e+01 1.50e-04 6.83e-04 -3.8 2.85e-01 - 1.00e+00 1.00e+00h 1\n", + " 11 -1.3144232e+01 1.07e-04 5.80e-05 -5.7 5.80e-01 -4.0 1.00e+00 1.00e+00h 1\n", + " 12 -1.3144447e+01 1.51e-03 7.27e-05 -5.7 2.18e+00 -4.5 1.00e+00 1.00e+00h 1\n", + " 13 -1.3144772e+01 4.00e-03 2.07e-04 -5.7 5.35e+00 -5.0 1.00e+00 6.14e-01h 1\n", + " 14 -1.3144770e+01 6.95e-04 3.62e-04 -5.7 1.73e-01 -5.4 1.00e+00 1.00e+00f 1\n", + " 15 -1.3144945e+01 6.78e-03 3.62e-05 -5.7 1.70e+00 -5.9 1.00e+00 1.00e+00h 1\n", + " 16 -1.3153640e+01 3.49e+01 9.15e-02 -5.7 2.83e+03 - 6.17e-02 6.37e-02h 1\n", + " 17 -1.3154824e+01 1.98e+01 3.84e-02 -5.7 8.27e+01 - 1.00e+00 5.97e-01f 1\n", + " 18 -1.3154428e+01 6.27e-01 2.75e-03 -5.7 1.22e+01 - 1.00e+00 1.00e+00f 1\n", + "Reallocating memory for MA57: lfact (319597)\n", + " 19 -1.3154555e+01 6.10e-02 9.67e-05 -5.7 8.95e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.3154553e+01 3.35e-04 1.10e-06 -5.7 5.85e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.3154553e+01 1.64e-08 9.42e-11 -5.7 3.56e-03 - 1.00e+00 1.00e+00h 1\n", + " 22 -1.3155149e+01 8.44e-01 1.54e-03 -8.6 2.87e+01 - 8.65e-01 9.44e-01h 1\n", + "Reallocating memory for MA57: lfact (350471)\n", + " 23 -1.3155196e+01 1.92e-02 2.59e-04 -8.6 1.21e+01 - 9.82e-01 1.00e+00h 1\n", + " 24 -1.3155201e+01 5.02e-03 6.53e-05 -8.6 6.33e+00 - 1.00e+00 1.00e+00h 1\n", + " 25 -1.3155202e+01 3.50e-04 5.41e-06 -8.6 1.69e+00 - 1.00e+00 1.00e+00h 1\n", + " 26 -1.3155202e+01 1.38e-06 3.84e-08 -8.6 1.06e-01 - 1.00e+00 1.00e+00h 1\n", + " 27 -1.3155202e+01 3.71e-11 2.10e-12 -8.6 5.52e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 27\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.3155202417249349e+01 -1.3155202417249349e+01\n", + "Dual infeasibility......: 2.0969252789257937e-12 2.0969252789257937e-12\n", + "Constraint violation....: 3.7140956976600137e-11 3.7140956976600137e-11\n", + "Complementarity.........: 2.5059043930329935e-09 2.5059043930329935e-09\n", + "Overall NLP error.......: 2.5059043930329935e-09 2.5059043930329935e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 34\n", + "Number of objective gradient evaluations = 28\n", + "Number of equality constraint evaluations = 34\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 28\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 27\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 1.008\n", + "Total CPU secs in NLP function evaluations = 0.042\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26094\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2590\n", + "\n", + "Total number of variables............................: 7086\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7086\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.40e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (299488)\n", + " 1 0.0000000e+00 4.43e+00 3.85e+02 -1.0 6.34e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 5.03e-02 3.85e+00 -1.0 4.73e+00 - 9.90e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 4.97e-04 4.39e+00 -1.0 5.33e-02 - 1.00e+00 9.90e-01h 1\n", + " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.27e-04 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 5.8342664033261826e-11 5.8342664033261826e-11\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 5.8342664033261826e-11 5.8342664033261826e-11\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.133\n", + "Total CPU secs in NLP function evaluations = 0.006\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 26208\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2610\n", + "\n", + "Reallocating memory for MA57: lfact (275736)\n", + "Total number of variables............................: 7106\n", + " variables with only lower bounds: 2316\n", + " variables with lower and upper bounds: 794\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 7096\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 2.9907566e-03 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (303702)\n", + " 1 2.4709143e-03 1.56e-01 1.03e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", + " 2 2.8475281e-03 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", + " 3 -7.4086018e-04 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", + " 4 6.6826430e-03 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", + " 5 5.0030420e-03 5.85e-01 4.74e+01 -1.0 3.45e+02 - 4.79e-01 8.93e-02f 2\n", + " 6 9.6602861e-03 1.37e-01 6.09e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", + " 7 8.8703660e-03 4.34e-01 2.96e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", + " 8 9.2713861e-03 3.83e-02 5.78e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", + " 9 9.2556032e-03 5.47e-03 4.05e-03 -2.5 6.40e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 10 9.1083712e-03 5.20e-04 3.49e-04 -3.8 1.06e+00 - 1.00e+00 1.00e+00h 1\n", + " 11 6.5758713e-03 1.85e-01 2.04e-02 -5.7 1.97e+01 - 8.02e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (319911)\n", + " 12 2.2595047e-03 9.80e-01 1.09e-02 -5.7 5.56e+01 - 8.79e-01 1.00e+00h 1\n", + " 13 -8.3311568e-04 8.21e-01 2.27e-02 -5.7 3.29e+01 - 9.59e-01 1.00e+00h 1\n", + " 14 -9.6435386e-05 1.08e-02 4.25e-04 -5.7 8.07e-01 -4.5 1.00e+00 1.00e+00h 1\n", + " 15 -1.2586985e-04 6.29e-07 1.66e-07 -5.7 1.19e-02 -5.0 1.00e+00 1.00e+00h 1\n", + " 16 -7.5509198e-04 4.26e-01 2.13e-02 -8.6 1.63e+02 - 3.64e-01 2.39e-01h 1\n", + " 17 -1.7704572e-03 1.04e-01 2.48e-03 -8.6 2.75e+01 - 8.25e-01 1.00e+00h 1\n", + " 18 -1.5994877e-03 1.71e-02 2.40e-04 -8.6 1.15e+01 - 9.87e-01 1.00e+00h 1\n", + "Reallocating memory for MA57: lfact (351858)\n", + " 19 -1.6003069e-03 2.49e-03 1.75e-05 -8.6 4.48e+00 - 1.00e+00 1.00e+00h 1\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 20 -1.6005224e-03 5.64e-05 4.27e-07 -8.6 6.79e-01 - 1.00e+00 1.00e+00h 1\n", + " 21 -1.6005305e-03 2.71e-08 2.85e-10 -8.6 1.49e-02 - 1.00e+00 1.00e+00h 1\n", + " 22 -1.6005305e-03 2.86e-13 2.91e-14 -8.6 7.06e-06 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 22\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: -1.6005305371233902e-03 -1.6005305371233902e-03\n", + "Dual infeasibility......: 2.9139664390433465e-14 2.9139664390433465e-14\n", + "Constraint violation....: 1.1865809618004581e-13 2.8599345114344032e-13\n", + "Complementarity.........: 2.5059035600370655e-09 2.5059035600370655e-09\n", + "Overall NLP error.......: 2.5059035600370655e-09 2.5059035600370655e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 27\n", + "Number of objective gradient evaluations = 23\n", + "Number of equality constraint evaluations = 27\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 23\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 22\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.929\n", + "Total CPU secs in NLP function evaluations = 0.041\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 2.8 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.22e-03 5.77e-01 -1.0 1.85e-01 - 9.91e-01 9.92e-01h 1\n", + " 4 0.0000000e+00 1.67e-09 1.36e-06 -1.0 1.54e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.6695191895621520e-09 1.6695191895621520e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.6695191895621520e-09 1.6695191895621520e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.104\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.2 seconds\n", + "Ipopt 3.13.2: linear_solver=ma57\n", + "halt_on_ampl_error=yes\n", + "max_iter=3000\n", + "\n", + "\n", + "******************************************************************************\n", + "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", + " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", + " For more information visit http://projects.coin-or.org/Ipopt\n", + "\n", + "This version of Ipopt was compiled from source code available at\n", + " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", + " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", + " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", + "\n", + "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", + " for large-scale scientific computation. All technical papers, sales and\n", + " publicity material resulting from use of the HSL codes within IPOPT must\n", + " contain the following acknowledgement:\n", + " HSL, a collection of Fortran codes for large-scale scientific\n", + " computation. See http://www.hsl.rl.ac.uk.\n", + "******************************************************************************\n", + "\n", + "This is Ipopt version 3.13.2, running with linear solver ma57.\n", + "\n", + "Number of nonzeros in equality constraint Jacobian...: 25344\n", + "Number of nonzeros in inequality constraint Jacobian.: 0\n", + "Number of nonzeros in Lagrangian Hessian.............: 2320\n", + "\n", + "Total number of variables............................: 6968\n", + " variables with only lower bounds: 2312\n", + " variables with lower and upper bounds: 784\n", + " variables with only upper bounds: 0\n", + "Total number of equality constraints.................: 6968\n", + "Total number of inequality constraints...............: 0\n", + " inequality constraints with only lower bounds: 0\n", + " inequality constraints with lower and upper bounds: 0\n", + " inequality constraints with only upper bounds: 0\n", + "\n", + "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", + " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", + "Reallocating memory for MA57: lfact (239448)\n", + " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", + " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", + " 3 0.0000000e+00 1.22e-03 5.77e-01 -1.0 1.85e-01 - 9.91e-01 9.92e-01h 1\n", + " 4 0.0000000e+00 1.67e-09 1.36e-06 -1.0 1.54e-03 - 1.00e+00 1.00e+00h 1\n", + "\n", + "Number of Iterations....: 4\n", + "\n", + " (scaled) (unscaled)\n", + "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Constraint violation....: 1.6694885474066723e-09 1.6694885474066723e-09\n", + "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", + "Overall NLP error.......: 1.6694885474066723e-09 1.6694885474066723e-09\n", + "\n", + "\n", + "Number of objective function evaluations = 5\n", + "Number of objective gradient evaluations = 5\n", + "Number of equality constraint evaluations = 5\n", + "Number of inequality constraint evaluations = 0\n", + "Number of equality constraint Jacobian evaluations = 5\n", + "Number of inequality constraint Jacobian evaluations = 0\n", + "Number of Lagrangian Hessian evaluations = 4\n", + "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", + "Total CPU secs in NLP function evaluations = 0.004\n", + "\n", + "EXIT: Optimal Solution Found.\n", + "INFO: elapsed time: 1.1 seconds\n" + ] + } + ], + "source": [ + "D_sc = []\n", + "D_sc_2 = []\n", + "D_unsc = []\n", + "D_unsc_2 = []\n", + "exp_conds_sc = []\n", + "exp_conds_unsc = []\n", + "FIM_opt_sc = []\n", + "FIM_opt_sc_2 = []\n", + "FIM_opt_unsc = []\n", + "FIM_opt_unsc_2 = []\n", + "jac_opt_sc = []\n", + "jac_opt_sc_2 = []\n", + "jac_opt_unsc = []\n", + "jac_opt_unsc_2 = []\n", + "standard_Ca = 5\n", + "standard_T = [300, 300, 300, 300, 300, 300, 300, 300, 300, ]\n", + "\n", + "FIM_new = None\n", + "FIM_new_unsc = None\n", + "\n", + "FIM_running = np.zeros((4, 4))\n", + "FIM_running_unsc = np.zeros((4, 4))\n", + "\n", + "for i in range(20):\n", + " # Optimize experiment (scaled)\n", + " sc_res = run_optimal_exp(standard_Ca, standard_T, FIM_new, True)\n", + " # sc_res.result_analysis()\n", + " sc_exp = get_exp_conds(sc_res.model)\n", + " FIM_new = sc_res.FIM\n", + "\n", + " # Optimize experiment (unscaled)\n", + " unsc_res = run_optimal_exp(standard_Ca, standard_T, FIM_new_unsc, False)\n", + " # unsc_res.result_analysis()\n", + " unsc_exp = get_exp_conds(unsc_res.model)\n", + " FIM_new_unsc = unsc_res.FIM\n", + "\n", + " # Compute FIM in isolation (scaled)\n", + " res_sc = compute_specific_FIM(sc_exp[0], sc_exp[1:], prior_FIM=None, scale_param=True)\n", + "\n", + " # Compute FIM in isolation (unscaled)\n", + " res_unsc = compute_specific_FIM(unsc_exp[0], unsc_exp[1:], prior_FIM=None, scale_param=False)\n", + "\n", + " # Computing running isolation FIM\n", + " FIM_running += res_sc.FIM\n", + " FIM_running_unsc += res_unsc.FIM\n", + "\n", + " # Compute objectives (D-optimality)\n", + " D_sc.append(np.log10(np.linalg.det(sc_res.FIM)))\n", + " D_sc_2.append(np.log10(np.linalg.det(FIM_running)))\n", + " D_unsc.append(np.log10(np.linalg.det(unsc_res.FIM)))\n", + " D_unsc_2.append(np.log10(np.linalg.det(FIM_running_unsc)))\n", + "\n", + " # Append experimental results\n", + " exp_conds_sc.append(sc_exp)\n", + " exp_conds_unsc.append(unsc_exp)\n", + "\n", + " # Append FIM information\n", + " FIM_opt_sc.append(FIM_new)\n", + " FIM_opt_sc_2.append(copy.deepcopy(FIM_running))\n", + " FIM_opt_unsc.append(FIM_new_unsc)\n", + " FIM_opt_unsc_2.append(copy.deepcopy(FIM_running_unsc))\n", + "\n", + " # Append jacobian information\n", + " jac_opt_sc.append(translate_jac(sc_res.jaco_information))\n", + " jac_opt_sc_2.append(translate_jac(res_sc.jaco_information))\n", + " jac_opt_unsc.append(translate_jac(unsc_res.jaco_information))\n", + " jac_opt_unsc_2.append(translate_jac(res_unsc.jaco_information))" + ] + }, + { + "cell_type": "markdown", + "id": "17763935-a215-4020-a6b4-9b4425bec1f2", + "metadata": {}, + "source": [ + "## Plotting the results" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "4d9a37ac-1d7e-452a-ad55-e87191ff7d5c", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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woQJ7N69m59//plRo0axbNky+vfvzxtvvMEnn3zCM888Q2xsLFqtFr1eT7169fj111/x8PBg+/btvPDCC/j6+vL444+X+HrLlVJJYmJilOeee04JCgpS7O3tlfr16ytvv/22kpOTU+hxnTp1UgCTZeTIkSU6d0pKigIoKSkppbkEIYSoNFlZWcrx48eVrKwsw4a8dEX5kcpZ8tKLHXenTp2UsWPHFti+YMECxcXFxbg+dOhQJTAwUMnPzzduGzhwoDJo0CBFURTl999/V5ydnZXU1NQCdaWmpip2dnbKt99+W+y4PvzwQ6V169bG9SlTpijh4eHG9QYNGiiLFy82OWb69OlKZGSkoiiK8s033ygeHh63Pg9FUb766isFUA4cOFDsONq3b6+MGDHCZNvAgQOVBx980LgOKC+++KJJmYiICGXUqFGKohi+X82dd+jQoUrfvn2N6506dVLuv/9+43p+fr7i4OCgPPPMM8ZtcXFxCqDs2LHDYswvvfSSMmDAAIvnKakCv9u3Kcn3d6W14Jw4cQK9Xs8333xDw4YNOXr0KCNGjCAjI4PZs2cXeuyIESN45513jOtarba8wxVCCFHBmjVrhpWVlXHd19eXI0eOANCjRw8CAwOpX78+vXr1olevXvTv3x+tVktUVBQ5OTl069bNYt0///wzn376KdHR0aSnp5Ofn4+zs7PZshkZGURHRzN8+HBGjBhh3J6fn2/s1xIVFUVYWBj29vbG/ZGRkSW+5qioKF544QWTbffdd1+B20B31h0ZGXlXT2uFhYUZX1tZWeHh4UHz5s2N27y9vQFISEgwbvviiy+YP38+sbGxZGVlkZubW+onzspDpSU4N38hb6pfvz4nT57kq6++KjLB0Wq1+Pj4lHeIQghRfVhp4fH0yjt3MTk7O5OSklJge3JycoFOsDY2NibrKpUKvV4PGG4x7d+/n82bN/PXX3/x9ttvM3XqVPbs2YNGoyk0hh07dvDUU08xbdo0evbsiYuLC0uWLOGjjz4yWz493fC+fvvtt0RERJjsuz0Bq47Mvce3b1PduPV4831fsmQJr776Kh999BGRkZE4OTnx4YcfsmvXrooLupiqVCfjlJQU3N3diyz3448/4unpyT333MOkSZPIzCz8vnNOTg6pqakmixBC1CgqFVg7VM5Sgv43ISEh7N+/v8D2/fv307hx4xJd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/MLUqVN5//332bt3L76+vnz5ZeFJ4KVLl3jwwQdp27Ythw4d4quvvmLevHm8++67JuW+++47rK2t2b17N3PnzuXjjz/m//7v/wBYunQp9erV45133iEuLo64uDiL54uOjmbNmjWsXbuWn376iXnz5tGnTx8uXrzIli1b+OCDD3jrrbeMiSCAWq3m008/5dixY3z33Xf8/fffTJgwodDrqkrkFpUQQogKtXLlShwdHcnPzycnJwe1Ws3nn38OQE5ODu+//z4bNmwgMjISgPr16/Pvv//yzTff0KlTJ2JjY2nZsiVt2rQBDP1Qblq8eDFXr15lz549uLu7A9CwYUPj/vDwcMLDw43r06dPZ9myZaxYsYLRo0cXiPXff/9l9+7dJCQkYGdnB8Ds2bNZvnw5v/32Gy+88AJz5sxh+PDhDB8+HIB3332XDRs2FNqK8+WXX+Lv78/nn3+OSqWiSZMmXL58mYkTJ/L222+jVhvaH/z9/fnkk09QqVSEhIRw5MgRPvnkE0aMGIG7uztWVlY4OTnh4+NT6Huu1+uZP38+Tk5ONG3alC5dunDy5ElWr16NWq0mJCSEDz74gE2bNhEREQHAuHHjjMcHBQXx7rvv8uKLLxaZvFUVkuAIIYSoUF26dOGrr74iIyODTz75BGtrawYMGADAmTNnyMzMpEePHibH5Obm0rJlSwBGjRrFgAED2L9/Pw888AD9+vWjffv2ABw8eJCWLVsak5s7paenM3XqVFatWkVcXBz5+flkZWVZbME5dOgQ6enpeHh4mGzPysoiOjoagKioKF588UWT/ZGRkWzatMniexAVFUVkZKTxthLAfffdR3p6OhcvXiQgIACAe++916RMZGQkH330ETqdDisrK4v13ykoKAgnJyfjure3N1ZWVsZE6ua2hIQE4/qGDRuYMWMGJ06cIDU1lfz8fLKzs8nMzESr1Rb73JVFEhwhhBAVysHBwdiqMn/+fMLDw5k3bx7Dhw839vFYtWoVdevWNTnuZgtK7969OX/+PKtXr2b9+vV069aNl156idmzZxfZufbVV19l/fr1zJ49m4YNG6LRaHjsscfIzc01Wz49PR1fX182b95cYF9VfkT6TjY2NibrN59iu3PbzVt5586d46GHHmLUqFG89957uLu78++//zJ8+HByc3OrRYIjfXCEEEJUGrVazRtvvMFbb71F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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Rescaling the scaled results\n", + "D_rescaled = []\n", + "param_vals = np.array([[85, 370, 8, 15], ])\n", + "for i in range(20):\n", + " resc_FIM = rescale_FIM(FIM_opt_sc_2[i], param_vals)\n", + " D_rescaled.append(np.log10(np.linalg.det(resc_FIM)))\n", + "\n", + "plt.plot(range(20), D_sc, color='green', ls='-', label='Scaled, optimal')\n", + "plt.scatter(range(20), D_sc_2, color='green', label='Scaled, compute')\n", + "plt.plot(range(20), D_unsc, color='orange', ls='-', label='Unscaled, optimal')\n", + "plt.scatter(range(20), D_unsc_2, color='orange', ls='--', label='Unscaled, compute')\n", + "plt.plot(range(20), D_rescaled, color='purple', ls=':', lw=5, label='Rescaled optimal')\n", + "\n", + "plt.legend()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py b/pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py new file mode 100644 index 00000000000..719983069f0 --- /dev/null +++ b/pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py @@ -0,0 +1,180 @@ +# ___________________________________________________________________________ +# +# 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. +# +# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation +# Initiative (CCSI), and is copyright (c) 2022 by the software owners: +# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., +# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, +# Battelle Memorial Institute, University of Notre Dame, +# The University of Pittsburgh, The University of Texas at Austin, +# University of Toledo, West Virginia University, et al. All rights reserved. +# +# NOTICE. This Software was developed under funding from the +# U.S. Department of Energy and the U.S. Government consequently retains +# certain rights. As such, the U.S. Government has been granted for itself +# and others acting on its behalf a paid-up, nonexclusive, irrevocable, +# worldwide license in the Software to reproduce, distribute copies to the +# public, prepare derivative works, and perform publicly and display +# publicly, and to permit other to do so. +# ___________________________________________________________________________ + +from pyomo.common.dependencies import numpy as np +from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure +from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables +import pyomo.environ as aml + +def get_exp_results(m): + vals = [aml.value(m.CA0[0]), ] + for i in [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]: + vals.append(aml.value(m.T[i])) + return vals + + +def get_FIM_from_exp(CA_0=None, T_0=None, prior=None): + if CA_0 is None: + CA_0 = 5 + if T_0 is None: + T_0 = [570, 300, 300, 300, 300, 300, 300, 300, 300] + ### Define inputs + # Control time set [h] + t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] + # Define parameter nominal value + parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} + + # measurement object + measurements = MeasurementVariables() + measurements.add_variables( + "C", # name of measurement + indices={0: ["CA", "CB", "CC"], 1: t_control}, # indices of measurement + time_index_position=1, + ) # position of time index + + # design object + exp_design = DesignVariables() + + # add CAO as design variable + exp_design.add_variables( + "CA0", # name of design variable + indices={0: [0]}, # indices of design variable + time_index_position=0, # position of time index + values=[CA_0], # nominal value of design variable + lower_bounds=1, # lower bound of design variable + upper_bounds=5, # upper bound of design variable + ) + + # add T as design variable + exp_design.add_variables( + "T", # name of design variable + indices={0: t_control}, # indices of design variable + time_index_position=0, # position of time index + values=list(T_0), # nominal value of design variable + lower_bounds=300, # lower bound of design variable + upper_bounds=700, # upper bound of design variable + ) + + doe_object2 = DesignOfExperiments( + parameter_dict, # dictionary of parameters + exp_design, # design variables + measurements, # measurement variables + create_model, # function to create model + prior_FIM=prior, + discretize_model=disc_for_measure, # function to discretize model + ) + + result = doe_object2.compute_FIM( + mode='sequential_finite', + formula = 'central', + ) + + result.result_analysis() + + return result.FIM + + +def main(CA_0=None, T_0=None, prior=None): + if CA_0 is None: + CA_0 = 5 + if T_0 is None: + T_0 = [570, 300, 300, 300, 300, 300, 300, 300, 300] + ### Define inputs + # Control time set [h] + t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] + # Define parameter nominal value + parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} + + # measurement object + measurements = MeasurementVariables() + measurements.add_variables( + "C", # name of measurement + indices={0: ["CA", "CB", "CC"], 1: t_control}, # indices of measurement + time_index_position=1, + ) # position of time index + + # design object + exp_design = DesignVariables() + + # add CAO as design variable + exp_design.add_variables( + "CA0", # name of design variable + indices={0: [0]}, # indices of design variable + time_index_position=0, # position of time index + values=[CA_0], # nominal value of design variable + lower_bounds=1, # lower bound of design variable + upper_bounds=5, # upper bound of design variable + ) + + # add T as design variable + exp_design.add_variables( + "T", # name of design variable + indices={0: t_control}, # indices of design variable + time_index_position=0, # position of time index + values=list(T_0), # nominal value of design variable + lower_bounds=300, # lower bound of design variable + upper_bounds=700, # upper bound of design variable + ) + + design_names = exp_design.variable_names + # exp1 = [5, 570, 300, 300, 300, 300, 300, 300, 300, 300] + # exp1_design_dict = dict(zip(design_names, exp1)) + # exp_design.update_values(exp1_design_dict) + + # add a prior information (scaled FIM with T=500 and T=300 experiments) + if prior is None: + prior = np.asarray( + [ + [28.67892806, 5.41249739, -81.73674601, -24.02377324], + [5.41249739, 26.40935036, -12.41816477, -139.23992532], + [-81.73674601, -12.41816477, 240.46276004, 58.76422806], + [-24.02377324, -139.23992532, 58.76422806, 767.25584508], + ] + ) + + doe_object2 = DesignOfExperiments( + parameter_dict, # dictionary of parameters + exp_design, # design variables + measurements, # measurement variables + create_model, # function to create model + prior_FIM=prior, # prior information + discretize_model=disc_for_measure, # function to discretize model + ) + + square_result, optimize_result = doe_object2.stochastic_program( + if_optimize=True, # if optimize + if_Cholesky=True, # if use Cholesky decomposition + # scale_nominal_param_value=True, # if scale nominal parameter value + objective_option="det", # objective option + L_initial=np.linalg.cholesky(prior), # initial Cholesky decomposition + ) + + return prior, optimize_result, square_result + + +if __name__ == "__main__": + main() diff --git a/pyomo/contrib/doe/result.py b/pyomo/contrib/doe/result.py deleted file mode 100644 index f7145ae2a46..00000000000 --- a/pyomo/contrib/doe/result.py +++ /dev/null @@ -1,758 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -from pyomo.common.dependencies import numpy as np, pandas as pd, matplotlib as plt -from pyomo.core.expr.numvalue import value - -from itertools import product -import logging -from pyomo.opt import SolverStatus, TerminationCondition - - -class FisherResults: - def __init__( - self, - parameter_names, - measurements, - jacobian_info=None, - all_jacobian_info=None, - prior_FIM=None, - store_FIM=None, - scale_constant_value=1, - max_condition_number=1.0e12, - ): - """Analyze the FIM result for a single run - - Parameters - ---------- - parameter_names: - A ``list`` of parameter names - measurements: - A ``MeasurementVariables`` which contains the Pyomo variable names and their corresponding indices and - bounds for experimental measurements - jacobian_info: - the jacobian for this measurement object - all_jacobian_info: - the overall jacobian - prior_FIM: - if there's prior FIM to be added - store_FIM: - if storing the FIM in a .csv or .txt, give the file name here as a string - scale_constant_value: - scale all elements in Jacobian matrix, default is 1. - max_condition_number: - max condition number - """ - self.parameter_names = parameter_names - self.measurements = measurements - self.measurement_variables = measurements.variable_names - - if jacobian_info is None: - self.jaco_information = all_jacobian_info - else: - self.jaco_information = jacobian_info - self.all_jacobian_info = all_jacobian_info - - self.prior_FIM = prior_FIM - self.store_FIM = store_FIM - self.scale_constant_value = scale_constant_value - self.fim_scale_constant_value = scale_constant_value**2 - self.max_condition_number = max_condition_number - self.logger = logging.getLogger(__name__) - self.logger.setLevel(level=logging.WARN) - - def result_analysis(self, result=None): - """Calculate FIM from Jacobian information. This is for grid search (combined models) results - - Parameters - ---------- - result: - solver status returned by IPOPT - """ - self.result = result - self.doe_result = None - - # get number of parameters - no_param = len(self.parameter_names) - - fim = np.zeros((no_param, no_param)) - - # convert dictionary to a numpy array - Q_all = [] - for par in self.parameter_names: - Q_all.append(self.jaco_information[par]) - n = len(self.parameter_names) - - Q_all = np.array(list(self.jaco_information[p] for p in self.parameter_names)).T - # add the FIM for each measurement variables together - for i, mea_name in enumerate(self.measurement_variables): - fim += ( - 1 - / self.measurements.variance[str(mea_name)] # variance of measurement - * ( - Q_all[i, :].reshape(n, 1) @ Q_all[i, :].reshape(n, 1).T - ) # Q.T @ Q for each measurement variable - ) - - # add prior information - if self.prior_FIM is not None: - try: - fim = fim + self.prior_FIM - self.logger.info("Existed information has been added.") - except: - raise ValueError("Check the shape of prior FIM.") - - if np.linalg.cond(fim) > self.max_condition_number: - self.logger.info( - "Warning: FIM is near singular. The condition number is: %s ;", - np.linalg.cond(fim), - ) - self.logger.info( - "A condition number bigger than %s is considered near singular.", - self.max_condition_number, - ) - - # call private methods - self._print_FIM_info(fim) - if self.result is not None: - self._get_solver_info() - - # if given store file name, store the FIM - if self.store_FIM is not None: - self._store_FIM() - - def subset(self, measurement_subset): - """Create new FisherResults object corresponding to provided measurement_subset. - This requires that measurement_subset is a true subset of the original measurement object. - - Parameters - ---------- - measurement_subset: Instance of Measurements class - - Returns - ------- - new_result: New instance of FisherResults - """ - - # Check that measurement_subset is a valid subset of self.measurement - self.measurements.check_subset(measurement_subset) - - # Split Jacobian (should already be 3D) - small_jac = self._split_jacobian(measurement_subset) - - # create a new subject - FIM_subset = FisherResults( - self.parameter_names, - measurement_subset, - jacobian_info=small_jac, - prior_FIM=self.prior_FIM, - store_FIM=self.store_FIM, - scale_constant_value=self.scale_constant_value, - max_condition_number=self.max_condition_number, - ) - - return FIM_subset - - def _split_jacobian(self, measurement_subset): - """ - Split jacobian - - Parameters - ---------- - measurement_subset: the object of the measurement subsets - - Returns - ------- - jaco_info: split Jacobian - """ - # create a dict for FIM. It has the same keys as the Jacobian dict. - jaco_info = {} - - # reorganize the jacobian subset with the same form of the jacobian - # loop over parameters - for par in self.parameter_names: - jaco_info[par] = [] - # loop over measurements - for name in measurement_subset.variable_names: - try: - n_all_measure = self.measurement_variables.index(name) - jaco_info[par].append(self.all_jacobian_info[par][n_all_measure]) - except: - raise ValueError( - "Measurement ", name, " is not in original measurement set." - ) - - return jaco_info - - def _print_FIM_info(self, FIM): - """ - using a dictionary to store all FIM information - - Parameters - ---------- - FIM: the Fisher Information Matrix, needs to be P.D. and symmetric - - Returns - ------- - fim_info: a FIM dictionary containing the following key:value pairs - ~['FIM']: a list of FIM itself - ~[design variable name]: a list of design variable values at each time point - ~['Trace']: a scalar number of Trace - ~['Determinant']: a scalar number of determinant - ~['Condition number:']: a scalar number of condition number - ~['Minimal eigen value:']: a scalar number of minimal eigen value - ~['Eigen values:']: a list of all eigen values - ~['Eigen vectors:']: a list of all eigen vectors - """ - eig = np.linalg.eigvals(FIM) - self.FIM = FIM - self.trace = np.trace(FIM) - self.det = np.linalg.det(FIM) - self.min_eig = min(eig) - self.cond = max(eig) / min(eig) - self.eig_vals = eig - self.eig_vecs = np.linalg.eig(FIM)[1] - - self.logger.info( - "FIM: %s; \n Trace: %s; \n Determinant: %s;", self.FIM, self.trace, self.det - ) - self.logger.info( - "Condition number: %s; \n Min eigenvalue: %s.", self.cond, self.min_eig - ) - - def _solution_info(self, m, dv_set): - """ - Solution information. Only for optimization problem - - Parameters - ---------- - m: model - dv_set: design variable dictionary - - Returns - ------- - model_info: model solutions dictionary containing the following key:value pairs - -['obj']: a scalar number of objective function value - -['det']: a scalar number of determinant calculated by the model (different from FIM_info['det'] which - is calculated by numpy) - -['trace']: a scalar number of trace calculated by the model - -[design variable name]: a list of design variable solution - """ - self.obj_value = value(m.obj) - - # When scaled with constant values, the effect of the scaling factors are removed here - # For determinant, the scaling factor to determinant is scaling factor ** (Dim of FIM) - # For trace, the scaling factor to trace is the scaling factor. - if self.obj == "det": - self.obj_det = np.exp(value(m.obj)) / (self.fim_scale_constant_value) ** ( - len(self.parameter_names) - ) - elif self.obj == "trace": - self.obj_trace = np.exp(value(m.obj)) / (self.fim_scale_constant_value) - - design_variable_names = list(dv_set.keys()) - dv_times = list(dv_set.values()) - - solution = {} - for d, dname in enumerate(design_variable_names): - sol = [] - if dv_times[d] is not None: - for t, time in enumerate(dv_times[d]): - newvar = getattr(m, dname)[time] - sol.append(value(newvar)) - else: - newvar = getattr(m, dname) - sol.append(value(newvar)) - - solution[dname] = sol - self.solution = solution - - def _store_FIM(self): - # if given store file name, store the FIM - store_dict = {} - for i, name in enumerate(self.parameter_names): - store_dict[name] = self.FIM[i] - FIM_store = pd.DataFrame(store_dict) - FIM_store.to_csv(self.store_FIM, index=False) - - def _get_solver_info(self): - """ - Solver information dictionary - - Return: - ------ - solver_status: a solver information dictionary containing the following key:value pairs - -['square']: a string of square result solver status - -['doe']: a string of doe result solver status - """ - - if (self.result.solver.status == SolverStatus.ok) and ( - self.result.solver.termination_condition == TerminationCondition.optimal - ): - self.status = "converged" - elif ( - self.result.solver.termination_condition == TerminationCondition.infeasible - ): - self.status = "infeasible" - else: - self.status = self.result.solver.status - - -class GridSearchResult: - def __init__( - self, - design_ranges, - design_dimension_names, - FIM_result_list, - store_optimality_name=None, - ): - """ - This class deals with the FIM results from grid search, providing A, D, E, ME-criteria results for each design variable. - Can choose to draw 1D sensitivity curves and 2D heatmaps. - - Parameters - ---------- - design_ranges: - a ``dict`` whose keys are design variable names, values are a list of design variable values to go over - design_dimension_names: - a ``list`` of design variables names - FIM_result_list: - a ``dict`` containing FIM results, keys are a tuple of design variable values, values are FIM result objects - store_optimality_name: - a .csv file name containing all four optimalities value - """ - # design variables - self.design_names = design_dimension_names - self.design_ranges = design_ranges - self.FIM_result_list = FIM_result_list - - self.store_optimality_name = store_optimality_name - - def extract_criteria(self): - """ - Extract design criteria values for every 'grid' (design variable combination) searched. - - Returns - ------- - self.store_all_results_dataframe: a pandas dataframe with columns as design variable names and A, D, E, ME-criteria names. - Each row contains the design variable value for this 'grid', and the 4 design criteria value for this 'grid'. - """ - - # a list store all results - store_all_results = [] - - # generate combinations of design variable values to go over - search_design_set = product(*self.design_ranges) - - # loop over deign value combinations - for design_set_iter in search_design_set: - # locate this grid in the dictionary of combined results - result_object_asdict = { - k: v for k, v in self.FIM_result_list.items() if k == design_set_iter - } - # an result object is identified by a tuple of the design variable value it uses - result_object_iter = result_object_asdict[design_set_iter] - - # store results as a row in the dataframe - store_iteration_result = list(design_set_iter) - store_iteration_result.append(result_object_iter.trace) - store_iteration_result.append(result_object_iter.det) - store_iteration_result.append(result_object_iter.min_eig) - store_iteration_result.append(result_object_iter.cond) - - # add this row to the dataframe - store_all_results.append(store_iteration_result) - - # generate column names for the dataframe - column_names = [] - # this count is for repeated design variable names which can happen in dynamic problems - for i in self.design_names: - # if design variables share the same value, use the first name as the column name - if type(i) is list: - column_names.append(i[0]) - else: - column_names.append(i) - - # Each design criteria has a column to store values - column_names.append("A") - column_names.append("D") - column_names.append("E") - column_names.append("ME") - # generate the dataframe - store_all_results = np.asarray(store_all_results) - self.store_all_results_dataframe = pd.DataFrame( - store_all_results, columns=column_names - ) - # if needs to store the values - if self.store_optimality_name is not None: - self.store_all_results_dataframe.to_csv( - self.store_optimality_name, index=False - ) - - def figure_drawing( - self, - fixed_design_dimensions, - sensitivity_dimension, - title_text, - xlabel_text, - ylabel_text, - font_axes=16, - font_tick=14, - log_scale=True, - ): - """ - Extract results needed for drawing figures from the overall result dataframe. - Draw 1D sensitivity curve or 2D heatmap. - It can be applied to results of any dimensions, but requires design variable values in other dimensions be fixed. - - Parameters - ---------- - fixed_design_dimensions: a dictionary, keys are the design variable names to be fixed, values are the value of it to be fixed. - sensitivity_dimension: a list of design variable names to draw figures. - If only one name is given, a 1D sensitivity curve is drawn - if two names are given, a 2D heatmap is drawn. - title_text: name of the figure, a string - xlabel_text: x label title, a string. - In a 1D sensitivity curve, it is the design variable by which the curve is drawn. - In a 2D heatmap, it should be the second design variable in the design_ranges - ylabel_text: y label title, a string. - A 1D sensitivity curve does not need it. In a 2D heatmap, it should be the first design variable in the dv_ranges - font_axes: axes label font size - font_tick: tick label font size - log_scale: if True, the result matrix will be scaled by log10 - - Returns - -------- - None - """ - self.fixed_design_names = list(fixed_design_dimensions.keys()) - self.fixed_design_values = list(fixed_design_dimensions.values()) - self.sensitivity_dimension = sensitivity_dimension - - if len(self.fixed_design_names) + len(self.sensitivity_dimension) != len( - self.design_names - ): - raise ValueError( - "Error: All dimensions except for those the figures are drawn by should be fixed." - ) - - if len(self.sensitivity_dimension) not in [1, 2]: - raise ValueError("Error: Either 1D or 2D figures can be drawn.") - - # generate a combination of logic sentences to filter the results of the DOF needed. - # an example filter: (self.store_all_results_dataframe["CA0"]==5). - if len(self.fixed_design_names) != 0: - filter = "" - for i in range(len(self.fixed_design_names)): - filter += "(self.store_all_results_dataframe[" - filter += str(self.fixed_design_names[i]) - filter += "]==" - filter += str(self.fixed_design_values[i]) - filter += ")" - if i != (len(self.fixed_design_names) - 1): - filter += "&" - # extract results with other dimensions fixed - figure_result_data = self.store_all_results_dataframe.loc[eval(filter)] - # if there is no other fixed dimensions - else: - figure_result_data = self.store_all_results_dataframe - - # add results for figures - self.figure_result_data = figure_result_data - - # if one design variable name is given as DOF, draw 1D sensitivity curve - if len(sensitivity_dimension) == 1: - self._curve1D( - title_text, xlabel_text, font_axes=16, font_tick=14, log_scale=True - ) - # if two design variable names are given as DOF, draw 2D heatmaps - elif len(sensitivity_dimension) == 2: - self._heatmap( - title_text, - xlabel_text, - ylabel_text, - font_axes=16, - font_tick=14, - log_scale=True, - ) - - def _curve1D( - self, title_text, xlabel_text, font_axes=16, font_tick=14, log_scale=True - ): - """ - Draw 1D sensitivity curves for all design criteria - - Parameters - ---------- - title_text: name of the figure, a string - xlabel_text: x label title, a string. - In a 1D sensitivity curve, it is the design variable by which the curve is drawn. - font_axes: axes label font size - font_tick: tick label font size - log_scale: if True, the result matrix will be scaled by log10 - - Returns - -------- - 4 Figures of 1D sensitivity curves for each criteria - """ - - # extract the range of the DOF design variable - x_range = self.figure_result_data[self.sensitivity_dimension[0]].values.tolist() - - # decide if the results are log scaled - if log_scale: - y_range_A = np.log10(self.figure_result_data["A"].values.tolist()) - y_range_D = np.log10(self.figure_result_data["D"].values.tolist()) - y_range_E = np.log10(self.figure_result_data["E"].values.tolist()) - y_range_ME = np.log10(self.figure_result_data["ME"].values.tolist()) - else: - y_range_A = self.figure_result_data["A"].values.tolist() - y_range_D = self.figure_result_data["D"].values.tolist() - y_range_E = self.figure_result_data["E"].values.tolist() - y_range_ME = self.figure_result_data["ME"].values.tolist() - - # Draw A-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - # plt.rcParams.update(params) - ax.plot(x_range, y_range_A) - ax.scatter(x_range, y_range_A) - ax.set_ylabel("$log_{10}$ Trace") - ax.set_xlabel(xlabel_text) - plt.pyplot.title(title_text + ": A-optimality") - plt.pyplot.show() - - # Draw D-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - # plt.rcParams.update(params) - ax.plot(x_range, y_range_D) - ax.scatter(x_range, y_range_D) - ax.set_ylabel("$log_{10}$ Determinant") - ax.set_xlabel(xlabel_text) - plt.pyplot.title(title_text + ": D-optimality") - plt.pyplot.show() - - # Draw E-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - # plt.rcParams.update(params) - ax.plot(x_range, y_range_E) - ax.scatter(x_range, y_range_E) - ax.set_ylabel("$log_{10}$ Minimal eigenvalue") - ax.set_xlabel(xlabel_text) - plt.pyplot.title(title_text + ": E-optimality") - plt.pyplot.show() - - # Draw Modified E-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - # plt.rcParams.update(params) - ax.plot(x_range, y_range_ME) - ax.scatter(x_range, y_range_ME) - ax.set_ylabel("$log_{10}$ Condition number") - ax.set_xlabel(xlabel_text) - plt.pyplot.title(title_text + ": Modified E-optimality") - plt.pyplot.show() - - def _heatmap( - self, - title_text, - xlabel_text, - ylabel_text, - font_axes=16, - font_tick=14, - log_scale=True, - ): - """ - Draw 2D heatmaps for all design criteria - - Parameters - ---------- - title_text: name of the figure, a string - xlabel_text: x label title, a string. - In a 2D heatmap, it should be the second design variable in the design_ranges - ylabel_text: y label title, a string. - In a 2D heatmap, it should be the first design variable in the dv_ranges - font_axes: axes label font size - font_tick: tick label font size - log_scale: if True, the result matrix will be scaled by log10 - - Returns - -------- - 4 Figures of 2D heatmap for each criteria - """ - - # achieve the design variable ranges this figure needs - # create a dictionary for sensitivity dimensions - sensitivity_dict = {} - for i, name in enumerate(self.design_names): - if name in self.sensitivity_dimension: - sensitivity_dict[name] = self.design_ranges[i] - elif name[0] in self.sensitivity_dimension: - sensitivity_dict[name[0]] = self.design_ranges[i] - - x_range = sensitivity_dict[self.sensitivity_dimension[0]] - y_range = sensitivity_dict[self.sensitivity_dimension[1]] - - # extract the design criteria values - A_range = self.figure_result_data["A"].values.tolist() - D_range = self.figure_result_data["D"].values.tolist() - E_range = self.figure_result_data["E"].values.tolist() - ME_range = self.figure_result_data["ME"].values.tolist() - - # reshape the design criteria values for heatmaps - cri_a = np.asarray(A_range).reshape(len(x_range), len(y_range)) - cri_d = np.asarray(D_range).reshape(len(x_range), len(y_range)) - cri_e = np.asarray(E_range).reshape(len(x_range), len(y_range)) - cri_e_cond = np.asarray(ME_range).reshape(len(x_range), len(y_range)) - - self.cri_a = cri_a - self.cri_d = cri_d - self.cri_e = cri_e - self.cri_e_cond = cri_e_cond - - # decide if log scaled - if log_scale: - hes_a = np.log10(self.cri_a) - hes_e = np.log10(self.cri_e) - hes_d = np.log10(self.cri_d) - hes_e2 = np.log10(self.cri_e_cond) - else: - hes_a = self.cri_a - hes_e = self.cri_e - hes_d = self.cri_d - hes_e2 = self.cri_e_cond - - # set heatmap x,y ranges - xLabel = x_range - yLabel = y_range - - # A-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - plt.pyplot.rcParams.update(params) - ax.set_yticks(range(len(yLabel))) - ax.set_yticklabels(yLabel) - ax.set_ylabel(ylabel_text) - ax.set_xticks(range(len(xLabel))) - ax.set_xticklabels(xLabel) - ax.set_xlabel(xlabel_text) - im = ax.imshow(hes_a.T, cmap=plt.pyplot.cm.hot_r) - ba = plt.pyplot.colorbar(im) - ba.set_label("log10(trace(FIM))") - plt.pyplot.title(title_text + ": A-optimality") - plt.pyplot.show() - - # D-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - plt.pyplot.rcParams.update(params) - ax.set_yticks(range(len(yLabel))) - ax.set_yticklabels(yLabel) - ax.set_ylabel(ylabel_text) - ax.set_xticks(range(len(xLabel))) - ax.set_xticklabels(xLabel) - ax.set_xlabel(xlabel_text) - im = ax.imshow(hes_d.T, cmap=plt.pyplot.cm.hot_r) - ba = plt.pyplot.colorbar(im) - ba.set_label("log10(det(FIM))") - plt.pyplot.title(title_text + ": D-optimality") - plt.pyplot.show() - - # E-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - plt.pyplot.rcParams.update(params) - ax.set_yticks(range(len(yLabel))) - ax.set_yticklabels(yLabel) - ax.set_ylabel(ylabel_text) - ax.set_xticks(range(len(xLabel))) - ax.set_xticklabels(xLabel) - ax.set_xlabel(xlabel_text) - im = ax.imshow(hes_e.T, cmap=plt.pyplot.cm.hot_r) - ba = plt.pyplot.colorbar(im) - ba.set_label("log10(minimal eig(FIM))") - plt.pyplot.title(title_text + ": E-optimality") - plt.pyplot.show() - - # modified E-optimality - fig = plt.pyplot.figure() - plt.pyplot.rc("axes", titlesize=font_axes) - plt.pyplot.rc("axes", labelsize=font_axes) - plt.pyplot.rc("xtick", labelsize=font_tick) - plt.pyplot.rc("ytick", labelsize=font_tick) - ax = fig.add_subplot(111) - params = {"mathtext.default": "regular"} - plt.pyplot.rcParams.update(params) - ax.set_yticks(range(len(yLabel))) - ax.set_yticklabels(yLabel) - ax.set_ylabel(ylabel_text) - ax.set_xticks(range(len(xLabel))) - ax.set_xticklabels(xLabel) - ax.set_xlabel(xlabel_text) - im = ax.imshow(hes_e2.T, cmap=plt.pyplot.cm.hot_r) - ba = plt.pyplot.colorbar(im) - ba.set_label("log10(cond(FIM))") - plt.pyplot.title(title_text + ": Modified E-optimality") - plt.pyplot.show() diff --git a/pyomo/contrib/doe/scenario.py b/pyomo/contrib/doe/scenario.py deleted file mode 100644 index 3faeb78dd10..00000000000 --- a/pyomo/contrib/doe/scenario.py +++ /dev/null @@ -1,181 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - -import pickle -from enum import Enum -from collections import namedtuple -import copy - - -class FiniteDifferenceStep(Enum): - forward = "forward" - central = "central" - backward = "backward" - - -# namedtuple for scenario data -ScenarioData = namedtuple( - "ScenarioData", ["scenario", "scena_num", "eps_abs", "scenario_indices"] -) - - -class ScenarioGenerator: - def __init__(self, parameter_dict=None, formula="central", step=0.001, store=False): - """Generate scenarios. - DoE library first calls this function to generate scenarios. - - Parameters - ----------- - parameter_dict: - a ``dict`` of parameter, keys are names of ''string'', values are their nominal value of ''float''. - for e.g., {'A1': 84.79, 'A2': 371.72, 'E1': 7.78, 'E2': 15.05} - formula: - choose from 'central', 'forward', 'backward', None. - step: - Sensitivity perturbation step size, a fraction between [0,1]. default is 0.001 - store: - if True, store results. - """ - # get info from parameter dictionary - self.parameters = parameter_dict - self.parameter_dict = parameter_dict - self.para_names = list(parameter_dict.keys()) - self.no_para = len(self.para_names) - # self.formula = FiniteDifferenceStep(formula) - self.formula = formula - self.step = step - self.store = store - self.scenario_nominal = [parameter_dict[d] for d in self.para_names] - - # generate scenarios - self.generate_scenario() - - def generate_scenario(self): - """ - Generate scenario data for the given parameter dictionary. - - Returns: - ------- - ScenarioData: a namedtuple containing scenarios information. - ScenarioData.scenario: a list of dictionaries, each dictionary contains a perturbed scenario - ScenarioData.scena_num: a dict of scenario number related to one parameter - ScenarioData.eps_abs: keys are parameter name, values are the step it is perturbed - ScenarioData.scenario_indices: a list of scenario indices - - - For e.g., if a dict {'P':100, 'D':20} is given, step=0.1, formula='central', it will return: - self.ScenarioData.scenario: [{'P':101, 'D':20}, {'P':99, 'D':20}, {'P':100, 'D':20.2}, {'P':100, 'D':19.8}], - self.ScenarioData.scena_num: {'P':[0,1], 'D':[2,3]}} - self.ScenarioData.eps_abs: {'P': 2.0, 'D': 0.4} - self.ScenarioData.scenario_indices: [0,1,2,3] - if formula ='forward', it will return: - self.ScenarioData.scenario:[{'P':101, 'D':20}, {'P':100, 'D':20.2}, {'P':100, 'D':20}], - self.ScenarioData.scena_num: {'P':[0,2], 'D':[1,2]}} - self.ScenarioData.eps_abs: {'P': 2.0, 'D': 0.4} - self.ScenarioData.scenario_indices: [0,1,2] - """ - # dict for parameter perturbation step size - eps_abs = {} - # scenario dict for block - scenario = [] - # number of scenario - scena_num = {} - - # count_scens = 0 - # for k, v in self.parameters.items(): - # if self.formula == FiniteDifferenceStep.central: - # scena_num[k.name] = [2 * count_scens, 2 * count_scens + 1] - # scena_dict_hi = {k.name: v * (1 + self.step)} - # scena_dict_lo = {k.name: v * (1 + self.step)} - - # eps_abs[k.name] = 2 * self.step * v - - # scenario.append(scena_dict_hi) - # scenario.append(scena_dict_lo) - - # self.ScenarioData = ScenarioData( - # scenario, scena_num, eps_abs, list(range(len(scenario))) - # ) - - ############################## - # Below is deprecated code # - ############################## - - # loop over parameter name - for p, para in enumerate(self.para_names): - ## get scenario dictionary - if self.formula == FiniteDifferenceStep.central: - if isinstance(para, str): - name = para - else: - name = para.name - scena_num[name] = [2 * p, 2 * p + 1] - scena_dict_up, scena_dict_lo = ( - copy.deepcopy(self.parameter_dict), - copy.deepcopy(self.parameter_dict), - ) - # corresponding parameter dictionary for the scenario - scena_dict_up[name] *= 1 + self.step - scena_dict_lo[name] *= 1 - self.step - - scenario.append(scena_dict_up) - scenario.append(scena_dict_lo) - - elif self.formula in [ - FiniteDifferenceStep.forward, - FiniteDifferenceStep.backward, - ]: - # the base case is added as the last one - scena_num[para] = [p, len(self.param_names)] - scena_dict_up, scena_dict_lo = ( - self.parameter_dict.copy(), - self.parameter_dict.copy(), - ) - if self.formula == FiniteDifferenceStep.forward: - scena_dict_up[para] *= 1 + self.step - - elif self.formula == FiniteDifferenceStep.backward: - scena_dict_lo[para] *= 1 - self.step - - scenario.append(scena_dict_up) - scenario.append(scena_dict_lo) - - ## get perturbation sizes - # for central difference scheme, perturbation size is two times the step size - if self.formula == FiniteDifferenceStep.central: - eps_abs[para] = 2 * self.step * self.parameter_dict[para] - else: - eps_abs[para] = self.step * self.parameter_dict[para] - - self.ScenarioData = ScenarioData( - scenario, scena_num, eps_abs, list(range(len(scenario))) - ) - - # store scenario - if self.store: - with open("scenario_simultaneous.pickle", "wb") as f: - pickle.dump(self.scenario_data, f) From 936cc4cda7840d39190f3a4dfc7167c9576bc177 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 11 Jul 2024 14:31:39 -0400 Subject: [PATCH 050/203] Removing more files --- pyomo/contrib/doe/measurements.py | 357 ------------------ .../doe/redesign/simple_reaction_example | 188 --------- 2 files changed, 545 deletions(-) delete mode 100644 pyomo/contrib/doe/measurements.py delete mode 100644 pyomo/contrib/doe/redesign/simple_reaction_example diff --git a/pyomo/contrib/doe/measurements.py b/pyomo/contrib/doe/measurements.py deleted file mode 100644 index 31a9dc19dbb..00000000000 --- a/pyomo/contrib/doe/measurements.py +++ /dev/null @@ -1,357 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - -import itertools -import collections.abc -from pyomo.common.numeric_types import native_numeric_types - - -class VariablesWithIndices: - def __init__(self): - """This class provides utility methods for DesignVariables and MeasurementVariables to create - lists of Pyomo variable names with an arbitrary number of indices. - """ - self.variable_names = [] - self.variable_names_value = {} - self.lower_bounds = {} - self.upper_bounds = {} - - def set_variable_name_list(self, variable_name_list): - """ - Specify variable names with its full name. - - Parameters - ---------- - variable_name_list: a ``list`` of ``string``, containing the variable names with indices, - for e.g. "C['CA', 23, 0]". - """ - self.variable_names.extend(variable_name_list) - - def add_variables( - self, - var_name, - indices=None, - time_index_position=None, - values=None, - lower_bounds=None, - upper_bounds=None, - ): - """ - Used for generating string names with indices. - - Parameters - ---------- - var_name: variable name in ``string`` - indices: a ``dict`` containing indices - if default (None), no extra indices needed for all var in var_name - for e.g., {0:["CA", "CB", "CC"], 1: [1,2,3]}. - time_index_position: an integer indicates which index is the time index - for e.g., 1 is the time index position in the indices example. - values: a ``list`` containing values which has the same shape of flattened variables - default choice is None, means there is no give nvalues - lower_bounds: a ``list `` of lower bounds. If given a scalar number, it is set as the lower bounds for all variables. - upper_bounds: a ``list`` of upper bounds. If given a scalar number, it is set as the upper bounds for all variables. - - Returns - ------- - if not defining values, return a set of variable names - if defining values, return a dictionary of variable names and its value - """ - added_names = self._generate_variable_names_with_indices( - var_name, indices=indices, time_index_position=time_index_position - ) - - self._check_valid_input( - len(added_names), - var_name, - indices, - time_index_position, - values, - lower_bounds, - upper_bounds, - ) - - if values is not None: - # if a scalar (int or float) is given, set it as the value for all variables - if type(values) in native_numeric_types: - values = [values] * len(added_names) - # this dictionary keys are special set, values are its value - self.variable_names_value.update(zip(added_names, values)) - - if lower_bounds is not None: - # if a scalar (int or float) is given, set it as the lower bound for all variables - if type(lower_bounds) in native_numeric_types: - lower_bounds = [lower_bounds] * len(added_names) - self.lower_bounds.update(zip(added_names, lower_bounds)) - - if upper_bounds is not None: - # if a scalar (int or float) is given, set it as the upper bound for all variables - if type(upper_bounds) in native_numeric_types: - upper_bounds = [upper_bounds] * len(added_names) - self.upper_bounds.update(zip(added_names, upper_bounds)) - - return added_names - - def _generate_variable_names_with_indices( - self, var_name, indices=None, time_index_position=None - ): - """ - Used for generating string names with indices. - - Parameters - ---------- - var_name: a ``list`` of var names - indices: a ``dict`` containing indices - if default (None), no extra indices needed for all var in var_name - for e.g., {0:["CA", "CB", "CC"], 1: [1,2,3]}. - time_index_position: an integer indicates which index is the time index - for e.g., 1 is the time index position in the indices example. - """ - # first combine all indices into a list - all_index_list = [] # contains all index lists - if indices is not None: - for index_pointer in indices: - all_index_list.append(indices[index_pointer]) - - # all index list for one variable, such as ["CA", 10, 1] - # exhaustively enumerate over the full product of indices. For e.g., - # {0:["CA", "CB", "CC"], 1: [1,2,3]} - # becomes ["CA", 1], ["CA", 2], ..., ["CC", 2], ["CC", 3] - all_variable_indices = list(itertools.product(*all_index_list)) - - # list store all names added this time - added_names = [] - # iterate over index combinations ["CA", 1], ["CA", 2], ..., ["CC", 2], ["CC", 3] - for index_instance in all_variable_indices: - var_name_index_string = var_name - # - # Suggestion from JS: "Can you re-use name_repr and index_repr from pyomo.core.base.component_namer here?" - # - for i, idx in enumerate(index_instance): - # if i is the first index, open the [] - if i == 0: - var_name_index_string += "[" - # use repr() is different from using str() - # with repr(), "CA" is "CA", with str(), "CA" is CA. The first is not valid in our interface. - var_name_index_string += str(idx) - - # if i is the last index, close the []. if not, add a "," for the next index. - if i == len(index_instance) - 1: - var_name_index_string += "]" - else: - var_name_index_string += "," - - self.variable_names.append(var_name_index_string) - added_names.append(var_name_index_string) - - return added_names - - def _check_valid_input( - self, - len_indices, - var_name, - indices, - time_index_position, - values, - lower_bounds, - upper_bounds, - ): - """ - Check if the measurement information provided are valid to use. - """ - if not isinstance(var_name, str): - raise TypeError("Variable name must be a string.") - - # debugging note: what is an integer versus a list versus a dictionary here? - # check if time_index_position is in indices - if ( - indices is not None # ensure not None - and time_index_position is not None # ensure not None - and time_index_position - not in indices.keys() # ensure time_index_position is in indices - ): - raise ValueError("time index cannot be found in indices.") - - # if given a list, check if values have the same length with flattened variable - if ( - values is not None # ensure not None - and not type(values) - in native_numeric_types # skip this test if scalar (int or float) - and len(values) != len_indices - ): - raise ValueError("Values is of different length with indices.") - - if ( - lower_bounds is not None # ensure not None - and not type(lower_bounds) - in native_numeric_types # skip this test if scalar (int or float) - and isinstance(lower_bounds, collections.abc.Sequence) # ensure list-like - and len(lower_bounds) != len_indices # ensure same length - ): - raise ValueError("Lowerbounds have a different length with indices.") - - if ( - upper_bounds is not None # ensure not None - and not type(upper_bounds) - in native_numeric_types # skip this test if scalar (int or float) - and isinstance(upper_bounds, collections.abc.Sequence) # ensure list-like - and len(upper_bounds) != len_indices # ensure same length - ): - raise ValueError("Upperbounds have a different length with indices.") - - -class MeasurementVariables(VariablesWithIndices): - def __init__(self): - """ - This class stores information on which algebraic and differential variables in the Pyomo model are considered measurements. - """ - super().__init__() - self.variance = {} - - def set_variable_name_list(self, variable_name_list, variance=1): - """ - Specify variable names if given strings containing names and indices. - - Parameters - ---------- - variable_name_list: a ``list`` of ``string``, containing the variable names with indices, - for e.g. "C['CA', 23, 0]". - variance: a ``list`` of scalar numbers , which is the variance for this measurement. - """ - super().set_variable_name_list(variable_name_list) - - # add variance - if variance is not list: - variance = [variance] * len(variable_name_list) - - self.variance.update(zip(variable_name_list, variance)) - - def add_variables( - self, var_name, indices=None, time_index_position=None, variance=1 - ): - """ - Parameters - ----------- - var_name: a ``list`` of var names - indices: a ``dict`` containing indices - if default (None), no extra indices needed for all var in var_name - for e.g., {0:["CA", "CB", "CC"], 1: [1,2,3]}. - time_index_position: an integer indicates which index is the time index - for e.g., 1 is the time index position in the indices example. - variance: a scalar number, which is the variance for this measurement. - """ - added_names = super().add_variables( - var_name=var_name, indices=indices, time_index_position=time_index_position - ) - - # store variance - # if variance is a scalar number, repeat it for all added names - if variance is not list: - variance = [variance] * len(added_names) - self.variance.update(zip(added_names, variance)) - - def check_subset(self, subset_object): - """ - Check if subset_object is a subset of the current measurement object - - Parameters - ---------- - subset_object: a measurement object - """ - for name in subset_object.variable_names: - if name not in self.variable_names: - raise ValueError("Measurement not in the set: ", name) - - return True - - -class DesignVariables(VariablesWithIndices): - """ - Define design variables - """ - - def __init__(self): - super().__init__() - - def set_variable_name_list(self, variable_name_list): - """ - Specify variable names with its full name. - - Parameters - ---------- - variable_name_list: a ``list`` of ``string``, containing the variable names with indices, - for e.g. "C['CA', 23, 0]". - """ - super().set_variable_name_list(variable_name_list) - - def add_variables( - self, - var_name, - indices=None, - time_index_position=None, - values=None, - lower_bounds=None, - upper_bounds=None, - ): - """ - - Parameters - ---------- - var_name: a ``list`` of var names - indices: a ``dict`` containing indices - if default (None), no extra indices needed for all var in var_name - for e.g., {0:["CA", "CB", "CC"], 1: [1,2,3]}. - time_index_position: an integer indicates which index is the time index - for e.g., 1 is the time index position in the indices example. - values: a ``list`` containing values which has the same shape of flattened variables - default choice is None, means there is no give nvalues - lower_bounds: a ``list`` of lower bounds. If given a scalar number, it is set as the lower bounds for all variables. - upper_bounds: a ``list`` of upper bounds. If given a scalar number, it is set as the upper bounds for all variables. - """ - super().add_variables( - var_name=var_name, - indices=indices, - time_index_position=time_index_position, - values=values, - lower_bounds=lower_bounds, - upper_bounds=upper_bounds, - ) - - def update_values(self, new_value_dict): - """ - Update values of variables. Used for defining values for design variables of different experiments. - - Parameters - ---------- - new_value_dict: a ``dict`` containing the new values for the variables. - for e.g., {"C['CA', 23, 0]": 0.5, "C['CA', 24, 0]": 0.6} - """ - for key in new_value_dict: - if key not in self.variable_names: - raise ValueError("Variable not in the set: ", key) - - self.variable_names_value[key] = new_value_dict[key] diff --git a/pyomo/contrib/doe/redesign/simple_reaction_example b/pyomo/contrib/doe/redesign/simple_reaction_example deleted file mode 100644 index 416cbff1c13..00000000000 --- a/pyomo/contrib/doe/redesign/simple_reaction_example +++ /dev/null @@ -1,188 +0,0 @@ -def expand_model_components(m, base_components, index_sets): - """ - Takes model components and index sets and returns the - model component labels. - - Arguments - --------- - m: Pyomo model - base_components: list of variables from model 'm' - index_sets: list, same length as base_components, where each - element is a list of index sets, or None - """ - for val, indexes in itertools.zip_longest(base_components, index_sets): - # If the variable has no index, - # add just the model component - if not val.is_indexed(): - yield val - # If the component is indexed but no - # index supplied, add all indices - elif indexes is None: - yield from val.values() - else: - for j in itertools.product(*indexes): - yield val[j] - -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) - - -class SimpleReactorExperiment(object): - def __init__(self, data, nfe, ncp): - self.data = data - self.nfe = nfe - self.ncp = ncp - self.model = None - - def get_labeled_model(self): - if self.model is None: - self.create_model() - self.finalize_model() - self.label_experiment_impl() - return self.model - - def create_model(self): - """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. - - Return - ------ - m: a Pyomo.DAE model - """ - - m = self.model = pyo.ConcreteModel() - - # Model parameters - m.R = pyo.Param(mutable=False, initialize=8.314) - - # Define model variables - ######################## - # time - m.t = ContinuousSet(bounds=[0, 1]) - - # Concentrations - m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Arrhenius rate law equations - m.A1 = pyo.Var(within=pyo.NonNegativeReals) - - # Differential variables (Conc.) - m.dCAdt = DerivativeVar(m.CA, wrt=m.t) - - ######################## - # End variable def. - - # Equation def'n - ######################## - - # Expression for rate constants - @m.Expression(m.t) - def k1(m, t): - return m.A1 - - # Concentration odes - @m.Constraint(m.t) - def CA_rxn_ode(m, t): - return m.dCAdt[t] == -m.k1[t] * m.CA[t] - - # algebraic balance for concentration of B - # Valid because the reaction system (A --> B) is equimolar - @m.Constraint(m.t) - def CB_balance(m, t): - return m.CA[0] == m.CA[t] + m.CB[t] - - ######################## - # End equation def'n - - def finalize_model(self): - """ - Example finalize model function. There are two main tasks - here: - 1. Extracting useful information for the model to align - with the experiment. (Here: CA0, t_final, t_control) - 2. Discretizing the model subject to this information. - - Arguments - --------- - m: Pyomo model - data: object containing vital experimental information - nfe: number of finite elements - ncp: number of collocation points for the finite elements - """ - m = self.model - - # Unpacking data before simulation - control_points = self.data['control_points'] - - m.CA[0].fix(self.data['CA0']) - m.CB[0].fix(self.data['CB0']) - # m.A1 = self.data['A1'] - m.A1.fix(self.data['A1']) - - # TODO: add simulation for initialization????? - # Call the simulator (optional) - # sim = Simulator(m, package='casadi') - # tsim, profiles = sim.simulate(numpoints=100, integrator='idas') - - # Discretizing the model - discr = pyo.TransformationFactory("dae.collocation") - discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) - - # sim.initialize_model() - - - def label_experiment_impl(self, index_sets_meas): - """ - Example for annotating (labeling) the model with a - full experiment. - - Arguments - --------- - - """ - m = self.model - - # Grab measurement labels - base_comp_meas = [m.CA, m.CB, ] - m.experiment_outputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - - # Adding no error for measurements currently - m.measurement_error = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - - # Grab design variables - base_comp_des = [m.CA, ] - index_sets_des = [[[m.t.first()]], ] - m.experiment_inputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) - - m.unknown_parameters = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1,]) - -f = open('result.json') -data_ex = json.load(f) -data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} - -experiments_simple = [ - SimpleReactorExperiment(data_ex, 32, 3), -] - -# in parmest / DoE: -expanded_experiments_simple = [e.get_labeled_model() for e in experiments_simple] \ No newline at end of file From 3e8c5e0039a3738804f4228e85a42880ec207c92 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 11 Jul 2024 16:21:50 -0400 Subject: [PATCH 051/203] Wrote solving tests Covering all different forms of DoE model (i.e., trace, det; central, forward, backward; full factorial FIM; compute FIM). --- pyomo/contrib/doe/doe.py | 16 +- .../doe/redesign/experiment_class_example.py | 29 -- pyomo/contrib/doe/redesign/test_build.py | 51 +--- .../doe/tests/experiment_class_example.py | 249 +++++++++++++++++ pyomo/contrib/doe/tests/result.json | 1 + pyomo/contrib/doe/tests/test_doe_solve.py | 252 ++++++++++++++++++ 6 files changed, 526 insertions(+), 72 deletions(-) create mode 100644 pyomo/contrib/doe/tests/experiment_class_example.py create mode 100644 pyomo/contrib/doe/tests/result.json create mode 100644 pyomo/contrib/doe/tests/test_doe_solve.py diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index fafff8f1954..70f08ffc1ff 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -26,6 +26,7 @@ # ___________________________________________________________________________ import pyomo.environ as pyo +from pyomo.opt import SolverStatus from pyomo.common import DeveloperError from pyomo.common.timing import TicTocTimer from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp @@ -301,8 +302,8 @@ def run_doe(self, model=None, results_file=None): model.L[c, d].value = L_vals_sq[i, j] # Solve the full model, which has now been initialized with the square solve - self.solver.solve(model, tee=self.tee) - + res = self.solver.solve(model, tee=self.tee) + # Track time used to solve the DoE model solve_time = sp_timer.toc(msg=None) @@ -319,6 +320,9 @@ def run_doe(self, model=None, results_file=None): # Make sure stale results don't follow the DoE object instance self.results = {} + + self.results['Solver Status'] = res.solver.status + self.results['Termination Condition'] = res.solver.termination_condition # Important quantities for optimal design self.results["FIM"] = fim_local @@ -396,6 +400,12 @@ def compute_FIM(self, model=None, method="sequential"): model = self.compute_FIM_model self.check_model_labels(model=model) + + # Set length values for the model features + self.n_parameters = len(model.unknown_parameters) + self.n_measurement_error = len(model.measurement_error) + self.n_experiment_inputs = len(model.experiment_inputs) + self.n_experiment_outputs = len(model.experiment_outputs) # Check FIM input, if it exists. Otherwise, set the prior_FIM attribute if self.prior_FIM is None: @@ -438,6 +448,8 @@ def _sequential_FIM(self, model=None): model = self.compute_FIM_model # Create suffix to keep track of parameter scenarios + if hasattr(model, 'parameter_scenarios'): + model.del_component(model.parameter_scenarios) model.parameter_scenarios = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) diff --git a/pyomo/contrib/doe/redesign/experiment_class_example.py b/pyomo/contrib/doe/redesign/experiment_class_example.py index 7855e32d2fc..eae355ebc89 100644 --- a/pyomo/contrib/doe/redesign/experiment_class_example.py +++ b/pyomo/contrib/doe/redesign/experiment_class_example.py @@ -153,16 +153,10 @@ def finalize_model(self): # Unpacking data before simulation control_points = self.data['control_points'] - # m.CA[0].fix(self.data['CA0']) m.CA[0].value = self.data['CA0'] m.CB[0].fix(self.data['CB0']) - # m.CC[0].fix(self.data['CC0']) m.t.update(self.data['t_range']) m.t.update(control_points) - # m.A1 = self.data['A1'] - # m.A2 = self.data['A2'] - # m.E1 = self.data['E1'] - # m.E2 = self.data['E2'] m.A1.fix(self.data['A1']) m.A2.fix(self.data['A2']) m.E1.fix(self.data['E1']) @@ -171,15 +165,8 @@ def finalize_model(self): m.CA[0].setlb(self.data['CA_bounds'][0]) m.CA[0].setub(self.data['CA_bounds'][1]) - # m.T[0].fix(control_points[0]) - m.t_control = control_points - # TODO: add simulation for initialization????? - # Call the simulator (optional) - # sim = Simulator(m, package='casadi') - # tsim, profiles = sim.simulate(numpoints=100, integrator='idas') - # Discretizing the model discr = pyo.TransformationFactory("dae.collocation") discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) @@ -189,13 +176,10 @@ def finalize_model(self): for t in m.t: if t in control_points: cv = control_points[t] - # m.T[t].fix(cv) m.T[t].setlb(self.data['T_bounds'][0]) m.T[t].setub(self.data['T_bounds'][1]) m.T[t] = cv - # m.extra_con = pyo.Constraint(expr=m.T[0.0] == m.T[1.0]) - @m.Constraint(m.t - control_points) def T_control(m, t): """ @@ -263,16 +247,3 @@ def label_experiment(self): """ m = self.model return self.label_experiment_impl([[m.t_control], [[m.t.last()]], [[m.t.last()]]]) - - -f = open('result.json') -data_ex = json.load(f) -data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} - -experiments = [ - FullReactorExperiment(data_ex, 10, 3), - PartialReactorExperiment(data_ex, 10, 3), -] - -# in parmest / DoE: -expanded_experiments = [e.get_labeled_model() for e in experiments] \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 0d1d84b217b..7d3bc398f70 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -1,15 +1,15 @@ from experiment_class_example import * from pyomo.contrib.doe import * -from pyomo.contrib.doe import * - -from simple_reaction_example import * import numpy as np import logging +f = open('result.json') +data_ex = json.load(f) +data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} + doe_obj = [0, 0, 0, 0,] obj = ['trace', 'det', 'det'] -file_name = ['trash1.json', 'trash2.json', 'trash3.json'] for ind, fd in enumerate(['central', 'backward', 'forward']): experiment = FullReactorExperiment(data_ex, 10, 3) @@ -32,50 +32,19 @@ _only_compute_fim_lower=True, logger_level=logging.INFO, ) - doe_obj[ind].run_doe(results_file=file_name[ind]) - - -ind = 3 - -doe_obj[ind] = DesignOfExperiments( - experiment, - fd_formula='central', - step=1e-3, - objective_option=ObjectiveLib.det, - scale_constant_value=1, - scale_nominal_param_value=(True and (ind != 2)), - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_initial=None, - L_LB=1e-7, - solver=None, - tee=False, - args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - logger_level=logging.INFO, - ) -doe_obj[ind].model.set_blocks = pyo.Set(initialize=[0, 1, 2]) -doe_obj[ind].model.block_instances = pyo.Block(doe_obj[ind].model.set_blocks) -doe_obj[ind].create_doe_model(model=doe_obj[ind].model.block_instances[0]) -doe_obj[ind].create_doe_model(model=doe_obj[ind].model.block_instances[1]) -doe_obj[ind].create_doe_model(model=doe_obj[ind].model.block_instances[2]) - -print('Multi-block build complete') + doe_obj[ind].run_doe() # add a prior information (scaled FIM with T=500 and T=300 experiments) # prior = np.asarray( # [ - # [28.67892806, 5.41249739, -81.73674601, -24.02377324], - # [5.41249739, 26.40935036, -12.41816477, -139.23992532], - # [-81.73674601, -12.41816477, 240.46276004, 58.76422806], - # [-24.02377324, -139.23992532, 58.76422806, 767.25584508], + # [ 1745.81343391 1599.21859987 -3512.47892155 -7589.26220445] + # [ 1599.21859987 3525.63856364 -2900.94638673 -16465.46338508] + # [ -3512.47892155 -2900.94638673 7190.13048958 13849.96839993] + # [ -7589.26220445 -16465.46338508 13849.96839993 77674.03976715]] # ] # ) prior = None - design_ranges = { 'CA[0]': [1, 5, 3], 'T[0]': [300, 700, 3], @@ -88,7 +57,6 @@ print(doe_obj[0].kaug_FIM) - # Optimal values print("Optimal values for determinant optimized experimental design:") print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.objective))) @@ -121,6 +89,7 @@ print("Results from using compute FIM (first old, then new)") print(doe_obj[0].kaug_FIM) print(doe_obj[0].seq_FIM) +print(np.isclose(doe_obj[0].kaug_FIM, doe_obj[0].seq_FIM, 1e-2)) print(np.log10(np.linalg.det(doe_obj[0].kaug_FIM))) print(np.log10(np.linalg.det(doe_obj[0].seq_FIM))) A = doe_obj[0].kaug_jac diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py new file mode 100644 index 00000000000..eae355ebc89 --- /dev/null +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -0,0 +1,249 @@ +# === Required imports === +import pyomo.environ as pyo +from pyomo.dae import ContinuousSet, DerivativeVar, Simulator + +import itertools +import json +# ======================== + + +def expand_model_components(m, base_components, index_sets): + """ + Takes model components and index sets and returns the + model component labels. + + Arguments + --------- + m: Pyomo model + base_components: list of variables from model 'm' + index_sets: list, same length as base_components, where each + element is a list of index sets, or None + """ + for val, indexes in itertools.zip_longest(base_components, index_sets): + # If the variable has no index, + # add just the model component + if not val.is_indexed(): + yield val + # If the component is indexed but no + # index supplied, add all indices + elif indexes is None: + yield from val.values() + else: + for j in itertools.product(*indexes): + yield val[j] + + +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) + + +class ReactorExperiment(object): + def __init__(self, data, nfe, ncp): + self.data = data + self.nfe = nfe + self.ncp = ncp + self.model = None + + def get_labeled_model(self): + if self.model is None: + self.create_model() + self.finalize_model() + self.label_experiment() + return self.model + + def create_model(self): + """ + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. + + Return + ------ + m: a Pyomo.DAE model + """ + + m = self.model = pyo.ConcreteModel() + + # Model parameters + m.R = pyo.Param(mutable=False, initialize=8.314) + + # m.A1 = pyo.Param(mutable=True) + # m.E1 = pyo.Param(mutable=True) + # m.A2 = pyo.Param(mutable=True) + # m.E2 = pyo.Param(mutable=True) + + # Define model variables + ######################## + # time + m.t = ContinuousSet(bounds=[0, 1]) + + # Concentrations + m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Temperature + m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Arrhenius rate law equations + m.A1 = pyo.Var(within=pyo.NonNegativeReals) + m.E1 = pyo.Var(within=pyo.NonNegativeReals) + m.A2 = pyo.Var(within=pyo.NonNegativeReals) + m.E2 = pyo.Var(within=pyo.NonNegativeReals) + + # Differential variables (Conc.) + m.dCAdt = DerivativeVar(m.CA, wrt=m.t) + m.dCBdt = DerivativeVar(m.CB, wrt=m.t) + + ######################## + # End variable def. + + # Equation def'n + ######################## + + # Expression for rate constants + @m.Expression(m.t) + def k1(m, t): + return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) + + @m.Expression(m.t) + def k2(m, t): + return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) + + # Concentration odes + @m.Constraint(m.t) + def CA_rxn_ode(m, t): + return m.dCAdt[t] == -m.k1[t] * m.CA[t] + + @m.Constraint(m.t) + def CB_rxn_ode(m, t): + return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] + + # algebraic balance for concentration of C + # Valid because the reaction system (A --> B --> C) is equimolar + @m.Constraint(m.t) + def CC_balance(m, t): + return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] + + ######################## + # End equation def'n + + def finalize_model(self): + """ + Example finalize model function. There are two main tasks + here: + 1. Extracting useful information for the model to align + with the experiment. (Here: CA0, t_final, t_control) + 2. Discretizing the model subject to this information. + + Arguments + --------- + m: Pyomo model + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ + m = self.model + + # Unpacking data before simulation + control_points = self.data['control_points'] + + m.CA[0].value = self.data['CA0'] + m.CB[0].fix(self.data['CB0']) + m.t.update(self.data['t_range']) + m.t.update(control_points) + m.A1.fix(self.data['A1']) + m.A2.fix(self.data['A2']) + m.E1.fix(self.data['E1']) + m.E2.fix(self.data['E2']) + + m.CA[0].setlb(self.data['CA_bounds'][0]) + m.CA[0].setub(self.data['CA_bounds'][1]) + + m.t_control = control_points + + # Discretizing the model + discr = pyo.TransformationFactory("dae.collocation") + discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) + + # Initializing Temperature in the model + cv = None + for t in m.t: + if t in control_points: + cv = control_points[t] + m.T[t].setlb(self.data['T_bounds'][0]) + m.T[t].setub(self.data['T_bounds'][1]) + m.T[t] = cv + + @m.Constraint(m.t - control_points) + def T_control(m, t): + """ + Piecewise constant Temperature between control points + """ + neighbour_t = max(tc for tc in control_points if tc < t) + return m.T[t] == m.T[neighbour_t] + + # sim.initialize_model() + + + def label_experiment_impl(self, index_sets_meas): + """ + Example for annotating (labeling) the model with a + full experiment. + + Arguments + --------- + + """ + m = self.model + + # Grab measurement labels + base_comp_meas = [m.CA, m.CB, m.CC] + m.experiment_outputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Adding no error for measurements currently + m.measurement_error = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + # Grab design variables + base_comp_des = [m.CA, m.T] + index_sets_des = [[[m.t.first()]], [m.t_control]] + m.experiment_inputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) + + m.unknown_parameters = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) + + +class FullReactorExperiment(ReactorExperiment): + def label_experiment(self): + m = self.model + return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]]) + + +class PartialReactorExperiment(ReactorExperiment): + def label_experiment(self): + """ + Example for annotating (labeling) the model with a + "partial" experiment. + + Arguments + --------- + + """ + m = self.model + return self.label_experiment_impl([[m.t_control], [[m.t.last()]], [[m.t.last()]]]) diff --git a/pyomo/contrib/doe/tests/result.json b/pyomo/contrib/doe/tests/result.json new file mode 100644 index 00000000000..7e1b1a79a1b --- /dev/null +++ b/pyomo/contrib/doe/tests/result.json @@ -0,0 +1 @@ +{"CA0": 5.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py new file mode 100644 index 00000000000..4102727fce5 --- /dev/null +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -0,0 +1,252 @@ +from pyomo.common.dependencies import ( + numpy as np, + numpy_available, + pandas as pd, + pandas_available, +) + +from experiment_class_example import * +from pyomo.contrib.doe import * + + +import pyomo.common.unittest as unittest + +from pyomo.opt import SolverFactory + +ipopt_available = SolverFactory("ipopt").available() + +f = open('result.json') +data_ex = json.load(f) +data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} + +class TestReactorExamples(unittest.TestCase): + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_central_solve(self): + fd_method = "central" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.run_doe() + + assert (doe_obj.results['Solver Status'] == "ok") + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_forward_solve(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.run_doe() + + assert (doe_obj.results['Solver Status'] == "ok") + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_backward_solve(self): + fd_method = "backward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.run_doe() + + assert (doe_obj.results['Solver Status'] == "ok") + + # TODO: Fix determinant objective code, something is awry + # Should only be using Cholesky=True + # @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + # @unittest.skipIf(not numpy_available, "Numpy is not available") + # def test_reactor_obj_det_solve(self): + # fd_method = "central" + # obj_used = "det" + + # experiment = FullReactorExperiment(data_ex, 10, 3) + + # doe_obj = DesignOfExperiments( + # experiment, + # fd_formula=fd_method, + # step=1e-3, + # objective_option=obj_used, + # scale_constant_value=1, + # scale_nominal_param_value=True, + # prior_FIM=None, + # jac_initial=None, + # fim_initial=None, + # L_initial=None, + # L_LB=1e-7, + # solver=None, + # tee=False, + # args=None, + # _Cholesky_option=False, + # _only_compute_fim_lower=False, + # ) + + # doe_obj.run_doe() + + # assert (doe_obj.results['Solver Status'] == "ok") + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_obj_cholesky_solve(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.run_doe() + + assert (doe_obj.results['Solver Status'] == "ok") + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_compute_FIM_seq(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + 'CA[0]': [1, 5, 3], + 'T[0]': [300, 700, 3], + } + + doe_obj.compute_FIM(method='sequential') + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_grid_search(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + 'CA[0]': [1, 5, 3], + 'T[0]': [300, 700, 3], + } + + doe_obj.compute_FIM_full_factorial(design_ranges=design_ranges, method='sequential') + + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From 53384ae385e5c3a5db9e74cc061489252fa6c795 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 11 Jul 2024 17:33:01 -0400 Subject: [PATCH 052/203] Adding placeholder files for other tests --- pyomo/contrib/doe/tests/test_doe_build.py | 0 pyomo/contrib/doe/tests/test_doe_errors.py | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 pyomo/contrib/doe/tests/test_doe_build.py create mode 100644 pyomo/contrib/doe/tests/test_doe_errors.py diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py new file mode 100644 index 00000000000..e69de29bb2d From 25753d4d8041d506b5dc1e53ce4a46606924fb29 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 08:34:13 -0400 Subject: [PATCH 053/203] Added checks that FIM, Q, and L are consistent after solve --- pyomo/contrib/doe/redesign/test_build.py | 5 ++ pyomo/contrib/doe/tests/test_doe_build.py | 48 ++++++++++++ pyomo/contrib/doe/tests/test_doe_solve.py | 93 +++++++++++++++++++++-- 3 files changed, 140 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py index 7d3bc398f70..05162179763 100644 --- a/pyomo/contrib/doe/redesign/test_build.py +++ b/pyomo/contrib/doe/redesign/test_build.py @@ -83,6 +83,11 @@ for i in range(27): sigma_inv_new_np[i, i] = sigma_inv_new[i] +# Check cholesky factorization +print("Cholesky Checking") +print(L_vals_new_np @ L_vals_new_np.T) +print(FIM_vals_new_np) + rescaled_FIM = rescale_FIM(FIM=FIM_vals_new_np, param_vals=param_vals) # Comparing values from compute FIM diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index e69de29bb2d..6f14f98b62a 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -0,0 +1,48 @@ +from pyomo.common.dependencies import ( + numpy as np, + numpy_available, + pandas as pd, + pandas_available, +) + +from experiment_class_example import * +from pyomo.contrib.doe import * + + +import pyomo.common.unittest as unittest + +from pyomo.opt import SolverFactory + +ipopt_available = SolverFactory("ipopt").available() + +f = open('result.json') +data_ex = json.load(f) +data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} + +class TestReactorExampleModel(unittest.TestCase): + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_central_solve(self): + fd_method = "central" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) \ No newline at end of file diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 4102727fce5..0bc6196d7c1 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -19,7 +19,45 @@ data_ex = json.load(f) data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} -class TestReactorExamples(unittest.TestCase): +def get_FIM_Q_L(doe_obj=None,): + """ + Helper function to retreive results to compare. + + """ + model = doe_obj.model + + n_param = doe_obj.n_parameters + n_y = doe_obj.n_experiment_outputs + + FIM_vals = [pyo.value(model.fim[i, j]) for i in model.parameter_names for j in model.parameter_names] + if hasattr(model, 'L'): + L_vals = [pyo.value(model.L[i, j]) for i in model.parameter_names for j in model.parameter_names] + else: + L_vals = [[0] * n_param] * n_param + Q_vals = [pyo.value(model.sensitivity_jacobian[i, j]) for i in model.output_names for j in model.parameter_names] + sigma_inv = [1 / v for k,v in model.scenario_blocks[0].measurement_error.items()] + param_vals = np.array([[v for k, v in model.scenario_blocks[0].unknown_parameters.items()], ]) + + FIM_vals_np = np.array(FIM_vals).reshape((n_param, n_param)) + + for i in range(n_param): + for j in range(n_param): + if j < i: + FIM_vals_np[j, i] = FIM_vals_np[i, j] + + L_vals_np = np.array(L_vals).reshape((n_param, n_param)) + Q_vals_np = np.array(Q_vals).reshape((n_y, n_param)) + + sigma_inv_np = np.zeros((n_y, n_y)) + + for ind, v in enumerate(sigma_inv): + sigma_inv_np[ind, ind] = v + + return FIM_vals_np, Q_vals_np, L_vals_np, sigma_inv_np + + + +class TestReactorExampleSolving(unittest.TestCase): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_solve(self): @@ -49,7 +87,19 @@ def test_reactor_fd_central_solve(self): doe_obj.run_doe() + # Assert model solves assert (doe_obj.results['Solver Status'] == "ok") + + # Assert that Q, F, and L are the same. + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + + # Since Trace is used, no comparison for FIM and L.T @ L + + # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) + assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) + + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -81,6 +131,14 @@ def test_reactor_fd_forward_solve(self): doe_obj.run_doe() assert (doe_obj.results['Solver Status'] == "ok") + + # Assert that Q, F, and L are the same. + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + + # Since Trace is used, no comparison for FIM and L.T @ L + + # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) + assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -112,6 +170,14 @@ def test_reactor_fd_backward_solve(self): doe_obj.run_doe() assert (doe_obj.results['Solver Status'] == "ok") + + # Assert that Q, F, and L are the same. + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + + # Since Trace is used, no comparison for FIM and L.T @ L + + # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) + assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) # TODO: Fix determinant objective code, something is awry # Should only be using Cholesky=True @@ -176,6 +242,15 @@ def test_reactor_obj_cholesky_solve(self): doe_obj.run_doe() assert (doe_obj.results['Solver Status'] == "ok") + + # Assert that Q, F, and L are the same. + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + + # Since Cholesky is used, there is comparison for FIM and L.T @ L + assert (np.all(np.isclose(FIM, L @ L.T))) + + # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) + assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -204,11 +279,6 @@ def test_compute_FIM_seq(self): _only_compute_fim_lower=True, ) - design_ranges = { - 'CA[0]': [1, 5, 3], - 'T[0]': [300, 700, 3], - } - doe_obj.compute_FIM(method='sequential') @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @@ -245,6 +315,17 @@ def test_reactor_grid_search(self): } doe_obj.compute_FIM_full_factorial(design_ranges=design_ranges, method='sequential') + + # Check to make sure the lengths of the inputs in results object are indeed correct + CA_vals = doe_obj.fim_factorial_results['CA[0]'] + T_vals = doe_obj.fim_factorial_results['T[0]'] + + # Assert length is correct + assert (len(CA_vals) == 9) and (len(T_vals) == 9) + assert (len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3) + + # Assert unique values are correct + assert (set(CA_vals).issuperset(set([1, 3, 5]))) and (set(T_vals).issuperset(set([300, 500, 700]))) From cdebfe9c94cdfc7273cc541222c881fce14bc5ab Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:38:25 -0400 Subject: [PATCH 054/203] Added build testing functions Added functions to make sure the finite differencing scheme is working properly and that design variable fixing is working properly for all currently available finite difference types (i.e., central, backward, forward). --- pyomo/contrib/doe/tests/test_doe_build.py | 293 +++++++++++++++++++++- 1 file changed, 290 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 6f14f98b62a..d9125f83a50 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -19,10 +19,10 @@ data_ex = json.load(f) data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} -class TestReactorExampleModel(unittest.TestCase): +class TestReactorExampleBuild(unittest.TestCase): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_fd_central_solve(self): + def test_reactor_fd_central_check_fd_eqns(self): fd_method = "central" obj_used = "trace" @@ -45,4 +45,291 @@ def test_reactor_fd_central_solve(self): args=None, _Cholesky_option=True, _only_compute_fim_lower=True, - ) \ No newline at end of file + ) + + doe_obj.create_doe_model() + + model = doe_obj.model + + # Check that the parameter values are correct + for s in model.scenarios: + param = model.parameter_scenarios[s] + + diff = (-1) ** s * doe_obj.step + + param_val = pyo.value(pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s])) + + param_val_from_step = model.scenario_blocks[0].unknown_parameters[pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0])] * (1 + diff) + + for k, v in model.scenario_blocks[s].unknown_parameters.items(): + name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") + + if ".".join(k.name.split(".")[name_ind + 1:]) == param.name: + continue + + other_param_val = pyo.value(k) + assert(np.isclose(other_param_val, v)) + + assert(np.isclose(param_val, param_val_from_step)) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_backward_check_fd_eqns(self): + fd_method = "backward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.create_doe_model() + + model = doe_obj.model + + # Check that the parameter values are correct + for s in model.scenarios: + diff = -doe_obj.step * (s != 0) + if s != 0: + param = model.parameter_scenarios[s] + + param_val = pyo.value(pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s])) + + param_val_from_step = model.scenario_blocks[0].unknown_parameters[pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0])] * (1 + diff) + assert(np.isclose(param_val, param_val_from_step)) + + for k, v in model.scenario_blocks[s].unknown_parameters.items(): + name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") + + if not (s == 0) and ".".join(k.name.split(".")[name_ind + 1:]) == param.name: + continue + + other_param_val = pyo.value(k) + assert(np.isclose(other_param_val, v)) + + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_forward_check_fd_eqns(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.create_doe_model() + + model = doe_obj.model + + # Check that the parameter values are correct + for s in model.scenarios: + diff = doe_obj.step * (s != 0) + if s != 0: + param = model.parameter_scenarios[s] + + param_val = pyo.value(pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s])) + + param_val_from_step = model.scenario_blocks[0].unknown_parameters[pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0])] * (1 + diff) + assert(np.isclose(param_val, param_val_from_step)) + + for k, v in model.scenario_blocks[s].unknown_parameters.items(): + name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") + + if not (s == 0) and ".".join(k.name.split(".")[name_ind + 1:]) == param.name: + continue + + other_param_val = pyo.value(k) + assert(np.isclose(other_param_val, v)) + + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_central_design_fixing(self): + fd_method = "central" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.create_doe_model() + + model = doe_obj.model + + # Check that the design fixing constraints are generated + design_vars = [k for k, v in model.scenario_blocks[0].experiment_inputs.items()] + + con_name_base = "global_design_eq_con_" + + # Ensure that + for ind, d in enumerate(design_vars): + if ind == 0: + continue + + con_name = con_name_base + str(ind) + assert hasattr(model, con_name) + + # Ensure that each set of constraints has all blocks pairs with scenario 0 + # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints + assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) + + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) + assert not hasattr(model, con_name_base + str(len(design_vars))) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_backward_design_fixing(self): + fd_method = "backward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.create_doe_model() + + model = doe_obj.model + + # Check that the design fixing constraints are generated + design_vars = [k for k, v in model.scenario_blocks[0].experiment_inputs.items()] + + con_name_base = "global_design_eq_con_" + + # Ensure that + for ind, d in enumerate(design_vars): + if ind == 0: + continue + + con_name = con_name_base + str(ind) + assert hasattr(model, con_name) + + # Ensure that each set of constraints has all blocks pairs with scenario 0 + # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints + assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) + + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) + assert not hasattr(model, con_name_base + str(len(design_vars))) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_fd_forward_design_fixing(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.create_doe_model() + + model = doe_obj.model + + # Check that the design fixing constraints are generated + design_vars = [k for k, v in model.scenario_blocks[0].experiment_inputs.items()] + + con_name_base = "global_design_eq_con_" + + # Ensure that + for ind, d in enumerate(design_vars): + if ind == 0: + continue + + con_name = con_name_base + str(ind) + assert hasattr(model, con_name) + + # Ensure that each set of constraints has all blocks pairs with scenario 0 + # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints + assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) + + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) + assert not hasattr(model, con_name_base + str(len(design_vars))) + + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file From a751f962e04d67fb3eb8ab02f1356af66739eb97 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:39:48 -0400 Subject: [PATCH 055/203] Ran Black --- pyomo/contrib/doe/doe.py | 12 +- pyomo/contrib/doe/tests/test_doe_build.py | 126 +++++++------ pyomo/contrib/doe/tests/test_doe_solve.py | 218 ++++++++++++---------- 3 files changed, 199 insertions(+), 157 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 70f08ffc1ff..9ec562ba562 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -303,7 +303,7 @@ def run_doe(self, model=None, results_file=None): # Solve the full model, which has now been initialized with the square solve res = self.solver.solve(model, tee=self.tee) - + # Track time used to solve the DoE model solve_time = sp_timer.toc(msg=None) @@ -320,9 +320,9 @@ def run_doe(self, model=None, results_file=None): # Make sure stale results don't follow the DoE object instance self.results = {} - - self.results['Solver Status'] = res.solver.status - self.results['Termination Condition'] = res.solver.termination_condition + + self.results["Solver Status"] = res.solver.status + self.results["Termination Condition"] = res.solver.termination_condition # Important quantities for optimal design self.results["FIM"] = fim_local @@ -400,7 +400,7 @@ def compute_FIM(self, model=None, method="sequential"): model = self.compute_FIM_model self.check_model_labels(model=model) - + # Set length values for the model features self.n_parameters = len(model.unknown_parameters) self.n_measurement_error = len(model.measurement_error) @@ -448,7 +448,7 @@ def _sequential_FIM(self, model=None): model = self.compute_FIM_model # Create suffix to keep track of parameter scenarios - if hasattr(model, 'parameter_scenarios'): + if hasattr(model, "parameter_scenarios"): model.del_component(model.parameter_scenarios) model.parameter_scenarios = pyo.Suffix( direction=pyo.Suffix.LOCAL, diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index d9125f83a50..f038a961bc2 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -15,9 +15,10 @@ ipopt_available = SolverFactory("ipopt").available() -f = open('result.json') +f = open("result.json") data_ex = json.load(f) -data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} +data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} + class TestReactorExampleBuild(unittest.TestCase): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @@ -25,11 +26,11 @@ class TestReactorExampleBuild(unittest.TestCase): def test_reactor_fd_central_check_fd_eqns(self): fd_method = "central" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -57,31 +58,35 @@ def test_reactor_fd_central_check_fd_eqns(self): diff = (-1) ** s * doe_obj.step - param_val = pyo.value(pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s])) + param_val = pyo.value( + pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s]) + ) - param_val_from_step = model.scenario_blocks[0].unknown_parameters[pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0])] * (1 + diff) + param_val_from_step = model.scenario_blocks[0].unknown_parameters[ + pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0]) + ] * (1 + diff) for k, v in model.scenario_blocks[s].unknown_parameters.items(): name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") - if ".".join(k.name.split(".")[name_ind + 1:]) == param.name: + if ".".join(k.name.split(".")[name_ind + 1 :]) == param.name: continue - + other_param_val = pyo.value(k) - assert(np.isclose(other_param_val, v)) + assert np.isclose(other_param_val, v) + + assert np.isclose(param_val, param_val_from_step) - assert(np.isclose(param_val, param_val_from_step)) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_check_fd_eqns(self): fd_method = "backward" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -109,31 +114,37 @@ def test_reactor_fd_backward_check_fd_eqns(self): if s != 0: param = model.parameter_scenarios[s] - param_val = pyo.value(pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s])) + param_val = pyo.value( + pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s]) + ) - param_val_from_step = model.scenario_blocks[0].unknown_parameters[pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0])] * (1 + diff) - assert(np.isclose(param_val, param_val_from_step)) + param_val_from_step = model.scenario_blocks[0].unknown_parameters[ + pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0]) + ] * (1 + diff) + assert np.isclose(param_val, param_val_from_step) for k, v in model.scenario_blocks[s].unknown_parameters.items(): name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") - - if not (s == 0) and ".".join(k.name.split(".")[name_ind + 1:]) == param.name: + + if ( + not (s == 0) + and ".".join(k.name.split(".")[name_ind + 1 :]) == param.name + ): continue - + other_param_val = pyo.value(k) - assert(np.isclose(other_param_val, v)) - + assert np.isclose(other_param_val, v) @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_check_fd_eqns(self): fd_method = "forward" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -161,31 +172,37 @@ def test_reactor_fd_forward_check_fd_eqns(self): if s != 0: param = model.parameter_scenarios[s] - param_val = pyo.value(pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s])) + param_val = pyo.value( + pyo.ComponentUID(param).find_component_on(model.scenario_blocks[s]) + ) - param_val_from_step = model.scenario_blocks[0].unknown_parameters[pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0])] * (1 + diff) - assert(np.isclose(param_val, param_val_from_step)) + param_val_from_step = model.scenario_blocks[0].unknown_parameters[ + pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0]) + ] * (1 + diff) + assert np.isclose(param_val, param_val_from_step) for k, v in model.scenario_blocks[s].unknown_parameters.items(): name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") - - if not (s == 0) and ".".join(k.name.split(".")[name_ind + 1:]) == param.name: + + if ( + not (s == 0) + and ".".join(k.name.split(".")[name_ind + 1 :]) == param.name + ): continue - + other_param_val = pyo.value(k) - assert(np.isclose(other_param_val, v)) + assert np.isclose(other_param_val, v) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_design_fixing(self): fd_method = "central" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -212,31 +229,31 @@ def test_reactor_fd_central_design_fixing(self): con_name_base = "global_design_eq_con_" - # Ensure that + # Ensure that for ind, d in enumerate(design_vars): if ind == 0: continue - + con_name = con_name_base + str(ind) assert hasattr(model, con_name) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) - + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) - + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_design_fixing(self): fd_method = "backward" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -263,18 +280,18 @@ def test_reactor_fd_backward_design_fixing(self): con_name_base = "global_design_eq_con_" - # Ensure that + # Ensure that for ind, d in enumerate(design_vars): if ind == 0: continue - + con_name = con_name_base + str(ind) assert hasattr(model, con_name) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) - + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) @@ -283,11 +300,11 @@ def test_reactor_fd_backward_design_fixing(self): def test_reactor_fd_forward_design_fixing(self): fd_method = "forward" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -314,22 +331,21 @@ def test_reactor_fd_forward_design_fixing(self): con_name_base = "global_design_eq_con_" - # Ensure that + # Ensure that for ind, d in enumerate(design_vars): if ind == 0: continue - + con_name = con_name_base + str(ind) assert hasattr(model, con_name) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) - + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) - if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 0bc6196d7c1..b88a471e43a 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -15,11 +15,14 @@ ipopt_available = SolverFactory("ipopt").available() -f = open('result.json') +f = open("result.json") data_ex = json.load(f) -data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} +data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} -def get_FIM_Q_L(doe_obj=None,): + +def get_FIM_Q_L( + doe_obj=None, +): """ Helper function to retreive results to compare. @@ -29,14 +32,30 @@ def get_FIM_Q_L(doe_obj=None,): n_param = doe_obj.n_parameters n_y = doe_obj.n_experiment_outputs - FIM_vals = [pyo.value(model.fim[i, j]) for i in model.parameter_names for j in model.parameter_names] - if hasattr(model, 'L'): - L_vals = [pyo.value(model.L[i, j]) for i in model.parameter_names for j in model.parameter_names] + FIM_vals = [ + pyo.value(model.fim[i, j]) + for i in model.parameter_names + for j in model.parameter_names + ] + if hasattr(model, "L"): + L_vals = [ + pyo.value(model.L[i, j]) + for i in model.parameter_names + for j in model.parameter_names + ] else: L_vals = [[0] * n_param] * n_param - Q_vals = [pyo.value(model.sensitivity_jacobian[i, j]) for i in model.output_names for j in model.parameter_names] - sigma_inv = [1 / v for k,v in model.scenario_blocks[0].measurement_error.items()] - param_vals = np.array([[v for k, v in model.scenario_blocks[0].unknown_parameters.items()], ]) + Q_vals = [ + pyo.value(model.sensitivity_jacobian[i, j]) + for i in model.output_names + for j in model.parameter_names + ] + sigma_inv = [1 / v for k, v in model.scenario_blocks[0].measurement_error.items()] + param_vals = np.array( + [ + [v for k, v in model.scenario_blocks[0].unknown_parameters.items()], + ] + ) FIM_vals_np = np.array(FIM_vals).reshape((n_param, n_param)) @@ -56,18 +75,17 @@ def get_FIM_Q_L(doe_obj=None,): return FIM_vals_np, Q_vals_np, L_vals_np, sigma_inv_np - class TestReactorExampleSolving(unittest.TestCase): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_solve(self): fd_method = "central" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -84,33 +102,32 @@ def test_reactor_fd_central_solve(self): _Cholesky_option=True, _only_compute_fim_lower=True, ) - + doe_obj.run_doe() - + # Assert model solves - assert (doe_obj.results['Solver Status'] == "ok") + assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + FIM, Q, L, sigma_inv = get_FIM_Q_L( + doe_obj=doe_obj, + ) # Since Trace is used, no comparison for FIM and L.T @ L # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - + assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_solve(self): fd_method = "forward" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -127,29 +144,31 @@ def test_reactor_fd_forward_solve(self): _Cholesky_option=True, _only_compute_fim_lower=True, ) - + doe_obj.run_doe() - - assert (doe_obj.results['Solver Status'] == "ok") + + assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + FIM, Q, L, sigma_inv = get_FIM_Q_L( + doe_obj=doe_obj, + ) # Since Trace is used, no comparison for FIM and L.T @ L # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - + assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_solve(self): fd_method = "backward" obj_used = "trace" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -166,62 +185,64 @@ def test_reactor_fd_backward_solve(self): _Cholesky_option=True, _only_compute_fim_lower=True, ) - + doe_obj.run_doe() - - assert (doe_obj.results['Solver Status'] == "ok") + + assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + FIM, Q, L, sigma_inv = get_FIM_Q_L( + doe_obj=doe_obj, + ) # Since Trace is used, no comparison for FIM and L.T @ L # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - + assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) + # TODO: Fix determinant objective code, something is awry # Should only be using Cholesky=True # @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") # @unittest.skipIf(not numpy_available, "Numpy is not available") # def test_reactor_obj_det_solve(self): - # fd_method = "central" - # obj_used = "det" - - # experiment = FullReactorExperiment(data_ex, 10, 3) - - # doe_obj = DesignOfExperiments( - # experiment, - # fd_formula=fd_method, - # step=1e-3, - # objective_option=obj_used, - # scale_constant_value=1, - # scale_nominal_param_value=True, - # prior_FIM=None, - # jac_initial=None, - # fim_initial=None, - # L_initial=None, - # L_LB=1e-7, - # solver=None, - # tee=False, - # args=None, - # _Cholesky_option=False, - # _only_compute_fim_lower=False, - # ) - - # doe_obj.run_doe() - - # assert (doe_obj.results['Solver Status'] == "ok") - + # fd_method = "central" + # obj_used = "det" + + # experiment = FullReactorExperiment(data_ex, 10, 3) + + # doe_obj = DesignOfExperiments( + # experiment, + # fd_formula=fd_method, + # step=1e-3, + # objective_option=obj_used, + # scale_constant_value=1, + # scale_nominal_param_value=True, + # prior_FIM=None, + # jac_initial=None, + # fim_initial=None, + # L_initial=None, + # L_LB=1e-7, + # solver=None, + # tee=False, + # args=None, + # _Cholesky_option=False, + # _only_compute_fim_lower=False, + # ) + + # doe_obj.run_doe() + + # assert (doe_obj.results['Solver Status'] == "ok") + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_obj_cholesky_solve(self): fd_method = "central" obj_used = "det" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -238,30 +259,32 @@ def test_reactor_obj_cholesky_solve(self): _Cholesky_option=True, _only_compute_fim_lower=True, ) - + doe_obj.run_doe() - - assert (doe_obj.results['Solver Status'] == "ok") + + assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj,) + FIM, Q, L, sigma_inv = get_FIM_Q_L( + doe_obj=doe_obj, + ) # Since Cholesky is used, there is comparison for FIM and L.T @ L - assert (np.all(np.isclose(FIM, L @ L.T))) + assert np.all(np.isclose(FIM, L @ L.T)) # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert (np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - + assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq(self): fd_method = "central" obj_used = "det" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -278,8 +301,8 @@ def test_compute_FIM_seq(self): _Cholesky_option=True, _only_compute_fim_lower=True, ) - - doe_obj.compute_FIM(method='sequential') + + doe_obj.compute_FIM(method="sequential") @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @@ -287,11 +310,11 @@ def test_compute_FIM_seq(self): def test_reactor_grid_search(self): fd_method = "central" obj_used = "det" - + experiment = FullReactorExperiment(data_ex, 10, 3) - + doe_obj = DesignOfExperiments( - experiment, + experiment, fd_formula=fd_method, step=1e-3, objective_option=obj_used, @@ -308,26 +331,29 @@ def test_reactor_grid_search(self): _Cholesky_option=True, _only_compute_fim_lower=True, ) - + design_ranges = { - 'CA[0]': [1, 5, 3], - 'T[0]': [300, 700, 3], + "CA[0]": [1, 5, 3], + "T[0]": [300, 700, 3], } - - doe_obj.compute_FIM_full_factorial(design_ranges=design_ranges, method='sequential') + + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) # Check to make sure the lengths of the inputs in results object are indeed correct - CA_vals = doe_obj.fim_factorial_results['CA[0]'] - T_vals = doe_obj.fim_factorial_results['T[0]'] + CA_vals = doe_obj.fim_factorial_results["CA[0]"] + T_vals = doe_obj.fim_factorial_results["T[0]"] # Assert length is correct assert (len(CA_vals) == 9) and (len(T_vals) == 9) assert (len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3) # Assert unique values are correct - assert (set(CA_vals).issuperset(set([1, 3, 5]))) and (set(T_vals).issuperset(set([300, 500, 700]))) - - + assert (set(CA_vals).issuperset(set([1, 3, 5]))) and ( + set(T_vals).issuperset(set([300, 500, 700])) + ) + if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() From ea528ebd999a199cf7e497f34e25466181bbf92b Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:52:56 -0400 Subject: [PATCH 056/203] Added user initialization check, Ran Black --- pyomo/contrib/doe/tests/test_doe_build.py | 112 ++++++++++++++++++++-- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index f038a961bc2..79d21fe6f6f 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -20,8 +20,68 @@ data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} +def get_FIM_FIMPrior_Q_L( + doe_obj=None, +): + """ + Helper function to retreive results to compare. + + """ + model = doe_obj.model + + n_param = doe_obj.n_parameters + n_y = doe_obj.n_experiment_outputs + + FIM_vals = [ + pyo.value(model.fim[i, j]) + for i in model.parameter_names + for j in model.parameter_names + ] + FIM_prior_vals = [ + pyo.value(model.priorFIM[i, j]) + for i in model.parameter_names + for j in model.parameter_names + ] + if hasattr(model, "L"): + L_vals = [ + pyo.value(model.L[i, j]) + for i in model.parameter_names + for j in model.parameter_names + ] + else: + L_vals = [[0] * n_param] * n_param + Q_vals = [ + pyo.value(model.sensitivity_jacobian[i, j]) + for i in model.output_names + for j in model.parameter_names + ] + sigma_inv = [1 / v for k, v in model.scenario_blocks[0].measurement_error.items()] + param_vals = np.array( + [ + [v for k, v in model.scenario_blocks[0].unknown_parameters.items()], + ] + ) + + FIM_vals_np = np.array(FIM_vals).reshape((n_param, n_param)) + FIM_prior_vals_np = np.array(FIM_prior_vals).reshape((n_param, n_param)) + + for i in range(n_param): + for j in range(n_param): + if j < i: + FIM_vals_np[j, i] = FIM_vals_np[i, j] + + L_vals_np = np.array(L_vals).reshape((n_param, n_param)) + Q_vals_np = np.array(Q_vals).reshape((n_y, n_param)) + + sigma_inv_np = np.zeros((n_y, n_y)) + + for ind, v in enumerate(sigma_inv): + sigma_inv_np[ind, ind] = v + + return FIM_vals_np, FIM_prior_vals_np, Q_vals_np, L_vals_np, sigma_inv_np + + class TestReactorExampleBuild(unittest.TestCase): - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_check_fd_eqns(self): fd_method = "central" @@ -77,7 +137,6 @@ def test_reactor_fd_central_check_fd_eqns(self): assert np.isclose(param_val, param_val_from_step) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_check_fd_eqns(self): fd_method = "backward" @@ -135,7 +194,6 @@ def test_reactor_fd_backward_check_fd_eqns(self): other_param_val = pyo.value(k) assert np.isclose(other_param_val, v) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_check_fd_eqns(self): fd_method = "forward" @@ -193,7 +251,6 @@ def test_reactor_fd_forward_check_fd_eqns(self): other_param_val = pyo.value(k) assert np.isclose(other_param_val, v) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_design_fixing(self): fd_method = "central" @@ -244,7 +301,6 @@ def test_reactor_fd_central_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_design_fixing(self): fd_method = "backward" @@ -295,7 +351,6 @@ def test_reactor_fd_backward_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_design_fixing(self): fd_method = "forward" @@ -346,6 +401,51 @@ def test_reactor_fd_forward_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_user_initialization(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + FIM_prior = np.ones((4, 4)) + FIM_initial = np.eye(4) + FIM_prior + JAC_initial = np.ones((27, 4)) * 2 + L_initial = np.tril( + np.ones((4, 4)) * 3 + ) # Must input lower triangular to get equality + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=FIM_prior, + jac_initial=JAC_initial, + fim_initial=FIM_initial, + L_initial=L_initial, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.create_doe_model() + + # Grab the matrix values on the model + FIM, FIM_prior_model, Q, L, sigma = get_FIM_FIMPrior_Q_L(doe_obj) + + # Make sure they match the inputs we gave + assert np.array_equal(FIM, FIM_initial) + assert np.array_equal(FIM_prior, FIM_prior_model) + assert np.array_equal(L_initial, L) + assert np.array_equal(JAC_initial, Q) + if __name__ == "__main__": unittest.main() From 1113b677adaa557324acff7810007b9434d81f66 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:56:52 -0400 Subject: [PATCH 057/203] Delete pyomo/contrib/doe/tests/test_reactor_example.py Removing old test files. --- .../contrib/doe/tests/test_reactor_example.py | 232 ------------------ 1 file changed, 232 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/test_reactor_example.py diff --git a/pyomo/contrib/doe/tests/test_reactor_example.py b/pyomo/contrib/doe/tests/test_reactor_example.py deleted file mode 100644 index 19fb4e61820..00000000000 --- a/pyomo/contrib/doe/tests/test_reactor_example.py +++ /dev/null @@ -1,232 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -# import libraries -from pyomo.common.dependencies import numpy as np, numpy_available, pandas_available -import pyomo.common.unittest as unittest -from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables -from pyomo.environ import value, ConcreteModel -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure -from pyomo.opt import SolverFactory - -ipopt_available = SolverFactory("ipopt").available() - - -class Test_Reaction_Kinetics_Example(unittest.TestCase): - def test_reaction_kinetics_create_model(self): - """Test the three options in the kinetics example.""" - # parmest option - mod = create_model(model_option="parmest") - - # global and block option - mod = ConcreteModel() - create_model(mod, model_option="stage1") - create_model(mod, model_option="stage2") - # both options need a given model, or raise errors - with self.assertRaises(ValueError): - create_model(model_option="stage1") - - with self.assertRaises(ValueError): - create_model(model_option="stage2") - - with self.assertRaises(ValueError): - create_model(model_option="NotDefined") - - @unittest.skipIf(not ipopt_available, "The 'ipopt' solver is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - @unittest.skipIf(not pandas_available, "Pandas is not available") - def test_kinetics_example_sequential_finite_then_optimize(self): - """Test the kinetics example with sequential_finite mode and then optimization""" - doe_object = self.specify_reaction_kinetics() - - # Test FIM calculation at nominal values - sensi_opt = "sequential_finite" - result = doe_object.compute_FIM( - mode=sensi_opt, scale_nominal_param_value=True, formula="central" - ) - result.result_analysis() - self.assertAlmostEqual(np.log10(result.trace), 2.7885, places=2) - self.assertAlmostEqual(np.log10(result.det), 2.8218, places=2) - self.assertAlmostEqual(np.log10(result.min_eig), -1.0123, places=2) - - ### check subset feature - sub_name = "C" - sub_indices = {0: ["CB", "CC"], 1: [0.125, 0.25, 0.5, 0.75, 0.875]} - - measure_subset = MeasurementVariables() - measure_subset.add_variables( - sub_name, indices=sub_indices, time_index_position=1 - ) - sub_result = result.subset(measure_subset) - sub_result.result_analysis() - - self.assertAlmostEqual(np.log10(sub_result.trace), 2.5535, places=2) - self.assertAlmostEqual(np.log10(sub_result.det), 1.3464, places=2) - self.assertAlmostEqual(np.log10(sub_result.min_eig), -1.5386, places=2) - - ### Test stochastic_program mode - # Prior information (scaled FIM with T=500 and T=300 experiments) - prior = np.asarray( - [ - [28.67892806, 5.41249739, -81.73674601, -24.02377324], - [5.41249739, 26.40935036, -12.41816477, -139.23992532], - [-81.73674601, -12.41816477, 240.46276004, 58.76422806], - [-24.02377324, -139.23992532, 58.76422806, 767.25584508], - ] - ) - doe_object2 = self.specify_reaction_kinetics(prior=prior) - - square_result, optimize_result = doe_object2.stochastic_program( - if_optimize=True, - if_Cholesky=True, - scale_nominal_param_value=True, - objective_option="det", - L_initial=np.linalg.cholesky(prior), - jac_initial=result.jaco_information.copy(), - tee_opt=True, - ) - - optimize_result.result_analysis() - ## 2024-May-26: changing this to test the objective instead of the optimal solution - ## It's possible the objective is flat and the optimal solution is not unique - # self.assertAlmostEqual(value(optimize_result.model.CA0[0]), 5.0, places=2) - # self.assertAlmostEqual(value(optimize_result.model.T[0.5]), 300, places=2) - self.assertAlmostEqual(np.log10(optimize_result.det), 5.744, places=2) - - square_result, optimize_result = doe_object2.stochastic_program( - if_optimize=True, - scale_nominal_param_value=True, - objective_option="trace", - jac_initial=result.jaco_information.copy(), - tee_opt=True, - ) - - optimize_result.result_analysis() - ## 2024-May-26: changing this to test the objective instead of the optimal solution - ## It's possible the objective is flat and the optimal solution is not unique - # self.assertAlmostEqual(value(optimize_result.model.CA0[0]), 5.0, places=2) - # self.assertAlmostEqual(value(optimize_result.model.T[0.5]), 300, places=2) - self.assertAlmostEqual(np.log10(optimize_result.trace), 3.340, places=2) - - @unittest.skipIf(not ipopt_available, "The 'ipopt' solver is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - @unittest.skipIf(not pandas_available, "Pandas is not available") - def test_kinetics_example_direct_k_aug(self): - doe_object = self.specify_reaction_kinetics() - - # Test FIM calculation at nominal values - sensi_opt = "direct_kaug" - result = doe_object.compute_FIM( - mode=sensi_opt, scale_nominal_param_value=True, formula="central" - ) - result.result_analysis() - self.assertAlmostEqual(np.log10(result.trace), 2.789, places=2) - self.assertAlmostEqual(np.log10(result.det), 2.8247, places=2) - self.assertAlmostEqual(np.log10(result.min_eig), -1.0112, places=2) - - ### check subset feature - sub_name = "C" - sub_indices = {0: ["CB", "CC"], 1: [0.125, 0.25, 0.5, 0.75, 0.875]} - - measure_subset = MeasurementVariables() - measure_subset.add_variables( - sub_name, indices=sub_indices, time_index_position=1 - ) - sub_result = result.subset(measure_subset) - sub_result.result_analysis() - - self.assertAlmostEqual(np.log10(sub_result.trace), 2.5535, places=2) - self.assertAlmostEqual(np.log10(sub_result.det), 1.3464, places=2) - self.assertAlmostEqual(np.log10(sub_result.min_eig), -1.5386, places=2) - - def specify_reaction_kinetics(self, prior=None): - ### Define inputs - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # Define parameter nominal value - parameter_dict = {"A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} - - # measurement object - variable_name = "C" - indices = {0: ["CA", "CB", "CC"], 1: t_control} - - measurements = MeasurementVariables() - measurements.add_variables( - variable_name, indices=indices, time_index_position=1 - ) - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - exp_design.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - design_names = exp_design.variable_names - exp1 = [5, 570, 300, 300, 300, 300, 300, 300, 300, 300] - exp1_design_dict = dict(zip(design_names, exp1)) - - exp_design.update_values(exp1_design_dict) - - doe_object = DesignOfExperiments( - parameter_dict, - exp_design, - measurements, - create_model, - discretize_model=disc_for_measure, - prior_FIM=prior, - ) - - return doe_object - - -if __name__ == "__main__": - unittest.main() From 7d5c562dab7b6dc71269a0e9285ce2734e8cdcbe Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:57:07 -0400 Subject: [PATCH 058/203] Delete pyomo/contrib/doe/tests/test_example.py Removing old test files. --- pyomo/contrib/doe/tests/test_example.py | 86 ------------------------- 1 file changed, 86 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/test_example.py diff --git a/pyomo/contrib/doe/tests/test_example.py b/pyomo/contrib/doe/tests/test_example.py deleted file mode 100644 index e4ffbe89142..00000000000 --- a/pyomo/contrib/doe/tests/test_example.py +++ /dev/null @@ -1,86 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -from pyomo.common.dependencies import ( - numpy as np, - numpy_available, - pandas as pd, - pandas_available, - scipy_available, -) - -import pyomo.common.unittest as unittest - -from pyomo.opt import SolverFactory - -ipopt_available = SolverFactory("ipopt").available() - - -class TestReactorExamples(unittest.TestCase): - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not scipy_available, "scipy is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_compute_FIM(self): - from pyomo.contrib.doe.examples import reactor_compute_FIM - - reactor_compute_FIM.main() - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_optimize_doe(self): - from pyomo.contrib.doe.examples import reactor_optimize_doe - - reactor_optimize_doe.main() - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_grid_search(self): - from pyomo.contrib.doe.examples import reactor_grid_search - - reactor_grid_search.main() - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_design_slim_create_model_interface(self): - from pyomo.contrib.doe.examples import reactor_design - - reactor_design.main(legacy_create_model_interface=False) - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_design_legacy_create_model_interface(self): - from pyomo.contrib.doe.examples import reactor_design - - reactor_design.main(legacy_create_model_interface=True) - - -if __name__ == "__main__": - unittest.main() From 7a9e0c9ecd400ca74e426c4b54a653e02291bee8 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:57:20 -0400 Subject: [PATCH 059/203] Delete pyomo/contrib/doe/tests/test_fim_doe.py Removing old test files. --- pyomo/contrib/doe/tests/test_fim_doe.py | 468 ------------------------ 1 file changed, 468 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/test_fim_doe.py diff --git a/pyomo/contrib/doe/tests/test_fim_doe.py b/pyomo/contrib/doe/tests/test_fim_doe.py deleted file mode 100644 index d9a8d60fdb4..00000000000 --- a/pyomo/contrib/doe/tests/test_fim_doe.py +++ /dev/null @@ -1,468 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - -from pyomo.common.dependencies import numpy as np, numpy_available -import pyomo.common.unittest as unittest -from pyomo.contrib.doe import ( - MeasurementVariables, - DesignVariables, - ScenarioGenerator, - DesignOfExperiments, - VariablesWithIndices, -) -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure - - -class TestMeasurementError(unittest.TestCase): - - def test_with_time_plus_one_extra_index(self): - """This tests confirms the typical usage with a time index plus one extra index. - - This test should execute without throwing any errors. - - """ - - MeasurementVariables().add_variables( - "C", indices={0: ["A", "B", "C"], 1: [0, 0.5, 1.0]}, time_index_position=1 - ) - - def test_with_time_plus_two_extra_indices(self): - """This tests confirms the typical usage with a time index plus two extra indices. - - This test should execute without throwing any errors. - - """ - - MeasurementVariables().add_variables( - "C", - indices={ - 0: ["A", "B", "C"], # species - 1: [0, 0.5, 1.0], # time - 2: [1, 2, 3], - }, # position - time_index_position=1, - ) - - def test_time_index_position_out_of_bounds(self): - """This test confirms that an error is thrown when the time index position is out of bounds.""" - - # if time index is not in indices, an value error is thrown. - with self.assertRaises(ValueError): - MeasurementVariables().add_variables( - "C", - indices={0: ["CA", "CB", "CC"], 1: [0, 0.5, 1.0]}, # species # time - time_index_position=2, # this is out of bounds - ) - - def test_single_measurement_variable(self): - """This test confirms we can specify a single measurement variable without - specifying the indices. - - The test should execute with no errors. - """ - measurements = MeasurementVariables() - measurements.add_variables("HelloWorld", indices=None, time_index_position=None) - - def test_without_time_index(self): - """This test confirms we can add a measurement variable without specifying the time index. - - The test should execute with no errors. - - """ - - MeasurementVariables().add_variables( - "C", - indices={0: ["CA", "CB", "CC"]}, # species as only index - time_index_position=None, # no time index - ) - - def test_only_time_index(self): - """This test confirms we can add a measurement variable without specifying the variable name. - - The test should execute with no errors. - - """ - - MeasurementVariables().add_variables( - "HelloWorld", # name of the variable - indices={0: [0, 0.5, 1.0]}, - time_index_position=0, - ) - - def test_with_no_measurement_name(self): - """This test confirms that an error is thrown when None is used as the measurement name.""" - - with self.assertRaises(TypeError): - MeasurementVariables().add_variables( - None, indices={0: [0, 0.5, 1.0]}, time_index_position=0 - ) - - def test_with_non_string_measurement_name(self): - """This test confirms that an error is thrown when a non-string is used as the measurement name.""" - - with self.assertRaises(TypeError): - MeasurementVariables().add_variables( - 1, indices={0: [0, 0.5, 1.0]}, time_index_position=0 - ) - - def test_non_integer_index_keys(self): - """This test confirms that strings can be used as keys for specifying the indices. - - Warning: it is possible this usage breaks something else in Pyomo.DoE. - There may be an implicit assumption that the order of the keys must match the order - of the indices in the Pyomo model. - - """ - - MeasurementVariables().add_variables( - "C", - indices={"species": ["CA", "CB", "CC"], "time": [0, 0.5, 1.0]}, - time_index_position="time", - ) - - def test_no_measurements(self): - """This test confirms that an error is thrown when the user forgets to add any measurements. - - It's okay to have no decision variables. With no measurement variables, the FIM is the zero matrix. - This (no measurements) is a common user mistake. - """ - - with self.assertRaises(ValueError): - decisions = DesignVariables() - measurements = MeasurementVariables() - DesignOfExperiments( - {}, decisions, measurements, create_model, disc_for_measure - ) - - -class TestDesignError(unittest.TestCase): - def test(self): - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # design object - exp_design = DesignVariables() - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - upper_bound = [ - 700, - 700, - 700, - 700, - 700, - 700, - 700, - 700, - 700, - 800, - ] # wrong upper bound since it has more elements than the length of variable names - lower_bound = [300, 300, 300, 300, 300, 300, 300, 300, 300] - - with self.assertRaises(ValueError): - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=lower_bound, - upper_bounds=upper_bound, - ) - - -@unittest.skipIf(not numpy_available, "Numpy is not available") -class TestPriorFIMError(unittest.TestCase): - def test(self): - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # measurement object - variable_name = "C" - indices = {0: ["CA", "CB", "CC"], 1: t_control} - - measurements = MeasurementVariables() - measurements.add_variables( - variable_name, indices=indices, time_index_position=1 - ) - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - exp_design.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - parameter_dict = {"A1": 1, "A2": 1, "E1": 1} - - # empty prior - prior_right = [[0] * 3 for i in range(3)] - prior_pass = [[0] * 5 for i in range(10)] - - # check if the error can be thrown when given a wrong shape of FIM prior - with self.assertRaises(ValueError): - doe_object = DesignOfExperiments( - parameter_dict, - exp_design, - measurements, - create_model, - prior_FIM=prior_pass, - discretize_model=disc_for_measure, - ) - - -class TestMeasurement(unittest.TestCase): - """Test the MeasurementVariables class, specify, add_element, update_variance, check_subset functions.""" - - def test_setup(self): - ### add_element function - - # control time for C [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # control time for T [h] - t_control2 = [0.2, 0.4, 0.6, 0.8] - - # measurement object - measurements = MeasurementVariables() - - # add variable C - variable_name = "C" - indices = {0: ["CA", "CB", "CC"], 1: t_control} - measurements.add_variables( - variable_name, indices=indices, time_index_position=1 - ) - - # add variable T - variable_name2 = "T" - indices2 = {0: [1, 3, 5], 1: t_control2} - measurements.add_variables( - variable_name2, indices=indices2, time_index_position=1, variance=10 - ) - - # check variable names - self.assertEqual(measurements.variable_names[0], "C[CA,0]") - self.assertEqual(measurements.variable_names[1], "C[CA,0.125]") - self.assertEqual(measurements.variable_names[-1], "T[5,0.8]") - self.assertEqual(measurements.variable_names[-2], "T[5,0.6]") - self.assertEqual(measurements.variance["T[5,0.4]"], 10) - self.assertEqual(measurements.variance["T[5,0.6]"], 10) - self.assertEqual(measurements.variance["T[5,0.4]"], 10) - self.assertEqual(measurements.variance["T[5,0.6]"], 10) - - ### specify function - var_names = [ - "C[CA,0]", - "C[CA,0.125]", - "C[CA,0.875]", - "C[CA,1]", - "C[CB,0]", - "C[CB,0.125]", - "C[CB,0.25]", - "C[CB,0.375]", - "C[CC,0]", - "C[CC,0.125]", - "C[CC,0.25]", - "C[CC,0.375]", - ] - - measurements2 = MeasurementVariables() - measurements2.set_variable_name_list(var_names) - - self.assertEqual(measurements2.variable_names[1], "C[CA,0.125]") - self.assertEqual(measurements2.variable_names[-1], "C[CC,0.375]") - - ### check_subset function - self.assertTrue(measurements.check_subset(measurements2)) - - -class TestDesignVariable(unittest.TestCase): - """Test the DesignVariable class, specify, add_element, add_bounds, update_values.""" - - def test_setup(self): - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - exp_design.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - self.assertEqual( - exp_design.variable_names, - [ - "CA0[0]", - "T[0]", - "T[0.125]", - "T[0.25]", - "T[0.375]", - "T[0.5]", - "T[0.625]", - "T[0.75]", - "T[0.875]", - "T[1]", - ], - ) - self.assertEqual(exp_design.variable_names_value["CA0[0]"], 5) - self.assertEqual(exp_design.variable_names_value["T[0]"], 470) - self.assertEqual(exp_design.upper_bounds["CA0[0]"], 5) - self.assertEqual(exp_design.upper_bounds["T[0]"], 700) - self.assertEqual(exp_design.lower_bounds["CA0[0]"], 1) - self.assertEqual(exp_design.lower_bounds["T[0]"], 300) - - design_names = exp_design.variable_names - exp1 = [4, 600, 300, 300, 300, 300, 300, 300, 300, 300] - exp1_design_dict = dict(zip(design_names, exp1)) - exp_design.update_values(exp1_design_dict) - self.assertEqual(exp_design.variable_names_value["CA0[0]"], 4) - self.assertEqual(exp_design.variable_names_value["T[0]"], 600) - - -class TestParameter(unittest.TestCase): - """Test the ScenarioGenerator class, generate_scenario function.""" - - def test_setup(self): - # set up parameter class - param_dict = {"A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} - - scenario_gene = ScenarioGenerator(param_dict, formula="central", step=0.1) - parameter_set = scenario_gene.ScenarioData - - self.assertAlmostEqual(parameter_set.eps_abs["A1"], 16.9582, places=1) - self.assertAlmostEqual(parameter_set.eps_abs["E1"], 1.5554, places=1) - self.assertEqual(parameter_set.scena_num["A2"], [2, 3]) - self.assertEqual(parameter_set.scena_num["E1"], [4, 5]) - self.assertAlmostEqual(parameter_set.scenario[0]["A1"], 93.2699, places=1) - self.assertAlmostEqual(parameter_set.scenario[2]["A2"], 408.8895, places=1) - self.assertAlmostEqual(parameter_set.scenario[-1]["E2"], 13.54, places=1) - self.assertAlmostEqual(parameter_set.scenario[-2]["E2"], 16.55, places=1) - - -class TestVariablesWithIndices(unittest.TestCase): - """Test the DesignVariable class, specify, add_element, add_bounds, update_values.""" - - def test_setup(self): - special = VariablesWithIndices() - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - ### add_element function - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - special.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - special.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - self.assertEqual( - special.variable_names, - [ - "CA0[0]", - "T[0]", - "T[0.125]", - "T[0.25]", - "T[0.375]", - "T[0.5]", - "T[0.625]", - "T[0.75]", - "T[0.875]", - "T[1]", - ], - ) - self.assertEqual(special.variable_names_value["CA0[0]"], 5) - self.assertEqual(special.variable_names_value["T[0]"], 470) - self.assertEqual(special.upper_bounds["CA0[0]"], 5) - self.assertEqual(special.upper_bounds["T[0]"], 700) - self.assertEqual(special.lower_bounds["CA0[0]"], 1) - self.assertEqual(special.lower_bounds["T[0]"], 300) - - -if __name__ == "__main__": - unittest.main() From ccc0be665853599cbb6ebd562d6846919e32cd5a Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:40:42 -0400 Subject: [PATCH 060/203] Corrected flags and added new test file for model building --- pyomo/contrib/doe/__init__.py | 1 + pyomo/contrib/doe/doe.py | 8 +- .../tests/experiment_class_example_flags.py | 241 ++++++++++++++++++ 3 files changed, 246 insertions(+), 4 deletions(-) create mode 100644 pyomo/contrib/doe/tests/experiment_class_example_flags.py diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index 2a667660056..6ce3ada420e 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -15,4 +15,5 @@ ModelOptionLib, FiniteDifferenceStep, ) +from .tests import experiment_class_example, experiment_class_example_flags from .utils import rescale_FIM diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 9ec562ba562..8d1263e9fe2 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1267,7 +1267,7 @@ def check_model_labels(self, model=None): try: outputs = [k.name for k, v in model.experiment_outputs.items()] except: - RuntimeError( + raise RuntimeError( "Experiment model does not have suffix " + '"experiment_outputs".' ) @@ -1275,7 +1275,7 @@ def check_model_labels(self, model=None): try: outputs = [k.name for k, v in model.experiment_inputs.items()] except: - RuntimeError( + raise RuntimeError( "Experiment model does not have suffix " + '"experiment_inputs".' ) @@ -1283,7 +1283,7 @@ def check_model_labels(self, model=None): try: outputs = [k.name for k, v in model.unknown_parameters.items()] except: - RuntimeError( + raise RuntimeError( "Experiment model does not have suffix " + '"unknown_parameters".' ) @@ -1291,7 +1291,7 @@ def check_model_labels(self, model=None): try: outputs = [k.name for k, v in model.measurement_error.items()] except: - RuntimeError( + raise RuntimeError( "Experiment model does not have suffix " + '"measurement_error".' ) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py new file mode 100644 index 00000000000..2a555dd61d4 --- /dev/null +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -0,0 +1,241 @@ +# === Required imports === +import pyomo.environ as pyo +from pyomo.dae import ContinuousSet, DerivativeVar, Simulator + +import itertools +import json +# ======================== + + +def expand_model_components(m, base_components, index_sets): + """ + Takes model components and index sets and returns the + model component labels. + + Arguments + --------- + m: Pyomo model + base_components: list of variables from model 'm' + index_sets: list, same length as base_components, where each + element is a list of index sets, or None + """ + for val, indexes in itertools.zip_longest(base_components, index_sets): + # If the variable has no index, + # add just the model component + if not val.is_indexed(): + yield val + # If the component is indexed but no + # index supplied, add all indices + elif indexes is None: + yield from val.values() + else: + for j in itertools.product(*indexes): + yield val[j] + + +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) + + +class ReactorExperiment(object): + def __init__(self, data, nfe, ncp): + self.data = data + self.nfe = nfe + self.ncp = ncp + self.model = None + + def get_labeled_model(self, flag=0): + if self.model is None: + self.create_model() + self.finalize_model() + self.label_experiment(flag=flag) + return self.model + + def create_model(self): + """ + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. + + Return + ------ + m: a Pyomo.DAE model + """ + + m = self.model = pyo.ConcreteModel() + + # Model parameters + m.R = pyo.Param(mutable=False, initialize=8.314) + + # m.A1 = pyo.Param(mutable=True) + # m.E1 = pyo.Param(mutable=True) + # m.A2 = pyo.Param(mutable=True) + # m.E2 = pyo.Param(mutable=True) + + # Define model variables + ######################## + # time + m.t = ContinuousSet(bounds=[0, 1]) + + # Concentrations + m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Temperature + m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Arrhenius rate law equations + m.A1 = pyo.Var(within=pyo.NonNegativeReals) + m.E1 = pyo.Var(within=pyo.NonNegativeReals) + m.A2 = pyo.Var(within=pyo.NonNegativeReals) + m.E2 = pyo.Var(within=pyo.NonNegativeReals) + + # Differential variables (Conc.) + m.dCAdt = DerivativeVar(m.CA, wrt=m.t) + m.dCBdt = DerivativeVar(m.CB, wrt=m.t) + + ######################## + # End variable def. + + # Equation def'n + ######################## + + # Expression for rate constants + @m.Expression(m.t) + def k1(m, t): + return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) + + @m.Expression(m.t) + def k2(m, t): + return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) + + # Concentration odes + @m.Constraint(m.t) + def CA_rxn_ode(m, t): + return m.dCAdt[t] == -m.k1[t] * m.CA[t] + + @m.Constraint(m.t) + def CB_rxn_ode(m, t): + return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] + + # algebraic balance for concentration of C + # Valid because the reaction system (A --> B --> C) is equimolar + @m.Constraint(m.t) + def CC_balance(m, t): + return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] + + ######################## + # End equation def'n + + def finalize_model(self): + """ + Example finalize model function. There are two main tasks + here: + 1. Extracting useful information for the model to align + with the experiment. (Here: CA0, t_final, t_control) + 2. Discretizing the model subject to this information. + + Arguments + --------- + m: Pyomo model + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ + m = self.model + + # Unpacking data before simulation + control_points = self.data['control_points'] + + m.CA[0].value = self.data['CA0'] + m.CB[0].fix(self.data['CB0']) + m.t.update(self.data['t_range']) + m.t.update(control_points) + m.A1.fix(self.data['A1']) + m.A2.fix(self.data['A2']) + m.E1.fix(self.data['E1']) + m.E2.fix(self.data['E2']) + + m.CA[0].setlb(self.data['CA_bounds'][0]) + m.CA[0].setub(self.data['CA_bounds'][1]) + + m.t_control = control_points + + # Discretizing the model + discr = pyo.TransformationFactory("dae.collocation") + discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) + + # Initializing Temperature in the model + cv = None + for t in m.t: + if t in control_points: + cv = control_points[t] + m.T[t].setlb(self.data['T_bounds'][0]) + m.T[t].setub(self.data['T_bounds'][1]) + m.T[t] = cv + + @m.Constraint(m.t - control_points) + def T_control(m, t): + """ + Piecewise constant Temperature between control points + """ + neighbour_t = max(tc for tc in control_points if tc < t) + return m.T[t] == m.T[neighbour_t] + + # sim.initialize_model() + + + def label_experiment_impl(self, index_sets_meas, flag=0): + """ + Example for annotating (labeling) the model with a + full experiment. + + Arguments + --------- + + """ + m = self.model + base_comp_meas = [m.CA, m.CB, m.CC] + + if flag != 1: + # Grab measurement labels + print("Made experimental outputs!") + m.experiment_outputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + if flag != 2: + # Adding no error for measurements currently + m.measurement_error = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + + if flag != 3: + # Grab design variables + base_comp_des = [m.CA, m.T] + index_sets_des = [[[m.t.first()]], [m.t_control]] + m.experiment_inputs = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) + + if flag != 4: + m.unknown_parameters = pyo.Suffix( + direction=pyo.Suffix.LOCAL, + ) + m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) + + +class FullReactorExperiment(ReactorExperiment): + def label_experiment(self, flag=0): + m = self.model + return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]], flag=flag) + From 31ede58b1513ba618a7e3073bac864d011eb44d5 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:46:23 -0400 Subject: [PATCH 061/203] Added some error tests Caught a bug while adding tests for checking model in the generate scenarios function. --- pyomo/contrib/doe/doe.py | 2 +- .../tests/experiment_class_example_flags.py | 1 - pyomo/contrib/doe/tests/test_doe_errors.py | 157 ++++++++++++++++++ 3 files changed, 158 insertions(+), 2 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 8d1263e9fe2..264e9de94ae 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -954,7 +954,7 @@ def _generate_scenario_blocks(self, model=None): model.base_model = self.experiment.get_labeled_model(**self.args).clone() # Check the model that labels are correct - self.check_model_labels(model=model) + self.check_model_labels(model=model.base_model) # Gather lengths of label structures for later use in the model build process self.n_parameters = len(model.base_model.unknown_parameters) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 2a555dd61d4..731ffa577e4 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -205,7 +205,6 @@ def label_experiment_impl(self, index_sets_meas, flag=0): if flag != 1: # Grab measurement labels - print("Made experimental outputs!") m.experiment_outputs = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index e69de29bb2d..f68788a8fe2 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -0,0 +1,157 @@ +from pyomo.common.dependencies import ( + numpy as np, + numpy_available, + pandas as pd, + pandas_available, +) + +from pyomo.contrib.doe.tests.experiment_class_example_flags import * +from pyomo.contrib.doe import * + + +import pyomo.common.unittest as unittest + +from pyomo.opt import SolverFactory + +from pathlib import Path + +ipopt_available = SolverFactory("ipopt").available() + +DATA_DIR = Path(__file__).parent +file_path = DATA_DIR / "result.json" + +f = open(file_path) +data_ex = json.load(f) +data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} + +class TestReactorExampleErrors(unittest.TestCase): + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_no_experiment_outputs(self): + fd_method = "central" + obj_used = "trace" + flag_val = 1 # Value for faulty model build mode - 1: No exp outputs + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Experiment model does not have suffix " + '"experiment_outputs".' + ): + doe_obj.create_doe_model() + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_no_measurement_error(self): + fd_method = "central" + obj_used = "trace" + flag_val = 2 # Value for faulty model build mode - 2: No meas error + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Experiment model does not have suffix " + '"measurement_error".' + ): + doe_obj.create_doe_model() + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_no_experiment_inputs(self): + fd_method = "central" + obj_used = "trace" + flag_val = 3 # Value for faulty model build mode - 3: No exp inputs/design vars + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Experiment model does not have suffix " + '"experiment_inputs".' + ): + doe_obj.create_doe_model() + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_no_unknown_parameters(self): + fd_method = "central" + obj_used = "trace" + flag_val = 4 # Value for faulty model build mode - 4: No unknown params + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Experiment model does not have suffix " + '"unknown_parameters".' + ): + doe_obj.create_doe_model() + +if __name__ == "__main__": + unittest.main() From a66bd6242d1d4ed6d664a821adddcb5f3c19c9b1 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:46:50 -0400 Subject: [PATCH 062/203] Updated model to have good imports And updated the file call to be robust. --- pyomo/contrib/doe/tests/test_doe_build.py | 9 +++++++-- pyomo/contrib/doe/tests/test_doe_solve.py | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 79d21fe6f6f..9365b289399 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -5,7 +5,7 @@ pandas_available, ) -from experiment_class_example import * +from pyomo.contrib.doe.tests.experiment_class_example import * from pyomo.contrib.doe import * @@ -13,9 +13,14 @@ from pyomo.opt import SolverFactory +from pathlib import Path + ipopt_available = SolverFactory("ipopt").available() -f = open("result.json") +DATA_DIR = Path(__file__).parent +file_path = DATA_DIR / "result.json" + +f = open(file_path) data_ex = json.load(f) data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index b88a471e43a..5577a56f055 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -5,7 +5,7 @@ pandas_available, ) -from experiment_class_example import * +from pyomo.contrib.doe.tests.experiment_class_example import * from pyomo.contrib.doe import * @@ -13,9 +13,14 @@ from pyomo.opt import SolverFactory +from pathlib import Path + ipopt_available = SolverFactory("ipopt").available() -f = open("result.json") +DATA_DIR = Path(__file__).parent +file_path = DATA_DIR / "result.json" + +f = open(file_path) data_ex = json.load(f) data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} From fe74e73f1edab89893e968a6c3d4a2371a2d5f7f Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:42:31 -0400 Subject: [PATCH 063/203] Updated all asserts to be raises; Added tests --- pyomo/contrib/doe/doe.py | 117 ++- .../tests/experiment_class_example_flags.py | 14 +- pyomo/contrib/doe/tests/test_doe_errors.py | 689 ++++++++++++++++++ 3 files changed, 748 insertions(+), 72 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 264e9de94ae..4b795062f7c 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -155,10 +155,9 @@ def __init__( logger_level: Specify the level of the logger. Change to logging.DEBUG for all messages. """ - # Assert that the Experiment object has callable ``get_labeled_model`` function - assert callable( - getattr(experiment, "get_labeled_model") - ), "The experiment object must have a ``get_labeled_model`` function" + # Check if the Experiment object has callable ``get_labeled_model`` function + if not hasattr(experiment, "get_labeled_model"): + raise ValueError("The experiment object must have a ``get_labeled_model`` function") # Set the experiment object from the user self.experiment = experiment @@ -234,6 +233,11 @@ def run_doe(self, model=None, results_file=None): default: None --> don't save """ + # Check results file name + if results_file is not None: + if type(results_file) not in [Path, str, ]: + raise ValueError("``results_file`` must be either a Path object or a string.") + # Start timer sp_timer = TicTocTimer() sp_timer.tic(msg=None) @@ -357,10 +361,6 @@ def run_doe(self, model=None, results_file=None): # If the user specifies to save the file, do it here as a json if results_file is not None: - assert type(results_file) in [ - Path, - str, - ], "`results_file` must be either a Path object or a string." with open(results_file, "w") as file: json.dump(self.results, file) @@ -962,11 +962,10 @@ def _generate_scenario_blocks(self, model=None): self.n_experiment_inputs = len(model.base_model.experiment_inputs) self.n_experiment_outputs = len(model.base_model.experiment_outputs) - assert ( - self.n_measurement_error == self.n_experiment_outputs - ), "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( + if self.n_measurement_error != self.n_experiment_outputs: + raise ValueError("Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( self.n_experiment_outputs, self.n_measurement_error - ) + )) self.logger.info("Experiment output and measurement error lengths match.") @@ -1310,23 +1309,19 @@ def check_model_FIM(self, FIM=None): ---------- model: model for suffix checking, Default: None, (self.model) """ - assert FIM.shape == ( - self.n_parameters, - self.n_parameters, - ), "Shape of FIM provided should be n_parameters x n_parameters, or {}, FIM provided has shape: {}".format( - (self.n_parameters, self.n_parameters), FIM.shape - ) + if FIM.shape != (self.n_parameters, self.n_parameters): + raise ValueError("Shape of FIM provided should be n parameters by n parameters, or {} by {}, FIM provided has shape {} by {}".format( + self.n_parameters, self.n_parameters, FIM.shape[0], FIM.shape[1] + )) self.logger.info("FIM provided matches expected dimensions from model.") # Check the jacobian shape against what is expected from the model. def check_model_jac(self, jac=None): - assert jac.shape == ( - self.n_experiment_outputs, - self.n_parameters, - ), "Shape of Jacobian provided should be n_experiment_outputs x n_parameters, or {}, Jacobian provided has shape: {}".format( - (self.n_experiment_outputs, self.n_parameters), jac.shape - ) + if jac.shape != (self.n_experiment_outputs, self.n_parameters): + raise ValueError("Shape of Jacobian provided should be n experiment outputs by n parameters, or {} by {}, Jacobian provided has shape {} by {}".format( + self.n_experiment_outputs, self.n_parameters, jac.shape[0], jac.shape[1] + )) self.logger.info("Jacobian provided matches expected dimensions from model.") @@ -1351,9 +1346,8 @@ def update_FIM_prior(self, model=None, FIM=None): "FIM input for update_FIM_prior must be a 2D, square numpy array." ) - assert hasattr( - model, "fim" - ), "``fim`` is not defined on the model provided. Please build the model first." + if not hasattr(model, "fim"): + raise RuntimeError("``fim`` is not defined on the model provided. Please build the model first.") self.check_model_FIM(model, FIM) @@ -1560,47 +1554,38 @@ def draw_factorial_figure( """ if results is None: - assert hasattr( - self, "fim_factorial_results" - ), "Results must be provided or the compute_FIM_full_factorial function must be run." + if not hasattr(self, "fim_factorial_results"): + raise RuntimeError("Results must be provided or the compute_FIM_full_factorial function must be run.") results = self.fim_factorial_results full_design_variable_names = [ k.name for k, v in self.factorial_model.experiment_inputs.items() ] else: - assert ( - full_design_variable_names is not None - ), "If results object is provided, you must include all the design variable names." + if full_design_variable_names is None: + raise ValueError("If results object is provided, you must include all the design variable names.") des_names = full_design_variable_names # Inputs must exist for the function to do anything # ToDo: Put in a default value function????? - assert ( - sensitivity_design_variables is not None - ), "``sensitivity_design_variables`` must be included." - assert ( - fixed_design_variables is not None - ), "``sensitivity_design_variables`` must be included." + if sensitivity_design_variables is None: + raise ValueError("``sensitivity_design_variables`` must be included.") + + if fixed_design_variables is None: + raise ValueError("``fixed_design_variables`` must be included.") # Check that the provided design variables are within the results object check_des_vars = True for k, v in fixed_design_variables.items(): - check_des_vars *= k in [k for k, v in results.items()] + check_des_vars *= k in ([k2 for k2, v2 in results.items()]) check_sens_vars = True for k in sensitivity_design_variables: - check_sens_vars *= k in [k for k, v in results.items()] + check_sens_vars *= (k in [k2 for k2, v2 in results.items()]) - assert ( - check_des_vars - ), "Fixed design variables {} do not all appear in the results object keys {}.".format( - fixed_design_variables.keys(), results.keys() - ) - assert ( - check_sens_vars - ), "Sensitivity design variables {} do not all appear in the results object keys {}.".format( - sensitivity_design_variables.keys(), results.keys() - ) + if not check_des_vars: + raise ValueError("Fixed design variables do not all appear in the results object keys.") + if not check_sens_vars: + raise ValueError("Sensitivity design variables do not all appear in the results object keys.") # ToDo: Make it possible to plot pair-wise sensitivities for all variables # e.g. a curve like low-dimensional posterior distributions @@ -1953,9 +1938,8 @@ def get_FIM(self, model=None): if model is None: model = self.model - assert hasattr( - model, "fim" - ), "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" + if not hasattr(model, "fim"): + raise RuntimeError("Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`") fim_vals = [ pyo.value(model.fim[i, j]) @@ -1992,9 +1976,8 @@ def get_sensitivity_matrix(self, model=None): if model is None: model = self.model - assert hasattr( - model, "sensitivity_jacobian" - ), "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" + if not hasattr(model, "sensitivity_jacboian"): + raise RuntimeError("Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`") Q_vals = [ pyo.value(model.sensitivity_jacobian[i, j]) @@ -2027,9 +2010,8 @@ def get_experiment_input_values(self, model=None): model = self.model if not hasattr(model, "experiment_inputs"): - assert hasattr( - model, "scenario_blocks" - ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, "scenario_blocks"): + raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") d_vals = [ pyo.value(k) @@ -2060,9 +2042,8 @@ def get_unknown_parameter_values(self, model=None): model = self.model if not hasattr(model, "unknown_parameters"): - assert hasattr( - model, "scenario_blocks" - ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, "scenario_blocks"): + raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") theta_vals = [ pyo.value(k) @@ -2093,9 +2074,8 @@ def get_experiment_output_values(self, model=None): model = self.model if not hasattr(model, "experiment_outputs"): - assert hasattr( - model, "scenario_blocks" - ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, "scenario_blocks"): + raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") y_hat_vals = [ pyo.value(k) @@ -2128,9 +2108,8 @@ def get_measurement_error_values(self, model=None): model = self.model if not hasattr(model, "measurement_error"): - assert hasattr( - model, "scenario_blocks" - ), "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + if not hasattr(model, "scenario_blocks"): + raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") sigma_vals = [ pyo.value(k) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 731ffa577e4..4b217ef691a 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -33,6 +33,11 @@ def expand_model_components(m, base_components, index_sets): yield val[j] +class BadExperiment(object): + def __init__(self): + self.model = None + + class Experiment(object): def __init__(self): self.model = None @@ -213,9 +218,12 @@ def label_experiment_impl(self, index_sets_meas, flag=0): if flag != 2: # Adding no error for measurements currently m.measurement_error = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + direction=pyo.Suffix.LOCAL, + ) + if flag == 5: + m.measurement_error.update((m.CA[0], 1e-2) for k in range(1)) + else: + m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) if flag != 3: # Grab design variables diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index f68788a8fe2..ba797a0fe59 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -25,6 +25,36 @@ data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} class TestReactorExampleErrors(unittest.TestCase): + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_no_get_labeled_model(self): + fd_method = "central" + obj_used = "trace" + flag_val = 1 # Value for faulty model build mode - 1: No exp outputs + + experiment = BadExperiment() + + with self.assertRaisesRegex( + ValueError, "The experiment object must have a ``get_labeled_model`` function" + ): + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_experiment_outputs(self): fd_method = "central" @@ -152,6 +182,665 @@ def test_reactor_check_no_unknown_parameters(self): RuntimeError, "Experiment model does not have suffix " + '"unknown_parameters".' ): doe_obj.create_doe_model() + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_bad_prior_size(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 0: full model + + prior_FIM = np.ones((5, 5)) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=prior_FIM, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + ValueError, "Shape of FIM provided should be n parameters by n parameters, or {} by {}, FIM provided has shape {} by {}".format( + 4, 4, prior_FIM.shape[0], prior_FIM.shape[1]) + ): + doe_obj.create_doe_model() + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_bad_jacobian_init_size(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 0: full model + + jac_init = np.ones((5, 5)) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=jac_init, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + ValueError, "Shape of Jacobian provided should be n experiment outputs by n parameters, or {} by {}, Jacobian provided has shape {} by {}".format( + 27, 4, jac_init.shape[0], jac_init.shape[1]) + ): + doe_obj.create_doe_model() + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_unbuilt_update_FIM(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 0: full model + + FIM_update = np.ones((4, 4)) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "``fim`` is not defined on the model provided. Please build the model first." + ): + doe_obj.update_FIM_prior(FIM=FIM_update) + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_results_file_name(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 0: Full model + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + ValueError, "``results_file`` must be either a Path object or a string." + ): + doe_obj.run_doe(results_file=int(15)) + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_measurement_and_output_length_match(self): + fd_method = "central" + obj_used = "trace" + flag_val = 5 # Value for faulty model build mode - 5: Mismatch error and output length + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + ValueError, "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( + 27, 1 + )): + doe_obj.create_doe_model() + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_grid_search_des_range_inputs(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + "not": [1, 5, 3], + "correct": [300, 700, 3], + } + + with self.assertRaisesRegex( + ValueError, "Design ranges keys must be a subset of experimental design names." + ): + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_premature_figure_drawing(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Results must be provided or the compute_FIM_full_factorial function must be run." + ): + doe_obj.draw_factorial_figure() + + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_figure_drawing_no_des_var_names(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + "CA[0]": [1, 5, 2], + "T[0]": [300, 700, 2], + } + + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) + + with self.assertRaisesRegex( + ValueError, "If results object is provided, you must include all the design variable names." + ): + doe_obj.draw_factorial_figure(results=doe_obj.fim_factorial_results) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_figure_drawing_no_sens_names(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + "CA[0]": [1, 5, 2], + "T[0]": [300, 700, 2], + } + + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) + + with self.assertRaisesRegex( + ValueError, "``sensitivity_design_variables`` must be included." + ): + doe_obj.draw_factorial_figure() + + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_figure_drawing_no_fixed_names(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + "CA[0]": [1, 5, 2], + "T[0]": [300, 700, 2], + } + + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) + + with self.assertRaisesRegex( + ValueError, "``fixed_design_variables`` must be included." + ): + doe_obj.draw_factorial_figure(sensitivity_design_variables={"dummy": "var"}) + + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_figure_drawing_bad_fixed_names(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + "CA[0]": [1, 5, 2], + "T[0]": [300, 700, 2], + } + + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) + + with self.assertRaisesRegex( + ValueError, "Fixed design variables do not all appear in the results object keys." + ): + doe_obj.draw_factorial_figure(sensitivity_design_variables={"CA[0]": 1}, fixed_design_variables={"bad": "entry"}) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_figure_drawing_bad_sens_names(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + design_ranges = { + "CA[0]": [1, 5, 2], + "T[0]": [300, 700, 2], + } + + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) + + with self.assertRaisesRegex( + ValueError, "Sensitivity design variables do not all appear in the results object keys." + ): + doe_obj.draw_factorial_figure(sensitivity_design_variables={"bad": "entry"}, fixed_design_variables={"CA[0]": 1}) + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_get_FIM_without_FIM(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" + ): + doe_obj.get_FIM() + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_get_sens_mat_without_model(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" + ): + doe_obj.get_sensitivity_matrix() + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_get_exp_inputs_without_model(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ): + doe_obj.get_experiment_input_values() + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_get_exp_outputs_without_model(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ): + doe_obj.get_experiment_output_values() + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_get_unknown_params_without_model(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ): + doe_obj.get_unknown_parameter_values() + + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_get_meas_error_without_model(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={'flag': flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ): + doe_obj.get_measurement_error_values() + + if __name__ == "__main__": unittest.main() From da285a9580e379301bbf0f8b9bd05584246d2db6 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:49:01 -0400 Subject: [PATCH 064/203] Delete pyomo/contrib/doe/redesign directory Removing temporary space for testing as build was ongoing. --- .../doe/redesign/experiment_class_example.py | 249 ------------------ pyomo/contrib/doe/redesign/result.json | 1 - .../doe/redesign/simple_reaction_example.py | 214 --------------- pyomo/contrib/doe/redesign/test_build.py | 140 ---------- 4 files changed, 604 deletions(-) delete mode 100644 pyomo/contrib/doe/redesign/experiment_class_example.py delete mode 100644 pyomo/contrib/doe/redesign/result.json delete mode 100644 pyomo/contrib/doe/redesign/simple_reaction_example.py delete mode 100644 pyomo/contrib/doe/redesign/test_build.py diff --git a/pyomo/contrib/doe/redesign/experiment_class_example.py b/pyomo/contrib/doe/redesign/experiment_class_example.py deleted file mode 100644 index eae355ebc89..00000000000 --- a/pyomo/contrib/doe/redesign/experiment_class_example.py +++ /dev/null @@ -1,249 +0,0 @@ -# === Required imports === -import pyomo.environ as pyo -from pyomo.dae import ContinuousSet, DerivativeVar, Simulator - -import itertools -import json -# ======================== - - -def expand_model_components(m, base_components, index_sets): - """ - Takes model components and index sets and returns the - model component labels. - - Arguments - --------- - m: Pyomo model - base_components: list of variables from model 'm' - index_sets: list, same length as base_components, where each - element is a list of index sets, or None - """ - for val, indexes in itertools.zip_longest(base_components, index_sets): - # If the variable has no index, - # add just the model component - if not val.is_indexed(): - yield val - # If the component is indexed but no - # index supplied, add all indices - elif indexes is None: - yield from val.values() - else: - for j in itertools.product(*indexes): - yield val[j] - - -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) - - -class ReactorExperiment(object): - def __init__(self, data, nfe, ncp): - self.data = data - self.nfe = nfe - self.ncp = ncp - self.model = None - - def get_labeled_model(self): - if self.model is None: - self.create_model() - self.finalize_model() - self.label_experiment() - return self.model - - def create_model(self): - """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. - - Return - ------ - m: a Pyomo.DAE model - """ - - m = self.model = pyo.ConcreteModel() - - # Model parameters - m.R = pyo.Param(mutable=False, initialize=8.314) - - # m.A1 = pyo.Param(mutable=True) - # m.E1 = pyo.Param(mutable=True) - # m.A2 = pyo.Param(mutable=True) - # m.E2 = pyo.Param(mutable=True) - - # Define model variables - ######################## - # time - m.t = ContinuousSet(bounds=[0, 1]) - - # Concentrations - m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Temperature - m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Arrhenius rate law equations - m.A1 = pyo.Var(within=pyo.NonNegativeReals) - m.E1 = pyo.Var(within=pyo.NonNegativeReals) - m.A2 = pyo.Var(within=pyo.NonNegativeReals) - m.E2 = pyo.Var(within=pyo.NonNegativeReals) - - # Differential variables (Conc.) - m.dCAdt = DerivativeVar(m.CA, wrt=m.t) - m.dCBdt = DerivativeVar(m.CB, wrt=m.t) - - ######################## - # End variable def. - - # Equation def'n - ######################## - - # Expression for rate constants - @m.Expression(m.t) - def k1(m, t): - return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) - - @m.Expression(m.t) - def k2(m, t): - return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) - - # Concentration odes - @m.Constraint(m.t) - def CA_rxn_ode(m, t): - return m.dCAdt[t] == -m.k1[t] * m.CA[t] - - @m.Constraint(m.t) - def CB_rxn_ode(m, t): - return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] - - # algebraic balance for concentration of C - # Valid because the reaction system (A --> B --> C) is equimolar - @m.Constraint(m.t) - def CC_balance(m, t): - return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] - - ######################## - # End equation def'n - - def finalize_model(self): - """ - Example finalize model function. There are two main tasks - here: - 1. Extracting useful information for the model to align - with the experiment. (Here: CA0, t_final, t_control) - 2. Discretizing the model subject to this information. - - Arguments - --------- - m: Pyomo model - data: object containing vital experimental information - nfe: number of finite elements - ncp: number of collocation points for the finite elements - """ - m = self.model - - # Unpacking data before simulation - control_points = self.data['control_points'] - - m.CA[0].value = self.data['CA0'] - m.CB[0].fix(self.data['CB0']) - m.t.update(self.data['t_range']) - m.t.update(control_points) - m.A1.fix(self.data['A1']) - m.A2.fix(self.data['A2']) - m.E1.fix(self.data['E1']) - m.E2.fix(self.data['E2']) - - m.CA[0].setlb(self.data['CA_bounds'][0]) - m.CA[0].setub(self.data['CA_bounds'][1]) - - m.t_control = control_points - - # Discretizing the model - discr = pyo.TransformationFactory("dae.collocation") - discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) - - # Initializing Temperature in the model - cv = None - for t in m.t: - if t in control_points: - cv = control_points[t] - m.T[t].setlb(self.data['T_bounds'][0]) - m.T[t].setub(self.data['T_bounds'][1]) - m.T[t] = cv - - @m.Constraint(m.t - control_points) - def T_control(m, t): - """ - Piecewise constant Temperature between control points - """ - neighbour_t = max(tc for tc in control_points if tc < t) - return m.T[t] == m.T[neighbour_t] - - # sim.initialize_model() - - - def label_experiment_impl(self, index_sets_meas): - """ - Example for annotating (labeling) the model with a - full experiment. - - Arguments - --------- - - """ - m = self.model - - # Grab measurement labels - base_comp_meas = [m.CA, m.CB, m.CC] - m.experiment_outputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - - # Adding no error for measurements currently - m.measurement_error = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - - # Grab design variables - base_comp_des = [m.CA, m.T] - index_sets_des = [[[m.t.first()]], [m.t_control]] - m.experiment_inputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) - - m.unknown_parameters = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) - - -class FullReactorExperiment(ReactorExperiment): - def label_experiment(self): - m = self.model - return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]]) - - -class PartialReactorExperiment(ReactorExperiment): - def label_experiment(self): - """ - Example for annotating (labeling) the model with a - "partial" experiment. - - Arguments - --------- - - """ - m = self.model - return self.label_experiment_impl([[m.t_control], [[m.t.last()]], [[m.t.last()]]]) diff --git a/pyomo/contrib/doe/redesign/result.json b/pyomo/contrib/doe/redesign/result.json deleted file mode 100644 index 7e1b1a79a1b..00000000000 --- a/pyomo/contrib/doe/redesign/result.json +++ /dev/null @@ -1 +0,0 @@ -{"CA0": 5.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/simple_reaction_example.py b/pyomo/contrib/doe/redesign/simple_reaction_example.py deleted file mode 100644 index 3bf4ac8ef74..00000000000 --- a/pyomo/contrib/doe/redesign/simple_reaction_example.py +++ /dev/null @@ -1,214 +0,0 @@ -# === Required imports === -import pyomo.environ as pyo -from pyomo.dae import ContinuousSet, DerivativeVar, Simulator - -import itertools -import json -# ======================== - -def expand_model_components(m, base_components, index_sets): - """ - Takes model components and index sets and returns the - model component labels. - - Arguments - --------- - m: Pyomo model - base_components: list of variables from model 'm' - index_sets: list, same length as base_components, where each - element is a list of index sets, or None - """ - for val, indexes in itertools.zip_longest(base_components, index_sets): - # If the variable has no index, - # add just the model component - if not val.is_indexed(): - yield val - # If the component is indexed but no - # index supplied, add all indices - elif indexes is None: - yield from val.values() - else: - for j in itertools.product(*indexes): - yield val[j] - -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) - - -class SimpleReactorExperiment(object): - def __init__(self, data, nfe, ncp): - self.data = data - self.nfe = nfe - self.ncp = ncp - self.model = None - - def get_labeled_model(self): - if self.model is None: - self.create_model() - self.finalize_model() - self.label_experiment_impl(index_sets_meas=[[self.model.t_control], [self.model.t_control],]) - return self.model - - def create_model(self): - """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. - - Return - ------ - m: a Pyomo.DAE model - """ - - m = self.model = pyo.ConcreteModel() - - # Model parameters - m.R = pyo.Param(mutable=False, initialize=8.314) - - # Define model variables - ######################## - # time - m.t = ContinuousSet(bounds=[0, 1]) - - # Concentrations - m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Arrhenius rate law equations - # m.A1 = pyo.Var(within=pyo.NonNegativeReals) - m.A1 = pyo.Param(initialize=0, mutable=True) - - # Differential variables (Conc.) - m.dCAdt = DerivativeVar(m.CA, wrt=m.t) - # m.dCBdt = DerivativeVar(m.CB, wrt=m.t) - - ######################## - # End variable def. - - # Equation def'n - ######################## - - m.k1 = pyo.Var(m.t, initialize=0) - - @m.Constraint(m.t) - def k1_con(m, t): - return m.k1[t] == m.A1 - - # @m.Expression(m.t) - # def k1(m, t): - # return m.A1 - - # Concentration odes - @m.Constraint(m.t) - def CA_rxn_ode(m, t): - return m.dCAdt[t] == -m.k1[t] * m.CA[t] - - # @m.Constraint(m.t) - # def CB_rxn_ode(m, t): - # return m.dCBdt[t] == m.A1 * m.CB[t] - - # algebraic balance for concentration of B - # Valid because the reaction system (A --> B) is equimolar - @m.Constraint(m.t) - def CB_balance(m, t): - return m.CA[0] == m.CA[t] + m.CB[t] - - ######################## - # End equation def'n - - def finalize_model(self): - """ - Example finalize model function. There are two main tasks - here: - 1. Extracting useful information for the model to align - with the experiment. (Here: CA0, t_final, t_control) - 2. Discretizing the model subject to this information. - - Arguments - --------- - m: Pyomo model - data: object containing vital experimental information - nfe: number of finite elements - ncp: number of collocation points for the finite elements - """ - m = self.model - - # Unpacking data before simulation - control_points = self.data['control_points'] - - m.CA[0].fix(self.data['CA0']) - # m.CB[0].fix(self.data['CB0']) - m.A1.value = self.data['A1'] - # m.A1.fix(self.data['A1']) - - m.k1.pprint() - - m.t_control = control_points - - print('SIMULATING MODEL.') - - # TODO: add simulation for initialization????? - # Call the simulator (optional) - sim = Simulator(m, package='casadi') - tsim, profiles = sim.simulate(integrator='idas') - - print('SIMULATION COMPLETE.') - - # Discretizing the model - discr = pyo.TransformationFactory("dae.collocation") - discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) - - # sim.initialize_model() - - - def label_experiment_impl(self, index_sets_meas): - """ - Example for annotating (labeling) the model with a - full experiment. - - Arguments - --------- - - """ - m = self.model - - # Grab measurement labels - base_comp_meas = [m.CA, m.CB, ] - m.experiment_outputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - - # Adding no error for measurements currently - m.measurement_error = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - - # Grab design variables - base_comp_des = [m.CA, ] - index_sets_des = [[[m.t.first()]], ] - m.experiment_inputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) - - m.unknown_parameters = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) - m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1,]) - -f = open('result.json') -data_ex = json.load(f) -data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} - -experiments_simple = [ - SimpleReactorExperiment(data_ex, 32, 3), -] - -expanded_experiments_simple = [e.get_labeled_model() for e in experiments_simple] \ No newline at end of file diff --git a/pyomo/contrib/doe/redesign/test_build.py b/pyomo/contrib/doe/redesign/test_build.py deleted file mode 100644 index 05162179763..00000000000 --- a/pyomo/contrib/doe/redesign/test_build.py +++ /dev/null @@ -1,140 +0,0 @@ -from experiment_class_example import * -from pyomo.contrib.doe import * - -import numpy as np -import logging - -f = open('result.json') -data_ex = json.load(f) -data_ex['control_points'] = {float(k): v for k, v in data_ex['control_points'].items()} - -doe_obj = [0, 0, 0, 0,] -obj = ['trace', 'det', 'det'] - -for ind, fd in enumerate(['central', 'backward', 'forward']): - experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj[ind] = DesignOfExperiments( - experiment, - fd_formula='central', - step=1e-3, - objective_option=ObjectiveLib(obj[ind]), - scale_constant_value=1, - scale_nominal_param_value=(True and (ind != 2)), - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_initial=None, - L_LB=1e-7, - solver=None, - tee=False, - args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - logger_level=logging.INFO, - ) - doe_obj[ind].run_doe() - -# add a prior information (scaled FIM with T=500 and T=300 experiments) -# prior = np.asarray( - # [ - # [ 1745.81343391 1599.21859987 -3512.47892155 -7589.26220445] - # [ 1599.21859987 3525.63856364 -2900.94638673 -16465.46338508] - # [ -3512.47892155 -2900.94638673 7190.13048958 13849.96839993] - # [ -7589.26220445 -16465.46338508 13849.96839993 77674.03976715]] - # ] -# ) - -prior = None -design_ranges = { - 'CA[0]': [1, 5, 3], - 'T[0]': [300, 700, 3], -} -doe_obj[0].compute_FIM_full_factorial(design_ranges=design_ranges, method='kaug') - -doe_obj[0].compute_FIM(method='kaug') - -doe_obj[0].compute_FIM(method='sequential') - -print(doe_obj[0].kaug_FIM) - -# Optimal values -print("Optimal values for determinant optimized experimental design:") -print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.objective))) -print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.objective))) - -# New values -FIM_vals_new = [pyo.value(doe_obj[1].model.fim[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] -L_vals_new = [pyo.value(doe_obj[1].model.L[i, j]) for i in doe_obj[1].model.parameter_names for j in doe_obj[1].model.parameter_names] -Q_vals_new = [pyo.value(doe_obj[1].model.sensitivity_jacobian[i, j]) for i in doe_obj[1].model.output_names for j in doe_obj[1].model.parameter_names] -sigma_inv_new = [1 / v for k,v in doe_obj[1].model.scenario_blocks[0].measurement_error.items()] -param_vals = np.array([[v for k, v in doe_obj[1].model.scenario_blocks[0].unknown_parameters.items()], ]) - -FIM_vals_new_np = np.array(FIM_vals_new).reshape((4, 4)) - -for i in range(4): - for j in range(4): - if j < i: - FIM_vals_new_np[j, i] = FIM_vals_new_np[i, j] - -L_vals_new_np = np.array(L_vals_new).reshape((4, 4)) -Q_vals_new_np = np.array(Q_vals_new).reshape((27, 4)) - -sigma_inv_new_np = np.zeros((27, 27)) -for i in range(27): - sigma_inv_new_np[i, i] = sigma_inv_new[i] - -# Check cholesky factorization -print("Cholesky Checking") -print(L_vals_new_np @ L_vals_new_np.T) -print(FIM_vals_new_np) - -rescaled_FIM = rescale_FIM(FIM=FIM_vals_new_np, param_vals=param_vals) - -# Comparing values from compute FIM -print("Results from using compute FIM (first old, then new)") -print(doe_obj[0].kaug_FIM) -print(doe_obj[0].seq_FIM) -print(np.isclose(doe_obj[0].kaug_FIM, doe_obj[0].seq_FIM, 1e-2)) -print(np.log10(np.linalg.det(doe_obj[0].kaug_FIM))) -print(np.log10(np.linalg.det(doe_obj[0].seq_FIM))) -A = doe_obj[0].kaug_jac -B = doe_obj[0].seq_jac -print(np.sum((A - B) ** 2)) - -measurement_vals_model = [] -meas_from_model = [] -mod = doe_obj[0].model -for p in mod.parameter_names: - fd_step_mult = 1 - param_ind = mod.parameter_names.data().index(p) - - # Different FD schemes lead to different scenarios for the computation - if doe_obj[0].fd_formula == FiniteDifferenceStep.central: - s1 = param_ind * 2 - s2 = param_ind * 2 + 1 - fd_step_mult = 2 - elif doe_obj[0].fd_formula == FiniteDifferenceStep.forward: - s1 = param_ind + 1 - s2 = 0 - elif doe_obj[0].fd_formula == FiniteDifferenceStep.backward: - s1 = 0 - s2 = param_ind + 1 - - var_up = [pyo.value(k) for k, v in mod.scenario_blocks[s1].experiment_outputs.items()] - var_lo = [pyo.value(k) for k, v in mod.scenario_blocks[s2].experiment_outputs.items()] - - meas_from_model.append(var_up) - meas_from_model.append(var_lo) - - -# Optimal values -print("Optimal values for determinant optimized experimental design:") -print("New formulation, scaled: {}".format(pyo.value(doe_obj[1].model.objective))) -print("New formulation, unscaled: {}".format(pyo.value(doe_obj[2].model.objective))) -print("New formulation, rescaled: {}".format(np.log10(np.linalg.det(rescaled_FIM)))) - -# Draw figures -sens_vars = ['CA[0]', 'T[0]'] -des_vars_fixed = {'T[' + str((i + 1) / 8) + ']': 300 for i in range(7)} -des_vars_fixed['T[1]'] = 300 -doe_obj[0].draw_factorial_figure(title_text='', xlabel_text='', ylabel_text='', sensitivity_design_variables=sens_vars, fixed_design_variables=des_vars_fixed,) \ No newline at end of file From fa1615dd3e0bcffd5cabe7c0621dc8f81a6b3fd2 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:49:54 -0400 Subject: [PATCH 065/203] Ran Black --- pyomo/contrib/doe/doe.py | 90 +++++++---- pyomo/contrib/doe/tests/test_doe_errors.py | 172 ++++++++++++--------- 2 files changed, 165 insertions(+), 97 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 4b795062f7c..3686dafdd51 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -157,7 +157,9 @@ def __init__( """ # Check if the Experiment object has callable ``get_labeled_model`` function if not hasattr(experiment, "get_labeled_model"): - raise ValueError("The experiment object must have a ``get_labeled_model`` function") + raise ValueError( + "The experiment object must have a ``get_labeled_model`` function" + ) # Set the experiment object from the user self.experiment = experiment @@ -235,9 +237,14 @@ def run_doe(self, model=None, results_file=None): """ # Check results file name if results_file is not None: - if type(results_file) not in [Path, str, ]: - raise ValueError("``results_file`` must be either a Path object or a string.") - + if type(results_file) not in [ + Path, + str, + ]: + raise ValueError( + "``results_file`` must be either a Path object or a string." + ) + # Start timer sp_timer = TicTocTimer() sp_timer.tic(msg=None) @@ -963,9 +970,11 @@ def _generate_scenario_blocks(self, model=None): self.n_experiment_outputs = len(model.base_model.experiment_outputs) if self.n_measurement_error != self.n_experiment_outputs: - raise ValueError("Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( - self.n_experiment_outputs, self.n_measurement_error - )) + raise ValueError( + "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( + self.n_experiment_outputs, self.n_measurement_error + ) + ) self.logger.info("Experiment output and measurement error lengths match.") @@ -1310,18 +1319,25 @@ def check_model_FIM(self, FIM=None): model: model for suffix checking, Default: None, (self.model) """ if FIM.shape != (self.n_parameters, self.n_parameters): - raise ValueError("Shape of FIM provided should be n parameters by n parameters, or {} by {}, FIM provided has shape {} by {}".format( - self.n_parameters, self.n_parameters, FIM.shape[0], FIM.shape[1] - )) + raise ValueError( + "Shape of FIM provided should be n parameters by n parameters, or {} by {}, FIM provided has shape {} by {}".format( + self.n_parameters, self.n_parameters, FIM.shape[0], FIM.shape[1] + ) + ) self.logger.info("FIM provided matches expected dimensions from model.") # Check the jacobian shape against what is expected from the model. def check_model_jac(self, jac=None): if jac.shape != (self.n_experiment_outputs, self.n_parameters): - raise ValueError("Shape of Jacobian provided should be n experiment outputs by n parameters, or {} by {}, Jacobian provided has shape {} by {}".format( - self.n_experiment_outputs, self.n_parameters, jac.shape[0], jac.shape[1] - )) + raise ValueError( + "Shape of Jacobian provided should be n experiment outputs by n parameters, or {} by {}, Jacobian provided has shape {} by {}".format( + self.n_experiment_outputs, + self.n_parameters, + jac.shape[0], + jac.shape[1], + ) + ) self.logger.info("Jacobian provided matches expected dimensions from model.") @@ -1347,7 +1363,9 @@ def update_FIM_prior(self, model=None, FIM=None): ) if not hasattr(model, "fim"): - raise RuntimeError("``fim`` is not defined on the model provided. Please build the model first.") + raise RuntimeError( + "``fim`` is not defined on the model provided. Please build the model first." + ) self.check_model_FIM(model, FIM) @@ -1555,14 +1573,18 @@ def draw_factorial_figure( """ if results is None: if not hasattr(self, "fim_factorial_results"): - raise RuntimeError("Results must be provided or the compute_FIM_full_factorial function must be run.") + raise RuntimeError( + "Results must be provided or the compute_FIM_full_factorial function must be run." + ) results = self.fim_factorial_results full_design_variable_names = [ k.name for k, v in self.factorial_model.experiment_inputs.items() ] else: if full_design_variable_names is None: - raise ValueError("If results object is provided, you must include all the design variable names.") + raise ValueError( + "If results object is provided, you must include all the design variable names." + ) des_names = full_design_variable_names @@ -1570,7 +1592,7 @@ def draw_factorial_figure( # ToDo: Put in a default value function????? if sensitivity_design_variables is None: raise ValueError("``sensitivity_design_variables`` must be included.") - + if fixed_design_variables is None: raise ValueError("``fixed_design_variables`` must be included.") @@ -1580,12 +1602,16 @@ def draw_factorial_figure( check_des_vars *= k in ([k2 for k2, v2 in results.items()]) check_sens_vars = True for k in sensitivity_design_variables: - check_sens_vars *= (k in [k2 for k2, v2 in results.items()]) + check_sens_vars *= k in [k2 for k2, v2 in results.items()] if not check_des_vars: - raise ValueError("Fixed design variables do not all appear in the results object keys.") + raise ValueError( + "Fixed design variables do not all appear in the results object keys." + ) if not check_sens_vars: - raise ValueError("Sensitivity design variables do not all appear in the results object keys.") + raise ValueError( + "Sensitivity design variables do not all appear in the results object keys." + ) # ToDo: Make it possible to plot pair-wise sensitivities for all variables # e.g. a curve like low-dimensional posterior distributions @@ -1939,7 +1965,9 @@ def get_FIM(self, model=None): model = self.model if not hasattr(model, "fim"): - raise RuntimeError("Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`") + raise RuntimeError( + "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" + ) fim_vals = [ pyo.value(model.fim[i, j]) @@ -1977,7 +2005,9 @@ def get_sensitivity_matrix(self, model=None): model = self.model if not hasattr(model, "sensitivity_jacboian"): - raise RuntimeError("Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`") + raise RuntimeError( + "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" + ) Q_vals = [ pyo.value(model.sensitivity_jacobian[i, j]) @@ -2011,7 +2041,9 @@ def get_experiment_input_values(self, model=None): if not hasattr(model, "experiment_inputs"): if not hasattr(model, "scenario_blocks"): - raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") + raise RuntimeError( + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ) d_vals = [ pyo.value(k) @@ -2043,7 +2075,9 @@ def get_unknown_parameter_values(self, model=None): if not hasattr(model, "unknown_parameters"): if not hasattr(model, "scenario_blocks"): - raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") + raise RuntimeError( + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ) theta_vals = [ pyo.value(k) @@ -2075,7 +2109,9 @@ def get_experiment_output_values(self, model=None): if not hasattr(model, "experiment_outputs"): if not hasattr(model, "scenario_blocks"): - raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") + raise RuntimeError( + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ) y_hat_vals = [ pyo.value(k) @@ -2109,7 +2145,9 @@ def get_measurement_error_values(self, model=None): if not hasattr(model, "measurement_error"): if not hasattr(model, "scenario_blocks"): - raise RuntimeError("Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`") + raise RuntimeError( + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + ) sigma_vals = [ pyo.value(k) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index ba797a0fe59..4074415c9fd 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -24,6 +24,7 @@ data_ex = json.load(f) data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} + class TestReactorExampleErrors(unittest.TestCase): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_get_labeled_model(self): @@ -34,7 +35,8 @@ def test_reactor_check_no_get_labeled_model(self): experiment = BadExperiment() with self.assertRaisesRegex( - ValueError, "The experiment object must have a ``get_labeled_model`` function" + ValueError, + "The experiment object must have a ``get_labeled_model`` function", ): doe_obj = DesignOfExperiments( experiment, @@ -54,7 +56,7 @@ def test_reactor_check_no_get_labeled_model(self): _Cholesky_option=True, _only_compute_fim_lower=True, ) - + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_experiment_outputs(self): fd_method = "central" @@ -77,16 +79,17 @@ def test_reactor_check_no_experiment_outputs(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Experiment model does not have suffix " + '"experiment_outputs".' + RuntimeError, + "Experiment model does not have suffix " + '"experiment_outputs".', ): doe_obj.create_doe_model() - + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_measurement_error(self): fd_method = "central" @@ -109,16 +112,17 @@ def test_reactor_check_no_measurement_error(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Experiment model does not have suffix " + '"measurement_error".' + RuntimeError, + "Experiment model does not have suffix " + '"measurement_error".', ): doe_obj.create_doe_model() - + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_experiment_inputs(self): fd_method = "central" @@ -141,16 +145,17 @@ def test_reactor_check_no_experiment_inputs(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Experiment model does not have suffix " + '"experiment_inputs".' + RuntimeError, + "Experiment model does not have suffix " + '"experiment_inputs".', ): doe_obj.create_doe_model() - + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_unknown_parameters(self): fd_method = "central" @@ -173,16 +178,16 @@ def test_reactor_check_no_unknown_parameters(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Experiment model does not have suffix " + '"unknown_parameters".' + RuntimeError, + "Experiment model does not have suffix " + '"unknown_parameters".', ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_bad_prior_size(self): @@ -208,17 +213,19 @@ def test_reactor_check_bad_prior_size(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - ValueError, "Shape of FIM provided should be n parameters by n parameters, or {} by {}, FIM provided has shape {} by {}".format( - 4, 4, prior_FIM.shape[0], prior_FIM.shape[1]) + ValueError, + "Shape of FIM provided should be n parameters by n parameters, or {} by {}, FIM provided has shape {} by {}".format( + 4, 4, prior_FIM.shape[0], prior_FIM.shape[1] + ), ): doe_obj.create_doe_model() - + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_bad_jacobian_init_size(self): fd_method = "central" @@ -243,17 +250,18 @@ def test_reactor_check_bad_jacobian_init_size(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - ValueError, "Shape of Jacobian provided should be n experiment outputs by n parameters, or {} by {}, Jacobian provided has shape {} by {}".format( - 27, 4, jac_init.shape[0], jac_init.shape[1]) + ValueError, + "Shape of Jacobian provided should be n experiment outputs by n parameters, or {} by {}, Jacobian provided has shape {} by {}".format( + 27, 4, jac_init.shape[0], jac_init.shape[1] + ), ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_unbuilt_update_FIM(self): @@ -279,17 +287,17 @@ def test_reactor_check_unbuilt_update_FIM(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "``fim`` is not defined on the model provided. Please build the model first." + RuntimeError, + "``fim`` is not defined on the model provided. Please build the model first.", ): doe_obj.update_FIM_prior(FIM=FIM_update) - - + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_results_file_name(self): fd_method = "central" @@ -312,7 +320,7 @@ def test_reactor_check_results_file_name(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -321,13 +329,14 @@ def test_reactor_check_results_file_name(self): ValueError, "``results_file`` must be either a Path object or a string." ): doe_obj.run_doe(results_file=int(15)) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_measurement_and_output_length_match(self): fd_method = "central" obj_used = "trace" - flag_val = 5 # Value for faulty model build mode - 5: Mismatch error and output length + flag_val = ( + 5 # Value for faulty model build mode - 5: Mismatch error and output length + ) experiment = FullReactorExperiment(data_ex, 10, 3) @@ -345,17 +354,19 @@ def test_reactor_check_measurement_and_output_length_match(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - ValueError, "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( - 27, 1 - )): + ValueError, + "Number of experiment outputs, {}, and length of measurement error, {}, do not match. Please check model labeling.".format( + 27, 1 + ), + ): doe_obj.create_doe_model() - + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -390,7 +401,8 @@ def test_reactor_grid_search_des_range_inputs(self): } with self.assertRaisesRegex( - ValueError, "Design ranges keys must be a subset of experimental design names." + ValueError, + "Design ranges keys must be a subset of experimental design names.", ): doe_obj.compute_FIM_full_factorial( design_ranges=design_ranges, method="sequential" @@ -425,10 +437,10 @@ def test_reactor_premature_figure_drawing(self): ) with self.assertRaisesRegex( - RuntimeError, "Results must be provided or the compute_FIM_full_factorial function must be run." + RuntimeError, + "Results must be provided or the compute_FIM_full_factorial function must be run.", ): doe_obj.draw_factorial_figure() - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @@ -468,10 +480,11 @@ def test_reactor_figure_drawing_no_des_var_names(self): ) with self.assertRaisesRegex( - ValueError, "If results object is provided, you must include all the design variable names." + ValueError, + "If results object is provided, you must include all the design variable names.", ): doe_obj.draw_factorial_figure(results=doe_obj.fim_factorial_results) - + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -513,7 +526,6 @@ def test_reactor_figure_drawing_no_sens_names(self): ValueError, "``sensitivity_design_variables`` must be included." ): doe_obj.draw_factorial_figure() - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @@ -556,7 +568,6 @@ def test_reactor_figure_drawing_no_fixed_names(self): ValueError, "``fixed_design_variables`` must be included." ): doe_obj.draw_factorial_figure(sensitivity_design_variables={"dummy": "var"}) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @@ -596,10 +607,14 @@ def test_reactor_figure_drawing_bad_fixed_names(self): ) with self.assertRaisesRegex( - ValueError, "Fixed design variables do not all appear in the results object keys." + ValueError, + "Fixed design variables do not all appear in the results object keys.", ): - doe_obj.draw_factorial_figure(sensitivity_design_variables={"CA[0]": 1}, fixed_design_variables={"bad": "entry"}) - + doe_obj.draw_factorial_figure( + sensitivity_design_variables={"CA[0]": 1}, + fixed_design_variables={"bad": "entry"}, + ) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -638,16 +653,21 @@ def test_reactor_figure_drawing_bad_sens_names(self): ) with self.assertRaisesRegex( - ValueError, "Sensitivity design variables do not all appear in the results object keys." + ValueError, + "Sensitivity design variables do not all appear in the results object keys.", ): - doe_obj.draw_factorial_figure(sensitivity_design_variables={"bad": "entry"}, fixed_design_variables={"CA[0]": 1}) - + doe_obj.draw_factorial_figure( + sensitivity_design_variables={"bad": "entry"}, + fixed_design_variables={"CA[0]": 1}, + ) @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_FIM_without_FIM(self): fd_method = "central" obj_used = "trace" - flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) experiment = FullReactorExperiment(data_ex, 10, 3) @@ -665,22 +685,24 @@ def test_reactor_check_get_FIM_without_FIM(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`" + RuntimeError, + "Model provided does not have variable `fim`. Please make sure the model is built properly before calling `get_FIM`", ): doe_obj.get_FIM() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_sens_mat_without_model(self): fd_method = "central" obj_used = "trace" - flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) experiment = FullReactorExperiment(data_ex, 10, 3) @@ -698,22 +720,24 @@ def test_reactor_check_get_sens_mat_without_model(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" + RuntimeError, + "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`", ): doe_obj.get_sensitivity_matrix() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_exp_inputs_without_model(self): fd_method = "central" obj_used = "trace" - flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) experiment = FullReactorExperiment(data_ex, 10, 3) @@ -731,22 +755,24 @@ def test_reactor_check_get_exp_inputs_without_model(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + RuntimeError, + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`", ): doe_obj.get_experiment_input_values() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_exp_outputs_without_model(self): fd_method = "central" obj_used = "trace" - flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) experiment = FullReactorExperiment(data_ex, 10, 3) @@ -764,22 +790,24 @@ def test_reactor_check_get_exp_outputs_without_model(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + RuntimeError, + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`", ): doe_obj.get_experiment_output_values() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_unknown_params_without_model(self): fd_method = "central" obj_used = "trace" - flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) experiment = FullReactorExperiment(data_ex, 10, 3) @@ -797,22 +825,24 @@ def test_reactor_check_get_unknown_params_without_model(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + RuntimeError, + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`", ): doe_obj.get_unknown_parameter_values() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_meas_error_without_model(self): fd_method = "central" obj_used = "trace" - flag_val = 0 # Value for faulty model build mode - 5: Mismatch error and output length + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) experiment = FullReactorExperiment(data_ex, 10, 3) @@ -830,17 +860,17 @@ def test_reactor_check_get_meas_error_without_model(self): L_LB=1e-7, solver=None, tee=False, - args={'flag': flag_val}, + args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) with self.assertRaisesRegex( - RuntimeError, "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`" + RuntimeError, + "Model provided does not have expected structure. Please make sure model is built properly before calling `get_experiment_input_values`", ): doe_obj.get_measurement_error_values() - if __name__ == "__main__": unittest.main() From 6871ba619508ae6b9aea587ab8bf8f80d2959c71 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:52:59 -0400 Subject: [PATCH 066/203] Fixed small typo --- pyomo/contrib/doe/doe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 3686dafdd51..d8f773879ee 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -2004,7 +2004,7 @@ def get_sensitivity_matrix(self, model=None): if model is None: model = self.model - if not hasattr(model, "sensitivity_jacboian"): + if not hasattr(model, "sensitivity_jacobian"): raise RuntimeError( "Model provided does not have variable `sensitivity_jacobian`. Please make sure the model is built properly before calling `get_sensitivity_matrix`" ) From 4a341f67e1ab0fe3b4e5b5cf5e6d95968040ec90 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:55:58 -0400 Subject: [PATCH 067/203] Delete pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb Removed old file --- .../contrib/doe/examples/PyomoDoE-plots.ipynb | 9116 ----------------- 1 file changed, 9116 deletions(-) delete mode 100644 pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb diff --git a/pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb b/pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb deleted file mode 100644 index f2d83550458..00000000000 --- a/pyomo/contrib/doe/examples/PyomoDoE-plots.ipynb +++ /dev/null @@ -1,9116 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 60, - "id": "22f7850b-5a09-4b71-a9cf-64555f21f7f5", - "metadata": {}, - "outputs": [], - "source": [ - "import pyomo.environ as pyo\n", - "from pyomo.dae import ContinuousSet, DerivativeVar\n", - "from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables, ModelOptionLib\n", - "import numpy as np\n", - "from random import sample\n", - "from matplotlib import pyplot as plt" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "2607b8c0-527c-4a6e-b73d-989b1471aa8f", - "metadata": {}, - "outputs": [], - "source": [ - "def create_model(\n", - " mod=None,\n", - " model_option=\"stage2\",\n", - " control_time=[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],\n", - " control_val=None,\n", - " t_range=[0.0, 1],\n", - " CA_init=1,\n", - " C_init=0.1,\n", - "):\n", - " \"\"\"\n", - " This is an example user model provided to DoE library.\n", - " It is a dynamic problem solved by Pyomo.DAE.\n", - "\n", - " Arguments\n", - " ---------\n", - " mod: Pyomo model. If None, a Pyomo concrete model is created\n", - " model_option: choose from the 3 options in model_option\n", - " if ModelOptionLib.parmest, create a process model.\n", - " if ModelOptionLib.stage1, create the global model.\n", - " if ModelOptionLib.stage2, add model variables and constraints for block.\n", - " control_time: a list of control timepoints\n", - " control_val: control design variable values T at corresponding timepoints\n", - " t_range: time range, h\n", - " CA_init: time-independent design (control) variable, an initial value for CA\n", - " C_init: An initial value for C\n", - "\n", - " Return\n", - " ------\n", - " m: a Pyomo.DAE model\n", - " \"\"\"\n", - "\n", - " theta = {\"A1\": 84.79, \"A2\": 371.72, \"E1\": 7.78, \"E2\": 15.05}\n", - "\n", - " model_option = ModelOptionLib(model_option)\n", - "\n", - " if model_option == ModelOptionLib.parmest:\n", - " mod = pyo.ConcreteModel()\n", - " return_m = True\n", - " elif model_option == ModelOptionLib.stage1 or model_option == ModelOptionLib.stage2:\n", - " if not mod:\n", - " raise ValueError(\n", - " \"If model option is stage1 or stage2, a created model needs to be provided.\"\n", - " )\n", - " return_m = False\n", - " else:\n", - " raise ValueError(\n", - " \"model_option needs to be defined as parmest,stage1, or stage2.\"\n", - " )\n", - "\n", - " if not control_val:\n", - " control_val = [300] * 9\n", - "\n", - " controls = {}\n", - " for i, t in enumerate(control_time):\n", - " controls[t] = control_val[i]\n", - "\n", - " mod.t0 = pyo.Set(initialize=[0])\n", - " mod.t_con = pyo.Set(initialize=control_time)\n", - " mod.CA0 = pyo.Var(\n", - " mod.t0, initialize=CA_init, bounds=(1.0, 5.0), within=pyo.NonNegativeReals\n", - " ) # mol/L\n", - "\n", - " # check if control_time is in time range\n", - " assert (\n", - " control_time[0] >= t_range[0] and control_time[-1] <= t_range[1]\n", - " ), \"control time is outside time range.\"\n", - "\n", - " if model_option == ModelOptionLib.stage1:\n", - " mod.T = pyo.Var(\n", - " mod.t_con,\n", - " initialize=controls,\n", - " bounds=(300, 700),\n", - " within=pyo.NonNegativeReals,\n", - " )\n", - " return\n", - "\n", - " else:\n", - " para_list = [\"A1\", \"A2\", \"E1\", \"E2\"]\n", - "\n", - " ### Add variables\n", - " mod.CA_init = CA_init\n", - " mod.para_list = para_list\n", - "\n", - " # timepoints\n", - " mod.t = ContinuousSet(bounds=t_range, initialize=control_time)\n", - "\n", - " # time-dependent design variable, initialized with the first control value\n", - " def T_initial(m, t):\n", - " if t in m.t_con:\n", - " return controls[t]\n", - " else:\n", - " # count how many control points are before the current t;\n", - " # locate the nearest neighbouring control point before this t\n", - " neighbour_t = max(tc for tc in control_time if tc < t)\n", - " return controls[neighbour_t]\n", - "\n", - " mod.T = pyo.Var(\n", - " mod.t, initialize=T_initial, bounds=(300, 700), within=pyo.NonNegativeReals\n", - " )\n", - "\n", - " mod.R = 8.31446261815324 # J / K / mole\n", - "\n", - " # Define parameters as Param\n", - " mod.A1 = pyo.Var(initialize=theta[\"A1\"])\n", - " mod.A2 = pyo.Var(initialize=theta[\"A2\"])\n", - " mod.E1 = pyo.Var(initialize=theta[\"E1\"])\n", - " mod.E2 = pyo.Var(initialize=theta[\"E2\"])\n", - "\n", - " # Concentration variables under perturbation\n", - " mod.C_set = pyo.Set(initialize=[\"CA\", \"CB\", \"CC\"])\n", - " mod.C = pyo.Var(\n", - " mod.C_set, mod.t, initialize=C_init, within=pyo.NonNegativeReals\n", - " )\n", - "\n", - " # time derivative of C\n", - " mod.dCdt = DerivativeVar(mod.C, wrt=mod.t)\n", - "\n", - " # kinetic parameters\n", - " def kp1_init(m, t):\n", - " return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def kp2_init(m, t):\n", - " return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", - "\n", - " mod.kp1 = pyo.Var(mod.t, initialize=kp1_init)\n", - " mod.kp2 = pyo.Var(mod.t, initialize=kp2_init)\n", - "\n", - " def T_control(m, t):\n", - " \"\"\"\n", - " T at interval timepoint equal to the T of the control time point at the beginning of this interval\n", - " Count how many control points are before the current t;\n", - " locate the nearest neighbouring control point before this t\n", - " \"\"\"\n", - " if t in m.t_con:\n", - " return pyo.Constraint.Skip\n", - " else:\n", - " neighbour_t = max(tc for tc in control_time if tc < t)\n", - " return m.T[t] == m.T[neighbour_t]\n", - "\n", - " def cal_kp1(m, t):\n", - " \"\"\"\n", - " Create the perturbation parameter sets\n", - " m: model\n", - " t: time\n", - " \"\"\"\n", - " # LHS: 1/h\n", - " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", - " return m.kp1[t] == m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def cal_kp2(m, t):\n", - " \"\"\"\n", - " Create the perturbation parameter sets\n", - " m: model\n", - " t: time\n", - " \"\"\"\n", - " # LHS: 1/h\n", - " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", - " return m.kp2[t] == m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def dCdt_control(m, y, t):\n", - " \"\"\"\n", - " Calculate CA in Jacobian matrix analytically\n", - " y: CA, CB, CC\n", - " t: timepoints\n", - " \"\"\"\n", - " if y == \"CA\":\n", - " return m.dCdt[y, t] == -m.kp1[t] * m.C[\"CA\", t]\n", - " elif y == \"CB\":\n", - " return m.dCdt[y, t] == m.kp1[t] * m.C[\"CA\", t] - m.kp2[t] * m.C[\"CB\", t]\n", - " elif y == \"CC\":\n", - " return pyo.Constraint.Skip\n", - "\n", - " def alge(m, t):\n", - " \"\"\"\n", - " The algebraic equation for mole balance\n", - " z: m.pert\n", - " t: time\n", - " \"\"\"\n", - " return m.C[\"CA\", t] + m.C[\"CB\", t] + m.C[\"CC\", t] == m.CA0[0]\n", - "\n", - " # Control time\n", - " mod.T_rule = pyo.Constraint(mod.t, rule=T_control)\n", - "\n", - " # calculating C, Jacobian, FIM\n", - " mod.k1_pert_rule = pyo.Constraint(mod.t, rule=cal_kp1)\n", - " mod.k2_pert_rule = pyo.Constraint(mod.t, rule=cal_kp2)\n", - " mod.dCdt_rule = pyo.Constraint(mod.C_set, mod.t, rule=dCdt_control)\n", - "\n", - " mod.alge_rule = pyo.Constraint(mod.t, rule=alge)\n", - "\n", - " # B.C.\n", - " mod.C[\"CB\", 0.0].fix(0.0)\n", - " mod.C[\"CC\", 0.0].fix(0.0)\n", - "\n", - " if return_m:\n", - " return mod" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "e76ef4de-7319-4047-9cc8-b61c8ce2c57f", - "metadata": {}, - "outputs": [], - "source": [ - "def disc_for_measure(m, nfe=32, block=True):\n", - " \"\"\"Pyomo.DAE discretization\n", - "\n", - " Arguments\n", - " ---------\n", - " m: Pyomo model\n", - " nfe: number of finite elements b\n", - " block: if True, the input model has blocks\n", - " \"\"\"\n", - " discretizer = pyo.TransformationFactory(\"dae.collocation\")\n", - " if block:\n", - " for s in range(len(m.block)):\n", - " discretizer.apply_to(m.block[s], nfe=nfe, ncp=3, wrt=m.block[s].t)\n", - " else:\n", - " discretizer.apply_to(m, nfe=nfe, ncp=3, wrt=m.t)\n", - " return m" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "42186821-ccaf-4a93-bf0e-86d8cd6098c0", - "metadata": {}, - "outputs": [], - "source": [ - " # Control time set [h]\n", - " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - " # Define parameter nominal value\n", - " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", - "\n", - " # Define measurement object\n", - " measurements = MeasurementVariables()\n", - " measurements.add_variables(\n", - " \"C\", # measurement variable name\n", - " indices={\n", - " 0: [\"CA\", \"CB\", \"CC\"],\n", - " 1: t_control,\n", - " }, # 0,1 are indices of the index sets\n", - " time_index_position=1,\n", - " )\n", - "\n", - " # design object\n", - " exp_design = DesignVariables()\n", - "\n", - " # add CAO as design variable\n", - " exp_design.add_variables(\n", - " \"CA0\", # design variable name\n", - " indices={0: [0]}, # index dictionary\n", - " time_index_position=0, # time index position\n", - " values=[5], # design variable values\n", - " lower_bounds=1, # design variable lower bounds\n", - " upper_bounds=5, # design variable upper bounds\n", - " )\n", - "\n", - " # add T as design variable\n", - " exp_design.add_variables(\n", - " \"T\", # design variable name\n", - " indices={0: t_control}, # index dictionary\n", - " time_index_position=0, # time index position\n", - " values=[\n", - " 570,\n", - " 300,\n", - " 300,\n", - " 300,\n", - " 300,\n", - " 300,\n", - " 300,\n", - " 300,\n", - " 300,\n", - " ], # same length with t_control\n", - " lower_bounds=300, # design variable lower bounds\n", - " upper_bounds=700, # design variable upper bounds\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "70a60f53-bee2-401b-8c23-5d3998447946", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.67e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 4.76e+01 3.85e+02 -1.0 2.67e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.83e+01 2.78e+02 -1.0 5.91e+01 - 6.65e-02 9.90e-01h 1\n", - " 3 0.0000000e+00 1.33e-01 7.65e+01 -1.0 1.09e+01 - 7.59e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 4.86e-06 2.23e+02 -1.0 8.75e-02 - 9.91e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (287125)\n", - " 5 0.0000000e+00 3.41e-13 1.00e-06 -1.0 2.73e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.4215102496496944e-13 3.4106051316484809e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.4215102496496944e-13 3.4106051316484809e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.173\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1\n" - ] - } - ], - "source": [ - " doe_object = DesignOfExperiments(\n", - " parameter_dict, # parameter dictionary\n", - " exp_design, # DesignVariables object\n", - " measurements, # MeasurementVariables object\n", - " create_model, # create model function\n", - " discretize_model=disc_for_measure, # discretize model function\n", - " )\n", - "\n", - " result = doe_object.compute_FIM(\n", - " mode=\"sequential_finite\", # calculation mode\n", - " scale_nominal_param_value=True, # scale nominal parameter value\n", - " formula=\"central\", # formula for finite difference\n", - " )\n", - "\n", - " result.result_analysis()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "dd45bb25-e3e4-4438-9f5e-b1544346d262", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.78e-01 9.66e+00 -1.0 3.72e+00 - 1.10e-01 9.90e-01h 1\n", - " 2 0.0000000e+00 2.78e-03 7.85e-02 -1.0 2.50e-01 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 2.23e-09 1.61e-04 -1.0 2.50e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 3\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2346848815857356e-09 2.2346848815857356e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2346848815857356e-09 2.2346848815857356e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 4\n", - "Number of objective gradient evaluations = 4\n", - "Number of equality constraint evaluations = 4\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 4\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 3\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.083\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 0.7\n", - "[[ 23.4919678 1.90035398 -73.31983907 -11.45520905]\n", - " [ 1.90035398 18.78885651 -5.92812017 -113.31030691]\n", - " [ -73.31983907 -5.92812017 228.84307107 35.73423936]\n", - " [ -11.45520905 -113.31030691 35.73423936 683.34280812]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.27e+02 2.27e+01 -1.0 1.97e+02 - 1.49e-02 3.57e-01f 1\n", - " 2 0.0000000e+00 1.18e+02 2.13e+01 -1.0 1.27e+02 - 2.20e-01 6.59e-02h 1\n", - " 3 0.0000000e+00 1.18e+02 1.57e+04 -1.0 1.18e+02 - 4.58e-01 1.07e-03h 1\n", - " 4 0.0000000e+00 1.18e+02 8.18e+08 -1.0 1.18e+02 - 5.67e-01 1.08e-05h 1\n", - " 5r 0.0000000e+00 1.18e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 5.40e-08R 2\n", - " 6r 0.0000000e+00 1.08e+02 8.37e+03 2.1 2.06e+04 - 5.73e-02 5.68e-03f 1\n", - " 7r 0.0000000e+00 9.81e+01 9.52e+03 2.1 1.83e+03 - 1.09e-01 5.87e-03f 1\n", - " 8r 0.0000000e+00 3.98e+01 5.75e+03 2.1 1.58e+03 - 8.18e-02 4.13e-02f 1\n", - " 9r 0.0000000e+00 2.03e+01 6.57e+03 1.4 9.62e+02 - 1.41e-01 2.07e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 3.00e+00 8.02e+03 1.4 3.63e+02 - 3.32e-01 5.56e-02f 1\n", - " 11r 0.0000000e+00 1.44e+00 5.13e+03 1.4 9.12e+00 - 6.26e-01 2.87e-01f 1\n", - " 12r 0.0000000e+00 8.25e-01 3.35e+03 1.4 6.02e+00 - 3.97e-01 3.54e-01f 1\n", - " 13r 0.0000000e+00 3.34e-01 1.92e+03 1.4 1.38e+00 - 1.00e+00 5.65e-01f 1\n", - " 14r 0.0000000e+00 8.90e-02 2.52e+01 1.4 4.37e-01 - 1.00e+00 1.00e+00f 1\n", - " 15r 0.0000000e+00 6.06e-02 6.19e+02 -0.7 3.41e+00 - 9.23e-01 2.41e-01f 1\n", - " 16r 0.0000000e+00 2.81e-02 7.76e+02 -0.7 5.14e+00 - 9.06e-01 4.55e-01f 1\n", - " 17r 0.0000000e+00 7.09e-03 4.75e+02 -0.7 2.70e+00 - 1.00e+00 7.43e-01f 1\n", - " 18r 0.0000000e+00 2.33e-03 8.38e+02 -0.7 5.62e-01 - 1.00e+00 6.77e-01f 1\n", - " 19r 0.0000000e+00 4.95e-04 3.26e+02 -0.7 3.01e-01 - 1.00e+00 8.74e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 3.22e-04 7.71e-03 -0.7 3.84e-02 - 1.00e+00 1.00e+00f 1\n", - " 21r 0.0000000e+00 5.09e-05 3.36e+02 -3.2 4.74e-02 - 1.00e+00 7.57e-01f 1\n", - " 22r 0.0000000e+00 2.83e-05 9.25e+02 -3.2 2.60e-02 - 9.52e-01 6.49e-01f 1\n", - " 23r 0.0000000e+00 8.26e-06 8.54e+02 -3.2 4.25e-03 - 9.08e-01 7.50e-01f 1\n", - " 24r 0.0000000e+00 1.07e-06 3.61e+01 -3.2 1.20e-03 - 9.68e-01 1.00e+00f 1\n", - " 25r 0.0000000e+00 1.06e-06 1.08e-07 -3.2 3.22e-06 - 1.00e+00 1.00e+00f 1\n", - " 26r 0.0000000e+00 1.25e-08 1.36e+00 -7.2 1.30e-05 - 1.00e+00 9.91e-01f 1\n", - " 27r 0.0000000e+00 4.44e-09 9.66e+01 -7.2 1.80e-07 - 1.00e+00 6.43e-01f 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 3.8353336372415511e-09 4.4417719505051396e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 3.8353336372415511e-09 4.4417719505051396e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 30\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 30\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 29\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.415\n", - "Total CPU secs in NLP function evaluations = 0.011\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.7\n", - "[[ 22.79600957 1.98478998 -70.74572684 -11.61551788]\n", - " [ 1.98478998 18.42336506 -6.01361754 -110.33089639]\n", - " [ -70.74572684 -6.01361754 219.92911039 35.57976045]\n", - " [ -11.61551788 -110.33089639 35.57976045 662.60606496]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.16e+02 2.62e+01 -1.0 3.97e+02 - 7.43e-03 2.04e-01f 1\n", - " 2 0.0000000e+00 3.03e+02 2.51e+01 -1.0 3.16e+02 - 1.45e-01 4.23e-02h 1\n", - " 3 0.0000000e+00 3.03e+02 8.97e+03 -1.0 3.03e+02 - 2.61e-01 7.62e-04h 1\n", - " 4r 0.0000000e+00 3.03e+02 1.00e+03 2.5 0.00e+00 - 0.00e+00 4.81e-07R 5\n", - " 5r 0.0000000e+00 2.80e+02 2.51e+04 2.5 1.49e+04 - 8.36e-04 2.01e-02f 1\n", - " 6r 0.0000000e+00 2.77e+02 4.72e+04 2.5 1.15e+03 - 4.92e-01 2.99e-03f 1\n", - " 7r 0.0000000e+00 1.44e+02 3.94e+04 2.5 8.87e+02 - 1.66e-01 1.77e-01f 1\n", - " 8r 0.0000000e+00 8.40e+01 2.88e+04 2.5 7.02e+02 - 5.33e-01 1.02e-01f 1\n", - " 9r 0.0000000e+00 7.98e+00 2.05e+04 2.5 2.25e+02 - 6.82e-01 3.66e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 2.42e+00 1.01e+04 1.8 1.19e+01 - 1.00e+00 5.27e-01f 1\n", - " 11r 0.0000000e+00 8.94e-01 1.27e+03 1.8 3.82e+00 - 1.00e+00 8.53e-01f 1\n", - " 12r 0.0000000e+00 5.02e-01 1.87e+03 1.1 1.61e+00 - 1.00e+00 5.52e-01f 1\n", - " 13r 0.0000000e+00 2.92e-01 1.58e+03 1.1 3.89e+00 - 1.00e+00 5.66e-01f 1\n", - " 14r 0.0000000e+00 2.10e-01 3.14e+00 1.1 1.42e+00 - 1.00e+00 1.00e+00f 1\n", - " 15r 0.0000000e+00 2.28e-01 5.05e+02 -1.0 9.32e-01 - 9.06e-01 6.86e-01f 1\n", - " 16r 0.0000000e+00 1.61e-01 3.01e+03 -1.0 4.16e+01 - 4.10e-01 6.33e-02f 1\n", - " 17r 0.0000000e+00 3.96e-02 2.90e+03 -1.0 3.34e+01 - 4.84e-01 2.04e-01f 1\n", - " 18r 0.0000000e+00 3.80e-02 2.77e+03 -1.0 1.90e+01 - 2.00e-02 3.94e-02f 1\n", - " 19r 0.0000000e+00 3.76e-02 3.37e+03 -1.0 1.24e+01 - 1.00e+00 1.20e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 3.18e-02 3.17e+03 -1.0 6.34e+00 - 1.00e+00 1.59e-01f 1\n", - " 21r 0.0000000e+00 1.30e-02 1.27e+03 -1.0 2.32e+00 - 1.00e+00 6.13e-01f 1\n", - " 22r 0.0000000e+00 2.75e-03 2.56e+02 -1.0 7.79e-01 - 1.00e+00 8.72e-01f 1\n", - " 23r 0.0000000e+00 1.24e-03 1.45e-02 -1.0 8.66e-02 - 1.00e+00 1.00e+00f 1\n", - " 24r 0.0000000e+00 4.49e-04 9.60e+02 -3.9 4.13e-02 - 1.00e+00 6.37e-01f 1\n", - " 25r 0.0000000e+00 2.39e-04 1.95e+03 -3.9 3.96e-02 - 9.64e-01 4.59e-01f 1\n", - " 26r 0.0000000e+00 6.90e-05 1.04e+03 -3.9 3.37e-03 - 9.83e-01 6.98e-01f 1\n", - " 27r 0.0000000e+00 2.36e-05 1.29e+03 -3.9 1.13e-03 - 9.70e-01 6.16e-01f 1\n", - " 28r 0.0000000e+00 4.53e-06 1.22e+03 -3.9 4.33e-04 - 1.00e+00 6.79e-01f 1\n", - " 29r 0.0000000e+00 1.29e-06 1.43e+03 -3.9 1.39e-04 - 1.00e+00 5.77e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 4.96e-07 7.07e-06 -3.9 5.89e-05 - 1.00e+00 1.00e+00f 1\n", - " 31r 0.0000000e+00 1.34e-07 1.42e+03 -5.8 4.88e-06 - 1.00e+00 5.68e-01f 1\n", - " 32r 0.0000000e+00 4.98e-08 1.83e+03 -5.8 2.01e-06 - 9.73e-01 6.09e-01f 1\n", - " 33r 0.0000000e+00 1.06e-08 2.39e+02 -5.8 8.73e-07 - 9.85e-01 9.28e-01f 1\n", - "\n", - "Number of Iterations....: 33\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 6.2369178856385201e-09 1.0648229654397684e-08\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 6.2369178856385201e-09 1.0648229654397684e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 35\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 33\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.459\n", - "Total CPU secs in NLP function evaluations = 0.090\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "[[ 22.63335364 1.90230787 -70.37558022 -11.25402903]\n", - " [ 1.90230787 18.17182952 -5.82082335 -109.34769934]\n", - " [ -70.37558022 -5.82082335 219.13827714 34.79632173]\n", - " [ -11.25402903 -109.34769934 34.79632173 658.86364692]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 9.05e-01 1.87e+02 -1.0 1.12e+01 - 5.21e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 9.03e-03 1.85e+00 -1.0 8.13e-01 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.20e-09 5.47e-05 -1.0 8.12e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 3\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.2006525186907311e-09 7.2006525186907311e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.2006525186907311e-09 7.2006525186907311e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 4\n", - "Number of objective gradient evaluations = 4\n", - "Number of equality constraint evaluations = 4\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 4\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 3\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.079\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 0.7\n", - "[[ 31.19226828 2.38044072 -98.01668477 -14.34224445]\n", - " [ 2.38044072 24.31185934 -7.46787881 -146.52347138]\n", - " [ -98.01668477 -7.46787881 308.05221217 44.99368637]\n", - " [ -14.34224445 -146.52347138 44.99368637 883.07370235]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.06e+02 8.67e+01 -1.0 1.97e+02 - 5.21e-03 4.63e-01f 1\n", - " 2 0.0000000e+00 1.03e+02 8.41e+01 -1.0 1.06e+02 - 1.23e-01 3.00e-02h 1\n", - " 3 0.0000000e+00 1.03e+02 1.14e+04 -1.0 1.03e+02 - 2.02e-01 3.66e-04h 1\n", - " 4r 0.0000000e+00 1.03e+02 1.00e+03 2.0 0.00e+00 - 0.00e+00 4.59e-07R 4\n", - " 5r 0.0000000e+00 9.98e+01 3.34e+03 2.0 1.78e+04 - 5.49e-03 2.23e-03f 1\n", - " 6r 0.0000000e+00 9.58e+01 1.77e+04 1.3 1.22e+04 - 2.58e-02 2.86e-03f 1\n", - " 7r 0.0000000e+00 7.91e+01 4.28e+04 1.3 3.59e+03 - 3.01e-02 5.36e-03f 1\n", - " 8r 0.0000000e+00 3.41e+01 4.38e+04 1.3 3.03e+03 - 3.45e-02 1.54e-02f 1\n", - " 9r 0.0000000e+00 2.48e+01 3.96e+04 1.3 1.85e+03 - 2.78e-01 5.04e-03f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 5.64e+00 3.44e+04 1.3 2.01e+02 - 1.86e-01 1.23e-01f 1\n", - " 11r 0.0000000e+00 2.42e+00 1.91e+04 1.3 1.70e+01 - 5.49e-01 2.58e-01f 1\n", - " 12r 0.0000000e+00 1.24e+00 8.44e+03 1.3 7.64e+00 - 6.61e-01 4.56e-01f 1\n", - " 13r 0.0000000e+00 1.19e+00 2.99e+03 1.3 2.61e+00 - 5.40e-01 3.71e-01f 1\n", - " 14r 0.0000000e+00 1.15e+00 4.69e+03 1.3 1.51e+00 - 8.83e-01 6.33e-01f 1\n", - " 15r 0.0000000e+00 1.13e+00 4.99e+03 1.3 6.01e-01 - 5.32e-01 7.72e-01f 1\n", - " 16r 0.0000000e+00 1.13e+00 1.09e+00 1.3 1.75e-01 - 1.00e+00 1.00e+00f 1\n", - " 17r 0.0000000e+00 1.62e+00 1.19e+02 -0.8 7.16e+00 - 6.51e-01 8.04e-01f 1\n", - " 18r 0.0000000e+00 1.29e+00 5.12e+02 -0.8 8.63e+00 - 3.56e-01 4.94e-01f 1\n", - " 19r 0.0000000e+00 7.07e-01 1.78e+02 -0.8 1.47e+01 - 5.56e-01 4.96e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 9.00e-03 8.30e+02 -0.8 2.77e+01 - 4.78e-01 3.14e-01f 1\n", - " 21r 0.0000000e+00 4.40e-03 2.34e+03 -0.8 1.62e+01 - 8.28e-01 5.79e-03f 1\n", - " 22r 0.0000000e+00 2.91e-03 1.69e+03 -0.8 2.80e+00 - 1.00e+00 2.71e-01f 1\n", - " 23r 0.0000000e+00 8.18e-04 5.53e+02 -0.8 1.23e+00 - 1.00e+00 6.90e-01f 1\n", - " 24r 0.0000000e+00 1.16e-03 1.32e-03 -0.8 2.40e-01 - 1.00e+00 1.00e+00f 1\n", - " 25r 0.0000000e+00 4.27e-04 4.03e+02 -3.3 2.88e-01 - 1.00e+00 7.55e-01f 1\n", - " 26r 0.0000000e+00 4.49e-05 3.83e+03 -3.3 7.00e-01 - 9.34e-01 1.68e-01f 1\n", - " 27r 0.0000000e+00 2.16e-06 1.67e+02 -3.3 2.07e-02 - 9.48e-01 9.55e-01f 1\n", - " 28r 0.0000000e+00 3.64e-08 1.90e-06 -3.3 8.95e-04 - 1.00e+00 1.00e+00f 1\n", - " 29r 0.0000000e+00 2.25e-09 2.47e-01 -7.5 1.53e-05 - 1.00e+00 9.98e-01f 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.9395965331428192e-09 2.2481533234965274e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.9395965331428192e-09 2.2481533234965274e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 31\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.614\n", - "Total CPU secs in NLP function evaluations = 0.081\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "[[ 24.92864423 3.14036468 -74.84967466 -15.78502396]\n", - " [ 3.14036468 21.02243624 -8.23735511 -119.70877671]\n", - " [ -74.84967466 -8.23735511 227.82656607 43.60337618]\n", - " [ -15.78502396 -119.70877671 43.60337618 696.44301405]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.04e+02 4.34e+01 -1.0 3.97e+02 - 5.21e-03 2.34e-01f 1\n", - " 2 0.0000000e+00 2.98e+02 4.26e+01 -1.0 3.04e+02 - 7.70e-02 2.01e-02h 1\n", - " 3 0.0000000e+00 2.98e+02 7.36e+03 -1.0 2.98e+02 - 1.28e-01 2.60e-04h 1\n", - " 4r 0.0000000e+00 2.98e+02 1.00e+03 2.5 0.00e+00 - 0.00e+00 3.26e-07R 4\n", - " 5r 0.0000000e+00 2.77e+02 1.21e+04 2.5 1.42e+04 - 1.92e-03 2.08e-02f 1\n", - " 6r 0.0000000e+00 2.74e+02 1.33e+04 1.8 1.29e+03 - 1.28e-01 2.52e-03f 1\n", - " 7r 0.0000000e+00 2.26e+02 1.74e+04 1.8 2.17e+03 - 1.75e-01 2.27e-02f 1\n", - " 8r 0.0000000e+00 1.70e+02 1.94e+04 1.8 1.50e+03 - 3.05e-01 4.00e-02f 1\n", - " 9r 0.0000000e+00 8.81e+01 1.78e+04 1.8 7.79e+02 - 2.82e-01 1.08e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 2.94e+01 1.40e+04 1.8 2.94e+02 - 5.10e-01 2.10e-01f 1\n", - " 11r 0.0000000e+00 2.15e+01 1.17e+04 1.8 4.85e+01 - 1.00e+00 1.67e-01f 1\n", - " 12r 0.0000000e+00 5.21e+00 2.64e+03 1.8 2.09e+01 - 1.00e+00 7.79e-01f 1\n", - " 13r 0.0000000e+00 2.67e+00 3.16e+03 1.1 5.47e+00 - 9.78e-01 5.06e-01f 1\n", - " 14r 0.0000000e+00 1.98e+00 9.35e+02 1.1 2.78e+00 - 1.00e+00 8.27e-01f 1\n", - " 15r 0.0000000e+00 2.00e+00 2.79e+03 0.4 1.09e+00 - 9.98e-01 4.40e-01f 1\n", - " 16r 0.0000000e+00 2.00e+00 1.21e+03 0.4 3.21e+00 - 9.19e-01 6.28e-01f 1\n", - " 17r 0.0000000e+00 1.99e+00 1.22e+00 0.4 8.67e-01 - 1.00e+00 1.00e+00f 1\n", - " 18r 0.0000000e+00 2.00e+00 1.65e+03 -1.7 5.96e-01 - 9.91e-01 4.10e-01f 1\n", - " 19r 0.0000000e+00 2.00e+00 1.83e+03 -1.7 2.35e+01 - 4.40e-01 1.42e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.00e+00 1.60e+03 -1.7 1.13e+01 - 7.62e-03 9.12e-02f 1\n", - " 21r 0.0000000e+00 1.88e+00 1.11e+03 -1.7 7.12e+01 - 4.10e-04 1.86e-01f 1\n", - " 22r 0.0000000e+00 7.03e-01 3.48e+03 -1.7 8.30e+01 - 3.09e-02 3.12e-01f 1\n", - " 23r 0.0000000e+00 4.00e-01 3.15e+03 -1.7 6.39e+01 - 9.85e-02 1.02e-01f 1\n", - " 24r 0.0000000e+00 3.97e-01 3.03e+03 -1.7 5.91e+01 - 2.08e-02 1.19e-03f 1\n", - " 25r 0.0000000e+00 2.62e-01 2.91e+03 -1.7 5.95e+01 - 4.23e-02 4.88e-02f 1\n", - " 26r 0.0000000e+00 1.40e-01 2.63e+03 -1.7 5.67e+01 - 9.35e-02 4.62e-02f 1\n", - " 27r 0.0000000e+00 1.38e-01 1.95e+03 -1.7 5.44e+01 - 2.47e-01 7.95e-04f 1\n", - " 28r 0.0000000e+00 9.04e-02 1.90e+03 -1.7 5.42e+01 - 1.88e-01 1.90e-02f 1\n", - " 29r 0.0000000e+00 3.77e-02 3.31e+03 -1.7 4.98e+01 - 5.30e-01 2.27e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 6.02e-03 3.61e+03 -1.7 1.34e+01 - 9.70e-01 6.02e-02f 1\n", - " 31r 0.0000000e+00 5.14e-03 3.30e+03 -1.7 6.99e+00 - 1.00e+00 1.53e-01f 1\n", - " 32r 0.0000000e+00 3.66e-03 2.50e+03 -1.7 5.55e-01 - 1.00e+00 3.01e-01f 1\n", - " 33r 0.0000000e+00 5.42e-04 2.44e+02 -1.7 3.24e-01 - 1.00e+00 9.11e-01f 1\n", - " 34r 0.0000000e+00 2.39e-04 3.00e-03 -1.7 2.78e-02 - 1.00e+00 1.00e+00f 1\n", - " 35r 0.0000000e+00 8.49e-05 1.01e+03 -3.9 1.83e-02 - 1.00e+00 6.33e-01f 1\n", - " 36r 0.0000000e+00 6.04e-05 2.69e+03 -3.9 2.68e-02 - 9.77e-01 2.72e-01f 1\n", - " 37r 0.0000000e+00 1.04e-05 8.23e+02 -3.9 1.42e-03 - 1.00e+00 7.69e-01f 1\n", - " 38r 0.0000000e+00 1.46e-06 1.11e+03 -3.9 2.73e-04 - 1.00e+00 6.80e-01f 1\n", - " 39r 0.0000000e+00 9.63e-07 2.09e+03 -3.9 8.74e-05 - 1.00e+00 3.68e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40r 0.0000000e+00 1.97e-07 3.12e-06 -3.9 5.52e-05 - 1.00e+00 1.00e+00f 1\n", - " 41r 0.0000000e+00 5.22e-08 1.13e+03 -5.8 5.75e-06 - 1.00e+00 6.12e-01f 1\n", - " 42r 0.0000000e+00 2.38e-08 1.61e+03 -5.8 4.28e-06 - 9.81e-01 6.72e-01f 1\n", - " 43r 0.0000000e+00 2.62e-09 1.78e-07 -5.8 5.81e-07 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 43\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.5727324704138637e-09 2.6229877388222538e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.5727324704138637e-09 2.6229877388222538e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 48\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 48\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 45\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 43\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.628\n", - "Total CPU secs in NLP function evaluations = 0.025\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.7\n", - "[[ 23.46474083 2.39802572 -71.51835509 -12.53162432]\n", - " [ 2.39802572 18.75861639 -6.50220745 -110.86000329]\n", - " [ -71.51835509 -6.50220745 220.70906678 36.55242777]\n", - " [ -12.53162432 -110.86000329 36.55242777 662.76125156]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.53e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.54e-02 3.85e+00 -1.0 1.38e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.52e-04 4.39e+00 -1.0 1.39e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 1.21e-12 1.02e-06 -1.0 1.37e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.2079226507921703e-12 1.2079226507921703e-12\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.2079226507921703e-12 1.2079226507921703e-12\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.108\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.4\n", - "[[ 46.59286925 3.34061422 -147.41037617 -20.11631538]\n", - " [ 3.34061422 35.357865 -10.54739617 -212.94980026]\n", - " [-147.41037617 -10.54739617 466.47049433 63.51258081]\n", - " [ -20.11631538 -212.94980026 63.51258081 1282.53549019]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 6.79e+01 2.55e+02 -1.0 1.97e+02 - 2.54e-03 6.55e-01f 1\n", - " 2 0.0000000e+00 6.61e+01 2.48e+02 -1.0 6.79e+01 - 9.64e-02 2.70e-02h 1\n", - " 3 0.0000000e+00 6.61e+01 8.37e+03 -1.0 6.61e+01 - 1.53e-01 3.12e-04h 1\n", - " 4r 0.0000000e+00 6.61e+01 1.00e+03 1.8 0.00e+00 - 0.00e+00 3.91e-07R 4\n", - " 5r 0.0000000e+00 6.67e+01 5.63e+03 1.8 1.73e+04 - 7.67e-03 9.94e-04f 1\n", - " 6r 0.0000000e+00 6.61e+01 9.66e+03 1.8 1.05e+04 - 7.18e-03 1.92e-03f 1\n", - " 7r 0.0000000e+00 5.73e+01 2.19e+04 1.8 3.17e+03 - 2.31e-02 8.98e-03f 1\n", - " 8r 0.0000000e+00 4.55e+01 4.36e+04 1.8 2.06e+03 - 3.06e-02 6.44e-03f 1\n", - " 9r 0.0000000e+00 1.70e+01 4.20e+04 1.8 1.76e+03 - 2.61e-02 1.63e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 3.30e+00 3.66e+04 1.8 1.16e+03 - 1.46e-01 1.44e-02f 1\n", - " 11r 0.0000000e+00 3.25e+00 3.00e+04 1.8 3.01e+01 - 2.44e-01 4.88e-02f 1\n", - " 12r 0.0000000e+00 2.82e+00 3.21e+04 1.8 2.66e+01 - 1.32e-01 2.76e-01f 1\n", - " 13r 0.0000000e+00 2.37e+00 3.59e+04 1.8 1.50e+01 - 2.84e-01 4.41e-01f 1\n", - " 14r 0.0000000e+00 2.16e+00 1.80e+04 1.8 5.42e+00 - 4.72e-01 4.96e-01f 1\n", - " 15r 0.0000000e+00 2.03e+00 1.32e+04 1.8 2.30e+00 - 3.74e-01 7.02e-01f 1\n", - " 16r 0.0000000e+00 1.98e+00 1.17e+03 1.8 7.23e-01 - 8.25e-01 1.00e+00f 1\n", - " 17r 0.0000000e+00 2.82e+00 1.50e+02 1.1 1.05e+01 - 8.15e-01 1.00e+00f 1\n", - " 18r 0.0000000e+00 2.91e+00 7.78e+02 -0.3 1.91e+00 - 1.00e+00 6.05e-01f 1\n", - " 19r 0.0000000e+00 1.90e+00 4.96e+02 -0.3 2.51e+01 - 3.68e-01 5.07e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 8.26e-01 1.70e+02 -0.3 2.16e+01 - 6.29e-01 6.19e-01f 1\n", - " 21r 0.0000000e+00 2.72e-02 5.46e+01 -0.3 1.07e+01 - 9.66e-01 9.45e-01f 1\n", - " 22r 0.0000000e+00 2.41e-01 9.04e-02 -0.3 2.89e+00 - 1.00e+00 1.00e+00h 1\n", - " 23r 0.0000000e+00 1.84e-01 2.23e+02 -1.7 8.95e-01 - 9.77e-01 8.00e-01f 1\n", - " 24r 0.0000000e+00 9.24e-02 3.27e+03 -1.7 7.88e+01 - 4.30e-01 2.01e-02f 1\n", - " 25r 0.0000000e+00 6.91e-02 4.42e+03 -1.7 2.78e+01 - 1.00e+00 8.35e-02f 1\n", - " 26r 0.0000000e+00 6.19e-02 4.27e+03 -1.7 2.15e+01 - 1.00e+00 1.01e-01f 1\n", - " 27r 0.0000000e+00 5.33e-02 3.71e+03 -1.7 1.63e+01 - 1.00e+00 1.38e-01f 1\n", - " 28r 0.0000000e+00 4.09e-02 2.86e+03 -1.7 1.70e+00 - 1.00e+00 2.31e-01f 1\n", - " 29r 0.0000000e+00 5.26e-04 3.44e+01 -1.7 6.11e-01 - 1.00e+00 9.88e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 4.79e-05 1.18e-05 -1.7 7.08e-03 - 1.00e+00 1.00e+00f 1\n", - " 31r 0.0000000e+00 2.78e-06 4.99e+01 -3.8 9.31e-03 - 1.00e+00 9.51e-01f 1\n", - " 32r 0.0000000e+00 9.04e-07 1.47e+02 -3.8 1.14e-03 - 1.00e+00 6.33e-01f 1\n", - " 33r 0.0000000e+00 2.71e-07 1.48e-07 -3.8 1.85e-04 - 1.00e+00 1.00e+00f 1\n", - " 34r 0.0000000e+00 9.86e-09 2.31e+00 -8.5 6.77e-06 - 1.00e+00 9.30e-01f 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.8581836027733516e-09 9.8581836027733516e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.8581836027733516e-09 9.8581836027733516e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 36\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.544\n", - "Total CPU secs in NLP function evaluations = 0.064\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "[[ 29.19391386 5.4515142 -83.05757061 -24.12403549]\n", - " [ 5.4515142 26.22057856 -12.68483021 -138.46453604]\n", - " [ -83.05757061 -12.68483021 243.6214775 59.65060539]\n", - " [ -24.12403549 -138.46453604 59.65060539 764.11690335]]\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.88e+02 1.06e+02 -1.0 3.97e+02 - 2.54e-03 2.75e-01f 1\n", - " 2 0.0000000e+00 2.84e+02 1.05e+02 -1.0 2.88e+02 - 5.84e-02 1.38e-02h 1\n", - " 3 0.0000000e+00 2.84e+02 6.74e+03 -1.0 2.84e+02 - 8.78e-02 1.63e-04h 1\n", - " 4r 0.0000000e+00 2.84e+02 1.00e+03 2.5 0.00e+00 - 0.00e+00 4.09e-07R 3\n", - " 5r 0.0000000e+00 2.65e+02 4.54e+03 2.5 1.27e+04 - 9.57e-03 2.21e-02f 1\n", - " 6r 0.0000000e+00 2.62e+02 5.22e+03 1.8 1.16e+03 - 1.22e-01 2.99e-03f 1\n", - " 7r 0.0000000e+00 2.17e+02 1.22e+04 1.8 2.24e+03 - 1.37e-01 2.14e-02f 1\n", - " 8r 0.0000000e+00 1.98e+02 2.11e+04 1.8 1.52e+03 - 3.43e-01 1.19e-02f 1\n", - " 9r 0.0000000e+00 7.11e+01 1.83e+04 1.8 8.57e+02 - 1.81e-01 1.62e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 3.55e+01 2.82e+04 1.8 3.09e+02 - 5.74e-01 1.19e-01f 1\n", - " 11r 0.0000000e+00 2.71e+01 2.37e+04 1.8 5.61e+01 - 2.77e-01 1.52e-01f 1\n", - " 12r 0.0000000e+00 1.86e+01 1.20e+04 1.8 3.65e+01 - 1.00e+00 2.34e-01f 1\n", - " 13r 0.0000000e+00 4.96e+00 1.82e+03 1.8 1.80e+01 - 1.00e+00 7.59e-01f 1\n", - " 14r 0.0000000e+00 3.88e+00 2.00e+03 1.1 8.16e+00 - 1.00e+00 6.28e-01f 1\n", - " 15r 0.0000000e+00 3.88e+00 2.12e+03 1.1 1.91e+00 - 1.00e+00 6.37e-01f 1\n", - " 16r 0.0000000e+00 3.89e+00 2.53e+01 1.1 5.29e-01 - 1.00e+00 1.00e+00f 1\n", - " 17r 0.0000000e+00 4.00e+00 9.24e+02 -1.0 6.41e+00 - 9.23e-01 3.65e-01f 1\n", - " 18r 0.0000000e+00 4.00e+00 6.06e+02 -1.0 8.54e+00 - 2.38e-01 6.12e-01f 1\n", - " 19r 0.0000000e+00 3.82e+00 2.67e+03 -1.0 1.38e+01 - 8.45e-03 4.34e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 3.49e+00 2.91e+03 -1.0 2.16e+01 - 1.81e-01 3.33e-01f 1\n", - " 21r 0.0000000e+00 3.04e+00 2.45e+03 -1.0 2.44e+01 - 2.81e-01 4.00e-01f 1\n", - " 22r 0.0000000e+00 2.49e+00 2.47e+03 -1.0 2.48e+01 - 1.11e-01 4.77e-01f 1\n", - " 23r 0.0000000e+00 2.02e+00 9.87e+02 -1.0 1.69e+01 - 5.96e-01 5.88e-01f 1\n", - " 24r 0.0000000e+00 1.58e+00 6.84e+02 -1.0 1.01e+01 - 7.58e-01 9.54e-01f 1\n", - " 25r 0.0000000e+00 1.54e+00 2.82e-03 -1.0 8.65e-01 - 1.00e+00 1.00e+00f 1\n", - " 26r 0.0000000e+00 1.55e+00 4.05e+02 -3.9 4.34e-01 - 9.88e-01 7.49e-01f 1\n", - " 27r 0.0000000e+00 6.78e-02 1.12e+03 -3.9 1.80e+03 - 2.85e-02 1.85e-02f 1\n", - " 28r 0.0000000e+00 6.78e-02 3.06e+03 -3.9 1.77e+03 - 5.48e-02 2.33e-06f 1\n", - " 29r 0.0000000e+00 6.78e-02 3.68e+03 -3.9 1.06e+03 - 9.19e-02 1.15e-04f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 4.53e-02 4.22e+03 -3.9 3.54e+02 - 1.00e+00 1.57e-02f 1\n", - " 31r 0.0000000e+00 3.59e-02 4.41e+03 -3.9 3.39e+02 - 1.00e+00 6.72e-03f 1\n", - " 32r 0.0000000e+00 4.50e-03 4.37e+03 -3.9 3.23e+02 - 1.00e+00 2.67e-02f 1\n", - " 33r 0.0000000e+00 3.36e-03 4.21e+03 -3.9 6.29e+00 - 1.00e+00 4.40e-02f 1\n", - " 34r 0.0000000e+00 1.89e-04 3.05e+02 -3.9 8.22e-01 - 1.00e+00 9.29e-01f 1\n", - " 35r 0.0000000e+00 6.15e-05 1.17e+03 -3.9 4.55e-02 - 1.00e+00 6.75e-01f 1\n", - " 36r 0.0000000e+00 3.79e-05 2.05e+03 -3.9 1.48e-02 - 1.00e+00 3.85e-01f 1\n", - " 37r 0.0000000e+00 1.94e-07 3.86e-06 -3.9 9.09e-03 - 1.00e+00 1.00e+00f 1\n", - " 38r 0.0000000e+00 6.81e-08 1.50e+03 -5.9 1.01e-05 - 1.00e+00 5.73e-01f 1\n", - " 39r 0.0000000e+00 2.35e-08 1.26e+03 -5.9 7.54e-06 - 9.51e-01 7.37e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40r 0.0000000e+00 6.36e-09 4.69e+02 -5.9 1.34e-06 - 1.00e+00 7.63e-01f 1\n", - "\n", - "Number of Iterations....: 40\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 6.3620335666314531e-09 6.3620335666314531e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 6.3620335666314531e-09 6.3620335666314531e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 44\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 44\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 42\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 40\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.718\n", - "Total CPU secs in NLP function evaluations = 0.045\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "[[ 25.12751441 3.3894616 -73.80390505 -15.08681458]\n", - " [ 3.3894616 19.93219076 -7.86497679 -113.88461226]\n", - " [ -73.80390505 -7.86497679 223.85064824 40.06464174]\n", - " [ -15.08681458 -113.88461226 40.06464174 670.5564622 ]]\n" - ] - } - ], - "source": [ - "# Make a function that takes in experimental design and gives you a new doe object\n", - "def new_doe_object(Ca, T0):\n", - " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", - " \n", - " measurements = MeasurementVariables()\n", - " measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", - " \n", - " exp_design = DesignVariables()\n", - " exp_design.add_variables(\n", - " \"CA0\",\n", - " time_index_position=0,\n", - " # values=[Ca],\n", - " lower_bounds=1,\n", - " indices={0: [0]},\n", - " upper_bounds=5,\n", - " )\n", - " exp_design.add_variables(\n", - " \"T\",\n", - " indices={0: t_control},\n", - " time_index_position=0,\n", - " # values=[T0]*9,\n", - " lower_bounds=300,\n", - " upper_bounds=700,\n", - " )\n", - "\n", - " exp_design.update_values({\"CA0[0]\": Ca, \"T[0]\": T0, \"T[0.125]\": T0, \"T[0.25]\": T0, \"T[0.375]\": T0, \"T[0.5]\": T0, \"T[0.625]\": T0,\n", - " \"T[0.75]\": T0, \"T[0.875]\": T0, \"T[1]\": T0})\n", - "\n", - " prior_pass = [\n", - " [22.52943024, 1.84034314, -70.23273336, -11.09432962],\n", - " [1.84034314, 18.09848116, -5.73565034, -109.15866135],\n", - " [-70.23273336, -5.73565034, 218.94192843, 34.57680848],\n", - " [-11.09432962, -109.15866135, 34.57680848, 658.37644634]\n", - " ]\n", - " \n", - " doe_object = DesignOfExperiments(\n", - " parameter_dict,\n", - " exp_design, \n", - " measurements, \n", - " create_model,\n", - " prior_FIM=prior_pass,\n", - " discretize_model=disc_for_measure,\n", - " )\n", - "\n", - " result = doe_object.compute_FIM(\n", - " mode=\"sequential_finite\",\n", - " scale_nominal_param_value=True,\n", - " formula=\"central\",\n", - " )\n", - "\n", - " result.result_analysis()\n", - " \n", - " return result\n", - "\n", - "\n", - "# Discretize the experimental design space (make a linspace) for sensitivity analysis\n", - "T_vals = np.linspace(300, 700, 3)\n", - "C_vals = np.linspace(1, 5, 3)\n", - "\n", - "A_opt_vals = []\n", - "D_opt_vals = []\n", - "E_opt_vals = []\n", - "ME_opt_vals = []\n", - "for i in C_vals:\n", - " for j in T_vals:\n", - " fims = new_doe_object(i, j)\n", - " print(fims.FIM)\n", - " A_opt = np.trace(fims.FIM)\n", - " D_opt = np.linalg.det(fims.FIM)\n", - " E_opt = min(np.linalg.eigvals(fims.FIM))\n", - " ME_opt = np.linalg.cond(fims.FIM)\n", - " \n", - " A_opt_vals.append(np.log10(A_opt))\n", - " D_opt_vals.append(np.log10(D_opt))\n", - " E_opt_vals.append(np.log10(E_opt))\n", - " ME_opt_vals.append(np.log10(ME_opt))" - ] - }, - { - "cell_type": "code", - "execution_count": 93, - "id": "f05a1814-1b73-4eef-853b-58594589635f", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([4.10820024])" - ] - }, - "execution_count": 93, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# random experiment loop\n", - "np.random.rand(1) * 4 + 1" - ] - }, - { - "cell_type": "code", - "execution_count": 94, - "id": "3127f8a2-798e-474e-a90d-89eb1c2aca06", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.47e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.64e+01 3.85e+02 -1.0 1.47e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.71e+00 5.99e+01 -1.0 3.11e+01 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 3.98e-02 2.06e+00 -1.0 3.19e+00 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 7.87e-07 2.39e-04 -1.0 2.80e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (287125)\n", - " 5 0.0000000e+00 2.27e-13 1.50e-09 -3.8 5.42e-07 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.3691704763652764e-13 2.2737367544323206e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.3691704763652764e-13 2.2737367544323206e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.072\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.4\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.79e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 9.63e+01 2.70e+02 -1.0 3.79e+02 - 2.73e-03 7.46e-01f 1\n", - " 2 0.0000000e+00 9.32e+01 2.61e+02 -1.0 9.63e+01 - 6.76e-02 3.18e-02h 1\n", - " 3 0.0000000e+00 9.32e+01 4.47e+03 -1.0 9.32e+01 - 1.23e-01 3.69e-04h 1\n", - " 4r 0.0000000e+00 9.32e+01 1.00e+03 2.0 0.00e+00 - 0.00e+00 4.62e-07R 4\n", - " 5r 0.0000000e+00 9.47e+01 3.38e+03 2.0 1.88e+04 - 7.23e-03 1.52e-03f 1\n", - " 6r 0.0000000e+00 9.56e+01 8.77e+03 1.3 9.69e+03 - 1.49e-02 2.29e-03f 1\n", - " 7r 0.0000000e+00 9.02e+01 1.81e+04 1.3 2.12e+03 - 1.81e-02 5.67e-03f 1\n", - " 8r 0.0000000e+00 7.27e+01 4.84e+04 1.3 2.78e+03 - 4.24e-02 8.77e-03f 1\n", - " 9r 0.0000000e+00 7.18e+01 4.87e+04 1.3 1.96e+03 - 1.12e-02 4.83e-04f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 3.41e+01 4.77e+04 1.3 1.67e+03 - 1.59e-02 2.26e-02f 1\n", - " 11r 0.0000000e+00 2.89e+01 4.49e+04 1.3 1.04e+03 - 1.79e-01 4.94e-03f 1\n", - " 12r 0.0000000e+00 2.20e+01 3.81e+04 1.3 2.29e+02 - 2.37e-01 3.01e-02f 1\n", - " 13r 0.0000000e+00 7.18e+00 3.39e+04 1.3 9.62e+01 - 3.56e-01 1.55e-01f 1\n", - " 14r 0.0000000e+00 3.48e+00 3.59e+04 1.3 2.78e+01 - 6.26e-01 2.52e-01f 1\n", - " 15r 0.0000000e+00 2.86e+00 2.83e+04 1.3 1.68e+01 - 3.20e-02 1.85e-01f 1\n", - " 16r 0.0000000e+00 2.68e+00 2.65e+04 1.3 1.50e+01 - 1.58e-01 6.45e-02f 1\n", - " 17r 0.0000000e+00 2.20e+00 2.12e+04 1.3 6.49e+00 - 5.44e-01 1.84e-01f 1\n", - " 18r 0.0000000e+00 1.93e+00 9.46e+03 1.3 4.48e+00 - 7.25e-01 5.25e-01f 1\n", - " 19r 0.0000000e+00 1.89e+00 6.10e+03 1.3 1.60e+00 - 1.00e+00 3.45e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 1.87e+00 3.70e+03 1.3 7.92e-01 - 3.59e-01 4.16e-01f 1\n", - " 21r 0.0000000e+00 1.87e+00 3.40e+04 1.3 4.32e-01 - 6.73e-01 2.10e-01f 1\n", - " 22r 0.0000000e+00 1.87e+00 1.96e+04 1.3 3.07e-01 - 2.16e-01 3.56e-01f 1\n", - " 23r 0.0000000e+00 1.88e+00 5.64e+04 1.3 2.13e-01 - 2.36e-01 1.00e+00f 1\n", - " 24r 0.0000000e+00 1.86e+00 2.34e+00 1.3 2.78e-01 - 1.00e+00 1.00e+00f 1\n", - " 25r 0.0000000e+00 2.46e+00 3.10e+01 -0.8 8.15e+00 - 6.90e-01 7.24e-01f 1\n", - " 26r 0.0000000e+00 1.88e+00 3.41e+02 -0.8 2.98e+01 - 4.36e-01 3.54e-01f 1\n", - " 27r 0.0000000e+00 5.36e-01 3.71e+02 -0.8 3.60e+01 - 4.50e-01 4.02e-01f 1\n", - " 28r 0.0000000e+00 9.73e-02 1.52e+03 -0.8 4.27e+01 - 3.79e-01 1.29e-01f 1\n", - " 29r 0.0000000e+00 9.74e-02 4.95e+03 -0.8 3.18e+01 - 6.93e-01 3.32e-03f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 9.31e-02 5.14e+03 -0.8 8.75e+00 - 1.00e+00 1.62e-01f 1\n", - " 31r 0.0000000e+00 7.82e-02 1.83e+03 -0.8 6.58e+00 - 1.00e+00 6.63e-01f 1\n", - " 32r 0.0000000e+00 7.12e-02 1.65e+02 -0.8 2.21e+00 - 1.00e+00 9.14e-01f 1\n", - " 33r 0.0000000e+00 7.05e-02 2.39e-05 -0.8 2.63e-01 - 1.00e+00 1.00e+00f 1\n", - " 34r 0.0000000e+00 7.07e-02 1.56e+02 -3.4 4.12e-01 - 1.00e+00 7.89e-01f 1\n", - " 35r 0.0000000e+00 3.58e-04 8.04e+02 -3.4 5.07e+02 - 9.62e-01 3.36e-02f 1\n", - " 36r 0.0000000e+00 3.58e-04 8.39e+02 -3.4 2.26e+02 - 1.00e+00 8.40e-05f 1\n", - " 37r 0.0000000e+00 1.64e-04 4.20e+02 -3.4 9.66e-02 - 1.00e+00 5.43e-01f 1\n", - " 38r 0.0000000e+00 6.08e-08 1.58e-05 -3.4 4.52e-02 - 1.00e+00 1.00e+00f 1\n", - " 39r 0.0000000e+00 4.61e-10 3.50e-01 -7.7 2.55e-05 - 1.00e+00 9.99e-01f 1\n", - "\n", - "Number of Iterations....: 39\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.6097259343014230e-10 4.6097259343014230e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.6097259343014230e-10 4.6097259343014230e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 44\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 44\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 41\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 39\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.332\n", - "Total CPU secs in NLP function evaluations = 0.028\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.47e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.21e+02 1.90e+02 -1.0 3.47e+02 - 3.38e-03 6.51e-01f 1\n", - " 2 0.0000000e+00 1.16e+02 1.83e+02 -1.0 1.21e+02 - 8.04e-02 3.68e-02h 1\n", - " 3 0.0000000e+00 1.16e+02 5.05e+03 -1.0 1.16e+02 - 1.48e-01 4.53e-04h 1\n", - " 4r 0.0000000e+00 1.16e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 2.84e-07R 5\n", - " 5r 0.0000000e+00 1.14e+02 2.71e+03 2.1 7.90e+03 - 1.08e-02 5.20e-03f 1\n", - " 6r 0.0000000e+00 1.10e+02 8.74e+03 1.4 1.44e+03 - 2.83e-02 5.26e-03f 1\n", - " 7r 0.0000000e+00 8.03e+01 1.59e+04 1.4 3.04e+03 - 4.49e-02 1.19e-02f 1\n", - " 8r 0.0000000e+00 4.23e+01 1.55e+04 1.4 2.42e+03 - 6.77e-02 1.57e-02f 1\n", - " 9r 0.0000000e+00 2.55e+01 9.59e+03 1.4 1.06e+03 - 3.03e-01 1.60e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 2.97e+00 6.56e+03 1.4 1.85e+02 - 1.66e-01 1.30e-01f 1\n", - " 11r 0.0000000e+00 2.46e+00 6.17e+03 1.4 2.18e+01 - 2.39e-01 1.35e-01f 1\n", - " 12r 0.0000000e+00 1.69e+00 8.83e+03 1.4 1.49e+01 - 2.90e-01 5.14e-01f 1\n", - " 13r 0.0000000e+00 1.63e+00 5.65e+03 1.4 2.04e+00 - 4.09e-01 3.77e-01f 1\n", - " 14r 0.0000000e+00 1.63e+00 4.72e+03 1.4 1.76e+00 - 1.17e-01 4.02e-01f 1\n", - " 15r 0.0000000e+00 1.63e+00 4.34e+03 1.4 1.14e+00 - 3.39e-01 2.20e-01f 1\n", - " 16r 0.0000000e+00 1.63e+00 5.17e+03 1.4 5.39e-01 - 2.44e-01 3.70e-01f 1\n", - " 17r 0.0000000e+00 1.61e+00 1.25e+04 1.4 2.67e-01 - 3.33e-01 1.00e+00f 1\n", - " 18r 0.0000000e+00 1.57e+00 6.37e-01 1.4 3.12e-01 - 1.00e+00 1.00e+00f 1\n", - " 19r 0.0000000e+00 2.14e+00 7.01e+01 -0.7 5.85e+00 - 6.75e-01 7.41e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 1.66e+00 6.97e+01 -0.7 1.81e+01 - 4.31e-01 4.08e-01f 1\n", - " 21r 0.0000000e+00 7.63e-01 5.00e+02 -0.7 2.19e+01 - 5.02e-01 3.90e-01f 1\n", - " 22r 0.0000000e+00 7.13e-02 6.33e+02 -0.7 2.85e+01 - 4.13e-01 2.39e-01f 1\n", - " 23r 0.0000000e+00 7.15e-02 1.44e+03 -0.7 2.04e+01 - 4.36e-01 4.86e-03f 1\n", - " 24r 0.0000000e+00 7.02e-02 2.07e+03 -0.7 5.19e+00 - 1.00e+00 8.72e-02f 1\n", - " 25r 0.0000000e+00 5.96e-02 3.86e+02 -0.7 4.18e+00 - 1.00e+00 8.42e-01f 1\n", - " 26r 0.0000000e+00 5.77e-02 2.81e-03 -0.7 6.30e-01 - 1.00e+00 1.00e+00f 1\n", - " 27r 0.0000000e+00 5.79e-02 6.37e+02 -3.2 5.03e-01 - 9.99e-01 6.84e-01f 1\n", - " 28r 0.0000000e+00 3.93e-02 2.66e+03 -3.2 2.99e+02 - 9.51e-01 1.50e-02f 1\n", - " 29r 0.0000000e+00 4.06e-04 3.64e+03 -3.2 2.94e+02 - 1.00e+00 3.22e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 4.05e-04 3.79e+03 -3.2 2.60e+01 - 1.00e+00 1.82e-03f 1\n", - " 31r 0.0000000e+00 2.92e-05 2.72e+02 -3.2 1.69e-01 - 1.00e+00 9.28e-01f 1\n", - " 32r 0.0000000e+00 1.25e-07 7.91e-06 -3.2 1.22e-02 - 1.00e+00 1.00e+00f 1\n", - " 33r 0.0000000e+00 5.10e-09 4.43e-01 -7.2 5.28e-05 - 1.00e+00 9.97e-01f 1\n", - "\n", - "Number of Iterations....: 33\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.1933425768594618e-09 5.0964019530138488e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.1933425768594618e-09 5.0964019530138488e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 35\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 33\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.281\n", - "Total CPU secs in NLP function evaluations = 0.043\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.75e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.27e+02 8.39e+01 -1.0 3.75e+02 - 7.66e-03 6.60e-01f 1\n", - " 2 0.0000000e+00 1.21e+02 7.95e+01 -1.0 1.27e+02 - 8.92e-02 5.26e-02h 1\n", - " 3 0.0000000e+00 1.21e+02 5.06e+03 -1.0 1.21e+02 - 1.90e-01 6.85e-04h 1\n", - " 4r 0.0000000e+00 1.21e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 4.29e-07R 5\n", - " 5r 0.0000000e+00 1.18e+02 3.76e+03 2.1 1.32e+04 - 1.10e-02 4.67e-03f 1\n", - " 6r 0.0000000e+00 1.13e+02 1.04e+04 1.4 1.51e+03 - 2.60e-02 6.04e-03f 1\n", - " 7r 0.0000000e+00 7.22e+01 1.49e+04 1.4 2.88e+03 - 2.82e-02 1.57e-02f 1\n", - " 8r 0.0000000e+00 4.91e+01 1.55e+04 1.4 2.25e+03 - 1.34e-01 1.11e-02f 1\n", - " 9r 0.0000000e+00 4.46e+01 1.03e+04 1.4 6.00e+02 - 1.39e-01 7.47e-03f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 1.28e+01 2.43e+04 1.4 2.89e+02 - 3.16e-01 1.10e-01f 1\n", - " 11r 0.0000000e+00 2.22e+00 2.04e+04 1.4 6.20e+01 - 2.94e-01 2.05e-01f 1\n", - " 12r 0.0000000e+00 1.78e+00 1.86e+04 1.4 1.16e+01 - 6.29e-01 1.84e-01f 1\n", - " 13r 0.0000000e+00 1.60e+00 1.47e+04 1.4 1.15e+01 - 2.26e-01 1.37e-01f 1\n", - " 14r 0.0000000e+00 1.18e+00 1.20e+04 1.4 5.45e+00 - 1.92e-01 2.67e-01f 1\n", - " 15r 0.0000000e+00 8.27e-01 7.10e+03 1.4 4.24e+00 - 3.39e-01 2.57e-01f 1\n", - " 16r 0.0000000e+00 7.55e-01 4.82e+03 1.4 2.29e+00 - 4.12e-01 1.42e-01f 1\n", - " 17r 0.0000000e+00 5.13e-01 1.07e+04 1.4 1.12e+00 - 2.45e-01 4.22e-01f 1\n", - " 18r 0.0000000e+00 5.10e-01 8.28e+03 1.4 6.72e-01 - 2.21e-01 2.17e-01f 1\n", - " 19r 0.0000000e+00 5.06e-01 9.33e+03 1.4 5.23e-01 - 2.44e-01 5.04e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 4.54e-01 9.33e+01 1.4 5.96e-01 - 9.69e-01 1.00e+00f 1\n", - " 21r 0.0000000e+00 9.44e-01 4.24e+02 -0.0 4.97e+00 - 4.34e-01 7.87e-01f 1\n", - " 22r 0.0000000e+00 7.53e-01 9.03e+01 -0.0 7.82e+00 - 5.74e-01 5.18e-01f 1\n", - " 23r 0.0000000e+00 3.96e-01 3.26e+02 -0.0 6.53e+00 - 7.93e-01 6.49e-01f 1\n", - " 24r 0.0000000e+00 6.22e-02 1.69e+02 -0.0 5.24e+00 - 1.00e+00 8.48e-01f 1\n", - " 25r 0.0000000e+00 1.21e-01 5.96e-02 -0.0 1.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 26r 0.0000000e+00 1.23e-01 2.48e+01 -1.4 6.66e-01 - 7.98e-01 7.68e-01f 1\n", - " 27r 0.0000000e+00 8.31e-02 1.67e+03 -1.4 6.15e+01 - 1.89e-01 1.54e-02f 1\n", - " 28r 0.0000000e+00 7.45e-02 3.08e+03 -1.4 2.92e+01 - 8.39e-01 1.52e-02f 1\n", - " 29r 0.0000000e+00 5.63e-02 2.74e+03 -1.4 2.79e+01 - 1.00e+00 1.93e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 3.32e-02 1.62e+03 -1.4 2.20e+01 - 1.00e+00 4.05e-01f 1\n", - " 31r 0.0000000e+00 3.05e-02 1.50e+03 -1.4 4.31e+00 - 1.00e+00 7.84e-02f 1\n", - " 32r 0.0000000e+00 2.85e-03 1.41e+02 -1.4 5.52e-01 - 1.00e+00 9.06e-01f 1\n", - " 33r 0.0000000e+00 8.12e-05 5.53e-04 -1.4 4.22e-02 - 1.00e+00 1.00e+00f 1\n", - " 34r 0.0000000e+00 5.19e-06 2.99e+01 -4.8 3.09e-02 - 1.00e+00 9.39e-01f 1\n", - " 35r 0.0000000e+00 2.12e-06 3.88e+02 -4.8 5.79e-03 - 1.00e+00 3.73e-01f 1\n", - " 36r 0.0000000e+00 4.48e-10 1.79e-06 -4.8 5.54e-04 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 36\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.4780146257750175e-10 4.4780146257750175e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.4780146257750175e-10 4.4780146257750175e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 42\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 42\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 38\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 36\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.329\n", - "Total CPU secs in NLP function evaluations = 0.023\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.8\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.15e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 5.48e+01 2.03e+02 -1.0 3.15e+02 - 4.01e-03 8.26e-01f 1\n", - " 2 0.0000000e+00 5.18e+01 1.92e+02 -1.0 5.48e+01 - 8.17e-02 5.52e-02h 1\n", - " 3 0.0000000e+00 5.17e+01 4.29e+03 -1.0 5.18e+01 - 1.73e-01 6.99e-04h 1\n", - " 4r 0.0000000e+00 5.17e+01 1.00e+03 1.7 0.00e+00 - 0.00e+00 4.38e-07R 5\n", - " 5r 0.0000000e+00 5.21e+01 3.90e+03 1.7 2.34e+03 - 4.16e-03 6.39e-04f 1\n", - " 6r 0.0000000e+00 5.22e+01 7.89e+03 1.7 1.59e+03 - 5.68e-03 1.06e-03f 1\n", - " 7r 0.0000000e+00 5.14e+01 4.08e+04 1.7 1.33e+03 - 4.31e-02 4.03e-03f 1\n", - " 8r 0.0000000e+00 3.35e+01 4.38e+04 1.7 1.29e+03 - 2.87e-02 1.99e-02f 1\n", - " 9r 0.0000000e+00 2.33e+01 3.77e+04 1.7 2.06e+03 - 8.82e-02 4.96e-03f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 5.31e+00 2.32e+04 1.7 8.19e+02 - 4.10e-01 2.82e-02f 1\n", - " 11r 0.0000000e+00 3.31e+00 9.35e+03 1.7 2.79e+01 - 4.57e-01 2.18e-01f 1\n", - " 12r 0.0000000e+00 1.54e+00 1.11e+04 1.7 1.44e+01 - 3.37e-01 4.76e-01f 1\n", - " 13r 0.0000000e+00 9.67e-01 5.00e+03 1.7 3.61e+00 - 6.85e-01 6.15e-01f 1\n", - " 14r 0.0000000e+00 7.59e-01 7.16e+00 1.7 2.56e+00 - 1.00e+00 1.00e+00f 1\n", - " 15r 0.0000000e+00 1.45e+00 2.49e+02 -0.4 9.91e+00 - 4.68e-01 7.63e-01f 1\n", - " 16r 0.0000000e+00 1.16e+00 3.68e+02 -0.4 1.08e+01 - 6.33e-01 4.50e-01f 1\n", - " 17r 0.0000000e+00 3.39e-01 2.33e+02 -0.4 1.75e+01 - 6.02e-01 5.35e-01f 1\n", - " 18r 0.0000000e+00 2.54e-02 1.04e+03 -0.4 2.08e+01 - 6.33e-01 1.79e-01f 1\n", - " 19r 0.0000000e+00 2.53e-02 1.45e+03 -0.4 6.72e+00 - 1.00e+00 1.86e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 1.60e-02 1.72e+02 -0.4 4.41e+00 - 1.00e+00 8.92e-01f 1\n", - " 21r 0.0000000e+00 1.49e-02 3.13e-03 -0.4 4.38e-01 - 1.00e+00 1.00e+00f 1\n", - " 22r 0.0000000e+00 1.46e-02 4.88e+02 -2.7 5.10e-01 - 1.00e+00 7.79e-01f 1\n", - " 23r 0.0000000e+00 1.62e-03 1.95e+03 -2.7 1.98e+02 - 8.89e-01 1.78e-02f 1\n", - " 24r 0.0000000e+00 1.33e-03 1.81e+03 -2.7 1.39e+00 - 1.00e+00 6.22e-02f 1\n", - " 25r 0.0000000e+00 7.19e-06 1.11e+01 -2.7 4.06e-01 - 1.00e+00 9.94e-01f 1\n", - " 26r 0.0000000e+00 3.77e-07 6.55e-08 -2.7 2.13e-03 - 1.00e+00 1.00e+00f 1\n", - " 27r 0.0000000e+00 7.89e-09 4.38e-01 -6.0 1.65e-04 - 1.00e+00 9.99e-01f 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 6.8976688608700370e-09 7.8893271863306191e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 6.8976688608700370e-09 7.8893271863306191e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 29\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.279\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.45e+02 4.98e+01 -1.0 3.96e+02 - 7.44e-03 3.82e-01f 1\n", - " 2 0.0000000e+00 2.36e+02 4.81e+01 -1.0 2.45e+02 - 1.33e-01 3.44e-02h 1\n", - " 3 0.0000000e+00 2.36e+02 1.20e+04 -1.0 2.36e+02 - 2.37e-01 4.38e-04h 1\n", - " 4r 0.0000000e+00 2.36e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 2.75e-07R 5\n", - " 5r 0.0000000e+00 2.26e+02 1.13e+03 2.4 1.23e+04 - 7.14e-03 8.92e-03f 1\n", - " 6r 0.0000000e+00 2.22e+02 2.63e+03 1.0 1.35e+03 - 4.20e-02 3.84e-03f 1\n", - " 7r 0.0000000e+00 1.66e+02 4.09e+03 1.0 4.68e+03 - 2.15e-02 1.19e-02f 1\n", - " 8r 0.0000000e+00 1.54e+02 7.04e+03 1.0 3.41e+03 - 6.48e-02 3.70e-03f 1\n", - " 9r 0.0000000e+00 1.00e+02 9.04e+03 1.0 2.10e+03 - 1.47e-01 2.81e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 5.77e+01 9.14e+03 1.0 6.36e+02 - 2.78e-01 6.69e-02f 1\n", - " 11r 0.0000000e+00 2.10e+01 7.43e+03 1.0 1.64e+02 - 2.45e-01 2.24e-01f 1\n", - " 12r 0.0000000e+00 6.07e+00 7.89e+03 1.0 4.33e+01 - 6.44e-01 3.46e-01f 1\n", - " 13r 0.0000000e+00 2.19e+00 4.02e+03 1.0 8.39e+00 - 5.64e-01 4.67e-01f 1\n", - " 14r 0.0000000e+00 9.56e-01 1.95e+03 1.0 3.19e+00 - 4.50e-01 3.89e-01f 1\n", - " 15r 0.0000000e+00 5.36e-01 9.74e+02 1.0 1.71e+00 - 3.50e-01 3.26e-01f 1\n", - " 16r 0.0000000e+00 5.38e-01 2.58e+03 1.0 9.75e-01 - 3.56e-01 4.28e-01f 1\n", - " 17r 0.0000000e+00 5.42e-01 1.63e+03 1.0 6.88e-01 - 6.24e-01 5.31e-01f 1\n", - " 18r 0.0000000e+00 5.46e-01 7.82e+00 1.0 5.18e-01 - 1.00e+00 1.00e+00f 1\n", - " 19r 0.0000000e+00 9.22e-01 4.37e+02 -1.1 5.33e+00 - 5.40e-01 8.04e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 5.65e-01 1.82e+03 -1.1 1.08e+01 - 1.64e-01 4.12e-01f 1\n", - " 21r 0.0000000e+00 4.50e-02 1.28e+03 -1.1 1.65e+01 - 3.58e-01 3.90e-01f 1\n", - " 22r 0.0000000e+00 2.31e-03 2.20e+03 -1.1 2.78e+01 - 4.49e-01 1.90e-02f 1\n", - " 23r 0.0000000e+00 2.27e-03 2.78e+03 -1.1 2.10e+00 - 1.00e+00 1.41e-02f 1\n", - " 24r 0.0000000e+00 1.39e-04 2.09e+02 -1.1 9.81e-01 - 1.00e+00 9.24e-01f 1\n", - " 25r 0.0000000e+00 6.99e-05 1.01e-03 -1.1 2.85e-02 - 1.00e+00 1.00e+00f 1\n", - " 26r 0.0000000e+00 2.43e-05 6.84e+02 -4.1 2.96e-02 - 1.00e+00 7.85e-01f 1\n", - " 27r 0.0000000e+00 1.04e-05 1.23e+03 -4.1 1.49e-02 - 8.56e-01 6.16e-01f 1\n", - " 28r 0.0000000e+00 4.47e-07 1.96e+01 -4.1 2.40e-03 - 1.00e+00 9.84e-01f 1\n", - " 29r 0.0000000e+00 2.05e-09 1.48e-08 -4.1 2.07e-04 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.0521482846369565e-09 2.0521482846369565e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.0521482846369565e-09 2.0521482846369565e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 35\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 35\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 31\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.239\n", - "Total CPU secs in NLP function evaluations = 0.039\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.72e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.61e+02 3.60e+01 -1.0 3.72e+02 - 7.93e-03 2.96e-01f 1\n", - " 2 0.0000000e+00 2.53e+02 3.49e+01 -1.0 2.61e+02 - 1.58e-01 3.06e-02h 1\n", - " 3 0.0000000e+00 2.53e+02 2.01e+04 -1.0 2.53e+02 - 3.10e-01 3.94e-04h 1\n", - " 4r 0.0000000e+00 2.53e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.95e-07R 4\n", - " 5r 0.0000000e+00 2.37e+02 1.05e+04 2.4 1.51e+04 - 1.17e-03 1.25e-02f 1\n", - " 6r 0.0000000e+00 2.35e+02 1.18e+04 1.7 1.30e+03 - 8.34e-02 1.70e-03f 1\n", - " 7r 0.0000000e+00 1.83e+02 1.27e+04 1.7 2.44e+03 - 6.29e-02 2.12e-02f 1\n", - " 8r 0.0000000e+00 1.24e+02 1.00e+04 1.7 1.85e+03 - 1.40e-01 3.23e-02f 1\n", - " 9r 0.0000000e+00 6.63e+01 1.21e+04 1.7 1.16e+03 - 2.28e-01 5.10e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 3.68e+01 1.07e+04 1.7 4.32e+02 - 2.77e-01 6.82e-02f 1\n", - " 11r 0.0000000e+00 1.57e+01 9.36e+03 1.7 1.56e+02 - 2.53e-01 1.35e-01f 1\n", - " 12r 0.0000000e+00 2.87e+00 8.33e+03 1.7 6.40e+01 - 5.80e-01 2.43e-01f 1\n", - " 13r 0.0000000e+00 1.93e+00 5.21e+03 1.7 3.30e+00 - 7.93e-01 3.21e-01f 1\n", - " 14r 0.0000000e+00 2.80e-01 2.68e+03 1.7 1.93e+00 - 7.69e-01 1.00e+00f 1\n", - " 15r 0.0000000e+00 1.98e-01 2.17e+03 1.0 2.62e+00 - 1.00e+00 3.68e-01f 1\n", - " 16r 0.0000000e+00 9.94e-02 2.32e+02 1.0 2.49e+00 - 1.00e+00 9.35e-01f 1\n", - " 17r 0.0000000e+00 1.07e-01 2.05e+02 0.3 1.61e+00 - 3.29e-01 4.41e-01f 1\n", - " 18r 0.0000000e+00 1.04e-01 1.05e+03 0.3 3.32e+00 - 1.00e+00 5.33e-01f 1\n", - " 19r 0.0000000e+00 6.40e-02 4.29e-01 0.3 1.54e+00 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 1.07e-01 1.10e+02 -1.8 1.41e+00 - 3.80e-01 4.37e-01f 1\n", - " 21r 0.0000000e+00 1.07e-01 2.01e+02 -1.8 1.95e+01 - 1.74e-01 2.31e-01f 1\n", - " 22r 0.0000000e+00 6.49e-02 5.91e+02 -1.8 9.96e+00 - 2.51e-03 1.11e-01f 1\n", - " 23r 0.0000000e+00 6.33e-02 4.58e+02 -1.8 1.93e+01 - 2.98e-02 7.77e-04f 1\n", - " 24r 0.0000000e+00 5.10e-02 3.76e+02 -1.8 1.93e+01 - 4.61e-02 5.71e-03f 1\n", - " 25r 0.0000000e+00 2.14e-02 2.76e+02 -1.8 1.72e+01 - 6.59e-02 1.56e-02f 1\n", - " 26r 0.0000000e+00 2.87e-03 1.64e+03 -1.8 7.05e+00 - 6.11e-01 3.14e-02f 1\n", - " 27r 0.0000000e+00 1.38e-03 1.02e+03 -1.8 7.30e-01 - 1.00e+00 5.15e-01f 1\n", - " 28r 0.0000000e+00 2.95e-04 3.93e+02 -1.8 1.31e-01 - 1.00e+00 8.08e-01f 1\n", - " 29r 0.0000000e+00 9.46e-05 7.73e+02 -1.8 2.27e-02 - 1.00e+00 7.75e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 3.57e-05 3.29e-04 -1.8 5.02e-03 - 1.00e+00 1.00e+00f 1\n", - " 31r 0.0000000e+00 6.02e-06 6.92e+02 -4.0 3.94e-03 - 1.00e+00 6.62e-01f 1\n", - " 32r 0.0000000e+00 2.81e-06 1.20e+03 -4.0 2.72e-03 - 9.73e-01 6.04e-01f 1\n", - " 33r 0.0000000e+00 9.98e-07 5.98e+02 -4.0 2.90e-04 - 9.64e-01 7.94e-01f 1\n", - " 34r 0.0000000e+00 2.20e-08 6.50e-06 -4.0 7.03e-05 - 1.00e+00 1.00e+00f 1\n", - " 35r 0.0000000e+00 2.23e-09 8.19e-02 -6.0 1.55e-06 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 35\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8426819152568400e-09 2.2255034382400569e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8426819152568400e-09 2.2255034382400569e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 40\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 40\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 37\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 35\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.274\n", - "Total CPU secs in NLP function evaluations = 0.058\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.87e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.68e+02 8.00e+01 -1.0 3.87e+02 - 6.89e-03 5.66e-01f 1\n", - " 2 0.0000000e+00 1.63e+02 7.76e+01 -1.0 1.68e+02 - 7.67e-02 2.95e-02h 1\n", - " 3 0.0000000e+00 1.63e+02 5.80e+03 -1.0 1.63e+02 - 1.40e-01 3.53e-04h 1\n", - " 4r 0.0000000e+00 1.63e+02 1.00e+03 2.2 0.00e+00 - 0.00e+00 4.43e-07R 4\n", - " 5r 0.0000000e+00 1.59e+02 6.51e+03 2.2 1.63e+04 - 1.20e-03 7.89e-03f 1\n", - " 6r 0.0000000e+00 1.58e+02 7.34e+03 1.5 1.51e+03 - 3.35e-02 1.55e-03f 1\n", - " 7r 0.0000000e+00 1.25e+02 9.10e+03 1.5 2.75e+03 - 3.40e-02 1.20e-02f 1\n", - " 8r 0.0000000e+00 7.96e+01 1.06e+04 1.5 2.37e+03 - 1.07e-01 2.00e-02f 1\n", - " 9r 0.0000000e+00 5.15e+01 1.07e+04 1.5 1.06e+03 - 1.37e-01 2.93e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 2.98e+01 9.15e+03 1.5 3.66e+02 - 1.10e-01 6.31e-02f 1\n", - " 11r 0.0000000e+00 1.42e+01 7.49e+03 1.5 1.56e+02 - 1.92e-01 1.00e-01f 1\n", - " 12r 0.0000000e+00 5.99e+00 6.19e+03 1.5 5.89e+01 - 2.77e-01 1.39e-01f 1\n", - " 13r 0.0000000e+00 1.73e+00 4.52e+03 1.5 2.35e+01 - 3.82e-01 2.55e-01f 1\n", - " 14r 0.0000000e+00 1.29e+00 2.91e+03 1.5 6.53e+00 - 4.45e-01 3.67e-01f 1\n", - " 15r 0.0000000e+00 1.23e+00 5.95e+03 1.5 2.69e+00 - 2.74e-01 5.38e-01f 1\n", - " 16r 0.0000000e+00 1.17e+00 1.13e+03 1.5 2.10e+00 - 7.15e-01 9.68e-01f 1\n", - " 17r 0.0000000e+00 1.51e+00 1.07e+02 0.8 7.88e+00 - 8.98e-01 9.05e-01f 1\n", - " 18r 0.0000000e+00 1.52e+00 5.98e+02 0.1 1.35e+00 - 1.00e+00 6.47e-01f 1\n", - " 19r 0.0000000e+00 1.45e+00 8.89e+02 0.1 2.43e+00 - 1.94e-01 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 1.11e+00 1.71e+02 0.1 7.15e+00 - 9.26e-01 1.00e+00f 1\n", - " 21r 0.0000000e+00 1.05e+00 4.83e-02 0.1 1.29e+00 - 1.00e+00 1.00e+00f 1\n", - " 22r 0.0000000e+00 1.19e+00 1.23e+02 -2.0 3.72e+00 - 8.52e-01 7.58e-01f 1\n", - " 23r 0.0000000e+00 4.52e-02 1.95e+03 -2.0 1.34e+02 - 5.22e-02 1.81e-01f 1\n", - " 24r 0.0000000e+00 2.87e-02 1.09e+03 -2.0 1.48e+02 - 1.91e-01 5.32e-03f 1\n", - " 25r 0.0000000e+00 2.87e-02 2.29e+03 -2.0 9.93e+01 - 3.30e-01 8.99e-04f 1\n", - " 26r 0.0000000e+00 1.33e-02 2.25e+03 -2.0 2.85e+01 - 1.00e+00 1.34e-01f 1\n", - " 27r 0.0000000e+00 3.43e-03 2.10e+03 -2.0 2.20e+01 - 1.00e+00 1.39e-01f 1\n", - " 28r 0.0000000e+00 1.99e-03 1.83e+03 -2.0 2.20e+00 - 1.00e+00 1.64e-01f 1\n", - " 29r 0.0000000e+00 1.11e-04 1.19e+02 -2.0 6.96e-01 - 1.00e+00 9.38e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 1.14e-05 2.14e-04 -2.0 4.33e-02 - 1.00e+00 1.00e+00f 1\n", - " 31r 0.0000000e+00 3.06e-06 1.72e+02 -4.5 3.76e-03 - 1.00e+00 8.67e-01f 1\n", - " 32r 0.0000000e+00 1.29e-06 1.73e+02 -4.5 1.18e-03 - 1.00e+00 5.83e-01f 1\n", - " 33r 0.0000000e+00 1.76e-09 1.28e-06 -4.5 1.67e-04 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 33\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.7635167770535531e-09 1.7635167770535531e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.7635167770535531e-09 1.7635167770535531e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 38\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 38\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 35\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 33\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.309\n", - "Total CPU secs in NLP function evaluations = 0.009\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.5\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.79e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.32e+02 8.73e+01 -1.0 3.79e+02 - 4.33e-03 3.87e-01f 1\n", - " 2 0.0000000e+00 2.27e+02 8.51e+01 -1.0 2.32e+02 - 8.32e-02 2.51e-02h 1\n", - " 3 0.0000000e+00 2.26e+02 6.87e+03 -1.0 2.27e+02 - 1.38e-01 3.13e-04h 1\n", - " 4r 0.0000000e+00 2.26e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 3.92e-07R 4\n", - " 5r 0.0000000e+00 2.18e+02 5.24e+03 2.4 6.72e+03 - 1.53e-03 8.08e-03f 1\n", - " 6r 0.0000000e+00 2.11e+02 6.39e+03 1.7 1.35e+03 - 5.23e-02 5.22e-03f 1\n", - " 7r 0.0000000e+00 1.63e+02 7.61e+03 1.7 2.61e+03 - 4.63e-02 1.85e-02f 1\n", - " 8r 0.0000000e+00 1.52e+02 8.34e+03 1.7 2.11e+03 - 1.43e-01 5.53e-03f 1\n", - " 9r 0.0000000e+00 8.62e+01 6.88e+03 1.7 1.35e+03 - 2.57e-01 5.01e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 4.41e+01 7.80e+03 1.7 4.99e+02 - 3.92e-01 8.96e-02f 1\n", - " 11r 0.0000000e+00 1.76e+01 6.21e+03 1.7 1.36e+02 - 1.98e-01 2.04e-01f 1\n", - " 12r 0.0000000e+00 7.94e+00 6.72e+03 1.7 5.67e+01 - 7.95e-01 1.70e-01f 1\n", - " 13r 0.0000000e+00 2.01e+00 4.62e+03 1.7 1.94e+01 - 1.00e+00 4.08e-01f 1\n", - " 14r 0.0000000e+00 1.95e+00 5.95e+02 1.7 3.44e+00 - 9.75e-01 8.56e-01f 1\n", - " 15r 0.0000000e+00 2.34e+00 1.49e+02 0.3 9.78e+00 - 8.14e-01 7.50e-01f 1\n", - " 16r 0.0000000e+00 2.29e+00 1.06e+03 0.3 2.00e+00 - 3.58e-01 6.35e-01f 1\n", - " 17r 0.0000000e+00 2.20e+00 4.59e+02 0.3 2.88e+00 - 8.54e-01 6.97e-01f 1\n", - " 18r 0.0000000e+00 2.04e+00 3.75e+02 0.3 3.28e+00 - 8.25e-01 1.00e+00f 1\n", - " 19r 0.0000000e+00 2.03e+00 4.69e-03 0.3 2.66e-01 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.19e+00 1.23e+02 -1.8 4.02e+00 - 9.06e-01 7.70e-01f 1\n", - " 21r 0.0000000e+00 9.38e-01 2.90e+03 -1.8 9.16e+01 - 4.10e-02 2.74e-01f 1\n", - " 22r 0.0000000e+00 2.46e-02 1.94e+03 -1.8 1.08e+02 - 2.21e-01 1.72e-01f 1\n", - " 23r 0.0000000e+00 2.47e-02 2.02e+03 -1.8 1.09e+02 - 2.16e-01 1.72e-03f 1\n", - " 24r 0.0000000e+00 2.45e-02 3.75e+03 -1.8 2.59e+01 - 7.11e-01 4.29e-03f 1\n", - " 25r 0.0000000e+00 1.61e-02 3.51e+03 -1.8 1.76e+01 - 1.00e+00 1.16e-01f 1\n", - " 26r 0.0000000e+00 1.08e-02 3.50e+03 -1.8 1.47e+01 - 1.00e+00 8.73e-02f 1\n", - " 27r 0.0000000e+00 2.06e-03 2.80e+03 -1.8 1.05e+01 - 1.00e+00 2.47e-01f 1\n", - " 28r 0.0000000e+00 1.24e-03 1.74e+03 -1.8 8.12e-01 - 1.00e+00 3.99e-01f 1\n", - " 29r 0.0000000e+00 5.90e-05 5.81e+01 -1.8 2.34e-01 - 1.00e+00 9.68e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 3.22e-05 1.22e-04 -1.8 7.57e-03 - 1.00e+00 1.00e+00f 1\n", - " 31r 0.0000000e+00 8.59e-06 4.05e+02 -4.1 9.74e-03 - 1.00e+00 7.37e-01f 1\n", - " 32r 0.0000000e+00 2.82e-06 1.88e+03 -4.1 7.91e-03 - 9.72e-01 3.73e-01f 1\n", - " 33r 0.0000000e+00 6.13e-07 5.39e+02 -4.1 3.14e-04 - 1.00e+00 8.82e-01f 1\n", - " 34r 0.0000000e+00 7.85e-09 2.16e-06 -4.1 5.11e-05 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 6.6954687905074195e-09 7.8509231044920165e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 6.6954687905074195e-09 7.8509231044920165e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 36\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.295\n", - "Total CPU secs in NLP function evaluations = 0.035\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.76e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.67e+02 3.55e+01 -1.0 3.76e+02 - 7.84e-03 2.89e-01f 1\n", - " 2 0.0000000e+00 2.58e+02 3.43e+01 -1.0 2.67e+02 - 1.36e-01 3.43e-02h 1\n", - " 3 0.0000000e+00 2.58e+02 1.25e+04 -1.0 2.58e+02 - 2.56e-01 4.71e-04h 1\n", - " 4r 0.0000000e+00 2.58e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 2.96e-07R 5\n", - " 5r 0.0000000e+00 2.45e+02 7.55e+03 2.4 1.31e+04 - 1.36e-03 1.03e-02f 1\n", - " 6r 0.0000000e+00 2.41e+02 8.88e+03 1.7 1.32e+03 - 7.60e-02 2.33e-03f 1\n", - " 7r 0.0000000e+00 1.91e+02 1.08e+04 1.7 2.50e+03 - 8.74e-02 2.02e-02f 1\n", - " 8r 0.0000000e+00 1.66e+02 1.34e+04 1.7 1.82e+03 - 3.14e-01 1.41e-02f 1\n", - " 9r 0.0000000e+00 6.77e+01 1.15e+04 1.7 9.90e+02 - 1.96e-01 9.89e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 4.22e+01 8.73e+03 1.7 4.00e+02 - 6.92e-01 7.58e-02f 1\n", - " 11r 0.0000000e+00 1.28e+01 7.30e+03 1.7 9.32e+01 - 1.00e+00 3.35e-01f 1\n", - " 12r 0.0000000e+00 3.55e+00 4.88e+03 1.7 2.64e+01 - 1.00e+00 3.50e-01f 1\n", - " 13r 0.0000000e+00 1.69e+00 2.88e+03 1.7 7.90e+00 - 1.00e+00 4.53e-01f 1\n", - " 14r 0.0000000e+00 6.03e-01 8.23e+02 1.0 2.33e+00 - 4.43e-01 8.26e-01f 1\n", - " 15r 0.0000000e+00 5.44e-01 6.26e+00 1.0 1.57e+00 - 1.00e+00 9.98e-01f 1\n", - " 16r 0.0000000e+00 7.15e-01 2.12e+02 -1.1 3.16e+00 - 5.99e-01 4.65e-01f 1\n", - " 17r 0.0000000e+00 7.08e-01 4.60e+02 -1.1 7.26e+00 - 7.72e-02 3.24e-01f 1\n", - " 18r 0.0000000e+00 5.24e-01 1.33e+03 -1.1 7.74e+00 - 1.41e-02 2.59e-01f 1\n", - " 19r 0.0000000e+00 2.34e-01 1.24e+03 -1.1 7.27e+00 - 2.80e-01 3.71e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 9.07e-03 1.06e+03 -1.1 9.86e+00 - 5.50e-01 2.08e-01f 1\n", - " 21r 0.0000000e+00 7.28e-03 1.75e+03 -1.1 1.31e+01 - 3.75e-01 2.95e-03f 1\n", - " 22r 0.0000000e+00 6.06e-03 2.39e+03 -1.1 4.91e+00 - 1.00e+00 1.03e-01f 1\n", - " 23r 0.0000000e+00 2.62e-03 1.50e+03 -1.1 4.00e+00 - 1.00e+00 4.71e-01f 1\n", - " 24r 0.0000000e+00 1.40e-03 3.97e+02 -1.1 1.08e+00 - 1.00e+00 7.99e-01f 1\n", - " 25r 0.0000000e+00 5.02e-04 1.55e-03 -1.1 1.68e-01 - 1.00e+00 1.00e+00f 1\n", - " 26r 0.0000000e+00 2.02e-04 1.03e+03 -4.0 1.53e-01 - 1.00e+00 6.42e-01f 1\n", - " 27r 0.0000000e+00 4.23e-05 3.32e+03 -4.0 3.68e-01 - 9.45e-01 1.64e-01f 1\n", - " 28r 0.0000000e+00 6.59e-06 8.73e+02 -4.0 6.96e-03 - 9.73e-01 7.76e-01f 1\n", - " 29r 0.0000000e+00 2.70e-06 1.28e+03 -4.0 1.13e-03 - 9.39e-01 6.61e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 6.39e-07 2.14e+02 -4.0 3.79e-04 - 8.88e-01 9.54e-01f 1\n", - " 31r 0.0000000e+00 5.66e-09 3.83e-07 -4.0 1.73e-05 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 31\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.6641896728493180e-09 5.6641896728493180e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.6641896728493180e-09 5.6641896728493180e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 37\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 37\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 33\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 31\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.299\n", - "Total CPU secs in NLP function evaluations = 0.020\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.4\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.12e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.42e+02 7.75e+01 -1.0 3.12e+02 - 6.86e-03 5.47e-01f 1\n", - " 2 0.0000000e+00 1.36e+02 7.44e+01 -1.0 1.42e+02 - 1.36e-01 4.13e-02h 1\n", - " 3 0.0000000e+00 1.36e+02 1.08e+04 -1.0 1.36e+02 - 2.46e-01 5.18e-04h 1\n", - " 4r 0.0000000e+00 1.36e+02 1.00e+03 2.1 0.00e+00 - 0.00e+00 3.25e-07R 5\n", - " 5r 0.0000000e+00 9.30e+01 4.20e+03 2.1 1.83e+04 - 1.01e-02 4.22e-03f 1\n", - " 6r 0.0000000e+00 8.60e+01 6.51e+03 1.4 1.12e+04 - 1.11e-02 5.18e-03f 1\n", - " 7r 0.0000000e+00 6.37e+01 2.08e+04 1.4 2.99e+03 - 3.09e-02 8.06e-03f 1\n", - " 8r 0.0000000e+00 6.32e+01 2.86e+04 1.4 2.43e+03 - 7.46e-02 2.34e-04f 1\n", - " 9r 0.0000000e+00 8.20e+00 2.07e+04 1.4 1.52e+03 - 3.82e-01 4.12e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 4.76e+00 1.27e+04 1.4 2.31e+01 - 3.36e-01 1.49e-01f 1\n", - " 11r 0.0000000e+00 9.35e-01 4.92e+03 1.4 1.05e+01 - 1.00e+00 4.51e-01f 1\n", - " 12r 0.0000000e+00 4.23e-01 6.26e+03 1.4 3.59e+00 - 6.30e-01 8.74e-01f 1\n", - " 13r 0.0000000e+00 4.02e-01 2.59e+00 1.4 5.34e-01 - 1.00e+00 1.00e+00f 1\n", - " 14r 0.0000000e+00 9.60e-01 2.09e+02 -0.7 5.84e+00 - 3.71e-01 7.86e-01f 1\n", - " 15r 0.0000000e+00 6.90e-01 1.17e+02 -0.7 5.80e+00 - 5.49e-01 5.65e-01f 1\n", - " 16r 0.0000000e+00 1.01e-01 1.58e+02 -0.7 1.02e+01 - 5.69e-01 5.29e-01f 1\n", - " 17r 0.0000000e+00 1.53e-02 1.59e+03 -0.7 1.68e+01 - 4.32e-01 5.29e-02f 1\n", - " 18r 0.0000000e+00 1.52e-02 2.33e+03 -0.7 2.54e+00 - 1.00e+00 2.41e-02f 1\n", - " 19r 0.0000000e+00 1.15e-02 1.53e+02 -0.7 2.10e+00 - 1.00e+00 9.43e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 1.14e-02 1.06e-03 -0.7 1.03e-01 - 1.00e+00 1.00e+00f 1\n", - " 21r 0.0000000e+00 1.13e-02 2.33e+02 -3.1 3.47e-01 - 1.00e+00 8.62e-01f 1\n", - " 22r 0.0000000e+00 3.48e-04 7.69e+02 -3.1 1.30e+02 - 9.77e-01 2.08e-02f 1\n", - " 23r 0.0000000e+00 3.41e-04 8.97e+02 -3.1 1.87e+00 - 1.00e+00 2.00e-02f 1\n", - " 24r 0.0000000e+00 2.53e-06 6.41e+00 -3.1 1.20e-01 - 1.00e+00 9.93e-01f 1\n", - " 25r 0.0000000e+00 1.31e-07 8.18e-09 -3.1 8.77e-04 - 1.00e+00 1.00e+00f 1\n", - " 26r 0.0000000e+00 9.78e-10 3.71e-01 -7.0 5.48e-05 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 26\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.1057295037444419e-10 9.7818515353703672e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.1057295037444419e-10 9.7818515353703672e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 32\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 32\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 28\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.258\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.5\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.85e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.56e+02 9.16e+01 -1.0 3.85e+02 - 3.57e-03 3.35e-01f 1\n", - " 2 0.0000000e+00 2.51e+02 8.99e+01 -1.0 2.56e+02 - 7.05e-02 1.89e-02h 1\n", - " 3 0.0000000e+00 2.51e+02 6.86e+03 -1.0 2.51e+02 - 1.12e-01 2.27e-04h 1\n", - " 4r 0.0000000e+00 2.51e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 2.84e-07R 4\n", - " 5r 0.0000000e+00 2.35e+02 2.10e+03 2.4 1.31e+04 - 8.56e-03 1.49e-02f 1\n", - " 6r 0.0000000e+00 2.33e+02 3.45e+03 1.0 1.24e+03 - 5.51e-02 2.07e-03f 1\n", - " 7r 0.0000000e+00 1.83e+02 5.32e+03 1.0 5.02e+03 - 2.27e-02 1.09e-02f 1\n", - " 8r 0.0000000e+00 1.70e+02 7.52e+03 1.0 3.56e+03 - 5.25e-02 4.04e-03f 1\n", - " 9r 0.0000000e+00 1.27e+02 1.02e+04 1.0 2.46e+03 - 1.06e-01 1.87e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 6.56e+01 2.01e+04 1.0 1.12e+03 - 3.63e-01 5.60e-02f 1\n", - " 11r 0.0000000e+00 3.55e+01 2.18e+04 1.0 2.21e+02 - 3.03e-01 1.42e-01f 1\n", - " 12r 0.0000000e+00 1.70e+01 2.29e+04 1.0 8.53e+01 - 5.79e-01 2.17e-01f 1\n", - " 13r 0.0000000e+00 1.39e+01 2.07e+04 1.0 3.36e+01 - 4.90e-02 9.28e-02f 1\n", - " 14r 0.0000000e+00 1.09e+01 1.86e+04 1.0 2.91e+01 - 2.30e-01 1.02e-01f 1\n", - " 15r 0.0000000e+00 3.48e+00 1.19e+04 1.0 2.33e+01 - 7.44e-01 3.19e-01f 1\n", - " 16r 0.0000000e+00 2.42e+00 8.14e+03 1.0 8.84e+00 - 2.88e-01 3.68e-01f 1\n", - " 17r 0.0000000e+00 2.45e+00 6.21e+03 1.0 1.85e+00 - 2.52e-01 2.81e-01f 1\n", - " 18r 0.0000000e+00 2.48e+00 4.36e+03 1.0 1.26e+00 - 2.84e-01 2.74e-01f 1\n", - " 19r 0.0000000e+00 2.51e+00 3.06e+03 1.0 6.66e-01 - 2.68e-01 2.60e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.53e+00 3.28e+03 1.0 7.04e-01 - 3.07e-01 3.65e-01f 1\n", - " 21r 0.0000000e+00 2.55e+00 2.35e+03 1.0 6.09e-01 - 3.82e-01 3.99e-01f 1\n", - " 22r 0.0000000e+00 2.57e+00 3.23e+03 1.0 4.76e-01 - 6.82e-01 1.00e+00f 1\n", - " 23r 0.0000000e+00 2.57e+00 1.41e-01 1.0 1.60e-01 - 1.00e+00 1.00e+00f 1\n", - " 24r 0.0000000e+00 2.87e+00 1.18e+02 -1.1 5.95e+00 - 8.69e-01 7.73e-01f 1\n", - " 25r 0.0000000e+00 2.84e+00 1.05e+03 -1.1 6.87e+00 - 4.86e-02 4.92e-01f 1\n", - " 26r 0.0000000e+00 2.47e+00 2.21e+03 -1.1 1.78e+01 - 3.48e-02 3.34e-01f 1\n", - " 27r 0.0000000e+00 2.00e+00 7.63e+02 -1.1 1.99e+01 - 5.19e-01 3.89e-01f 1\n", - " 28r 0.0000000e+00 7.56e-01 1.03e+03 -1.1 4.01e+01 - 3.41e-01 5.09e-01f 1\n", - " 29r 0.0000000e+00 1.13e-02 2.08e+03 -1.1 2.16e+01 - 1.78e-01 5.64e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 5.30e-03 1.16e+03 -1.1 9.51e+00 - 3.26e-01 1.34e-02f 1\n", - " 31r 0.0000000e+00 5.52e-03 1.97e+03 -1.1 1.86e+00 - 1.00e+00 3.77e-02f 1\n", - " 32r 0.0000000e+00 1.14e-02 1.04e+02 -1.1 1.87e+00 - 7.66e-01 1.00e+00f 1\n", - " 33r 0.0000000e+00 1.15e-02 1.58e-05 -1.1 1.75e-01 - 1.00e+00 1.00e+00f 1\n", - " 34r 0.0000000e+00 1.15e-02 3.84e+02 -4.0 3.45e-01 - 9.63e-01 7.35e-01f 1\n", - " 35r 0.0000000e+00 1.39e-03 3.05e+03 -4.0 4.05e+02 - 9.71e-01 6.73e-03f 1\n", - " 36r 0.0000000e+00 1.39e-03 3.64e+03 -4.0 2.50e+02 - 1.00e+00 2.55e-04f 1\n", - " 37r 0.0000000e+00 7.73e-04 2.45e+03 -4.0 4.49e-01 - 1.00e+00 3.79e-01f 1\n", - " 38r 0.0000000e+00 1.11e-04 3.84e+02 -4.0 1.97e-01 - 1.00e+00 8.57e-01f 1\n", - " 39r 0.0000000e+00 3.89e-05 1.28e+03 -4.0 2.82e-02 - 1.00e+00 6.49e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40r 0.0000000e+00 5.46e-06 8.75e+02 -4.0 9.91e-03 - 1.00e+00 8.60e-01f 1\n", - " 41r 0.0000000e+00 7.94e-09 8.92e-07 -4.0 1.39e-03 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 41\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.5392754261827122e-09 7.9367750923575655e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.5392754261827122e-09 7.9367750923575655e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 46\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 46\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 43\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 41\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.370\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.4\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.63e+02 4.22e+01 -1.0 3.92e+02 - 7.52e-03 3.28e-01f 1\n", - " 2 0.0000000e+00 2.56e+02 4.09e+01 -1.0 2.63e+02 - 1.51e-01 2.93e-02h 1\n", - " 3 0.0000000e+00 2.56e+02 1.88e+04 -1.0 2.56e+02 - 2.78e-01 3.64e-04h 1\n", - " 4r 0.0000000e+00 2.56e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.56e-07R 4\n", - " 5r 0.0000000e+00 2.11e+02 9.30e+03 2.4 1.35e+03 - 5.28e-03 3.32e-02f 1\n", - " 6r 0.0000000e+00 1.91e+02 8.43e+03 1.7 1.19e+03 - 4.36e-02 1.76e-02f 1\n", - " 7r 0.0000000e+00 1.47e+02 6.95e+03 1.7 2.30e+03 - 4.86e-02 2.14e-02f 1\n", - " 8r 0.0000000e+00 1.17e+02 9.39e+03 1.7 1.63e+03 - 2.42e-01 1.83e-02f 1\n", - " 9r 0.0000000e+00 6.91e+01 1.17e+04 1.7 9.11e+02 - 3.84e-01 5.68e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 3.46e+01 1.09e+04 1.7 2.42e+02 - 1.00e+00 1.53e-01f 1\n", - " 11r 0.0000000e+00 2.02e+01 7.14e+03 1.7 4.19e+01 - 6.28e-01 3.44e-01f 1\n", - " 12r 0.0000000e+00 3.51e-01 1.44e+03 1.7 2.48e+01 - 1.00e+00 8.12e-01f 1\n", - " 13r 0.0000000e+00 4.10e-01 1.23e+03 1.0 4.59e+00 - 6.08e-01 1.61e-01f 1\n", - " 14r 0.0000000e+00 4.75e-01 1.49e+02 1.0 2.07e+00 - 1.00e+00 8.77e-01f 1\n", - " 15r 0.0000000e+00 5.52e-01 6.94e+02 0.3 3.21e+00 - 8.25e-01 3.97e-01f 1\n", - " 16r 0.0000000e+00 5.50e-01 3.86e+02 0.3 2.58e+00 - 1.00e+00 7.86e-01f 1\n", - " 17r 0.0000000e+00 5.27e-01 1.24e-01 0.3 7.99e-01 - 1.00e+00 1.00e+00f 1\n", - " 18r 0.0000000e+00 5.52e-01 7.33e+02 -1.8 1.28e+00 - 8.78e-01 3.61e-01f 1\n", - " 19r 0.0000000e+00 5.52e-01 7.69e+02 -1.8 1.91e+01 - 3.11e-01 1.63e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 5.43e-01 5.05e+02 -1.8 3.60e+00 - 4.54e-03 1.68e-01f 1\n", - " 21r 0.0000000e+00 2.60e-01 6.69e+02 -1.8 6.84e+01 - 4.13e-03 1.48e-01f 1\n", - " 22r 0.0000000e+00 2.55e-01 3.52e+02 -1.8 6.82e+01 - 7.60e-02 1.55e-03f 1\n", - " 23r 0.0000000e+00 2.37e-01 5.27e+02 -1.8 7.29e+01 - 8.64e-02 4.59e-03f 1\n", - " 24r 0.0000000e+00 2.03e-01 1.07e+03 -1.8 7.70e+01 - 1.27e-01 8.57e-03f 1\n", - " 25r 0.0000000e+00 1.31e-01 2.01e+03 -1.8 8.06e+01 - 2.26e-01 1.70e-02f 1\n", - " 26r 0.0000000e+00 2.55e-02 2.65e+03 -1.8 7.48e+01 - 3.10e-01 2.71e-02f 1\n", - " 27r 0.0000000e+00 3.51e-03 3.18e+03 -1.8 9.82e+00 - 9.46e-01 4.99e-02f 1\n", - " 28r 0.0000000e+00 2.39e-04 4.89e+02 -1.8 3.27e-01 - 1.00e+00 8.56e-01f 1\n", - " 29r 0.0000000e+00 5.43e-05 8.27e+02 -1.8 4.57e-02 - 1.00e+00 7.04e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 1.52e-05 6.90e-04 -1.8 1.36e-02 - 1.00e+00 1.00e+00f 1\n", - " 31r 0.0000000e+00 8.56e-06 1.25e+03 -4.0 3.76e-03 - 1.00e+00 7.07e-01f 1\n", - " 32r 0.0000000e+00 2.49e-06 9.69e+02 -4.0 2.26e-03 - 8.51e-01 7.40e-01f 1\n", - " 33r 0.0000000e+00 5.33e-08 6.71e-06 -4.0 5.23e-04 - 1.00e+00 1.00e+00f 1\n", - " 34r 0.0000000e+00 5.37e-10 1.01e-01 -6.0 2.49e-05 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.4637958782706658e-10 5.3720153514778086e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.4637958782706658e-10 5.3720153514778086e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 36\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.319\n", - "Total CPU secs in NLP function evaluations = 0.007\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.51e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.10e+02 4.62e+01 -1.0 3.51e+02 - 8.40e-03 4.00e-01f 1\n", - " 2 0.0000000e+00 2.04e+02 4.48e+01 -1.0 2.10e+02 - 2.17e-01 2.95e-02h 1\n", - " 3 0.0000000e+00 2.04e+02 3.94e+04 -1.0 2.04e+02 - 4.22e-01 3.55e-04h 1\n", - " 4r 0.0000000e+00 2.04e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 4.44e-07R 4\n", - " 5r 0.0000000e+00 1.81e+02 3.64e+03 2.3 1.78e+04 - 3.08e-03 1.14e-02f 1\n", - " 6r 0.0000000e+00 1.79e+02 5.13e+03 1.6 1.42e+03 - 8.45e-02 1.49e-03f 1\n", - " 7r 0.0000000e+00 1.19e+02 1.08e+04 1.6 2.58e+03 - 7.51e-02 2.40e-02f 1\n", - " 8r 0.0000000e+00 6.76e+01 6.25e+03 1.6 1.81e+03 - 1.70e-01 2.92e-02f 1\n", - " 9r 0.0000000e+00 1.88e+01 6.76e+03 1.6 8.62e+02 - 3.07e-01 5.65e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 5.08e+00 6.06e+03 1.6 1.67e+02 - 2.49e-01 1.12e-01f 1\n", - " 11r 0.0000000e+00 3.81e+00 4.70e+03 1.6 1.06e+01 - 3.13e-01 2.13e-01f 1\n", - " 12r 0.0000000e+00 2.12e+00 1.83e+03 1.6 6.54e+00 - 7.68e-01 4.05e-01f 1\n", - " 13r 0.0000000e+00 1.94e+00 1.61e+03 0.9 2.15e+00 - 6.59e-01 8.52e-02f 1\n", - " 14r 0.0000000e+00 2.67e-01 2.64e+02 0.9 2.93e+00 - 1.00e+00 8.54e-01f 1\n", - " 15r 0.0000000e+00 1.91e-01 8.59e+02 0.2 8.87e-01 - 8.22e-01 2.83e-01f 1\n", - " 16r 0.0000000e+00 6.01e-02 8.76e+02 0.2 2.97e+00 - 1.00e+00 6.84e-01f 1\n", - " 17r 0.0000000e+00 2.69e-02 2.67e+00 0.2 1.04e+00 - 1.00e+00 1.00e+00f 1\n", - " 18r 0.0000000e+00 3.87e-02 1.69e+02 -1.9 6.90e-01 - 4.97e-01 4.22e-01f 1\n", - " 19r 0.0000000e+00 3.87e-02 3.21e+02 -1.9 1.56e+01 - 2.54e-01 1.72e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.81e-02 3.53e+02 -1.9 3.29e+00 - 3.47e-03 2.20e-01f 1\n", - " 21r 0.0000000e+00 1.46e-02 3.77e+02 -1.9 4.69e+01 - 5.08e-03 8.11e-03f 1\n", - " 22r 0.0000000e+00 1.26e-02 3.42e+02 -1.9 3.88e+01 - 1.21e-02 1.00e-03f 1\n", - " 23r 0.0000000e+00 3.16e-03 2.94e+02 -1.9 2.90e+01 - 2.40e-02 6.20e-03f 1\n", - " 24r 0.0000000e+00 1.80e-03 2.20e+03 -1.9 4.26e+00 - 8.01e-01 1.54e-02f 1\n", - " 25r 0.0000000e+00 2.09e-04 6.36e+02 -1.9 5.92e-01 - 1.00e+00 7.90e-01f 1\n", - " 26r 0.0000000e+00 4.97e-05 7.73e+02 -1.9 4.07e-02 - 1.00e+00 7.06e-01f 1\n", - " 27r 0.0000000e+00 1.73e-05 2.67e+01 -1.9 1.17e-02 - 1.00e+00 9.81e-01f 1\n", - " 28r 0.0000000e+00 4.43e-06 1.78e-04 -1.9 2.17e-04 - 1.00e+00 1.00e+00f 1\n", - " 29r 0.0000000e+00 2.35e-06 5.22e+01 -4.2 1.68e-03 - 1.00e+00 9.10e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 2.92e-07 1.85e+01 -4.2 3.04e-04 - 1.00e+00 8.79e-01f 1\n", - " 31r 0.0000000e+00 1.26e-09 7.00e-08 -4.2 1.09e-04 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 31\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.2612473843098826e-09 1.2612473843098826e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.2612473843098826e-09 1.2612473843098826e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 36\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 36\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 33\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 31\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.271\n", - "Total CPU secs in NLP function evaluations = 0.023\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.83e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 6.16e+01 3.98e+01 -1.0 1.83e+02 - 1.60e-02 6.64e-01f 1\n", - " 2 0.0000000e+00 5.16e+01 3.35e+01 -1.0 6.16e+01 - 3.45e-01 1.63e-01h 1\n", - " 3 0.0000000e+00 5.14e+01 1.26e+04 -1.0 5.16e+01 - 7.21e-01 4.84e-03h 1\n", - " 4 0.0000000e+00 5.14e+01 2.29e+08 -1.0 5.14e+01 - 9.11e-01 5.02e-05h 1\n", - " 5r 0.0000000e+00 5.14e+01 1.00e+03 1.7 0.00e+00 - 0.00e+00 2.52e-07R 2\n", - " 6r 0.0000000e+00 4.50e+01 1.23e+04 1.7 1.84e+04 - 2.52e-02 2.32e-03f 1\n", - " 7r 0.0000000e+00 3.54e+01 4.07e+04 1.7 2.49e+03 - 6.96e-02 3.85e-03f 1\n", - " 8r 0.0000000e+00 5.85e+00 4.93e+04 1.7 1.43e+03 - 8.64e-02 2.45e-02f 1\n", - " 9r 0.0000000e+00 3.35e+00 1.48e+04 1.7 5.73e+01 - 7.58e-01 5.86e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 2.86e+00 1.09e+04 1.7 4.88e+00 - 1.57e-01 1.13e-01f 1\n", - " 11r 0.0000000e+00 2.68e-01 2.71e+04 1.7 4.02e+00 - 1.46e-01 8.12e-01f 1\n", - " 12r 0.0000000e+00 1.04e+00 2.76e+03 1.7 4.27e+00 - 8.58e-01 1.00e+00f 1\n", - " 13r 0.0000000e+00 2.25e-01 1.74e+02 1.0 4.50e+00 - 8.78e-01 9.22e-01f 1\n", - " 14r 0.0000000e+00 3.86e-02 9.86e+02 0.3 2.51e+00 - 1.00e+00 4.78e-01f 1\n", - " 15r 0.0000000e+00 2.63e-02 1.70e+03 0.3 1.78e+00 - 1.00e+00 4.16e-01f 1\n", - " 16r 0.0000000e+00 8.78e-03 1.77e+02 0.3 1.30e+00 - 1.00e+00 9.07e-01f 1\n", - " 17r 0.0000000e+00 8.83e-03 5.64e-04 0.3 3.49e-01 - 1.00e+00 1.00e+00f 1\n", - " 18r 0.0000000e+00 2.39e-03 2.14e+02 -1.8 1.08e+00 - 9.93e-01 7.08e-01f 1\n", - " 19r 0.0000000e+00 6.59e-04 3.82e+02 -1.8 2.55e+00 - 1.00e+00 3.14e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 1.07e-04 7.78e+01 -1.8 1.63e-01 - 1.00e+00 8.17e-01f 1\n", - " 21r 0.0000000e+00 2.42e-05 4.73e+01 -1.8 2.45e-02 - 1.00e+00 8.44e-01f 1\n", - " 22r 0.0000000e+00 2.70e-06 4.22e-07 -1.8 4.46e-03 - 1.00e+00 1.00e+00f 1\n", - " 23r 0.0000000e+00 1.78e-06 3.08e+00 -4.0 1.12e-03 - 1.00e+00 9.46e-01f 1\n", - " 24r 0.0000000e+00 1.34e-07 4.68e-07 -4.0 4.21e-04 - 1.00e+00 1.00e+00f 1\n", - " 25r 0.0000000e+00 9.50e-11 2.65e-02 -6.0 5.53e-05 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 25\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.5036423175542950e-11 9.5036423175542950e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.5036423175542950e-11 9.5036423175542950e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 28\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 28\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 27\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 25\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.235\n", - "Total CPU secs in NLP function evaluations = 0.015\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.5\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.85e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.08e+02 1.71e+02 -1.0 3.85e+02 - 2.65e-03 4.60e-01f 1\n", - " 2 0.0000000e+00 2.04e+02 1.68e+02 -1.0 2.08e+02 - 7.77e-02 1.78e-02h 1\n", - " 3 0.0000000e+00 2.04e+02 8.66e+03 -1.0 2.04e+02 - 1.18e-01 2.03e-04h 1\n", - " 4r 0.0000000e+00 2.04e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 2.54e-07R 4\n", - " 5r 0.0000000e+00 1.94e+02 9.86e+02 2.3 1.29e+04 - 1.19e-02 1.28e-02f 1\n", - " 6r 0.0000000e+00 1.91e+02 1.69e+04 0.9 1.49e+03 - 5.89e-02 2.58e-03f 1\n", - " 7r 0.0000000e+00 1.47e+02 3.49e+04 0.9 4.77e+03 - 2.90e-02 9.30e-03f 1\n", - " 8r 0.0000000e+00 1.09e+02 3.82e+04 0.9 3.42e+03 - 5.74e-02 1.25e-02f 1\n", - " 9r 0.0000000e+00 1.03e+02 3.57e+04 0.9 1.67e+03 - 2.11e-01 3.92e-03f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 3.97e+01 3.04e+04 0.9 5.25e+02 - 1.76e-01 1.26e-01f 1\n", - " 11r 0.0000000e+00 2.44e+01 3.83e+04 0.9 1.50e+02 - 5.49e-01 1.02e-01f 1\n", - " 12r 0.0000000e+00 7.22e+00 3.16e+04 0.9 5.01e+01 - 7.21e-01 3.44e-01f 1\n", - " 13r 0.0000000e+00 2.66e+00 1.79e+04 0.9 1.69e+01 - 6.25e-01 4.25e-01f 1\n", - " 14r 0.0000000e+00 2.70e+00 1.27e+04 0.9 1.52e+00 - 3.28e-01 2.87e-01f 1\n", - " 15r 0.0000000e+00 2.72e+00 8.79e+03 0.9 1.07e+00 - 3.59e-01 2.85e-01f 1\n", - " 16r 0.0000000e+00 2.79e+00 6.00e+03 0.9 1.91e+00 - 3.34e-01 2.96e-01f 1\n", - " 17r 0.0000000e+00 2.81e+00 4.53e+03 0.9 1.14e+00 - 2.48e-01 2.63e-01f 1\n", - " 18r 0.0000000e+00 2.86e+00 2.90e+03 0.9 1.45e+00 - 3.42e-01 3.27e-01f 1\n", - " 19r 0.0000000e+00 2.88e+00 1.22e+03 0.9 7.48e-01 - 3.63e-01 3.24e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.92e+00 3.75e+03 0.9 6.52e-01 - 5.04e-01 5.89e-01f 1\n", - " 21r 0.0000000e+00 2.93e+00 4.25e+04 0.9 2.49e-01 - 4.20e-01 9.81e-01f 1\n", - " 22r 0.0000000e+00 2.93e+00 1.50e+03 0.9 5.14e-02 - 8.63e-01 1.00e+00f 1\n", - " 23r 0.0000000e+00 2.93e+00 7.38e-03 0.9 6.94e-03 - 1.00e+00 1.00e+00f 1\n", - " 24r 0.0000000e+00 3.29e+00 1.59e+02 -1.2 4.49e+00 - 8.54e-01 7.15e-01f 1\n", - " 25r 0.0000000e+00 2.68e+00 3.13e+02 -1.2 3.24e+01 - 1.92e-01 2.63e-01f 1\n", - " 26r 0.0000000e+00 1.50e+00 3.12e+02 -1.2 3.25e+01 - 3.28e-01 3.55e-01f 1\n", - " 27r 0.0000000e+00 1.07e-01 3.03e+02 -1.2 3.79e+01 - 3.23e-01 3.74e-01f 1\n", - " 28r 0.0000000e+00 1.07e-01 9.17e+02 -1.2 3.15e+01 - 2.55e-01 5.49e-03f 1\n", - " 29r 0.0000000e+00 1.07e-01 2.86e+03 -1.2 1.92e+01 - 7.85e-01 1.14e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 1.01e-01 2.05e+03 -1.2 5.56e+00 - 1.00e+00 3.41e-01f 1\n", - " 31r 0.0000000e+00 9.73e-02 1.58e+03 -1.2 3.30e+00 - 1.00e+00 3.01e-01f 1\n", - " 32r 0.0000000e+00 8.92e-02 4.60e+01 -1.2 2.31e+00 - 1.00e+00 9.73e-01f 1\n", - " 33r 0.0000000e+00 8.90e-02 8.87e-04 -1.2 1.20e-01 - 1.00e+00 1.00e+00f 1\n", - " 34r 0.0000000e+00 8.91e-02 3.61e+02 -4.2 1.72e-01 - 9.81e-01 7.79e-01f 1\n", - " 35r 0.0000000e+00 7.41e-02 1.37e+03 -4.2 6.60e+02 - 1.61e-01 5.45e-03f 1\n", - " 36r 0.0000000e+00 7.35e-02 6.49e+03 -4.2 6.55e+02 - 9.03e-01 2.46e-04f 1\n", - " 37r 0.0000000e+00 3.03e-04 6.68e+03 -4.2 5.94e+02 - 8.93e-01 2.98e-02f 1\n", - " 38r 0.0000000e+00 2.75e-04 6.08e+03 -4.2 2.39e-01 - 1.00e+00 8.74e-02f 1\n", - " 39r 0.0000000e+00 1.08e-08 2.67e-04 -4.2 8.74e-02 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40r 0.0000000e+00 8.78e-11 2.37e-01 -6.4 2.18e-06 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 40\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.3066333062577876e-11 8.7764854222018352e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.3066333062577876e-11 8.7764854222018352e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 45\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 45\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 42\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 40\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.307\n", - "Total CPU secs in NLP function evaluations = 0.049\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.36e+02 1.43e+02 -1.0 3.96e+02 - 2.78e-03 4.05e-01f 1\n", - " 2 0.0000000e+00 2.32e+02 1.41e+02 -1.0 2.36e+02 - 1.32e-01 1.71e-02h 1\n", - " 3 0.0000000e+00 2.32e+02 2.28e+04 -1.0 2.32e+02 - 1.88e-01 1.93e-04h 1\n", - " 4r 0.0000000e+00 2.32e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.83e-07R 3\n", - " 5r 0.0000000e+00 2.17e+02 9.85e+02 2.4 1.19e+04 - 1.06e-02 1.36e-02f 1\n", - " 6r 0.0000000e+00 2.14e+02 1.30e+04 1.0 1.27e+03 - 5.82e-02 2.44e-03f 1\n", - " 7r 0.0000000e+00 1.62e+02 2.34e+04 1.0 4.91e+03 - 2.38e-02 1.16e-02f 1\n", - " 8r 0.0000000e+00 1.57e+02 2.45e+04 1.0 3.32e+03 - 6.10e-02 1.67e-03f 1\n", - " 9r 0.0000000e+00 1.32e+02 2.26e+04 1.0 2.02e+03 - 1.26e-01 1.32e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 6.58e+01 2.03e+04 1.0 9.37e+02 - 1.95e-01 7.75e-02f 1\n", - " 11r 0.0000000e+00 4.25e+01 3.75e+04 1.0 2.34e+02 - 5.24e-01 9.91e-02f 1\n", - " 12r 0.0000000e+00 9.87e+00 1.92e+04 1.0 6.76e+01 - 4.88e-01 4.85e-01f 1\n", - " 13r 0.0000000e+00 8.03e+00 1.63e+04 1.0 1.29e+01 - 1.21e-01 1.43e-01f 1\n", - " 14r 0.0000000e+00 6.78e+00 1.54e+04 1.0 1.03e+01 - 4.81e-01 1.22e-01f 1\n", - " 15r 0.0000000e+00 2.80e+00 7.26e+03 1.0 8.05e+00 - 6.67e-01 4.96e-01f 1\n", - " 16r 0.0000000e+00 2.51e+00 5.18e+03 1.0 3.44e+00 - 2.86e-01 2.98e-01f 1\n", - " 17r 0.0000000e+00 2.53e+00 3.39e+03 1.0 2.35e+00 - 2.85e-01 1.95e-01f 1\n", - " 18r 0.0000000e+00 2.56e+00 2.71e+03 1.0 1.86e+00 - 2.75e-01 3.16e-01f 1\n", - " 19r 0.0000000e+00 2.58e+00 2.08e+03 1.0 1.22e+00 - 2.65e-01 2.72e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.61e+00 2.39e+03 1.0 8.14e-01 - 3.60e-01 4.17e-01f 1\n", - " 21r 0.0000000e+00 2.62e+00 1.38e+03 1.0 3.95e-01 - 4.37e-01 3.67e-01f 1\n", - " 22r 0.0000000e+00 2.63e+00 9.07e+03 1.0 2.59e-01 - 7.30e-01 1.00e+00f 1\n", - " 23r 0.0000000e+00 2.63e+00 2.12e-01 1.0 7.58e-02 - 1.00e+00 1.00e+00f 1\n", - " 24r 0.0000000e+00 3.06e+00 6.51e+01 -1.1 8.23e+00 - 8.22e-01 7.61e-01f 1\n", - " 25r 0.0000000e+00 2.19e+00 1.34e+03 -1.1 2.73e+01 - 2.45e-01 4.74e-01f 1\n", - " 26r 0.0000000e+00 9.32e-01 7.84e+02 -1.1 4.34e+01 - 4.27e-01 4.32e-01f 1\n", - " 27r 0.0000000e+00 1.88e-02 5.84e+02 -1.1 5.35e+01 - 2.86e-01 2.55e-01f 1\n", - " 28r 0.0000000e+00 1.89e-02 2.49e+03 -1.1 3.90e+01 - 3.89e-01 3.63e-03f 1\n", - " 29r 0.0000000e+00 1.87e-02 5.16e+03 -1.1 2.92e+00 - 1.00e+00 3.09e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 1.28e-02 9.16e-03 -1.1 2.56e+00 - 1.00e+00 1.00e+00f 1\n", - " 31r 0.0000000e+00 1.27e-02 1.52e+02 -4.1 1.56e-01 - 9.63e-01 9.13e-01f 1\n", - " 32r 0.0000000e+00 5.45e-03 5.50e+02 -4.1 4.28e+02 - 1.00e+00 4.09e-03f 1\n", - " 33r 0.0000000e+00 3.87e-04 9.26e+02 -4.1 3.38e+01 - 1.00e+00 3.76e-02f 1\n", - " 34r 0.0000000e+00 1.37e-05 6.68e+01 -4.1 1.08e-01 - 1.00e+00 9.28e-01f 1\n", - " 35r 0.0000000e+00 5.96e-09 2.75e-07 -4.1 3.78e-03 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 35\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.9644783556578318e-09 5.9644783556578318e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.9644783556578318e-09 5.9644783556578318e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 37\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 35\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.282\n", - "Total CPU secs in NLP function evaluations = 0.018\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.91e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.24e+02 8.48e+01 -1.0 3.91e+02 - 4.93e-03 4.28e-01f 1\n", - " 2 0.0000000e+00 2.19e+02 8.30e+01 -1.0 2.24e+02 - 1.02e-01 2.13e-02h 1\n", - " 3 0.0000000e+00 2.19e+02 1.20e+04 -1.0 2.19e+02 - 1.62e-01 2.46e-04h 1\n", - " 4r 0.0000000e+00 2.19e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 3.08e-07R 4\n", - " 5r 0.0000000e+00 2.10e+02 9.91e+02 2.3 9.42e+03 - 6.94e-03 7.96e-03f 1\n", - " 6r 0.0000000e+00 2.03e+02 8.13e+03 0.9 1.28e+03 - 5.02e-02 5.28e-03f 1\n", - " 7r 0.0000000e+00 1.48e+02 1.44e+04 0.9 5.00e+03 - 2.26e-02 1.21e-02f 1\n", - " 8r 0.0000000e+00 1.39e+02 1.73e+04 0.9 3.27e+03 - 5.92e-02 2.98e-03f 1\n", - " 9r 0.0000000e+00 1.03e+02 1.60e+04 0.9 1.87e+03 - 1.25e-01 1.91e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 4.88e+01 2.24e+04 0.9 7.38e+02 - 4.01e-01 7.65e-02f 1\n", - " 11r 0.0000000e+00 1.43e+01 1.91e+04 0.9 1.24e+02 - 4.48e-01 2.85e-01f 1\n", - " 12r 0.0000000e+00 1.09e+01 2.06e+04 0.9 2.83e+01 - 5.27e-01 1.19e-01f 1\n", - " 13r 0.0000000e+00 1.73e+00 8.52e+03 0.9 1.86e+01 - 3.55e-01 5.53e-01f 1\n", - " 14r 0.0000000e+00 1.74e+00 6.65e+03 0.9 3.33e+00 - 6.71e-01 2.03e-01f 1\n", - " 15r 0.0000000e+00 1.77e+00 3.19e+03 0.9 6.45e-01 - 5.58e-01 5.19e-01f 1\n", - " 16r 0.0000000e+00 1.81e+00 1.87e+03 0.9 7.55e-01 - 4.69e-01 4.19e-01f 1\n", - " 17r 0.0000000e+00 1.84e+00 8.90e+02 0.9 6.66e-01 - 5.24e-01 5.24e-01f 1\n", - " 18r 0.0000000e+00 1.86e+00 7.28e+03 0.9 3.80e-01 - 6.38e-01 9.45e-01f 1\n", - " 19r 0.0000000e+00 1.86e+00 2.29e-01 0.9 1.35e-01 - 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.11e+00 1.47e+02 -1.2 7.42e+00 - 8.33e-01 6.69e-01f 1\n", - " 21r 0.0000000e+00 2.09e+00 8.04e+02 -1.2 9.84e+00 - 5.60e-02 5.23e-01f 1\n", - " 22r 0.0000000e+00 1.67e+00 2.28e+03 -1.2 2.04e+01 - 2.82e-02 4.16e-01f 1\n", - " 23r 0.0000000e+00 1.29e+00 1.28e+03 -1.2 2.24e+01 - 3.92e-01 3.52e-01f 1\n", - " 24r 0.0000000e+00 4.93e-01 1.35e+03 -1.2 3.49e+01 - 1.31e-01 4.69e-01f 1\n", - " 25r 0.0000000e+00 1.86e-02 1.21e+03 -1.2 2.81e+01 - 2.80e-01 3.53e-01f 1\n", - " 26r 0.0000000e+00 1.87e-02 7.43e+02 -1.2 2.09e+01 - 2.66e-01 5.16e-03f 1\n", - " 27r 0.0000000e+00 1.89e-02 1.38e+03 -1.2 5.45e+00 - 9.74e-01 2.34e-02f 1\n", - " 28r 0.0000000e+00 2.27e-02 6.45e-03 -1.2 8.25e-01 - 1.00e+00 1.00e+00f 1\n", - " 29r 0.0000000e+00 2.26e-02 9.20e+02 -4.2 1.72e-01 - 9.80e-01 7.59e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 1.75e-02 5.71e+03 -4.2 4.73e+02 - 8.52e-01 2.65e-03f 1\n", - " 31r 0.0000000e+00 1.72e-02 5.75e+03 -4.2 2.67e+02 - 9.30e-01 2.46e-04f 1\n", - " 32r 0.0000000e+00 4.12e-04 3.38e+03 -4.2 1.00e+01 - 1.00e+00 4.12e-01f 1\n", - " 33r 0.0000000e+00 5.00e-06 4.10e+01 -4.2 9.28e-02 - 1.00e+00 9.88e-01f 1\n", - " 34r 0.0000000e+00 5.72e-09 1.95e-08 -4.2 1.14e-03 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.7186637647532734e-09 5.7186637647532734e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.7186637647532734e-09 5.7186637647532734e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 36\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.280\n", - "Total CPU secs in NLP function evaluations = 0.016\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.2\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.20e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.98e+02 4.01e+01 -1.0 3.20e+02 - 9.18e-03 3.81e-01f 1\n", - " 2 0.0000000e+00 1.89e+02 3.82e+01 -1.0 1.98e+02 - 1.50e-01 4.65e-02h 1\n", - " 3 0.0000000e+00 1.89e+02 1.15e+04 -1.0 1.89e+02 - 2.92e-01 6.46e-04h 1\n", - " 4r 0.0000000e+00 1.89e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 4.05e-07R 5\n", - " 5r 0.0000000e+00 1.48e+02 9.55e+03 2.3 1.59e+03 - 3.15e-03 2.97e-02f 1\n", - " 6r 0.0000000e+00 1.35e+02 9.39e+03 1.6 1.41e+03 - 5.41e-02 8.85e-03f 1\n", - " 7r 0.0000000e+00 1.07e+02 9.99e+03 1.6 2.53e+03 - 6.98e-02 1.11e-02f 1\n", - " 8r 0.0000000e+00 5.51e+01 1.07e+04 1.6 1.83e+03 - 1.60e-01 2.86e-02f 1\n", - " 9r 0.0000000e+00 1.52e+01 1.04e+04 1.6 8.87e+02 - 3.72e-01 4.50e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 2.13e+00 9.47e+03 1.6 1.20e+02 - 5.89e-01 1.26e-01f 1\n", - " 11r 0.0000000e+00 1.13e+00 6.09e+03 1.6 5.27e+00 - 4.85e-01 3.78e-01f 1\n", - " 12r 0.0000000e+00 4.39e-01 3.50e+03 1.6 2.77e+00 - 9.96e-01 5.47e-01f 1\n", - " 13r 0.0000000e+00 1.67e-01 5.99e+01 1.6 7.56e-01 - 1.00e+00 1.00e+00f 1\n", - " 14r 0.0000000e+00 1.43e-01 6.08e+02 -0.5 2.07e+00 - 4.41e-01 2.19e-01f 1\n", - " 15r 0.0000000e+00 1.14e-01 9.82e+02 -0.5 5.71e+00 - 6.67e-01 2.18e-01f 1\n", - " 16r 0.0000000e+00 1.01e-01 1.95e+03 -0.5 6.61e+00 - 9.73e-01 1.02e-01f 1\n", - " 17r 0.0000000e+00 2.24e-02 6.60e+02 -0.5 4.47e+00 - 1.00e+00 7.58e-01f 1\n", - " 18r 0.0000000e+00 5.86e-03 6.65e+02 -0.5 2.81e+00 - 1.00e+00 7.35e-01f 1\n", - " 19r 0.0000000e+00 1.87e-03 5.67e+02 -0.5 8.99e-01 - 1.00e+00 8.08e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 9.39e-04 7.94e-03 -0.5 3.57e-01 - 1.00e+00 1.00e+00f 1\n", - " 21r 0.0000000e+00 3.11e-04 4.65e+02 -2.9 2.41e-01 - 1.00e+00 6.65e-01f 1\n", - " 22r 0.0000000e+00 7.23e-05 1.37e+03 -2.9 3.38e-01 - 9.96e-01 3.40e-01f 1\n", - " 23r 0.0000000e+00 1.78e-05 6.46e+02 -2.9 1.48e-02 - 1.00e+00 8.26e-01f 1\n", - " 24r 0.0000000e+00 2.87e-06 2.62e+02 -2.9 3.33e-03 - 9.07e-01 1.00e+00f 1\n", - " 25r 0.0000000e+00 1.20e-07 2.54e-06 -2.9 2.24e-04 - 1.00e+00 1.00e+00f 1\n", - " 26r 0.0000000e+00 2.61e-08 1.39e+00 -6.5 4.87e-05 - 1.00e+00 9.92e-01f 1\n", - " 27r 0.0000000e+00 9.46e-10 7.24e-01 -6.5 3.19e-06 - 1.00e+00 9.84e-01f 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.4556971974579795e-10 9.4556971974579795e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.4556971974579795e-10 9.4556971974579795e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 29\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.236\n", - "Total CPU secs in NLP function evaluations = 0.016\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.4\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.79e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.95e+02 1.42e+02 -1.0 3.79e+02 - 3.35e-03 4.85e-01f 1\n", - " 2 0.0000000e+00 1.90e+02 1.39e+02 -1.0 1.95e+02 - 6.27e-02 2.35e-02h 1\n", - " 3 0.0000000e+00 1.90e+02 4.85e+03 -1.0 1.90e+02 - 1.07e-01 2.78e-04h 1\n", - " 4r 0.0000000e+00 1.90e+02 1.00e+03 2.3 0.00e+00 - 0.00e+00 3.48e-07R 4\n", - " 5r 0.0000000e+00 1.83e+02 1.25e+03 2.3 1.20e+04 - 9.88e-03 9.54e-03f 1\n", - " 6r 0.0000000e+00 1.80e+02 1.08e+04 0.9 1.40e+03 - 5.06e-02 3.21e-03f 1\n", - " 7r 0.0000000e+00 1.29e+02 1.89e+04 0.9 5.14e+03 - 2.68e-02 1.17e-02f 1\n", - " 8r 0.0000000e+00 1.20e+02 1.97e+04 0.9 3.41e+03 - 6.44e-02 2.90e-03f 1\n", - " 9r 0.0000000e+00 7.81e+01 1.73e+04 0.9 1.72e+03 - 1.46e-01 2.61e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 4.04e+01 1.34e+04 0.9 5.31e+02 - 1.94e-01 7.10e-02f 1\n", - " 11r 0.0000000e+00 1.84e+01 2.35e+04 0.9 1.78e+02 - 4.56e-01 1.24e-01f 1\n", - " 12r 0.0000000e+00 2.31e+00 1.73e+04 0.9 5.28e+01 - 4.92e-01 3.46e-01f 1\n", - " 13r 0.0000000e+00 2.32e+00 1.46e+04 0.9 2.67e+00 - 2.76e-01 1.71e-01f 1\n", - " 14r 0.0000000e+00 2.38e+00 8.69e+03 0.9 2.34e+00 - 1.52e-01 4.16e-01f 1\n", - " 15r 0.0000000e+00 2.46e+00 5.56e+03 0.9 2.11e+00 - 3.20e-01 4.13e-01f 1\n", - " 16r 0.0000000e+00 2.49e+00 2.92e+03 0.9 7.46e-01 - 5.68e-01 6.55e-01f 1\n", - " 17r 0.0000000e+00 2.50e+00 6.54e+03 0.9 6.35e-01 - 6.89e-01 4.64e-01f 1\n", - " 18r 0.0000000e+00 2.50e+00 1.87e+03 0.9 4.61e-01 - 3.88e-01 4.89e-01f 1\n", - " 19r 0.0000000e+00 2.51e+00 4.78e+03 0.9 3.13e-01 - 5.43e-01 9.57e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 2.50e+00 1.46e-01 0.9 1.10e-01 - 1.00e+00 1.00e+00f 1\n", - " 21r 0.0000000e+00 2.82e+00 5.49e+01 -1.2 7.01e+00 - 8.58e-01 7.83e-01f 1\n", - " 22r 0.0000000e+00 2.11e+00 1.56e+03 -1.2 2.69e+01 - 1.33e-01 4.64e-01f 1\n", - " 23r 0.0000000e+00 1.24e+00 1.21e+03 -1.2 3.79e+01 - 3.54e-01 4.06e-01f 1\n", - " 24r 0.0000000e+00 2.10e-02 1.01e+03 -1.2 4.93e+01 - 2.92e-01 4.34e-01f 1\n", - " 25r 0.0000000e+00 2.13e-02 1.06e+03 -1.2 3.44e+01 - 3.13e-01 6.32e-03f 1\n", - " 26r 0.0000000e+00 2.12e-02 2.85e+03 -1.2 8.72e+00 - 9.89e-01 1.30e-02f 1\n", - " 27r 0.0000000e+00 1.80e-02 1.32e+03 -1.2 1.90e+00 - 1.00e+00 5.52e-01f 1\n", - " 28r 0.0000000e+00 1.54e-02 1.66e-03 -1.2 6.86e-01 - 1.00e+00 1.00e+00f 1\n", - " 29r 0.0000000e+00 1.52e-02 6.58e+02 -4.3 1.27e-01 - 9.97e-01 6.89e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30r 0.0000000e+00 4.21e-03 4.72e+03 -4.3 5.52e+02 - 9.32e-01 4.85e-03f 1\n", - " 31r 0.0000000e+00 2.80e-03 5.53e+03 -4.3 7.54e+01 - 9.19e-01 4.50e-03f 1\n", - " 32r 0.0000000e+00 4.43e-05 1.13e+03 -4.3 8.54e-01 - 1.00e+00 7.96e-01f 1\n", - " 33r 0.0000000e+00 1.04e-08 2.00e-05 -4.3 9.88e-03 - 1.00e+00 1.00e+00f 1\n", - " 34r 0.0000000e+00 6.20e-11 1.70e-01 -6.5 2.71e-06 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.3625672114701202e-11 6.1975749971474384e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.3625672114701202e-11 6.1975749971474384e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 36\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.303\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.91e+02 3.29e+01 -1.0 3.92e+02 - 7.53e-03 2.58e-01f 1\n", - " 2 0.0000000e+00 2.82e+02 3.20e+01 -1.0 2.91e+02 - 1.86e-01 2.98e-02h 1\n", - " 3 0.0000000e+00 2.82e+02 2.19e+04 -1.0 2.82e+02 - 2.86e-01 3.83e-04h 1\n", - " 4r 0.0000000e+00 2.82e+02 1.00e+03 2.4 0.00e+00 - 0.00e+00 4.80e-07R 4\n", - " 5r 0.0000000e+00 2.69e+02 2.38e+03 2.4 1.17e+04 - 4.31e-03 9.93e-03f 1\n", - " 6r 0.0000000e+00 2.64e+02 2.51e+03 1.1 1.25e+03 - 4.37e-02 3.56e-03f 1\n", - " 7r 0.0000000e+00 2.09e+02 3.67e+03 1.1 4.56e+03 - 2.42e-02 1.23e-02f 1\n", - " 8r 0.0000000e+00 2.03e+02 7.82e+03 1.1 3.40e+03 - 1.53e-01 1.74e-03f 1\n", - " 9r 0.0000000e+00 9.66e+01 7.79e+03 1.1 1.93e+03 - 7.98e-02 5.71e-02f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10r 0.0000000e+00 6.20e+01 8.90e+03 1.1 8.06e+02 - 1.95e-01 4.86e-02f 1\n", - " 11r 0.0000000e+00 3.84e+01 1.20e+04 1.1 2.44e+02 - 7.62e-01 9.71e-02f 1\n", - " 12r 0.0000000e+00 1.60e+01 6.06e+03 1.1 5.46e+01 - 1.00e+00 4.10e-01f 1\n", - " 13r 0.0000000e+00 5.82e-01 1.27e+03 1.1 2.06e+01 - 1.00e+00 7.70e-01f 1\n", - " 14r 0.0000000e+00 4.84e-01 3.32e+03 1.1 9.52e-01 - 1.00e+00 1.69e-01f 1\n", - " 15r 0.0000000e+00 9.97e-02 2.79e+01 1.1 1.14e+00 - 1.00e+00 1.00e+00f 1\n", - " 16r 0.0000000e+00 8.91e-02 4.40e+02 -1.0 1.27e+00 - 5.29e-01 3.11e-01f 1\n", - " 17r 0.0000000e+00 7.90e-02 4.60e+02 -1.0 8.04e+00 - 2.34e-01 8.48e-02f 1\n", - " 18r 0.0000000e+00 7.13e-02 1.09e+03 -1.0 6.71e+00 - 7.40e-01 7.36e-02f 1\n", - " 19r 0.0000000e+00 2.65e-02 6.12e+02 -1.0 5.05e+00 - 1.00e+00 5.80e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20r 0.0000000e+00 9.27e-03 5.14e+02 -1.0 3.33e+00 - 1.00e+00 7.03e-01f 1\n", - " 21r 0.0000000e+00 6.56e-04 5.07e+02 -1.0 1.64e+00 - 1.00e+00 7.90e-01f 1\n", - " 22r 0.0000000e+00 1.79e-04 7.46e+01 -1.0 2.19e-01 - 1.00e+00 9.76e-01f 1\n", - " 23r 0.0000000e+00 2.84e-04 8.65e+02 -1.0 5.80e-02 - 4.80e-01 1.00e+00f 1\n", - " 24r 0.0000000e+00 3.74e-04 9.40e-06 -1.0 2.16e-02 - 1.00e+00 1.00e+00f 1\n", - " 25r 0.0000000e+00 3.06e-05 5.52e+02 -3.9 6.97e-02 - 1.00e+00 7.26e-01f 1\n", - " 26r 0.0000000e+00 1.41e-05 2.27e+03 -3.9 2.89e-02 - 9.71e-01 4.66e-01f 1\n", - " 27r 0.0000000e+00 4.15e-06 1.11e+03 -3.9 1.25e-03 - 9.53e-01 8.10e-01f 1\n", - " 28r 0.0000000e+00 1.67e-07 1.22e+02 -3.9 7.64e-04 - 9.19e-01 1.00e+00f 1\n", - " 29r 0.0000000e+00 4.10e-09 2.54e-08 -3.9 3.49e-06 - 1.00e+00 1.00e+00f 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.0956430746863504e-09 4.0956430746863504e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.0956430746863504e-09 4.0956430746863504e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 31\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.216\n", - "Total CPU secs in NLP function evaluations = 0.049\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n" - ] - } - ], - "source": [ - "def new_doe_object2(Ca, T0, FIM_prior):\n", - " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", - " \n", - " measurements = MeasurementVariables()\n", - " measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", - " \n", - " exp_design = DesignVariables()\n", - " exp_design.add_variables(\n", - " \"CA0\",\n", - " time_index_position=0,\n", - " values=[Ca, ],\n", - " lower_bounds=1,\n", - " indices={0: [0]},\n", - " upper_bounds=5,\n", - " )\n", - " exp_design.add_variables(\n", - " \"T\",\n", - " indices={0: t_control},\n", - " time_index_position=0,\n", - " values=list(T0),\n", - " lower_bounds=300,\n", - " upper_bounds=700,\n", - " )\n", - "\n", - " # exp_design.update_values({\"CA0[0]\": Ca, \"T[0]\": T0[0], \"T[0.125]\": T0[1], \"T[0.25]\": T0[2], \"T[0.375]\": T0[3], \"T[0.5]\": T0[4], \"T[0.625]\": T0[5],\n", - " # \"T[0.75]\": T0[6], \"T[0.875]\": T0[7], \"T[1]\": T0[8]})\n", - " \n", - " doe_object = DesignOfExperiments(\n", - " parameter_dict,\n", - " exp_design, \n", - " measurements, \n", - " create_model,\n", - " # prior_FIM=FIM_prior,\n", - " discretize_model=disc_for_measure,\n", - " )\n", - "\n", - " result = doe_object.compute_FIM(\n", - " mode=\"sequential_finite\",\n", - " scale_nominal_param_value=True,\n", - " formula=\"central\",\n", - " )\n", - "\n", - " result.result_analysis()\n", - " \n", - " return result\n", - "\n", - "n_para = len(parameter_dict)\n", - "\n", - "\n", - "t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - "parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", - " \n", - "measurements = MeasurementVariables()\n", - "measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", - " \n", - "exp_design = DesignVariables()\n", - "exp_design.add_variables(\n", - " \"CA0\",\n", - " indices={0: [0]},\n", - " time_index_position=0,\n", - " lower_bounds=1,\n", - " upper_bounds=5,\n", - " )\n", - "exp_design.add_variables(\n", - " \"T\",\n", - " indices={0: t_control},\n", - " time_index_position=0,\n", - " lower_bounds=300,\n", - " upper_bounds=700,\n", - " )\n", - "\n", - "exp_design.update_values({\"CA0[0]\": 5, \"T[0]\": 450, \"T[0.125]\": 300, \"T[0.25]\": 300, \"T[0.375]\": 300, \"T[0.5]\": 300, \"T[0.625]\": 300,\n", - " \"T[0.75]\": 300, \"T[0.875]\": 300, \"T[1]\": 300})\n", - " \n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict,\n", - " exp_design, \n", - " measurements, \n", - " create_model,\n", - " discretize_model=disc_for_measure,\n", - " )\n", - "\n", - "result = doe_object.compute_FIM(\n", - " mode=\"sequential_finite\",\n", - " scale_nominal_param_value=True,\n", - " formula=\"central\",\n", - " )\n", - "\n", - "result.result_analysis()\n", - "\n", - "FIM_prior = result.FIM\n", - "FIM_new = np.zeros((n_para, n_para))\n", - "A_vals_rand = []\n", - "D_vals_rand = []\n", - "exp_conds_rand = []\n", - "FIM_rand = None\n", - "\n", - "for i in range(20):\n", - " FIM_prior += FIM_new\n", - " # T_val = sample(range(300, 750, 50), 1)\n", - " T_val = np.random.rand(9)\n", - " T_val = 300 + (700 - 300) * T_val\n", - " # C_val = sample([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0], 1)\n", - " C_val = np.random.rand(1)\n", - " C_val = 1.0 + (5.0 - 1.0) * C_val\n", - " \n", - " new_exp = new_doe_object2(C_val[0], T_val, FIM_prior)\n", - " FIM_new = new_exp.FIM\n", - " if FIM_rand is None:\n", - " FIM_rand = [FIM_new, ]\n", - " else:\n", - " FIM_rand.append(FIM_new)\n", - " A_opt = np.trace(FIM_new)\n", - " D_opt = np.linalg.det(FIM_new)\n", - " A_vals_rand.append(np.log10(A_opt))\n", - " D_vals_rand.append(np.log10(D_opt))" - ] - }, - { - "cell_type": "code", - "execution_count": 99, - "id": "883c7a88-c484-4d30-a240-0f59b7851641", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[array([[ 7.41191972, 1.91892715, -17.16569693, -5.13978557],\n", - " [ 1.91892715, 3.00288018, -3.30481097, -9.22942421],\n", - " [-17.16569693, -3.30481097, 40.83791667, 8.43170603],\n", - " [ -5.13978557, -9.22942421, 8.43170603, 29.03347955]]), array([[ 4.85545081, 0.91633779, -11.26700706, -2.3725946 ],\n", - " [ 0.91633779, 2.07545769, -1.67466172, -6.76212137],\n", - " [-11.26700706, -1.67466172, 26.48743701, 4.09255167],\n", - " [ -2.3725946 , -6.76212137, 4.09255167, 22.59510839]]), array([[ 1.63712282, 0.26253947, -3.61049017, -0.64461976],\n", - " [ 0.26253947, 0.65918137, -0.44757963, -2.18785091],\n", - " [-3.61049017, -0.44757963, 8.05695621, 1.03503989],\n", - " [-0.64461976, -2.18785091, 1.03503989, 7.4873944 ]]), array([[ 2.97488904, 0.93745651, -5.81666255, -3.06492446],\n", - " [ 0.93745651, 2.37956777, -1.78533978, -8.23677851],\n", - " [-5.81666255, -1.78533978, 11.39473346, 5.858635 ],\n", - " [-3.06492446, -8.23677851, 5.858635 , 28.72717236]]), array([[ 1.45973057, 0.98386612, -2.86168557, -3.83501583],\n", - " [ 0.98386612, 2.15443774, -1.91504893, -8.31274632],\n", - " [-2.86168557, -1.91504893, 5.61339247, 7.46485661],\n", - " [-3.83501583, -8.31274632, 7.46485661, 32.13147505]]), array([[ 0.32942076, 0.05277751, -0.72206457, -0.14075814],\n", - " [ 0.05277751, 0.16812912, -0.10170988, -0.57890579],\n", - " [-0.72206457, -0.10170988, 1.59135893, 0.26682263],\n", - " [-0.14075814, -0.57890579, 0.26682263, 2.03945911]]), array([[ 0.76173934, 0.46813848, -1.06469869, -1.24519301],\n", - " [ 0.46813848, 0.55668808, -0.65355734, -1.47375114],\n", - " [-1.06469869, -0.65355734, 1.48829363, 1.73857997],\n", - " [-1.24519301, -1.47375114, 1.73857997, 3.90772047]]), array([[ 1.58568372, 1.03312929, -2.30508585, -2.88710352],\n", - " [ 1.03312929, 1.33624454, -1.49728349, -3.71846817],\n", - " [-2.30508585, -1.49728349, 3.35175044, 4.18651955],\n", - " [-2.88710352, -3.71846817, 4.18651955, 10.36697694]]), array([[ 0.9146211 , 0.2098628 , -2.02667857, -0.78736555],\n", - " [ 0.2098628 , 0.76055504, -0.46593176, -2.99906867],\n", - " [-2.02667857, -0.46593176, 4.49422093, 1.7552855 ],\n", - " [-0.78736555, -2.99906867, 1.7552855 , 11.87833482]]), array([[ 2.26254966, 1.09103039, -4.86569687, -3.9775466 ],\n", - " [ 1.09103039, 2.48711336, -2.27302328, -9.29606811],\n", - " [-4.86569687, -2.27302328, 10.48284989, 8.27766951],\n", - " [-3.9775466 , -9.29606811, 8.27766951, 34.86643729]]), array([[ 2.37963826, 1.31101885, -3.90017864, -3.96581534],\n", - " [ 1.31101885, 2.32934987, -2.15691544, -7.08276537],\n", - " [-3.90017864, -2.15691544, 6.39343664, 6.52737831],\n", - " [-3.96581534, -7.08276537, 6.52737831, 21.54981334]]), array([[ 0.39317634, 0.27099406, -0.59222429, -0.7984167 ],\n", - " [ 0.27099406, 0.37061251, -0.40707655, -1.08492437],\n", - " [-0.59222429, -0.40707655, 0.8924423 , 1.20061859],\n", - " [-0.7984167 , -1.08492437, 1.20061859, 3.18892252]]), array([[ 0.22495 , 0.17358708, -0.34404272, -0.54730493],\n", - " [ 0.17358708, 0.2354521 , -0.2639738 , -0.73582788],\n", - " [-0.34404272, -0.2639738 , 0.52689608, 0.83381041],\n", - " [-0.54730493, -0.73582788, 0.83381041, 2.32359059]]), array([[ 1.46276597, 0.62662469, -3.9557259 , -2.91076272],\n", - " [ 0.62662469, 2.25275237, -1.67394427, -10.7119166 ],\n", - " [ -3.9557259 , -1.67394427, 10.70199128, 7.76623662],\n", - " [ -2.91076272, -10.7119166 , 7.76623662, 51.07349918]]), array([[ 6.54061161, 1.02433269, -16.03397716, -2.356947 ],\n", - " [ 1.02433269, 2.12804573, -1.76843941, -6.46991952],\n", - " [-16.03397716, -1.76843941, 40.14490486, 3.56281626],\n", - " [ -2.356947 , -6.46991952, 3.56281626, 20.19787514]]), array([[ 9.75348357, 7.80718051, -17.89422681, -30.05800918],\n", - " [ 7.80718051, 14.92544475, -13.33572462, -56.99505773],\n", - " [-17.89422681, -13.33572462, 33.23087006, 51.41850532],\n", - " [-30.05800918, -56.99505773, 51.41850532, 219.15103769]]), array([[ 1.77917606, 1.29540968, -2.57471389, -3.86435101],\n", - " [ 1.29540968, 1.60079675, -1.84799977, -4.7469565 ],\n", - " [-2.57471389, -1.84799977, 3.73604891, 5.52039717],\n", - " [-3.86435101, -4.7469565 , 5.52039717, 14.22683014]]), array([[ 1.0426306 , 0.31074057, -2.58096954, -1.12614861],\n", - " [ 0.31074057, 0.89576898, -0.74096629, -3.4507674 ],\n", - " [-2.58096954, -0.74096629, 6.42529421, 2.68122134],\n", - " [-1.12614861, -3.4507674 , 2.68122134, 13.34402829]]), array([[ 2.62318377, 1.58532964, -4.11611868, -4.65267119],\n", - " [ 1.58532964, 2.43243152, -2.4907991 , -7.1402936 ],\n", - " [-4.11611868, -2.4907991 , 6.46038325, 7.31016341],\n", - " [-4.65267119, -7.1402936 , 7.31016341, 20.97349451]]), array([[ 0.45863109, 0.06430434, -1.28081215, -0.18713209],\n", - " [ 0.06430434, 0.24416895, -0.16066722, -0.93320429],\n", - " [-1.28081215, -0.16066722, 3.61921878, 0.46801022],\n", - " [-0.18713209, -0.93320429, 0.46801022, 3.64970397]])]\n" - ] - }, - { - "data": { - "image/png": "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ypQp9O/fn8TERJo3b85Pf/pT1q5dW+tz5syZg8vlOu62Zs0aH1XdMPfee+9xNaemptb6nED8TN0yMzNr/JwmTpxY4/GB9LnOmzePn/zkJ6SlpeFyuXjvvfeqfd1xHO69917S0tKIjY3l7LPPZuXKlSd93enTp9OtWzeio6Pp1q0b7777rpfeQd3V9l5LS0v5/e9/T48ePYiPjyctLY1rr72W7OzsWl/z5ZdfrvGzLioq8vK7ObmTfbbXX3/9cXUPHDjwpK8baJ8tUONn5HK5eOihh074mv782XpL0AaRN998k9tvv50//vGPLF26lKFDh3LhhReybdu2Go/fvHkzo0aNYujQoSxdupQ//OEP3HbbbUyfPt3HldfP3LlzmThxIgsXLmTmzJmUlZUxYsQICgoKTvrctWvXsnPnzspbx44dfVDxqTnttNOq1bx8+fITHhuon6nbokWLqr3XmTNnAnDFFVfU+rxA+FwLCgro2bMnTz75ZI1f/8c//sEjjzzCk08+yaJFi0hNTeX888+v3H+qJt988w1XXXUV48aNY9myZYwbN44rr7ySb7/91ltvo05qe6+FhYV8//33/PnPf+b777/nnXfeYd26dVxyySUnfd2kpKRqn/POnTuJiYnxxluol5N9tgAjR46sVvcnn3xS62sG4mcLHPf5vPjii7hcLi6//PJaX9dfP1uvcYLUGWec4UyYMKHaY126dHHuuuuuGo//3e9+53Tp0qXaY7/85S+dgQMHeq1Gb9izZ48DOHPnzj3hMbNnz3YA58CBA74rzAPuuecep2fPnnU+Plg+U7df//rXTvv27Z2Kiooavx6onyvgvPvuu5X/rqiocFJTU50HH3yw8rGioiInOTnZefbZZ0/4OldeeaUzcuTIao9dcMEFzpgxYzxec0Md+15r8t133zmAs3Xr1hMe89JLLznJycmeLc4Lanq/1113nXPppZfW63WC5bO99NJLnXPOOafWYwLls/WkoOwRKSkpYcmSJYwYMaLa4yNGjGDBggU1Puebb7457vgLLriAxYsXU1pa6rVaPS03NxeAxo0bn/TY3r1707JlS84991xmz57t7dI8Yv369aSlpdG2bVvGjBnDpk2bTnhssHymYP6ffvXVV7nxxhtPugFkIH6uR9u8eTO7du2q9tlFR0czbNiwE37/wok/79qe449yc3NxuVw0atSo1uMOHTpEmzZtSE9P5+KLL2bp0qW+KdAD5syZQ/PmzenUqRM333wze/bsqfX4YPhsd+/ezccff8z48eNPemwgf7YNEZRBJCcnh/Lyclq0aFHt8RYtWrBr164an7Nr164ajy8rKyMnJ8drtXqS4zhMnjyZIUOG0L179xMe17JlS55//nmmT5/OO++8Q+fOnTn33HOZN2+eD6utvwEDBvCf//yHzz//nBdeeIFdu3YxePBg9u3bV+PxwfCZur333nscPHiQ66+//oTHBOrneiz392h9vn/dz6vvc/xNUVERd911F2PHjq11Q7QuXbrw8ssv88EHH/D6668TExPDmWeeyfr1631YbcNceOGFvPbaa8yaNYt//vOfLFq0iHPOOYfi4uITPicYPttXXnmFxMRERo8eXetxgfzZNpRf7757qo79y9FxnFr/mqzp+Joe91eTJk3ixx9/5Ouvv671uM6dO9O5c+fKfw8aNIisrCwefvhhzjrrLG+X2WAXXnhhZbtHjx4MGjSI9u3b88orrzB58uQanxPon6nb1KlTufDCC0lLSzvhMYH6uZ5Ifb9/G/ocf1FaWsqYMWOoqKjg6aefrvXYgQMHVhvgeeaZZ9KnTx+eeOIJHn/8cW+Xekquuuqqynb37t3p168fbdq04eOPP671l3Qgf7YAL774Itdcc81Jx3oE8mfbUEHZI9K0aVPCw8OPS8t79uw5LlW7paam1nh8REQETZo08VqtnnLrrbfywQcfMHv2bNLT0+v9/IEDBwZc4o6Pj6dHjx4nrDvQP1O3rVu38sUXX3DTTTfV+7mB+Lm6Z0LV5/vX/bz6PsdflJaWcuWVV7J582ZmzpxZ7+3hw8LC6N+/f8B91mB68tq0aVNr7YH82QJ89dVXrF27tkHfw4H82dZVUAaRqKgo+vbtWznLwG3mzJkMHjy4xucMGjTouONnzJhBv379iIyM9Fqtp8pxHCZNmsQ777zDrFmzaNu2bYNeZ+nSpbRs2dLD1XlXcXExq1evPmHdgfqZHuull16iefPmXHTRRfV+biB+rm3btiU1NbXaZ1dSUsLcuXNP+P0LJ/68a3uOP3CHkPXr1/PFF180KCQ7jsMPP/wQcJ81wL59+8jKyqq19kD9bN2mTp1K37596dmzZ72fG8ifbZ3ZGiXrbW+88YYTGRnpTJ061Vm1apVz++23O/Hx8c6WLVscx3Gcu+66yxk3blzl8Zs2bXLi4uKcO+64w1m1apUzdepUJzIy0nn77bdtvYU6+dWvfuUkJyc7c+bMcXbu3Fl5KywsrDzm2Pf66KOPOu+++66zbt06Z8WKFc5dd93lAM706dNtvIU6u/POO505c+Y4mzZtchYuXOhcfPHFTmJiYtB9pkcrLy93Wrdu7fz+978/7muB/Lnm5+c7S5cudZYuXeoAziOPPOIsXbq0cqbIgw8+6CQnJzvvvPOOs3z5cufqq692WrZs6eTl5VW+xrhx46rNgps/f74THh7uPPjgg87q1audBx980ImIiHAWLlzo8/d3tNrea2lpqXPJJZc46enpzg8//FDte7i4uLjyNY59r/fee6/z2WefORs3bnSWLl3q3HDDDU5ERITz7bff2niL1dT2fvPz850777zTWbBggbN582Zn9uzZzqBBg5xWrVoF3Wfrlpub68TFxTnPPPNMja8RSJ+ttwRtEHEcx3nqqaecNm3aOFFRUU6fPn2qTWm97rrrnGHDhlU7fs6cOU7v3r2dqKgoJzMz84T/4/gToMbbSy+9VHnMse/173//u9O+fXsnJibGSUlJcYYMGeJ8/PHHvi++nq666iqnZcuWTmRkpJOWluaMHj3aWblyZeXXg+UzPdrnn3/uAM7atWuP+1ogf67uqcbH3q677jrHccwU3nvuucdJTU11oqOjnbPOOstZvnx5tdcYNmxY5fFub731ltO5c2cnMjLS6dKli1+EsNre6+bNm0/4PTx79uzK1zj2vd5+++1O69atnaioKKdZs2bOiBEjnAULFvj+zdWgtvdbWFjojBgxwmnWrJkTGRnptG7d2rnuuuucbdu2VXuNYPhs3Z577jknNjbWOXjwYI2vEUifrbe4HOfI6D0RERERHwvKMSIiIiISGBRERERExBoFEREREbFGQURERESsURARERERaxRERERExBoFEREREbFGQURERESsURARERERaxRERERExBoFEREREbFGQURERESs+X8Eavm372QE9AAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "D_vals_rand_from_ind_FIM = []\n", - "running_FIM = np.zeros((n_para, n_para))\n", - "print(FIM_rand)\n", - "for i in range(20):\n", - " running_FIM += FIM_rand[i]\n", - " D_vals_rand_from_ind_FIM.append(np.log10(np.linalg.det(running_FIM)))\n", - "\n", - "plt.plot(range(20), D_vals_rand_from_ind_FIM, color='green')\n", - "plt.plot(range(20), D_vals_rand, color='orange')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d0bf5a03-4f8a-4c7b-9ee3-57577550689e", - "metadata": {}, - "outputs": [], - "source": [ - "# mobel based design" - ] - }, - { - "cell_type": "code", - "execution_count": 106, - "id": "be09a59b-5783-4cdd-a023-380be8f2935a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.47e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 2.64e+01 3.85e+02 -1.0 1.47e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.71e+00 5.99e+01 -1.0 3.11e+01 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 3.98e-02 2.06e+00 -1.0 3.19e+00 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 7.87e-07 2.39e-04 -1.0 2.80e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (287125)\n", - " 5 0.0000000e+00 2.27e-13 1.50e-09 -3.8 5.42e-07 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.3691704763652764e-13 2.2737367544323206e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.3691704763652764e-13 2.2737367544323206e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.078\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 8.41e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 5.97e+02 3.85e+02 -1.0 8.40e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 9.58e+01 5.99e+01 -1.0 8.73e+02 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.25e+00 2.06e+00 -1.0 7.86e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.23e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (394005)\n", - " 5 0.0000000e+00 2.52e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.3691704763652764e-13 2.5224267119483557e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.3691704763652764e-13 2.5224267119483557e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.097\n", - "Total CPU secs in NLP function evaluations = 0.015\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -7.7248744e+00 8.42e+02 3.03e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303416)\n", - " 1 -9.5185054e+00 3.55e+02 1.97e+00 -1.0 2.49e+01 - 6.64e-01 5.10e-01h 1\n", - " 2 -1.0459243e+01 2.21e+01 1.06e+00 -1.0 1.03e+01 - 9.89e-01 1.00e+00f 1\n", - " 3 -1.0005982e+01 2.37e+00 1.82e+01 -1.0 6.69e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -9.4350217e+00 6.84e+00 2.90e+01 -1.0 1.66e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -9.9270718e+00 3.91e+00 4.23e+00 -1.0 7.85e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 -9.8988295e+00 8.63e-02 7.95e-01 -1.0 4.47e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -9.9256371e+00 1.12e-02 8.03e-02 -1.7 1.69e+00 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.0115145e+01 6.09e-01 3.86e+00 -2.5 1.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.0716463e+01 1.17e+01 7.10e+01 -2.5 4.55e+02 - 2.86e-01 2.24e-01h 2\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.1139383e+01 3.90e+00 1.50e+01 -2.5 3.96e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (326891)\n", - " 11 -1.1160539e+01 7.96e-02 1.12e-01 -2.5 2.01e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 -1.1161798e+01 1.04e-03 2.28e-03 -2.5 3.39e+00 - 1.00e+00 1.00e+00h 1\n", - " 13 -1.1804938e+01 5.61e+00 3.57e+00 -3.8 7.07e+01 - 7.08e-01 1.00e+00f 1\n", - " 14 -1.2138004e+01 2.90e+00 2.94e+00 -3.8 6.85e+01 - 9.69e-01 1.00e+00h 1\n", - " 15 -1.2260171e+01 8.52e-01 5.77e-01 -3.8 3.63e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 -1.2249771e+01 6.32e-03 2.20e-02 -3.8 9.24e+00 - 1.00e+00 1.00e+00h 1\n", - " 17 -1.2249799e+01 6.45e-06 1.24e-05 -3.8 3.70e-01 - 1.00e+00 1.00e+00h 1\n", - " 18 -1.2341110e+01 2.89e-01 1.08e-01 -5.7 2.25e+01 - 9.19e-01 9.86e-01f 1\n", - " 19 -1.2347950e+01 6.26e-03 1.40e-03 -5.7 2.74e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2348059e+01 2.15e-06 1.44e-06 -5.7 4.38e-02 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.2349341e+01 7.29e-05 2.04e-05 -8.6 3.46e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (355282)\n", - " 22 -1.2349342e+01 2.92e-10 5.48e-08 -8.6 5.48e-04 -4.0 1.00e+00 1.00e+00h 1\n", - " 23 -1.2349342e+01 4.55e-13 2.15e-11 -8.6 6.44e-07 -4.5 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2349342292918536e+01 -1.2349342292918536e+01\n", - "Dual infeasibility......: 2.1473493827409733e-11 2.1473493827409733e-11\n", - "Constraint violation....: 1.7053025658242404e-13 4.5474735088646412e-13\n", - "Complementarity.........: 2.5059035849180921e-09 2.5059035849180921e-09\n", - "Overall NLP error.......: 2.5059035849180921e-09 2.5059035849180921e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 27\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 27\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.487\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.83e+01 4.31e+01 -1.0 4.78e+01 - 4.76e-01 9.84e-01h 1\n", - " 3 0.0000000e+00 2.63e-01 4.48e+02 -1.0 2.89e+01 - 4.02e-02 9.90e-01h 1\n", - " 4 0.0000000e+00 5.47e-04 1.17e+02 -1.0 1.35e-01 - 9.90e-01 9.98e-01h 1\n", - "Reallocating memory for MA57: lfact (284905)\n", - " 5 0.0000000e+00 6.26e-11 1.00e-06 -1.0 2.79e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 6.2641447584610432e-11 6.2641447584610432e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 6.2641447584610432e-11 6.2641447584610432e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.078\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.19e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 6.10e+02 3.85e+02 -1.0 2.19e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 9.60e+01 5.99e+01 -1.0 8.86e+02 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.25e+00 2.06e+00 -1.0 7.87e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.23e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (394385)\n", - " 5 0.0000000e+00 2.27e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.5474735088646412e-13 2.2737367544323206e-12\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.5474735088646412e-13 2.2737367544323206e-12\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.113\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.3841270e+01 8.42e+02 1.61e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303016)\n", - " 1 -1.4404335e+01 3.97e+02 3.77e+00 -1.0 2.54e+01 - 8.41e-01 5.01e-01h 1\n", - " 2 -1.4812683e+01 1.50e+01 5.74e-01 -1.0 7.17e+00 - 9.88e-01 1.00e+00f 1\n", - " 3 -1.4522399e+01 4.44e+00 1.61e+01 -1.0 8.94e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -1.4388879e+01 1.20e+01 1.37e+01 -1.0 1.49e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.4491792e+01 1.25e+00 1.12e+00 -1.0 3.05e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 -1.4495171e+01 5.96e-04 9.48e-03 -1.0 1.09e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -1.4495521e+01 8.41e-05 5.34e-03 -2.5 3.10e-01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.4516522e+01 7.21e-01 1.81e+00 -3.8 1.75e+01 - 7.92e-01 1.00e+00h 1\n", - " 9 -1.4530830e+01 4.10e-03 1.85e-02 -3.8 1.06e+00 -4.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.4533751e+01 1.58e-03 4.43e-03 -3.8 1.26e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 11 -1.4540008e+01 1.21e-02 4.52e-02 -3.8 2.29e+00 -5.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.4566257e+01 2.27e-01 7.87e-01 -3.8 9.29e+00 -5.4 1.00e+00 1.00e+00h 1\n", - " 13 -1.4585780e+01 3.91e-02 1.61e-01 -3.8 3.90e+00 -5.0 1.00e+00 1.00e+00h 1\n", - " 14 -1.4657627e+01 8.05e-01 2.88e+00 -3.8 1.70e+01 -5.5 1.00e+00 1.00e+00h 1\n", - " 15 -1.5563505e+01 8.18e+01 2.82e+02 -3.8 4.19e+02 -6.0 2.05e-01 5.14e-01h 1\n", - " 16 -1.5523849e+01 2.68e+01 2.80e+01 -3.8 6.91e+01 -5.5 1.00e+00 1.00e+00h 1\n", - " 17 -1.5802664e+01 2.51e+01 5.48e+00 -3.8 1.72e+02 - 3.49e-01 4.82e-01h 1\n", - " 18 -1.5795220e+01 1.64e+01 1.24e+01 -3.8 1.44e+02 - 1.00e+00 1.00e+00f 1\n", - " 19 -1.5802973e+01 1.78e+00 6.66e-01 -3.8 5.80e+01 - 9.66e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.5792518e+01 6.29e-02 1.87e-02 -3.8 2.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.5792562e+01 6.62e-05 7.16e-05 -3.8 6.47e-01 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.5863869e+01 1.39e+00 8.36e-01 -5.7 8.31e+01 - 7.11e-01 1.00e+00f 1\n", - " 23 -1.5877663e+01 1.08e-01 5.90e-02 -5.7 2.81e+01 - 9.75e-01 1.00e+00h 1\n", - " 24 -1.5878910e+01 9.88e-03 7.73e-04 -5.7 8.80e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (330048)\n", - " 25 -1.5878920e+01 2.19e-04 2.60e-06 -5.7 1.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.5878920e+01 4.59e-08 3.36e-10 -5.7 1.93e-02 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.5880196e+01 1.15e-03 2.24e-04 -8.6 3.06e+00 - 9.93e-01 1.00e+00f 1\n", - "Reallocating memory for MA57: lfact (362150)\n", - " 28 -1.5880200e+01 1.55e-06 3.86e-08 -8.6 1.13e-01 - 1.00e+00 1.00e+00h 1\n", - " 29 -1.5880200e+01 4.40e-12 1.85e-10 -8.6 1.90e-04 -6.0 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.5880200473415972e+01 -1.5880200473415972e+01\n", - "Dual infeasibility......: 1.8546108990308775e-10 1.8546108990308775e-10\n", - "Constraint violation....: 4.3998138465894954e-12 4.3998138465894954e-12\n", - "Complementarity.........: 2.5059390926675284e-09 2.5059390926675284e-09\n", - "Overall NLP error.......: 2.5059390926675284e-09 2.5059390926675284e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 30\n", - "Number of objective gradient evaluations = 30\n", - "Number of equality constraint evaluations = 30\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 30\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.620\n", - "Total CPU secs in NLP function evaluations = 0.028\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.4\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.19e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 5.67e+01 3.85e+02 -1.0 3.19e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 2.60e+01 4.39e+02 -1.0 7.08e+01 - 5.65e-02 9.90e-01h 1\n", - " 3 0.0000000e+00 1.79e-01 1.22e+02 -1.0 1.49e+01 - 5.20e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 7.30e-06 2.37e+02 -1.0 1.13e-01 - 9.91e-01 1.00e+00h 1\n", - " 5 0.0000000e+00 3.41e-13 1.00e-06 -1.0 4.00e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.7701825750354685e-13 3.4106051316484809e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.7701825750354685e-13 3.4106051316484809e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.065\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 4.70e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 6.35e+02 3.85e+02 -1.0 4.70e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 9.62e+01 5.99e+01 -1.0 9.11e+02 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.26e+00 2.06e+00 -1.0 7.87e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.24e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393774)\n", - " 5 0.0000000e+00 4.55e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.3691704763652764e-13 4.5474735088646412e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.3691704763652764e-13 4.5474735088646412e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.119\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.7948727e+01 8.42e+02 1.33e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303016)\n", - " 1 -1.8165832e+01 4.09e+02 4.51e+00 -1.0 2.53e+01 - 9.19e-01 5.02e-01h 1\n", - " 2 -1.8347575e+01 8.18e+00 2.41e-01 -1.0 3.98e+00 - 9.87e-01 1.00e+00f 1\n", - " 3 -1.8279037e+01 6.26e+00 5.74e+00 -1.0 1.03e+02 - 1.00e+00 1.00e+00f 1\n", - " 4 -1.8238859e+01 1.69e+01 3.91e+00 -1.0 1.64e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.8269310e+01 2.31e-01 2.75e-01 -1.0 2.89e+00 - 1.00e+00 1.00e+00h 1\n", - " 6 -1.8270555e+01 5.19e-04 4.57e-04 -1.7 6.60e-01 - 1.00e+00 1.00e+00h 1\n", - " 7 -1.8270805e+01 7.88e-04 6.63e-04 -3.8 5.00e-01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.8271500e+01 9.45e-04 5.28e-04 -5.7 1.71e+00 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -1.8273229e+01 5.92e-03 1.56e-04 -5.7 4.65e+00 -4.5 1.00e+00 9.14e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.8273631e+01 2.13e-03 1.40e-03 -5.7 3.86e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 11 -1.8275013e+01 2.11e-02 2.82e-03 -5.7 1.28e+00 -5.4 1.00e+00 1.00e+00h 1\n", - " 12 -1.8275591e+01 3.07e-03 4.00e-04 -5.7 5.07e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 13 -1.8277354e+01 3.13e-02 4.47e-03 -5.7 1.63e+00 -5.5 1.00e+00 1.00e+00h 1\n", - " 14 -1.8284188e+01 4.35e-01 7.97e-02 -5.7 6.56e+00 -6.0 1.00e+00 1.00e+00h 1\n", - " 15 -1.8339799e+01 2.22e+01 6.67e+00 -5.7 9.02e+01 -6.4 9.31e-01 6.26e-01h 1\n", - "Reallocating memory for MA57: lfact (332105)\n", - " 16 -1.8410872e+01 1.03e+01 2.06e+00 -5.7 1.03e+02 -6.0 1.00e+00 7.09e-01f 1\n", - " 17 -1.8453249e+01 9.48e+00 2.01e+00 -5.7 1.70e+02 -6.5 1.00e+00 1.89e-01f 1\n", - " 18 -1.8469379e+01 8.31e+00 1.68e+00 -5.7 8.57e+01 -7.0 4.45e-01 1.63e-01h 1\n", - " 19 -1.8493566e+01 3.77e+00 6.76e-01 -5.7 3.26e+01 -6.5 1.00e+00 5.98e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.8501400e+01 3.15e+00 5.56e-01 -5.7 5.39e+01 -7.0 1.00e+00 1.78e-01h 1\n", - " 21 -1.8519701e+01 2.67e-01 7.89e-02 -5.7 2.04e+01 -6.6 1.00e+00 1.00e+00f 1\n", - " 22 -1.8524363e+01 3.95e-01 2.25e-01 -5.7 6.41e+01 -7.1 1.00e+00 2.07e-01h 1\n", - " 23 -1.8531234e+01 2.84e-01 2.21e-01 -5.7 1.59e+01 -6.6 1.00e+00 1.00e+00f 1\n", - " 24 -1.8538783e+01 6.75e-01 4.74e-01 -5.7 5.12e+01 -7.1 1.00e+00 3.67e-01h 1\n", - " 25 -1.8551386e+01 4.55e+00 1.63e+00 -5.7 8.00e+01 -7.6 1.00e+00 1.00e+00f 1\n", - " 26 -1.8545090e+01 1.46e-01 1.88e-01 -5.7 2.34e+01 -7.2 1.00e+00 1.00e+00h 1\n", - " 27 -1.8546477e+01 1.85e-01 1.29e-01 -5.7 9.39e+01 -7.6 1.00e+00 5.95e-01h 1\n", - " 28 -1.8546576e+01 2.34e-02 6.92e-03 -5.7 2.28e+01 - 1.00e+00 1.00e+00f 1\n", - " 29 -1.8546954e+01 2.55e-02 9.41e-03 -5.7 2.37e+01 - 1.00e+00 9.61e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -1.8546953e+01 3.64e-05 1.38e-05 -5.7 9.21e-01 - 1.00e+00 1.00e+00h 1\n", - " 31 -1.8546953e+01 3.38e-09 1.41e-09 -5.7 8.86e-03 - 1.00e+00 1.00e+00h 1\n", - " 32 -1.8548230e+01 1.41e-03 1.43e-04 -8.6 1.62e+00 - 9.94e-01 9.96e-01f 1\n", - " 33 -1.8548236e+01 9.75e-08 1.46e-08 -8.6 9.43e-03 - 1.00e+00 1.00e+00h 1\n", - " 34 -1.8548236e+01 9.09e-13 1.54e-13 -8.6 8.26e-07 -8.1 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.8548235998334103e+01 -1.8548235998334103e+01\n", - "Dual infeasibility......: 1.5371362792196526e-13 1.5371362792196526e-13\n", - "Constraint violation....: 9.0949470177292824e-13 9.0949470177292824e-13\n", - "Complementarity.........: 2.5059035679086560e-09 2.5059035679086560e-09\n", - "Overall NLP error.......: 2.5059035679086560e-09 2.5059035679086560e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 35\n", - "Number of objective gradient evaluations = 35\n", - "Number of equality constraint evaluations = 35\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 35\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.987\n", - "Total CPU secs in NLP function evaluations = 0.017\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.54e+01 4.20e+01 -1.0 4.92e+01 - 4.94e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 3.23e-01 3.50e+02 -1.0 2.84e+01 - 2.68e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 9.11e-06 2.34e+02 -1.0 1.90e-01 - 9.91e-01 1.00e+00h 1\n", - " 5 0.0000000e+00 3.13e-13 1.00e-06 -1.0 6.34e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.2971319830862150e-13 3.1263880373444408e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.2971319830862150e-13 3.1263880373444408e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.056\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 9.91e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 6.88e+02 3.85e+02 -1.0 9.91e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 9.67e+01 5.99e+01 -1.0 9.63e+02 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.26e+00 2.06e+00 -1.0 7.88e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.24e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393643)\n", - " 5 0.0000000e+00 1.82e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8189894035458565e-12 1.8189894035458565e-12\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8189894035458565e-12 1.8189894035458565e-12\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -2.1041036e+01 8.42e+02 1.22e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303234)\n", - " 1 -2.1145524e+01 4.14e+02 4.86e+00 -1.0 2.53e+01 - 9.57e-01 5.02e-01h 1\n", - " 2 -2.1235982e+01 4.29e+00 1.97e-01 -1.0 3.69e+00 - 9.85e-01 1.00e+00f 1\n", - " 3 -2.1196637e+01 7.15e+00 3.48e+00 -1.0 1.06e+02 - 1.00e+00 1.00e+00f 1\n", - " 4 -2.1182737e+01 1.81e+01 1.49e+00 -1.0 1.80e+02 - 1.00e+00 1.00e+00h 1\n", - " 5 -2.1196659e+01 9.63e-02 8.45e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 6 -2.1196935e+01 1.22e-04 1.64e-03 -2.5 3.09e-01 - 1.00e+00 1.00e+00h 1\n", - " 7 -2.1197254e+01 5.64e-03 3.71e-04 -3.8 1.98e+00 - 1.00e+00 1.00e+00h 1\n", - " 8 -2.1197442e+01 2.71e-04 1.49e-04 -3.8 9.31e-01 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -2.1197814e+01 1.12e-03 1.02e-04 -5.7 1.87e+00 -4.5 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -2.1198435e+01 3.31e-03 1.47e-04 -5.7 3.66e+00 -5.0 1.00e+00 8.46e-01h 1\n", - " 11 -2.1198609e+01 2.27e-03 4.45e-04 -5.7 5.23e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 12 -2.1199224e+01 2.27e-02 1.60e-03 -5.7 1.87e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 13 -2.1201389e+01 2.97e-01 1.99e-02 -5.7 4.95e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 14 -2.1215482e+01 2.18e+01 3.79e+00 -5.7 1.77e+02 -6.9 4.71e-01 3.13e-01h 1\n", - " 15r-2.1215482e+01 2.18e+01 9.99e+02 1.3 0.00e+00 -7.3 0.00e+00 2.37e-07R 5\n", - " 16r-2.1215529e+01 2.18e+01 9.65e+03 1.3 7.99e+05 - 1.23e-05 4.88e-07f 1\n", - " 17r-2.1332007e+01 5.50e+00 9.67e+03 1.3 2.14e+04 - 7.52e-05 1.01e-03f 1\n", - " 18 -2.1341179e+01 6.06e+00 2.11e-01 -5.7 1.51e+03 - 9.35e-02 1.40e-02h 1\n", - " 19 -2.1348895e+01 6.45e+00 1.98e-01 -5.7 2.96e+03 - 8.78e-02 6.18e-02h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -2.1348057e+01 6.10e+00 1.44e+00 -5.7 3.35e+02 -7.8 1.00e+00 8.82e-02h 1\n", - " 21 -2.1337687e+01 5.02e+00 8.30e-01 -5.7 2.16e+02 -8.3 1.00e+00 3.48e-01h 1\n", - " 22 -2.1256596e+01 2.16e+01 7.80e+03 -5.7 6.01e+02 -7.9 7.05e-05 3.63e-01h 1\n", - " 23 -2.1229440e+01 6.42e+00 1.69e+03 -5.7 5.09e+01 -3.8 3.31e-01 7.83e-01h 1\n", - " 24 -2.1225416e+01 7.91e-02 1.07e+00 -5.7 4.92e+00 -4.3 1.85e-04 1.00e+00h 1\n", - " 25 -2.1234904e+01 2.01e-01 1.93e-02 -5.7 1.80e+01 -4.8 1.00e+00 1.00e+00h 1\n", - " 26 -2.1254412e+01 9.46e-01 1.46e-02 -5.7 5.59e+01 -5.3 1.00e+00 6.93e-01h 1\n", - " 27 -2.1288915e+01 3.38e+00 4.31e-02 -5.7 1.68e+02 -5.7 1.00e+00 4.35e-01f 1\n", - " 28 -2.1310182e+01 3.91e+00 4.77e-02 -5.7 3.62e+02 -6.2 1.00e+00 1.26e-01f 1\n", - " 29 -2.1313014e+01 6.05e-02 3.51e-02 -5.7 7.03e+00 -6.7 8.65e-02 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (332877)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -2.1314539e+01 1.81e-01 7.17e-02 -5.7 2.17e+01 -7.2 1.00e+00 4.80e-01h 1\n", - " 31 -2.1322536e+01 5.42e+00 6.40e+01 -5.7 1.14e+03 - 4.87e-05 5.01e-02h 2\n", - " 32 -2.1318925e+01 6.40e-02 1.01e+00 -5.7 1.52e+00 - 6.09e-02 1.00e+00h 1\n", - " 33 -2.1319551e+01 1.97e-03 3.61e-04 -5.7 1.05e+00 - 1.00e+00 1.00e+00h 1\n", - " 34 -2.1319541e+01 3.42e-06 6.83e-07 -5.7 2.81e-01 - 1.00e+00 1.00e+00h 1\n", - " 35 -2.1320810e+01 5.55e-03 3.24e-04 -8.6 3.28e+00 - 9.87e-01 9.90e-01h 1\n", - " 36 -2.1320824e+01 1.71e-06 1.42e-07 -8.6 4.12e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (355912)\n", - "Reallocating memory for MA57: lfact (403977)\n", - " 37 -2.1320824e+01 4.55e-13 1.22e-13 -8.6 1.29e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 37\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -2.1320823847268578e+01 -2.1320823847268578e+01\n", - "Dual infeasibility......: 1.2172728103276853e-13 1.2172728103276853e-13\n", - "Constraint violation....: 4.5474735088646412e-13 4.5474735088646412e-13\n", - "Complementarity.........: 2.5059035644843673e-09 2.5059035644843673e-09\n", - "Overall NLP error.......: 2.5059035644843673e-09 2.5059035644843673e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 45\n", - "Number of objective gradient evaluations = 37\n", - "Number of equality constraint evaluations = 45\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 39\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 37\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.000\n", - "Total CPU secs in NLP function evaluations = 0.051\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.54e+01 4.20e+01 -1.0 4.92e+01 - 4.94e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 3.11e-01 3.50e+02 -1.0 2.84e+01 - 2.68e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 8.56e-06 2.34e+02 -1.0 1.82e-01 - 9.91e-01 1.00e+00h 1\n", - " 5 0.0000000e+00 2.97e-13 1.00e-06 -1.0 5.95e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.2308013703147609e-13 2.9665159217984183e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.2308013703147609e-13 2.9665159217984183e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.069\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.03e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 7.92e+02 3.85e+02 -1.0 2.03e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 9.78e+01 5.99e+01 -1.0 1.07e+03 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.27e+00 2.06e+00 -1.0 7.91e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.25e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393908)\n", - " 5 0.0000000e+00 4.55e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2737367544323206e-13 4.5474735088646412e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2737367544323206e-13 4.5474735088646412e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.118\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -2.3957786e+01 8.42e+02 1.15e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303016)\n", - " 1 -2.4009165e+01 4.16e+02 5.03e+00 -1.0 2.52e+01 - 9.74e-01 5.03e-01h 1\n", - " 2 -2.4053676e+01 2.23e+00 1.57e-01 -1.0 6.82e+00 - 9.83e-01 1.00e+00f 1\n", - " 3 -2.4049598e+01 2.63e-01 1.04e-01 -1.7 2.03e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -2.4031404e+01 5.51e+00 8.43e-01 -1.7 1.66e+02 - 1.00e+00 9.62e-01f 1\n", - " 5 -2.4031794e+01 9.63e+00 1.11e-01 -1.7 1.31e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -2.4034753e+01 9.12e-03 4.93e-03 -1.7 9.57e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -2.4034764e+01 5.23e-06 2.40e-04 -3.8 5.16e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (320596)\n", - " 8 -2.4036325e+01 4.61e-01 4.50e-02 -5.7 2.11e+01 - 8.48e-01 1.00e+00h 1\n", - " 9 -2.4036710e+01 3.52e-04 5.33e-04 -5.7 3.85e-01 -4.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -2.4036850e+01 6.00e-04 7.85e-05 -5.7 1.39e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 11 -2.4036956e+01 2.95e-04 4.05e-04 -5.7 1.52e+00 -5.0 1.00e+00 6.87e-01H 1\n", - " 12 -2.4036981e+01 2.11e-04 1.51e-04 -5.7 1.55e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 13 -2.4037122e+01 2.08e-03 9.42e-05 -5.7 8.97e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 14 -2.4037545e+01 1.84e-02 9.37e-04 -5.7 2.52e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 15 -2.4038911e+01 1.53e-01 1.30e-02 -5.7 7.03e+00 -6.9 1.00e+00 1.00e+00h 1\n", - " 16 -2.4039513e+01 1.71e-02 2.17e-03 -5.7 2.31e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 17 -2.4041456e+01 2.25e-01 5.40e-02 -5.7 1.12e+01 -6.9 1.00e+00 1.00e+00h 1\n", - " 18 -2.4042770e+01 5.07e-02 2.20e-02 -5.7 5.24e+00 -6.5 1.00e+00 1.00e+00h 1\n", - " 19 -2.4050544e+01 4.39e+00 1.42e+00 -5.7 4.13e+01 -7.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -2.4066468e+01 2.01e+00 5.80e-01 -5.7 6.98e+01 -6.5 1.00e+00 1.00e+00h 1\n", - " 21 -2.4093450e+01 6.18e+00 2.10e+00 -5.7 3.11e+02 -7.0 6.69e-01 3.36e-01h 1\n", - " 22 -2.4106017e+01 6.61e+00 2.16e+00 -5.7 7.31e+02 -7.5 1.00e+00 5.80e-02h 1\n", - " 23 -2.4143250e+01 1.35e+01 2.72e+00 -5.7 4.43e+02 -8.0 6.35e-01 3.17e-01h 1\n", - " 24 -2.4148932e+01 1.23e+01 2.04e+00 -5.7 2.31e+02 -8.4 7.03e-01 2.32e-01h 1\n", - " 25 -2.4151239e+01 1.14e+01 1.84e+00 -5.7 1.07e+03 -8.9 2.31e-01 9.52e-02h 1\n", - " 26 -2.4155618e+01 9.19e+00 6.95e-01 -5.7 1.24e+02 - 1.00e+00 7.89e-01f 1\n", - " 27 -2.4153220e+01 4.92e-01 8.71e-02 -5.7 2.88e+01 - 1.00e+00 1.00e+00h 1\n", - " 28 -2.4153102e+01 1.90e-02 1.51e-04 -5.7 1.19e+01 - 1.00e+00 1.00e+00h 1\n", - " 29 -2.4153101e+01 3.02e-05 6.13e-08 -5.7 4.80e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -2.4153101e+01 6.65e-10 1.93e-11 -5.7 2.26e-03 - 1.00e+00 1.00e+00h 1\n", - " 31 -2.4154362e+01 2.69e-02 4.53e-03 -8.6 1.45e+01 - 9.56e-01 1.00e+00f 1\n", - "Reallocating memory for MA57: lfact (345644)\n", - " 32 -2.4154374e+01 4.15e-04 2.66e-06 -8.6 1.84e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (384901)\n", - " 33 -2.4154374e+01 4.16e-07 6.54e-10 -8.6 5.84e-02 - 1.00e+00 1.00e+00h 1\n", - " 34 -2.4154374e+01 9.09e-13 1.27e-13 -8.6 3.70e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -2.4154373723270826e+01 -2.4154373723270826e+01\n", - "Dual infeasibility......: 1.2724980870831129e-13 1.2724980870831129e-13\n", - "Constraint violation....: 6.9129384604076763e-13 9.0949470177292824e-13\n", - "Complementarity.........: 2.5059035618469615e-09 2.5059035618469615e-09\n", - "Overall NLP error.......: 2.5059035618469615e-09 2.5059035618469615e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 36\n", - "Number of objective gradient evaluations = 35\n", - "Number of equality constraint evaluations = 36\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 35\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.007\n", - "Total CPU secs in NLP function evaluations = 0.010\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.24e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 5.76e+01 3.85e+02 -1.0 3.24e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 2.68e+01 4.57e+02 -1.0 7.19e+01 - 5.57e-02 9.90e-01h 1\n", - " 3 0.0000000e+00 1.69e-01 1.26e+02 -1.0 1.53e+01 - 4.90e-01 9.91e-01f 1\n", - " 4 0.0000000e+00 6.46e-06 2.38e+02 -1.0 1.08e-01 - 9.91e-01 1.00e+00h 1\n", - " 5 0.0000000e+00 4.55e-13 1.00e-06 -1.0 3.54e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.9311082636750565e-13 4.5474735088646412e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.9311082636750565e-13 4.5474735088646412e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.071\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 4.10e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 9.98e+02 3.85e+02 -1.0 4.10e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 9.98e+01 5.99e+01 -1.0 1.27e+03 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.29e+00 2.06e+00 -1.0 7.95e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.27e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393985)\n", - " 5 0.0000000e+00 7.28e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.2759576141834259e-12 7.2759576141834259e-12\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.2759576141834259e-12 7.2759576141834259e-12\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -2.6831720e+01 8.42e+02 1.11e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303196)\n", - " 1 -2.6856995e+01 4.17e+02 5.11e+00 -1.0 2.52e+01 - 9.83e-01 5.03e-01h 1\n", - " 2 -2.6878754e+01 1.15e+00 1.70e-01 -1.0 1.35e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -2.6876993e+01 2.41e-01 8.47e-02 -1.7 2.32e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -2.6868640e+01 5.70e+00 3.70e-01 -1.7 1.61e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -2.6869023e+01 8.10e+00 4.89e-02 -1.7 1.19e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -2.6870266e+01 5.51e-03 2.48e-03 -1.7 8.49e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -2.6870267e+01 1.82e-06 9.94e-05 -3.8 3.28e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -2.6870637e+01 1.33e-01 5.56e-03 -5.7 1.03e+01 - 9.45e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (320847)\n", - " 9 -2.6870673e+01 2.67e-05 3.18e-05 -5.7 3.18e-01 -4.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -2.6870728e+01 3.86e-04 3.70e-05 -5.7 1.11e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 11 -2.6870877e+01 2.81e-03 3.33e-05 -5.7 3.00e+00 -5.0 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (337659)\n", - " 12 -2.6870878e+01 1.08e-04 7.14e-05 -5.7 8.84e-02 -5.4 1.00e+00 1.00e+00h 1\n", - " 13 -2.6870919e+01 1.06e-03 1.84e-05 -5.7 6.15e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 14 -2.6871022e+01 9.59e-03 1.61e-04 -5.7 1.37e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 15 -2.6871350e+01 1.01e-01 1.67e-03 -5.7 3.88e+00 -6.9 1.00e+00 1.00e+00h 1\n", - " 16 -2.6872711e+01 2.39e+00 4.78e-02 -5.7 1.44e+01 -7.3 1.00e+00 1.00e+00h 1\n", - " 17 -2.6874054e+01 5.83e-01 1.31e-02 -5.7 1.62e+01 -6.9 1.00e+00 1.00e+00h 1\n", - " 18 -2.6879134e+01 1.19e+01 4.46e-01 -5.7 1.13e+02 -7.4 1.00e+00 5.07e-01h 1\n", - " 19 -2.6887284e+01 4.11e+00 1.69e-01 -5.7 7.00e+01 -7.0 1.00e+00 9.59e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -2.6892052e+01 4.46e+00 1.97e-01 -5.7 1.88e+02 -7.4 1.00e+00 1.65e-01f 1\n", - " 21 -2.6894657e+01 1.59e+00 4.78e-02 -5.7 2.29e+01 -7.9 9.98e-01 8.13e-01f 1\n", - " 22 -2.6895685e+01 1.03e-01 2.03e-03 -5.7 1.09e+01 -7.5 1.00e+00 1.00e+00f 1\n", - " 23 -2.6896013e+01 3.73e-02 4.31e-03 -5.7 8.81e+00 -8.0 1.00e+00 1.00e+00h 1\n", - " 24 -2.6896032e+01 1.65e-03 4.30e-04 -5.7 1.77e+00 -7.5 1.00e+00 1.00e+00h 1\n", - " 25 -2.6896510e+01 5.88e+00 1.25e+00 -5.7 9.18e+01 -8.0 1.00e+00 1.00e+00h 1\n", - " 26 -2.6897324e+01 2.35e+00 1.70e-01 -5.7 8.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 27 -2.6899093e+01 2.49e-01 4.48e-02 -5.7 3.94e+01 - 1.00e+00 9.34e-01h 1\n", - " 28 -2.6898971e+01 7.46e-02 2.34e-03 -5.7 2.43e+01 - 1.00e+00 1.00e+00f 1\n", - " 29 -2.6898969e+01 4.09e-03 9.27e-06 -5.7 5.54e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -2.6898969e+01 2.54e-05 4.67e-08 -5.7 4.39e-01 - 1.00e+00 1.00e+00h 1\n", - " 31 -2.6898969e+01 8.92e-10 1.97e-11 -5.7 2.60e-03 - 1.00e+00 1.00e+00h 1\n", - " 32 -2.6900308e+01 1.16e-01 2.77e-03 -8.6 1.79e+01 - 9.13e-01 9.53e-01f 1\n", - " 33 -2.6900393e+01 3.09e-03 1.29e-04 -8.6 4.98e+00 - 1.00e+00 1.00e+00h 1\n", - " 34 -2.6900395e+01 2.18e-04 1.36e-06 -8.6 1.34e+00 - 1.00e+00 1.00e+00h 1\n", - " 35 -2.6900395e+01 9.33e-07 2.55e-09 -8.6 8.75e-02 - 1.00e+00 1.00e+00h 1\n", - " 36 -2.6900395e+01 1.48e-11 5.99e-14 -8.6 3.48e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 36\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -2.6900395275199973e+01 -2.6900395275199973e+01\n", - "Dual infeasibility......: 5.9903245874163696e-14 5.9903245874163696e-14\n", - "Constraint violation....: 1.4777956636180534e-11 1.4777956636180534e-11\n", - "Complementarity.........: 2.5059038382096498e-09 2.5059038382096498e-09\n", - "Overall NLP error.......: 2.5059038382096498e-09 2.5059038382096498e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 37\n", - "Number of objective gradient evaluations = 37\n", - "Number of equality constraint evaluations = 37\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 37\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 36\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.085\n", - "Total CPU secs in NLP function evaluations = 0.056\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.53e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.54e-02 3.84e+00 -1.0 1.38e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.22e-04 3.52e+00 -1.0 1.38e-02 - 1.00e+00 9.92e-01h 1\n", - " 4 0.0000000e+00 7.74e-13 1.01e-06 -1.0 1.10e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.7449158197850920e-13 7.7449158197850920e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.7449158197850920e-13 7.7449158197850920e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.049\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 8.26e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 1.41e+03 3.85e+02 -1.0 8.26e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.04e+02 5.99e+01 -1.0 1.69e+03 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.33e+00 2.06e+00 -1.0 8.05e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.31e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393607)\n", - " 5 0.0000000e+00 9.09e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0949470177292824e-13 9.0949470177292824e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0949470177292824e-13 9.0949470177292824e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -2.9638946e+01 8.42e+02 1.08e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303234)\n", - " 1 -2.9651536e+01 4.17e+02 5.15e+00 -1.0 2.52e+01 - 9.87e-01 5.03e-01h 1\n", - " 2 -2.9662204e+01 5.88e-01 1.69e-01 -1.0 1.90e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -2.9661372e+01 2.28e-01 8.72e-02 -1.7 2.54e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -2.9657366e+01 5.59e+00 1.74e-01 -1.7 1.57e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -2.9657597e+01 7.45e+00 2.43e-02 -1.7 1.12e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -2.9658155e+01 9.80e-03 5.94e-04 -1.7 9.51e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -2.9658157e+01 2.42e-07 4.73e-05 -3.8 1.06e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (324542)\n", - " 8 -2.9658248e+01 2.96e-02 2.07e-03 -5.7 5.06e+00 - 9.80e-01 1.00e+00h 1\n", - " 9 -2.9658255e+01 8.09e-06 1.82e-05 -5.7 1.82e-01 -4.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -2.9658269e+01 1.10e-04 1.97e-05 -8.6 5.90e-01 -4.5 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (353780)\n", - " 11 -2.9658314e+01 1.01e-03 1.99e-05 -8.6 1.79e+00 -5.0 1.00e+00 1.00e+00h 1\n", - " 12 -2.9658384e+01 2.94e-03 1.98e-05 -8.6 5.34e+00 -5.4 1.00e+00 5.24e-01h 1\n", - " 13 -2.9658390e+01 2.14e-04 6.05e-05 -8.6 1.92e-01 -5.9 1.00e+00 1.00e+00f 1\n", - " 14 -2.9658414e+01 2.03e-03 1.72e-05 -8.6 7.84e-01 -6.4 1.00e+00 1.00e+00h 1\n", - " 15 -2.9658485e+01 1.95e-02 1.65e-04 -8.6 2.16e+00 -6.9 1.00e+00 1.00e+00h 1\n", - " 16 -2.9658723e+01 2.33e-01 1.94e-03 -8.6 6.13e+00 -7.3 1.00e+00 1.00e+00h 1\n", - " 17 -2.9659707e+01 2.00e+01 4.71e-01 -8.6 4.15e+02 -7.8 2.10e-01 1.32e-01h 1\n", - " 18 -2.9661723e+01 1.08e+01 6.12e+00 -8.6 7.98e+01 -7.4 1.00e+00 5.36e-01h 1\n", - " 19 -2.9662944e+01 1.03e+01 8.86e+00 -8.6 2.03e+02 -7.9 7.79e-01 1.08e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -2.9664685e+01 1.03e+01 1.59e+01 -8.6 1.87e+02 -8.3 1.00e+00 1.08e-01h 1\n", - " 21 -2.9668199e+01 7.67e+00 4.66e+00 -8.6 1.09e+02 -7.9 1.00e+00 5.18e-01h 1\n", - " 22 -2.9669825e+01 7.05e+00 2.58e+01 -8.6 2.15e+02 -8.4 1.00e+00 1.50e-01h 1\n", - " 23 -2.9670730e+01 3.22e+00 2.25e+01 -8.6 3.00e+01 -8.0 4.59e-01 5.76e-01h 1\n", - " 24 -2.9672420e+01 2.48e+01 1.63e+01 -8.6 4.62e+02 -8.4 3.30e-01 2.77e-01f 1\n", - " 25 -2.9671141e+01 6.69e+00 4.35e+00 -8.6 2.59e+01 -8.0 1.00e+00 7.33e-01h 1\n", - " 26 -2.9672562e+01 4.65e-01 2.66e-02 -8.6 2.69e+01 -8.5 1.00e+00 1.00e+00h 1\n", - " 27 -2.9672664e+01 4.46e-01 1.65e-02 -8.6 1.35e+02 -9.0 1.00e+00 4.39e-01h 1\n", - " 28 -2.9672722e+01 1.68e-01 1.61e-03 -8.6 1.93e+01 - 1.00e+00 1.00e+00h 1\n", - " 29 -2.9672724e+01 1.86e-02 5.75e-04 -8.6 2.08e+01 - 1.00e+00 9.29e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -2.9672723e+01 3.34e-06 7.50e-08 -8.6 2.03e-02 - 1.00e+00 1.00e+00h 1\n", - " 31 -2.9672723e+01 1.46e-11 9.19e-14 -8.6 1.60e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 31\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -2.9672723137182857e+01 -2.9672723137182857e+01\n", - "Dual infeasibility......: 9.1912354482113998e-14 9.1912354482113998e-14\n", - "Constraint violation....: 3.6379788070917130e-12 1.4551915228366852e-11\n", - "Complementarity.........: 2.5059038164605147e-09 2.5059038164605147e-09\n", - "Overall NLP error.......: 2.5059038164605147e-09 2.5059038164605147e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 32\n", - "Number of objective gradient evaluations = 32\n", - "Number of equality constraint evaluations = 32\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 32\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 31\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.978\n", - "Total CPU secs in NLP function evaluations = 0.022\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.44e-01 3.41e+02 -1.0 2.83e+01 - 2.90e-01 9.94e-01h 1\n", - " 4 0.0000000e+00 2.63e-06 2.33e+02 -1.0 7.93e-02 - 9.91e-01 1.00e+00h 1\n", - " 5 0.0000000e+00 2.49e-13 1.00e-06 -1.0 1.80e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.0318095320003983e-13 2.4868995751603507e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.0318095320003983e-13 2.4868995751603507e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.056\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.66e+05 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 2.25e+03 3.85e+02 -1.0 1.66e+05 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.12e+02 5.99e+01 -1.0 2.52e+03 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.41e+00 2.06e+00 -1.0 8.23e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.39e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393985)\n", - " 5 0.0000000e+00 2.91e-11 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.9103830456733704e-11 2.9103830456733704e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.9103830456733704e-11 2.9103830456733704e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.109\n", - "Total CPU secs in NLP function evaluations = 0.010\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -3.2428486e+01 8.42e+02 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303234)\n", - " 1 -3.2434768e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", - " 2 -3.2440069e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -3.2439664e+01 2.27e-01 8.67e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -3.2437689e+01 5.57e+00 1.18e-01 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -3.2437810e+01 7.15e+00 1.20e-02 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -3.2438076e+01 1.07e-02 4.29e-04 -1.7 9.35e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -3.2438077e+01 3.69e-07 2.81e-05 -3.8 6.32e-03 - 1.00e+00 1.00e+00h 1\n", - " 8 -3.2438078e+01 1.83e-06 7.60e-06 -5.7 7.60e-02 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -3.2438082e+01 2.75e-05 9.82e-06 -8.6 2.95e-01 -4.5 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -3.2438093e+01 2.57e-04 1.00e-05 -8.6 9.02e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 11 -3.2438127e+01 2.32e-03 1.00e-05 -8.6 2.71e+00 -5.4 1.00e+00 1.00e+00h 1\n", - " 12 -3.2438152e+01 3.01e-03 1.00e-05 -8.6 8.06e+00 -5.9 1.00e+00 2.49e-01h 1\n", - " 13 -3.2438155e+01 4.60e-04 4.53e-05 -8.6 2.32e-01 -6.4 1.00e+00 1.00e+00f 1\n", - " 14 -3.2438173e+01 4.53e-03 1.89e-05 -8.6 1.27e+00 -6.9 1.00e+00 1.00e+00h 1\n", - " 15 -3.2438225e+01 4.49e-02 1.89e-04 -8.6 3.33e+00 -7.3 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (333035)\n", - " 16 -3.2438415e+01 6.88e-01 2.78e-03 -8.6 9.07e+00 -7.8 1.00e+00 1.00e+00h 1\n", - " 17 -3.2438526e+01 1.13e-01 3.98e-04 -8.6 3.08e+00 -7.4 1.00e+00 1.00e+00h 1\n", - " 18 -3.2438959e+01 3.03e+00 2.02e-02 -8.6 1.89e+01 -7.9 1.00e+00 1.00e+00h 1\n", - " 19 -3.2439451e+01 9.31e-01 4.43e-03 -8.6 2.65e+01 -7.4 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -3.2440256e+01 3.61e+00 2.46e-02 -8.6 2.05e+02 -7.9 9.03e-01 1.92e-01h 1\n", - " 21 -3.2440820e+01 2.54e+00 1.86e-02 -8.6 4.61e+01 -7.5 1.00e+00 4.20e-01f 1\n", - " 22 -3.2443038e+01 8.60e+00 1.12e-01 -8.6 2.61e+02 -8.0 8.80e-01 2.74e-01f 1\n", - " 23 -3.2443317e+01 8.60e+00 1.12e-01 -8.6 1.27e+03 -8.4 5.04e-01 5.61e-03h 1\n", - " 24 -3.2444082e+01 2.43e+00 2.51e-02 -8.6 1.87e+01 -8.0 1.42e-01 7.76e-01h 1\n", - " 25 -3.2444206e+01 2.00e+00 2.04e-02 -8.6 2.84e+01 -8.5 8.77e-01 1.87e-01f 1\n", - " 26 -3.2444524e+01 1.50e-01 2.01e-03 -8.6 1.06e+01 -8.1 1.00e+00 1.00e+00h 1\n", - " 27 -3.2444530e+01 1.48e-01 1.97e-03 -8.6 3.53e+01 -8.5 1.00e+00 1.95e-02h 1\n", - " 28 -3.2444603e+01 2.35e-02 9.67e-04 -8.6 9.31e+00 -8.1 1.00e+00 1.00e+00f 1\n", - " 29 -3.2444869e+01 3.57e+00 1.39e-01 -8.6 8.64e+01 -8.6 1.00e+00 6.85e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -3.2445180e+01 2.78e+00 5.43e-02 -8.6 2.44e+02 -9.1 1.00e+00 6.18e-01f 1\n", - " 31 -3.2445337e+01 1.07e+00 1.03e-02 -8.6 5.66e+01 - 1.00e+00 1.00e+00h 1\n", - " 32 -3.2445329e+01 4.67e-01 4.82e-03 -8.6 9.94e+01 - 1.00e+00 5.69e-01h 1\n", - " 33 -3.2445311e+01 1.99e-03 3.70e-05 -8.6 9.19e-01 - 1.00e+00 1.00e+00h 1\n", - " 34 -3.2445311e+01 1.62e-07 1.29e-09 -8.6 1.08e-02 - 1.00e+00 1.00e+00h 1\n", - " 35 -3.2445311e+01 5.82e-11 2.86e-14 -8.6 7.59e-07 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 35\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -3.2445310986118486e+01 -3.2445310986118486e+01\n", - "Dual infeasibility......: 2.8629516867220174e-14 2.8629516867220174e-14\n", - "Constraint violation....: 2.9103830456733704e-11 5.8207660913467407e-11\n", - "Complementarity.........: 2.5059035597432385e-09 2.5059035597432385e-09\n", - "Overall NLP error.......: 2.5059035597432385e-09 2.5059035597432385e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 36\n", - "Number of objective gradient evaluations = 36\n", - "Number of equality constraint evaluations = 36\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 36\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 35\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.090\n", - "Total CPU secs in NLP function evaluations = 0.019\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.94e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.70e-02 3.43e+02 -1.0 2.83e+01 - 2.90e-01 9.98e-01h 1\n", - " 4 0.0000000e+00 7.99e-08 2.33e+02 -1.0 4.00e-02 - 9.91e-01 1.00e+00h 1\n", - " 5 0.0000000e+00 2.63e-13 1.00e-06 -1.0 7.80e-08 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.2874055091167042e-13 2.6290081223123707e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.2874055091167042e-13 2.6290081223123707e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.048\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.32e+05 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 3.91e+03 3.85e+02 -1.0 3.32e+05 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.29e+02 5.99e+01 -1.0 4.18e+03 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.58e+00 2.06e+00 -1.0 8.61e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.56e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393774)\n", - " 5 0.0000000e+00 1.82e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8189894035458565e-12 1.8189894035458565e-12\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8189894035458565e-12 1.8189894035458565e-12\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", - "Total CPU secs in NLP function evaluations = 0.017\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -3.5209502e+01 8.42e+02 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303016)\n", - " 1 -3.5212641e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", - " 2 -3.5215292e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -3.5215089e+01 2.27e-01 8.53e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -3.5214101e+01 5.57e+00 9.59e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -3.5214161e+01 7.15e+00 6.15e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -3.5214294e+01 1.06e-02 4.14e-04 -1.7 9.34e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -3.5214295e+01 7.51e-07 1.89e-05 -3.8 1.17e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -3.5214300e+01 1.80e-03 1.13e-05 -5.7 1.27e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (327848)\n", - " 9 -3.5214301e+01 6.97e-07 4.87e-06 -5.7 4.87e-02 -4.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -3.5214302e+01 7.02e-06 4.97e-06 -8.6 1.49e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 11 -3.5214305e+01 6.46e-05 5.02e-06 -8.6 4.52e-01 -5.0 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (348486)\n", - " 12 -3.5214313e+01 5.82e-04 5.03e-06 -8.6 1.36e+00 -5.4 1.00e+00 1.00e+00h 1\n", - " 13 -3.5214337e+01 4.65e-03 5.02e-06 -8.6 4.07e+00 -5.9 1.00e+00 9.40e-01h 1\n", - " 14 -3.5214337e+01 4.50e-03 2.33e-04 -8.6 1.47e+00 -6.4 1.00e+00 3.12e-02f 6\n", - " 15 -3.5214341e+01 1.09e-03 3.28e-05 -8.6 6.15e-01 -6.9 1.00e+00 1.00e+00h 1\n", - " 16 -3.5214353e+01 9.95e-03 2.09e-05 -8.6 1.69e+00 -7.3 1.00e+00 1.00e+00h 1\n", - " 17 -3.5214394e+01 1.07e-01 2.26e-04 -8.6 4.92e+00 -7.8 1.00e+00 1.00e+00h 1\n", - " 18 -3.5214572e+01 3.42e+00 7.71e-03 -8.6 1.68e+01 -8.3 1.00e+00 1.00e+00h 1\n", - " 19 -3.5214789e+01 1.03e+00 2.63e-03 -8.6 2.34e+01 -7.9 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -3.5215305e+01 8.47e+00 3.52e-02 -8.6 5.34e+02 -8.3 2.91e-01 1.01e-01h 1\n", - " 21 -3.5215730e+01 6.31e+00 2.51e-02 -8.6 7.99e+01 -7.9 1.00e+00 3.57e-01f 1\n", - " 22 -3.5216694e+01 1.02e+01 5.63e-02 -8.6 7.73e+02 -8.4 3.55e-01 7.78e-02h 1\n", - " 23 -3.5216797e+01 9.76e+00 5.36e-02 -8.6 1.42e+02 -8.9 1.04e-01 4.84e-02h 1\n", - " 24 -3.5216885e+01 8.53e+00 4.68e-02 -8.6 2.74e+01 -8.4 5.30e-01 1.28e-01h 1\n", - " 25 -3.5217124e+01 6.99e+00 3.66e-02 -8.6 5.63e+01 -8.9 3.25e-01 2.16e-01h 1\n", - " 26 -3.5217494e+01 4.51e-01 1.53e-03 -8.6 1.69e+01 -8.5 1.00e+00 9.89e-01f 1\n", - " 27 -3.5217762e+01 3.34e+01 5.83e-01 -8.6 2.98e+02 -9.0 3.79e-01 5.84e-01f 1\n", - " 28 -3.5217782e+01 3.08e+01 5.37e-01 -8.6 9.68e+01 -8.5 5.35e-01 8.04e-02h 1\n", - " 29 -3.5215828e+01 2.37e+01 4.05e-01 -8.6 4.07e+01 -8.1 2.51e-02 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -3.5216161e+01 1.84e+01 3.12e-01 -8.6 2.64e+01 -8.6 8.03e-01 2.30e-01h 1\n", - " 31 -3.5217419e+01 3.16e+00 2.96e-02 -8.6 2.66e+01 -9.1 1.20e-04 1.00e+00f 1\n", - " 32 -3.5217481e+01 3.12e+00 2.90e-02 -8.6 1.92e+02 -9.6 4.18e-01 3.25e-02h 1\n", - " 33 -3.5217730e+01 3.96e+00 6.86e-02 -8.6 1.96e+02 -10.0 2.65e-07 1.67e-01h 1\n", - " 34 -3.5218174e+01 1.05e+01 5.09e-02 -8.6 6.76e+01 - 4.79e-01 1.00e+00f 1\n", - " 35 -3.5218144e+01 9.56e+00 4.62e-02 -8.6 5.60e+02 - 6.27e-01 9.14e-02h 1\n", - " 36 -3.5217875e+01 1.29e-01 6.80e-03 -8.6 1.14e+01 - 1.00e+00 1.00e+00h 1\n", - " 37 -3.5217899e+01 1.43e-02 9.14e-05 -8.6 2.93e+00 - 1.00e+00 1.00e+00h 1\n", - " 38 -3.5217899e+01 1.12e-05 9.11e-08 -8.6 7.12e-02 - 1.00e+00 1.00e+00h 1\n", - " 39 -3.5217899e+01 5.82e-11 8.02e-14 -8.6 6.30e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 39\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -3.5217898835055578e+01 -3.5217898835055578e+01\n", - "Dual infeasibility......: 8.0154814536833473e-14 8.0154814536833473e-14\n", - "Constraint violation....: 5.8207660913467407e-11 5.8207660913467407e-11\n", - "Complementarity.........: 2.5059035610674620e-09 2.5059035610674620e-09\n", - "Overall NLP error.......: 2.5059035610674620e-09 2.5059035610674620e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 45\n", - "Number of objective gradient evaluations = 40\n", - "Number of equality constraint evaluations = 45\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 40\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 39\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.271\n", - "Total CPU secs in NLP function evaluations = 0.044\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 4.2\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.93e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.18e-01 3.44e+02 -1.0 2.83e+01 - 2.89e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 7.85e-11 1.38e+02 -1.0 8.41e-02 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.8493656019418268e-11 7.8493656019418268e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.8493656019418268e-11 7.8493656019418268e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.062\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.64e+05 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 7.23e+03 3.85e+02 -1.0 6.64e+05 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.62e+02 5.99e+01 -1.0 7.51e+03 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.91e+00 2.06e+00 -1.0 9.36e+01 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.89e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393697)\n", - " 5 0.0000000e+00 7.28e-12 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.2759576141834259e-12 7.2759576141834259e-12\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.2759576141834259e-12 7.2759576141834259e-12\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -3.7986293e+01 8.42e+02 1.03e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303122)\n", - " 1 -3.7987862e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", - " 2 -3.7989187e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -3.7989086e+01 2.27e-01 8.49e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -3.7988591e+01 5.57e+00 8.46e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -3.7988622e+01 7.15e+00 3.66e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -3.7988688e+01 1.06e-02 4.07e-04 -1.7 9.34e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -3.7988689e+01 1.02e-06 1.41e-05 -3.8 1.65e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -3.7988690e+01 4.48e-04 5.42e-06 -5.7 6.35e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (324149)\n", - " 9 -3.7988690e+01 1.84e-07 2.46e-06 -5.7 2.46e-02 -4.0 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -3.7988690e+01 1.76e-06 2.49e-06 -8.6 7.46e-02 -4.5 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (343489)\n", - " 11 -3.7988691e+01 1.62e-05 2.51e-06 -8.6 2.26e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 12 -3.7988693e+01 1.46e-04 2.51e-06 -8.6 6.79e-01 -5.4 1.00e+00 1.00e+00h 1\n", - " 13 -3.7988699e+01 1.31e-03 2.51e-06 -8.6 2.04e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 14 -3.7988708e+01 3.29e-03 2.51e-06 -8.6 6.08e+00 -6.4 1.00e+00 4.72e-01h 1\n", - " 15 -3.7988708e+01 2.88e-03 9.75e-05 -8.6 7.36e-01 -6.9 1.00e+00 1.25e-01f 4\n", - " 16 -3.7988711e+01 2.52e-03 2.24e-05 -8.6 9.76e-01 -7.3 1.00e+00 1.00e+00h 1\n", - " 17 -3.7988721e+01 2.30e-02 2.42e-05 -8.6 2.53e+00 -7.8 1.00e+00 1.00e+00h 1\n", - " 18 -3.7988753e+01 2.83e-01 2.94e-04 -8.6 7.23e+00 -8.3 1.00e+00 1.00e+00h 1\n", - " 19 -3.7988768e+01 4.05e-02 4.12e-05 -8.6 1.67e+00 -7.9 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -3.7988818e+01 6.38e-01 6.02e-04 -8.6 6.87e+00 -8.3 1.00e+00 1.00e+00h 1\n", - " 21 -3.7988847e+01 1.12e-01 1.12e-04 -8.6 4.05e+00 -7.9 1.00e+00 1.00e+00h 1\n", - " 22 -3.7988962e+01 2.54e+00 4.68e-03 -8.6 1.86e+01 -8.4 1.00e+00 1.00e+00h 1\n", - " 23 -3.7989078e+01 7.34e-01 8.67e-04 -8.6 2.48e+01 -8.0 1.00e+00 1.00e+00h 1\n", - " 24 -3.7989232e+01 2.08e+00 3.41e-03 -8.6 1.45e+02 -8.4 1.00e+00 2.09e-01h 1\n", - " 25 -3.7989337e+01 1.43e+00 2.58e-03 -8.6 3.34e+01 -8.0 1.00e+00 4.49e-01f 1\n", - " 26 -3.7989784e+01 5.92e+00 1.95e-02 -8.6 1.61e+02 -8.5 1.00e+00 3.75e-01f 1\n", - " 27 -3.7990124e+01 2.81e+00 9.84e-03 -8.6 4.53e+01 -8.1 1.00e+00 6.70e-01f 1\n", - " 28 -3.7990143e+01 1.18e+00 3.83e-03 -8.6 1.17e+01 -8.5 1.00e+00 6.36e-01f 1\n", - " 29 -3.7990260e+01 5.81e-01 1.51e-03 -8.6 2.24e+01 -9.0 1.00e+00 6.81e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -3.7990293e+01 3.41e-02 1.10e-04 -8.6 6.65e+00 -8.6 1.00e+00 1.00e+00f 1\n", - " 31 -3.7990329e+01 1.38e-01 1.24e-03 -8.6 1.50e+01 -9.1 1.00e+00 1.00e+00h 1\n", - " 32 -3.7990335e+01 1.01e-01 8.90e-04 -8.6 9.80e+00 -8.7 1.00e+00 3.33e-01h 1\n", - " 33 -3.7990393e+01 2.39e+00 2.02e-02 -8.6 5.51e+01 -9.1 1.00e+00 7.80e-01f 1\n", - " 34 -3.7990507e+01 4.27e+00 1.27e-02 -8.6 7.38e+01 -9.6 1.00e+00 7.82e-01h 1\n", - " 35 -3.7990474e+01 4.87e-02 8.37e-04 -8.6 1.92e+01 -9.2 1.00e+00 1.00e+00h 1\n", - " 36 -3.7990485e+01 2.85e-01 3.77e-04 -8.6 6.89e+01 -9.7 1.00e+00 1.00e+00h 1\n", - " 37 -3.7990486e+01 2.82e-01 3.75e-04 -8.6 4.06e+02 -10.1 1.00e+00 1.75e-02h 1\n", - " 38 -3.7990487e+01 5.77e-04 7.14e-07 -8.6 6.52e-01 - 1.00e+00 1.00e+00h 1\n", - " 39 -3.7990487e+01 1.03e-05 3.01e-08 -8.6 4.89e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 -3.7990487e+01 1.16e-10 1.03e-13 -8.6 7.76e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 40\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -3.7990486683995655e+01 -3.7990486683995655e+01\n", - "Dual infeasibility......: 1.0349462628516265e-13 1.0349462628516265e-13\n", - "Constraint violation....: 2.5821123017522041e-11 1.1641532182693481e-10\n", - "Complementarity.........: 2.5059035596820578e-09 2.5059035596820578e-09\n", - "Overall NLP error.......: 2.5059035596820578e-09 2.5059035596820578e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 44\n", - "Number of objective gradient evaluations = 41\n", - "Number of equality constraint evaluations = 44\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 41\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 40\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.453\n", - "Total CPU secs in NLP function evaluations = 0.019\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 4.5\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.97e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.93e+01 3.85e+02 -1.0 3.97e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.51e+01 4.19e+01 -1.0 4.93e+01 - 4.96e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.16e-01 3.45e+02 -1.0 2.83e+01 - 2.89e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 7.46e-11 6.85e+01 -1.0 8.27e-02 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 7.4614092682168121e-11 7.4614092682168121e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 7.4614092682168121e-11 7.4614092682168121e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.064\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.33e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 1.39e+04 3.85e+02 -1.0 1.33e+06 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 2.29e+02 5.99e+01 -1.0 1.42e+04 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 5.56e+00 2.06e+00 -1.0 1.16e+02 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 4.54e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (394246)\n", - " 5 0.0000000e+00 2.33e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.3283064365386963e-10 2.3283064365386963e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.3283064365386963e-10 2.3283064365386963e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.108\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -4.0760980e+01 8.42e+02 1.02e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303234)\n", - " 1 -4.0761764e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.03e-01h 1\n", - " 2 -4.0762427e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -4.0762376e+01 2.27e-01 8.49e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -4.0762129e+01 5.57e+00 7.90e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -4.0762144e+01 7.15e+00 3.34e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -4.0762177e+01 1.06e-02 4.09e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -4.0762177e+01 1.17e-06 1.27e-05 -3.8 1.89e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -4.0762177e+01 1.11e-04 2.70e-06 -5.7 3.17e-01 - 1.00e+00 1.00e+00h 1\n", - " 9 -4.0762222e+01 5.53e-01 1.52e-03 -5.7 2.86e+01 - 1.00e+00 1.00e+00H 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -4.0762239e+01 1.77e-01 2.60e-03 -5.7 5.61e+01 - 1.00e+00 2.50e-01h 3\n", - " 11 -4.0762241e+01 3.40e-04 3.60e-05 -5.7 3.60e-01 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -4.0762241e+01 2.26e-07 8.96e-07 -5.7 2.69e-02 -4.5 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319066)\n", - " 13 -4.0762540e+01 3.15e+01 1.26e-01 -8.6 1.14e+02 - 3.56e-01 1.00e+00h 1\n", - " 14 -4.0763467e+01 6.08e+01 2.43e-01 -8.6 1.29e+04 - 2.22e-02 2.26e-02h 1\n", - " 15 -4.0763784e+01 2.63e+01 3.51e-02 -8.6 1.44e+02 - 4.76e-01 1.00e+00h 1\n", - " 16 -4.0763958e+01 8.50e-01 4.67e-03 -8.6 7.67e+01 - 6.65e-01 1.00e+00h 1\n", - " 17 -4.0764005e+01 2.35e+00 2.00e-03 -8.6 1.84e+02 - 6.15e-01 6.58e-01h 1\n", - " 18 -4.0764023e+01 3.56e-02 1.49e-04 -8.6 5.80e+00 - 1.00e+00 1.00e+00h 1\n", - " 19 -4.0764023e+01 3.49e-05 5.34e-08 -8.6 5.34e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -4.0764023e+01 3.10e-09 4.31e-12 -8.6 5.03e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 20\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -4.0764023387128162e+01 -4.0764023387128162e+01\n", - "Dual infeasibility......: 4.3057665671855009e-12 4.3057665671855009e-12\n", - "Constraint violation....: 3.0985215504486519e-09 3.0985215504486519e-09\n", - "Complementarity.........: 2.5059046339081401e-09 2.5059046339081401e-09\n", - "Overall NLP error.......: 3.0985215504486519e-09 3.0985215504486519e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 25\n", - "Number of objective gradient evaluations = 21\n", - "Number of equality constraint evaluations = 25\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 21\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 20\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.467\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.4\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.25e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 5.78e+01 3.85e+02 -1.0 3.25e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 2.70e+01 4.60e+02 -1.0 7.21e+01 - 5.56e-02 9.90e-01h 1\n", - " 3 0.0000000e+00 1.18e-01 1.30e+02 -1.0 1.54e+01 - 4.83e-01 1.00e+00f 1\n", - " 4 0.0000000e+00 2.62e-10 5.01e+01 -1.0 5.82e-02 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.6183499812759692e-10 2.6183499812759692e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.6183499812759692e-10 2.6183499812759692e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.041\n", - "Total CPU secs in NLP function evaluations = 0.028\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.66e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 2.72e+04 3.85e+02 -1.0 2.66e+06 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 3.62e+02 5.99e+01 -1.0 2.75e+04 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 6.88e+00 2.06e+00 -1.0 2.49e+02 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 5.86e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393945)\n", - " 5 0.0000000e+00 4.66e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.6566128730773926e-10 4.6566128730773926e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.6566128730773926e-10 4.6566128730773926e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.118\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -4.3535091e+01 8.42e+02 1.01e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303234)\n", - " 1 -4.3535483e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -4.3535814e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -4.3535789e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -4.3535665e+01 5.57e+00 7.62e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -4.3535673e+01 7.15e+00 3.19e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -4.3535690e+01 1.06e-02 4.10e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -4.3535690e+01 1.25e-06 1.39e-05 -3.8 2.01e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -4.3535690e+01 7.45e-09 4.81e-07 -5.7 4.81e-03 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -4.3535690e+01 1.10e-07 6.22e-07 -8.6 1.86e-02 -4.5 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -4.3535690e+01 1.02e-06 6.29e-07 -8.6 5.66e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 11 -4.3535690e+01 9.13e-06 6.29e-07 -8.6 1.70e-01 -5.4 1.00e+00 1.00e+00h 1\n", - " 12 -4.3535690e+01 8.21e-05 6.29e-07 -8.6 5.09e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 13 -4.3535691e+01 7.36e-04 6.28e-07 -8.6 1.53e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 14 -4.3535694e+01 4.46e-03 6.23e-07 -8.6 4.53e+00 -6.9 1.00e+00 8.17e-01h 1\n", - " 15 -4.3535694e+01 3.40e-03 2.22e-05 -8.6 1.51e+00 -7.3 1.00e+00 2.50e-01f 3\n", - " 16 -4.3535694e+01 6.98e-05 3.89e-07 -8.6 4.14e-01 -6.9 1.00e+00 1.00e+00h 1\n", - " 17 -4.3535695e+01 1.95e-04 1.16e-07 -8.6 3.13e-01 -7.4 1.00e+00 1.00e+00h 1\n", - " 18 -4.3535695e+01 1.68e-03 4.37e-07 -8.6 7.09e-01 -7.9 1.00e+00 1.00e+00h 1\n", - " 19 -4.3535696e+01 2.35e-04 6.20e-08 -8.6 2.55e-01 -7.4 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (335313)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -4.3535696e+01 2.19e-03 5.77e-07 -8.6 7.85e-01 -7.9 1.00e+00 1.00e+00h 1\n", - " 21 -4.3535699e+01 2.12e-02 5.60e-06 -8.6 2.33e+00 -8.4 1.00e+00 1.00e+00h 1\n", - " 22 -4.3535706e+01 2.57e-01 6.66e-05 -8.6 6.62e+00 -8.9 1.00e+00 1.00e+00h 1\n", - " 23 -4.3535710e+01 3.67e-02 9.31e-06 -8.6 1.58e+00 -8.4 1.00e+00 1.00e+00h 1\n", - " 24 -4.3535722e+01 5.54e-01 1.31e-04 -8.6 6.37e+00 -8.9 1.00e+00 1.00e+00h 1\n", - " 25 -4.3535728e+01 9.45e-02 2.27e-05 -8.6 3.44e+00 -8.5 1.00e+00 1.00e+00h 1\n", - " 26 -4.3535753e+01 1.95e+00 8.61e-04 -8.6 1.60e+01 -9.0 1.00e+00 1.00e+00h 1\n", - " 27 -4.3535776e+01 5.09e-01 1.62e-04 -8.6 1.94e+01 -8.5 1.00e+00 1.00e+00h 1\n", - " 28 -4.3535823e+01 2.99e+00 1.35e-03 -8.6 9.76e+01 -9.0 1.00e+00 3.84e-01h 1\n", - " 29 -4.3535854e+01 1.72e+00 8.11e-04 -8.6 3.16e+01 -8.6 1.00e+00 5.32e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -4.3535966e+01 5.97e+00 4.83e-03 -8.6 1.46e+02 -9.1 1.00e+00 4.18e-01f 1\n", - " 31 -4.3536027e+01 6.62e+00 5.59e-03 -8.6 4.78e+03 -9.6 8.09e-02 5.49e-03h 1\n", - " 32 -4.3536055e+01 5.60e+00 4.51e-03 -8.6 8.68e+01 -10.0 3.39e-01 1.92e-01h 1\n", - " 33 -4.3536080e+01 2.83e+00 2.13e-03 -8.6 2.89e+01 -9.6 8.95e-01 5.28e-01h 1\n", - " 34 -4.3536087e+01 1.67e+00 1.24e-03 -8.6 1.23e+01 -9.2 1.00e+00 4.18e-01f 1\n", - " 35 -4.3536112e+01 1.12e+00 2.09e-03 -8.6 3.20e+01 -9.7 1.00e+00 1.00e+00f 1\n", - " 36 -4.3536116e+01 1.13e+00 2.04e-03 -8.6 9.56e+01 -10.1 1.00e+00 7.04e-02h 1\n", - " 37 -4.3536133e+01 1.45e+00 1.17e-03 -8.6 2.53e+01 -9.7 1.00e+00 1.00e+00f 1\n", - " 38 -4.3536137e+01 7.69e-01 2.36e-04 -8.6 5.00e+01 -10.2 1.00e+00 1.00e+00h 1\n", - " 39 -4.3536139e+01 6.87e-01 2.41e-04 -8.6 5.07e+02 -10.7 6.28e-01 1.78e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 -4.3536137e+01 4.16e-02 2.05e-05 -8.6 2.23e+01 - 1.00e+00 1.00e+00h 1\n", - " 41 -4.3536138e+01 2.47e-02 1.88e-05 -8.6 2.36e+01 - 1.00e+00 9.45e-01h 1\n", - " 42 -4.3536138e+01 1.80e-05 1.27e-08 -8.6 6.48e-01 - 1.00e+00 1.00e+00h 1\n", - " 43 -4.3536138e+01 1.79e-09 1.37e-12 -8.6 6.46e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 43\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -4.3536137623477664e+01 -4.3536137623477664e+01\n", - "Dual infeasibility......: 1.3656458789760815e-12 1.3656458789760815e-12\n", - "Constraint violation....: 1.7926176099081204e-09 1.7926176099081204e-09\n", - "Complementarity.........: 2.5060411067492794e-09 2.5060411067492794e-09\n", - "Overall NLP error.......: 2.5060411067492794e-09 2.5060411067492794e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 46\n", - "Number of objective gradient evaluations = 44\n", - "Number of equality constraint evaluations = 46\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 44\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 43\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.281\n", - "Total CPU secs in NLP function evaluations = 0.049\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 4.2\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.93e+01 3.85e+02 -1.0 3.96e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.51e+01 4.20e+01 -1.0 4.92e+01 - 4.96e-01 9.91e-01h 1\n", - " 3 0.0000000e+00 1.04e-01 3.48e+02 -1.0 2.82e+01 - 2.86e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 5.40e-11 1.66e+01 -1.0 7.42e-02 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.3969273494658410e-11 5.3969273494658410e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.3969273494658410e-11 5.3969273494658410e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.043\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 5.32e+06 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 5.38e+04 3.85e+02 -1.0 5.32e+06 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 6.28e+02 5.99e+01 -1.0 5.40e+04 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 9.50e+00 2.06e+00 -1.0 5.15e+02 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 8.48e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393530)\n", - " 5 0.0000000e+00 1.16e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.1641532182693481e-10 1.1641532182693481e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.1641532182693481e-10 1.1641532182693481e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.016\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -4.6308203e+01 8.42e+02 1.01e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303016)\n", - " 1 -4.6308399e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -4.6308565e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -4.6308552e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -4.6308490e+01 5.57e+00 7.50e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -4.6308494e+01 7.15e+00 3.11e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -4.6308502e+01 1.06e-02 4.10e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -4.6308502e+01 1.29e-06 1.45e-05 -3.8 2.07e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -4.6308502e+01 2.79e-09 2.41e-07 -5.7 2.41e-03 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -4.6308502e+01 2.70e-08 3.11e-07 -8.6 9.33e-03 -4.5 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -4.6308502e+01 2.54e-07 3.15e-07 -8.6 2.83e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 11 -4.6308502e+01 2.28e-06 3.14e-07 -8.6 8.49e-02 -5.4 1.00e+00 1.00e+00h 1\n", - " 12 -4.6308503e+01 2.05e-05 3.14e-07 -8.6 2.55e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 13 -4.6308503e+01 1.84e-04 3.14e-07 -8.6 7.63e-01 -6.4 1.00e+00 1.00e+00h 1\n", - " 14 -4.6308504e+01 1.64e-03 3.12e-07 -8.6 2.28e+00 -6.9 1.00e+00 1.00e+00h 1\n", - " 15 -4.6308505e+01 3.08e-03 3.98e-07 -8.6 6.49e+00 -7.3 1.00e+00 3.96e-01h 1\n", - " 16 -4.6308505e+01 4.06e-04 1.16e-06 -8.6 5.34e-01 -7.8 1.00e+00 1.00e+00f 1\n", - "Reallocating memory for MA57: lfact (332229)\n", - " 17 -4.6308505e+01 3.58e-03 4.28e-07 -8.6 1.71e+00 -8.3 1.00e+00 1.00e+00h 1\n", - " 18 -4.6308507e+01 2.97e-02 3.87e-06 -8.6 2.87e+00 -8.8 1.00e+00 1.00e+00h 1\n", - " 19 -4.6308511e+01 3.82e-01 4.92e-05 -8.6 7.99e+00 -9.2 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -4.6308514e+01 5.59e-02 6.88e-06 -8.6 1.91e+00 -8.8 1.00e+00 1.00e+00h 1\n", - " 21 -4.6308521e+01 9.99e-01 1.26e-04 -8.6 9.30e+00 -9.3 1.00e+00 1.00e+00h 1\n", - " 22 -4.6308527e+01 1.97e-01 3.02e-05 -8.6 7.51e+00 -8.9 1.00e+00 1.00e+00h 1\n", - " 23 -4.6308550e+01 5.83e+00 1.53e-03 -8.6 3.22e+01 -9.4 1.00e+00 1.00e+00h 1\n", - " 24 -4.6308572e+01 3.03e+00 6.36e-04 -8.6 5.12e+01 -8.9 1.00e+00 6.43e-01h 1\n", - " 25 -4.6308591e+01 3.33e+00 7.08e-04 -8.6 1.77e+02 -9.4 1.00e+00 1.29e-01f 1\n", - " 26 -4.6308634e+01 1.98e+00 7.94e-04 -8.6 4.29e+01 -9.0 1.00e+00 1.00e+00f 1\n", - " 27 -4.6308670e+01 2.73e+00 1.19e-03 -8.6 1.96e+02 -9.5 1.00e+00 1.61e-01h 1\n", - " 28 -4.6308683e+01 2.71e+00 1.18e-03 -8.6 2.33e+02 -9.9 1.00e+00 4.70e-02h 1\n", - " 29 -4.6308696e+01 2.50e-01 9.00e-05 -8.6 9.45e+00 -9.5 8.17e-01 9.93e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -4.6308703e+01 2.04e-01 1.41e-04 -8.6 2.34e+01 -10.0 1.00e+00 5.79e-01f 1\n", - " 31 -4.6308703e+01 2.45e-02 1.55e-05 -8.6 6.94e+00 -9.6 1.00e+00 1.00e+00f 1\n", - " 32 -4.6308709e+01 8.74e-01 1.10e-03 -8.6 3.06e+01 -10.0 1.00e+00 9.86e-01h 1\n", - " 33 -4.6308713e+01 4.19e-01 1.63e-04 -8.6 1.23e+01 -9.6 1.00e+00 1.00e+00f 1\n", - " 34 -4.6308722e+01 1.83e+00 9.77e-04 -8.6 3.09e+01 -10.1 1.00e+00 1.00e+00h 1\n", - " 35 -4.6308726e+01 9.33e-01 1.76e-04 -8.6 6.82e+01 -10.6 1.00e+00 1.00e+00h 1\n", - " 36 -4.6308726e+01 8.58e-01 1.24e-04 -8.6 8.39e+02 -11.0 4.07e-01 8.08e-02h 1\n", - " 37 -4.6308725e+01 2.75e-02 9.18e-06 -8.6 1.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 38 -4.6308725e+01 9.21e-03 3.64e-06 -8.6 1.42e+01 - 1.00e+00 1.00e+00h 1\n", - " 39 -4.6308725e+01 2.12e-05 8.21e-09 -8.6 7.01e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 -4.6308725e+01 1.86e-09 1.31e-13 -8.6 2.53e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 40\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -4.6308725472442092e+01 -4.6308725472442092e+01\n", - "Dual infeasibility......: 1.3063844228700835e-13 1.3063844228700835e-13\n", - "Constraint violation....: 9.3132257461547852e-10 1.8626451492309570e-09\n", - "Complementarity.........: 2.5059035596850455e-09 2.5059035596850455e-09\n", - "Overall NLP error.......: 2.5059035596850455e-09 2.5059035596850455e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 41\n", - "Number of objective gradient evaluations = 41\n", - "Number of equality constraint evaluations = 41\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 41\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 40\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.242\n", - "Total CPU secs in NLP function evaluations = 0.010\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 4.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.96e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.92e+01 3.85e+02 -1.0 3.96e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.51e+01 4.22e+01 -1.0 4.90e+01 - 4.96e-01 9.93e-01h 1\n", - " 3 0.0000000e+00 8.83e-02 3.52e+02 -1.0 2.82e+01 - 2.81e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 3.29e-11 8.00e+00 -1.0 6.29e-02 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 3.2869706956262235e-11 3.2869706956262235e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 3.2869706956262235e-11 3.2869706956262235e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.046\n", - "Total CPU secs in NLP function evaluations = 0.016\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.8\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.06e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 1.07e+05 3.85e+02 -1.0 1.06e+07 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.16e+03 5.99e+01 -1.0 1.07e+05 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.48e+01 2.06e+00 -1.0 1.05e+03 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 1.37e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393774)\n", - " 5 0.0000000e+00 2.33e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.3283064365386963e-10 2.3283064365386963e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.3283064365386963e-10 2.3283064365386963e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -4.9081053e+01 8.42e+02 1.01e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303140)\n", - " 1 -4.9081151e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -4.9081234e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -4.9081228e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -4.9081197e+01 5.57e+00 7.50e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -4.9081199e+01 7.15e+00 3.08e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -4.9081203e+01 1.06e-02 4.10e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -4.9081203e+01 1.31e-06 1.47e-05 -3.8 2.10e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -4.9081203e+01 1.70e-06 3.33e-07 -5.7 3.92e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (322057)\n", - " 9 -4.9081203e+01 1.16e-02 2.45e-05 -8.6 3.24e+00 - 9.81e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -4.9081203e+01 2.03e-07 2.70e-07 -8.6 2.70e-03 -4.0 1.00e+00 1.00e+00h 1\n", - " 11 -4.9081203e+01 7.45e-09 1.57e-07 -8.6 4.71e-03 -4.5 1.00e+00 1.00e+00h 1\n", - " 12 -4.9081203e+01 6.33e-08 1.57e-07 -8.6 1.41e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 13 -4.9081203e+01 5.66e-07 1.57e-07 -8.6 4.24e-02 -5.4 1.00e+00 1.00e+00h 1\n", - " 14 -4.9081203e+01 5.09e-06 1.57e-07 -8.6 1.27e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 15 -4.9081203e+01 4.57e-05 1.57e-07 -8.6 3.81e-01 -6.4 1.00e+00 1.00e+00h 1\n", - " 16 -4.9081203e+01 4.07e-04 1.56e-07 -8.6 1.14e+00 -6.9 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (342868)\n", - " 17 -4.9081204e+01 3.47e-03 1.52e-07 -8.6 3.32e+00 -7.3 1.00e+00 1.00e+00h 1\n", - " 18 -4.9081204e+01 3.11e-03 3.19e-06 -8.6 4.30e+00 -7.8 1.00e+00 1.35e-01h 1\n", - " 19 -4.9081204e+01 7.01e-04 7.88e-07 -8.6 2.87e-01 -8.3 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -4.9081205e+01 6.81e-03 4.46e-07 -8.6 1.48e+00 -8.8 1.00e+00 1.00e+00h 1\n", - " 21 -4.9081206e+01 6.91e-02 4.53e-06 -8.6 4.12e+00 -9.2 1.00e+00 1.00e+00h 1\n", - " 22 -4.9081210e+01 1.25e+00 7.64e-05 -8.6 1.05e+01 -9.7 1.00e+00 1.00e+00h 1\n", - " 23 -4.9081212e+01 2.32e-01 1.39e-05 -8.6 6.13e+00 -9.3 1.00e+00 1.00e+00h 1\n", - " 24 -4.9081226e+01 1.28e+01 1.87e-03 -8.6 4.40e+01 -9.8 1.00e+00 1.00e+00h 1\n", - " 25 -4.9081236e+01 9.38e+00 1.30e-03 -8.6 9.23e+01 -9.4 1.00e+00 3.14e-01h 1\n", - " 26 -4.9081256e+01 1.10e+01 1.39e-03 -8.6 4.30e+02 -9.8 6.97e-01 1.11e-01f 1\n", - " 27 -4.9081286e+01 6.05e+00 8.65e-04 -8.6 8.29e+01 -9.4 1.00e+00 6.91e-01f 1\n", - " 28 -4.9081293e+01 1.88e+00 2.33e-04 -8.6 1.25e+01 -9.9 8.83e-01 7.46e-01f 1\n", - " 29 -4.9081301e+01 8.63e-01 1.23e-04 -8.6 2.66e+01 -10.4 1.00e+00 6.71e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -4.9081302e+01 4.34e-02 7.27e-06 -8.6 6.80e+00 -9.9 1.00e+00 1.00e+00f 1\n", - " 31 -4.9081305e+01 2.53e+00 1.66e-03 -8.6 5.25e+01 -10.4 1.00e+00 1.00e+00h 1\n", - " 32 -4.9081319e+01 1.27e+01 2.66e-03 -8.6 1.00e+02 -10.9 1.00e+00 8.30e-01h 1\n", - " 33 -4.9081310e+01 4.58e-01 2.81e-04 -8.6 2.59e+01 -10.5 1.00e+00 1.00e+00h 1\n", - " 34 -4.9081312e+01 3.50e-01 1.29e-04 -8.6 7.29e+01 -10.9 1.00e+00 6.14e-01h 1\n", - " 35 -4.9081313e+01 1.07e-01 8.13e-06 -8.6 1.93e+01 - 1.00e+00 1.00e+00f 1\n", - " 36 -4.9081313e+01 1.48e-02 3.65e-06 -8.6 1.78e+01 - 1.00e+00 1.00e+00h 1\n", - " 37 -4.9081313e+01 5.02e-05 1.04e-08 -8.6 1.08e+00 - 1.00e+00 1.00e+00h 1\n", - " 38 -4.9081313e+01 1.86e-09 3.39e-13 -8.6 6.17e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 38\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -4.9081313321398035e+01 -4.9081313321398035e+01\n", - "Dual infeasibility......: 3.3870588295113704e-13 3.3870588295113704e-13\n", - "Constraint violation....: 1.6578169947933930e-09 1.8626451492309570e-09\n", - "Complementarity.........: 2.5059035596847262e-09 2.5059035596847262e-09\n", - "Overall NLP error.......: 2.5059035596847262e-09 2.5059035596847262e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 39\n", - "Number of objective gradient evaluations = 39\n", - "Number of equality constraint evaluations = 39\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 39\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 38\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.199\n", - "Total CPU secs in NLP function evaluations = 0.015\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 4.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.94e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.91e+01 3.85e+02 -1.0 3.94e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.52e+01 4.24e+01 -1.0 4.87e+01 - 4.96e-01 9.95e-01h 1\n", - " 3 0.0000000e+00 5.64e-02 3.60e+02 -1.0 2.82e+01 - 2.71e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 8.55e-12 3.70e+00 -1.0 4.01e-02 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 8.5549345385516062e-12 8.5549345385516062e-12\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 8.5549345385516062e-12 8.5549345385516062e-12\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.053\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.13e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 2.13e+05 3.85e+02 -1.0 2.13e+07 - 2.54e-03 9.90e-01h 1\n", - " 2 0.0000000e+00 2.22e+03 5.99e+01 -1.0 2.14e+05 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 2.53e+01 2.06e+00 -1.0 2.11e+03 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 2.42e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393985)\n", - " 5 0.0000000e+00 4.66e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.6566128730773926e-10 4.6566128730773926e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.6566128730773926e-10 4.6566128730773926e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.110\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -5.1853772e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303252)\n", - " 1 -5.1853821e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -5.1853862e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -5.1853859e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -5.1853844e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -5.1853845e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -5.1853847e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -5.1853847e+01 1.32e-06 1.49e-05 -3.8 2.12e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -5.1853847e+01 7.45e-09 6.02e-08 -5.7 6.02e-04 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -5.1853847e+01 7.45e-09 7.78e-08 -8.6 2.33e-03 -4.5 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -5.1853847e+01 1.86e-08 7.86e-08 -8.6 7.08e-03 -5.0 1.00e+00 1.00e+00h 1\n", - " 11 -5.1853847e+01 1.42e-07 7.86e-08 -8.6 2.12e-02 -5.4 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (327115)\n", - " 12 -5.1853847e+01 1.28e-06 7.86e-08 -8.6 6.37e-02 -5.9 1.00e+00 1.00e+00h 1\n", - " 13 -5.1853847e+01 1.15e-05 7.85e-08 -8.6 1.91e-01 -6.4 1.00e+00 1.00e+00h 1\n", - " 14 -5.1853847e+01 1.03e-04 7.82e-08 -8.6 5.70e-01 -6.9 1.00e+00 1.00e+00h 1\n", - " 15 -5.1853847e+01 8.97e-04 7.70e-08 -8.6 1.68e+00 -7.3 1.00e+00 1.00e+00h 1\n", - " 16 -5.1853847e+01 1.50e-03 1.82e-07 -8.6 4.60e+00 -7.8 1.00e+00 3.75e-01h 2\n", - " 17 -5.1853847e+01 1.53e-03 1.58e-06 -8.6 6.12e+00 -8.3 1.00e+00 1.44e-01h 2\n", - " 18 -5.1853847e+01 1.32e-03 1.57e-06 -8.6 1.69e+00 -8.8 1.00e+00 4.38e-01h 2\n", - "Reallocating memory for MA57: lfact (345657)\n", - " 19 -5.1853848e+01 1.70e-02 1.12e-06 -8.6 2.40e+00 -9.2 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -5.1853848e+01 1.75e-01 5.67e-06 -8.6 6.21e+00 -9.7 1.00e+00 1.00e+00h 1\n", - " 21 -5.1853853e+01 1.96e+01 1.30e-03 -8.6 4.77e+01 -10.2 1.00e+00 1.00e+00h 1\n", - " 22 -5.1853862e+01 1.44e+01 8.05e-04 -8.6 1.50e+02 -9.8 1.00e+00 4.12e-01h 1\n", - " 23 -5.1853873e+01 1.77e+01 9.19e-04 -8.6 4.63e+03 -10.3 6.40e-02 1.19e-02h 1\n", - " 24 -5.1853883e+01 1.46e+01 4.64e-02 -8.6 1.25e+02 -10.7 1.00e+00 2.45e-01h 1\n", - " 25 -5.1853894e+01 1.55e+00 9.50e-01 -8.6 3.86e+01 -10.3 6.08e-02 1.00e+00h 1\n", - " 26 -5.1853897e+01 3.12e-01 2.79e-01 -8.6 5.18e+01 -10.8 1.00e+00 7.06e-01H 1\n", - " 27 -5.1853898e+01 3.16e-01 5.81e-05 -8.6 1.47e+01 -10.4 1.00e+00 1.00e+00f 1\n", - " 28 -5.1853901e+01 2.65e+00 3.38e-04 -8.6 3.87e+01 -10.8 1.00e+00 1.00e+00h 1\n", - " 29 -5.1853901e+01 1.04e+00 9.14e-05 -8.6 1.20e+02 -11.3 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -5.1853901e+01 1.15e-02 1.39e-06 -8.6 1.55e+00 - 1.00e+00 1.00e+00h 1\n", - " 31 -5.1853901e+01 4.45e-06 6.79e-10 -8.6 1.25e-01 - 1.00e+00 1.00e+00h 1\n", - " 32 -5.1853901e+01 3.73e-09 2.52e-14 -8.6 2.14e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 32\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -5.1853901170234600e+01 -5.1853901170234600e+01\n", - "Dual infeasibility......: 2.5166233628543340e-14 2.5166233628543340e-14\n", - "Constraint violation....: 4.6566128730773926e-10 3.7252902984619141e-09\n", - "Complementarity.........: 2.5059035596808703e-09 2.5059035596808703e-09\n", - "Overall NLP error.......: 2.5059035596808703e-09 3.7252902984619141e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 44\n", - "Number of objective gradient evaluations = 33\n", - "Number of equality constraint evaluations = 44\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 33\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 32\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.946\n", - "Total CPU secs in NLP function evaluations = 0.023\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.8\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.89e+01 3.85e+02 -1.0 3.92e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.52e+01 4.30e+01 -1.0 4.82e+01 - 4.96e-01 1.00e+00h 1\n", - " 3 0.0000000e+00 4.26e-04 3.75e+02 -1.0 2.80e+01 - 2.55e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 2.52e-13 3.50e+00 -1.0 1.87e-04 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.0465496681718326e-13 2.5224267119483557e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.0465496681718326e-13 2.5224267119483557e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.047\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.8\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 4.26e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 4.26e+05 3.85e+02 -1.0 4.26e+07 - 2.54e-03 9.90e-01h 1\n", - " 2 0.0000000e+00 4.35e+03 5.99e+01 -1.0 4.26e+05 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.63e+01 2.06e+00 -1.0 4.24e+03 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 4.52e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393567)\n", - " 5 0.0000000e+00 9.31e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.3132257461547852e-10 9.3132257461547852e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.3132257461547852e-10 9.3132257461547852e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.113\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -5.4626425e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303140)\n", - " 1 -5.4626450e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -5.4626470e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -5.4626469e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -5.4626461e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -5.4626462e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -5.4626463e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -5.4626463e+01 1.33e-06 1.50e-05 -3.8 2.12e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -5.4626463e+01 7.45e-09 3.01e-08 -5.7 3.01e-04 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -5.4626463e+01 7.31e-04 4.97e-06 -8.6 8.12e-01 - 9.96e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (323556)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -5.4626463e+01 7.45e-09 3.51e-08 -8.6 1.05e-03 -4.5 1.00e+00 1.00e+00h 1\n", - " 11 -5.4626463e+01 7.45e-09 3.93e-08 -8.6 3.53e-03 -5.0 1.00e+00 1.00e+00h 1\n", - " 12 -5.4626463e+01 3.73e-08 3.93e-08 -8.6 1.06e-02 -5.4 1.00e+00 1.00e+00h 1\n", - " 13 -5.4626463e+01 3.20e-07 3.92e-08 -8.6 3.18e-02 -5.9 1.00e+00 1.00e+00h 1\n", - " 14 -5.4626463e+01 2.87e-06 3.92e-08 -8.6 9.52e-02 -6.4 1.00e+00 1.00e+00h 1\n", - " 15 -5.4626463e+01 2.56e-05 3.90e-08 -8.6 2.84e-01 -6.9 1.00e+00 1.00e+00h 1\n", - " 16 -5.4626463e+01 2.24e-04 3.85e-08 -8.6 8.42e-01 -7.3 1.00e+00 1.00e+00h 1\n", - " 17 -5.4626463e+01 1.80e-03 3.64e-08 -8.6 2.39e+00 -7.8 1.00e+00 1.00e+00h 1\n", - " 18 -5.4626463e+01 1.75e-03 4.42e-07 -8.6 4.44e+00 -8.3 1.00e+00 2.55e-01h 2\n", - " 19 -5.4626463e+01 1.22e-03 7.37e-07 -8.6 1.65e+00 -8.8 1.00e+00 4.26e-01h 2\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -5.4626463e+01 3.93e-03 2.60e-07 -8.6 1.20e+00 -9.2 1.00e+00 1.00e+00h 1\n", - " 21 -5.4626463e+01 3.61e-02 5.90e-07 -8.6 3.14e+00 -9.7 1.00e+00 1.00e+00h 1\n", - " 22 -5.4626464e+01 4.44e-01 7.03e-06 -8.6 8.61e+00 -10.2 1.00e+00 1.00e+00h 1\n", - " 23 -5.4626464e+01 6.25e-02 9.33e-07 -8.6 2.01e+00 -9.8 1.00e+00 1.00e+00h 1\n", - " 24 -5.4626465e+01 1.08e+00 1.99e-05 -8.6 9.96e+00 -10.3 1.00e+00 1.00e+00h 1\n", - " 25 -5.4626466e+01 2.09e-01 4.63e-06 -8.6 8.06e+00 -9.8 1.00e+00 1.00e+00h 1\n", - " 26 -5.4626469e+01 6.30e+00 2.33e-04 -8.6 3.45e+01 -10.3 1.00e+00 1.00e+00h 1\n", - " 27 -5.4626473e+01 1.97e+00 5.73e-05 -8.6 4.80e+01 -9.9 1.00e+00 1.00e+00h 1\n", - " 28 -5.4626482e+01 8.48e+00 4.36e-04 -8.6 1.83e+02 -10.4 1.00e+00 4.10e-01h 1\n", - " 29 -5.4626483e+01 7.19e+00 3.68e-04 -8.6 3.53e+01 -10.8 1.00e+00 1.56e-01f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -5.4626486e+01 2.22e-01 2.33e-05 -8.6 6.24e+00 -10.4 5.58e-01 1.00e+00f 1\n", - " 31 -5.4626486e+01 1.20e-01 1.81e-05 -8.6 1.55e+01 -10.9 1.00e+00 1.00e+00h 1\n", - " 32 -5.4626486e+01 1.29e-02 4.92e-07 -8.6 3.51e+00 -10.5 1.00e+00 1.00e+00h 1\n", - " 33 -5.4626487e+01 2.08e-01 3.17e-05 -8.6 1.49e+01 -10.9 1.00e+00 1.00e+00h 1\n", - " 34 -5.4626487e+01 8.32e-02 7.55e-06 -8.6 7.39e+00 -10.5 1.00e+00 1.00e+00h 1\n", - " 35 -5.4626488e+01 2.61e+00 2.60e-04 -8.6 4.11e+01 -11.0 1.00e+00 1.00e+00h 1\n", - " 36 -5.4626489e+01 2.50e+00 5.32e-05 -8.6 7.17e+01 -11.5 1.00e+00 1.00e+00h 1\n", - " 37 -5.4626489e+01 1.89e+00 4.09e-05 -8.6 2.88e+02 -11.9 1.00e+00 2.43e-01h 1\n", - " 38 -5.4626489e+01 1.35e-02 1.91e-06 -8.6 1.74e+01 - 1.00e+00 1.00e+00h 1\n", - " 39 -5.4626489e+01 2.25e-03 9.41e-08 -8.6 6.88e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 40 -5.4626489e+01 1.34e-06 5.72e-11 -8.6 1.71e-01 - 1.00e+00 1.00e+00h 1\n", - " 41 -5.4626489e+01 1.49e-08 2.51e-14 -8.6 1.61e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 41\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -5.4626489018506717e+01 -5.4626489018506717e+01\n", - "Dual infeasibility......: 2.5104508813183050e-14 2.5104508813183050e-14\n", - "Constraint violation....: 9.3132257461547852e-10 1.4901161193847656e-08\n", - "Complementarity.........: 2.5059035596801395e-09 2.5059035596801395e-09\n", - "Overall NLP error.......: 2.5059035596801395e-09 1.4901161193847656e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 48\n", - "Number of objective gradient evaluations = 42\n", - "Number of equality constraint evaluations = 48\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 42\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 41\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.229\n", - "Total CPU secs in NLP function evaluations = 0.069\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.5\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.86e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.85e+01 3.85e+02 -1.0 3.86e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.41e+01 4.32e+01 -1.0 4.70e+01 - 4.96e-01 1.00e+00h 1\n", - " 3 0.0000000e+00 4.19e-04 3.70e+02 -1.0 2.74e+01 - 2.54e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 3.41e-13 3.45e+00 -1.0 1.89e-04 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.4150530724576891e-13 3.4106051316484809e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.4150530724576891e-13 3.4106051316484809e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.047\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.0\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 8.51e+07 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 8.52e+05 3.85e+02 -1.0 8.51e+07 - 2.54e-03 9.90e-01h 1\n", - " 2 0.0000000e+00 8.61e+03 5.99e+01 -1.0 8.52e+05 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 8.83e+01 2.06e+00 -1.0 8.49e+03 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 8.73e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (394288)\n", - " 5 0.0000000e+00 4.66e-10 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 4.6566128730773926e-10 4.6566128730773926e-10\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 4.6566128730773926e-10 4.6566128730773926e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.090\n", - "Total CPU secs in NLP function evaluations = 0.015\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -5.7399046e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303434)\n", - " 1 -5.7399058e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -5.7399068e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -5.7399068e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -5.7399064e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -5.7399064e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -5.7399065e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -5.7399065e+01 1.33e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -5.7399065e+01 1.49e-08 1.51e-08 -5.7 1.51e-04 -4.0 1.00e+00 1.00e+00h 1\n", - " 9 -5.7399065e+01 2.98e-08 1.94e-08 -8.6 5.83e-04 -4.5 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -5.7399065e+01 1.49e-08 1.97e-08 -9.0 1.77e-03 -5.0 1.00e+00 1.00e+00h 1\n", - " 11 -5.7399065e+01 2.98e-08 1.97e-08 -9.0 5.31e-03 -5.4 1.00e+00 1.00e+00h 1\n", - " 12 -5.7399065e+01 8.94e-08 1.97e-08 -9.0 1.59e-02 -5.9 1.00e+00 1.00e+00h 1\n", - " 13 -5.7399065e+01 7.15e-07 1.96e-08 -9.0 4.77e-02 -6.4 1.00e+00 1.00e+00h 1\n", - " 14 -5.7399065e+01 6.48e-06 1.96e-08 -9.0 1.43e-01 -6.9 1.00e+00 1.00e+00h 1\n", - " 15 -5.7399065e+01 5.78e-05 1.95e-08 -9.0 4.27e-01 -7.3 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (333906)\n", - " 16 -5.7399065e+01 5.04e-04 1.92e-08 -9.0 1.26e+00 -7.8 1.00e+00 1.00e+00h 1\n", - " 17 -5.7399065e+01 3.89e-03 1.78e-08 -9.0 3.51e+00 -8.3 1.00e+00 1.00e+00h 1\n", - " 18 -5.7399065e+01 3.09e-03 5.12e-07 -9.0 1.50e+00 -8.8 1.00e+00 2.16e-01h 2\n", - " 19 -5.7399065e+01 9.36e-04 9.20e-08 -9.0 5.07e-01 -9.2 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -5.7399065e+01 8.67e-03 7.11e-08 -9.0 1.60e+00 -9.7 1.00e+00 1.00e+00h 1\n", - " 21 -5.7399065e+01 8.90e-02 7.27e-07 -9.0 4.66e+00 -10.2 1.00e+00 1.00e+00h 1\n", - " 22 -5.7399065e+01 1.83e+00 1.34e-05 -9.0 1.12e+01 -10.7 1.00e+00 1.00e+00h 1\n", - " 23 -5.7399066e+01 3.81e-01 3.61e-06 -9.0 1.00e+01 -10.3 1.00e+00 1.00e+00h 1\n", - " 24 -5.7399069e+01 8.09e+00 2.59e-04 -9.0 7.69e+01 -10.7 9.52e-01 6.16e-01H 1\n", - " 25 -5.7399072e+01 3.81e+00 1.19e-04 -9.0 5.43e+01 -10.3 1.00e+00 7.55e-01f 1\n", - " 26 -5.7399075e+01 4.33e+00 1.32e-04 -9.0 2.22e+02 -10.8 1.00e+00 1.41e-01f 1\n", - " 27 -5.7399076e+01 1.97e+00 3.29e-05 -9.0 2.73e+01 -11.3 8.89e-01 7.54e-01f 1\n", - " 28 -5.7399077e+01 1.75e-01 1.41e-06 -9.0 1.54e+01 -10.8 1.00e+00 1.00e+00f 1\n", - " 29 -5.7399077e+01 9.22e-01 7.02e-05 -9.0 3.11e+01 -11.3 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -5.7399077e+01 4.41e-01 1.26e-05 -9.0 1.65e+01 -10.9 1.00e+00 1.00e+00h 1\n", - " 31 -5.7399078e+01 2.23e+00 7.37e-05 -9.0 3.40e+01 -11.4 1.00e+00 1.00e+00h 1\n", - " 32 -5.7399078e+01 6.05e-01 8.47e-06 -9.0 8.14e+01 -11.8 1.00e+00 1.00e+00h 1\n", - " 33 -5.7399078e+01 5.73e-01 8.79e-06 -9.0 3.08e+02 -12.3 1.00e+00 1.64e-01h 1\n", - " 34 -5.7399078e+01 1.59e-02 1.89e-07 -9.0 1.07e+01 - 1.00e+00 1.00e+00h 1\n", - " 35 -5.7399078e+01 4.00e-04 1.26e-08 -9.0 2.96e+00 - 1.00e+00 1.00e+00h 1\n", - " 36 -5.7399078e+01 4.81e-08 1.16e-12 -9.0 3.27e-02 - 1.00e+00 1.00e+00h 1\n", - " 37 -5.7399078e+01 1.49e-08 9.10e-15 -9.0 5.66e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 37\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -5.7399077980658021e+01 -5.7399077980658021e+01\n", - "Dual infeasibility......: 9.1002942970123576e-15 9.1002942970123576e-15\n", - "Constraint violation....: 1.8626451492309570e-09 1.4901161193847656e-08\n", - "Complementarity.........: 9.0909090909093753e-10 9.0909090909093753e-10\n", - "Overall NLP error.......: 1.8626451492309570e-09 1.4901161193847656e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 40\n", - "Number of objective gradient evaluations = 38\n", - "Number of equality constraint evaluations = 40\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 38\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 37\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.064\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.8\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.89e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.87e+01 3.85e+02 -1.0 3.89e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.47e+01 4.31e+01 -1.0 4.76e+01 - 4.96e-01 1.00e+00h 1\n", - " 3 0.0000000e+00 4.23e-04 3.73e+02 -1.0 2.77e+01 - 2.54e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 2.79e-13 3.48e+00 -1.0 1.88e-04 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.2337636129035084e-13 2.7888802378583932e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.2337636129035084e-13 2.7888802378583932e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.063\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.8\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.70e+08 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 1.70e+06 3.85e+02 -1.0 1.70e+08 - 2.54e-03 9.90e-01h 1\n", - " 2 0.0000000e+00 1.71e+04 5.99e+01 -1.0 1.70e+06 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.72e+02 2.06e+00 -1.0 1.70e+04 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 1.71e+02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393530)\n", - " 5 0.0000000e+00 4.55e-13 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.3691704763652764e-13 4.5474735088646412e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.3691704763652764e-13 4.5474735088646412e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.115\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -6.0171651e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303252)\n", - " 1 -6.0171657e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -6.0171662e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -6.0171662e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -6.0171660e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -6.0171660e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -6.0171660e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -6.0171660e+01 1.34e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -6.0171660e+01 2.98e-08 2.02e-08 -5.7 1.92e-03 - 1.00e+00 1.00e+00h 1\n", - " 9 -6.0171660e+01 4.53e-05 2.16e-08 -8.6 2.02e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (326464)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -6.0171660e+01 2.98e-08 9.06e-09 -8.6 9.06e-05 -4.0 1.00e+00 1.00e+00h 1\n", - " 11 -6.0171660e+01 3.73e-09 9.82e-09 -8.6 2.94e-04 -4.5 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 11\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -6.0171659998267266e+01 -6.0171659998267266e+01\n", - "Dual infeasibility......: 9.8158985796691289e-09 9.8158985796691289e-09\n", - "Constraint violation....: 3.7252902984619141e-09 3.7252902984619141e-09\n", - "Complementarity.........: 2.5059035655454891e-09 2.5059035655454891e-09\n", - "Overall NLP error.......: 9.8158985796691289e-09 9.8158985796691289e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 12\n", - "Number of objective gradient evaluations = 12\n", - "Number of equality constraint evaluations = 12\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 12\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 11\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.265\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.55e+01 3.85e+02 -1.0 1.92e+02 - 2.55e-03 9.95e-01f 1\n", - " 2 0.0000000e+00 1.07e+01 4.90e+01 -1.0 1.71e+01 - 2.60e-01 1.00e+00h 1\n", - " 3 0.0000000e+00 4.19e-05 2.46e+01 -1.0 7.37e+00 - 5.90e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 2.27e-13 1.48e-01 -1.0 3.16e-05 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.1202303897534080e-13 2.2737367544323206e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.1202303897534080e-13 2.2737367544323206e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.057\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.9\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.40e+08 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 3.40e+06 3.85e+02 -1.0 3.40e+08 - 2.54e-03 9.90e-01h 1\n", - " 2 0.0000000e+00 3.41e+04 5.99e+01 -1.0 3.41e+06 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 3.40e+02 2.06e+00 -1.0 3.40e+04 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.10e-04 2.39e-04 -1.0 3.39e+02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393908)\n", - " 5 0.0000000e+00 1.49e-08 1.50e-09 -3.8 3.14e-04 - 1.00e+00 1.00e+00h 1\n", - " 6 0.0000000e+00 4.55e-13 1.84e-11 -5.7 1.49e-08 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.8851038199681022e-14 4.5474735088646412e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.8851038199681022e-14 4.5474735088646412e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.120\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -6.2944244e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303034)\n", - " 1 -6.2944247e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -6.2944250e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -6.2944249e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -6.2944249e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -6.2944249e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -6.2944249e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -6.2944249e+01 1.31e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -6.2944249e+01 5.96e-08 1.04e-08 -5.7 6.73e-04 - 1.00e+00 1.00e+00h 1\n", - " 9 -6.2944249e+01 1.13e-05 1.08e-08 -8.6 1.01e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (326761)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -6.2944249e+01 5.96e-08 4.72e-09 -8.6 4.72e-05 -4.0 1.00e+00 1.00e+00h 1\n", - " 11 -6.2944249e+01 5.96e-08 4.91e-09 -9.0 1.47e-04 -4.5 1.00e+00 1.00e+00h 1\n", - " 12 -6.2944249e+01 1.49e-08 4.91e-09 -9.0 4.42e-04 -5.0 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 12\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -6.2944248720059186e+01 -6.2944248720059186e+01\n", - "Dual infeasibility......: 4.9123733168040214e-09 4.9123733168040214e-09\n", - "Constraint violation....: 7.4505805969238281e-09 1.4901161193847656e-08\n", - "Complementarity.........: 9.0909090909090920e-10 9.0909090909090920e-10\n", - "Overall NLP error.......: 7.4505805969238281e-09 1.4901161193847656e-08\n", - "\n", - "\n", - "Number of objective function evaluations = 13\n", - "Number of objective gradient evaluations = 13\n", - "Number of equality constraint evaluations = 13\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 13\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 12\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.286\n", - "Total CPU secs in NLP function evaluations = 0.017\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.55e+01 3.85e+02 -1.0 1.92e+02 - 2.55e-03 9.95e-01f 1\n", - " 2 0.0000000e+00 1.07e+01 4.90e+01 -1.0 1.71e+01 - 2.60e-01 1.00e+00h 1\n", - " 3 0.0000000e+00 4.17e-05 2.47e+01 -1.0 7.37e+00 - 5.89e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 3.41e-13 1.49e-01 -1.0 3.15e-05 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.6092568863958805e-13 3.4106051316484809e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.6092568863958805e-13 3.4106051316484809e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.064\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.81e+08 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (295725)\n", - " 1 0.0000000e+00 6.81e+06 3.85e+02 -1.0 6.81e+08 - 2.54e-03 9.90e-01h 1\n", - " 2 0.0000000e+00 6.82e+04 5.99e+01 -1.0 6.81e+06 - 1.29e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 6.77e+02 2.06e+00 -1.0 6.81e+04 - 9.84e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 3.11e-04 2.39e-04 -1.0 6.76e+02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393607)\n", - " 5 0.0000000e+00 2.98e-08 1.50e-09 -3.8 3.15e-04 - 1.00e+00 1.00e+00h 1\n", - " 6 0.0000000e+00 4.55e-13 1.84e-11 -5.7 2.98e-08 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 6\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.7123678492091068e-14 4.5474735088646412e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.7123678492091068e-14 4.5474735088646412e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 7\n", - "Number of objective gradient evaluations = 7\n", - "Number of equality constraint evaluations = 7\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 7\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 6\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.117\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -6.5716835e+01 8.42e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303450)\n", - " 1 -6.5716837e+01 4.18e+02 5.15e+00 -1.0 2.52e+01 - 9.88e-01 5.04e-01h 1\n", - " 2 -6.5716838e+01 3.73e-01 1.66e-01 -1.0 2.07e+01 - 9.82e-01 1.00e+00f 1\n", - " 3 -6.5716838e+01 2.27e-01 8.50e-02 -1.7 2.61e+01 - 1.00e+00 1.00e+00f 1\n", - " 4 -6.5716837e+01 5.57e+00 7.49e-02 -1.7 1.56e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -6.5716837e+01 7.15e+00 3.09e-03 -1.7 1.09e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -6.5716837e+01 1.06e-02 4.11e-04 -1.7 9.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 7 -6.5716837e+01 1.43e-06 1.50e-05 -3.8 2.13e-02 - 1.00e+00 1.00e+00h 1\n", - " 8 -6.5716837e+01 1.19e-07 6.81e-09 -5.7 2.30e-04 - 1.00e+00 1.00e+00h 1\n", - " 9 -6.5716837e+01 2.74e-06 5.39e-09 -8.6 5.05e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (321428)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -6.5716837e+01 1.19e-07 2.41e-09 -8.6 2.41e-05 -4.0 1.00e+00 1.00e+00h 1\n", - " 11 -6.5716837e+01 1.19e-07 2.45e-09 -8.6 7.36e-05 -4.5 1.00e+00 1.00e+00h 1\n", - " 12 -6.5716837e+01 1.19e-07 2.45e-09 -8.6 2.21e-04 -5.0 1.00e+00 1.00e+00h 1\n", - " 13 -6.5716837e+01 1.49e-08 2.45e-09 -8.6 6.62e-04 -5.4 1.00e+00 1.00e+00h 1\n", - " 14 -6.5716837e+01 1.19e-07 2.45e-09 -9.0 1.99e-03 -5.9 1.00e+00 1.00e+00h 1\n", - " 15 -6.5716837e+01 1.19e-07 2.45e-09 -9.0 5.96e-03 -6.4 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 15\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -6.5716837442211869e+01 -6.5716837442211869e+01\n", - "Dual infeasibility......: 2.4545255939761519e-09 2.4545255939761519e-09\n", - "Constraint violation....: 2.4652589872487225e-10 1.1920928955078125e-07\n", - "Complementarity.........: 9.0909090909090920e-10 9.0909090909090920e-10\n", - "Overall NLP error.......: 2.4545255939761519e-09 1.1920928955078125e-07\n", - "\n", - "\n", - "Number of objective function evaluations = 16\n", - "Number of objective gradient evaluations = 16\n", - "Number of equality constraint evaluations = 16\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 16\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 15\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.401\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.92e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 1.55e+01 3.85e+02 -1.0 1.92e+02 - 2.55e-03 9.95e-01f 1\n", - " 2 0.0000000e+00 1.07e+01 4.90e+01 -1.0 1.71e+01 - 2.60e-01 1.00e+00h 1\n", - " 3 0.0000000e+00 4.18e-05 2.47e+01 -1.0 7.37e+00 - 5.89e-01 1.00e+00h 1\n", - " 4 0.0000000e+00 2.57e-13 1.49e-01 -1.0 3.16e-05 - 9.91e-01 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.0672779846629121e-13 2.5723867480564877e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.0672779846629121e-13 2.5723867480564877e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.067\n", - "Total CPU secs in NLP function evaluations = 0.000\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.9\n" - ] - } - ], - "source": [ - "n_para = len(parameter_dict)\n", - "\n", - "t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - "parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", - " \n", - "measurements = MeasurementVariables()\n", - "measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", - " \n", - "exp_design = DesignVariables()\n", - "exp_design.add_variables(\n", - " \"CA0\",\n", - " indices={0: [0]},\n", - " time_index_position=0,\n", - " lower_bounds=1,\n", - " upper_bounds=5,\n", - " )\n", - "exp_design.add_variables(\n", - " \"T\",\n", - " indices={0: t_control},\n", - " time_index_position=0,\n", - " lower_bounds=300,\n", - " upper_bounds=700,\n", - " )\n", - "\n", - "exp_design.update_values({\"CA0[0]\": 5, \"T[0]\": 450, \"T[0.125]\": 300, \"T[0.25]\": 300, \"T[0.375]\": 300, \"T[0.5]\": 300, \"T[0.625]\": 300,\n", - " \"T[0.75]\": 300, \"T[0.875]\": 300, \"T[1]\": 300})\n", - " \n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict,\n", - " exp_design, \n", - " measurements, \n", - " create_model,\n", - " discretize_model=disc_for_measure,\n", - " )\n", - "\n", - "result = doe_object.compute_FIM(\n", - " mode=\"sequential_finite\",\n", - " scale_nominal_param_value=True,\n", - " formula=\"central\",\n", - " )\n", - "\n", - "result.result_analysis()\n", - "\n", - "FIM_prior = result.FIM\n", - "FIM_new = np.zeros((n_para, n_para))\n", - "A_vals = []\n", - "D_vals = []\n", - "exp_conds = []\n", - "FIM_opt = None\n", - "\n", - "def get_exp_conds(m):\n", - " return [pyo.value(m.CA0[0]), pyo.value(m.T[0]), pyo.value(m.T[0.125]), pyo.value(m.T[0.25]), pyo.value(m.T[0.375]), pyo.value(m.T[0.5]), pyo.value(m.T[0.625]), pyo.value(m.T[0.75]), pyo.value(m.T[0.875]), pyo.value(m.T[1])]\n", - "\n", - "for i in range(20):\n", - " FIM_prior += FIM_new\n", - " \n", - " doe_object = DesignOfExperiments(\n", - " parameter_dict,\n", - " exp_design, \n", - " measurements, \n", - " create_model,\n", - " prior_FIM=FIM_prior,\n", - " discretize_model=disc_for_measure,\n", - " )\n", - " \n", - " square_result, optimize_result = doe_object.stochastic_program(\n", - " if_optimize=True,\n", - " if_Cholesky=True,\n", - " scale_nominal_param_value=True,\n", - " objective_option=\"det\",\n", - " L_initial=np.linalg.cholesky(FIM_prior),\n", - " )\n", - " FIM_new = optimize_result.FIM\n", - " \n", - " new_exp_conds = get_exp_conds(optimize_result.model)\n", - " result = new_doe_object2(new_exp_conds[0], new_exp_conds[1:], FIM_new)\n", - "\n", - " if FIM_opt is None:\n", - " FIM_opt = [result.FIM, ]\n", - " else:\n", - " FIM_opt.append(result.FIM)\n", - " \n", - " D_opt = np.linalg.det(FIM_new)\n", - " # A_vals.append(np.log10(A_opt))\n", - " D_vals.append(np.log10(D_opt))\n", - " exp_conds.append(new_exp_conds)" - ] - }, - { - "cell_type": "code", - "execution_count": 109, - "id": "8d7175ef-92b3-44f4-8bbb-5af12527e668", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAGdCAYAAACyzRGfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAABRRklEQVR4nO3dd3wUBf7/8demF5JQ0ygxIhCaCAgEFFA5EfyJBT0ULOBZIAVpimI50VM6iJQk551iQ8EC6H3BgpSA9GCQmlClh0CAJCQhdX5/LCwJSYBAks1m38/HYx6zOzM7+xnHuG8/00yGYRiIiIiIVBIHaxcgIiIi9kXhQ0RERCqVwoeIiIhUKoUPERERqVQKHyIiIlKpFD5ERESkUil8iIiISKVS+BAREZFK5WTtAi5XUFDAsWPH8PLywmQyWbscERERuQaGYZCenk5gYCAODlfubVS58HHs2DEaNmxo7TJERETkOhw+fJgGDRpccZkqFz68vLwAc/He3t5WrkZERESuRVpaGg0bNrT8jl9JlQsfFw+1eHt7K3yIiIjYmGs5ZUInnIqIiEilUvgQERGRSqXwISIiIpVK4UNEREQqlcKHiIiIVCqFDxEREalUCh8iIiJSqRQ+REREpFIpfIiIiEilUvgQERGRSqXwISIiIpVK4UNEREQqlcKHiIiIncjOzua9997jzTfftGodVe6ptiIiIlL+li9fTnh4OImJiTg6OjJw4ECaNGlilVrU+RAREanGkpKSePLJJ+nRoweJiYn4+/vzxRdfcMstt1itJoUPERGRaig/P5/Zs2cTEhLCV199hYODA5GRkSQkJNC/f39MJpPVatNhFxERkWomLi6OsLAw4uLiALj99tuJiYmhffv2Vq7MTJ0PERGRauLs2bNERkbSsWNH4uLi8PHxYfbs2axfv77KBA9Q50NERMTmGYbB119/zciRIzlx4gQATz75JFOmTMHf39/K1RWn8CEiImLDEhMTiYiIYNmyZQA0bdqUqKgoevToYeXKSqfDLiIiIjYoKyuLf/7zn9x6660sW7YMNzc3/vWvf7F169YqHTxAnQ8RERGb89NPPxEZGcn+/fsB6N27N7NmzeLmm2+2cmXXRp0PERERG3HkyBEee+wx7r//fvbv30/9+vX57rvvWLx4sc0ED1D4EBERqfLy8vL44IMPaN68Od9//z2Ojo6MHDmSXbt28eijj1r1nh3XQ4ddREREqrB169YRFhbGn3/+CUDnzp2Jjo6mTZs2Vq7s+qnzISIiUgWdPn2aF198kS5duvDnn39Sq1YtPvroI37//XebDh6gzoeIiEiVYhgGn332Ga+88gqnTp0CYNCgQUyaNIl69epZubryofAhIiJSRezYsYOwsDBWr14NQMuWLYmOjqZr165Wrqx86bCLiIiIlWVkZPDqq69y2223sXr1ajw8PJg4cSLx8fHVLniAOh8iIiJW9eOPPzJ06FAOHToEwEMPPcSHH35IUFCQlSurOAofIiIiVnDw4EFeeuklfvzxRwCCgoKYOXMmffr0sXJlFU+HXURERCpRbm4uEydOpEWLFvz44484OTnx6quvsmPHDrsIHqDOh4iISKVZtWoVYWFh7Ny5E4Bu3boRFRVFy5YtrVxZ5VLnQ0REpIKdPHmSZ599lu7du7Nz507q1q3LZ599xsqVK+0ueIDCh4iISIUpKCjgP//5D82aNePTTz8F4MUXXyQxMZFnnnnG5m6LXl502EVERKQC/Pnnn4SFhbFu3ToA2rRpQ0xMDKGhoVauzPrU+RARESlH6enpjBw5kvbt27Nu3Tpq1KjBBx98QFxcnILHBep8iIiIlAPDMPj+++8ZPnw4R48eBeCxxx5j+vTp1K9f38rVVS0KHyIiIjdo3759REZG8vPPPwNw8803M3v2bHr16mXlyqomHXYRERG5TtnZ2bz33nu0atWKn3/+GRcXF/75z3+yfft2BY8rUOdDRETkOixfvpzw8HASExMB6NGjB1FRUTRt2tTKlVV96nyIiIiUQVJSEk899RQ9evQgMTERf39/vvrqK5YuXargcY0UPkRERK5Bfn4+s2fPJiQkhLlz52IymYiMjCQhIYH+/fvb7T07rocOu4iIiFzF5s2bGTJkCHFxcQC0b9+emJgYbr/9ditXZpvU+RARESlFamoqQ4cOpWPHjsTFxeHj48Ps2bPZsGGDgscNUOdDRETkMoZhMG/ePEaOHElSUhIATz75JFOmTMHf39/K1dk+hQ8REZFCdu/eTUREBL/99hsATZs2JSoqih49eli5supDh11ERESArKws/vnPf9K6dWt+++033Nzc+Ne//sXWrVsVPMqZOh8iImL3fv75ZyIjI9m3bx8AvXv3ZtasWdx8881Wrqx6UudDRETs1tGjR+nXrx+9e/dm37591K9fn++++47FixcreFQghQ8REbE7eXl5TJ8+nZCQEL799lscHR0ZOXIku3bt4tFHH9U9OyqYDruIiIhdWb9+PWFhYWzZsgWAzp07Ex0dTZs2baxbmB0pU+dj/PjxdOjQAS8vL3x9fXn44Yct97S/aNCgQZhMpiJDaGhouRYtIiJSVqdPn2bw4MF06dKFLVu2UKtWLT766CN+//13BY9KVqbwERsbS0REBOvXr2fp0qXk5eXRs2dPMjIyiizXq1cvjh8/bhmWLFlSrkWLiIhcK8Mw+OyzzwgJCeGjjz7CMAwGDRpEYmIiL7zwAg4OOgOhspXpsMvPP/9c5P2cOXPw9fVl8+bNdOvWzTLd1dVVN2ERERGr27lzJ2FhYaxatQqAli1bEh0dTdeuXa1cmX27obiXmpoKQO3atYtMX7lyJb6+vjRt2pQXXniB5OTkUteRnZ1NWlpakUFERORGZGZmMmbMGNq0acOqVavw8PBg4sSJxMfHK3hUASbDMIzr+aBhGDz00EOcOXOG1atXW6bPnz+fGjVqEBQUxIEDB3jrrbfIy8tj8+bNuLq6FlvP2LFjeeedd4pNT01Nxdvb+3pKExERO/a///2PoUOHcvDgQQAeeughPvzwQ4KCgqxcWfWWlpaGj4/PNf1+X3f4iIiIYPHixfz+++80aNCg1OWOHz9OUFAQ8+bNo2/fvsXmZ2dnk52dXaT4hg0bKnyIiEiZHDp0iJdeeokffvgBgKCgIGbOnEmfPn2sXJl9KEv4uK5LbYcOHcqPP/7IqlWrrhg8AAICAggKCmLPnj0lznd1dS2xIyIiInItcnNz+eCDD3jnnXfIzMzEycmJUaNG8dZbb+Hp6Wnt8qQEZQofhmEwdOhQFi5cyMqVKwkODr7qZ1JSUjh8+DABAQHXXaSIiEhJVq9eTVhYGDt27ACgW7duREVF0bJlSytXJldSphNOIyIi+PLLL/nqq6/w8vIiKSmJpKQksrKyADh37hwvv/wy69at46+//mLlypX06dOHunXr8sgjj1TIBoiIiP05efIkzz77LN26dWPHjh3UrVuXTz/9lJUrVyp42IAynfNR2u1m58yZw6BBg8jKyuLhhx8mPj6es2fPEhAQwN13382//vUvGjZseE3fUZZjRiIiYl8KCgr4+OOPee211zh9+jQAL774IuPHjy925aVUrgo75+NqOcXd3Z1ffvmlLKsUERG5Jn/++SdhYWGsW7cOgDZt2hAdHU3nzp2tXJmUlW7rJiIiVVp6ejojR46kffv2rFu3jho1ajBt2jTi4uIUPGyUHiwnIiJVkmEYLFiwgGHDhnH06FEAHnvsMT744IOrXmkpVZvCh4iIVDn79+8nMjKSn376CYCbb76Z2bNn06tXLytXJuVBh11ERKTKyM7O5r333qNly5b89NNPuLi48NZbb7F9+3YFj2pEnQ8REakSli9fTnh4OImJiQD06NGD2bNn06xZMytXJuVNnQ8REbGqpKQknnzySXr06EFiYiJ+fn7MnTuXpUuXKnhUUwofIiJiFfn5+cyePZuQkBC++uorTCYTERERJCQkMGDAgFLvLSW2T4ddRESk0m3evJkhQ4YQFxcHQPv27YmJieH222+3cmVSGdT5EBGRSpOamkpkZCQdOnQgLi4Ob29vZs2axYYNGxQ87Ig6HyIiUuEMw2DevHmMHDmSpKQkAPr378/UqVP14FE7pPAhIiIVavfu3YSHh7Ns2TIAmjZtSlRUFD169LByZWItOuwiIiIVIisri3/+85+0bt2aZcuW4erqyrvvvsvWrVsVPOycOh8iIlLufv75ZyIjI9m3bx8AvXr1YtasWTRu3NjKlUlVoM6HiIiUm6NHj9KvXz969+7Nvn37CAwM5Ntvv2XJkiUKHmKh8CEiIjcsLy+P6dOnExISwrfffouDgwMjRowgISGBxx57TPfskCJ02EVERG7I+vXrCQsLY8uWLQCEhoYSHR3NbbfdZtW6pOpS50NERK7L6dOnGTx4MF26dGHLli3UqlWLjz76iDVr1ih4yBWp8yEiImViGAZffPEFL7/8MidPngRg4MCBTJ48mXr16lm5OrEFCh8iInLNdu7cSXh4OLGxsQC0aNGC6OhounXrZuXKxJbosIuIiFxVZmYmY8aMoU2bNsTGxuLu7s6ECROIj49X8JAyU+dDRESu6P/+7/+IjIzk4MGDADz44IPMmDGDoKAgK1cmtkqdDxERKdGhQ4d45JFH6NOnDwcPHqRRo0b88MMP/PDDDwoeckMUPkREpIjc3FwmT55M8+bNWbRoEU5OTrz66qvs3LmTBx980NrlSTWgwy4iImLx+++/ExYWxvbt2wHo2rUr0dHRtGzZ0sqVSXWizoeIiHDq1Cn+8Y9/0LVrV7Zv307dunWZM2cOsbGxCh5S7hQ+RETsWEFBAf/9739p1qwZc+bMAeCFF14gISGBQYMG6bboUiF02EVExE5t3bqVsLAw1q5dC0CbNm2Ijo6mc+fOVq5Mqjt1PkRE7Ex6ejqjRo2iXbt2rF27lho1ajBt2jTi4uIUPKRSqPMhImInDMNgwYIFDBs2jKNHjwLw2GOP8cEHH9CgQQMrVyf2ROFDRMQO7N+/n6FDh7JkyRIAbr75ZmbNmkXv3r2tXJnYIx12ERGpxrKzs3n//fdp2bIlS5YswcXFhbfeeovt27creIjVqPMhIlJNLV++nPDwcBITEwHo0aMHs2fPplmzZlauTOydOh8iItXMiRMneOqpp+jRoweJiYn4+fkxd+5cli5dquAhVYLCh4hINZGfn09UVBTNmjVj7ty5mEwmIiIiSEhIYMCAAbpnh1QZOuwiIlINbN68mbCwMDZt2gRA+/btiYmJ4fbbb7dyZSLFqfMhImLDUlNTGTp0KB07dmTTpk14e3sza9YsNmzYoOAhVZY6HyIiNsgwDObPn8+IESNISkoCYMCAAUydOhV/f38rVydyZQofIiI2Zvfu3URERPDbb78B0LRpU6KioujRo4eVKxO5NjrsIiJiI86fP8/bb79N69at+e2333B1deXdd99l69atCh5iU9T5EBGxAb/88gsRERHs27cPgF69ejFr1iwaN25s5cpEyk6dDxGRKuzo0aP069ePXr16sW/fPgIDA/n2229ZsmSJgofYLIUPEZEqKC8vjw8//JDmzZvz7bff4uDgwIgRI0hISOCxxx7TPTvEpumwi4hIFbNhwwaGDBnCli1bAAgNDSU6OprbbrvNqnWJlBd1PkREqogzZ84wZMgQOnfuzJYtW6hVqxb//ve/WbNmjYKHVCvqfIiIWJlhGHzxxRe8/PLLnDx5EoCBAwcyadIkfH19rVydSPlT+BARsaKdO3cSHh5ObGwsAC1atCA6Oppu3bpZuTKRiqPDLiIiVpCZmcmYMWNo06YNsbGxuLu7M378eOLj4xU8pNpT50NEpJL93//9H5GRkRw8eBCAPn36MGPGDG666SbrFiZSSdT5EBGpJIcOHeKRRx6hT58+HDx4kEaNGrFo0SJ+/PFHBQ+xKwofIiIVLDc3l8mTJ9O8eXMWLVqEk5MTo0ePZufOnTz00EPWLk+k0pUpfIwfP54OHTrg5eWFr68vDz/8MImJiUWWMQyDsWPHEhgYiLu7O3fddRc7duwo16JFRGzF77//Trt27Rg9ejSZmZl07dqV+Ph4Jk6ciKenp7XLE7GKMoWP2NhYIiIiWL9+PUuXLiUvL4+ePXuSkZFhWWbSpElMmzaNWbNmsWnTJvz9/bn33ntJT08v9+JFRKqqU6dO8dxzz9G1a1e2b99O3bp1mTNnDrGxsbRq1cra5YlYlckwDON6P3zy5El8fX2JjY2lW7duGIZBYGAgw4cP59VXXwUgOzsbPz8/Jk6cyODBg6+6zrS0NHx8fEhNTcXb2/t6SxMRsYqCggLmzJnD6NGjOX36NADPP/88EyZMoE6dOlauTqTilOX3+4bO+UhNTQWgdu3aABw4cICkpCR69uxpWcbV1ZXu3buzdu3aEteRnZ1NWlpakUFExBZt3bqVrl278vzzz3P69GluvfVW1qxZw3/+8x8FD5FCrjt8GIbByJEjufPOOy0txKSkJAD8/PyKLOvn52eZd7nx48fj4+NjGRo2bHi9JYmIWMW5c+d4+eWXadeuHWvXrsXT05OpU6eyefNmunTpYu3yRKqc6w4fkZGRbN26la+//rrYvMuftmgYRqlPYBwzZgypqamW4fDhw9dbkohIpTIMgwULFtC8eXOmTp1Kfn4+jz76KAkJCYwcORInJ91KSaQk1/WXMXToUH788UdWrVpFgwYNLNP9/f0BcwckICDAMj05OblYN+QiV1dXXF1dr6cMERGr2b9/P0OHDmXJkiUABAcHM2vWLO6//34rVyZS9ZWp82EYBpGRkSxYsIDly5cTHBxcZH5wcDD+/v4sXbrUMi0nJ4fY2Fi1HkWkWsjOzub999+nZcuWLFmyBGdnZ95880127Nih4CFyjcrU+YiIiOCrr77ihx9+wMvLy3Ieh4+PD+7u7phMJoYPH864ceNo0qQJTZo0Ydy4cXh4eDBgwIAK2QARkcqyYsUKwsLCLPc3uvvuu4mKiiIkJMTKlYnYljKFj+joaADuuuuuItPnzJnDoEGDABg9ejRZWVmEh4dz5swZOnXqxK+//oqXl1e5FCwiUtlOnDjBqFGjmDt3LgC+vr5MmzaNAQMGlHo+m4iU7obu81ERdJ8PEakq8vPz+fe//83rr79OamoqJpOJsLAw3n//fWrWrGnt8kSqlLL8futUbBGREmzevJmwsDA2bdoEQPv27YmOjqZDhw5WrkzE9unBciIihaSmpvLSSy/RsWNHNm3ahLe3NzNnzmTDhg0KHiLlRJ0PERHMV/PNnz+fESNGWE6m79+/P1OnTi1y6wARuXEKHyJi93bv3k1ERAS//fYbAE2bNmX27Nn87W9/s3JlItWTDruIiN06f/48b7/9Nq1bt+a3337D1dWVd999l61btyp4iFQgdT5ExC798ssvREREsG/fPgB69erFrFmzaNy4sZUrE6n+1PkQEbty9OhR+vXrR69evdi3bx+BgYF88803LFmyRMFDpJIofIiIXcjLy+PDDz+kefPmfPvttzg4ODBixAgSEhL4+9//rpuFiVQiHXYRkWpv/fr1hIWFsWXLFgBCQ0OJjo7mtttus2pdIvZKnQ8RqbZOnz7N4MGD6dKlC1u2bKFWrVr8+9//Zs2aNQoeIlakzoeIVDuGYfDFF1/w8ssvc/LkSQAGDhzIpEmT8PX1tXJ1IqLwISLVys6dOwkPDyc2NhaAFi1aEB0dTbdu3axcmYhcpMMuIlItZGZmMmbMGNq0aUNsbCzu7u5MmDCB+Ph4BQ+RKkadDxGxef/73/8YOnQoBw8eBODBBx9kxowZBAUFWbkyESmJwoeI2KxDhw7x0ksv8cMPPwDQqFEjZsyYwUMPPWTlykTkSnTYRURsTm5uLpMmTaJ58+b88MMPODk5MXr0aHbu3KngIWID1PkQEZuyevVqwsLC2LFjBwBdu3YlKiqKVq1aWbkyEblW6nyIiE04efIkzz77LN26dWPHjh3UrVuXOXPmEBsbq+AhYmMUPkSkSisoKOC///0vISEhfPrppwC88MILJCQkMGjQIN0WXcQG6bCLiFRZW7duZciQIaxbtw6AW2+9lZiYGDp37mzlykTkRqjzISJVTnp6OqNGjaJdu3asW7eOGjVqMG3aNDZv3qzgIVINqPMhIlWGYRgsWLCAYcOGcfToUQAeffRRpk+fToMGDaxcnYiUF4UPEakS9u/fz9ChQ1myZAkAwcHBzJ49m969e1u5MhEpbzrsIiJWlZ2dzfvvv0/Lli1ZsmQJzs7OvPnmm+zYsUPBQ6SaUudDRKxmxYoVhIWFkZiYCMDdd99NVFQUISEhVq5MRCqSOh8iUulOnDjBU089xT333ENiYiK+vr58+eWXLFu2TMFDxA4ofIhIpcnPzyc6OppmzZoxd+5cTCYT4eHhJCYm8uSTT+qeHSJ2QoddRKRS/PHHHwwZMoRNmzYB0K5dO2JiYujQoYOVKxORyqbOh4hUqNTUVF566SU6dOjApk2b8Pb2ZsaMGWzcuFHBQ8ROqfMhIhXCMAy++eYbRowYwfHjxwHo378/U6dOJSAgwMrViYg1KXyISLnbs2cPERERLF26FIAmTZoQFRXF3/72NytXJiJVgQ67iEi5OX/+PGPHjqV169YsXboUV1dX3nnnHbZu3argISIW6nyISLn49ddfiYiIYO/evQDcd999zJo1i1tuucXKlYlIVaPOh4jckGPHjvHEE09w3333sXfvXgIDA/nmm2/46aefFDxEpEQKHyJyXfLy8pgxYwbNmzdn/vz5ODg4MGzYMHbt2sXf//533bNDREqlwy4iUmYbN25kyJAhxMfHA9CpUyeio6Np27atlSsTEVugzoeIXLMzZ84QFhZGaGgo8fHx1KxZk5iYGNauXavgISLXTJ0PEbkqwzCYO3cuo0aNIjk5GYBnnnmGyZMn4+vra+XqRMTWKHyIyBUlJCQQHh7OihUrAGjevDnR0dF0797dypWJiK3SYRcRKVFmZiZvvPEGt956KytWrMDd3Z3x48ezZcsWBQ8RuSHqfIhIMYsXLyYyMpK//voLgAceeICZM2dy0003WbUuEake1PkQEYvDhw/Tt29fHnjgAf766y8aNmzIwoUL+fHHHxU8RKTcKHyICLm5uUyZMoXmzZuzcOFCnJyceOWVV9i5cycPP/yw7tkhIuVKh11E7NyaNWsICwtj27ZtANx5551ER0fTqlUrK1cmItWVOh8idurUqVM899xz3HnnnWzbto06derwySefEBsbq+AhIhVKnQ8RO1NQUMCcOXN49dVXSUlJAeD5559nwoQJ1KlTx8rViYg9UPgQsSPbtm0jLCyMNWvWANC6dWuio6O54447rFyZiNgTHXYRsQPnzp3jlVdeoW3btqxZswZPT0+mTJnC5s2bFTxEpNKp8yFSjRmGwaJFixg2bBiHDx8GoG/fvkyfPp2GDRtauToRsVdl7nysWrWKPn36EBgYiMlkYtGiRUXmDxo0CJPJVGQIDQ0tr3pF5BodOHCAPn360LdvXw4fPkxwcDCLFy/m+++/V/AQEasqc/jIyMigTZs2zJo1q9RlevXqxfHjxy3DkiVLbqhIEbl2OTk5jBs3jpYtW7J48WKcnZ1544032L59O/fff7+1yxMRKfthl969e9O7d+8rLuPq6oq/v/91FyUi12flypWEhYWRkJAAwN13301UVBQhISFWrkxE5JIKOeF05cqV+Pr60rRpU1544QXLI7hLkp2dTVpaWpFBRMomOTmZZ555hrvvvpuEhAR8fX358ssvWbZsmYKHiFQ55R4+evfuzdy5c1m+fDlTp05l06ZN3HPPPWRnZ5e4/Pjx4/Hx8bEMOhYtcu0KCgqIiYmhWbNmfPHFF5hMJkvn48knn9Rt0UWkSjIZhmFc94dNJhYuXMjDDz9c6jLHjx8nKCiIefPm0bdv32Lzs7OziwSTtLQ0GjZsSGpqKt7e3tdbmki1Fx8fz5AhQ9i4cSMA7dq1Izo6mo4dO1q5MhGxR2lpafj4+FzT73eFX2obEBBAUFAQe/bsKXG+q6srrq6uFV2GSLWRlpbGW2+9xaxZsygoKMDb25v33nuP8PBwHB0drV2eiMhVVXj4SElJ4fDhwwQEBFT0V4lUa4Zh8M033zBixAiOHz8OwBNPPMG0adP09yUiNqXM4ePcuXPs3bvX8v7AgQNs2bKF2rVrU7t2bcaOHcujjz5KQEAAf/31F6+//jp169blkUceKdfCRezJnj17iIyM5NdffwWgSZMmzJ49m3vvvdfKlYmIlF2Zw0dcXBx333235f3IkSMBGDhwINHR0Wzbto3PP/+cs2fPEhAQwN133838+fPx8vIqv6pF7MT58+eZOHEi48ePJzs7G1dXV15//XVGjx6Nm5ubtcsTEbkuN3TCaUUoywkrItXZ0qVLCQ8Pt3Qae/bsyezZs7nlllusXJmISHFl+f3Wg+VEqphjx47xxBNP0LNnT/bu3UtAQADz58/n559/VvAQkWpB4UOkisjPz2fGjBmEhIQwf/58HBwcGDZsGAkJCfTr10/37BCRakNPtRWpAjZu3MiQIUOIj48HoGPHjsTExNC2bVsrVyYiUv7U+RCxojNnzhAeHk5oaCjx8fHUrFmT6Oho1q5dq+AhItWWOh8iVmAYBnPnzmXUqFGWZx89/fTTTJ48GT8/PytXJyJSsRQ+RCpZQkIC4eHhrFixAoDmzZsTFRXFXXfdZd3CREQqiQ67iFSSzMxM3njjDW699VZWrFiBu7s748aNY8uWLQoeImJX1PkQqQSLFy8mMjKSv/76C4AHHniAGTNmEBwcbN3CRESsQOFDpAIdPnyYYcOGsXDhQgAaNGjAzJkzeeihh3TprIjYLR12EakAubm5TJkyhebNm7Nw4UIcHR15+eWX2bVrFw8//LCCh4jYNXU+RMrZmjVrCAsLY9u2bQDccccdREdH07p1aytXJiJSNajzIVJOUlJSeP7557nzzjvZtm0bderU4eOPP2bVqlUKHiIihajzIXKDCgoK+PTTTxk9ejQpKSkAPPfcc0ycOJE6depYuToRkapH4UPkBmzbto2wsDDWrFkDQOvWrYmOjuaOO+6wcmUiIlWXDruIXIdz587xyiuv0LZtW9asWYOnpydTpkxh8+bNCh4iIlehzodIGRiGwaJFixg2bBiHDx8GoG/fvkyfPp2GDRtauToREdug8CFyjQ4cOMDQoUNZvHgxAMHBwcyaNYv777/fypWJiNgWHXYRuYqcnBzGjx9Py5YtWbx4Mc7Ozrz++uts375dwUNE5Dqo8yFyBStXriQ8PJxdu3YBcNdddxEVFUXz5s2tXJmIiO1S50OkBMnJyTzzzDPcfffd7Nq1C19fX7744guWL1+u4CEicoMUPkQKKSgoICYmhmbNmvHFF19gMpkICwsjISGBp556SrdFFxEpBzrsInJBfHw8Q4YMYePGjQC0a9eO6OhoOnbsaOXKRESqF3U+xO6lpaUxbNgwbr/9djZu3IiXlxczZsxg48aNCh4iIhVAnQ+xW4Zh8O233zJ8+HCOHz8OwOOPP860adMIDAy0cnUiItWXwofYpb179xIREcGvv/4KwC233EJUVBT33nuvlSsTEan+dNhF7Mr58+d55513aNWqFb/++iuurq6MHTuWbdu2KXiIiFQSdT7EbixdupTw8HD27t0LQM+ePZk9eza33HKLlSsTEbEv6nxItXfs2DGeeOIJevbsyd69ewkICGD+/Pn8/PPPCh4iIlag8CHVVn5+PjNmzCAkJIT58+fj4ODAsGHDSEhIoF+/frpnh4iIleiwi1RLGzduZMiQIcTHxwPQsWNHYmJiaNu2rZUrExERdT6kWjlz5gxhYWGEhoYSHx9PzZo1iY6OZu3atQoeIiJVhDofUi0YhsHcuXMZNWoUycnJADz99NNMnjwZPz8/K1cnIiKFKXyIzdu1axcRERGsWLECgObNmxMVFcVdd91l3cJERKREOuwiNisjI4MxY8bQpk0bVqxYgbu7O+PGjWPLli0KHiIiVZg6H2JzDMPghx9+YNiwYRw6dAiAPn368OGHHxIcHGzl6kRE5GoUPsSm7N+/n6FDh7JkyRIAgoKCmDFjBg8++KCVKxMRkWulwy5iE86fP8+//vUvWrZsyZIlS3B2dub1119n586dCh4iIjZGnQ+p8n799VciIiIst0Xv0aMHs2fPplmzZlauTEREroc6H1JlHTlyhH79+nHfffdZbos+b948li5dquAhImLDFD6kysnNzWXq1KmEhITw7bff4ujoyPDhw0lISODxxx/XbdFFRGycDrtIlbJ69WrCw8PZvn07AF26dCEqKoo2bdpYuTIRESkv6nxIlZCcnMygQYPo1q0b27dvp27dunzyySesXr1awUNEpJpR+BCrys/PJzo6mmbNmvHZZ59hMpkYPHgwiYmJPPvsszg46F9REZHqRoddxGo2bdpEeHg4cXFxALRt25bo6Gg6depk5cpERKQi6X8rpdKdOXOG8PBwOnXqRFxcHD4+PsyaNYtNmzYpeIiI2AF1PqTSGIbB559/ziuvvMLJkycBPXlWRMQeKXxIpdi+fTvh4eGsXr0agBYtWhAVFUX37t2tXJmIiFQ2HXaRCpWZmclrr71G27ZtWb16NR4eHkyaNIktW7YoeIiI2Cl1PqTC/PLLL4SFhXHgwAEA+vbty/Tp02nYsKGVKxMREWtS50PK3YkTJxgwYAC9evXiwIEDNGzYkB9//JHvv/9ewUNERMoePlatWkWfPn0IDAzEZDKxaNGiIvMNw2Ds2LEEBgbi7u7OXXfdxY4dO8qrXqnCCgoK+M9//kNISAhff/01Dg4OjBgxgp07d9KnTx9rlyciIlVEmcNHRkYGbdq0YdasWSXOnzRpEtOmTbNcOunv78+9995Lenr6DRcrVdfOnTvp3r07L774ImfPnqV9+/Zs2rSJadOmUaNGDWuXJyIiVUiZz/no3bs3vXv3LnGeYRhMnz6dN954g759+wLw2Wef4efnx1dffcXgwYNvrFqpcrKyshg3bhwTJ04kNzcXT09P3nvvPSIjI3Fy0ilFIiJSXLme83HgwAGSkpLo2bOnZZqrqyvdu3dn7dq1JX4mOzubtLS0IoPYhmXLlnHrrbfy3nvvkZuby4MPPsiuXbsYPny4goeIiJSqXMNHUlISQLEbRvn5+VnmXW78+PH4+PhYBp2QWPWdPHmSZ555hr/97W/s3buXwMBAFixYwKJFi7T/RETkqirkaheTyVTkvWEYxaZdNGbMGFJTUy3D4cOHK6IkKQeGYTBnzhxCQkL44osvMJlMDB06lF27dvHII4+Uuo9FREQKK9feuL+/P2DugAQEBFimJycnl3r7bFdXV1xdXcuzDKkAiYmJDB48mNjYWADatGnDRx99RMeOHa1cmYiI2Jpy7XwEBwfj7+/P0qVLLdNycnKIjY2lS5cu5flVUkmys7MZO3Yst956K7GxsXh4eDB58mTi4uIUPEREbIRhGGTlZpGSmcKRtCPsO73PqvWUufNx7tw59u7da3l/4MABtmzZQu3atWnUqBHDhw9n3LhxNGnShCZNmjBu3Dg8PDwYMGBAuRYuFS82NpbBgweTmJgImK90ioqK4qabbrJuYSIi1UReQR4ZORlk5maSmZtJRu6l15m5mWTlZpGVl2V5nZmbWfR9XinTL3uflZdV5Hs9nT059/o5K231dYSPuLg47r77bsv7kSNHAjBw4EA+/fRTRo8eTVZWFuHh4Zw5c4ZOnTrx66+/4uXlVX5VS4VKSUnhlVdeYc6cOYD5cNqHH37I3//+d53XISJ2wzAMcvJzyMjNICMng3M554q8LhwSCocGS5jIyyw1WFycnluQW+nb5ezgjIujyxXPx6xoJsMwDKt8cynS0tLw8fEhNTUVb29va5djVwzD4Msvv2TkyJGcOnUKk8nEkCFDGDduHDVr1rR2eSIiJcrNz7WEgos/8hk5GaWGBsvr3HOW5c7llPw6ryCvUrbBhAlPF088nD3wdPbE3dkdD2cPPJw9cHcyv3Z3dsfDycMyr8j0q7wv/NrJoWJuhVCW32/djEEA2LNnD2FhYSxbtgyAVq1a8dFHH9G5c2crVyYits4wDLLysor8+Bf+gb/YCSgcGopMu8oyldE9cHF0wdPZE08XT2q41LC8vhgQPJ1LeV3KMpfPc3V0tavOssKHnTt//jwTJ05k/PjxZGdn4+bmxttvv82oUaNwdna2dnkiUokuhoRzOedIz04vFhTO5ZwrcZrlfWnTczIwqPgmu6PJsUj34PKgYHntfOG1y7W/dnbUfw/Lk8KHHVu6dCnh4eGWE4h79uxJVFQUjRs3tnJlInIt8gryigSF9Jz0a3t/YVzSvAKjoEJrdndyL/KjfnF8sRNwMRxcHiKKLVPCNBdHF7vqHtgyhQ87dOzYMUaOHMn8+fMBCAgIYPr06TqhVKQS5Bfkk56TTnp2OmnZaaRlp5GeY359cVqR9zlppc67/AqG8lTDpYZlKNwFKPK+lE5BaZ/xcPbA0cGxwmoW26HwYUfy8/OZPXs2b775Junp6Tg4ODB06FDeffddndwrchWGYZCRm0Hq+VRSs1Mt47TstGLTCk+/PGBk5maWe20uji54uXhRw6UGXq4XxhfeF359+bzS3ns4e+BgqpAbYIsACh92Y9OmTQwZMoQ//vgDgI4dOxITE0Pbtm2tXJlI5cjOy+bM+TOcPX+WM1nm8cWhtOBwecgoz0MSLo4ueLt64+3qjZeLl3ns6lXk/VXnXQgLLo4u5VaXSGVQ+Kjmzp49y+uvv05MTAyGYVCzZk0mTJjA888/j6Oj2p9iO/IL8knLTisxQBSZln22yPyL887nnS+XOhxNjvi4+eDj6mMZe7t6X5pWwvTLQ4SXixeuTnqshNgvhY9qyjAM5s6dy6hRo0hOTgbgmWeeYfLkyfj6+lq5OpGiDMMgJSuFfaf3se/MPst4/5n9HEo9ZOlO3CgTJnzcfKjpVpNabrWo6VazxNBwpXDh4eyhc6NEbpDCRzWUkJBAeHg4K1asAKB58+ZERUVx1113WbcwsWt5BXkcTj1sCRWWoHHhfVp22jWtx8PZo0h4qOlWk1rutajpWuh1SfPdauLt6q1zGUSqAIWPaiQzM5P333+fyZMnk5ubi7u7O2+99RajRo3CxUXHhKXiZeRkmIPFZd2LfWf28dfZv656t8j6XvVpXLsxjWuZh5tr3cxNNW+ijkcdc5fC1UeHK0SqAYWPamLx4sVERkby119/AfDAAw8wY8YMgoODrVuY2LzzeedJyUzhVOYpUrJSSMlMsYxPZZ7iZOZJDpw9wL7T+ziRceKK63J1dCW4VnCRcHExbATXCsbNya2StkpErEnhw8YdPnyY4cOHs2DBAgAaNGjAzJkzeeihh3RcWoowDIP0nPQrBomUrOLvy3ppaG332peCRa3GlnBxc62bqe9dX4c9REThw1bl5uYyY8YM3n77bTIyMnB0dGTEiBG8/fbb1KhRw9rlSSUwDIO07DSSM5JJzkjmZOZJy+vLp53MOMnprNPX/QwMJwcn6rjXoY5HHcu4rntdy/ugmkGWoFHTrWb5bqiIVDsKHzZo7dq1DBkyhG3btgFwxx13EB0dTevWra1cmdyorNysEsNDaaEiJz+nzN/h7uROXY+6pQaJi+PCy3i7equTJiLlRuHDhqSkpPDqq6/y8ccfA1CnTh0mTZrEoEGDcHBQK7uqKjAKOJV5iuPpxzl+7rhlfCz9mOX9iYwTJGckcy7nXJnX7+Xiha+nL/U86+Hr6Yuvh695fGGo51mPeh71LEHC3dm9ArZSROTaKXzYgIKCAj755BNee+01UlJSAHjuueeYOHEiderUsXJ19iu/IJ/kjOQiIeLi+Ni5Y5b3SeeSrnqVR2Euji74efpdChOXBYrC0+t51FOYEBGbo/BRxW3YsIHIyEji4uIAaN26NdHR0dxxxx1Wrqx6y8jJ4FDqIctwOO1wsY5FckZymW63Xc+jHgFeAQTUCCDQK5CAGgGW9/41/PGr4Yevpy9eLl46xCEi1ZrCRxV14sQJxowZw5w5cwDw9vbmnXfeISIiAmdnZytXZ9sKjAKSziUVCReXDylZKde0LgeTA76evpfCxIVAcXm48Kvhp+dviIhcoPBRxeTm5jJ79mzefvtt0tLMd3wcNGgQEyZMwM/Pz8rV2YZzOeeuGCyOpB25pqs+vFy8CKoZRCOfRjT0blgkUFx87evpq0eEi4iUkcJHFbJ8+XKGDh3Kzp07Abj99tuZOXMmoaGhVq6sajEMg2Ppx9idsps9p/ewO2U3e0/v5WDqQQ6lHuJ01umrrsPR5Eh97/o08mlkHrwbXXp9YfBx86mErRERsT8KH1XAoUOHGDVqFN999x0AdevWZfz48fzjH/+w26tYLj5obHfKbvak7CkWNDJyM674eR9Xn2JhovAQ6BWIk4P+9RcRsQb919eKzp8/z5QpUxg3bhxZWVk4ODgQERHBO++8Q61ataxdXqVIy05jT8oeS7C4ON6dspuz58+W+jlHkyPBtYJpUrsJTes0pUntJgTXCrYcIlHXQkSk6lL4sALDMPjf//7HiBEj2L9/PwDdunVj5syZ3HrrrVaurvwZhsHe03vZnry9WMC42rNAGno3tISLpnWa0qSOeRxcMxhnR514KyJiixQ+Ktnu3bsZNmwYP//8MwD169dnypQpPP7449Xm8krDMNh1ahexf8USezCWVQdXcfzc8VKX9/X0LRowLowb126Mh7NHJVYuIiKVQeGjkqSnp/Pee+/xwQcfkJubi7OzM6NGjeKNN96w+WexFBgFbE/eXiRsnMw8WWQZF0cXbvW7laZ1mtK09qUORpPaTXSIRETEzih8VDDDMPjqq68YPXo0x44dA+D+++9n+vTpNGnSxMrVXZ/8gnz+PPGnJWysPrS62BUm7k7udG7Yme5B3eke1J1ODTrpcekiIgIofFSoP//8k6FDh7J69WoAGjduzPTp03nggQesXFnZ5BXk8cfxPyxh4/dDv5OanVpkGU9nT+5odIclbHSo30E31RIRkRIpfFSA06dP89ZbbxETE0NBQQEeHh68/vrrjBo1Cje3qv9//zn5OcQdi7OEjTWH1xR74Jm3qzd3NrrTEjbaBbTTCaAiInJNFD7KUX5+Pv/973954403LA+A69evH1OmTKFhw4ZWrq506dnpxB2L4/dDvxN7MJa1h9eSlZdVZJlabrXoGtTVEjZu879Nd/YUEZHrovBRTnbv3s2AAQPYvHkzAK1atWLGjBncfffdVq6sqAKjgIRTCaw/sp71R9az4egGtidvL/aAtLoedekW1M0SNlr7tcbBZJ83PBMRkfKl8FEOFi1axDPPPEN6ejo+Pj68++67hIeH4+Rk/X+8pzJPseHIBjYc3WAJG2nZacWWa+TTiM4NOlsCR4t6LarNpb8iIlK1WP/X0Ybl5eXx1ltvMWHCBAC6du3K/PnzCQgIsEo9ufm5bD2x1dzVOGrubOw9vbfYch7OHnQI7EBog1BCG4TSqX4nArysU7OIiNgfhY/rdPLkSfr378+yZcsAGDFiBBMnTqzUx90fSTtiOXyy/sh6Nh/fzPm888WWC6kbYg4a9c1ho6VvSz3XRERErEa/QNdh48aNPProoxw5cgRPT08++eQT+vXrV6HfmVeQx/oj61l3eB3rj65nw5ENHE0/Wmy5Wm61LB2N0AahdAjsQC13+3hOjIiI2AaFjzIwDIOPPvqIl156iZycHJo2bcrChQtp0aJFhXxfgVHAusPr+Hr713yz45tidw11NDnSxr8NofVD6dSgE6ENQmlSu4nO1RARkSpN4eMaZWVlER4ezqeffgrAI488wqeffoq3t3e5fo9hGGxL3sZX275i3vZ5HEw9aJl38QqUi4dP2ge217NPRETE5ih8XIMDBw7w6KOPEh8fj4ODA+PHj+eVV14p1w7D/jP7+Xrb13y9/Wt2nNxhme7l4sUjzR9hQKsB9Li5h87VEBERm6dfsqv46aefePLJJzlz5gz16tVj3rx53HPPPeWy7qRzSXyz4xu+2vYVG45usEx3cXThgaYP0L9Vf/5fk/+Hu7N7uXyfiIhIVaDwUYqCggL+9a9/8c4772AYBh07duS777674TuVnj1/loW7FvLV9q9YfmC55eZeDiYHegT3oH+r/jzS/BFqutUsh60QERGpehQ+SnDmzBmeeuoplixZAkBYWBgffPABrq6u17W+rNwsFu9ZzFfbvmLxnsXk5OdY5oU2CKV/q/70a9kP/xr+5VK/iIhIVabwcZktW7bQt29fDhw4gJubGzExMQwcOLDM68kryOO3/b/x9favWbhrIek56ZZ5Leq14MnWT/JEqye4udbN5Vm+iIhIlafwUcjnn3/O4MGDOX/+PMHBwSxYsIDbbrvtmj9/pUtjg3yC6N+qP/1b96e1b2tdDisiInZL4QPIzs5mxIgRREdHA3D//ffz5ZdfUqvWtd+c61j6MXp+0bPIlSr1POrRr2U/+rfqT+eGnfVgNhERERQ+OHLkCI899hgbNmzAZDLx9ttv89Zbb+HgULag8P6q99lxcgc1XGrQt3lfXRorIiJSCrv+ZVy+fDlPPPEEJ0+epFatWsydO5fevXuXeT3H0o/xcfzHAPxf//+j+03dy7tUERGRasMujwMYhsGkSZO49957OXnyJLfddhtxcXHXFTwApq6dSnZ+Nnc2upNuQd3KuVoREZHqxe46H2lpaQwaNIiFCxcCMHDgQKKjo3F3v74beZ3MOEnM5hgA3uj6hk4kFRERuQq7Ch87duygb9++7N69G2dnZ2bOnMmLL754Q4Fh+vrpZOZm0j6gPfc1vq8cqxUREame7CZ8xMfH07VrVzIyMmjQoAHfffcdnTp1uqF1nj1/llmbZgHwZrc31fUQERG5BuUePsaOHcs777xTZJqfnx9JSUnl/VVl0rp1azp06ICDgwPz5s2jXr16N7zOWRtnkZadRivfVjzY7MFyqFJEROyKUQC56ZCbCrlp5nFOKuRnQEE+GHlg5Bca8i5ML/S+8PyCvGub5+AEnf5rtc2ukM5Hy5Yt+e233yzvHR0dK+JrysTJyYmFCxdSo0YNnJxufLPP5Zzjg/UfAOZzPXQPDxERO1OQdykwXAwNhd9bpqUWDxeWaemAUfm1O7hWv/Dh5OSEv3/Ve05JzZo1y21dMXExnM46TZPaTfh7i7+X23pFROQKCvIg75x5yD1X6HX6pdcX5xVkQ0GueTDyLoxzL00rPL0s84w8yM+G/Mzy2y4HZ3D2uTQ4eZq7EyYnMDleGhwue194/pXmXT7fwaX8ar8OFRI+9uzZQ2BgIK6urnTq1Ilx48Zx880lP8MkOzub7Oxsy/u0tLSKKKlcZeVmMWXtFABe7/o6jg7W7+yIiNiMvAw4uQYyDhYPDlcKFHnnIP+8tasvztH9QmjwNo9dfIoGCcv7K8x3dLP2VlSqcg8fnTp14vPPP6dp06acOHGC9957jy5durBjxw7q1KlTbPnx48cXO0ekqvs4/mNOZJwgyCeIJ1s/ae1yRESqtvxsSNkAScvhxDLz64LcG1unyQmcvcCphnko/Nqphrlz4OhmXs7Buehgujh2Knm6g1Oh16XMc3QBJ29zoHC0bhfBFpkMw6jQg00ZGRk0btyY0aNHM3LkyGLzS+p8NGzYkNTUVLy9vSuytOuSk59D4xmNOZJ2hKj7owjrEGbtkkREqpaCfDjzB5xYbg4cJ1dDflbRZTwaQa025h/vwqHBuQY4eRV6XaPkgKEf/ConLS0NHx+fa/r9rvBLbT09PWndujV79uwpcb6rqyuurq4VXUa5+fzPzzmSdoSAGgE82/ZZa5cjImJ9hgGpO8xh48RyOLHSfDJlYW6+4HePefDvAZ7BoNsT2K0KDx/Z2dns2rWLrl27VvRXVbi8gjwm/D4BgFe6vIKbk30doxMRAcxh49z+QmFjOZxPLrqMsw/43XUhcPQAnxYKG2JR7uHj5Zdfpk+fPjRq1Ijk5GTee+890tLSGDhwYHl/VaWbv30++87so65HXV5s/6K1yxERqTyZxy4FjaRlkHmo6HxHd6jXFfwvhI1abUEn40spyj18HDlyhP79+3Pq1Cnq1atHaGgo69evJygoqLy/qlIVGAW8v/p9AEaGjsTTxdPKFYmIVBCjADIOwenNlwJHWkLRZRycoU7opcModTqCo+0cQhfrKvfwMW/evPJeZZWwcNdCdp3aRU23mkR0jLB2OSIiNy7nLKQlmof0xEKv95jvkVGECWq3v3Tehu+d5itKRK6D3Tzb5UYYhsF7q98DYGjHoXi7Vr2rcERESlSQaz4/o6SQkX2y9M85uIB3M/C960Lg6A4utSqtbKneFD6uwZI9S9iStAVPZ0+GdRpm7XJERIoyDPMJn4WDxcWgcW6/+VkepXEPNIcMr2bmsXcz8GoKnjfpnA2pMAofV1G46xHeIZw6HsVvlCYiUmnyz8OZLXBqg/mcjLQESN9d/NLWwpw8zYGiSMhoap7m7FVppYtcpPBxFSv+WsH6I+txc3JjZOfiN0kTEakwRgGk7YaUjea7gqZshLN/lnJ3UJO5W+F9WQfDuxm419dlrlKlKHxcxXurzF2PF9q9gH+NqvewPBGpRrJOFA0aKRtL7mi41oM6naBOB/BpeSFo3GJ3zwcR26XwcQVrDq1hxV8rcHZw5pUur1i7HBGpTvIyzYdNCoeNjIPFl3N0M19lUqeT+XLWOp3AM0idDLFpCh9XcPG+HoNuG0RDn4ZWrkZEbFZBPqTtuhQyTm2A1O0lnAhqMt8J9GLIqNMRarYy31NDpBpR+CjF5mOb+WnvTziYHHj1jletXY6IXGQY5h9tI8987sPFcZHXeWDkXva60Lggt9C0PPO5FUb+pTGF319p3mXjy+cV5ELqTjgdZ34c/OXcAy+FjLqdzB0OZ13KL9WfwkcpLnY9BrQeQOPaja1cjUg1ZRRA9inIPAqZRyCr8PjC6+zk4uHCFjnVgNq3m0PGxc6GR31rVyViFQofJdievJ2FCQsxYWLMnWOsXY6IbcrPgaxjRYPE5eEi62j5hQmTo/nwhMnJPC782uQMDiW9drowOILJofiYEqYVHuNwlXmOUOMmc9Dwbq77ZohcoPBRgvG/jwfg0RaP0qJeCytXI1LFFOSZ74x5/gRkJcH5pEtBIvPIhddHij/ltFQm8+PWPRqYLwn1qF/0tZsfOLiWECguCxk6AVPEZih8XGZPyh7mbTc/n+aNrm9YuRqRSnLx8IclUJwwh4rCAePi6+xTgHFt63VwuRQi3C+EimLhIgAcXSp080SkalH4uMyE3ydQYBTwQNMHuM3/NmuXI1J2hgEFOZCbbj7JMS/dHBgKh4rLA8b55CvfgvtyJgfzvSbc/M2dicvDxcXXrnXVkRCRYhQ+Cjl49iCfb/0cUNdDKpFhQF6GOSRcDAyXj/PSIffC2DK9pGkXxkbe9dXiWvdSoHC/MC7y/sJr17o6f0FErpvCRyGT1kwiryCPHsE9CG0Qau1ypDrJSYWMA3DuwpBxAM79ZR5n/GUOHxXB0d18lYVrnZJDRJGAUU/3kxCRSqHwccGx9GN8HP8xAG92e9PK1YjNycs0h4hzBwqNC4WN3LPXsBKT+SFfTjUujZ28Spl2YXxxeonzPM1XdYiIVDH6L9MFU9dOJTs/mzsa3kH3oO7WLkeqmvwcyDxcevfi/Imrr8O1LngGQ40Lg2ew+UFgNYLN50k4euj8CBGxCwofwKnMU8RsjgHMXQ+TfgDsQ0H+pSs8il3dcdm08ye56hUezt6XwoVnsPn+Dpb3N5k7EiIiovABMH39dDJzM2kf0J77Gt9n7XLkRhgFkJ1S6KqOK4SK7JMXbol9jRzdL3UqLg8XNYLBuaY6FyIi18Duw8fZ82eZuXEmoK5HuTMM842nUneah+yUS8/kMPIvPPsi7+rTCgrNMwrNKyi8TC7kpJT9klFMF67wKOHqjmLTfBUuRETKgd2Hj1kbZ5GWnUYr31Y82OxBa5djmwzDfBvt1B2FhguBIzfVOjUVvrrDcmXH5ZeN+pnvVaGTMkVEKpVd/1f3XM45Plj/AQCv3/k6DiYHK1dUxRULGTsvjUsLGSZH8GoCPi3NP/wOhZ+l4XjhveOlaQ6F5l3TtELvXWrrklERERtg1+EjJi6G01mnaVK7Cf1a9rN2OVWHJWTsLN7NuJaQ4dPiwrgleDXVrbNFRKQIuw0fWblZTFk7BYAxd47B0Z7v1njuACQtg5SNl4LGVUNGoYDh09I8zdG1cusWERGbZLfh45P4TziRcYJGPo146tanrF1O5co6DidWmAPHieXmm2JdzuQIXrdcChfeLaDmxU6GQoaIiFw/uwwfOfk5TFwzEYDX7ngNZ8dqfn5Azhk4EQsnLoSN1J1F55ucoG4o+HYDn9YKGSIiUqHsMnx88ecXHE47TECNAJ5t+6y1yyl/eRmQ/Ls5aJxYBqf/oOgNskxQqy343wN+PaDenboBloiIVBq7Cx95BXmM/308AK90eQU3JzcrV1QO8nMgZYM5bCQtg5T15vteFOYdAn73gH8P8O1uvhRVRETECuwufMzfPp99Z/ZR16MuL7Z/0drlXJ+CfDi75dI5G8mrIT+z6DIejcxBw+8e8+ARaJVSRURELmdX4aPAKOD91e8DMCJ0BJ4unlau6BrkZUDGYcg8BGmJ5hNFk1eaz+MozLXehc7GhUMpNW7W3ThFRKRKsqvwsXDXQnad2oWPqw8RHSKsXY75uSLnkyHjoDlcZFwYMguNs0+V/Flnb/PhE78e5sDh00phQ0REbILdhA/DMCxdj5c6vYSPm0/Ff2le5oXHsB8sHioyDpnnFeRcfT1OXuAZZB7q3WHucNRur9uCi4iITbKbX69tydvYlrwNT2dPhnUaVv5fcO4A7P0PpO26eteiMJMDuNcHz0bm8zQ8G5lDxsXXHo3ApRKCkoiISCWxm/Bxq9+t7Bm6h/jj8dTxKMcrPc5sgZ0T4dA3JT+e3dK1KCVcuAeqgyEiInbFrn71bqp5EzfVvOnGV2QY5hM/d06EpF8vTQ+4D+r3uXSIRF0LERGRYuwqfNywgnw4stAcOk7HmaeZHKHR49DiFah1m1XLExERsQUKH9ci/zwc+Bx2TYH0PeZpju7Q+DkIGQk1gq1bn4iIiA1R+LiSnLOwJxoSP4TzJ8zTXGpD00jz4FbPquWJiIjYIoWPkmQehcTpsOffkJdunubREEJGmbsdeg6KiIjIdVP4KCw1AXZNhr++uPRsFJ9W0GI0BD0BDtX86bciIiKVQOED4OQ62DURjvxwaZpvN2j+KgT21p1DRUREypH9hg/DgGNLzFeunFx9aXqDh6HFq1A31GqliYiIVGf2Fz4KcuHgPNg5CVK3m6c5OMNNT0PzV8AnxLr1iYiIVHP2Ez7yMmDvfyFhmvnW52C++2iTwdBsOHjUt2p5IiIi9sJ+wkdWEsSPNN8C3c3PHDiaDAGXmtauTERExK7YT/jwamy+VNbrFgh+BhzdrF2RiIiIXbKf8AHQdpK1KxAREbF7DtYuQEREROyLwoeIiIhUqgoLH1FRUQQHB+Pm5kb79u1ZvXr11T8kIiIi1V6FhI/58+czfPhw3njjDeLj4+natSu9e/fm0KFDFfF1IiIiYkNMhmEY5b3STp060a5dO6Kjoy3TmjdvzsMPP8z48eOv+Nm0tDR8fHxITU3F29u7vEsTERGRClCW3+9y73zk5OSwefNmevbsWWR6z549Wbt2bXl/nYiIiNiYcr/U9tSpU+Tn5+Pn51dkup+fH0lJScWWz87OJjs72/I+LS2tvEsSERGRKqTCTjg1XfYkWMMwik0DGD9+PD4+PpahYcOGFVWSiIiIVAHlHj7q1q2Lo6NjsS5HcnJysW4IwJgxY0hNTbUMhw8fLu+SREREpAop9/Dh4uJC+/btWbp0aZHpS5cupUuXLsWWd3V1xdvbu8ggIiIi1VeF3F595MiRPP3009x+++107tyZjz76iEOHDjFkyJCK+DoRERGxIRUSPh5//HFSUlJ49913OX78OK1atWLJkiUEBQVVxNeJiIiIDamQ+3zcCN3nQ0RExPaU5fe7yj3V9mIW0iW3IiIituPi7/a19DSqXPhIT08H0CW3IiIiNig9PR0fH58rLlPlDrsUFBRw7NgxvLy8SrwvyI1IS0ujYcOGHD58uNof0rGnbQX72l5ta/VlT9urba1+DMMgPT2dwMBAHByufDFtlet8ODg40KBBgwr9Dnu6pNeethXsa3u1rdWXPW2vtrV6uVrH46IKu8OpiIiISEkUPkRERKRS2VX4cHV15e2338bV1dXapVQ4e9pWsK/t1bZWX/a0vdpW+1blTjgVERGR6s2uOh8iIiJifQofIiIiUqkUPkRERKRSKXyIiIhIpap24SMqKorg4GDc3Nxo3749q1evvuLysbGxtG/fHjc3N26++WZiYmIqqdLrN378eDp06ICXlxe+vr48/PDDJCYmXvEzK1euxGQyFRsSEhIqqerrN3bs2GJ1+/v7X/EztrhfAW666aYS91NERESJy9vSfl21ahV9+vQhMDAQk8nEokWLisw3DIOxY8cSGBiIu7s7d911Fzt27Ljqer///ntatGiBq6srLVq0YOHChRW0BWVzpe3Nzc3l1VdfpXXr1nh6ehIYGMgzzzzDsWPHrrjOTz/9tMT9ff78+Qremiu72r4dNGhQsZpDQ0Ovut6quG+vtq0l7R+TycTkyZNLXWdV3a8VqVqFj/nz5zN8+HDeeOMN4uPj6dq1K7179+bQoUMlLn/gwAHuv/9+unbtSnx8PK+//jovvfQS33//fSVXXjaxsbFERESwfv16li5dSl5eHj179iQjI+Oqn01MTOT48eOWoUmTJpVQ8Y1r2bJlkbq3bdtW6rK2ul8BNm3aVGQ7ly5dCsDf//73K37OFvZrRkYGbdq0YdasWSXOnzRpEtOmTWPWrFls2rQJf39/7r33Xsvznkqybt06Hn/8cZ5++mn+/PNPnn76afr168eGDRsqajOu2ZW2NzMzkz/++IO33nqLP/74gwULFrB7924efPDBq67X29u7yL4+fvw4bm5uFbEJ1+xq+xagV69eRWpesmTJFddZVfft1bb18n3zySefYDKZePTRR6+43qq4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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "D_vals_opt_from_ind_FIM = []\n", - "running_FIM = np.zeros((n_para, n_para))\n", - "for i in range(20):\n", - " running_FIM += FIM_opt[i]\n", - " D_vals_opt_from_ind_FIM.append(np.log10(np.linalg.det(running_FIM)))\n", - "\n", - "plt.plot(range(20), D_vals, color='black')\n", - "plt.plot(range(20), D_vals_opt_from_ind_FIM, color='green')\n", - "plt.plot(range(20), D_vals_rand_from_ind_FIM, color='orange')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 104, - "id": "2e53d948-0c13-41be-b417-3a771e09b3c4", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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k9i9e/eovSfDKSkpwde//nXpjnddXR0aGxtH3W/Zj+1vf/tbfPDBB3n9hmU9rrkoqgDF6/Vi1qxZetWDZvfu3Zg3b96wfzN37twLtn/jjTcwe/ZseDwe0/a1UKqq4q//+q/xyiuv4M0338S0adPyep4jR46grq7O4L0zXzQaxfvvvz/ivst6XDM9++yzmDJlCm644Yac/1bG4zpt2jQEg8Gs4xaLxbBv374Rf7/AyMd6tL8RhRacHD9+HHv27MkreFZVFe+++650x/v8+fM4c+bMqPst87EFBnpAZ82aha985Ss5/62sxzUndmXn2mXHjh2qx+NRt2zZor733ntqc3OzWl5erp46dUpVVVX94Q9/qN5111369idOnFDLysrU73//++p7772nbtmyRfV4POr/+T//x663MC7/43/8DzUQCKh79+5V29ra9Ftvb6++zdD3umnTJnXnzp3qhx9+qB49elT94Q9/qAJQX375ZTveQk7WrFmj7t27Vz1x4oR68OBBdcmSJWpFRYXjjqsmmUyqn//859Uf/OAHFzwm83Ht6upSjxw5oh45ckQFoD7++OPqkSNH9KqVRx55RA0EAuorr7yitra2qt/5znfUuro6NRKJ6M9x1113ZVXl/du//ZvqcrnURx55RH3//ffVRx55RHW73erBgwctf39DjfZ+4/G4unTpUvWiiy5S33333azfcTQa1Z9j6PttaWlRX3/9dfW//uu/1CNHjqh/8Rd/obrdbvV3v/udHW9RN9p77erqUtesWaMeOHBAPXnypPrWW2+pc+fOVT/3uc9JeWzH+h6rqqqGw2G1rKxMfeqpp4Z9DlmOq5mKLkBRVVX9x3/8R7WxsVH1er3q1772tazS2xUrVqjz58/P2n7v3r3qzJkzVa/Xq06dOnXEL5RIAAx7e/bZZ/Vthr7XRx99VL344otVv9+vVldXq9/4xjfUV1991fqdz8Ott96q1tXVqR6PR62vr1eXLVumHjt2TH/cKcdVs2vXLhWA+sEHH1zwmMzHVSuJHnpbsWKFqqoDpcY/+tGP1GAwqPp8PvVP/uRP1NbW1qznmD9/vr695l/+5V/USy+9VPV4POqXvvQlYYKz0d7vyZMnR/wdv/XWW/pzDH2/zc3N6uc//3nV6/WqkydPVhctWqQeOHDA+jc3xGjvtbe3V120aJE6efJk1ePxqJ///OfVFStWqB999FHWc8hybMf6Hquqqv7sZz9TS0tL1c7OzmGfQ5bjaiZFVQczA4mIiIgEUVQ5KERERCQHBihEREQkHAYoREREJBwGKERERCQcBihEREQkHAYoREREJBwGKERERCQcBihEREQkHAYoREREJBwGKERERCQcBihEREQkHAYoREREJJz/H0t8KKeI27v/AAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "exp_conds_array = np.array(exp_conds)\n", - "plt.plot(range(20), exp_conds_array[:, 9])\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 79, - "id": "a2243b52-d5fe-4a52-8280-fb0ce4436ed6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO: =======Iteration Number: 1 =====\n", - "INFO: elapsed time: 2.2\n", - "INFO: This is run 1 out of 9.\n", - "INFO: The code has run 2.19064669997897 seconds.\n", - "INFO: Estimated remaining time: 7.667263449926395 seconds\n", - "INFO: =======Iteration Number: 2 =====\n", - "INFO: elapsed time: 1.0\n", - "INFO: This is run 2 out of 9.\n", - "INFO: The code has run 3.2144447999307886 seconds.\n", - "INFO: Estimated remaining time: 6.428889599861577 seconds\n", - "INFO: =======Iteration Number: 3 =====\n", - "INFO: elapsed time: 1.3\n", - "INFO: This is run 3 out of 9.\n", - "INFO: The code has run 4.496953599969856 seconds.\n", - "INFO: Estimated remaining time: 5.6211919999623206 seconds\n", - "INFO: =======Iteration Number: 4 =====\n", - "INFO: elapsed time: 1.0\n", - "INFO: This is run 4 out of 9.\n", - "INFO: The code has run 5.520735299913213 seconds.\n", - "INFO: Estimated remaining time: 4.4165882399305705 seconds\n", - "INFO: =======Iteration Number: 5 =====\n", - "INFO: elapsed time: 1.2\n", - "INFO: This is run 5 out of 9.\n", - "INFO: The code has run 6.751729399897158 seconds.\n", - "INFO: Estimated remaining time: 3.375864699948579 seconds\n", - "INFO: =======Iteration Number: 6 =====\n", - "INFO: elapsed time: 1.2\n", - "INFO: This is run 6 out of 9.\n", - "INFO: The code has run 7.984732399811037 seconds.\n", - "INFO: Estimated remaining time: 2.281352114231725 seconds\n", - "INFO: =======Iteration Number: 7 =====\n", - "INFO: elapsed time: 1.1\n", - "INFO: This is run 7 out of 9.\n", - "INFO: The code has run 9.039862399804406 seconds.\n", - "INFO: Estimated remaining time: 1.1299827999755507 seconds\n", - "INFO: =======Iteration Number: 8 =====\n", - "INFO: elapsed time: 2.8\n", - "INFO: This is run 8 out of 9.\n", - "INFO: The code has run 11.875191299826838 seconds.\n", - "INFO: Estimated remaining time: 0.0 seconds\n", - "INFO: =======Iteration Number: 9 =====\n", - "INFO: elapsed time: 0.9\n", - "INFO: This is run 9 out of 9.\n", - "INFO: The code has run 12.811318899854086 seconds.\n", - "INFO: Estimated remaining time: -1.2811318899854087 seconds\n", - "INFO: Overall wall clock time [s]: 12.811318899854086\n" - ] - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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o23btjh8+LDiCcMnT55g9+7dqFOnDnr37i1yhEREZWMSRVSF5eTkAACsrKx0aqd3796QSCSlRnyel5CQgEGDBsHGxgb29vYYPXo0Hj58qFO/6hg9ejSKi4uxfft2AMD+/fuRmZkJf3//V3L0jYheHUyiiKow+XogXYpo3r9/H0eOHAFQ9pNwubm58PPzw927d7F9+3b8+OOPOHnyJN544w2UlJRo3bc6/P39YWxsrEjw5P+VP71HRFRV8Z95RFVY/fr1AQB37tzRuo1t27ahpKQEvXv3xuHDh5GSkgIHBwelc1avXo379+/j5MmTcHR0BPCsKKa3tzd+/fVXvPXWW9p/iJdwcHBAr169EBkZiWPHjuHgwYPw8PBA+/btK6xPIiJ94EgUURUmL1dw8uRJFBUVadXG5s2b0bp1ayxZskRp2ux5+/fvh5+fnyKBAp5VC2/atCn27dunXfAakC8gHz16NJ4+fcoF5URkEJhEEVVhr7/+OqytrZGWloY9e/ZofP2VK1cQFxeHkSNHwsvLC82bN1c5pXf16lW0aNGi1P4WLVrg2rVrWsWuibfeegvW1tZISkpSlD4gIqrqmEQRVWE1atTABx98AACYPn16ue+kA569oFheFgF4NgolkUjw7rvvAni2zuj8+fOlEqOMjAzUqFGjVHs1a9ZEenq6bh9CDZaWlvj444/Rs2dPvPfee3BxcanwPomIdMUkiqiKCw0NRefOnZGamorOnTtj8+bNKCgoUDrnxo0bmDJlCnx9fZGWlgbgWdXvbdu2wcfHBw0aNAAAjBw5EhKJROVolEQiKbWvMt9PHhoair/++gurVq2qtD6JiHTBJIqoijMzM8OhQ4cwdOhQpKSkYMyYMahZsyZatWoFb29vNGjQAO7u7vj+++/h4OCAJk2aAACioqKQnJyMQYMGITMzE5mZmbC1tUXHjh2xdetWpQTJ3t4eGRkZpfrOyMhAzZo1K+2zEhEZEiZRRAbA2toae/bswbFjxzBu3Dg4OTkhISEBcXFxEAQBb7zxBtatW4cbN26gZcuWAP5XzuCjjz6Cvb29Yjt9+jQSExNx4sQJRfstWrTA1atXS/V79epVNGvWrHI+JBGRgWGJAyID0r17d3Tv3v2l5xUUFGDPnj3o168fZs+erXSssLAQAwcOxJYtWxRtvfnmm5g3b55S+YO///4b//zzD8LCwvT6GV62rutFDRo0qNRpRSIidUkE/u1E9MrZtWsXhg8fjv379+ONN94odXz48OH4888/kZKSAjMzM+Tk5KB169aoXbs2QkJCUFBQgNmzZ6NWrVo4deoUjIxePmidkJCAhg0bQiqVKmo8BQUFISgoSO+fTy4wMBDx8fHIysrC5cuX4ePjg6ioqArrj4joeZzOI3oFbdmyBQ4ODujXr5/K44GBgcjIyMCBAwcAPKuMfuTIETg4OGD48OEYN24cOnXqhP3796uVQD3vyZMniImJQUxMDJKSknT+LOW5cOECYmJicPny5Qrth4hIFY5EEREREWmBI1FEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKQFJlFEREREWmASRURERKSF/wOJlcL9geJOrwAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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unTpolPdERER6NWrl8Z2a2trhIWFYd68efpdVCWqdrPDiIiISJ2bm5vawr0rV64ssez777+PuLg4bN68GbVq6f/w1jp16mD16tVISEhATk4Obt26hR07dsDJyQnz58/H+vXr9T53Zak23WFEREQ1j6HdYUUAoLUlSJu4uDi89957eOedd9C+fXsD6n3yoPGnu9Jq166NsWPHok2bNujQoQNCQkIwdepUmJlV3faWqhsZERFRjWecx2bY29urvUpKgiZOnAhvb+8Knc3VqlUrdO7cGXfv3lV7YHlVxJYgIiIiExEXFwcAsLKy0rq/a9euAID9+/dj6NChetejHBj96NEjvc9RGZgEERERScY43WG6eu2117Ruj4qKQlJSEoYMGYI6derA09NT74gKCwtx4cIFyGQyuLu7632eysAkiIiISDLKB6jqq7BcpTdu3Kh1+6RJk5CUlIRFixZpzA5LT09Heno6nJ2d1aa+K2eSPb0AcWFhIebNm4eUlBT0798fTk5O5YqvsjEJIiIiohKFh4cjLCwMISEhamOJxowZA5lMhm7dusHV1RUZGRmIiorC1atX4e7ujnXr1kkXtI6YBBEREUnG0O4w6b7GZ8yYgaNHjyIiIgLp6emwsLBA48aNsWTJErz99ttwdHSULDZdcbFEI+NiiaaFiyWaFi6WaBoqd7HEMNjbax+krNt5cqFQhFRorDUZp8gTERGRSWJ3GBERkWSqb3dYTcC7R0REJBkmQVLi3SMiIpKMoVPkzY0ViEnimCAiIiIySWwJIiIikgy7w6TEu0dERCQZJkFSYncYERERmSSmkERERJIxh2GDmzkw2hBMgoiIiCTD2WFSYncYERERmSS2BBEREUmGA6OlxLtHREQkGSZBUmJ3GBEREZkkppBERESSYUuQlHj3iIiIJMMkSEq8e0RERJLhFHkpcUwQERERmSS2BBEREUmG3WFS4t0jIiKSDJMgKbE7jIiIiEwSU0giIiLJsCVISrx7REREkmESJCV2hxEREZFJYgpJREQkGa4TJCUmQURERJJhd5iUePeIiIgkwyRIShwTRERERCaJKSQREZFk2BIkJd49IiIiyXBgtJTYHUZEREQmiS1BREREkjGHYa05bAkyBJMgIiIiyXBMkJTYHUZEREQmiSkkERGRZNgSJCXePSIiIskwCZISu8OIiIjIJDGFJCIi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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "### Define inputs\n", - "# Control time set [h]\n", - "t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - "# Define parameter nominal value\n", - "parameter_dict = {\"A1\": 85, \"A2\": 372, \"E1\": 8, \"E2\": 15}\n", - "\n", - "# measurement object\n", - "measurements = MeasurementVariables()\n", - "measurements.add_variables(\n", - " \"C\", # variable name\n", - " indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, # indices\n", - " time_index_position=1,\n", - ") # position of time index\n", - "\n", - "# design object\n", - "exp_design = DesignVariables()\n", - "\n", - "# add CAO as design variable\n", - "exp_design.add_variables(\n", - " \"CA0\", # variable name\n", - " indices={0: [0]}, # indices\n", - " time_index_position=0, # position of time index\n", - " values=[5], # nominal value\n", - " lower_bounds=1, # lower bound\n", - " upper_bounds=5, # upper bound\n", - ")\n", - "\n", - "# add T as design variable\n", - "exp_design.add_variables(\n", - " \"T\", # variable name\n", - " indices={0: t_control}, # indices\n", - " time_index_position=0, # position of time index\n", - " values=[470, 300, 300, 300, 300, 300, 300, 300, 300], # nominal value\n", - " lower_bounds=300, # lower bound\n", - " upper_bounds=700, # upper bound\n", - ")\n", - "\n", - "# For each variable, we define a list of possible values that are used\n", - "# in the sensitivity analysis\n", - "\n", - "design_ranges = {\n", - " \"CA0[0]\": [1, 3, 5],\n", - " (\n", - " \"T[0]\",\n", - " \"T[0.125]\",\n", - " \"T[0.25]\",\n", - " \"T[0.375]\",\n", - " \"T[0.5]\",\n", - " \"T[0.625]\",\n", - " \"T[0.75]\",\n", - " \"T[0.875]\",\n", - " \"T[1]\",\n", - " ): [300, 500, 700],\n", - "}\n", - "## choose from \"sequential_finite\", \"direct_kaug\"\n", - "sensi_opt = \"direct_kaug\"\n", - "\n", - "prior_pass = [\n", - " [22.52943024, 1.84034314, -70.23273336, -11.09432962],\n", - " [1.84034314, 18.09848116, -5.73565034, -109.15866135],\n", - " [-70.23273336, -5.73565034, 218.94192843, 34.57680848],\n", - " [-11.09432962, -109.15866135, 34.57680848, 658.37644634],\n", - "]\n", - "\n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict, # parameter dictionary\n", - " exp_design, # design variables\n", - " measurements, # measurement variables\n", - " create_model, # model function\n", - " prior_FIM = prior_pass, \n", - " discretize_model=disc_for_measure, # discretization function\n", - ")\n", - "# run full factorial grid search\n", - "all_fim = doe_object.run_grid_search(design_ranges, mode=sensi_opt)\n", - "\n", - "all_fim.extract_criteria()\n", - "\n", - "for i in all_fim.store_all_results_dataframe.columns:\n", - " all_fim.store_all_results_dataframe[i] = all_fim.store_all_results_dataframe[i].values.real\n", - "\n", - "\n", - "fixed = {}\n", - "all_fim.figure_drawing(\n", - " fixed, \n", - " [\"CA0[0]\",\"T[0]\"],\n", - " \"Reactor\",\n", - " \"$C_{A0}$ [M]\",\n", - " \"T [K]\"\n", - ")\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "b805fb89-45a9-4ca2-8c72-325747d3fd25", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO: =======Iteration Number: 1 =====\n", - "INFO: elapsed time: 0.7\n", - "INFO: This is run 1 out of 8.\n", - "INFO: The code has run 0.7312748000040301 seconds.\n", - "INFO: Estimated remaining time: 2.1938244000120903 seconds\n", - "INFO: =======Iteration Number: 2 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 2 out of 8.\n", - "INFO: The code has run 1.5368452000038815 seconds.\n", - "INFO: Estimated remaining time: 2.5614086666731355 seconds\n", - "INFO: =======Iteration Number: 3 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 3 out of 8.\n", - "INFO: The code has run 2.300336200009042 seconds.\n", - "INFO: Estimated remaining time: 2.300336200009042 seconds\n", - "INFO: =======Iteration Number: 4 =====\n", - "INFO: elapsed time: 1.0\n", - "INFO: This is run 4 out of 8.\n", - "INFO: The code has run 3.2964527000076487 seconds.\n", - "INFO: Estimated remaining time: 1.9778716200045894 seconds\n", - "INFO: =======Iteration Number: 5 =====\n", - "INFO: elapsed time: 0.7\n", - "INFO: This is run 5 out of 8.\n", - "INFO: The code has run 3.9811715000105323 seconds.\n", - "INFO: Estimated remaining time: 1.3270571666701774 seconds\n", - "INFO: =======Iteration Number: 6 =====\n", - "INFO: elapsed time: 0.7\n", - "INFO: This is run 6 out of 8.\n", - "INFO: The code has run 4.726026500014996 seconds.\n", - "INFO: Estimated remaining time: 0.675146642859285 seconds\n", - "INFO: =======Iteration Number: 7 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 7 out of 8.\n", - "INFO: The code has run 5.568790400015132 seconds.\n", - "INFO: Estimated remaining time: 0.0 seconds\n", - "INFO: =======Iteration Number: 8 =====\n", - "INFO: elapsed time: 0.7\n", - "INFO: This is run 8 out of 8.\n", - "INFO: The code has run 6.320087100015371 seconds.\n", - "INFO: Estimated remaining time: -0.7022319000017079 seconds\n", - "INFO: Overall wall clock time [s]: 6.320087100015371\n" - ] - }, - { - "data": { - "image/png": "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4eTkBE9PTxgZGVW5njod8JWUlGDLli2QSCQYPXp0TTdHrWbNmoVp06bJ/s7JyYGVlVUNtoiIiIiqi5GREXr16oVevXpVS/l1OuA7cuQIUlNT0b17d4WDhaW9a6X1okmHSF/thTMxMalQ+tJUpu7X6ejoQEdHp9y6iIiI5LGHrzZKTU1VSznW1taVylenAz5lizWkyptzp2yenaOjI06fPo2HDx8qzOMrb15eVesmIiJSD3UFfKROtra2kFRxbqVEIkFxcXGl8tbZgO/x48f47bffYGZmho8//ljhuaOjIywtLXHq1Ck8ffpUbrVsQUEBoqOjYWlpiebNm8vue3t74/Tp0zh8+DBGjBghV15kZKQsTXkqUzcRERGJl7W1dZUDvqqos9uybNu2Dc+fP8ewYcOUDn1KJBIEBAQgLy8P8+bNk3u2cOFCPHnyBAEBAXJvvr+/P7S0tLBgwQK54dhr167hp59+goODA7p16yZXVmpqKuLj4/Hs2bMq1U1ERKQemnjZn1OVizsvq1tycjJu375d5auyJEId3f23bdu2uHr1Kq5cuYK2bdsqTfP06VN4enrKjjfr0KEDLl++jD/++ANubm5KjzdbsGAB5syZA2trawwYMABPnz7Fjh07kJ+fj8jISPj4+Mil79q1K44fP45jx47JHbtWmbrLkpOTI5tjKF3lSyQ+Y2u6AUTVJifnOUxMtlbbf8f/9zvRCMbGVevPyckpgYnJI/7miEid7OGLjY3F1atX0alTp1KDPQAwMDBAVFQUpk6divj4eCxbtgxXr17F1KlTERUVpTTgmj17NsLDw2Fubo61a9di586d6NKlC06dOqUQ7JWlMnUTERERVYc628P3tmEPH70d2MNH4vXmeviaqKmH74HKbb137x527dqFgwcPIj4+Hg8fPoSZmRk8PDwwY8YMvPPOOyrXfffuXXzzzTf4448/8PDhQzRs2BA9e/bEvHnzytyebO/evVizZg0uXryIZ8+ewcLCAu+++y6WLFkil2/jxo3Yt28frl69ivT0dGhpacHW1hYfffQRvvjiC5iZmcmVm5ycrLATyKt27NiBIUOGqPz6akqdXbRBREREymih6gN4FTtlY9WqVVi8eDEcHBzg6+sLc3NzJCQkICIiAhEREdixYwcGDRpUbjlJSUno0qUL0tPT4evri8GDByMhIQFbt27FwYMH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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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1aVLF8XExCgkJETp6en6/PPPlZOTo7vvvlv/+te/5Od36avw++1fWrVqpS1btujLL78sdfuXqVOn6rnnnrNtPXP27FktWrRIubm5WrFihbp06WJ3fefOnbVmzRqtXr3ablsaV+q+EraeQUXA1jMws/LaeuZTSY7/dinZWUl9xNYzzvCpZRP69eunzMxMff/991q7dq3OnTunyMhIJSYmavDgwerfv79dr09ISIhSUlI0efJkffTRR0pJSVFUVJSefvppJSUllRhoJk6cqNjYWL355pt67733FBgYqPbt22vKlClq3bq1w211pW4AAOCbfKqHqiKjhwoVAT1UMLPy6qH6XJ7pofqj6KFyhk/1UAEAgCvzxBwo5lA5j88MAADATfRQAQBgIuzl5x0EKgAATIRA5R0EKgAA4JbDhw9ryZIl+uKLL7Rz504dPXpUkZGRSkhI0NixY3XLLbd4rW0XLlzQpk2btG7dOqWnp+vEiRPKzc1V1apVdcMNN6hly5bq0KGDatas6VY9BCoAAEzEIvcnSDu77PTf/vY3vfLKK6pXr5569OihatWqac+ePfr444/18ccfa9GiRbr33nvdbJVzVq9erZkzZ+rjjz9WXl6eJKmkhQ2Klltq3Lixhg0bpsGDB6tq1apO18eyCT6CZRNQEbBsAsysvJZNWCMp1M2yciR1kuNt/fe//60bbrhBHTp0sDv+3XffqVu3bgoLC9ORI0dktVrdbNnVLV++XOPHj9eOHTtkGIYCAgLUvHlztW7dWtWrV1dkZKSCg4N16tQpnTp1Stu3b9emTZt07NgxSVJgYKAefvhhPf/887rhhhscrpdA5SMIVKgICFQws/IKVN/JM4GqgzzT1l69emnlypXatGmT4uPj3WzZlXXs2FGpqakKDg7WHXfcof79+6tXr14KCrr6L859+/Zp8eLFWrRokbZv366wsDB98MEH+tOf/uRQ3SybAAAAykylSpUkSQEBZT/LaOvWrXr++ed16NAhLVq0SH/6058cClOSVK9ePU2cOFFbt27VN998o1atWunnn392uG7mUAEAYCLX0lN+Bw8e1Ndff62oqCg1b97cQ6WWLj09XWFhYW6X06VLF3Xp0kXZ2dkO30OgAgDARDwZqLKysuyOW61Wh+dBXbhwQYMGDVJ+fr6mT58uf/+yX4zBE2HK1fIY8gMAACWKjo5WRESE7TVt2jSH7issLNSwYcO0du1ajRgxQoMGDSrjlnofPVQAAJiIJ/fyy8jIsJuU7kjvlGEYGjFihJKTkzVw4EC9//77brbGs86dO6fc3FxFRkbalkzwBAIVAAAm4skhv/DwcKee8issLNTw4cM1Z84cDRgwQHPnzpWfn/cGw7KysvTpp59q7dq1toU9i9akslgsioyMtC3s2bNnT7Vu3drlulg2wUewbAIqApZNgJmV17IJP8ozyya0lHNtvTxM3XfffVqwYEG5zJsqycaNG/Xuu+9q6dKlys3NLXFBz8sV9VQ1a9ZMw4cP10MPPaTKlSs7VSc9VAAAmIif3O+hcrZPqbCwUA899JDmzp2re+65R8nJyV4JU7t379b48eP18ccfyzAMVa1aVX379lWbNm2uuLDnxo0blZqaqvXr1+upp57SSy+9pEmTJmnEiBEO97ARqAAAMBFPzqFy1JQpUzR37lyFhoaqQYMGevHFF4tdc+edd6pFixZutuzKmjZtKkm677779OCDD6p79+6lBrtq1aqpWrVqatSoke666y5Jl/YkXLRokd577z099thj+u233zRhwgSH6iZQAQAAtxw4cECSlJOTo6lTp5Z4TWxsbJkHqsGDB2vChAmqV6+eS/fXrFlTzzzzjJ5++mktWLDAqUnrzKHyEcyhQkXAHCqYWXnNodomyd3VmLIlNVXZtdWM6KECAMBEvDHkBwIVAACmci1tPVOREKgAAIBprF271u0yOnbs6PQ9BCoAAEykovdQde7c2a0V0C0WiwoKCpy+j0AFAICJMIfqkurVqys4OLjc6iNQAQAAUzEMQzk5OerVq5cGDhyoLl26lHmdZgihAADg/xStlO7Oy5fDwZYtWzRmzBiFhoZqzpw56t69u2JiYjRhwgRt3769zOr15c8MAAD8jrthyhNzsLypefPmevXVV5WRkaGVK1dq4MCBOnPmjF5++WU1b95cLVu21BtvvKGjR496tF4CFQAAMB2LxaLu3btr3rx5Onr0qJKTk9WzZ09t3bpVY8aMUXR0tG699VYtWLBA586dc7s+AhUAACbi56GXmQQHB+v+++/Xl19+qUOHDun1119XixYttHLlSg0ePFj9+vVzuw4mpQMAYCIVfdmEq6lWrZoGDx6swMBAnThxQgcPHnRpmYTfI1ABAADTO3/+vD799FMlJyfrq6++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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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aYIaNWqovF4QBISHh2tVJ5MzIiIiY8LZmpLKycnBG2+8gZMnT0IURTx+/BiPHz8u83oplthgckZERGRMmJxJatGiRQgPD0ft2rUxdepUtG/fnuucEREREenKd999B3Nzc0RGRqJly5ZVUieTMyIiImPCpTQklZ6eDk9PzypLzAAmZ0RERMaF3ZqSat68OXJycqq0TubGREREpFMrV65Ev3794OLiAmtra9SuXRve3t5YvXo18vLyNC4vLCwM/v7+kMlksLOzg7+/P8LCwioU2zvvvIObN28iIiKiQvdXBJMzIiIiY2KAi9Bu3LgR6enp6Nu3L2bNmoWAgADk5+fj/fffR/fu3TVK0Hbt2oUBAwbg6tWrGDduHCZMmIC4uDgMGDAAu3bt0ji2yZMnY86cORg6dCjWrVtXJa1ogiiKYqXXQlrLysqCvb09MjMzIZPJdB0OUeUYypUvyXhlFQL2R1Bp/x1X/E78CshstCwrF7DvU3mxvig/Px9WVlaljo8dOxY7d+7E+vXr8e677760nPT0dDRu3BhmZma4ePEiXFxcAAD379+Hl5cX8vPzcfv2bTg4OKgdm3z7prt376K4uBgA4OTkVO46Z7du3VK7fFXYckZEREQ6pSoxA4Dhw4cDAG7evKlWOQcOHEBGRgZmzpypSMwAoF69epg9ezYyMjJw4MABjWJLSEhAQkICioqKIIoiRFFEamqq4riql7Y4IYCIiMiYmED7bkk9abo5evQoAKB169ZqXS8fF9avX79S5/r374/58+cjMjISU6dOVTuGO3fuqH2tVJicERERGRMDXkpjzZo1yMjIQEZGBqKjo3HhwgX069cPY8eOVev++Ph4AICHh0epc/Jj8mvU5ebmptH1UmByRkREZEwkXEojKytL6bClpSUsLS21LLxsa9asQWJiouL9mDFjsGHDBpibm6t1f2ZmJgDA3t6+1DkbGxuYmpoqrtFnetJwSURERPrGxcUF9vb2iteKFSvKvNbR0RGCIKj9UrU0RUJCAkRRxP3797F7925ERESgS5cuuHv3biV+Sv3DljMiIiJjImHLWXJystJszfJazQICApCdna12Fc7OzuWeCwgIQNOmTdG5c2e8//772Ldv30vLlLeYZWZmonbt2krncnNzUVxcrLJVTa5169b46KOPMHLkSK32zkxKSsLy5cvRqFEjfPjhhxrf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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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iMomC5leChMZGYmOHTtizZo1RR63evVqdOzYEdHR0Ua3Jfvp27p1K3r06IEaNWpg2rRpyMjIwMKFC3HlyhXs27cPQgi9k3gRERERyWHdunU4duwYWrduXeRxrVu3RkREBDZs2GB0W7JPC44YMQKSJKFLly5YsmQJmjRpotmXmpoqd3NERET0NE4L6nTq1Ck4OzvrzG/1tMaNG6NSpUov1shVp06dIEkSDh8+jDFjxmDZsmW4efOm3M0QERGRLhJMnxJUYM6fGzduwMvLS69jvby8cOPGDaPbkj24Onz4MP79918sXboUABAUFAQPDw907twZmzdvhiQp8BMjIiKiF5q1tTUePnyo17EPHz6EhYXxIVKxLFlzc3PDe++9h7/++guxsbGYMWMGEhMT8e6770IIgY8//hgHDhwA85cSERHJzNTnCsoxrfgCqlu3LhITE5GQkFDkcQkJCUhISICvr6/RbRX7/QD169fHkiVLcPXqVRw5cgRjxoxBdHQ0evbsCXd39+JunoiIqGxhcKXTgAEDIITAyJEjkZKSovOYlJQUjBo1CpIkYdCgQUa3ZZbH32RlZeHnn3/G1q1b8fPPP5d086USH39DZQEff0NKVmKPvwkBHGxMrCsTcAxR1uNvMjIy0KxZM1y8eBGurq5444030LJlS1SsWBEpKSk4deoUNmzYgDt37qBu3br4888/S/bZgufPn8elS5fg6uqKVq1aPff4kydP4t69e6hVqxbq169vVEfLOgZXVBYwuCIlY3BlftevX0e/fv1w5swZnWvAhRDw8/PDDz/8YNLsmsGpGB4/foyuXbsiOTkZR48e1auMEAIDBw5EtWrVcPHiRahUJj5RkoiIiHRjKoZCubu74/Tp0/jxxx/x888/Iy4uDmlpaahQoQIaNGiAvn37om/fviYtZgeMCK62b9+OW7duYeLEiWjTpo1eZdq0aYPx48dj9erV2LFjB0aNGmVwR4mIiEgPDK6KZGFhgYEDB2LgwIHF14ahBX766SdIkoQpU6YYVE59p+APP/xgaJNEREREpYbBI1d//fUXqlatirp16xpUrnbt2qhevTr++usvQ5skIiIifcnxbEAFPluwJBl8+pKTk1G9enWjGqtWrRqSk5ONKktERER6sIDpaRhKeXDVsGFDfPvttybn07x27RomTpyIjz/+2KByBp8+GxsbZGRkGFoMwJPbIK2trY0qS0RERKSPhw8f4vXXX4evry8++ugjJCYm6l02Ozsbu3btwsCBA1G7dm2sW7cOrq6uBrVv8LRg1apVcenSJWRlZRl0119WVhYuXboEDw8PQ5skIiIifXFaEAkJCVixYgWWLFmC4OBghISEwMfHBy1atECzZs1QtWpVODs7Q6VSISUlBffv30dcXBxiYmIQExOD9PR0CCHQpUsXfPzxx2jSpIlB7RscXLVt2xbr16/Hzp07MWzYML3Lff/998jIyEDbtm0NbZKIiIj0xbsFoVKpEBQUhIkTJ2LLli1Yu3Ytzp49i6SkJGzfvl1nGfUUop2dHcaOHYsJEyagefPmRrVvcBLREydOICAgANWqVcPJkyf1SrJ17do1tGrVCnfu3EFkZCT8/f2N6mxZxiSiVBYwiSgpWYklEf0McDAusfj/6soAHKcpK4loYmIiIiMjceLECVy9ehXJycnIzMyEs7MzXF1d0aRJEwQEBKBNmzYoX768SW0ZPHLVpk0bDBo0CN9//z1atmyJL774AgMGDNCZcCs/Px87d+7Eu+++izt37mDAgAEMrIiIiIoTR650ql27NmrXro033ij+v+IMDq4AYNOmTbhx4wZOnDiBIUOGoHLlyvD390fNmjVhZ2eH9PR0XL58GSdOnMDdu3chhEDr1q2xadMmmbtPREREWrjmyuyMCq5sbW0RERGBkJAQrFy5Enfv3sWuXbu0ntOjnm20t7fH5MmTERISAisrK3l6TURERLpx5MrsjAquAKBcuXJYsGABZs6cib179+LEiRO4ceMGHj58iAoVKqB69epo06YNevbsCUdHRzn7TERERKS3e/fu4eeff8bvv/+OxMREPHjwABkZGbC1tYWTkxNq166Nli1bok+fPganXdDF4AXtZB5c0E5lARe0k5KV2IL2NTItaH+z9C9oz8zMxMyZM/H1118jJyenyKSikiTBysoK48ePx9KlS2Fra/xJNHrkioiIiF5A6gztptZRymVlZaF9+/b4448/IIRA3bp14e/vD29vbzg5OUGlUiErKwsPHjzAP//8g+joaMTHx+Orr77C6dOncfz4caMTnzO4IiIiIsX55JNPcPr0adSpUwcbNmxA69atn1vmxIkTGDt2LGJiYrB06VLMnTvXqLYVEJsSERGRhqnPFZRjQfwLYPv27bC2tsahQ4f0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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - " ### 3 design variable example\n", - "# Define design ranges\n", - "design_ranges = {\n", - " \"CA0[0]\": list(np.linspace(1, 5, 2)),\n", - " \"T[0]\": list(np.linspace(300, 700, 2)),\n", - " (\n", - " \"T[0.125]\",\n", - " \"T[0.25]\",\n", - " \"T[0.375]\",\n", - " \"T[0.5]\",\n", - " \"T[0.625]\",\n", - " \"T[0.75]\",\n", - " \"T[0.875]\",\n", - " \"T[1]\",\n", - " ): [300, 500],\n", - "}\n", - "\n", - "sensi_opt = \"direct_kaug\"\n", - "\n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict, # parameter dictionary\n", - " exp_design, # design variables\n", - " measurements, # measurement variables\n", - " create_model, # model function\n", - " prior_FIM = prior_pass, \n", - " discretize_model=disc_for_measure, # discretization function\n", - ")\n", - "# run the grid search for 3 dimensional case\n", - "all_fim = doe_object.run_grid_search(design_ranges, mode=sensi_opt)\n", - "\n", - "all_fim.extract_criteria()\n", - "\n", - "# see the criteria values\n", - "all_fim.store_all_results_dataframe\n", - "\n", - "\n", - "\n", - "fixed = {\"('T[0.125]', 'T[0.25]', 'T[0.375]', 'T[0.5]', 'T[0.625]', 'T[0.75]', 'T[0.875]','T[1]')\": 300}\n", - "\n", - "all_fim.figure_drawing(\n", - " fixed, \n", - " [\"CA0[0]\",\"T[0]\"],\n", - " \"Reactor\", \n", - " \"T [K]\", \n", - " \"$C_{A0}$ [M]\"\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10c928cf-bc40-4a62-a176-3e3eb19ec78e", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.14" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 3ec88c087f7e6748a72422429e35e98c7536ce4d Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:56:16 -0400 Subject: [PATCH 068/203] Delete pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb Removing old file --- .../doe/examples/debugging_compute_FIM.ipynb | 10011 ---------------- 1 file changed, 10011 deletions(-) delete mode 100644 pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb diff --git a/pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb b/pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb deleted file mode 100644 index 1c2f5383e58..00000000000 --- a/pyomo/contrib/doe/examples/debugging_compute_FIM.ipynb +++ /dev/null @@ -1,10011 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "59659c7f-5ced-42da-b7dd-de22f614db9f", - "metadata": {}, - "source": [ - "# Imports" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "f875a1ff-c70d-4f94-a65c-495fbf8faa0c", - "metadata": {}, - "outputs": [], - "source": [ - "import pyomo.environ as pyo\n", - "from pyomo.dae import ContinuousSet, DerivativeVar\n", - "from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables, ModelOptionLib\n", - "import copy\n", - "import numpy as np\n", - "from random import sample\n", - "from matplotlib import pyplot as plt" - ] - }, - { - "cell_type": "markdown", - "id": "3b4d475b-bcf6-4e73-ba3b-0393bb65da30", - "metadata": {}, - "source": [ - "## Model function" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "7cf05f64-c3b1-4905-b5c1-b54dcb3aacea", - "metadata": {}, - "outputs": [], - "source": [ - "def create_model(\n", - " mod=None,\n", - " model_option=\"stage2\",\n", - " control_time=[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],\n", - " control_val=None,\n", - " t_range=[0.0, 1],\n", - " CA_init=1,\n", - " C_init=0.1,\n", - "):\n", - " \"\"\"\n", - " This is an example user model provided to DoE library.\n", - " It is a dynamic problem solved by Pyomo.DAE.\n", - "\n", - " Arguments\n", - " ---------\n", - " mod: Pyomo model. If None, a Pyomo concrete model is created\n", - " model_option: choose from the 3 options in model_option\n", - " if ModelOptionLib.parmest, create a process model.\n", - " if ModelOptionLib.stage1, create the global model.\n", - " if ModelOptionLib.stage2, add model variables and constraints for block.\n", - " control_time: a list of control timepoints\n", - " control_val: control design variable values T at corresponding timepoints\n", - " t_range: time range, h\n", - " CA_init: time-independent design (control) variable, an initial value for CA\n", - " C_init: An initial value for C\n", - "\n", - " Return\n", - " ------\n", - " m: a Pyomo.DAE model\n", - " \"\"\"\n", - "\n", - " theta = {\"A1\": 84.79, \"A2\": 371.72, \"E1\": 7.78, \"E2\": 15.05}\n", - "\n", - " model_option = ModelOptionLib(model_option)\n", - "\n", - " if model_option == ModelOptionLib.parmest:\n", - " mod = pyo.ConcreteModel()\n", - " return_m = True\n", - " elif model_option == ModelOptionLib.stage1 or model_option == ModelOptionLib.stage2:\n", - " if not mod:\n", - " raise ValueError(\n", - " \"If model option is stage1 or stage2, a created model needs to be provided.\"\n", - " )\n", - " return_m = False\n", - " else:\n", - " raise ValueError(\n", - " \"model_option needs to be defined as parmest,stage1, or stage2.\"\n", - " )\n", - "\n", - " if not control_val:\n", - " control_val = [300] * 9\n", - "\n", - " controls = {}\n", - " for i, t in enumerate(control_time):\n", - " controls[t] = control_val[i]\n", - "\n", - " mod.t0 = pyo.Set(initialize=[0])\n", - " mod.t_con = pyo.Set(initialize=control_time)\n", - " mod.CA0 = pyo.Var(\n", - " mod.t0, initialize=CA_init, bounds=(1.0, 5.0), within=pyo.NonNegativeReals\n", - " ) # mol/L\n", - "\n", - " # check if control_time is in time range\n", - " assert (\n", - " control_time[0] >= t_range[0] and control_time[-1] <= t_range[1]\n", - " ), \"control time is outside time range.\"\n", - "\n", - " if model_option == ModelOptionLib.stage1:\n", - " mod.T = pyo.Var(\n", - " mod.t_con,\n", - " initialize=controls,\n", - " bounds=(300, 700),\n", - " within=pyo.NonNegativeReals,\n", - " )\n", - " return\n", - "\n", - " else:\n", - " para_list = [\"A1\", \"A2\", \"E1\", \"E2\"]\n", - "\n", - " ### Add variables\n", - " mod.CA_init = CA_init\n", - " mod.para_list = para_list\n", - "\n", - " # timepoints\n", - " mod.t = ContinuousSet(bounds=t_range, initialize=control_time)\n", - "\n", - " # time-dependent design variable, initialized with the first control value\n", - " def T_initial(m, t):\n", - " if t in m.t_con:\n", - " return controls[t]\n", - " else:\n", - " # count how many control points are before the current t;\n", - " # locate the nearest neighbouring control point before this t\n", - " neighbour_t = max(tc for tc in control_time if tc < t)\n", - " return controls[neighbour_t]\n", - "\n", - " mod.T = pyo.Var(\n", - " mod.t, initialize=T_initial, bounds=(300, 700), within=pyo.NonNegativeReals\n", - " )\n", - "\n", - " mod.R = 8.31446261815324 # J / K / mole\n", - "\n", - " # Define parameters as Param\n", - " mod.A1 = pyo.Var(initialize=theta[\"A1\"])\n", - " mod.A2 = pyo.Var(initialize=theta[\"A2\"])\n", - " mod.E1 = pyo.Var(initialize=theta[\"E1\"])\n", - " mod.E2 = pyo.Var(initialize=theta[\"E2\"])\n", - "\n", - " # Concentration variables under perturbation\n", - " mod.C_set = pyo.Set(initialize=[\"CA\", \"CB\", \"CC\"])\n", - " mod.C = pyo.Var(\n", - " mod.C_set, mod.t, initialize=C_init, within=pyo.NonNegativeReals\n", - " )\n", - "\n", - " # time derivative of C\n", - " mod.dCdt = DerivativeVar(mod.C, wrt=mod.t)\n", - "\n", - " # kinetic parameters\n", - " def kp1_init(m, t):\n", - " return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def kp2_init(m, t):\n", - " return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", - "\n", - " mod.kp1 = pyo.Var(mod.t, initialize=kp1_init)\n", - " mod.kp2 = pyo.Var(mod.t, initialize=kp2_init)\n", - "\n", - " def T_control(m, t):\n", - " \"\"\"\n", - " T at interval timepoint equal to the T of the control time point at the beginning of this interval\n", - " Count how many control points are before the current t;\n", - " locate the nearest neighbouring control point before this t\n", - " \"\"\"\n", - " if t in m.t_con:\n", - " return pyo.Constraint.Skip\n", - " else:\n", - " neighbour_t = max(tc for tc in control_time if tc < t)\n", - " return m.T[t] == m.T[neighbour_t]\n", - "\n", - " def cal_kp1(m, t):\n", - " \"\"\"\n", - " Create the perturbation parameter sets\n", - " m: model\n", - " t: time\n", - " \"\"\"\n", - " # LHS: 1/h\n", - " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", - " return m.kp1[t] == m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def cal_kp2(m, t):\n", - " \"\"\"\n", - " Create the perturbation parameter sets\n", - " m: model\n", - " t: time\n", - " \"\"\"\n", - " # LHS: 1/h\n", - " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", - " return m.kp2[t] == m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def dCdt_control(m, y, t):\n", - " \"\"\"\n", - " Calculate CA in Jacobian matrix analytically\n", - " y: CA, CB, CC\n", - " t: timepoints\n", - " \"\"\"\n", - " if y == \"CA\":\n", - " return m.dCdt[y, t] == -m.kp1[t] * m.C[\"CA\", t]\n", - " elif y == \"CB\":\n", - " return m.dCdt[y, t] == m.kp1[t] * m.C[\"CA\", t] - m.kp2[t] * m.C[\"CB\", t]\n", - " elif y == \"CC\":\n", - " return pyo.Constraint.Skip\n", - "\n", - " def alge(m, t):\n", - " \"\"\"\n", - " The algebraic equation for mole balance\n", - " z: m.pert\n", - " t: time\n", - " \"\"\"\n", - " return m.C[\"CA\", t] + m.C[\"CB\", t] + m.C[\"CC\", t] == m.CA0[0]\n", - "\n", - " # Control time\n", - " mod.T_rule = pyo.Constraint(mod.t, rule=T_control)\n", - "\n", - " # calculating C, Jacobian, FIM\n", - " mod.k1_pert_rule = pyo.Constraint(mod.t, rule=cal_kp1)\n", - " mod.k2_pert_rule = pyo.Constraint(mod.t, rule=cal_kp2)\n", - " mod.dCdt_rule = pyo.Constraint(mod.C_set, mod.t, rule=dCdt_control)\n", - "\n", - " mod.alge_rule = pyo.Constraint(mod.t, rule=alge)\n", - "\n", - " # B.C.\n", - " mod.C[\"CB\", 0.0].fix(0.0)\n", - " mod.C[\"CC\", 0.0].fix(0.0)\n", - "\n", - " if return_m:\n", - " return mod\n", - "\n", - "\n", - "def disc_for_measure(m, nfe=32, block=True):\n", - " \"\"\"Pyomo.DAE discretization\n", - "\n", - " Arguments\n", - " ---------\n", - " m: Pyomo model\n", - " nfe: number of finite elements b\n", - " block: if True, the input model has blocks\n", - " \"\"\"\n", - " discretizer = pyo.TransformationFactory(\"dae.collocation\")\n", - " if block:\n", - " for s in range(len(m.block)):\n", - " discretizer.apply_to(m.block[s], nfe=nfe, ncp=3, wrt=m.block[s].t)\n", - " else:\n", - " discretizer.apply_to(m, nfe=nfe, ncp=3, wrt=m.t)\n", - " return m" - ] - }, - { - "cell_type": "markdown", - "id": "ac9e76cb-cbf5-44fb-aa53-bbb5dca1bcb0", - "metadata": {}, - "source": [ - "## Helper Functions" - ] - }, - { - "cell_type": "markdown", - "id": "2814a5e6-e4b0-4fa1-948c-a8671c52fb4b", - "metadata": {}, - "source": [ - "### Create a doe object" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "24628fdb-317d-4121-b4ea-9909298a757e", - "metadata": {}, - "outputs": [], - "source": [ - "def create_doe_object(Ca_val, T_vals, prior_FIM=None):\n", - " t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - " parameter_dict = {\"A1\": 85, \"A2\": 370, \"E1\": 8, \"E2\": 15}\n", - " \n", - " measurements = MeasurementVariables()\n", - " measurements.add_variables(\"C\", indices={0: [\"CA\", \"CB\", \"CC\"], 1: t_control}, time_index_position=1)\n", - " \n", - " exp_design = DesignVariables()\n", - " exp_design.add_variables(\n", - " \"CA0\",\n", - " time_index_position=0,\n", - " values=[Ca_val, ],\n", - " lower_bounds=1,\n", - " indices={0: [0]},\n", - " upper_bounds=5,\n", - " )\n", - " exp_design.add_variables(\n", - " \"T\",\n", - " indices={0: t_control},\n", - " time_index_position=0,\n", - " values=T_vals,\n", - " lower_bounds=300,\n", - " upper_bounds=700,\n", - " )\n", - " \n", - " doe_object = DesignOfExperiments(\n", - " parameter_dict,\n", - " exp_design, \n", - " measurements, \n", - " create_model,\n", - " prior_FIM=prior_FIM,\n", - " discretize_model=disc_for_measure,\n", - " )\n", - " return doe_object" - ] - }, - { - "cell_type": "markdown", - "id": "35346c15-408b-4f32-bbfa-b4de9da2eaae", - "metadata": {}, - "source": [ - "### Compute FIM using the compute_FIM function" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "0a2d84d7-9989-43d3-84d0-df01a95c5a66", - "metadata": {}, - "outputs": [], - "source": [ - "def compute_specific_FIM(Ca_val, T_vals, prior_FIM=None, scale_param=True):\n", - " doe_object = create_doe_object(Ca_val, T_vals, prior_FIM)\n", - "\n", - " result = doe_object.compute_FIM(\n", - " mode=\"sequential_finite\",\n", - " scale_nominal_param_value=scale_param,\n", - " formula=\"central\",\n", - " )\n", - " result.result_analysis()\n", - " \n", - " return result" - ] - }, - { - "cell_type": "markdown", - "id": "1a6f71b5-f09c-40d3-9793-b830f05aae54", - "metadata": {}, - "source": [ - "### Rescale FIM" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "d000abc6-9140-4634-a180-d1c2b6df9e0c", - "metadata": {}, - "outputs": [], - "source": [ - "def rescale_FIM(FIM, param_vals):\n", - " param_scaling_mat = (1 / param_vals).transpose().dot(1 / param_vals)\n", - " unscaled_FIM = np.multiply(FIM, param_scaling_mat)\n", - " return unscaled_FIM" - ] - }, - { - "cell_type": "markdown", - "id": "679466b7-5299-4489-a3fb-cbfdd74cfc27", - "metadata": {}, - "source": [ - "### Translate Jacobian to numpy array" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "dff13661-d577-44a3-a171-b3fa1e6ff367", - "metadata": {}, - "outputs": [], - "source": [ - "def translate_jac(jac_dict):\n", - " param_names = ['A1', 'A2', 'E1', 'E2']\n", - " Q_all = np.array(list(jac_dict for p in param_names)).T\n", - " return Q_all" - ] - }, - { - "cell_type": "markdown", - "id": "60fcc29c-dad9-4d85-8d2c-81daeb08deb3", - "metadata": {}, - "source": [ - "### Get experimental conditions from solved model" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d6923520-83b5-4a64-9040-f19e1fa663f2", - "metadata": {}, - "outputs": [], - "source": [ - "def get_exp_conds(m):\n", - " return [pyo.value(m.CA0[0]),\n", - " pyo.value(m.T[0]),\n", - " pyo.value(m.T[0.125]),\n", - " pyo.value(m.T[0.25]),\n", - " pyo.value(m.T[0.375]),\n", - " pyo.value(m.T[0.5]),\n", - " pyo.value(m.T[0.625]),\n", - " pyo.value(m.T[0.75]),\n", - " pyo.value(m.T[0.875]),\n", - " pyo.value(m.T[1])]" - ] - }, - { - "cell_type": "markdown", - "id": "ed69f2f3-0517-4bdd-ae43-9566560e7e73", - "metadata": {}, - "source": [ - "### Run optimal experiment" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "id": "989b0b0d-6cca-4c56-8088-8c95c9c1773a", - "metadata": {}, - "outputs": [], - "source": [ - "def run_optimal_exp(Ca, Ta_vals, prior_FIM=None, scale_param=True):\n", - " doe_object = create_doe_object(Ca, Ta_vals, prior_FIM)\n", - "\n", - " if prior_FIM is None:\n", - " prior_FIM = np.eye(4)\n", - " \n", - " square_result, optimize_result = doe_object.stochastic_program(\n", - " if_optimize=True,\n", - " if_Cholesky=True,\n", - " scale_nominal_param_value=scale_param,\n", - " objective_option=\"det\",\n", - " L_initial=np.linalg.cholesky(prior_FIM),\n", - " )\n", - " \n", - " return optimize_result" - ] - }, - { - "cell_type": "markdown", - "id": "950f0e98-74b7-42bb-8781-a94da863eac6", - "metadata": {}, - "source": [ - "# Perform the analysis" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "e5013f1e-0e77-4697-a9de-8c137d930452", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 5.77e+02 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 6.70e+00 3.85e+00 -1.0 6.23e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 6.62e-02 4.39e+00 -1.0 7.18e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.10e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -7.8073036e+00 1.25e+00 1.21e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -7.8354856e+00 6.29e-01 5.10e+00 -1.0 4.68e+01 - 9.58e-01 4.97e-01h 1\n", - " 2 -7.8368689e+00 8.10e-01 1.42e+00 -1.0 3.23e+01 - 9.25e-01 1.00e+00f 1\n", - " 3 -7.9348649e+00 7.30e+01 1.59e+02 -1.0 4.72e+02 - 2.16e-01 7.26e-01f 1\n", - " 4 -7.7429992e+00 1.53e+01 2.05e+00 -1.0 1.61e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -7.7606510e+00 3.51e+00 2.02e+00 -1.0 1.39e+02 - 1.00e+00 1.00e+00f 1\n", - " 6 -7.6711598e+00 5.13e+00 3.33e-01 -1.0 4.03e+01 - 1.00e+00 1.00e+00h 1\n", - " 7 -7.6659485e+00 4.95e-02 7.71e-03 -1.0 2.74e+00 - 1.00e+00 1.00e+00h 1\n", - " 8 -7.6685762e+00 2.86e-03 1.24e-02 -2.5 8.68e-01 - 1.00e+00 1.00e+00h 1\n", - " 9 -7.7508739e+00 3.08e+00 3.55e-01 -3.8 3.14e+01 - 8.03e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -7.8600596e+00 6.29e+00 2.01e-01 -3.8 6.87e+01 - 1.00e+00 1.00e+00h 1\n", - " 11 -7.9182984e+00 4.14e+00 1.52e-01 -3.8 2.68e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 -7.9098461e+00 6.13e-02 2.12e-03 -3.8 8.74e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (325287)\n", - " 13 -7.9098458e+00 4.63e-05 4.17e-06 -3.8 2.49e-01 - 1.00e+00 1.00e+00h 1\n", - " 14 -7.9395810e+00 1.47e+00 5.37e-02 -5.7 2.73e+01 - 7.73e-01 1.00e+00h 1\n", - " 15 -7.9504201e+00 6.12e-01 7.82e-02 -5.7 2.47e+01 - 9.84e-01 1.00e+00h 1\n", - " 16 -7.9503130e+00 1.96e-02 5.10e-03 -5.7 1.22e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (347931)\n", - " 17 -7.9503760e+00 2.90e-03 7.32e-04 -5.7 4.78e+00 - 1.00e+00 1.00e+00h 1\n", - " 18 -7.9503861e+00 5.47e-05 1.53e-05 -5.7 6.60e-01 - 1.00e+00 1.00e+00h 1\n", - " 19 -7.9503862e+00 1.43e-08 5.92e-09 -5.7 1.07e-02 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -7.9510641e+00 2.59e-03 7.06e-04 -8.6 4.57e+00 - 9.84e-01 1.00e+00h 1\n", - " 21 -7.9510903e+00 1.70e-04 5.47e-05 -8.6 1.18e+00 - 1.00e+00 1.00e+00h 1\n", - " 22 -7.9510917e+00 4.69e-07 2.65e-07 -8.6 6.21e-02 - 1.00e+00 1.00e+00h 1\n", - " 23 -7.9510917e+00 4.83e-12 5.34e-12 -8.6 1.99e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -7.9510917256426819e+00 -7.9510917256426819e+00\n", - "Dual infeasibility......: 5.3406483518369473e-12 5.3406483518369473e-12\n", - "Constraint violation....: 4.8324677592859189e-12 4.8324677592859189e-12\n", - "Complementarity.........: 2.5059057458010459e-09 2.5059057458010459e-09\n", - "Overall NLP error.......: 2.5059057458010459e-09 2.5059057458010459e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 24\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 24\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.827\n", - "Total CPU secs in NLP function evaluations = 0.027\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.5 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 3.83e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.42e-02 3.85e+00 -1.0 4.12e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.37e-04 4.39e+00 -1.0 4.72e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.67e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8338667230373176e-11 5.8338667230373176e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8338667230373176e-11 5.8338667230373176e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.3463002e+00 1.25e+00 7.84e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 5.3181206e+00 6.32e-01 4.24e+01 -1.0 7.13e-01 - 9.72e-01 4.95e-01h 1\n", - " 2 5.3083839e+00 2.63e-02 1.90e+00 -1.0 3.89e+00 - 9.00e-01 1.00e+00f 1\n", - " 3 5.2237497e+00 1.10e+01 1.32e+02 -1.0 1.82e+02 - 1.89e-01 6.62e-01f 1\n", - " 4 5.4304758e+00 5.04e-01 2.27e+00 -1.0 3.13e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 5.3767095e+00 5.59e-01 3.10e+01 -1.0 1.35e+02 - 1.00e+00 4.26e-01f 2\n", - " 6 5.4552152e+00 8.41e-01 3.31e+00 -1.0 8.84e+01 - 9.40e-01 3.64e-01f 2\n", - " 7 5.5170724e+00 4.57e-01 4.85e-01 -1.0 4.86e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 5.5110643e+00 5.10e-03 2.84e-02 -1.7 1.44e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 5.4931986e+00 9.03e-03 1.34e-02 -2.5 4.22e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.4082326e+00 3.49e-01 3.95e-01 -3.8 2.69e+01 - 7.84e-01 1.00e+00h 1\n", - " 11 5.3009072e+00 1.28e+00 1.94e-01 -3.8 6.45e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 5.2328311e+00 3.94e-01 2.25e-01 -3.8 2.80e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 5.2437917e+00 5.42e-03 2.96e-03 -3.8 2.67e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (320786)\n", - " 14 5.2437575e+00 2.67e-05 8.17e-06 -3.8 2.13e-01 - 1.00e+00 1.00e+00h 1\n", - " 15 5.2424530e+00 7.65e-06 1.35e-05 -5.7 9.87e-02 -4.0 1.00e+00 1.00e+00h 1\n", - " 16 5.2417146e+00 5.83e-05 6.61e-05 -8.6 3.00e-01 -4.5 9.97e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (344430)\n", - " 17 5.2399653e+00 4.96e-04 6.20e-04 -8.6 8.80e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 18 5.2353444e+00 3.84e-03 4.47e-03 -8.6 2.48e+00 -5.4 1.00e+00 1.00e+00h 1\n", - " 19 5.2251746e+00 2.39e-02 2.25e-02 -8.6 6.35e+00 -5.9 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 5.2221058e+00 2.25e-02 2.03e-02 -8.6 1.32e+01 -6.4 1.00e+00 1.69e-01h 1\n", - " 21 5.2103493e+00 7.19e-02 5.06e-02 -8.6 2.54e+01 -6.9 1.00e+00 6.04e-01f 1\n", - " 22 5.1989953e+00 2.17e-01 1.44e-01 -8.6 5.35e+01 - 1.00e+00 7.30e-01f 1\n", - " 23 5.1994362e+00 1.93e-01 1.25e-01 -8.6 4.05e+01 - 1.00e+00 1.27e-01h 1\n", - " 24 5.2008740e+00 1.40e-01 6.63e-02 -8.6 3.68e+01 - 1.00e+00 4.77e-01h 1\n", - " 25 5.2025347e+00 1.75e-03 2.05e-03 -8.6 3.78e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (363451)\n", - " 26 5.2025125e+00 1.38e-03 1.06e-05 -8.6 3.34e+00 - 1.00e+00 1.00e+00h 1\n", - " 27 5.2025121e+00 2.22e-05 1.37e-07 -8.6 4.27e-01 - 1.00e+00 1.00e+00h 1\n", - " 28 5.2025121e+00 3.85e-09 2.27e-11 -8.6 5.62e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 28\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 5.2025120660150401e+00 5.2025120660150401e+00\n", - "Dual infeasibility......: 2.2651314864147046e-11 2.2651314864147046e-11\n", - "Constraint violation....: 3.8472891539242937e-09 3.8472891539242937e-09\n", - "Complementarity.........: 2.5061201652512559e-09 2.5061201652512559e-09\n", - "Overall NLP error.......: 3.8472891539242937e-09 3.8472891539242937e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 35\n", - "Number of objective gradient evaluations = 29\n", - "Number of equality constraint evaluations = 35\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 29\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 28\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.155\n", - "Total CPU secs in NLP function evaluations = 0.043\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.9 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.43e-03 1.52e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.33e-09 1.52e-06 -1.0 1.82e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.3276043314979233e-09 2.3276043314979233e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.3276043314979233e-09 2.3276043314979233e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.43e-03 1.52e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.33e-09 1.52e-06 -1.0 1.82e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.3276034433195036e-09 2.3276034433195036e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.3276034433195036e-09 2.3276034433195036e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 7.65e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 5.84e+02 3.85e+02 -1.0 7.65e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 6.77e+00 3.85e+00 -1.0 6.31e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 6.70e-02 4.39e+00 -1.0 7.25e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.17e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0383309725439176e-09 9.0383309725439176e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0383309725439176e-09 9.0383309725439176e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -9.0980672e+00 1.25e+00 1.13e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -9.1088823e+00 6.23e-01 5.20e+00 -1.0 4.67e+01 - 9.73e-01 5.02e-01h 1\n", - " 2 -9.1070281e+00 1.28e+00 1.94e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -9.1458221e+00 7.33e+01 1.31e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -9.0628162e+00 1.67e+01 2.33e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -9.0789051e+00 1.17e+01 3.14e+01 -1.0 1.36e+02 - 1.00e+00 4.20e-01f 2\n", - " 6 -9.0469561e+00 1.20e+01 3.32e+00 -1.0 9.02e+01 - 9.08e-01 3.50e-01f 2\n", - " 7 -9.0194008e+00 3.33e+00 5.06e-01 -1.0 5.04e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -9.0315738e+00 3.90e-01 6.40e-02 -1.0 9.89e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 -9.0319624e+00 5.08e-04 4.68e-03 -1.7 3.22e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -9.0344881e+00 1.57e-02 2.20e-01 -3.8 2.67e+00 - 9.84e-01 1.00e+00h 1\n", - " 11 -9.0929490e+00 9.49e+00 2.02e-01 -3.8 7.71e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 -9.1265794e+00 4.04e+00 1.08e-01 -3.8 2.61e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 -9.1216817e+00 7.85e-02 1.20e-03 -3.8 1.12e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (325095)\n", - " 14 -9.1216910e+00 9.57e-05 3.07e-06 -3.8 2.80e-01 - 1.00e+00 1.00e+00h 1\n", - " 15 -9.1419843e+00 2.21e+00 4.13e-02 -5.7 3.31e+01 - 7.83e-01 1.00e+00h 1\n", - " 16 -9.1523277e+00 3.23e+00 1.07e-01 -5.7 5.50e+01 - 5.77e-01 8.28e-01h 1\n", - " 17 -9.1542206e+00 1.66e-01 4.37e-03 -5.7 1.73e+01 - 1.00e+00 1.00e+00h 1\n", - " 18 -9.1545142e+00 1.36e-02 1.84e-03 -5.7 1.01e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -9.1545212e+00 1.02e-03 1.25e-04 -5.7 2.81e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (343319)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -9.1545223e+00 4.18e-06 5.47e-07 -5.7 1.81e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -9.1551820e+00 9.84e-03 7.80e-04 -8.6 6.83e+00 - 9.73e-01 1.00e+00h 1\n", - " 22 -9.1552078e+00 8.18e-04 1.19e-04 -8.6 2.58e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (362498)\n", - " 23 -9.1552112e+00 1.16e-05 2.50e-06 -8.6 3.08e-01 - 1.00e+00 1.00e+00h 1\n", - " 24 -9.1552112e+00 1.62e-09 9.16e-10 -8.6 3.65e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 24\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -9.1552111997823289e+00 -9.1552111997823289e+00\n", - "Dual infeasibility......: 9.1614693867759918e-10 9.1614693867759918e-10\n", - "Constraint violation....: 1.6240718769822138e-09 1.6240718769822138e-09\n", - "Complementarity.........: 2.5062713088537995e-09 2.5062713088537995e-09\n", - "Overall NLP error.......: 2.5062713088537995e-09 2.5062713088537995e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 31\n", - "Number of objective gradient evaluations = 25\n", - "Number of equality constraint evaluations = 31\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 25\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 24\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.818\n", - "Total CPU secs in NLP function evaluations = 0.029\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.3 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 3.86e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.45e-02 3.85e+00 -1.0 4.15e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.40e-04 4.39e+00 -1.0 4.75e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.70e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8336890873533775e-11 5.8336890873533775e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8336890873533775e-11 5.8336890873533775e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", - "Total CPU secs in NLP function evaluations = 0.007\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 4.0555365e+00 1.25e+00 4.96e+01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 4.0447179e+00 6.24e-01 2.67e+01 -1.0 7.09e-01 - 9.72e-01 5.01e-01h 1\n", - " 2 4.0465757e+00 2.64e-02 1.93e+00 -1.0 3.91e+00 - 8.99e-01 1.00e+00f 1\n", - " 3 4.0077802e+00 1.10e+01 1.31e+02 -1.0 1.82e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 4.0907795e+00 5.11e-01 2.33e+00 -1.0 3.13e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 4.0746958e+00 5.49e-01 3.14e+01 -1.0 1.36e+02 - 1.00e+00 4.20e-01f 2\n", - " 6 4.1066414e+00 8.29e-01 3.32e+00 -1.0 9.02e+01 - 9.08e-01 3.50e-01f 2\n", - " 7 4.1341891e+00 4.99e-01 5.06e-01 -1.0 5.03e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 4.1322707e+00 5.59e-03 2.41e-02 -1.7 1.21e+00 - 1.00e+00 1.00e+00h 1\n", - " 9 4.1294448e+00 1.74e-03 1.90e-01 -3.8 1.80e+00 - 9.85e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 4.0577304e+00 2.51e+00 3.18e-01 -3.8 8.71e+01 - 1.00e+00 1.00e+00h 1\n", - " 11 4.0619968e+00 6.23e-02 7.22e-03 -3.8 1.27e+00 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 4.0610820e+00 2.11e-05 1.57e-05 -3.8 1.71e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 4.0025145e+00 1.12e+00 2.83e-01 -5.7 5.61e+01 - 6.15e-01 1.00e+00h 1\n", - " 14 4.0028658e+00 3.34e-01 8.43e-02 -5.7 2.46e+01 - 6.14e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (328499)\n", - " 15 3.9993729e+00 8.26e-02 2.36e-02 -5.7 1.29e+01 - 1.00e+00 8.29e-01h 1\n", - " 16 3.9990307e+00 1.69e-02 2.80e-03 -5.7 1.13e+01 - 1.00e+00 1.00e+00f 1\n", - " 17 3.9990819e+00 1.12e-03 1.43e-04 -5.7 2.96e+00 - 1.00e+00 1.00e+00h 1\n", - " 18 3.9990815e+00 4.62e-06 7.31e-07 -5.7 1.90e-01 - 1.00e+00 1.00e+00h 1\n", - " 19 3.9984217e+00 5.89e-03 7.80e-04 -8.6 6.83e+00 - 9.73e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (356713)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 3.9983959e+00 8.18e-04 1.19e-04 -8.6 2.58e+00 - 1.00e+00 1.00e+00h 1\n", - " 21 3.9983926e+00 1.16e-05 2.50e-06 -8.6 3.08e-01 - 1.00e+00 1.00e+00h 1\n", - " 22 3.9983926e+00 1.62e-09 9.16e-10 -8.6 3.65e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 22\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 3.9983925918754277e+00 3.9983925918754277e+00\n", - "Dual infeasibility......: 9.1638497048149078e-10 9.1638497048149078e-10\n", - "Constraint violation....: 1.6245825795735414e-09 1.6245825795735414e-09\n", - "Complementarity.........: 2.5062714319510496e-09 2.5062714319510496e-09\n", - "Overall NLP error.......: 2.5062714319510496e-09 2.5062714319510496e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 29\n", - "Number of objective gradient evaluations = 23\n", - "Number of equality constraint evaluations = 29\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 23\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 22\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.757\n", - "Total CPU secs in NLP function evaluations = 0.035\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.5 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.43e-03 1.62e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.31e-09 1.52e-06 -1.0 1.81e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.3096600187955119e-09 2.3096600187955119e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.3096600187955119e-09 2.3096600187955119e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.008\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.43e-03 1.62e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.31e-09 1.52e-06 -1.0 1.81e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.3096582424386725e-09 2.3096582424386725e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.3096582424386725e-09 2.3096582424386725e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.53e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 5.92e+02 3.85e+02 -1.0 1.53e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 6.85e+00 3.85e+00 -1.0 6.39e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 6.78e-02 4.39e+00 -1.0 7.33e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.25e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0381035988684744e-09 9.0381035988684744e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0381035988684744e-09 9.0381035988684744e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -9.8243678e+00 1.25e+00 1.11e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -9.8309752e+00 6.21e-01 5.18e+00 -1.0 4.66e+01 - 9.73e-01 5.03e-01h 1\n", - " 2 -9.8284057e+00 1.28e+00 1.94e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -9.8536224e+00 7.33e+01 1.31e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -9.8018928e+00 1.67e+01 2.30e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -9.8108490e+00 1.17e+01 3.16e+01 -1.0 1.36e+02 - 1.00e+00 4.18e-01f 2\n", - " 6 -9.7907700e+00 1.21e+01 3.32e+00 -1.0 9.09e+01 - 8.96e-01 3.45e-01f 2\n", - " 7 -9.7727931e+00 3.44e+00 5.16e-01 -1.0 5.11e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -9.7806557e+00 4.10e-01 6.89e-02 -1.0 1.03e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -9.7808078e+00 3.15e-04 3.35e-03 -1.7 2.38e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -9.7818625e+00 6.70e-03 1.10e-01 -3.8 1.81e+00 - 9.92e-01 1.00e+00h 1\n", - " 11 -9.8219871e+00 1.08e+01 1.59e-01 -3.8 8.04e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 -9.8318869e+00 1.12e+00 2.36e-02 -3.8 1.46e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 -9.8315331e+00 8.02e-03 5.09e-05 -3.8 3.56e+00 - 1.00e+00 1.00e+00h 1\n", - " 14 -9.8315167e+00 4.91e-06 6.23e-08 -3.8 2.45e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319727)\n", - " 15 -9.8470261e+00 2.31e+00 2.95e-02 -5.7 3.68e+01 - 7.66e-01 1.00e+00f 1\n", - " 16 -9.8550043e+00 3.01e+00 3.76e-02 -5.7 4.15e+01 - 6.44e-01 1.00e+00h 1\n", - " 17 -9.8580603e+00 2.13e+00 3.03e-02 -5.7 5.38e+01 - 9.08e-01 5.97e-01h 1\n", - "Reallocating memory for MA57: lfact (343560)\n", - " 18 -9.8590178e+00 5.44e-02 3.07e-03 -5.7 1.49e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -9.8588956e+00 2.88e-03 2.14e-04 -5.7 4.70e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -9.8588964e+00 2.30e-05 1.59e-06 -5.7 4.22e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -9.8588964e+00 1.08e-09 9.88e-11 -5.7 2.90e-03 - 1.00e+00 1.00e+00h 1\n", - " 22 -9.8595479e+00 2.23e-02 7.77e-04 -8.6 8.37e+00 - 9.64e-01 1.00e+00f 1\n", - " 23 -9.8595710e+00 1.73e-03 1.60e-04 -8.6 3.74e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 -9.8595756e+00 5.35e-05 6.70e-06 -8.6 6.62e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (362351)\n", - " 25 -9.8595757e+00 3.41e-08 9.69e-09 -8.6 1.67e-02 - 1.00e+00 1.00e+00h 1\n", - " 26 -9.8595757e+00 4.55e-13 5.52e-14 -8.6 2.20e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 26\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -9.8595757275986511e+00 -9.8595757275986511e+00\n", - "Dual infeasibility......: 5.5219338836918813e-14 5.5219338836918813e-14\n", - "Constraint violation....: 1.1824654114063750e-13 4.5474735088646412e-13\n", - "Complementarity.........: 2.5059035684619852e-09 2.5059035684619852e-09\n", - "Overall NLP error.......: 2.5059035684619852e-09 2.5059035684619852e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 27\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 27\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.850\n", - "Total CPU secs in NLP function evaluations = 0.040\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.5 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 3.89e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.48e-02 3.85e+00 -1.0 4.18e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.43e-04 4.39e+00 -1.0 4.79e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.73e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8336446784323925e-11 5.8336446784323925e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8336446784323925e-11 5.8336446784323925e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 3.3292360e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 3.3241914e+00 1.69e-01 1.13e+00 -1.0 5.96e-01 - 9.79e-01 8.65e-01h 1\n", - " 2 3.3248864e+00 3.48e-02 1.06e+01 -1.0 6.02e+00 - 8.34e-01 1.00e+00f 1\n", - " 3 3.3013605e+00 1.26e+01 5.70e+01 -1.0 1.80e+02 - 1.92e-01 7.12e-01f 1\n", - " 4 3.3560475e+00 7.19e-01 2.65e+00 -1.0 2.65e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 3.3417261e+00 5.86e-01 4.46e+01 -1.0 3.82e+02 - 4.35e-01 8.06e-02f 2\n", - " 6 3.3757459e+00 1.35e-01 4.87e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", - " 7 3.3696371e+00 4.25e-01 3.04e-01 -1.0 5.43e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 3.3719932e+00 4.00e-02 5.66e-02 -1.7 1.71e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 3.3709820e+00 4.47e-03 3.86e-03 -2.5 5.77e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 3.3640190e+00 1.64e-02 7.98e-02 -3.8 6.30e+00 - 9.57e-01 1.00e+00h 1\n", - " 11 3.3273550e+00 8.10e-01 8.71e-02 -3.8 4.15e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 3.3219891e+00 1.09e-01 1.42e-02 -3.8 1.16e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 3.3220787e+00 1.81e-04 1.97e-05 -3.8 5.23e-01 - 1.00e+00 1.00e+00h 1\n", - " 14 3.3065783e+00 3.88e-01 2.95e-02 -5.7 3.68e+01 - 7.66e-01 1.00e+00h 1\n", - " 15 3.3088038e+00 6.58e-04 2.85e-03 -5.7 1.95e-01 -4.5 9.73e-01 1.00e+00h 1\n", - " 16 3.3086408e+00 2.78e-05 4.37e-06 -5.7 2.06e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 17 3.3082900e+00 2.44e-04 3.75e-05 -5.7 6.13e-01 -5.4 1.00e+00 1.00e+00h 1\n", - " 18 3.3073216e+00 2.02e-03 3.10e-04 -5.7 1.78e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 19 3.3049420e+00 1.48e-02 2.24e-03 -5.7 4.93e+00 -6.4 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 3.3006609e+00 6.58e-02 9.79e-03 -5.7 1.19e+01 -6.9 1.00e+00 8.79e-01h 1\n", - " 21 3.2971545e+00 1.04e-01 2.91e-02 -5.7 1.96e+01 -7.3 1.00e+00 1.00e+00f 1\n", - " 22 3.2963467e+00 1.07e-01 2.86e-02 -5.7 9.98e+01 - 9.97e-01 5.49e-02h 1\n", - " 23 3.2940284e+00 2.58e-01 2.86e-02 -5.7 4.31e+01 - 1.00e+00 1.00e+00f 1\n", - "Reallocating memory for MA57: lfact (328243)\n", - " 24 3.2947114e+00 6.39e-03 2.75e-03 -5.7 5.48e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 3.2947076e+00 2.82e-04 1.21e-05 -5.7 1.48e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 3.2947074e+00 3.77e-07 7.87e-09 -5.7 5.41e-02 - 1.00e+00 1.00e+00h 1\n", - " 27 3.2940558e+00 8.94e-03 7.77e-04 -8.6 8.37e+00 - 9.64e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (351796)\n", - " 28 3.2940328e+00 1.73e-03 1.60e-04 -8.6 3.74e+00 - 1.00e+00 1.00e+00h 1\n", - " 29 3.2940282e+00 5.35e-05 6.70e-06 -8.6 6.62e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 3.2940281e+00 3.41e-08 9.69e-09 -8.6 1.67e-02 - 1.00e+00 1.00e+00h 1\n", - " 31 3.2940281e+00 3.59e-13 6.26e-14 -8.6 2.20e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 31\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 3.2940280640592707e+00 3.2940280640592707e+00\n", - "Dual infeasibility......: 6.2616567740385095e-14 6.2616567740385095e-14\n", - "Constraint violation....: 1.5287940420760863e-13 3.5882408155885059e-13\n", - "Complementarity.........: 2.5059035684585384e-09 2.5059035684585384e-09\n", - "Overall NLP error.......: 2.5059035684585384e-09 2.5059035684585384e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 36\n", - "Number of objective gradient evaluations = 32\n", - "Number of equality constraint evaluations = 36\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 32\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 31\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.195\n", - "Total CPU secs in NLP function evaluations = 0.048\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.9 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.42e-03 1.85e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.27e-09 1.51e-06 -1.0 1.79e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2713546599106849e-09 2.2713546599106849e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2713546599106849e-09 2.2713546599106849e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.104\n", - "Total CPU secs in NLP function evaluations = 0.007\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.42e-03 1.85e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.27e-09 1.51e-06 -1.0 1.79e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2713533276430553e-09 2.2713533276430553e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2713533276430553e-09 2.2713533276430553e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.30e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.00e+02 3.85e+02 -1.0 2.30e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 6.93e+00 3.85e+00 -1.0 6.46e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 6.85e-02 4.39e+00 -1.0 7.41e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.33e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", - "Total CPU secs in NLP function evaluations = 0.008\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.0333966e+01 1.25e+00 1.09e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.0338708e+01 6.20e-01 5.17e+00 -1.0 4.65e+01 - 9.73e-01 5.04e-01h 1\n", - " 2 -1.0336296e+01 1.28e+00 1.95e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.0354984e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.0317441e+01 1.67e+01 2.27e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.0323555e+01 1.17e+01 3.18e+01 -1.0 1.36e+02 - 1.00e+00 4.16e-01f 2\n", - " 6 -1.0308913e+01 1.22e+01 3.32e+00 -1.0 9.13e+01 - 8.90e-01 3.42e-01f 2\n", - " 7 -1.0295537e+01 3.50e+00 5.22e-01 -1.0 5.14e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.0301363e+01 4.21e-01 7.17e-02 -1.0 1.05e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.0301441e+01 2.63e-04 2.69e-03 -1.7 2.08e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.0302019e+01 3.71e-03 5.57e-02 -3.8 1.37e+00 - 9.96e-01 1.00e+00h 1\n", - " 11 -1.0333647e+01 1.23e+01 1.35e-01 -3.8 8.29e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 -1.0334471e+01 3.28e-01 4.31e-03 -3.8 1.15e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 -1.0335026e+01 4.18e-03 1.95e-05 -3.8 6.62e-01 - 1.00e+00 1.00e+00h 1\n", - " 14 -1.0335021e+01 3.25e-07 2.67e-09 -3.8 1.60e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (324090)\n", - " 15 -1.0347510e+01 2.31e+00 2.80e-02 -5.7 3.87e+01 - 7.60e-01 1.00e+00f 1\n", - " 16 -1.0354058e+01 2.41e+00 2.21e-02 -5.7 3.02e+01 - 7.30e-01 1.00e+00h 1\n", - " 17 -1.0356712e+01 3.68e+00 4.66e-02 -5.7 1.52e+02 - 5.86e-01 2.47e-01h 1\n", - " 18 -1.0358821e+01 2.88e-01 4.06e-03 -5.7 1.96e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.0358654e+01 8.94e-03 4.59e-04 -5.7 8.19e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.0358657e+01 2.20e-04 8.10e-06 -5.7 1.30e+00 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.0358657e+01 9.03e-08 2.32e-09 -5.7 2.63e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (347964)\n", - " 22 -1.0359304e+01 3.93e-02 7.56e-04 -8.6 9.55e+00 - 9.56e-01 1.00e+00h 1\n", - " 23 -1.0359325e+01 2.75e-03 1.87e-04 -8.6 4.70e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 -1.0359330e+01 1.37e-04 1.18e-05 -8.6 1.06e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.0359330e+01 2.28e-07 3.96e-08 -8.6 4.33e-02 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.0359330e+01 1.70e-12 4.97e-13 -8.6 1.18e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 26\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.0359330165707208e+01 -1.0359330165707208e+01\n", - "Dual infeasibility......: 4.9706657073264839e-13 4.9706657073264839e-13\n", - "Constraint violation....: 1.7005286068183523e-12 1.7005286068183523e-12\n", - "Complementarity.........: 2.5059037505427129e-09 2.5059037505427129e-09\n", - "Overall NLP error.......: 2.5059037505427129e-09 2.5059037505427129e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 27\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 27\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.860\n", - "Total CPU secs in NLP function evaluations = 0.024\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.6 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 3.92e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.51e-02 3.85e+00 -1.0 4.21e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.46e-04 4.39e+00 -1.0 4.82e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.76e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8337334962743626e-11 5.8337334962743626e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8337334962743626e-11 5.8337334962743626e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.125\n", - "Total CPU secs in NLP function evaluations = 0.010\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 2.8196379e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 2.8162115e+00 1.65e-01 1.10e+00 -1.0 5.96e-01 - 9.79e-01 8.68e-01h 1\n", - " 2 2.8171449e+00 3.48e-02 1.08e+01 -1.0 6.03e+00 - 8.34e-01 1.00e+00f 1\n", - " 3 2.7994163e+00 1.25e+01 5.72e+01 -1.0 1.80e+02 - 1.92e-01 7.12e-01f 1\n", - " 4 2.8392046e+00 7.17e-01 2.60e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 2.8292019e+00 5.86e-01 4.54e+01 -1.0 3.71e+02 - 4.48e-01 8.32e-02f 2\n", - " 6 2.8540376e+00 1.35e-01 5.27e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", - " 7 2.8496419e+00 4.28e-01 2.99e-01 -1.0 5.45e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 2.8514802e+00 3.95e-02 5.69e-02 -1.7 1.69e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 2.8509342e+00 4.75e-03 3.32e-03 -2.5 5.95e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.8470769e+00 9.20e-03 3.76e-02 -3.8 4.69e+00 - 9.80e-01 1.00e+00h 1\n", - " 11 2.8179475e+00 8.07e-01 7.45e-02 -3.8 3.88e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 2.8189649e+00 2.78e-02 1.87e-03 -3.8 5.72e+00 - 1.00e+00 1.00e+00h 1\n", - " 13 2.8185808e+00 5.85e-05 6.97e-06 -3.8 3.19e-01 - 1.00e+00 1.00e+00h 1\n", - " 14 2.8060943e+00 4.50e-01 2.80e-02 -5.7 3.87e+01 - 7.60e-01 1.00e+00h 1\n", - " 15 2.8076988e+00 1.27e-03 1.40e-03 -5.7 2.15e-01 -4.5 9.84e-01 1.00e+00h 1\n", - " 16 2.8075717e+00 1.61e-05 2.02e-06 -5.7 1.49e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 17 2.8073034e+00 1.50e-04 2.56e-05 -8.6 4.56e-01 -5.4 9.91e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (332552)\n", - " 18 2.7996057e+00 1.17e+00 3.50e-01 -8.6 1.18e+02 - 2.14e-01 7.03e-01h 1\n", - " 19 2.7992999e+00 1.00e+00 2.99e-01 -8.6 1.21e+02 - 1.40e-01 1.38e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 2.7992903e+00 9.94e-01 2.96e-01 -8.6 3.79e+01 - 7.17e-01 9.13e-03h 1\n", - " 21 2.7990482e+00 6.68e-01 1.97e-01 -8.6 3.87e+01 - 9.68e-01 3.74e-01h 1\n", - " 22 2.7989147e+00 5.66e-01 1.67e-01 -8.6 3.55e+01 - 1.00e+00 1.65e-01f 1\n", - " 23 2.7981330e+00 2.94e-01 8.73e-02 -8.6 3.53e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (356955)\n", - " 24 2.7982525e+00 9.54e-03 2.30e-03 -8.6 6.04e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 25 2.7953817e+00 8.37e-01 2.60e-01 -8.6 8.53e+01 - 7.77e-02 6.80e-01h 1\n", - " 26 2.7970874e+00 5.84e-01 1.64e-01 -8.6 5.21e+01 - 1.00e+00 5.00e-01h 2\n", - " 27 2.7963533e+00 2.95e-02 5.91e-03 -8.6 2.18e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 28 2.7958325e+00 8.11e-03 1.49e-03 -8.6 5.48e+00 -6.9 1.00e+00 1.00e+00h 1\n", - " 29 2.7945535e+00 7.95e-02 1.40e-02 -8.6 1.74e+01 -7.3 6.23e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 2.7944657e+00 7.83e-02 1.38e-02 -8.6 5.44e+01 -7.8 8.23e-01 1.76e-02h 1\n", - " 31 2.7944608e+00 7.71e-02 1.36e-02 -8.6 7.54e+00 - 8.32e-01 1.59e-02h 1\n", - " 32 2.7941818e+00 6.39e-03 2.32e-03 -8.6 7.11e+00 - 1.00e+00 1.00e+00f 1\n", - " 33 2.7942732e+00 7.14e-05 1.97e-05 -8.6 7.45e-01 - 1.00e+00 1.00e+00h 1\n", - " 34 2.7942736e+00 7.61e-09 1.93e-09 -8.6 7.70e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 34\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.7942736259106784e+00 2.7942736259106784e+00\n", - "Dual infeasibility......: 1.9311658899047611e-09 1.9311658899047611e-09\n", - "Constraint violation....: 7.6102699697599974e-09 7.6102699697599974e-09\n", - "Complementarity.........: 2.5060093311148399e-09 2.5060093311148399e-09\n", - "Overall NLP error.......: 7.6102699697599974e-09 7.6102699697599974e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 40\n", - "Number of objective gradient evaluations = 35\n", - "Number of equality constraint evaluations = 40\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 35\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 34\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.244\n", - "Total CPU secs in NLP function evaluations = 0.050\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.41e-03 2.08e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.23e-09 1.50e-06 -1.0 1.78e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2333721538814189e-09 2.2333721538814189e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2333721538814189e-09 2.2333721538814189e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.41e-03 2.08e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.23e-09 1.50e-06 -1.0 1.78e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2333717097922090e-09 2.2333717097922090e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2333717097922090e-09 2.2333717097922090e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 0.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.06e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.07e+02 3.85e+02 -1.0 3.06e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.00e+00 3.85e+00 -1.0 6.54e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 6.93e-02 4.39e+00 -1.0 7.48e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.40e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0381035988684744e-09 9.0381035988684744e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0381035988684744e-09 9.0381035988684744e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", - "Total CPU secs in NLP function evaluations = 0.007\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.0727169e+01 1.25e+00 1.08e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.0730862e+01 6.19e-01 5.16e+00 -1.0 4.65e+01 - 9.73e-01 5.05e-01h 1\n", - " 2 -1.0728705e+01 1.28e+00 1.95e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.0743551e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.0714096e+01 1.67e+01 2.25e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.0718710e+01 1.18e+01 3.18e+01 -1.0 1.36e+02 - 1.00e+00 4.15e-01f 2\n", - " 6 -1.0707188e+01 1.22e+01 3.32e+00 -1.0 9.16e+01 - 8.86e-01 3.40e-01f 2\n", - " 7 -1.0696529e+01 3.54e+00 5.25e-01 -1.0 5.17e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.0701162e+01 4.28e-01 7.36e-02 -1.0 1.06e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.0701207e+01 2.45e-04 2.30e-03 -1.7 2.53e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.0701573e+01 2.36e-03 2.36e-02 -3.8 1.10e+00 - 9.98e-01 1.00e+00h 1\n", - " 11 -1.0728466e+01 1.41e+01 1.22e-01 -3.8 8.53e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 -1.0724859e+01 5.12e-01 5.81e-03 -3.8 1.89e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 -1.0725400e+01 2.98e-03 1.26e-05 -3.8 1.22e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319443)\n", - " 14 -1.0725400e+01 2.16e-08 1.65e-09 -3.8 6.85e-03 - 1.00e+00 1.00e+00h 1\n", - " 15 -1.0735769e+01 2.29e+00 2.70e-02 -5.7 3.95e+01 - 7.59e-01 1.00e+00f 1\n", - " 16 -1.0741697e+01 2.18e+00 1.82e-02 -5.7 3.17e+01 - 7.93e-01 1.00e+00h 1\n", - " 17 -1.0742738e+01 2.63e+00 1.88e-02 -5.7 3.36e+02 - 3.31e-01 5.69e-02h 2\n", - " 18 -1.0746014e+01 1.33e+00 1.30e-02 -5.7 3.62e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.0746312e+01 1.77e-01 1.01e-03 -5.7 1.56e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (336826)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.0746301e+01 6.01e-04 1.57e-05 -5.7 2.13e+00 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.0746301e+01 5.82e-07 8.09e-09 -5.7 6.66e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.0746946e+01 6.09e-02 7.31e-04 -8.6 1.05e+01 - 9.50e-01 1.00e+00h 1\n", - " 23 -1.0746963e+01 3.80e-03 2.04e-04 -8.6 5.52e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (359506)\n", - " 24 -1.0746969e+01 2.64e-04 1.71e-05 -8.6 1.47e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.0746970e+01 8.56e-07 1.03e-07 -8.6 8.39e-02 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.0746970e+01 1.75e-11 3.92e-12 -8.6 3.79e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 26\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.0746969709499885e+01 -1.0746969709499885e+01\n", - "Dual infeasibility......: 3.9211112624388169e-12 3.9211112624388169e-12\n", - "Constraint violation....: 1.7519652395492358e-11 1.7519652395492358e-11\n", - "Complementarity.........: 2.5059051337529310e-09 2.5059051337529310e-09\n", - "Overall NLP error.......: 2.5059051337529310e-09 2.5059051337529310e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 36\n", - "Number of objective gradient evaluations = 27\n", - "Number of equality constraint evaluations = 36\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 27\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.940\n", - "Total CPU secs in NLP function evaluations = 0.036\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.32e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 3.95e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.55e-02 3.85e+00 -1.0 4.25e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.50e-04 4.39e+00 -1.0 4.85e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.80e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", - "Total CPU secs in NLP function evaluations = 0.008\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 2.4264349e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 2.4238621e+00 1.63e-01 1.09e+00 -1.0 5.95e-01 - 9.79e-01 8.70e-01h 1\n", - " 2 2.4248028e+00 3.48e-02 1.10e+01 -1.0 6.03e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 2.4105783e+00 1.25e+01 5.73e+01 -1.0 1.80e+02 - 1.92e-01 7.12e-01f 1\n", - " 4 2.4418472e+00 7.15e-01 2.57e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 2.4341825e+00 5.85e-01 4.59e+01 -1.0 3.64e+02 - 4.56e-01 8.47e-02f 2\n", - " 6 2.4537211e+00 1.36e-01 5.47e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", - " 7 2.4503021e+00 4.30e-01 2.96e-01 -1.0 5.46e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 2.4518079e+00 3.92e-02 5.71e-02 -1.7 1.69e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 2.4514688e+00 4.92e-03 3.01e-03 -2.5 6.06e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.4490209e+00 5.79e-03 1.11e-02 -3.8 3.70e+00 - 9.94e-01 1.00e+00h 1\n", - " 11 2.4240878e+00 7.98e-01 6.68e-02 -3.8 3.99e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 2.4284887e+00 8.05e-03 3.01e-03 -3.8 7.54e+00 - 1.00e+00 1.00e+00h 1\n", - " 13 2.4282037e+00 3.91e-05 3.61e-06 -3.8 2.51e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (321514)\n", - " 14 2.4178352e+00 4.81e-01 2.70e-02 -5.7 3.95e+01 - 7.59e-01 1.00e+00h 1\n", - " 15 2.4119071e+00 2.15e-01 1.82e-02 -5.7 3.17e+01 - 7.93e-01 1.00e+00h 1\n", - " 16 2.4108659e+00 2.12e-01 1.88e-02 -5.7 2.81e+02 - 3.31e-01 5.69e-02h 2\n", - " 17 2.4075899e+00 1.15e-01 1.30e-02 -5.7 2.13e+01 - 1.00e+00 1.00e+00h 1\n", - " 18 2.4072917e+00 1.38e-02 1.01e-03 -5.7 1.01e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (337602)\n", - " 19 2.4073026e+00 6.01e-04 1.57e-05 -5.7 2.13e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 2.4073027e+00 5.82e-07 8.09e-09 -5.7 6.66e-02 - 1.00e+00 1.00e+00h 1\n", - " 21 2.4066582e+00 1.43e-02 7.31e-04 -8.6 1.05e+01 - 9.50e-01 1.00e+00h 1\n", - " 22 2.4066404e+00 3.80e-03 2.04e-04 -8.6 5.52e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (360986)\n", - " 23 2.4066344e+00 2.64e-04 1.71e-05 -8.6 1.47e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 2.4066341e+00 8.56e-07 1.03e-07 -8.6 8.39e-02 - 1.00e+00 1.00e+00h 1\n", - " 25 2.4066341e+00 1.75e-11 3.92e-12 -8.6 3.79e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 25\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.4066340821203402e+00 2.4066340821203402e+00\n", - "Dual infeasibility......: 3.9211113364714817e-12 3.9211113364714817e-12\n", - "Constraint violation....: 1.7518986261677583e-11 1.7518986261677583e-11\n", - "Complementarity.........: 2.5059051337162099e-09 2.5059051337162099e-09\n", - "Overall NLP error.......: 2.5059051337162099e-09 2.5059051337162099e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 26\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 26\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 25\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.855\n", - "Total CPU secs in NLP function evaluations = 0.033\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.6 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.39e-03 2.31e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.20e-09 1.49e-06 -1.0 1.76e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1957125007077138e-09 2.1957125007077138e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1957125007077138e-09 2.1957125007077138e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.102\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.39e-03 2.31e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.20e-09 1.49e-06 -1.0 1.76e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1957116125292941e-09 2.1957116125292941e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1957116125292941e-09 2.1957116125292941e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.83e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.15e+02 3.85e+02 -1.0 3.83e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.08e+00 3.85e+00 -1.0 6.62e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.00e-02 4.39e+00 -1.0 7.56e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.48e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0390130935702473e-09 9.0390130935702473e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0390130935702473e-09 9.0390130935702473e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.1047463e+01 1.25e+00 1.08e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.1050486e+01 6.19e-01 5.16e+00 -1.0 4.65e+01 - 9.73e-01 5.05e-01h 1\n", - " 2 -1.1048562e+01 1.28e+00 1.95e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.1060878e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.1036646e+01 1.67e+01 2.24e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.1040342e+01 1.18e+01 3.19e+01 -1.0 1.36e+02 - 1.00e+00 4.15e-01f 2\n", - " 6 -1.1030843e+01 1.22e+01 3.32e+00 -1.0 9.18e+01 - 8.84e-01 3.39e-01f 2\n", - " 7 -1.1021982e+01 3.57e+00 5.28e-01 -1.0 5.19e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.1025828e+01 4.33e-01 7.49e-02 -1.0 1.07e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.1025857e+01 2.38e-04 2.03e-03 -1.7 2.83e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.1026109e+01 1.63e-03 2.25e-03 -3.8 9.21e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.1026632e+01 7.86e-04 4.02e-04 -3.8 1.57e+00 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.1027550e+01 2.46e-03 3.00e-04 -5.7 2.75e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 -1.1028272e+01 2.47e-03 5.48e-04 -5.7 2.72e+00 -5.0 1.00e+00 7.82e-01h 1\n", - " 14 -1.1028813e+01 8.65e-03 7.74e-04 -5.7 1.44e+00 -5.4 1.00e+00 1.00e+00f 1\n", - " 15r-1.1028813e+01 8.65e-03 9.99e+02 -2.1 0.00e+00 - 0.00e+00 3.69e-07R 16\n", - " 16r-1.1028744e+01 1.97e-03 2.91e+02 -2.1 2.14e+02 - 1.00e+00 9.90e-04f 1\n", - " 17 -1.1028797e+01 1.97e-03 7.77e-02 -5.7 7.31e+03 - 6.04e-02 2.22e-05h 2\n", - " 18 -1.1070945e+01 5.57e+01 7.49e-02 -5.7 4.61e+03 - 3.70e-02 3.66e-02h 1\n", - " 19 -1.1077425e+01 5.37e+01 7.00e-02 -5.7 7.35e+02 - 7.21e-02 6.45e-02h 1\n", - "Reallocating memory for MA57: lfact (323295)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.1075942e+01 4.63e+01 6.82e-02 -5.7 2.71e+02 - 1.00e+00 1.71e-01h 1\n", - " 21 -1.1056650e+01 7.71e+00 7.12e-01 -5.7 9.20e+01 - 7.89e-01 1.00e+00h 1\n", - " 22 -1.1061268e+01 4.91e-01 3.85e-02 -5.7 2.95e+01 -5.9 1.00e+00 1.00e+00h 1\n", - " 23 -1.1062198e+01 6.67e-01 2.40e-02 -5.7 3.95e+01 - 1.00e+00 3.17e-01h 2\n", - " 24 -1.1062691e+01 5.52e-01 1.59e-02 -5.7 1.91e+01 - 1.00e+00 3.26e-01h 2\n", - " 25 -1.1063214e+01 1.71e-01 4.96e-03 -5.7 7.52e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.1063041e+01 1.76e-02 8.52e-04 -5.7 4.14e+00 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.1063029e+01 1.30e-04 4.18e-06 -5.7 3.18e-01 - 1.00e+00 1.00e+00h 1\n", - " 28 -1.1063029e+01 3.22e-09 1.10e-10 -5.7 1.63e-03 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (352737)\n", - " 29 -1.1063672e+01 8.69e-02 7.05e-04 -8.6 1.13e+01 - 9.43e-01 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -1.1063687e+01 4.85e-03 2.15e-04 -8.6 6.22e+00 - 1.00e+00 1.00e+00h 1\n", - " 31 -1.1063694e+01 4.30e-04 2.22e-05 -8.6 1.87e+00 - 1.00e+00 1.00e+00h 1\n", - " 32 -1.1063694e+01 2.31e-06 2.07e-07 -8.6 1.38e-01 - 1.00e+00 1.00e+00h 1\n", - " 33 -1.1063694e+01 1.00e-10 1.87e-11 -8.6 9.08e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 33\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.1063694185536061e+01 -1.1063694185536061e+01\n", - "Dual infeasibility......: 1.8708625160522883e-11 1.8708625160522883e-11\n", - "Constraint violation....: 1.0035383635198514e-10 1.0035383635198514e-10\n", - "Complementarity.........: 2.5059110801775927e-09 2.5059110801775927e-09\n", - "Overall NLP error.......: 2.5059110801775927e-09 2.5059110801775927e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 66\n", - "Number of objective gradient evaluations = 34\n", - "Number of equality constraint evaluations = 66\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 35\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 33\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.097\n", - "Total CPU secs in NLP function evaluations = 0.054\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.63e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 3.99e+00 3.85e+02 -1.0 1.87e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.58e-02 3.85e+00 -1.0 4.28e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.53e-04 4.39e+00 -1.0 4.88e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.83e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8337334962743626e-11 5.8337334962743626e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8337334962743626e-11 5.8337334962743626e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.135\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 2.1061408e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 2.1040894e+00 1.61e-01 1.07e+00 -1.0 5.95e-01 - 9.79e-01 8.71e-01h 1\n", - " 2 2.1049797e+00 3.48e-02 1.10e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 2.0931025e+00 1.25e+01 5.73e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 2.1188567e+00 7.15e-01 2.55e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 2.1126515e+00 5.85e-01 4.62e+01 -1.0 3.59e+02 - 4.61e-01 8.58e-02f 2\n", - " 6 2.1287303e+00 1.37e-01 5.55e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 2.1259503e+00 4.30e-01 2.96e-01 -1.0 5.46e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 2.1272270e+00 3.91e-02 5.74e-02 -1.7 1.69e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 2.1269980e+00 5.05e-03 3.05e-03 -2.5 6.14e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.1253079e+00 3.93e-03 1.72e-03 -3.8 3.02e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 2.1243236e+00 3.24e-05 7.52e-06 -3.8 8.12e-02 -4.5 1.00e+00 1.00e+00h 1\n", - " 12 2.1000010e+00 1.90e+00 1.12e-01 -5.7 6.66e+01 - 5.63e-01 1.00e+00h 1\n", - " 13 2.0975393e+00 2.59e-01 1.56e-02 -5.7 2.55e+01 - 7.81e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319517)\n", - " 14 2.0918091e+00 4.08e-01 3.59e-02 -5.7 2.58e+01 - 6.49e-01 9.22e-01h 1\n", - " 15 2.0912149e+00 4.07e-01 3.58e-02 -5.7 3.86e+03 - 3.37e-02 2.90e-03h 2\n", - " 16 2.0907195e+00 2.80e-02 2.35e-03 -5.7 1.32e+01 - 1.00e+00 1.00e+00h 1\n", - " 17 2.0905779e+00 7.03e-03 8.20e-04 -5.7 6.05e+00 - 1.00e+00 1.00e+00h 1\n", - " 18 2.0905748e+00 5.81e-05 1.08e-06 -5.7 6.63e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (342692)\n", - " 19 2.0905749e+00 3.67e-09 1.14e-10 -5.7 5.27e-03 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 2.0899322e+00 1.67e-02 7.05e-04 -8.6 1.13e+01 - 9.43e-01 1.00e+00h 1\n", - " 21 2.0899164e+00 4.85e-03 2.15e-04 -8.6 6.22e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (360246)\n", - " 22 2.0899101e+00 4.30e-04 2.22e-05 -8.6 1.87e+00 - 1.00e+00 1.00e+00h 1\n", - " 23 2.0899096e+00 2.31e-06 2.07e-07 -8.6 1.38e-01 - 1.00e+00 1.00e+00h 1\n", - " 24 2.0899096e+00 1.00e-10 1.87e-11 -8.6 9.08e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 24\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.0899096060902953e+00 2.0899096060902953e+00\n", - "Dual infeasibility......: 1.8708625206653092e-11 1.8708625206653092e-11\n", - "Constraint violation....: 1.0035450248579991e-10 1.0035450248579991e-10\n", - "Complementarity.........: 2.5059110801021708e-09 2.5059110801021708e-09\n", - "Overall NLP error.......: 2.5059110801021708e-09 2.5059110801021708e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 31\n", - "Number of objective gradient evaluations = 25\n", - "Number of equality constraint evaluations = 31\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 25\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 24\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.848\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.6 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.38e-03 2.54e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.16e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1583757003895698e-09 2.1583757003895698e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1583757003895698e-09 2.1583757003895698e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.2 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.38e-03 2.54e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.16e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1583757003895698e-09 2.1583757003895698e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1583757003895698e-09 2.1583757003895698e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 4.60e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.23e+02 3.85e+02 -1.0 4.60e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.16e+00 3.85e+00 -1.0 6.69e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.08e-02 4.39e+00 -1.0 7.64e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.55e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.122\n", - "Total CPU secs in NLP function evaluations = 0.009\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.1317732e+01 1.25e+00 1.07e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.1320290e+01 6.18e-01 5.16e+00 -1.0 4.65e+01 - 9.73e-01 5.05e-01h 1\n", - " 2 -1.1318564e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.1329088e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.1308507e+01 1.67e+01 2.23e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.1311584e+01 1.18e+01 3.19e+01 -1.0 1.36e+02 - 1.00e+00 4.14e-01f 2\n", - " 6 -1.1303505e+01 1.23e+01 3.32e+00 -1.0 9.19e+01 - 8.82e-01 3.38e-01f 2\n", - " 7 -1.1295920e+01 3.59e+00 5.30e-01 -1.0 5.20e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.1299210e+01 4.37e-01 7.59e-02 -1.0 1.08e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.1299229e+01 2.36e-04 1.85e-03 -1.7 3.04e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.1299413e+01 1.20e-03 1.91e-03 -3.8 7.92e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.1299812e+01 6.26e-04 3.20e-04 -3.8 1.40e+00 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.1322678e+01 1.98e+01 1.23e-01 -5.7 8.86e+01 - 5.46e-01 1.00e+00h 1\n", - " 13 -1.1325322e+01 1.20e+00 1.52e-02 -5.7 6.84e+01 - 7.61e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (323203)\n", - " 14 -1.1329152e+01 3.27e+00 1.89e-02 -5.7 3.81e+01 - 7.29e-01 1.00e+00h 1\n", - " 15 -1.1329720e+01 3.61e+00 1.87e-02 -5.7 8.73e+02 - 1.61e-01 1.97e-02h 2\n", - " 16 -1.1330564e+01 3.94e-01 2.15e-03 -5.7 2.39e+01 - 1.00e+00 1.00e+00h 1\n", - " 17 -1.1330828e+01 1.37e-01 1.02e-03 -5.7 1.22e+01 - 1.00e+00 1.00e+00h 1\n", - " 18 -1.1330818e+01 1.25e-04 4.23e-06 -5.7 5.25e-01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.1330818e+01 4.23e-09 1.18e-10 -5.7 2.97e-03 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.1330839e+01 4.74e-06 1.48e-06 -8.6 4.43e-02 -4.5 1.00e+00 1.00e+00h 1\n", - " 21 -1.1330851e+01 4.21e-05 2.23e-06 -8.6 1.69e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 22 -1.1330889e+01 3.75e-04 3.31e-06 -8.6 5.08e-01 -5.4 1.00e+00 1.00e+00h 1\n", - " 23 -1.1330999e+01 3.26e-03 2.88e-05 -8.6 1.52e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 24 -1.1331064e+01 3.74e-03 3.29e-05 -8.6 4.44e+00 -6.4 1.00e+00 2.10e-01h 1\n", - " 25 -1.1331228e+01 1.65e-02 2.12e-04 -8.6 4.71e+00 -6.9 1.00e+00 7.65e-01f 1\n", - " 26 -1.1331449e+01 1.71e-02 7.80e-04 -8.6 2.93e+01 - 1.00e+00 3.63e-01f 1\n", - " 27 -1.1331483e+01 1.98e-02 6.89e-04 -8.6 2.97e+01 - 1.00e+00 2.88e-01f 1\n", - " 28 -1.1331484e+01 1.83e-02 6.23e-04 -8.6 1.76e+01 - 1.00e+00 9.54e-02f 1\n", - " 29 -1.1331489e+01 7.02e-03 1.41e-04 -8.6 3.15e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (355308)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -1.1331481e+01 2.07e-06 4.96e-08 -8.6 1.21e-01 - 1.00e+00 1.00e+00h 1\n", - " 31 -1.1331481e+01 4.19e-11 6.10e-14 -8.6 5.87e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 31\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.1331480835989968e+01 -1.1331480835989968e+01\n", - "Dual infeasibility......: 6.1028774360629264e-14 6.1028774360629264e-14\n", - "Constraint violation....: 4.1914582915580922e-11 4.1914582915580922e-11\n", - "Complementarity.........: 2.5059039158044294e-09 2.5059039158044294e-09\n", - "Overall NLP error.......: 2.5059039158044294e-09 2.5059039158044294e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 41\n", - "Number of objective gradient evaluations = 32\n", - "Number of equality constraint evaluations = 41\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 32\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 31\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.143\n", - "Total CPU secs in NLP function evaluations = 0.040\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.97e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.02e+00 3.85e+02 -1.0 1.92e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.61e-02 3.85e+00 -1.0 4.31e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.56e-04 4.39e+00 -1.0 4.91e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.86e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8332005892225425e-11 5.8332005892225425e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8332005892225425e-11 5.8332005892225425e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 1.8358716e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 1.8341696e+00 1.60e-01 1.07e+00 -1.0 5.95e-01 - 9.79e-01 8.72e-01h 1\n", - " 2 1.8349973e+00 3.48e-02 1.11e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 1.8248024e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 1.8466954e+00 7.14e-01 2.53e+00 -1.0 2.66e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 1.8414860e+00 5.85e-01 4.65e+01 -1.0 3.56e+02 - 4.65e-01 8.65e-02f 2\n", - " 6 1.8551941e+00 1.36e-01 5.72e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", - " 7 1.8528188e+00 4.32e-01 2.96e-01 -1.0 5.47e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 1.8539217e+00 3.88e-02 5.74e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 1.8537565e+00 5.12e-03 3.24e-03 -2.5 6.19e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 1.8525196e+00 2.82e-03 1.42e-03 -3.8 2.54e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 1.8366692e+00 5.04e-01 3.65e-02 -3.8 3.44e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 1.8399503e+00 1.30e-02 1.92e-03 -3.8 6.01e+00 - 1.00e+00 1.00e+00h 1\n", - " 13 1.8398900e+00 1.11e-05 6.33e-07 -3.8 2.77e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (320183)\n", - " 14 1.8323517e+00 4.84e-01 2.54e-02 -5.7 3.88e+01 - 7.65e-01 1.00e+00h 1\n", - " 15 1.8270480e+00 3.24e-01 1.26e-02 -5.7 3.83e+01 - 8.75e-01 1.00e+00h 1\n", - " 16 1.8263301e+00 3.14e-01 1.52e-02 -5.7 5.98e+02 - 1.79e-01 2.87e-02h 2\n", - " 17 1.8227920e+00 2.59e-01 1.45e-02 -5.7 2.36e+01 - 1.00e+00 1.00e+00h 1\n", - " 18 1.8227886e+00 1.83e-02 5.07e-04 -5.7 1.16e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (338938)\n", - " 19 1.8227858e+00 8.79e-04 1.36e-05 -5.7 2.56e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 1.8227857e+00 9.53e-07 6.96e-09 -5.7 8.47e-02 - 1.00e+00 1.00e+00h 1\n", - " 21 1.8221441e+00 1.90e-02 6.81e-04 -8.6 1.20e+01 - 9.37e-01 1.00e+00h 1\n", - " 22 1.8221300e+00 5.89e-03 2.23e-04 -8.6 6.84e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (356229)\n", - " 23 1.8221235e+00 6.31e-04 2.70e-05 -8.6 2.27e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 1.8221230e+00 5.04e-06 3.54e-07 -8.6 2.03e-01 - 1.00e+00 1.00e+00h 1\n", - " 25 1.8221230e+00 3.93e-10 6.30e-11 -8.6 1.80e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 25\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.8221229556418135e+00 1.8221229556418135e+00\n", - "Dual infeasibility......: 6.2966011365859705e-11 6.2966011365859705e-11\n", - "Constraint violation....: 3.9269965057542322e-10 3.9269965057542322e-10\n", - "Complementarity.........: 2.5059288062561410e-09 2.5059288062561410e-09\n", - "Overall NLP error.......: 2.5059288062561410e-09 2.5059288062561410e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 26\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 26\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 25\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.855\n", - "Total CPU secs in NLP function evaluations = 0.037\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.37e-03 2.77e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.12e-09 1.47e-06 -1.0 1.73e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1213626411054065e-09 2.1213626411054065e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1213626411054065e-09 2.1213626411054065e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", - "Total CPU secs in NLP function evaluations = 0.001\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.37e-03 2.77e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.12e-09 1.47e-06 -1.0 1.73e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1213617529269868e-09 2.1213617529269868e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1213617529269868e-09 2.1213617529269868e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.007\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 0.9 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 5.36e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.30e+02 3.85e+02 -1.0 5.36e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.23e+00 3.85e+00 -1.0 6.77e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.15e-02 4.39e+00 -1.0 7.71e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.63e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.1551525e+01 1.25e+00 1.07e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.1553742e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.1552181e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.1561368e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.1543482e+01 1.67e+01 2.22e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.1546117e+01 1.18e+01 3.19e+01 -1.0 1.36e+02 - 1.00e+00 4.14e-01f 2\n", - " 6 -1.1539087e+01 1.23e+01 3.32e+00 -1.0 9.20e+01 - 8.80e-01 3.37e-01f 2\n", - " 7 -1.1532457e+01 3.60e+00 5.31e-01 -1.0 5.21e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.1535331e+01 4.40e-01 7.66e-02 -1.0 1.08e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.1535344e+01 2.36e-04 1.71e-03 -1.7 3.20e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.1535485e+01 9.17e-04 1.68e-03 -3.8 6.95e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.1550192e+01 1.09e+01 5.80e-02 -3.8 6.98e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 -1.1547006e+01 6.44e-01 3.84e-03 -3.8 1.74e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 -1.1547077e+01 6.58e-05 2.09e-06 -3.8 5.97e-01 - 1.00e+00 1.00e+00h 1\n", - " 14 -1.1553620e+01 2.12e+00 2.46e-02 -5.7 3.77e+01 - 7.69e-01 1.00e+00h 1\n", - " 15 -1.1558721e+01 2.04e+00 1.06e-02 -5.7 4.14e+01 - 9.03e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (322351)\n", - " 16 -1.1559371e+01 2.71e+00 1.30e-02 -5.7 6.60e+02 - 1.85e-01 3.02e-02h 2\n", - " 17 -1.1562122e+01 1.66e+00 1.35e-02 -5.7 6.81e+01 - 1.00e+00 7.45e-01H 1\n", - " 18 -1.1562895e+01 1.70e-01 1.76e-03 -5.7 1.75e+01 - 1.00e+00 1.00e+00f 1\n", - " 19 -1.1562787e+01 1.94e-03 2.65e-05 -5.7 3.56e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.1562787e+01 3.18e-06 1.64e-08 -5.7 1.32e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.1563428e+01 1.52e-01 7.00e-04 -8.6 1.27e+01 - 9.31e-01 9.99e-01h 1\n", - "Reallocating memory for MA57: lfact (365434)\n", - " 22 -1.1563441e+01 6.92e-03 2.29e-04 -8.6 7.40e+00 - 1.00e+00 1.00e+00h 1\n", - " 23 -1.1563447e+01 8.62e-04 3.14e-05 -8.6 2.65e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 -1.1563448e+01 9.50e-06 5.44e-07 -8.6 2.79e-01 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.1563448e+01 1.19e-09 1.68e-10 -8.6 3.13e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 25\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.1563448115914573e+01 -1.1563448115914573e+01\n", - "Dual infeasibility......: 1.6756190666721757e-10 1.6756190666721757e-10\n", - "Constraint violation....: 1.1895755491764248e-09 1.1895755491764248e-09\n", - "Complementarity.........: 2.5059705354210223e-09 2.5059705354210223e-09\n", - "Overall NLP error.......: 2.5059705354210223e-09 2.5059705354210223e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 36\n", - "Number of objective gradient evaluations = 26\n", - "Number of equality constraint evaluations = 36\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 26\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 25\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.877\n", - "Total CPU secs in NLP function evaluations = 0.040\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.31e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.05e+00 3.85e+02 -1.0 2.26e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.64e-02 3.85e+00 -1.0 4.34e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.59e-04 4.39e+00 -1.0 4.95e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.89e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8339111319583026e-11 5.8339111319583026e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8339111319583026e-11 5.8339111319583026e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 1.6020788e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 1.6006263e+00 1.59e-01 1.06e+00 -1.0 5.95e-01 - 9.79e-01 8.73e-01h 1\n", - " 2 1.6013928e+00 3.48e-02 1.11e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 1.5924626e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 1.6115012e+00 7.14e-01 2.52e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 1.6070137e+00 5.85e-01 4.67e+01 -1.0 3.54e+02 - 4.67e-01 8.70e-02f 2\n", - " 6 1.6189485e+00 1.36e-01 5.81e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", - " 7 1.6168842e+00 4.32e-01 2.97e-01 -1.0 5.47e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 1.6178560e+00 3.87e-02 5.74e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 1.6177317e+00 5.19e-03 3.40e-03 -2.5 6.23e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 1.6167878e+00 2.10e-03 1.20e-03 -3.8 2.17e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 1.6042274e+00 4.07e-01 2.56e-02 -3.8 3.07e+01 - 1.00e+00 1.00e+00h 1\n", - " 12 1.6065666e+00 8.43e-03 1.13e-03 -3.8 4.88e+00 - 1.00e+00 1.00e+00h 1\n", - " 13 1.6065263e+00 4.74e-06 3.38e-07 -3.8 1.65e-01 - 1.00e+00 1.00e+00h 1\n", - " 14 1.6002214e+00 9.01e-01 7.69e-02 -5.7 9.37e+03 - 1.90e-02 7.73e-03f 1\n", - "Reallocating memory for MA57: lfact (349533)\n", - " 15 1.5979843e+00 1.46e-01 1.53e-02 -5.7 3.06e+01 - 8.53e-01 1.00e+00h 1\n", - " 16 1.5934679e+00 3.30e-01 2.00e-02 -5.7 4.37e+01 - 8.47e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (378883)\n", - " 17 1.5941729e+00 2.50e-03 1.57e-04 -5.7 3.14e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 18 1.5941556e+00 1.90e-06 8.52e-07 -5.7 7.65e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 19 1.5941055e+00 2.45e-05 6.85e-06 -8.6 1.93e-01 -5.4 9.98e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 1.5940068e+00 2.13e-04 1.22e-05 -8.6 5.73e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 21 1.5937364e+00 1.77e-03 1.01e-04 -8.6 1.67e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 22 1.5931017e+00 1.24e-02 7.08e-04 -8.6 4.73e+00 -6.9 1.00e+00 9.59e-01h 1\n", - " 23 1.5922166e+00 4.10e-02 2.42e-03 -8.6 1.30e+01 -7.3 1.00e+00 6.17e-01f 1\n", - " 24 1.5911477e+00 1.11e-01 1.25e-02 -8.6 1.93e+01 -7.8 1.00e+00 1.00e+00f 1\n", - " 25 1.5905350e+00 3.48e-02 2.72e-03 -8.6 9.72e+00 -7.4 1.00e+00 1.00e+00h 1\n", - " 26 1.5903800e+00 3.48e-02 2.76e-03 -8.6 4.21e+01 -7.9 1.00e+00 7.61e-02h 1\n", - " 27 1.5901978e+00 7.47e-02 1.56e-03 -8.6 5.28e+01 - 1.00e+00 4.36e-01f 1\n", - " 28 1.5901521e+00 1.15e-01 6.10e-04 -8.6 4.20e+01 - 1.00e+00 6.10e-01f 1\n", - " 29 1.5901546e+00 9.61e-03 5.06e-05 -8.6 8.82e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (415680)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 1.5901559e+00 6.03e-03 5.58e-06 -8.6 6.93e+00 - 1.00e+00 1.00e+00h 1\n", - " 31 1.5901557e+00 3.61e-04 2.83e-07 -8.6 1.72e+00 - 1.00e+00 1.00e+00h 1\n", - " 32 1.5901557e+00 1.01e-06 7.50e-10 -8.6 9.08e-02 - 1.00e+00 1.00e+00h 1\n", - " 33 1.5901557e+00 6.89e-12 4.35e-14 -8.6 2.38e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 33\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.5901556757175646e+00 1.5901556757175646e+00\n", - "Dual infeasibility......: 4.3539707029773698e-14 4.3539707029773698e-14\n", - "Constraint violation....: 6.8930416929902094e-12 6.8930416929902094e-12\n", - "Complementarity.........: 2.5059036071950574e-09 2.5059036071950574e-09\n", - "Overall NLP error.......: 2.5059036071950574e-09 2.5059036071950574e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 38\n", - "Number of objective gradient evaluations = 34\n", - "Number of equality constraint evaluations = 38\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 34\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 33\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.558\n", - "Total CPU secs in NLP function evaluations = 0.050\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.2 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.36e-03 3.00e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.08e-09 1.46e-06 -1.0 1.72e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.0846711024091746e-09 2.0846711024091746e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.0846711024091746e-09 2.0846711024091746e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.36e-03 3.00e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.08e-09 1.46e-06 -1.0 1.72e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.0846711024091746e-09 2.0846711024091746e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.0846711024091746e-09 2.0846711024091746e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.115\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.13e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.38e+02 3.85e+02 -1.0 6.13e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.31e+00 3.85e+00 -1.0 6.85e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.23e-02 4.39e+00 -1.0 7.79e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.70e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.1757533e+01 1.25e+00 1.06e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.1759489e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.1758067e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.1766218e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.1750403e+01 1.67e+01 2.21e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.1752706e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", - " 6 -1.1746485e+01 1.23e+01 3.32e+00 -1.0 9.21e+01 - 8.79e-01 3.37e-01f 2\n", - " 7 -1.1740596e+01 3.61e+00 5.32e-01 -1.0 5.22e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.1743147e+01 4.42e-01 7.72e-02 -1.0 1.09e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.1743157e+01 2.36e-04 1.60e-03 -1.7 3.33e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.1743267e+01 7.25e-04 1.49e-03 -3.8 6.20e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.1755095e+01 8.91e+00 4.24e-02 -5.7 6.38e+01 - 6.52e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (321581)\n", - " 12 -1.1761884e+01 2.85e+00 1.21e-02 -5.7 5.80e+01 - 8.37e-01 1.00e+00h 1\n", - " 13 -1.1766537e+01 6.45e+00 3.35e-02 -5.7 4.38e+01 - 7.40e-01 1.00e+00h 1\n", - " 14 -1.1766408e+01 5.42e+00 4.34e-02 -5.7 1.45e+01 -4.0 9.76e-01 1.60e-01h 1\n", - " 15 -1.1766359e+01 4.32e-01 3.46e-02 -5.7 2.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 -1.1766255e+01 4.65e-04 1.06e-04 -5.7 2.81e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 17 -1.1766639e+01 3.37e-01 3.56e-03 -5.7 2.92e+02 - 4.58e-01 5.22e-02h 2\n", - " 18 -1.1767572e+01 9.44e-02 2.21e-03 -5.7 1.59e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.1767397e+01 5.01e-03 9.03e-05 -5.7 3.57e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.1767399e+01 1.54e-05 1.56e-06 -5.7 2.76e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.1768035e+01 1.89e-01 7.56e-04 -8.6 1.38e+01 - 9.26e-01 9.95e-01h 1\n", - "Reallocating memory for MA57: lfact (343029)\n", - " 22 -1.1768050e+01 8.01e-03 2.35e-04 -8.6 7.95e+00 - 1.00e+00 1.00e+00h 1\n", - " 23 -1.1768057e+01 1.12e-03 3.57e-05 -8.6 3.02e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (360465)\n", - " 24 -1.1768058e+01 1.63e-05 7.80e-07 -8.6 3.65e-01 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.1768058e+01 3.05e-09 3.84e-10 -8.6 5.01e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 25\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.1768057697799625e+01 -1.1768057697799625e+01\n", - "Dual infeasibility......: 3.8359587305625804e-10 3.8359587305625804e-10\n", - "Constraint violation....: 3.0509063053685281e-09 3.0509063053685281e-09\n", - "Complementarity.........: 2.5060563776015687e-09 2.5060563776015687e-09\n", - "Overall NLP error.......: 3.0509063053685281e-09 3.0509063053685281e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 35\n", - "Number of objective gradient evaluations = 26\n", - "Number of equality constraint evaluations = 35\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 26\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 25\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.901\n", - "Total CPU secs in NLP function evaluations = 0.037\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.65e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.08e+00 3.85e+02 -1.0 2.60e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.67e-02 3.85e+00 -1.0 4.37e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.62e-04 4.39e+00 -1.0 4.98e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.92e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.133\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 1.3960708e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 1.3948050e+00 1.58e-01 1.05e+00 -1.0 5.95e-01 - 9.79e-01 8.73e-01h 1\n", - " 2 1.3955154e+00 3.48e-02 1.12e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 1.3875708e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 1.4044133e+00 7.13e-01 2.51e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 1.4004729e+00 5.85e-01 4.68e+01 -1.0 3.52e+02 - 4.69e-01 8.75e-02f 2\n", - " 6 1.4110288e+00 1.36e-01 5.85e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", - " 7 1.4092120e+00 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 1.4100813e+00 3.86e-02 5.75e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 1.4099850e+00 5.24e-03 3.52e-03 -2.5 6.26e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 1.4092414e+00 1.61e-03 1.03e-03 -3.8 1.89e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 1.4087035e+00 1.89e-05 1.98e-06 -3.8 5.64e-02 -4.5 1.00e+00 1.00e+00h 1\n", - " 12 1.3969745e+00 9.17e-01 3.82e-02 -5.7 4.48e+01 - 6.43e-01 1.00e+00h 1\n", - " 13 1.3917215e+00 4.19e-01 9.20e-03 -5.7 3.84e+01 - 8.02e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (324236)\n", - " 14 1.3869756e+00 5.56e-01 3.16e-02 -5.7 2.67e+01 - 7.65e-01 1.00e+00h 1\n", - " 15 1.3879570e+00 9.86e-03 5.26e-04 -5.7 5.35e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 1.3879136e+00 3.18e-06 4.27e-07 -5.7 6.95e-02 -5.4 1.00e+00 1.00e+00h 1\n", - " 17 1.3878380e+00 9.80e-05 2.86e-05 -8.6 3.89e-01 -5.9 9.93e-01 1.00e+00h 1\n", - " 18 1.3876686e+00 9.18e-04 5.19e-05 -8.6 1.23e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 19 1.3875598e+00 9.24e-04 5.14e-05 -8.6 1.98e+00 -6.9 1.00e+00 3.25e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 1.3870548e+00 1.12e-02 6.48e-04 -8.6 4.76e+00 -7.3 1.00e+00 1.00e+00f 1\n", - " 21 1.3861210e+00 1.22e-01 1.05e-02 -8.6 2.04e+01 -7.8 1.00e+00 1.00e+00h 1\n", - " 22 1.3856832e+00 2.64e-02 2.12e-03 -8.6 9.07e+00 -7.4 1.00e+00 9.62e-01h 1\n", - " 23 1.3856413e+00 2.12e-02 1.73e-03 -8.6 3.86e+01 - 1.00e+00 2.02e-01f 1\n", - "Reallocating memory for MA57: lfact (344436)\n", - " 24 1.3856015e+00 1.68e-02 1.37e-03 -8.6 4.03e+01 - 1.00e+00 2.09e-01f 1\n", - " 25 1.3855581e+00 5.06e-02 6.97e-04 -8.6 3.68e+01 - 1.00e+00 4.94e-01f 1\n", - " 26 1.3855412e+00 1.19e-03 6.42e-05 -8.6 3.12e+00 - 1.00e+00 1.00e+00h 1\n", - " 27 1.3855461e+00 9.23e-04 7.59e-07 -8.6 2.74e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (362997)\n", - " 28 1.3855461e+00 9.77e-06 6.77e-09 -8.6 2.83e-01 - 1.00e+00 1.00e+00h 1\n", - " 29 1.3855461e+00 7.29e-10 5.06e-13 -8.6 2.45e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.3855460938286592e+00 1.3855460938286592e+00\n", - "Dual infeasibility......: 5.0636527904345562e-13 5.0636527904345562e-13\n", - "Constraint violation....: 7.2855699251306305e-10 7.2855699251306305e-10\n", - "Complementarity.........: 2.5059081084119374e-09 2.5059081084119374e-09\n", - "Overall NLP error.......: 2.5059081084119374e-09 2.5059081084119374e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 30\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 30\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.307\n", - "Total CPU secs in NLP function evaluations = 0.036\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.35e-03 3.23e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.05e-09 1.46e-06 -1.0 1.70e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.0483019724792939e-09 2.0483019724792939e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.0483019724792939e-09 2.0483019724792939e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.35e-03 3.23e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.05e-09 1.46e-06 -1.0 1.70e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.0483028606577136e-09 2.0483028606577136e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.0483028606577136e-09 2.0483028606577136e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.89e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.46e+02 3.85e+02 -1.0 6.89e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.39e+00 3.85e+00 -1.0 6.92e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.30e-02 4.39e+00 -1.0 7.87e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.78e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0394678409211338e-09 9.0394678409211338e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0394678409211338e-09 9.0394678409211338e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.126\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.1941668e+01 1.25e+00 1.06e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.1943417e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.1942113e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.1949438e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.1935265e+01 1.67e+01 2.21e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.1937309e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", - " 6 -1.1931730e+01 1.23e+01 3.32e+00 -1.0 9.21e+01 - 8.78e-01 3.37e-01f 2\n", - " 7 -1.1926433e+01 3.62e+00 5.33e-01 -1.0 5.22e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.1928727e+01 4.44e-01 7.77e-02 -1.0 1.09e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.1928733e+01 2.37e-04 1.51e-03 -1.7 3.43e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.1928823e+01 5.88e-04 1.35e-03 -3.8 5.59e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.1929034e+01 3.59e-04 1.83e-04 -5.7 1.06e+00 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.1929754e+01 4.19e-03 1.21e-04 -5.7 3.63e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 -1.1930039e+01 3.14e-03 1.97e-03 -5.7 3.45e+00 -5.0 1.00e+00 4.14e-01h 1\n", - " 14 -1.1930215e+01 3.02e-03 9.79e-04 -5.7 8.14e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 15 -1.1930791e+01 2.61e-02 4.88e-05 -5.7 2.66e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 16 -1.1939335e+01 1.10e+01 4.69e-02 -5.7 8.17e+03 - 1.91e-02 9.26e-03h 1\n", - " 17 -1.1943119e+01 1.42e+01 5.92e-02 -5.7 4.18e+02 - 4.56e-01 7.84e-02h 1\n", - " 18 -1.1956668e+01 1.38e+01 5.53e-02 -5.7 1.09e+02 - 1.00e+00 8.15e-01h 1\n", - " 19 -1.1949881e+01 3.43e+00 1.16e-02 -5.7 5.57e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (321695)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.1950414e+01 8.23e-03 6.43e-04 -5.7 6.89e+00 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.1950429e+01 3.89e-04 2.65e-05 -5.7 1.74e+00 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.1950430e+01 6.41e-07 3.85e-08 -5.7 7.08e-02 - 1.00e+00 1.00e+00h 1\n", - " 23 -1.1951063e+01 2.31e-01 8.26e-04 -8.6 1.51e+01 - 9.21e-01 9.90e-01h 1\n", - "Reallocating memory for MA57: lfact (348619)\n", - " 24 -1.1951080e+01 9.09e-03 2.41e-04 -8.6 8.45e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.1951086e+01 1.41e-03 3.96e-05 -8.6 3.38e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.1951087e+01 2.57e-05 1.05e-06 -8.6 4.59e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (367172)\n", - " 27 -1.1951087e+01 7.10e-09 7.68e-10 -8.6 7.64e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.1951087152217010e+01 -1.1951087152217010e+01\n", - "Dual infeasibility......: 7.6785714050494160e-10 7.6785714050494160e-10\n", - "Constraint violation....: 7.1010632929358053e-09 7.1010632929358053e-09\n", - "Complementarity.........: 2.5062084307979245e-09 2.5062084307979245e-09\n", - "Overall NLP error.......: 7.1010632929358053e-09 7.1010632929358053e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 28\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 28\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.951\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 2.99e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.11e+00 3.85e+02 -1.0 2.94e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.71e-02 3.85e+00 -1.0 4.41e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.65e-04 4.39e+00 -1.0 5.01e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.95e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.135\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 1.2119360e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 1.2108149e+00 1.58e-01 1.05e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", - " 2 1.2114751e+00 3.48e-02 1.12e+01 -1.0 6.04e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 1.2043202e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 1.2194210e+00 7.13e-01 2.50e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 1.2159091e+00 5.85e-01 4.69e+01 -1.0 3.51e+02 - 4.71e-01 8.78e-02f 2\n", - " 6 1.2253787e+00 1.36e-01 5.90e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", - " 7 1.2237509e+00 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 1.2245368e+00 3.86e-02 5.75e-02 -1.7 1.68e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 1.2244603e+00 5.28e-03 3.61e-03 -2.5 6.28e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 1.2238595e+00 1.27e-03 8.99e-04 -3.8 1.66e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 1.2147814e+00 6.50e-01 3.09e-02 -5.7 3.86e+01 - 6.91e-01 1.00e+00h 1\n", - " 12 1.2082820e+00 6.40e-01 9.84e-03 -5.7 4.61e+01 - 8.50e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319971)\n", - " 13 1.2037280e+00 6.91e-01 3.73e-02 -5.7 2.97e+01 - 7.52e-01 9.98e-01h 1\n", - " 14 1.2048711e+00 1.91e-02 1.61e-03 -5.7 3.27e+00 -4.5 9.31e-01 1.00e+00h 1\n", - " 15 1.2048031e+00 2.24e-06 5.66e-07 -5.7 2.40e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 1.2047671e+00 1.36e-05 6.26e-06 -8.6 1.52e-01 -5.4 9.99e-01 1.00e+00h 1\n", - " 17 1.2047082e+00 1.26e-04 6.76e-06 -8.6 4.70e-01 -5.9 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (336051)\n", - " 18 1.2045445e+00 1.05e-03 5.65e-05 -8.6 1.37e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 19 1.2044052e+00 1.58e-03 8.51e-05 -8.6 3.73e+00 -6.9 1.00e+00 3.42e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 1.2039397e+00 9.51e-03 5.22e-04 -8.6 4.63e+00 -7.3 1.00e+00 1.00e+00f 1\n", - " 21 1.2031551e+00 8.32e-02 6.07e-03 -8.6 1.92e+01 -7.8 1.00e+00 8.71e-01h 1\n", - " 22 1.2028414e+00 1.08e-01 7.48e-03 -8.6 1.19e+03 -8.3 7.23e-02 8.23e-03h 1\n", - " 23 1.2025270e+00 5.89e-02 4.04e-03 -8.6 3.92e+01 - 1.00e+00 4.53e-01f 1\n", - " 24 1.2025096e+00 4.44e-02 3.04e-03 -8.6 3.68e+01 - 5.41e-01 2.48e-01f 1\n", - " 25 1.2025058e+00 4.33e-02 2.05e-03 -8.6 3.17e+01 - 1.00e+00 3.26e-01f 1\n", - " 26 1.2025106e+00 1.21e-03 1.32e-04 -8.6 2.37e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (356718)\n", - " 27 1.2025167e+00 5.23e-04 3.85e-07 -8.6 2.06e+00 - 1.00e+00 1.00e+00h 1\n", - " 28 1.2025166e+00 3.31e-06 2.06e-09 -8.6 1.65e-01 - 1.00e+00 1.00e+00h 1\n", - " 29 1.2025166e+00 8.35e-11 7.43e-14 -8.6 8.28e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.2025166394012419e+00 1.2025166394012419e+00\n", - "Dual infeasibility......: 7.4296667615744834e-14 7.4296667615744834e-14\n", - "Constraint violation....: 8.3521300986433289e-11 8.3521300986433289e-11\n", - "Complementarity.........: 2.5059040285569865e-09 2.5059040285569865e-09\n", - "Overall NLP error.......: 2.5059040285569865e-09 2.5059040285569865e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 30\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 30\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.243\n", - "Total CPU secs in NLP function evaluations = 0.037\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.33e-03 3.46e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.01e-09 1.45e-06 -1.0 1.69e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.0122556954049742e-09 2.0122556954049742e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.0122556954049742e-09 2.0122556954049742e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.2 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.33e-03 3.46e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.01e-09 1.45e-06 -1.0 1.69e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.0122561394941840e-09 2.0122561394941840e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.0122561394941840e-09 2.0122561394941840e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 0.9 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 7.66e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.53e+02 3.85e+02 -1.0 7.66e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.46e+00 3.85e+00 -1.0 7.00e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.38e-02 4.39e+00 -1.0 7.94e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.85e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2108134e+01 1.25e+00 1.06e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2109716e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2108512e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2115163e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2102323e+01 1.67e+01 2.21e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2104160e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", - " 6 -1.2099103e+01 1.23e+01 3.32e+00 -1.0 9.22e+01 - 8.77e-01 3.36e-01f 2\n", - " 7 -1.2094289e+01 3.63e+00 5.34e-01 -1.0 5.23e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2096373e+01 4.45e-01 7.81e-02 -1.0 1.09e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2096378e+01 2.38e-04 1.44e-03 -1.7 3.51e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2096452e+01 4.87e-04 1.23e-03 -3.8 5.09e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2104600e+01 6.30e+00 3.11e-02 -5.7 5.44e+01 - 6.88e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319533)\n", - " 12 -1.2111071e+01 3.68e+00 1.30e-02 -5.7 6.59e+01 - 8.37e-01 1.00e+00h 1\n", - " 13 -1.2115222e+01 6.14e+00 2.84e-02 -5.7 3.51e+01 - 8.03e-01 1.00e+00h 1\n", - " 14 -1.2115127e+01 5.38e+00 4.94e-02 -5.7 1.50e+01 -4.0 1.00e+00 1.24e-01h 1\n", - " 15 -1.2114999e+01 4.47e-01 2.64e-02 -5.7 2.58e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 -1.2114900e+01 4.96e-04 8.86e-05 -5.7 3.02e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 17 -1.2115229e+01 5.02e-01 4.88e-03 -5.7 6.65e+02 - 1.86e-01 2.67e-02h 2\n", - " 18 -1.2116201e+01 2.32e-01 2.86e-03 -5.7 1.63e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.2115996e+01 6.36e-03 8.56e-05 -5.7 2.06e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (337748)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2116001e+01 1.11e-05 1.53e-06 -5.7 2.94e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.2116631e+01 2.76e-01 8.95e-04 -8.6 1.65e+01 - 9.16e-01 9.85e-01h 1\n", - " 22 -1.2116650e+01 1.02e-02 2.45e-04 -8.6 8.93e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (355121)\n", - " 23 -1.2116656e+01 1.72e-03 4.32e-05 -8.6 3.73e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 -1.2116657e+01 3.81e-05 1.36e-06 -8.6 5.59e-01 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.2116657e+01 1.56e-08 1.40e-09 -8.6 1.13e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (375561)\n", - " 26 -1.2116658e+01 6.53e-07 1.86e-08 -9.0 7.32e-02 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.2116658e+01 1.00e-11 4.32e-13 -9.0 2.87e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2116658032211422e+01 -1.2116658032211422e+01\n", - "Dual infeasibility......: 4.3248756227463823e-13 4.3248756227463823e-13\n", - "Constraint violation....: 9.9974473144470721e-12 9.9974473144470721e-12\n", - "Complementarity.........: 9.0909106880328588e-10 9.0909106880328588e-10\n", - "Overall NLP error.......: 9.0909106880328588e-10 9.0909106880328588e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 37\n", - "Number of objective gradient evaluations = 28\n", - "Number of equality constraint evaluations = 37\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 28\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.055\n", - "Total CPU secs in NLP function evaluations = 0.036\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.33e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.15e+00 3.85e+02 -1.0 3.28e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.74e-02 3.85e+00 -1.0 4.44e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.69e-04 4.39e+00 -1.0 5.04e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 4.98e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8339111319583026e-11 5.8339111319583026e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8339111319583026e-11 5.8339111319583026e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 1.0454702e+00 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 1.0444646e+00 1.58e-01 1.05e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", - " 2 1.0450802e+00 3.48e-02 1.12e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 1.0385721e+00 1.25e+01 5.74e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 1.0522576e+00 7.13e-01 2.50e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 1.0490906e+00 5.85e-01 4.70e+01 -1.0 3.50e+02 - 4.73e-01 8.81e-02f 2\n", - " 6 1.0576821e+00 1.36e-01 5.97e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", - " 7 1.0562026e+00 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 1.0569195e+00 3.85e-02 5.75e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 1.0568573e+00 5.31e-03 3.69e-03 -2.5 6.30e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 1.0563619e+00 1.01e-03 7.93e-04 -3.8 1.47e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 1.0487134e+00 5.52e-01 2.96e-02 -5.7 3.53e+01 - 7.06e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319271)\n", - " 12 1.0424427e+00 7.03e-01 1.05e-02 -5.7 4.80e+01 - 8.51e-01 1.00e+00h 1\n", - " 13 1.0381157e+00 7.10e-01 3.48e-02 -5.7 3.01e+01 - 7.81e-01 1.00e+00h 1\n", - " 14 1.0390532e+00 1.28e-02 1.27e-03 -5.7 6.87e-01 -4.5 9.40e-01 1.00e+00h 1\n", - " 15 1.0390112e+00 4.50e-06 9.50e-07 -5.7 8.32e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 1.0389810e+00 7.21e-06 4.11e-06 -8.6 1.03e-01 -5.4 9.99e-01 1.00e+00h 1\n", - " 17 1.0389364e+00 8.39e-05 3.92e-06 -8.6 3.70e-01 -5.9 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (335399)\n", - " 18 1.0388452e+00 3.85e-04 1.79e-05 -8.6 1.04e+00 -6.4 1.00e+00 7.44e-01h 1\n", - " 19 1.0386655e+00 1.98e-03 6.30e-05 -8.6 1.81e+00 -6.9 1.00e+00 1.00e+00f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 1.0382979e+00 7.70e-03 3.44e-04 -8.6 3.97e+00 -7.3 1.00e+00 1.00e+00h 1\n", - " 21 1.0375873e+00 7.24e-02 5.06e-03 -8.6 1.56e+01 -7.8 1.00e+00 1.00e+00h 1\n", - " 22 1.0372258e+00 1.16e-01 7.43e-03 -8.6 5.45e+02 -8.3 1.62e-01 2.38e-02h 1\n", - " 23 1.0369759e+00 6.56e-02 4.17e-03 -8.6 3.95e+01 - 1.00e+00 4.33e-01f 1\n", - " 24 1.0369555e+00 5.05e-02 3.21e-03 -8.6 3.72e+01 - 1.00e+00 2.30e-01f 1\n", - " 25 1.0369460e+00 4.41e-02 2.04e-03 -8.6 3.24e+01 - 1.00e+00 3.64e-01f 1\n", - " 26 1.0369409e+00 1.26e-03 1.02e-04 -8.6 2.22e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (358185)\n", - " 27 1.0369464e+00 3.96e-04 2.65e-07 -8.6 1.80e+00 - 1.00e+00 1.00e+00h 1\n", - " 28 1.0369464e+00 1.87e-06 1.06e-09 -8.6 1.24e-01 - 1.00e+00 1.00e+00h 1\n", - " 29 1.0369464e+00 2.65e-11 3.91e-14 -8.6 4.66e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.0369464064985126e+00 1.0369464064985126e+00\n", - "Dual infeasibility......: 3.9074655964464579e-14 3.9074655964464579e-14\n", - "Constraint violation....: 2.6508573114369938e-11 2.6508573114369938e-11\n", - "Complementarity.........: 2.5059036949607426e-09 2.5059036949607426e-09\n", - "Overall NLP error.......: 2.5059036949607426e-09 2.5059036949607426e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 30\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 30\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.435\n", - "Total CPU secs in NLP function evaluations = 0.045\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.89e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.41e-03 2.08e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.23e-09 1.50e-06 -1.0 1.78e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2337816041329006e-09 2.2337816041329006e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2337816041329006e-09 2.2337816041329006e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.104\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.32e-03 3.69e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.98e-09 1.44e-06 -1.0 1.67e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.9765331593646351e-09 1.9765331593646351e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.9765331593646351e-09 1.9765331593646351e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.2 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 8.43e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.61e+02 3.85e+02 -1.0 8.43e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.54e+00 3.85e+00 -1.0 7.08e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.46e-02 4.39e+00 -1.0 8.02e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 7.93e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2260028e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2261473e+01 6.18e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2260355e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2266446e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2254710e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2256378e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", - " 6 -1.2251753e+01 1.23e+01 3.32e+00 -1.0 9.22e+01 - 8.77e-01 3.36e-01f 2\n", - " 7 -1.2247342e+01 3.64e+00 5.35e-01 -1.0 5.23e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2249251e+01 4.47e-01 7.84e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2249255e+01 2.39e-04 1.38e-03 -1.7 3.57e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2249317e+01 4.10e-04 1.13e-03 -3.8 4.68e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2249467e+01 2.64e-04 1.34e-04 -5.7 9.10e-01 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.2250000e+01 3.31e-03 1.08e-04 -5.7 3.23e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 -1.2250322e+01 3.13e-03 1.32e-03 -5.7 4.61e+00 -5.0 1.00e+00 4.23e-01h 1\n", - " 14 -1.2250433e+01 2.06e-03 7.85e-04 -5.7 6.18e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 15 -1.2261629e+01 2.19e+01 8.47e-02 -5.7 6.04e+03 - 2.88e-02 2.27e-02h 1\n", - " 16 -1.2265527e+01 2.15e+01 6.31e-02 -5.7 1.28e+02 - 1.00e+00 2.59e-01f 1\n", - " 17 -1.2268702e+01 9.75e-01 1.54e-02 -5.7 2.61e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (320847)\n", - " 18 -1.2267146e+01 3.13e-01 1.00e-03 -5.7 1.77e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.2267156e+01 4.84e-04 4.02e-06 -5.7 5.89e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (338500)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2267156e+01 3.56e-08 2.75e-09 -5.7 1.30e-02 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.2267782e+01 3.24e-01 9.64e-04 -8.6 1.78e+01 - 9.11e-01 9.81e-01h 1\n", - " 22 -1.2267804e+01 1.12e-02 2.49e-04 -8.6 9.37e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (357003)\n", - " 23 -1.2267811e+01 2.04e-03 4.64e-05 -8.6 4.06e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 -1.2267812e+01 5.38e-05 1.69e-06 -8.6 6.64e-01 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.2267812e+01 3.11e-08 2.34e-09 -8.6 1.60e-02 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.2267812e+01 4.55e-13 3.29e-14 -8.6 2.09e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 26\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2267811714197844e+01 -1.2267811714197844e+01\n", - "Dual infeasibility......: 3.2899955311301634e-14 3.2899955311301634e-14\n", - "Constraint violation....: 1.2096124245683242e-13 4.5474735088646412e-13\n", - "Complementarity.........: 2.5059035616651650e-09 2.5059035616651650e-09\n", - "Overall NLP error.......: 2.5059035616651650e-09 2.5059035616651650e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 27\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 27\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.945\n", - "Total CPU secs in NLP function evaluations = 0.030\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 3.67e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.18e+00 3.85e+02 -1.0 3.62e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.77e-02 3.85e+00 -1.0 4.47e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.72e-04 4.39e+00 -1.0 5.07e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.02e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.132\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 8.9357618e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 8.9266467e-01 1.57e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", - " 2 8.9324077e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 8.8727234e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 8.9978503e-01 7.13e-01 2.49e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 8.9690135e-01 5.85e-01 4.71e+01 -1.0 3.49e+02 - 4.74e-01 8.83e-02f 2\n", - " 6 9.0474858e-01 1.37e-01 5.96e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 9.0340741e-01 4.33e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 9.0406676e-01 3.85e-02 5.76e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 9.0401537e-01 5.34e-03 3.76e-03 -2.5 6.32e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 9.0360000e-01 8.24e-04 7.04e-04 -3.8 1.31e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 8.9706762e-01 4.73e-01 2.82e-02 -5.7 3.26e+01 - 7.21e-01 1.00e+00h 1\n", - " 12 8.9104362e-01 7.55e-01 1.10e-02 -5.7 4.96e+01 - 8.53e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (326956)\n", - " 13 8.8691901e-01 7.24e-01 3.26e-02 -5.7 3.05e+01 - 8.07e-01 1.00e+00h 1\n", - " 14 8.8783634e-01 1.23e-02 9.48e-04 -5.7 7.02e-01 -4.5 9.51e-01 1.00e+00h 1\n", - " 15 8.8779529e-01 1.18e-06 3.71e-07 -5.7 3.26e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 8.8776642e-01 7.96e-06 3.75e-06 -8.6 1.12e-01 -5.4 9.99e-01 1.00e+00h 1\n", - " 17 8.8772695e-01 7.85e-05 3.35e-06 -8.6 3.61e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 18 8.8761634e-01 6.66e-04 2.84e-05 -8.6 1.06e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 19 8.8755498e-01 7.42e-04 3.16e-05 -8.6 2.76e+00 -6.9 1.00e+00 2.24e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 8.8717865e-01 9.48e-03 3.05e-04 -8.6 4.13e+00 -7.3 1.00e+00 1.00e+00f 1\n", - " 21 8.8657032e-01 4.66e-02 2.97e-03 -8.6 1.24e+01 -7.8 1.00e+00 9.75e-01h 1\n", - " 22 8.8612174e-01 1.44e-01 8.55e-03 -8.6 3.02e+02 -8.3 3.51e-01 6.41e-02h 1\n", - " 23 8.8583006e-01 7.53e-02 4.42e-03 -8.6 4.03e+01 - 1.00e+00 4.78e-01f 1\n", - " 24 8.8580769e-01 5.71e-02 3.34e-03 -8.6 3.65e+01 - 1.00e+00 2.44e-01f 1\n", - " 25 8.8579801e-01 4.72e-02 2.21e-03 -8.6 3.13e+01 - 1.00e+00 3.38e-01f 1\n", - "Reallocating memory for MA57: lfact (344590)\n", - " 26 8.8578794e-01 1.54e-03 9.57e-05 -8.6 2.23e+00 - 1.00e+00 1.00e+00h 1\n", - " 27 8.8579268e-01 3.27e-04 1.98e-07 -8.6 1.63e+00 - 1.00e+00 1.00e+00h 1\n", - " 28 8.8579267e-01 1.28e-06 6.66e-10 -8.6 1.03e-01 - 1.00e+00 1.00e+00h 1\n", - " 29 8.8579267e-01 4.37e-12 1.51e-10 -8.6 1.89e-04 -7.0 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 8.8579267060918165e-01 8.8579267060918165e-01\n", - "Dual infeasibility......: 1.5144484733052913e-10 1.5144484733052913e-10\n", - "Constraint violation....: 4.3728354270911041e-12 4.3728354270911041e-12\n", - "Complementarity.........: 2.5059074743708337e-09 2.5059074743708337e-09\n", - "Overall NLP error.......: 2.5059074743708337e-09 2.5059074743708337e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 30\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 30\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.345\n", - "Total CPU secs in NLP function evaluations = 0.035\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.31e-03 3.92e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.94e-09 1.43e-06 -1.0 1.66e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.9411232621280305e-09 1.9411232621280305e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.9411232621280305e-09 1.9411232621280305e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.31e-03 3.92e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.94e-09 1.43e-06 -1.0 1.66e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.9411330320906472e-09 1.9411330320906472e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.9411330320906472e-09 1.9411330320906472e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.099\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 9.19e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.69e+02 3.85e+02 -1.0 9.19e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.62e+00 3.85e+00 -1.0 7.15e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.53e-02 4.39e+00 -1.0 8.10e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.01e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2399698e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2401027e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2399984e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2405602e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2394795e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2396322e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", - " 6 -1.2392061e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.76e-01 3.36e-01f 2\n", - " 7 -1.2387991e+01 3.64e+00 5.35e-01 -1.0 5.23e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2389753e+01 4.48e-01 7.87e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2389755e+01 2.40e-04 1.33e-03 -1.7 3.63e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2389808e+01 3.50e-04 1.04e-03 -3.8 4.33e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2389937e+01 2.30e-04 1.17e-04 -5.7 8.50e-01 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.2390402e+01 2.96e-03 1.02e-04 -5.7 3.06e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 -1.2390734e+01 3.18e-03 1.06e-03 -5.7 4.98e+00 -5.0 1.00e+00 4.36e-01h 1\n", - " 14 -1.2390822e+01 1.73e-03 7.04e-04 -5.7 5.30e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 15 -1.2391170e+01 1.55e-02 2.13e-05 -5.7 2.13e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 16 -1.2392122e+01 1.25e-01 1.80e-04 -5.7 5.69e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 17 -1.2394535e+01 8.51e-01 1.24e-03 -5.7 1.34e+01 -6.9 1.00e+00 1.00e+00h 1\n", - " 18 -1.2399248e+01 3.83e+00 7.22e-03 -5.7 1.90e+01 -7.3 1.00e+00 1.00e+00h 1\n", - " 19 -1.2404443e+01 8.34e+00 2.26e-02 -5.7 3.55e+01 -7.8 1.00e+00 9.24e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2403887e+01 1.53e-01 1.60e-03 -5.7 1.03e+01 -7.4 1.00e+00 1.00e+00f 1\n", - " 21 -1.2405117e+01 4.79e-01 2.18e-03 -5.7 1.71e+01 -7.9 1.00e+00 1.00e+00h 1\n", - " 22 -1.2405374e+01 7.00e-02 1.88e-04 -5.7 8.45e+00 -7.4 1.00e+00 1.00e+00h 1\n", - " 23 -1.2405756e+01 2.12e-01 1.22e-03 -5.7 1.03e+02 - 1.00e+00 2.08e-01h 2\n", - " 24 -1.2406358e+01 1.03e+00 2.17e-03 -5.7 8.46e+01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (322545)\n", - " 25 -1.2406204e+01 1.75e-02 7.25e-05 -5.7 4.61e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.2406205e+01 2.37e-04 2.08e-07 -5.7 1.32e+00 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.2406205e+01 7.23e-08 5.15e-11 -5.7 2.30e-02 - 1.00e+00 1.00e+00h 1\n", - " 28 -1.2406828e+01 3.77e-01 1.03e-03 -8.6 1.92e+01 - 9.07e-01 9.76e-01h 1\n", - "Reallocating memory for MA57: lfact (354103)\n", - " 29 -1.2406852e+01 1.23e-02 2.52e-04 -8.6 9.79e+00 - 9.97e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -1.2406858e+01 2.37e-03 4.93e-05 -8.6 4.37e+00 - 1.00e+00 1.00e+00h 1\n", - " 31 -1.2406860e+01 7.39e-05 2.07e-06 -8.6 7.78e-01 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (376176)\n", - " 32 -1.2406860e+01 5.90e-08 3.77e-09 -8.6 2.20e-02 - 1.00e+00 1.00e+00h 1\n", - " 33 -1.2406860e+01 1.82e-12 3.89e-14 -8.6 3.63e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 33\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2406859586044352e+01 -1.2406859586044352e+01\n", - "Dual infeasibility......: 3.8887996860705895e-14 3.8887996860705895e-14\n", - "Constraint violation....: 9.1789600112649688e-13 1.8189894035458565e-12\n", - "Complementarity.........: 2.5059035652168643e-09 2.5059035652168643e-09\n", - "Overall NLP error.......: 2.5059035652168643e-09 2.5059035652168643e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 43\n", - "Number of objective gradient evaluations = 34\n", - "Number of equality constraint evaluations = 43\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 34\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 33\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.368\n", - "Total CPU secs in NLP function evaluations = 0.051\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 4.01e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.21e+00 3.85e+02 -1.0 3.96e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.80e-02 3.85e+00 -1.0 4.50e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.75e-04 4.39e+00 -1.0 5.11e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.05e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 7.5390617e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 7.5307280e-01 1.57e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.74e-01h 1\n", - " 2 7.5361378e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 7.4810233e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 7.5962740e-01 7.12e-01 2.49e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 7.5698063e-01 5.85e-01 4.71e+01 -1.0 3.48e+02 - 4.75e-01 8.85e-02f 2\n", - " 6 7.6420980e-01 1.37e-01 5.99e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 7.6297451e-01 4.34e-01 2.97e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 7.6358498e-01 3.85e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 7.6354212e-01 5.37e-03 3.81e-03 -2.5 6.34e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 7.6350175e-01 2.77e-06 2.26e-05 -3.8 3.72e-02 -4.5 1.00e+00 1.00e+00h 1\n", - " 11 7.5733271e-01 4.48e-01 2.29e-02 -5.7 3.01e+01 - 7.11e-01 1.00e+00h 1\n", - " 12 7.5196585e-01 6.78e-01 8.94e-03 -5.7 4.61e+01 - 8.18e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (327108)\n", - " 13 7.4797841e-01 6.41e-01 2.55e-02 -5.7 2.96e+01 - 8.64e-01 1.00e+00h 1\n", - " 14 7.4890109e-01 8.10e-03 4.06e-04 -5.7 6.20e-01 -5.0 1.00e+00 1.00e+00h 1\n", - " 15 7.4886319e-01 1.99e-06 2.82e-07 -5.7 5.38e-02 -5.4 1.00e+00 1.00e+00h 1\n", - " 16 7.4881137e-01 6.86e-05 1.98e-05 -8.6 3.31e-01 -5.9 9.95e-01 1.00e+00h 1\n", - " 17 7.4870952e-01 6.03e-04 2.31e-05 -8.6 9.93e-01 -6.4 1.00e+00 1.00e+00h 1\n", - " 18 7.4845170e-01 4.66e-03 1.77e-04 -8.6 2.80e+00 -6.9 1.00e+00 1.00e+00h 1\n", - " 19 7.4825676e-01 6.71e-03 2.55e-04 -8.6 7.30e+00 -7.3 1.00e+00 3.51e-01h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 7.4767097e-01 3.32e-02 1.65e-03 -8.6 8.46e+00 -7.8 1.00e+00 1.00e+00f 1\n", - " 21 7.4711216e-01 2.44e-01 1.54e-02 -8.6 1.14e+02 -8.3 9.80e-01 2.52e-01h 1\n", - " 22 7.4688518e-01 1.38e-01 8.67e-03 -8.6 4.16e+01 - 1.00e+00 4.39e-01f 1\n", - " 23 7.4683046e-01 1.02e-01 6.42e-03 -8.6 3.76e+01 - 1.00e+00 2.59e-01f 1\n", - " 24 7.4679078e-01 6.26e-02 3.91e-03 -8.6 3.27e+01 - 1.00e+00 3.90e-01f 1\n", - " 25 7.4674071e-01 1.91e-03 7.64e-05 -8.6 2.40e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (350967)\n", - " 26 7.4674477e-01 5.39e-04 3.03e-07 -8.6 2.09e+00 - 1.00e+00 1.00e+00h 1\n", - " 27 7.4674475e-01 3.40e-06 1.63e-09 -8.6 1.67e-01 - 1.00e+00 1.00e+00h 1\n", - " 28 7.4674475e-01 8.78e-11 6.54e-14 -8.6 8.49e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 28\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 7.4674475313131294e-01 7.4674475313131294e-01\n", - "Dual infeasibility......: 6.5380653010782577e-14 6.5380653010782577e-14\n", - "Constraint violation....: 8.7840845708342385e-11 8.7840845708342385e-11\n", - "Complementarity.........: 2.5059039393135571e-09 2.5059039393135571e-09\n", - "Overall NLP error.......: 2.5059039393135571e-09 2.5059039393135571e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 33\n", - "Number of objective gradient evaluations = 29\n", - "Number of equality constraint evaluations = 33\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 29\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 28\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.211\n", - "Total CPU secs in NLP function evaluations = 0.043\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.9 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.30e-03 4.15e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.91e-09 1.42e-06 -1.0 1.64e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.9060446554419741e-09 1.9060446554419741e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.9060446554419741e-09 1.9060446554419741e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.30e-03 4.15e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.91e-09 1.42e-06 -1.0 1.64e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.9060530931369613e-09 1.9060530931369613e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.9060530931369613e-09 1.9060530931369613e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 0.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 9.96e+03 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.76e+02 3.85e+02 -1.0 9.96e+03 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.69e+00 3.85e+00 -1.0 7.23e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.61e-02 4.39e+00 -1.0 8.17e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.08e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0403773356229067e-09 9.0403773356229067e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0403773356229067e-09 9.0403773356229067e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.132\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2528966e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2530197e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2529220e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2534432e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2524418e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2525826e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", - " 6 -1.2521877e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.76e-01 3.35e-01f 2\n", - " 7 -1.2518098e+01 3.65e+00 5.36e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2519733e+01 4.49e-01 7.90e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2519735e+01 2.41e-04 1.29e-03 -1.7 3.68e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2519781e+01 3.02e-04 9.67e-04 -3.8 4.03e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2519893e+01 2.02e-04 1.02e-04 -5.7 7.97e-01 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.2520302e+01 2.66e-03 9.65e-05 -5.7 2.89e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 -1.2520638e+01 3.26e-03 8.46e-04 -5.7 5.24e+00 -5.0 1.00e+00 4.54e-01h 1\n", - " 14 -1.2520708e+01 1.48e-03 6.33e-04 -5.7 4.47e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 15 -1.2521012e+01 1.34e-02 1.66e-05 -5.7 2.02e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 16 -1.2521836e+01 1.09e-01 1.45e-04 -5.7 5.34e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 17 -1.2523945e+01 7.51e-01 9.99e-04 -5.7 1.28e+01 -6.9 1.00e+00 1.00e+00h 1\n", - " 18r-1.2523945e+01 7.51e-01 9.99e+02 -0.1 0.00e+00 - 0.00e+00 3.08e-07R 18\n", - " 19r-1.2523451e+01 1.72e-01 9.81e+02 -0.1 3.12e+03 - 1.04e-01 9.90e-04f 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2524823e+01 1.77e-01 5.03e-02 -5.7 1.23e+04 - 7.38e-02 7.99e-04h 1\n", - " 21 -1.2539231e+01 3.95e+01 4.75e-02 -5.7 2.75e+03 - 3.37e-04 5.44e-02h 1\n", - "Reallocating memory for MA57: lfact (323127)\n", - " 22 -1.2541247e+01 3.61e+01 4.11e-02 -5.7 3.01e+02 - 1.46e-01 1.36e-01f 1\n", - " 23 -1.2539740e+01 2.50e+01 3.16e-02 -5.7 1.12e+02 - 1.19e-01 3.51e-01h 1\n", - " 24 -1.2536325e+01 1.39e+01 5.47e-02 -5.7 9.93e+01 - 1.00e+00 5.51e-01h 1\n", - " 25 -1.2536505e+01 1.38e+01 2.22e-01 -5.7 5.62e+02 - 1.93e-03 4.60e-02h 1\n", - " 26 -1.2534286e+01 1.59e+00 1.76e-01 -5.7 3.49e+01 - 1.24e-01 1.00e+00f 1\n", - " 27 -1.2534443e+01 5.57e-02 3.13e-04 -5.7 1.15e+01 -7.3 1.00e+00 1.00e+00h 1\n", - " 28 -1.2534551e+01 9.81e-02 7.65e-04 -5.7 7.58e+00 -7.8 1.00e+00 1.00e+00h 1\n", - " 29 -1.2534950e+01 1.03e+00 6.91e-03 -5.7 2.80e+01 -8.3 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -1.2534831e+01 1.41e-01 1.08e-03 -5.7 8.88e+00 - 1.00e+00 1.00e+00h 1\n", - " 31 -1.2534949e+01 4.97e-02 3.05e-04 -5.7 6.88e+00 - 1.00e+00 1.00e+00h 1\n", - " 32 -1.2534944e+01 2.69e-04 2.11e-06 -5.7 4.40e-01 - 1.00e+00 1.00e+00h 1\n", - " 33 -1.2534944e+01 1.07e-08 1.03e-10 -5.7 2.72e-03 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (344149)\n", - " 34 -1.2535563e+01 4.32e-01 1.10e-03 -8.6 2.06e+01 - 9.03e-01 9.71e-01h 1\n", - "Reallocating memory for MA57: lfact (363431)\n", - " 35 -1.2535591e+01 1.34e-02 2.54e-04 -8.6 1.02e+01 - 9.95e-01 1.00e+00h 1\n", - " 36 -1.2535597e+01 2.72e-03 5.20e-05 -8.6 4.68e+00 - 1.00e+00 1.00e+00h 1\n", - " 37 -1.2535598e+01 9.81e-05 2.47e-06 -8.6 8.96e-01 - 1.00e+00 1.00e+00h 1\n", - " 38 -1.2535598e+01 1.05e-07 5.76e-09 -8.6 2.93e-02 - 1.00e+00 1.00e+00h 1\n", - " 39 -1.2535598e+01 1.82e-12 5.88e-14 -8.6 5.95e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 39\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2535597772942342e+01 -1.2535597772942342e+01\n", - "Dual infeasibility......: 5.8821618000241020e-14 5.8821618000241020e-14\n", - "Constraint violation....: 1.8189894035458565e-12 1.8189894035458565e-12\n", - "Complementarity.........: 2.5059035734822043e-09 2.5059035734822043e-09\n", - "Overall NLP error.......: 2.5059035734822043e-09 2.5059035734822043e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 66\n", - "Number of objective gradient evaluations = 40\n", - "Number of equality constraint evaluations = 66\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 41\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 39\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.508\n", - "Total CPU secs in NLP function evaluations = 0.067\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.3 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 4.35e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.24e+00 3.85e+02 -1.0 4.30e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.83e-02 3.85e+00 -1.0 4.53e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.78e-04 4.39e+00 -1.0 5.14e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.08e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 6.2463783e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 6.2387037e-01 1.57e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.75e-01h 1\n", - " 2 6.2438002e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 6.1926056e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 6.2994249e-01 7.12e-01 2.48e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 6.2749675e-01 5.85e-01 4.72e+01 -1.0 3.48e+02 - 4.75e-01 8.87e-02f 2\n", - " 6 6.3421863e-01 1.35e-01 6.11e+00 -1.0 2.40e+01 -4.0 8.21e-01 1.00e+00F 1\n", - " 7 6.3306025e-01 4.35e-01 2.98e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 6.3362659e-01 3.83e-02 5.75e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 6.3358982e-01 5.38e-03 3.85e-03 -2.5 6.34e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 6.3355519e-01 2.58e-06 2.12e-05 -3.8 3.51e-02 -4.5 1.00e+00 1.00e+00h 1\n", - " 11 6.3322338e-01 2.85e-05 3.51e-06 -5.7 9.23e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 12 6.3264654e-01 1.33e-04 5.05e-06 -5.7 2.72e-01 -5.4 1.00e+00 1.00e+00h 1\n", - " 13 6.3233614e-01 4.22e-04 2.05e-05 -5.7 7.80e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 14 6.3145086e-01 3.55e-03 1.66e-04 -5.7 2.26e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 15 6.2329402e-01 1.79e+00 4.47e-02 -5.7 7.85e+02 - 1.56e-01 9.99e-02h 1\n", - " 16 6.2001136e-01 1.37e+00 4.66e-02 -5.7 1.24e+02 - 1.00e+00 2.70e-01f 1\n", - " 17 6.1736350e-01 1.24e-01 1.13e-02 -5.7 2.91e+01 - 1.00e+00 1.00e+00f 1\n", - "Reallocating memory for MA57: lfact (322135)\n", - " 18 6.1867566e-01 7.27e-03 6.10e-04 -5.7 4.56e+00 - 1.00e+00 1.00e+00h 1\n", - " 19 6.1866009e-01 5.67e-05 3.42e-06 -5.7 6.62e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 6.1866005e-01 2.03e-08 1.12e-09 -5.7 1.25e-02 - 1.00e+00 1.00e+00h 1\n", - " 21 6.1804128e-01 3.11e-02 1.10e-03 -8.6 1.54e+01 - 9.03e-01 9.71e-01h 1\n", - "Reallocating memory for MA57: lfact (347921)\n", - " 22 6.1801354e-01 1.34e-02 2.54e-04 -8.6 1.02e+01 - 9.95e-01 1.00e+00h 1\n", - " 23 6.1800773e-01 2.72e-03 5.20e-05 -8.6 4.68e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 6.1800657e-01 9.81e-05 2.47e-06 -8.6 8.96e-01 - 1.00e+00 1.00e+00h 1\n", - " 25 6.1800653e-01 1.05e-07 5.76e-09 -8.6 2.93e-02 - 1.00e+00 1.00e+00h 1\n", - " 26 6.1800653e-01 4.32e-13 5.93e-14 -8.6 5.95e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 26\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 6.1800652712078263e-01 6.1800652712078263e-01\n", - "Dual infeasibility......: 5.9277911925848335e-14 5.9277911925848335e-14\n", - "Constraint violation....: 4.3220982348657344e-13 4.3220982348657344e-13\n", - "Complementarity.........: 2.5059035734816410e-09 2.5059035734816410e-09\n", - "Overall NLP error.......: 2.5059035734816410e-09 2.5059035734816410e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 31\n", - "Number of objective gradient evaluations = 27\n", - "Number of equality constraint evaluations = 31\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 27\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.926\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.29e-03 4.38e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.87e-09 1.41e-06 -1.0 1.63e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8712897897898984e-09 1.8712897897898984e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8712897897898984e-09 1.8712897897898984e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.103\n", - "Total CPU secs in NLP function evaluations = 0.002\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.29e-03 4.38e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.87e-09 1.41e-06 -1.0 1.63e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8712982274848855e-09 1.8712982274848855e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8712982274848855e-09 1.8712982274848855e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.098\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.07e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.84e+02 3.85e+02 -1.0 1.07e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.77e+00 3.85e+00 -1.0 7.31e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.68e-02 4.39e+00 -1.0 8.25e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.16e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2649276e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2650421e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2649502e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2654364e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2645035e+01 1.67e+01 2.20e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2646341e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.13e-01f 2\n", - " 6 -1.2642660e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.75e-01 3.35e-01f 2\n", - " 7 -1.2639134e+01 3.65e+00 5.36e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2640660e+01 4.49e-01 7.92e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2640661e+01 2.42e-04 1.25e-03 -1.7 3.72e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2640701e+01 2.64e-04 9.04e-04 -3.8 3.77e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2645246e+01 3.62e+00 2.60e-02 -5.7 4.21e+01 - 7.44e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319822)\n", - " 12 -1.2650749e+01 4.98e+00 1.49e-02 -5.7 7.45e+01 - 8.19e-01 1.00e+00h 1\n", - " 13 -1.2654062e+01 5.16e+00 1.87e-02 -5.7 3.19e+01 - 9.04e-01 1.00e+00h 1\n", - " 14 -1.2654011e+01 4.69e+00 5.08e-02 -5.7 1.46e+01 -4.0 1.00e+00 9.14e-02h 1\n", - " 15 -1.2654035e+01 7.16e-01 2.01e-02 -5.7 3.14e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 -1.2653941e+01 1.00e-03 9.08e-05 -5.7 3.69e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 17 -1.2654241e+01 6.33e-01 5.16e-03 -5.7 1.06e+02 - 1.00e+00 1.70e-01h 2\n", - " 18 -1.2654880e+01 3.29e-01 2.15e-03 -5.7 1.63e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.2654796e+01 6.21e-03 3.76e-05 -5.7 1.47e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2654797e+01 9.53e-06 4.39e-08 -5.7 1.04e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.2655412e+01 4.92e-01 1.17e-03 -8.6 2.19e+01 - 8.97e-01 9.66e-01h 1\n", - "Reallocating memory for MA57: lfact (343005)\n", - " 22 -1.2655443e+01 1.44e-02 2.56e-04 -8.6 1.06e+01 - 9.92e-01 1.00e+00h 1\n", - " 23 -1.2655449e+01 3.08e-03 5.46e-05 -8.6 4.98e+00 - 1.00e+00 1.00e+00h 1\n", - " 24 -1.2655450e+01 1.28e-04 2.92e-06 -8.6 1.02e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (360209)\n", - " 25 -1.2655450e+01 1.79e-07 8.58e-09 -8.6 3.83e-02 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.2655450e+01 1.82e-12 1.06e-13 -8.6 9.45e-05 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 26\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2655450125163370e+01 -1.2655450125163370e+01\n", - "Dual infeasibility......: 1.0562293264999832e-13 1.0562293264999832e-13\n", - "Constraint violation....: 1.0876854972252659e-12 1.8189894035458565e-12\n", - "Complementarity.........: 2.5059035921766028e-09 2.5059035921766028e-09\n", - "Overall NLP error.......: 2.5059035921766028e-09 2.5059035921766028e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 37\n", - "Number of objective gradient evaluations = 27\n", - "Number of equality constraint evaluations = 37\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 27\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 26\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.992\n", - "Total CPU secs in NLP function evaluations = 0.043\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 4.69e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.27e+00 3.85e+02 -1.0 4.64e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.87e-02 3.85e+00 -1.0 4.57e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.81e-04 4.39e+00 -1.0 5.17e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.11e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.134\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 5.0432833e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 5.0361720e-01 1.56e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.75e-01h 1\n", - " 2 5.0409878e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 4.9931925e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 5.0927300e-01 7.12e-01 2.48e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 5.0699996e-01 5.85e-01 4.72e+01 -1.0 3.47e+02 - 4.76e-01 8.88e-02f 2\n", - " 6 5.1324183e-01 1.37e-01 6.01e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 5.1217900e-01 4.34e-01 2.96e-01 -1.0 5.48e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 5.1271052e-01 3.84e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 5.1267962e-01 5.41e-03 3.90e-03 -2.5 6.36e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 5.1241548e-01 5.08e-04 5.15e-04 -3.8 9.59e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 5.0807961e-01 3.17e-01 2.48e-02 -5.7 2.63e+01 - 7.57e-01 1.00e+00h 1\n", - " 12 5.0278293e-01 8.71e-01 1.15e-02 -5.7 5.29e+01 - 8.62e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (326106)\n", - " 13 4.9913241e-01 7.64e-01 2.78e-02 -5.7 3.15e+01 - 8.71e-01 1.00e+00h 1\n", - " 14 4.9997874e-01 1.14e-02 5.09e-04 -5.7 7.44e-01 -4.5 9.85e-01 1.00e+00h 1\n", - " 15 4.9994319e-01 6.15e-07 2.09e-07 -5.7 1.61e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 4.9991846e-01 5.82e-06 2.33e-06 -8.6 9.55e-02 -5.4 9.99e-01 1.00e+00h 1\n", - " 17 4.9989124e-01 5.24e-05 1.77e-06 -8.6 2.92e-01 -5.9 1.00e+00 1.00e+00h 1\n", - " 18 4.9981470e-01 4.48e-04 1.51e-05 -8.6 8.57e-01 -6.4 1.00e+00 1.00e+00h 1\n", - " 19 4.9961545e-01 3.50e-03 1.17e-04 -8.6 2.43e+00 -6.9 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 4.9957792e-01 3.35e-03 1.12e-04 -8.6 6.02e+00 -7.3 1.00e+00 8.63e-02h 1\n", - " 21 4.9902524e-01 3.02e-02 1.14e-03 -8.6 7.74e+00 -7.8 1.00e+00 1.00e+00f 1\n", - " 22 4.9848008e-01 2.40e-01 1.30e-02 -8.6 7.13e+01 -8.3 1.00e+00 4.02e-01h 1\n", - " 23 4.9828290e-01 1.29e-01 7.02e-03 -8.6 4.11e+01 - 1.00e+00 4.70e-01f 1\n", - " 24 4.9823261e-01 9.68e-02 5.22e-03 -8.6 3.63e+01 - 1.00e+00 2.57e-01f 1\n", - " 25 4.9820105e-01 6.31e-02 3.38e-03 -8.6 3.10e+01 - 1.00e+00 3.52e-01f 1\n", - " 26 4.9815087e-01 2.36e-03 6.18e-05 -8.6 2.04e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (361644)\n", - " 27 4.9815415e-01 3.57e-04 1.71e-07 -8.6 1.71e+00 - 1.00e+00 1.00e+00h 1\n", - " 28 4.9815414e-01 1.50e-06 6.26e-10 -8.6 1.11e-01 - 1.00e+00 1.00e+00h 1\n", - " 29 4.9815414e-01 1.71e-11 3.34e-14 -8.6 3.75e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 29\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 4.9815414100226940e-01 4.9815414100226940e-01\n", - "Dual infeasibility......: 3.3405414623680940e-14 3.3405414623680940e-14\n", - "Constraint violation....: 1.7140733277187792e-11 1.7140733277187792e-11\n", - "Complementarity.........: 2.5059036238671544e-09 2.5059036238671544e-09\n", - "Overall NLP error.......: 2.5059036238671544e-09 2.5059036238671544e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 30\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 30\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 29\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.235\n", - "Total CPU secs in NLP function evaluations = 0.038\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.27e-03 4.61e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.84e-09 1.40e-06 -1.0 1.61e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8368555565473343e-09 1.8368555565473343e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8368555565473343e-09 1.8368555565473343e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.27e-03 4.61e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.84e-09 1.40e-06 -1.0 1.61e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8368631060639018e-09 1.8368631060639018e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8368631060639018e-09 1.8368631060639018e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.102\n", - "Total CPU secs in NLP function evaluations = 0.003\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.15e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.92e+02 3.85e+02 -1.0 1.15e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.85e+00 3.85e+00 -1.0 7.38e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.76e-02 4.39e+00 -1.0 8.33e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.23e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0367393568158150e-09 9.0367393568158150e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0367393568158150e-09 9.0367393568158150e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.126\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2761788e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2762860e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2761992e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2766548e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2757815e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2759034e+01 1.18e+01 3.20e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", - " 6 -1.2755587e+01 1.23e+01 3.32e+00 -1.0 9.23e+01 - 8.75e-01 3.35e-01f 2\n", - " 7 -1.2752282e+01 3.66e+00 5.36e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2753712e+01 4.50e-01 7.94e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2753713e+01 2.43e-04 1.22e-03 -1.7 3.76e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2753748e+01 2.32e-04 8.49e-04 -3.8 3.54e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2753835e+01 1.60e-04 8.09e-05 -5.7 7.08e-01 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.2754158e+01 2.17e-03 8.72e-05 -5.7 2.61e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 -1.2754496e+01 3.46e-03 5.33e-04 -5.7 5.48e+00 -5.0 1.00e+00 4.99e-01h 1\n", - " 14 -1.2754536e+01 1.11e-03 5.18e-04 -5.7 2.85e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 15 -1.2754778e+01 1.03e-02 2.28e-05 -5.7 1.85e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 16 -1.2755412e+01 8.41e-02 9.87e-05 -5.7 4.74e+00 -6.4 1.00e+00 1.00e+00h 1\n", - " 17 -1.2757064e+01 5.97e-01 6.84e-04 -5.7 1.17e+01 -6.9 1.00e+00 1.00e+00h 1\n", - " 18 -1.2760500e+01 2.94e+00 4.15e-03 -5.7 1.95e+01 -7.3 1.00e+00 1.00e+00h 1\n", - " 19 -1.2761019e+01 9.59e+00 2.25e-02 -5.7 6.29e+02 - 1.13e-01 1.41e-01h 2\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2764864e+01 1.90e+01 9.25e-02 -5.7 1.73e+02 - 3.33e-01 3.01e-01h 1\n", - " 21 -1.2764680e+01 1.16e+01 1.82e-01 -5.7 2.07e+02 - 3.79e-01 7.21e-01H 1\n", - " 22 -1.2767567e+01 1.81e+01 2.45e-01 -5.7 1.01e+02 - 1.00e+00 1.00e+00f 1\n", - " 23 -1.2767317e+01 1.23e+01 1.12e-01 -5.7 1.91e+02 - 1.00e+00 5.53e-01h 1\n", - "Reallocating memory for MA57: lfact (319005)\n", - " 24 -1.2767311e+01 8.83e+00 7.94e-02 -5.7 8.23e+01 - 8.73e-01 9.30e-01f 1\n", - " 25 -1.2766311e+01 1.99e+00 2.60e-02 -5.7 3.16e+01 - 1.00e+00 1.00e+00f 1\n", - " 26 -1.2766561e+01 2.73e-01 7.90e-04 -5.7 2.07e+01 -7.8 1.00e+00 1.00e+00h 1\n", - " 27 -1.2766765e+01 6.11e-01 2.75e-03 -5.7 3.40e+02 - 4.24e-01 4.80e-02h 2\n", - " 28 -1.2766866e+01 3.52e-02 1.15e-04 -5.7 5.75e+00 - 1.00e+00 1.00e+00h 1\n", - " 29 -1.2766913e+01 1.08e-02 5.42e-05 -5.7 3.27e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 30 -1.2766912e+01 5.95e-06 4.85e-08 -5.7 5.76e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (340818)\n", - " 31 -1.2767524e+01 5.55e-01 1.25e-03 -8.6 2.33e+01 - 8.91e-01 9.61e-01h 1\n", - " 32 -1.2767558e+01 1.54e-02 2.57e-04 -8.6 1.09e+01 - 9.90e-01 1.00e+00h 1\n", - " 33 -1.2767563e+01 3.45e-03 5.70e-05 -8.6 5.26e+00 - 1.00e+00 1.00e+00h 1\n", - " 34 -1.2767564e+01 1.62e-04 3.39e-06 -8.6 1.15e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (358770)\n", - " 35 -1.2767564e+01 2.90e-07 1.23e-08 -8.6 4.88e-02 - 1.00e+00 1.00e+00h 1\n", - " 36 -1.2767564e+01 2.51e-12 1.99e-13 -8.6 1.44e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 36\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2767564482596377e+01 -1.2767564482596377e+01\n", - "Dual infeasibility......: 1.9925310697126672e-13 1.9925310697126672e-13\n", - "Constraint violation....: 2.5131008385415043e-12 2.5131008385415043e-12\n", - "Complementarity.........: 2.5059036300337093e-09 2.5059036300337093e-09\n", - "Overall NLP error.......: 2.5059036300337093e-09 2.5059036300337093e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 51\n", - "Number of objective gradient evaluations = 37\n", - "Number of equality constraint evaluations = 51\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 37\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 36\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.271\n", - "Total CPU secs in NLP function evaluations = 0.053\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 5.03e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.31e+00 3.85e+02 -1.0 4.98e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.90e-02 3.85e+00 -1.0 4.60e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.84e-04 4.39e+00 -1.0 5.20e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.14e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8342664033261826e-11 5.8342664033261826e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8342664033261826e-11 5.8342664033261826e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.128\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 3.9181573e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 3.9115328e-01 1.56e-01 1.04e+00 -1.0 5.95e-01 - 9.79e-01 8.75e-01h 1\n", - " 2 3.9160960e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 3.8712768e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 3.9644619e-01 7.12e-01 2.48e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 3.9432311e-01 5.85e-01 4.73e+01 -1.0 3.46e+02 - 4.77e-01 8.89e-02f 2\n", - " 6 4.0017008e-01 1.36e-01 6.05e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 3.9917425e-01 4.34e-01 2.97e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 3.9967295e-01 3.84e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 3.9964620e-01 5.42e-03 3.94e-03 -2.5 6.37e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 3.9941445e-01 5.23e-04 4.68e-04 -3.8 8.72e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 3.9556789e-01 2.81e-01 2.38e-02 -5.7 2.46e+01 - 7.68e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (320660)\n", - " 12 3.9049239e-01 8.99e-01 1.14e-02 -5.7 5.36e+01 - 8.66e-01 1.00e+00h 1\n", - " 13 3.8696936e-01 7.77e-01 2.66e-02 -5.7 3.18e+01 - 8.89e-01 1.00e+00h 1\n", - " 14 3.8779264e-01 1.12e-02 4.89e-04 -5.7 7.59e-01 -4.5 9.97e-01 1.00e+00h 1\n", - " 15 3.8775852e-01 6.21e-07 1.98e-07 -5.7 1.51e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 3.8730660e-01 3.80e-01 2.43e-02 -8.6 1.44e+04 - 7.13e-03 2.64e-03h 1\n", - " 17 3.8571434e-01 1.57e-01 4.82e-03 -8.6 3.21e+01 - 8.01e-01 1.00e+00h 1\n", - " 18 3.8604273e-01 1.97e-02 3.18e-04 -8.6 1.23e+01 - 9.78e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (352373)\n", - " 19 3.8603975e-01 2.68e-03 8.27e-06 -8.6 4.65e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 3.8603975e-01 4.52e-05 4.68e-08 -8.6 6.09e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 3.8603975e-01 1.34e-08 4.74e-12 -8.6 1.05e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 3.8603911e-01 1.37e-06 2.67e-08 -9.0 1.06e-01 - 1.00e+00 1.00e+00h 1\n", - " 23 3.8603911e-01 4.37e-11 1.28e-12 -9.0 5.99e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 3.8603910736158609e-01 3.8603910736158609e-01\n", - "Dual infeasibility......: 1.2773062897591488e-12 1.2773062897591488e-12\n", - "Constraint violation....: 4.3745562727792731e-11 4.3745562727792731e-11\n", - "Complementarity.........: 9.0909138582673236e-10 9.0909138582673236e-10\n", - "Overall NLP error.......: 9.0909138582673236e-10 9.0909138582673236e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 28\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 28\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.951\n", - "Total CPU secs in NLP function evaluations = 0.031\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.26e-03 4.84e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.80e-09 1.40e-06 -1.0 1.60e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.8027450643387510e-09 1.8027450643387510e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.8027450643387510e-09 1.8027450643387510e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.38e-03 2.49e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.17e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1657315940615263e-09 2.1657315940615263e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1657315940615263e-09 2.1657315940615263e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.106\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 0.9 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.23e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 6.99e+02 3.85e+02 -1.0 1.23e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 7.92e+00 3.85e+00 -1.0 7.46e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.83e-02 4.39e+00 -1.0 8.40e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.31e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", - "Total CPU secs in NLP function evaluations = 0.008\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2867454e+01 1.25e+00 1.05e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2868460e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2867639e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2871924e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2863717e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2864858e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", - " 6 -1.2861618e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", - " 7 -1.2858508e+01 3.66e+00 5.37e-01 -1.0 5.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2859854e+01 4.51e-01 7.96e-02 -1.0 1.10e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2859854e+01 2.44e-04 1.19e-03 -1.7 3.79e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2859885e+01 2.06e-04 8.00e-04 -3.8 3.33e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2863468e+01 2.88e+00 2.39e-02 -5.7 3.78e+01 - 7.65e-01 1.00e+00h 1\n", - " 12 -1.2868524e+01 5.45e+00 1.49e-02 -5.7 7.69e+01 - 8.12e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (324125)\n", - " 13 -1.2871542e+01 4.87e+00 1.57e-02 -5.7 3.27e+01 - 9.43e-01 1.00e+00h 1\n", - " 14 -1.2871505e+01 4.47e+00 5.03e-02 -5.7 1.42e+01 -4.0 1.00e+00 8.24e-02h 1\n", - " 15 -1.2871544e+01 7.88e-01 1.77e-02 -5.7 3.24e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 -1.2871459e+01 1.19e-03 1.13e-04 -5.7 4.55e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 17 -1.2871817e+01 6.63e-01 4.65e-03 -5.7 4.38e+01 - 1.00e+00 4.24e-01h 2\n", - " 18 -1.2872068e+01 6.22e-01 3.65e-03 -5.7 3.60e+01 - 1.00e+00 3.97e-01h 2\n", - " 19 -1.2872235e+01 1.80e-02 4.42e-04 -5.7 5.48e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2872228e+01 2.81e-04 1.04e-06 -5.7 7.92e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.2872228e+01 6.84e-09 4.81e-11 -5.7 2.27e-03 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.2872836e+01 6.22e-01 1.32e-03 -8.6 2.46e+01 - 8.84e-01 9.57e-01h 1\n", - "Reallocating memory for MA57: lfact (352404)\n", - " 23 -1.2872873e+01 1.64e-02 2.58e-04 -8.6 1.12e+01 - 9.88e-01 1.00e+00h 1\n", - " 24 -1.2872878e+01 3.83e-03 5.93e-05 -8.6 5.54e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.2872880e+01 2.02e-04 3.88e-06 -8.6 1.28e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.2872880e+01 4.51e-07 1.70e-08 -8.6 6.08e-02 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.2872880e+01 5.38e-12 3.77e-13 -8.6 2.10e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2872879704090735e+01 -1.2872879704090735e+01\n", - "Dual infeasibility......: 3.7744241620007363e-13 3.7744241620007363e-13\n", - "Constraint violation....: 5.3804738442408961e-12 5.3804738442408961e-12\n", - "Complementarity.........: 2.5059037015571048e-09 2.5059037015571048e-09\n", - "Overall NLP error.......: 2.5059037015571048e-09 2.5059037015571048e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 43\n", - "Number of objective gradient evaluations = 28\n", - "Number of equality constraint evaluations = 43\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 28\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.074\n", - "Total CPU secs in NLP function evaluations = 0.067\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 3.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 5.38e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.34e+00 3.85e+02 -1.0 5.32e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.93e-02 3.85e+00 -1.0 4.63e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.87e-04 4.39e+00 -1.0 5.23e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.17e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.127\n", - "Total CPU secs in NLP function evaluations = 0.007\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 2.8614991e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 2.8552993e-01 1.56e-01 1.04e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", - " 2 2.8596341e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 2.8174414e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 2.9050364e-01 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 2.8851199e-01 5.85e-01 4.73e+01 -1.0 3.46e+02 - 4.77e-01 8.91e-02f 2\n", - " 6 2.9401108e-01 1.36e-01 6.08e+00 -1.0 2.40e+01 -4.0 8.22e-01 1.00e+00F 1\n", - " 7 2.9307524e-01 4.34e-01 2.97e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 2.9354482e-01 3.83e-02 5.77e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 2.9352137e-01 5.43e-03 3.97e-03 -2.5 6.38e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 2.9331638e-01 5.29e-04 4.27e-04 -3.8 8.79e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 2.8988055e-01 2.51e-01 2.28e-02 -5.7 2.32e+01 - 7.77e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319389)\n", - " 12 2.8501317e-01 9.24e-01 1.13e-02 -5.7 5.42e+01 - 8.69e-01 1.00e+00h 1\n", - " 13 2.8160648e-01 7.91e-01 2.55e-02 -5.7 3.22e+01 - 9.07e-01 1.00e+00h 1\n", - " 14 2.8240769e-01 1.11e-02 4.72e-04 -5.7 7.74e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 15 2.8237479e-01 6.27e-07 1.90e-07 -5.7 1.42e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 2.8187382e-01 3.93e-01 2.36e-02 -8.6 6.25e+02 - 1.42e-01 6.14e-02h 1\n", - " 17 2.8044338e-01 1.41e-01 4.08e-03 -8.6 3.11e+01 - 8.06e-01 1.00e+00h 1\n", - " 18 2.8072577e-01 1.89e-02 2.94e-04 -8.6 1.21e+01 - 9.80e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (348083)\n", - " 19 2.8072395e-01 2.58e-03 1.02e-05 -8.6 4.56e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 2.8072390e-01 4.67e-05 1.13e-07 -8.6 6.18e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 2.8072390e-01 1.53e-08 1.88e-11 -8.6 1.12e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 2.8072325e-01 1.54e-06 2.83e-08 -9.0 1.12e-01 - 1.00e+00 1.00e+00h 1\n", - " 23 2.8072325e-01 5.55e-11 1.52e-12 -9.0 6.75e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 2.8072325129350517e-01 2.8072325129350517e-01\n", - "Dual infeasibility......: 1.5217814371823493e-12 1.5217814371823493e-12\n", - "Constraint violation....: 5.5502491491665751e-11 5.5502491491665751e-11\n", - "Complementarity.........: 9.0909147761315399e-10 9.0909147761315399e-10\n", - "Overall NLP error.......: 9.0909147761315399e-10 9.0909147761315399e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 28\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 28\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.822\n", - "Total CPU secs in NLP function evaluations = 0.040\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.6 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.25e-03 5.07e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.77e-09 1.39e-06 -1.0 1.58e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.7689547604504696e-09 1.7689547604504696e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.7689547604504696e-09 1.7689547604504696e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.38e-03 2.57e-01 -1.0 1.85e-01 - 9.91e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 2.15e-09 1.48e-06 -1.0 1.75e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1522383875094420e-09 2.1522383875094420e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1522383875094420e-09 2.1522383875094420e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.101\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.0 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.30e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 7.07e+02 3.85e+02 -1.0 1.30e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 8.00e+00 3.85e+00 -1.0 7.54e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.91e-02 4.39e+00 -1.0 8.48e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.38e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.2967058e+01 1.25e+00 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.2968006e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.06e-01h 1\n", - " 2 -1.2967227e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.2971272e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.2963530e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.2964604e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", - " 6 -1.2961547e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", - " 7 -1.2958610e+01 3.66e+00 5.37e-01 -1.0 5.25e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.2959880e+01 4.51e-01 7.97e-02 -1.0 1.11e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.2959880e+01 2.45e-04 1.16e-03 -1.7 3.82e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.2959908e+01 1.85e-04 7.57e-04 -3.8 3.15e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.2963121e+01 2.60e+00 2.30e-02 -5.7 3.59e+01 - 7.75e-01 1.00e+00h 1\n", - " 12 -1.2967974e+01 5.66e+00 1.48e-02 -5.7 7.78e+01 - 8.10e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319946)\n", - " 13 -1.2970867e+01 4.77e+00 1.46e-02 -5.7 3.30e+01 - 9.60e-01 1.00e+00h 1\n", - " 14 -1.2970834e+01 4.39e+00 4.99e-02 -5.7 1.40e+01 -4.0 1.00e+00 7.87e-02h 1\n", - " 15 -1.2970871e+01 8.04e-01 1.66e-02 -5.7 3.26e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 -1.2970791e+01 1.23e-03 1.24e-04 -5.7 4.78e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 17 -1.2971470e+01 2.07e+00 1.31e-02 -5.7 3.26e+01 - 1.00e+00 1.00e+00h 1\n", - " 18 -1.2971390e+01 2.65e-01 2.02e-03 -5.7 1.09e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.2971539e+01 1.75e-01 7.49e-04 -5.7 1.26e+01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.2971523e+01 4.44e-03 2.61e-05 -5.7 1.85e+00 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.2971523e+01 2.35e-06 1.59e-08 -5.7 3.77e-02 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (342795)\n", - " 22 -1.2972127e+01 6.92e-01 1.39e-03 -8.6 2.60e+01 - 8.78e-01 9.52e-01h 1\n", - " 23 -1.2972167e+01 1.73e-02 2.59e-04 -8.6 1.15e+01 - 9.86e-01 1.00e+00h 1\n", - " 24 -1.2972172e+01 4.22e-03 6.14e-05 -8.6 5.81e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.2972173e+01 2.46e-04 4.38e-06 -8.6 1.42e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (361301)\n", - " 26 -1.2972174e+01 6.76e-07 2.28e-08 -8.6 7.45e-02 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.2972174e+01 1.08e-11 6.93e-13 -8.6 2.98e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.2972173508586897e+01 -1.2972173508586897e+01\n", - "Dual infeasibility......: 6.9302411901920606e-13 6.9302411901920606e-13\n", - "Constraint violation....: 1.0807355010911124e-11 1.0807355010911124e-11\n", - "Complementarity.........: 2.5059038289136340e-09 2.5059038289136340e-09\n", - "Overall NLP error.......: 2.5059038289136340e-09 2.5059038289136340e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 28\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 28\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.039\n", - "Total CPU secs in NLP function evaluations = 0.034\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.9 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 5.72e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.37e+00 3.85e+02 -1.0 5.66e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.96e-02 3.85e+00 -1.0 4.66e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.91e-04 4.39e+00 -1.0 5.27e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.21e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8335558605904225e-11 5.8335558605904225e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.130\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 1.8654549e-01 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 1.8596289e-01 1.56e-01 1.03e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", - " 2 1.8637565e-01 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 1.8238996e-01 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 1.9065372e-01 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 1.8877820e-01 5.85e-01 4.73e+01 -1.0 3.46e+02 - 4.78e-01 8.92e-02f 2\n", - " 6 1.9396149e-01 1.37e-01 6.06e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 1.9308197e-01 4.34e-01 2.96e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 1.9352656e-01 3.83e-02 5.78e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 1.9350624e-01 5.45e-03 4.00e-03 -2.5 6.39e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 1.9332380e-01 5.30e-04 3.89e-04 -3.8 9.48e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 1.9023661e-01 2.26e-01 2.20e-02 -5.7 2.19e+01 - 7.86e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (320076)\n", - " 12 1.8556544e-01 9.45e-01 1.12e-02 -5.7 5.48e+01 - 8.73e-01 1.00e+00h 1\n", - " 13 1.8226712e-01 8.03e-01 2.46e-02 -5.7 3.25e+01 - 9.25e-01 1.00e+00h 1\n", - " 14 1.8304698e-01 1.11e-02 4.57e-04 -5.7 7.87e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 15 1.8301518e-01 6.34e-07 1.83e-07 -5.7 1.33e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 1.8246962e-01 4.04e-01 2.28e-02 -8.6 3.22e+02 - 2.45e-01 1.20e-01h 1\n", - " 17 1.8118955e-01 1.25e-01 3.47e-03 -8.6 2.99e+01 - 8.12e-01 1.00e+00h 1\n", - " 18 1.8143090e-01 1.83e-02 2.70e-04 -8.6 1.19e+01 - 9.83e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (352539)\n", - " 19 1.8142961e-01 2.51e-03 1.26e-05 -8.6 4.50e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 1.8142950e-01 4.81e-05 1.90e-07 -8.6 6.28e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 1.8142949e-01 1.74e-08 5.29e-11 -8.6 1.19e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 1.8142885e-01 1.72e-06 2.99e-08 -9.0 1.19e-01 - 1.00e+00 1.00e+00h 1\n", - " 23 1.8142885e-01 6.95e-11 1.80e-12 -9.0 7.55e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 1.8142884693002581e-01 1.8142884693002581e-01\n", - "Dual infeasibility......: 1.7962352785824499e-12 1.7962352785824499e-12\n", - "Constraint violation....: 6.9450334372334055e-11 6.9450334372334055e-11\n", - "Complementarity.........: 9.0909158006744088e-10 9.0909158006744088e-10\n", - "Overall NLP error.......: 9.0909158006744088e-10 9.0909158006744088e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 28\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 28\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.945\n", - "Total CPU secs in NLP function evaluations = 0.037\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.24e-03 5.30e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 1.74e-09 1.38e-06 -1.0 1.57e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.7354877535069591e-09 1.7354877535069591e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.7354877535069591e-09 1.7354877535069591e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.38e-03 2.66e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.14e-09 1.48e-06 -1.0 1.74e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1387873694322934e-09 2.1387873694322934e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1387873694322934e-09 2.1387873694322934e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.107\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.3 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.38e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 7.15e+02 3.85e+02 -1.0 1.38e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 8.08e+00 3.85e+00 -1.0 7.61e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 7.99e-02 4.39e+00 -1.0 8.56e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.46e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0367393568158150e-09 9.0367393568158150e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0367393568158150e-09 9.0367393568158150e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.129\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.3061258e+01 1.25e+00 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.3062155e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.07e-01h 1\n", - " 2 -1.3061413e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.3065245e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.3057918e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.3058931e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", - " 6 -1.3056038e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", - " 7 -1.3053256e+01 3.67e+00 5.37e-01 -1.0 5.25e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.3054459e+01 4.52e-01 7.98e-02 -1.0 1.11e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.3054459e+01 2.46e-04 1.14e-03 -1.7 3.85e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.3054484e+01 1.66e-04 7.18e-04 -3.8 2.99e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.3057381e+01 2.35e+00 2.21e-02 -5.7 3.43e+01 - 7.84e-01 1.00e+00h 1\n", - " 12 -1.3062042e+01 5.84e+00 1.46e-02 -5.7 7.86e+01 - 8.08e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (325047)\n", - " 13 -1.3064822e+01 4.69e+00 1.36e-02 -5.7 3.33e+01 - 9.76e-01 1.00e+00h 1\n", - " 14 -1.3064793e+01 4.33e+00 4.95e-02 -5.7 1.38e+01 -4.0 1.00e+00 7.55e-02h 1\n", - " 15 -1.3064825e+01 8.10e-01 1.55e-02 -5.7 3.27e+01 - 1.00e+00 1.00e+00h 1\n", - " 16 -1.3064750e+01 1.24e-03 1.35e-04 -5.7 4.92e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 17 -1.3065327e+01 1.32e+00 8.45e-03 -5.7 2.57e+01 - 1.00e+00 1.00e+00h 1\n", - " 18 -1.3065563e+01 3.66e-01 9.07e-04 -5.7 2.45e+01 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.3065455e+01 8.75e-02 3.46e-04 -5.7 9.07e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.3065447e+01 1.22e-03 6.52e-06 -5.7 9.79e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.3065447e+01 1.73e-07 1.14e-09 -5.7 1.04e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.3066047e+01 7.66e-01 1.47e-03 -8.6 2.73e+01 - 8.72e-01 9.48e-01h 1\n", - "Reallocating memory for MA57: lfact (349926)\n", - " 23 -1.3066091e+01 1.83e-02 2.59e-04 -8.6 1.18e+01 - 9.84e-01 1.00e+00h 1\n", - " 24 -1.3066096e+01 4.62e-03 6.34e-05 -8.6 6.08e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.3066097e+01 2.96e-04 4.89e-06 -8.6 1.55e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.3066097e+01 9.81e-07 2.99e-08 -8.6 8.97e-02 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.3066097e+01 2.05e-11 1.23e-12 -8.6 4.11e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.3066097364112752e+01 -1.3066097364112752e+01\n", - "Dual infeasibility......: 1.2294764961011457e-12 1.2294764961011457e-12\n", - "Constraint violation....: 2.0529578037553620e-11 2.0529578037553620e-11\n", - "Complementarity.........: 2.5059040443903054e-09 2.5059040443903054e-09\n", - "Overall NLP error.......: 2.5059040443903054e-09 2.5059040443903054e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 28\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 28\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.154\n", - "Total CPU secs in NLP function evaluations = 0.047\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.06e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.40e+00 3.85e+02 -1.0 6.00e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 4.99e-02 3.85e+00 -1.0 4.69e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.94e-04 4.39e+00 -1.0 5.30e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.24e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8342664033261826e-11 5.8342664033261826e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8342664033261826e-11 5.8342664033261826e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.145\n", - "Total CPU secs in NLP function evaluations = 0.007\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 9.2344539e-02 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 9.1795096e-02 1.56e-01 1.03e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", - " 2 9.2188972e-02 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 8.8412352e-02 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 9.6233482e-02 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 9.4461313e-02 5.85e-01 4.74e+01 -1.0 3.45e+02 - 4.78e-01 8.92e-02f 2\n", - " 6 9.9368726e-02 1.36e-01 6.08e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 9.8535727e-02 4.34e-01 2.97e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 9.8957264e-02 3.83e-02 5.78e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 9.8939356e-02 5.46e-03 4.02e-03 -2.5 6.39e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 9.8775901e-02 5.26e-04 3.62e-04 -3.8 1.01e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 9.5986597e-02 2.04e-01 2.11e-02 -5.7 2.08e+01 - 7.94e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319905)\n", - " 12 9.1498624e-02 9.64e-01 1.11e-02 -5.7 5.52e+01 - 8.77e-01 1.00e+00h 1\n", - " 13 8.8299544e-02 8.17e-01 2.37e-02 -5.7 3.28e+01 - 9.41e-01 1.00e+00h 1\n", - " 14 8.9059447e-02 1.11e-02 4.46e-04 -5.7 8.02e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 15 8.9028548e-02 6.44e-07 1.79e-07 -5.7 1.25e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 8.8442722e-02 4.14e-01 2.20e-02 -8.6 2.18e+02 - 3.15e-01 1.78e-01h 1\n", - " 17 8.7303204e-02 1.14e-01 2.94e-03 -8.6 2.87e+01 - 8.18e-01 1.00e+00h 1\n", - " 18 8.7506248e-02 1.77e-02 2.54e-04 -8.6 1.17e+01 - 9.86e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (349182)\n", - " 19 8.7505239e-02 2.49e-03 1.53e-05 -8.6 4.48e+00 - 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (366797)\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 8.7505073e-02 5.20e-05 3.04e-07 -8.6 6.52e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 8.7505067e-02 2.17e-08 1.39e-10 -8.6 1.33e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 8.7504422e-02 1.91e-06 3.15e-08 -9.0 1.25e-01 - 1.00e+00 1.00e+00h 1\n", - " 23 8.7504422e-02 1.03e-12 3.41e-10 -9.0 9.20e-05 -5.4 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 8.7504422324047759e-02 8.7504422324047759e-02\n", - "Dual infeasibility......: 3.4067176250603508e-10 3.4067176250603508e-10\n", - "Constraint violation....: 1.0300649222472202e-12 1.0300649222472202e-12\n", - "Complementarity.........: 9.0912236625038064e-10 9.0912236625038064e-10\n", - "Overall NLP error.......: 9.0912236625038064e-10 9.0912236625038064e-10\n", - "\n", - "\n", - "Number of objective function evaluations = 28\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 28\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.014\n", - "Total CPU secs in NLP function evaluations = 0.041\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.7 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.23e-03 5.54e-01 -1.0 1.85e-01 - 9.91e-01 9.92e-01h 1\n", - " 4 0.0000000e+00 1.70e-09 1.37e-06 -1.0 1.55e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.7023418230621701e-09 1.7023418230621701e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.7023418230621701e-09 1.7023418230621701e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.118\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.4 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.37e-03 2.74e-01 -1.0 1.85e-01 - 9.91e-01 9.91e-01h 1\n", - " 4 0.0000000e+00 2.13e-09 1.47e-06 -1.0 1.73e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.1253634407969457e-09 2.1253634407969457e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.1253634407969457e-09 2.1253634407969457e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.100\n", - "Total CPU secs in NLP function evaluations = 0.005\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.46e+04 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (298604)\n", - " 1 0.0000000e+00 7.22e+02 3.85e+02 -1.0 1.46e+04 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 8.15e+00 3.85e+00 -1.0 7.69e+02 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 8.06e-02 4.39e+00 -1.0 8.63e+00 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 9.04e-09 1.02e-06 -1.0 8.54e-02 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.0385583462193608e-09 9.0385583462193608e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.131\n", - "Total CPU secs in NLP function evaluations = 0.009\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.3150611e+01 1.25e+00 1.04e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 -1.3151462e+01 6.17e-01 5.15e+00 -1.0 4.65e+01 - 9.73e-01 5.07e-01h 1\n", - " 2 -1.3150755e+01 1.28e+00 1.96e+00 -1.0 4.46e+01 - 8.99e-01 1.00e+00f 1\n", - " 3 -1.3154393e+01 7.33e+01 1.30e+02 -1.0 5.12e+02 - 1.88e-01 6.60e-01f 1\n", - " 4 -1.3147440e+01 1.67e+01 2.19e+00 -1.0 1.72e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.3148399e+01 1.18e+01 3.21e+01 -1.0 1.36e+02 - 1.00e+00 4.12e-01f 2\n", - " 6 -1.3145653e+01 1.23e+01 3.32e+00 -1.0 9.24e+01 - 8.74e-01 3.35e-01f 2\n", - " 7 -1.3143010e+01 3.67e+00 5.37e-01 -1.0 5.25e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.3144153e+01 4.52e-01 8.00e-02 -1.0 1.11e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 -1.3144153e+01 2.47e-04 1.12e-03 -1.7 3.87e-01 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.3144175e+01 1.50e-04 6.83e-04 -3.8 2.85e-01 - 1.00e+00 1.00e+00h 1\n", - " 11 -1.3144232e+01 1.07e-04 5.80e-05 -5.7 5.80e-01 -4.0 1.00e+00 1.00e+00h 1\n", - " 12 -1.3144447e+01 1.51e-03 7.27e-05 -5.7 2.18e+00 -4.5 1.00e+00 1.00e+00h 1\n", - " 13 -1.3144772e+01 4.00e-03 2.07e-04 -5.7 5.35e+00 -5.0 1.00e+00 6.14e-01h 1\n", - " 14 -1.3144770e+01 6.95e-04 3.62e-04 -5.7 1.73e-01 -5.4 1.00e+00 1.00e+00f 1\n", - " 15 -1.3144945e+01 6.78e-03 3.62e-05 -5.7 1.70e+00 -5.9 1.00e+00 1.00e+00h 1\n", - " 16 -1.3153640e+01 3.49e+01 9.15e-02 -5.7 2.83e+03 - 6.17e-02 6.37e-02h 1\n", - " 17 -1.3154824e+01 1.98e+01 3.84e-02 -5.7 8.27e+01 - 1.00e+00 5.97e-01f 1\n", - " 18 -1.3154428e+01 6.27e-01 2.75e-03 -5.7 1.22e+01 - 1.00e+00 1.00e+00f 1\n", - "Reallocating memory for MA57: lfact (319597)\n", - " 19 -1.3154555e+01 6.10e-02 9.67e-05 -5.7 8.95e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.3154553e+01 3.35e-04 1.10e-06 -5.7 5.85e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.3154553e+01 1.64e-08 9.42e-11 -5.7 3.56e-03 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.3155149e+01 8.44e-01 1.54e-03 -8.6 2.87e+01 - 8.65e-01 9.44e-01h 1\n", - "Reallocating memory for MA57: lfact (350471)\n", - " 23 -1.3155196e+01 1.92e-02 2.59e-04 -8.6 1.21e+01 - 9.82e-01 1.00e+00h 1\n", - " 24 -1.3155201e+01 5.02e-03 6.53e-05 -8.6 6.33e+00 - 1.00e+00 1.00e+00h 1\n", - " 25 -1.3155202e+01 3.50e-04 5.41e-06 -8.6 1.69e+00 - 1.00e+00 1.00e+00h 1\n", - " 26 -1.3155202e+01 1.38e-06 3.84e-08 -8.6 1.06e-01 - 1.00e+00 1.00e+00h 1\n", - " 27 -1.3155202e+01 3.71e-11 2.10e-12 -8.6 5.52e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 27\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.3155202417249349e+01 -1.3155202417249349e+01\n", - "Dual infeasibility......: 2.0969252789257937e-12 2.0969252789257937e-12\n", - "Constraint violation....: 3.7140956976600137e-11 3.7140956976600137e-11\n", - "Complementarity.........: 2.5059043930329935e-09 2.5059043930329935e-09\n", - "Overall NLP error.......: 2.5059043930329935e-09 2.5059043930329935e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 34\n", - "Number of objective gradient evaluations = 28\n", - "Number of equality constraint evaluations = 34\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 28\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 27\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 1.008\n", - "Total CPU secs in NLP function evaluations = 0.042\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26094\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7086\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7086\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.40e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (299488)\n", - " 1 0.0000000e+00 4.43e+00 3.85e+02 -1.0 6.34e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 5.03e-02 3.85e+00 -1.0 4.73e+00 - 9.90e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 4.97e-04 4.39e+00 -1.0 5.33e-02 - 1.00e+00 9.90e-01h 1\n", - " 4 0.0000000e+00 5.83e-11 1.02e-06 -1.0 5.27e-04 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 5.8342664033261826e-11 5.8342664033261826e-11\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 5.8342664033261826e-11 5.8342664033261826e-11\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.133\n", - "Total CPU secs in NLP function evaluations = 0.006\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26208\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (275736)\n", - "Total number of variables............................: 7106\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7096\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 2.9907566e-03 1.25e+00 8.80e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303702)\n", - " 1 2.4709143e-03 1.56e-01 1.03e+00 -1.0 5.94e-01 - 9.79e-01 8.75e-01h 1\n", - " 2 2.8475281e-03 3.48e-02 1.13e+01 -1.0 6.05e+00 - 8.35e-01 1.00e+00f 1\n", - " 3 -7.4086018e-04 1.25e+01 5.75e+01 -1.0 1.80e+02 - 1.92e-01 7.11e-01f 1\n", - " 4 6.6826430e-03 7.12e-01 2.47e+00 -1.0 2.67e+01 - 1.00e+00 1.00e+00f 1\n", - " 5 5.0030420e-03 5.85e-01 4.74e+01 -1.0 3.45e+02 - 4.79e-01 8.93e-02f 2\n", - " 6 9.6602861e-03 1.37e-01 6.09e+00 -1.0 2.40e+01 -4.0 8.23e-01 1.00e+00F 1\n", - " 7 8.8703660e-03 4.34e-01 2.96e-01 -1.0 5.49e+01 - 1.00e+00 1.00e+00h 1\n", - " 8 9.2713861e-03 3.83e-02 5.78e-02 -1.7 1.67e+01 - 1.00e+00 1.00e+00h 1\n", - " 9 9.2556032e-03 5.47e-03 4.05e-03 -2.5 6.40e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 9.1083712e-03 5.20e-04 3.49e-04 -3.8 1.06e+00 - 1.00e+00 1.00e+00h 1\n", - " 11 6.5758713e-03 1.85e-01 2.04e-02 -5.7 1.97e+01 - 8.02e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319911)\n", - " 12 2.2595047e-03 9.80e-01 1.09e-02 -5.7 5.56e+01 - 8.79e-01 1.00e+00h 1\n", - " 13 -8.3311568e-04 8.21e-01 2.27e-02 -5.7 3.29e+01 - 9.59e-01 1.00e+00h 1\n", - " 14 -9.6435386e-05 1.08e-02 4.25e-04 -5.7 8.07e-01 -4.5 1.00e+00 1.00e+00h 1\n", - " 15 -1.2586985e-04 6.29e-07 1.66e-07 -5.7 1.19e-02 -5.0 1.00e+00 1.00e+00h 1\n", - " 16 -7.5509198e-04 4.26e-01 2.13e-02 -8.6 1.63e+02 - 3.64e-01 2.39e-01h 1\n", - " 17 -1.7704572e-03 1.04e-01 2.48e-03 -8.6 2.75e+01 - 8.25e-01 1.00e+00h 1\n", - " 18 -1.5994877e-03 1.71e-02 2.40e-04 -8.6 1.15e+01 - 9.87e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (351858)\n", - " 19 -1.6003069e-03 2.49e-03 1.75e-05 -8.6 4.48e+00 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.6005224e-03 5.64e-05 4.27e-07 -8.6 6.79e-01 - 1.00e+00 1.00e+00h 1\n", - " 21 -1.6005305e-03 2.71e-08 2.85e-10 -8.6 1.49e-02 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.6005305e-03 2.86e-13 2.91e-14 -8.6 7.06e-06 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 22\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.6005305371233902e-03 -1.6005305371233902e-03\n", - "Dual infeasibility......: 2.9139664390433465e-14 2.9139664390433465e-14\n", - "Constraint violation....: 1.1865809618004581e-13 2.8599345114344032e-13\n", - "Complementarity.........: 2.5059035600370655e-09 2.5059035600370655e-09\n", - "Overall NLP error.......: 2.5059035600370655e-09 2.5059035600370655e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 27\n", - "Number of objective gradient evaluations = 23\n", - "Number of equality constraint evaluations = 27\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 23\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 22\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.929\n", - "Total CPU secs in NLP function evaluations = 0.041\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.8 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.22e-03 5.77e-01 -1.0 1.85e-01 - 9.91e-01 9.92e-01h 1\n", - " 4 0.0000000e+00 1.67e-09 1.36e-06 -1.0 1.54e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.6695191895621520e-09 1.6695191895621520e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.6695191895621520e-09 1.6695191895621520e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.104\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.2 seconds\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 6.90e+01 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.28e+00 3.85e+02 -1.0 6.90e+01 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.46e-01 3.07e+01 -1.0 5.88e+00 - 5.91e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 1.22e-03 5.77e-01 -1.0 1.85e-01 - 9.91e-01 9.92e-01h 1\n", - " 4 0.0000000e+00 1.67e-09 1.36e-06 -1.0 1.54e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 4\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 1.6694885474066723e-09 1.6694885474066723e-09\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 1.6694885474066723e-09 1.6694885474066723e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 5\n", - "Number of objective gradient evaluations = 5\n", - "Number of equality constraint evaluations = 5\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 5\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 4\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.105\n", - "Total CPU secs in NLP function evaluations = 0.004\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 1.1 seconds\n" - ] - } - ], - "source": [ - "D_sc = []\n", - "D_sc_2 = []\n", - "D_unsc = []\n", - "D_unsc_2 = []\n", - "exp_conds_sc = []\n", - "exp_conds_unsc = []\n", - "FIM_opt_sc = []\n", - "FIM_opt_sc_2 = []\n", - "FIM_opt_unsc = []\n", - "FIM_opt_unsc_2 = []\n", - "jac_opt_sc = []\n", - "jac_opt_sc_2 = []\n", - "jac_opt_unsc = []\n", - "jac_opt_unsc_2 = []\n", - "standard_Ca = 5\n", - "standard_T = [300, 300, 300, 300, 300, 300, 300, 300, 300, ]\n", - "\n", - "FIM_new = None\n", - "FIM_new_unsc = None\n", - "\n", - "FIM_running = np.zeros((4, 4))\n", - "FIM_running_unsc = np.zeros((4, 4))\n", - "\n", - "for i in range(20):\n", - " # Optimize experiment (scaled)\n", - " sc_res = run_optimal_exp(standard_Ca, standard_T, FIM_new, True)\n", - " # sc_res.result_analysis()\n", - " sc_exp = get_exp_conds(sc_res.model)\n", - " FIM_new = sc_res.FIM\n", - "\n", - " # Optimize experiment (unscaled)\n", - " unsc_res = run_optimal_exp(standard_Ca, standard_T, FIM_new_unsc, False)\n", - " # unsc_res.result_analysis()\n", - " unsc_exp = get_exp_conds(unsc_res.model)\n", - " FIM_new_unsc = unsc_res.FIM\n", - "\n", - " # Compute FIM in isolation (scaled)\n", - " res_sc = compute_specific_FIM(sc_exp[0], sc_exp[1:], prior_FIM=None, scale_param=True)\n", - "\n", - " # Compute FIM in isolation (unscaled)\n", - " res_unsc = compute_specific_FIM(unsc_exp[0], unsc_exp[1:], prior_FIM=None, scale_param=False)\n", - "\n", - " # Computing running isolation FIM\n", - " FIM_running += res_sc.FIM\n", - " FIM_running_unsc += res_unsc.FIM\n", - "\n", - " # Compute objectives (D-optimality)\n", - " D_sc.append(np.log10(np.linalg.det(sc_res.FIM)))\n", - " D_sc_2.append(np.log10(np.linalg.det(FIM_running)))\n", - " D_unsc.append(np.log10(np.linalg.det(unsc_res.FIM)))\n", - " D_unsc_2.append(np.log10(np.linalg.det(FIM_running_unsc)))\n", - "\n", - " # Append experimental results\n", - " exp_conds_sc.append(sc_exp)\n", - " exp_conds_unsc.append(unsc_exp)\n", - "\n", - " # Append FIM information\n", - " FIM_opt_sc.append(FIM_new)\n", - " FIM_opt_sc_2.append(copy.deepcopy(FIM_running))\n", - " FIM_opt_unsc.append(FIM_new_unsc)\n", - " FIM_opt_unsc_2.append(copy.deepcopy(FIM_running_unsc))\n", - "\n", - " # Append jacobian information\n", - " jac_opt_sc.append(translate_jac(sc_res.jaco_information))\n", - " jac_opt_sc_2.append(translate_jac(res_sc.jaco_information))\n", - " jac_opt_unsc.append(translate_jac(unsc_res.jaco_information))\n", - " jac_opt_unsc_2.append(translate_jac(res_unsc.jaco_information))" - ] - }, - { - "cell_type": "markdown", - "id": "17763935-a215-4020-a6b4-9b4425bec1f2", - "metadata": {}, - "source": [ - "## Plotting the results" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "id": "4d9a37ac-1d7e-452a-ad55-e87191ff7d5c", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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woQJ7N69m59//plRo0axbNky+vfvzxtvvMEnn3zCM888Q2xsLFqtFr1eT7169fj111/x8PBg+/btvPDCC/j6+vL444+X+HrLlVJJYmJilOeee04JCgpS7O3tlfr16ytvv/22kpOTU+hxnTp1UgCTZeTIkSU6d0pKigIoKSkppbkEIYSoNFlZWcrx48eVrKwsw4a8dEX5kcpZ8tKLHXenTp2UsWPHFti+YMECxcXFxbg+dOhQJTAwUMnPzzduGzhwoDJo0CBFURTl999/V5ydnZXU1NQCdaWmpip2dnbKt99+W+y4PvzwQ6V169bG9SlTpijh4eHG9QYNGiiLFy82OWb69OlKZGSkoiiK8s033ygeHh63Pg9FUb766isFUA4cOFDsONq3b6+MGDHCZNvAgQOVBx980LgOKC+++KJJmYiICGXUqFGKohi+X82dd+jQoUrfvn2N6506dVLuv/9+43p+fr7i4OCgPPPMM8ZtcXFxCqDs2LHDYswvvfSSMmDAAIvnKakCv9u3Kcn3d6W14Jw4cQK9Xs8333xDw4YNOXr0KCNGjCAjI4PZs2cXeuyIESN45513jOtarba8wxVCCFHBmjVrhpWVlXHd19eXI0eOANCjRw8CAwOpX78+vXr1olevXvTv3x+tVktUVBQ5OTl069bNYt0///wzn376KdHR0aSnp5Ofn4+zs7PZshkZGURHRzN8+HBGjBhh3J6fn2/s1xIVFUVYWBj29vbG/ZGRkSW+5qioKF544QWTbffdd1+B20B31h0ZGXlXT2uFhYUZX1tZWeHh4UHz5s2N27y9vQFISEgwbvviiy+YP38+sbGxZGVlkZubW+onzspDpSU4N38hb6pfvz4nT57kq6++KjLB0Wq1+Pj4lHeIQghRfVhp4fH0yjt3MTk7O5OSklJge3JycoFOsDY2NibrKpUKvV4PGG4x7d+/n82bN/PXX3/x9ttvM3XqVPbs2YNGoyk0hh07dvDUU08xbdo0evbsiYuLC0uWLOGjjz4yWz493fC+fvvtt0RERJjsuz0Bq47Mvce3b1PduPV4831fsmQJr776Kh999BGRkZE4OTnx4YcfsmvXrooLupiqVCfjlJQU3N3diyz3448/4unpyT333MOkSZPIzCz8vnNOTg6pqakmixBC1CgqFVg7VM5Sgv43ISEh7N+/v8D2/fv307hx4xJd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/MLUqVN5//332bt3L76+vnz5ZeFJ4KVLl3jwwQdp27Ythw4d4quvvmLevHm8++67JuW+++47rK2t2b17N3PnzuXjjz/m//7v/wBYunQp9erV45133iEuLo64uDiL54uOjmbNmjWsXbuWn376iXnz5tGnTx8uXrzIli1b+OCDD3jrrbeMiSCAWq3m008/5dixY3z33Xf8/fffTJgwodDrqkrkFpUQQogKtXLlShwdHcnPzycnJwe1Ws3nn38OQE5ODu+//z4bNmwgMjISgPr16/Pvv//yzTff0KlTJ2JjY2nZsiVt2rQBDP1Qblq8eDFXr15lz549uLu7A9CwYUPj/vDwcMLDw43r06dPZ9myZaxYsYLRo0cXiPXff/9l9+7dJCQkYGdnB8Ds2bNZvnw5v/32Gy+88AJz5sxh+PDhDB8+HIB3332XDRs2FNqK8+WXX+Lv78/nn3+OSqWiSZMmXL58mYkTJ/L222+jVhvaH/z9/fnkk09QqVSEhIRw5MgRPvnkE0aMGIG7uztWVlY4OTnh4+NT6Huu1+uZP38+Tk5ONG3alC5dunDy5ElWr16NWq0mJCSEDz74gE2bNhEREQHAuHHjjMcHBQXx7rvv8uKLLxaZvFUVkuAIIYSoUF26dOGrr74iIyODTz75BGtrawYMGADAmTNnyMzMpEePHibH5Obm0rJlSwBGjRrFgAED2L9/Pw888AD9+vWjffv2ABw8eJCWLVsak5s7paenM3XqVFatWkVcXBz5+flkZWVZbME5dOgQ6enpeHh4mGzPysoiOjoagKioKF588UWT/ZGRkWzatMniexAVFUVkZKTxthLAfffdR3p6OhcvXiQgIACAe++916RMZGQkH330ETqdDisrK4v13ykoKAgnJyfjure3N1ZWVsZE6ua2hIQE4/qGDRuYMWMGJ06cIDU1lfz8fLKzs8nMzESr1Rb73JVFEhwhhBAVysHBwdiqMn/+fMLDw5k3bx7Dhw839vFYtWoVdevWNTnuZgtK7969OX/+PKtXr2b9+vV069aNl156idmzZxfZufbVV19l/fr1zJ49m4YNG6LRaHjsscfIzc01Wz49PR1fX182b95cYF9VfkT6TjY2NibrN59iu3PbzVt5586d46GHHmLUqFG89957uLu78++//zJ8+HByc3OrRYIjfXCEEEJUGrVazRtvvMFbb71F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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Rescaling the scaled results\n", - "D_rescaled = []\n", - "param_vals = np.array([[85, 370, 8, 15], ])\n", - "for i in range(20):\n", - " resc_FIM = rescale_FIM(FIM_opt_sc_2[i], param_vals)\n", - " D_rescaled.append(np.log10(np.linalg.det(resc_FIM)))\n", - "\n", - "plt.plot(range(20), D_sc, color='green', ls='-', label='Scaled, optimal')\n", - "plt.scatter(range(20), D_sc_2, color='green', label='Scaled, compute')\n", - "plt.plot(range(20), D_unsc, color='orange', ls='-', label='Unscaled, optimal')\n", - "plt.scatter(range(20), D_unsc_2, color='orange', ls='--', label='Unscaled, compute')\n", - "plt.plot(range(20), D_rescaled, color='purple', ls=':', lw=5, label='Rescaled optimal')\n", - "\n", - "plt.legend()\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.14" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From de535f49306158d7d5c52ba6e5fe9ebb72a7c997 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 13:56:31 -0400 Subject: [PATCH 069/203] Delete pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py Removing old file --- .../doe/examples/reactor_optimize_doe_DJL.py | 180 ------------------ 1 file changed, 180 deletions(-) delete mode 100644 pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py diff --git a/pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py b/pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py deleted file mode 100644 index 719983069f0..00000000000 --- a/pyomo/contrib/doe/examples/reactor_optimize_doe_DJL.py +++ /dev/null @@ -1,180 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - -from pyomo.common.dependencies import numpy as np -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure -from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables -import pyomo.environ as aml - -def get_exp_results(m): - vals = [aml.value(m.CA0[0]), ] - for i in [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]: - vals.append(aml.value(m.T[i])) - return vals - - -def get_FIM_from_exp(CA_0=None, T_0=None, prior=None): - if CA_0 is None: - CA_0 = 5 - if T_0 is None: - T_0 = [570, 300, 300, 300, 300, 300, 300, 300, 300] - ### Define inputs - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # Define parameter nominal value - parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} - - # measurement object - measurements = MeasurementVariables() - measurements.add_variables( - "C", # name of measurement - indices={0: ["CA", "CB", "CC"], 1: t_control}, # indices of measurement - time_index_position=1, - ) # position of time index - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - exp_design.add_variables( - "CA0", # name of design variable - indices={0: [0]}, # indices of design variable - time_index_position=0, # position of time index - values=[CA_0], # nominal value of design variable - lower_bounds=1, # lower bound of design variable - upper_bounds=5, # upper bound of design variable - ) - - # add T as design variable - exp_design.add_variables( - "T", # name of design variable - indices={0: t_control}, # indices of design variable - time_index_position=0, # position of time index - values=list(T_0), # nominal value of design variable - lower_bounds=300, # lower bound of design variable - upper_bounds=700, # upper bound of design variable - ) - - doe_object2 = DesignOfExperiments( - parameter_dict, # dictionary of parameters - exp_design, # design variables - measurements, # measurement variables - create_model, # function to create model - prior_FIM=prior, - discretize_model=disc_for_measure, # function to discretize model - ) - - result = doe_object2.compute_FIM( - mode='sequential_finite', - formula = 'central', - ) - - result.result_analysis() - - return result.FIM - - -def main(CA_0=None, T_0=None, prior=None): - if CA_0 is None: - CA_0 = 5 - if T_0 is None: - T_0 = [570, 300, 300, 300, 300, 300, 300, 300, 300] - ### Define inputs - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # Define parameter nominal value - parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} - - # measurement object - measurements = MeasurementVariables() - measurements.add_variables( - "C", # name of measurement - indices={0: ["CA", "CB", "CC"], 1: t_control}, # indices of measurement - time_index_position=1, - ) # position of time index - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - exp_design.add_variables( - "CA0", # name of design variable - indices={0: [0]}, # indices of design variable - time_index_position=0, # position of time index - values=[CA_0], # nominal value of design variable - lower_bounds=1, # lower bound of design variable - upper_bounds=5, # upper bound of design variable - ) - - # add T as design variable - exp_design.add_variables( - "T", # name of design variable - indices={0: t_control}, # indices of design variable - time_index_position=0, # position of time index - values=list(T_0), # nominal value of design variable - lower_bounds=300, # lower bound of design variable - upper_bounds=700, # upper bound of design variable - ) - - design_names = exp_design.variable_names - # exp1 = [5, 570, 300, 300, 300, 300, 300, 300, 300, 300] - # exp1_design_dict = dict(zip(design_names, exp1)) - # exp_design.update_values(exp1_design_dict) - - # add a prior information (scaled FIM with T=500 and T=300 experiments) - if prior is None: - prior = np.asarray( - [ - [28.67892806, 5.41249739, -81.73674601, -24.02377324], - [5.41249739, 26.40935036, -12.41816477, -139.23992532], - [-81.73674601, -12.41816477, 240.46276004, 58.76422806], - [-24.02377324, -139.23992532, 58.76422806, 767.25584508], - ] - ) - - doe_object2 = DesignOfExperiments( - parameter_dict, # dictionary of parameters - exp_design, # design variables - measurements, # measurement variables - create_model, # function to create model - prior_FIM=prior, # prior information - discretize_model=disc_for_measure, # function to discretize model - ) - - square_result, optimize_result = doe_object2.stochastic_program( - if_optimize=True, # if optimize - if_Cholesky=True, # if use Cholesky decomposition - # scale_nominal_param_value=True, # if scale nominal parameter value - objective_option="det", # objective option - L_initial=np.linalg.cholesky(prior), # initial Cholesky decomposition - ) - - return prior, optimize_result, square_result - - -if __name__ == "__main__": - main() From c8ef2dd2e4d3cd0e1cfca006b64af9031857cf27 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 12 Jul 2024 14:16:29 -0400 Subject: [PATCH 070/203] Ran Black --- .../doe/tests/experiment_class_example.py | 59 +++++++++------- .../tests/experiment_class_example_flags.py | 68 +++++++++++-------- 2 files changed, 75 insertions(+), 52 deletions(-) diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index eae355ebc89..08d205df39b 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -4,6 +4,7 @@ import itertools import json + # ======================== @@ -59,12 +60,12 @@ def get_labeled_model(self): def create_model(self): """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. - Return - ------ - m: a Pyomo.DAE model + Return + ------ + m: a Pyomo.DAE model """ m = self.model = pyo.ConcreteModel() @@ -151,19 +152,19 @@ def finalize_model(self): m = self.model # Unpacking data before simulation - control_points = self.data['control_points'] + control_points = self.data["control_points"] - m.CA[0].value = self.data['CA0'] - m.CB[0].fix(self.data['CB0']) - m.t.update(self.data['t_range']) + m.CA[0].value = self.data["CA0"] + m.CB[0].fix(self.data["CB0"]) + m.t.update(self.data["t_range"]) m.t.update(control_points) - m.A1.fix(self.data['A1']) - m.A2.fix(self.data['A2']) - m.E1.fix(self.data['E1']) - m.E2.fix(self.data['E2']) + m.A1.fix(self.data["A1"]) + m.A2.fix(self.data["A2"]) + m.E1.fix(self.data["E1"]) + m.E2.fix(self.data["E2"]) - m.CA[0].setlb(self.data['CA_bounds'][0]) - m.CA[0].setub(self.data['CA_bounds'][1]) + m.CA[0].setlb(self.data["CA_bounds"][0]) + m.CA[0].setub(self.data["CA_bounds"][1]) m.t_control = control_points @@ -176,8 +177,8 @@ def finalize_model(self): for t in m.t: if t in control_points: cv = control_points[t] - m.T[t].setlb(self.data['T_bounds'][0]) - m.T[t].setub(self.data['T_bounds'][1]) + m.T[t].setlb(self.data["T_bounds"][0]) + m.T[t].setub(self.data["T_bounds"][1]) m.T[t] = cv @m.Constraint(m.t - control_points) @@ -190,7 +191,6 @@ def T_control(m, t): # sim.initialize_model() - def label_experiment_impl(self, index_sets_meas): """ Example for annotating (labeling) the model with a @@ -207,13 +207,19 @@ def label_experiment_impl(self, index_sets_meas): m.experiment_outputs = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - + m.experiment_outputs.update( + (k, None) + for k in expand_model_components(m, base_comp_meas, index_sets_meas) + ) + # Adding no error for measurements currently m.measurement_error = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + m.measurement_error.update( + (k, 1e-2) + for k in expand_model_components(m, base_comp_meas, index_sets_meas) + ) # Grab design variables base_comp_des = [m.CA, m.T] @@ -221,8 +227,11 @@ def label_experiment_impl(self, index_sets_meas): m.experiment_inputs = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) - + m.experiment_inputs.update( + (k, pyo.ComponentUID(k)) + for k in expand_model_components(m, base_comp_des, index_sets_des) + ) + m.unknown_parameters = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) @@ -246,4 +255,6 @@ def label_experiment(self): """ m = self.model - return self.label_experiment_impl([[m.t_control], [[m.t.last()]], [[m.t.last()]]]) + return self.label_experiment_impl( + [[m.t_control], [[m.t.last()]], [[m.t.last()]]] + ) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 4b217ef691a..0e4ee7c816f 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -4,6 +4,7 @@ import itertools import json + # ======================== @@ -64,12 +65,12 @@ def get_labeled_model(self, flag=0): def create_model(self): """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. - Return - ------ - m: a Pyomo.DAE model + Return + ------ + m: a Pyomo.DAE model """ m = self.model = pyo.ConcreteModel() @@ -156,19 +157,19 @@ def finalize_model(self): m = self.model # Unpacking data before simulation - control_points = self.data['control_points'] + control_points = self.data["control_points"] - m.CA[0].value = self.data['CA0'] - m.CB[0].fix(self.data['CB0']) - m.t.update(self.data['t_range']) + m.CA[0].value = self.data["CA0"] + m.CB[0].fix(self.data["CB0"]) + m.t.update(self.data["t_range"]) m.t.update(control_points) - m.A1.fix(self.data['A1']) - m.A2.fix(self.data['A2']) - m.E1.fix(self.data['E1']) - m.E2.fix(self.data['E2']) + m.A1.fix(self.data["A1"]) + m.A2.fix(self.data["A2"]) + m.E1.fix(self.data["E1"]) + m.E2.fix(self.data["E2"]) - m.CA[0].setlb(self.data['CA_bounds'][0]) - m.CA[0].setub(self.data['CA_bounds'][1]) + m.CA[0].setlb(self.data["CA_bounds"][0]) + m.CA[0].setub(self.data["CA_bounds"][1]) m.t_control = control_points @@ -181,8 +182,8 @@ def finalize_model(self): for t in m.t: if t in control_points: cv = control_points[t] - m.T[t].setlb(self.data['T_bounds'][0]) - m.T[t].setub(self.data['T_bounds'][1]) + m.T[t].setlb(self.data["T_bounds"][0]) + m.T[t].setub(self.data["T_bounds"][1]) m.T[t] = cv @m.Constraint(m.t - control_points) @@ -195,7 +196,6 @@ def T_control(m, t): # sim.initialize_model() - def label_experiment_impl(self, index_sets_meas, flag=0): """ Example for annotating (labeling) the model with a @@ -213,17 +213,23 @@ def label_experiment_impl(self, index_sets_meas, flag=0): m.experiment_outputs = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - m.experiment_outputs.update((k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) - + m.experiment_outputs.update( + (k, None) + for k in expand_model_components(m, base_comp_meas, index_sets_meas) + ) + if flag != 2: # Adding no error for measurements currently m.measurement_error = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + direction=pyo.Suffix.LOCAL, + ) if flag == 5: m.measurement_error.update((m.CA[0], 1e-2) for k in range(1)) else: - m.measurement_error.update((k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas)) + m.measurement_error.update( + (k, 1e-2) + for k in expand_model_components(m, base_comp_meas, index_sets_meas) + ) if flag != 3: # Grab design variables @@ -232,17 +238,23 @@ def label_experiment_impl(self, index_sets_meas, flag=0): m.experiment_inputs = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - m.experiment_inputs.update((k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des)) - + m.experiment_inputs.update( + (k, pyo.ComponentUID(k)) + for k in expand_model_components(m, base_comp_des, index_sets_des) + ) + if flag != 4: m.unknown_parameters = pyo.Suffix( direction=pyo.Suffix.LOCAL, ) - m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) + m.unknown_parameters.update( + (k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2] + ) class FullReactorExperiment(ReactorExperiment): def label_experiment(self, flag=0): m = self.model - return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]], flag=flag) - + return self.label_experiment_impl( + [[m.t_control], [m.t_control], [m.t_control]], flag=flag + ) From 5c89e4a89eabf757aa4e0045b01287df7c67bbd0 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 15 Jul 2024 08:24:56 -0600 Subject: [PATCH 071/203] Ran Black with correct command with flags --- pyomo/contrib/doe/doe.py | 29 +++++------------- .../doe/tests/experiment_class_example.py | 16 +++------- .../tests/experiment_class_example_flags.py | 16 +++------- pyomo/contrib/doe/tests/test_doe_build.py | 8 ++--- pyomo/contrib/doe/tests/test_doe_errors.py | 30 ++++--------------- pyomo/contrib/doe/tests/test_doe_solve.py | 29 +++++------------- pyomo/contrib/doe/utils.py | 12 ++------ 7 files changed, 32 insertions(+), 108 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index d8f773879ee..403d0c8cd4c 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -237,10 +237,7 @@ def run_doe(self, model=None, results_file=None): """ # Check results file name if results_file is not None: - if type(results_file) not in [ - Path, - str, - ]: + if type(results_file) not in [Path, str]: raise ValueError( "``results_file`` must be either a Path object or a string." ) @@ -457,9 +454,7 @@ def _sequential_FIM(self, model=None): # Create suffix to keep track of parameter scenarios if hasattr(model, "parameter_scenarios"): model.del_component(model.parameter_scenarios) - model.parameter_scenarios = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + model.parameter_scenarios = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Populate parameter scenarios, and scenario inds based on finite difference scheme if self.fd_formula == FiniteDifferenceStep.central: @@ -752,9 +747,7 @@ def initialize_jac(m, i, j): return 0.1 model.sensitivity_jacobian = pyo.Var( - model.output_names, - model.parameter_names, - initialize=initialize_jac, + model.output_names, model.parameter_names, initialize=initialize_jac ) # Initialize the FIM @@ -770,15 +763,11 @@ def initialize_fim(m, j, d): if self.fim_initial is not None: model.fim = pyo.Var( - model.parameter_names, - model.parameter_names, - initialize=initialize_fim, + model.parameter_names, model.parameter_names, initialize=initialize_fim ) else: model.fim = pyo.Var( - model.parameter_names, - model.parameter_names, - initialize=identity_matrix, + model.parameter_names, model.parameter_names, initialize=identity_matrix ) # To-Do: Look into this functionality..... @@ -801,9 +790,7 @@ def init_cho(m, i, j): # Initialize with L in L_initial if self.L_initial is not None: model.L = pyo.Var( - model.parameter_names, - model.parameter_names, - initialize=init_cho, + model.parameter_names, model.parameter_names, initialize=init_cho ) # or initialize with the identity matrix else: @@ -993,9 +980,7 @@ def _generate_scenario_blocks(self, model=None): self.jac_initial = np.eye(self.n_experiment_outputs, self.n_parameters) # Make a new Suffix to hold which scenarios are associated with parameters - model.parameter_scenarios = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + model.parameter_scenarios = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Populate parameter scenarios, and scenario inds based on finite difference scheme if self.fd_formula == FiniteDifferenceStep.central: diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index 08d205df39b..56fdda6a4a9 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -204,18 +204,14 @@ def label_experiment_impl(self, index_sets_meas): # Grab measurement labels base_comp_meas = [m.CA, m.CB, m.CC] - m.experiment_outputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.experiment_outputs.update( (k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas) ) # Adding no error for measurements currently - m.measurement_error = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.measurement_error.update( (k, 1e-2) for k in expand_model_components(m, base_comp_meas, index_sets_meas) @@ -224,17 +220,13 @@ def label_experiment_impl(self, index_sets_meas): # Grab design variables base_comp_des = [m.CA, m.T] index_sets_des = [[[m.t.first()]], [m.t_control]] - m.experiment_inputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.experiment_inputs.update( (k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des) ) - m.unknown_parameters = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 0e4ee7c816f..9b89d19d759 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -210,9 +210,7 @@ def label_experiment_impl(self, index_sets_meas, flag=0): if flag != 1: # Grab measurement labels - m.experiment_outputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.experiment_outputs.update( (k, None) for k in expand_model_components(m, base_comp_meas, index_sets_meas) @@ -220,9 +218,7 @@ def label_experiment_impl(self, index_sets_meas, flag=0): if flag != 2: # Adding no error for measurements currently - m.measurement_error = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) if flag == 5: m.measurement_error.update((m.CA[0], 1e-2) for k in range(1)) else: @@ -235,18 +231,14 @@ def label_experiment_impl(self, index_sets_meas, flag=0): # Grab design variables base_comp_des = [m.CA, m.T] index_sets_des = [[[m.t.first()]], [m.t_control]] - m.experiment_inputs = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.experiment_inputs.update( (k, pyo.ComponentUID(k)) for k in expand_model_components(m, base_comp_des, index_sets_des) ) if flag != 4: - m.unknown_parameters = pyo.Suffix( - direction=pyo.Suffix.LOCAL, - ) + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.unknown_parameters.update( (k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2] ) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 9365b289399..065b8cce711 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -25,9 +25,7 @@ data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} -def get_FIM_FIMPrior_Q_L( - doe_obj=None, -): +def get_FIM_FIMPrior_Q_L(doe_obj=None): """ Helper function to retreive results to compare. @@ -62,9 +60,7 @@ def get_FIM_FIMPrior_Q_L( ] sigma_inv = [1 / v for k, v in model.scenario_blocks[0].measurement_error.items()] param_vals = np.array( - [ - [v for k, v in model.scenario_blocks[0].unknown_parameters.items()], - ] + [[v for k, v in model.scenario_blocks[0].unknown_parameters.items()]] ) FIM_vals_np = np.array(FIM_vals).reshape((n_param, n_param)) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 4074415c9fd..9977bffe94e 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -395,10 +395,7 @@ def test_reactor_grid_search_des_range_inputs(self): _only_compute_fim_lower=True, ) - design_ranges = { - "not": [1, 5, 3], - "correct": [300, 700, 3], - } + design_ranges = {"not": [1, 5, 3], "correct": [300, 700, 3]} with self.assertRaisesRegex( ValueError, @@ -470,10 +467,7 @@ def test_reactor_figure_drawing_no_des_var_names(self): _only_compute_fim_lower=True, ) - design_ranges = { - "CA[0]": [1, 5, 2], - "T[0]": [300, 700, 2], - } + design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} doe_obj.compute_FIM_full_factorial( design_ranges=design_ranges, method="sequential" @@ -513,10 +507,7 @@ def test_reactor_figure_drawing_no_sens_names(self): _only_compute_fim_lower=True, ) - design_ranges = { - "CA[0]": [1, 5, 2], - "T[0]": [300, 700, 2], - } + design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} doe_obj.compute_FIM_full_factorial( design_ranges=design_ranges, method="sequential" @@ -555,10 +546,7 @@ def test_reactor_figure_drawing_no_fixed_names(self): _only_compute_fim_lower=True, ) - design_ranges = { - "CA[0]": [1, 5, 2], - "T[0]": [300, 700, 2], - } + design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} doe_obj.compute_FIM_full_factorial( design_ranges=design_ranges, method="sequential" @@ -597,10 +585,7 @@ def test_reactor_figure_drawing_bad_fixed_names(self): _only_compute_fim_lower=True, ) - design_ranges = { - "CA[0]": [1, 5, 2], - "T[0]": [300, 700, 2], - } + design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} doe_obj.compute_FIM_full_factorial( design_ranges=design_ranges, method="sequential" @@ -643,10 +628,7 @@ def test_reactor_figure_drawing_bad_sens_names(self): _only_compute_fim_lower=True, ) - design_ranges = { - "CA[0]": [1, 5, 2], - "T[0]": [300, 700, 2], - } + design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} doe_obj.compute_FIM_full_factorial( design_ranges=design_ranges, method="sequential" diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 5577a56f055..5ac2c879a42 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -25,9 +25,7 @@ data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} -def get_FIM_Q_L( - doe_obj=None, -): +def get_FIM_Q_L(doe_obj=None): """ Helper function to retreive results to compare. @@ -57,9 +55,7 @@ def get_FIM_Q_L( ] sigma_inv = [1 / v for k, v in model.scenario_blocks[0].measurement_error.items()] param_vals = np.array( - [ - [v for k, v in model.scenario_blocks[0].unknown_parameters.items()], - ] + [[v for k, v in model.scenario_blocks[0].unknown_parameters.items()]] ) FIM_vals_np = np.array(FIM_vals).reshape((n_param, n_param)) @@ -114,9 +110,7 @@ def test_reactor_fd_central_solve(self): assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L( - doe_obj=doe_obj, - ) + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L @@ -155,9 +149,7 @@ def test_reactor_fd_forward_solve(self): assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L( - doe_obj=doe_obj, - ) + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L @@ -196,9 +188,7 @@ def test_reactor_fd_backward_solve(self): assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L( - doe_obj=doe_obj, - ) + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L @@ -270,9 +260,7 @@ def test_reactor_obj_cholesky_solve(self): assert doe_obj.results["Solver Status"] == "ok" # Assert that Q, F, and L are the same. - FIM, Q, L, sigma_inv = get_FIM_Q_L( - doe_obj=doe_obj, - ) + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Cholesky is used, there is comparison for FIM and L.T @ L assert np.all(np.isclose(FIM, L @ L.T)) @@ -337,10 +325,7 @@ def test_reactor_grid_search(self): _only_compute_fim_lower=True, ) - design_ranges = { - "CA[0]": [1, 5, 3], - "T[0]": [300, 700, 3], - } + design_ranges = {"CA[0]": [1, 5, 3], "T[0]": [300, 700, 3]} doe_obj.compute_FIM_full_factorial( design_ranges=design_ranges, method="sequential" diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py index ed0569e461f..cb00dfcd67f 100644 --- a/pyomo/contrib/doe/utils.py +++ b/pyomo/contrib/doe/utils.py @@ -43,11 +43,7 @@ def rescale_FIM(FIM, param_vals): """ if isinstance(param_vals, list): - param_vals = np.array( - [ - param_vals, - ] - ) + param_vals = np.array([param_vals]) elif isinstance(param_vals, np.ndarray): if len(param_vals.shape) > 2 or ( (len(param_vals.shape) == 2) and (param_vals.shape[0] != 1) @@ -58,11 +54,7 @@ def rescale_FIM(FIM, param_vals): ) ) if len(param_vals.shape) == 1: - param_vals = np.array( - [ - param_vals, - ] - ) + param_vals = np.array([param_vals]) scaling_mat = (1 / param_vals).transpose().dot((1 / param_vals)) scaled_FIM = np.multiply(FIM, scaling_mat) return scaled_FIM From 8bbf084207d57efaaa6817d265a6c436b1aa2379 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 15 Jul 2024 08:32:43 -0600 Subject: [PATCH 072/203] Fixed typos --- pyomo/contrib/doe/doe.py | 20 ++++++++++---------- pyomo/contrib/doe/tests/test_doe_build.py | 2 +- pyomo/contrib/doe/tests/test_doe_solve.py | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 403d0c8cd4c..1a83598c1f5 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -104,7 +104,7 @@ def __init__( should have a ``get_labeled_model`` where a model is returned with the following labeled sets: ``unknown_parameters``, ``experimental_inputs``, ``experimental_outputs`` fd_formula: - Finite difference formula for computing the sensitivy matrix. Must be one of + Finite difference formula for computing the sensitivity matrix. Must be one of [``central``, ``forward``, ``backward``], default: ``central`` step: Relative step size for the finite difference formula. @@ -120,7 +120,7 @@ def __init__( scale_nominal_param_value: Boolean for whether or not to scale the sensitivity matrix by the nominal parameter values. Every column of the sensitivity matrix will be divided by the respective - nominal paramter value. + nominal parameter value. default: False prior_FIM: 2D numpy array representing information from prior experiments. If no value is given, @@ -262,7 +262,7 @@ def run_doe(self, model=None, results_file=None): # Track time required to build the DoE model build_time = sp_timer.toc(msg=None) self.logger.info( - "Succesfully built the DoE model.\nBuild time: %0.1f seconds" % build_time + "Successfully built the DoE model.\nBuild time: %0.1f seconds" % build_time ) # Solve the square problem first to initialize the fim and @@ -279,7 +279,7 @@ def run_doe(self, model=None, results_file=None): # Track time to initialize the DoE model initialization_time = sp_timer.toc(msg=None) self.logger.info( - "Succesfully initialized the DoE model.\nInitialization time: %0.1f seconds" + "Successfully initialized the DoE model.\nInitialization time: %0.1f seconds" % initialization_time ) @@ -316,7 +316,7 @@ def run_doe(self, model=None, results_file=None): solve_time = sp_timer.toc(msg=None) self.logger.info( - "Succesfully optimized experiment.\nSolve time: %0.1f seconds" % solve_time + "Successfully optimized experiment.\nSolve time: %0.1f seconds" % solve_time ) self.logger.info( "Total time for build, initialization, and solve: %0.1f seconds" @@ -371,13 +371,13 @@ def run_doe(self, model=None, results_file=None): # Perform multi-experiment doe (sequential, or ``greedy`` approach) def run_multi_doe_sequential(self, N_exp=1): raise NotImplementedError( - "Multipled experiment optimization not yet supported." + "Multiple experiment optimization not yet supported." ) # Perform multi-experiment doe (simultaneous, optimal approach) def run_multi_doe_simultaneous(self, N_exp=1): raise NotImplementedError( - "Multipled experiment optimization not yet supported." + "Multiple experiment optimization not yet supported." ) # Compute FIM for the DoE object @@ -1154,7 +1154,7 @@ def cholesky_imp(m, c, d): Calculate Cholesky L matrix using algebraic constraints """ # If the row is greater than or equal to the column, we are in the - # lower traingle region of the L and FIM matrices. + # lower triangle region of the L and FIM matrices. # This region is where our equations are well-defined. if list(model.parameter_names).index(c) >= list( model.parameter_names @@ -1363,7 +1363,7 @@ def update_FIM_prior(self, model=None, FIM=None): # ToDo: Add an update function for the parameter values? --> closed loop parameter estimation? # Or leave this to the user????? - def udpate_unknown_parameter_values(self, model=None, param_vals=None): + def update_unknown_parameter_values(self, model=None, param_vals=None): return # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) @@ -1391,7 +1391,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): self.factorial_model = self.experiment.get_labeled_model(**self.args).clone() model = self.factorial_model - # Permute the inputs to be aligned with the experiment input indicies + # Permute the inputs to be aligned with the experiment input indices design_ranges_enum = {k: np.linspace(*v) for k, v in design_ranges.items()} design_map = { ind: (k[0].name, k[0]) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 065b8cce711..cfadecb867c 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -27,7 +27,7 @@ def get_FIM_FIMPrior_Q_L(doe_obj=None): """ - Helper function to retreive results to compare. + Helper function to retrieve results to compare. """ model = doe_obj.model diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 5ac2c879a42..78abb857717 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -27,7 +27,7 @@ def get_FIM_Q_L(doe_obj=None): """ - Helper function to retreive results to compare. + Helper function to retrieve results to compare. """ model = doe_obj.model From 615329d448435796f534fb2bc3281cdb942bf99e Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 15 Jul 2024 08:35:05 -0600 Subject: [PATCH 073/203] Ran Black again --- pyomo/contrib/doe/doe.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 1a83598c1f5..ceed2fe422a 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -370,15 +370,11 @@ def run_doe(self, model=None, results_file=None): # Perform multi-experiment doe (sequential, or ``greedy`` approach) def run_multi_doe_sequential(self, N_exp=1): - raise NotImplementedError( - "Multiple experiment optimization not yet supported." - ) + raise NotImplementedError("Multiple experiment optimization not yet supported.") # Perform multi-experiment doe (simultaneous, optimal approach) def run_multi_doe_simultaneous(self, N_exp=1): - raise NotImplementedError( - "Multiple experiment optimization not yet supported." - ) + raise NotImplementedError("Multiple experiment optimization not yet supported.") # Compute FIM for the DoE object def compute_FIM(self, model=None, method="sequential"): From 5c82a5741ed0e9cb6fdd121f0c510838365b0131 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 15 Jul 2024 08:37:33 -0600 Subject: [PATCH 074/203] Fixed another typo --- pyomo/contrib/doe/doe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index ceed2fe422a..01f4edd8603 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -114,7 +114,7 @@ def __init__( ``det`` (for determinant, or D-optimality) and ``trace`` (for trace or A-optimality) scale_constant_value: - Constant scaling for the sensitivty matrix. Every element will be multiplied by this + Constant scaling for the sensitivity matrix. Every element will be multiplied by this scaling factor. default: 1 scale_nominal_param_value: From d13f94bd9c7c462c7cfe898accc81ea76a930bd9 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 15 Jul 2024 09:26:47 -0600 Subject: [PATCH 075/203] Removing commented lines from example files --- pyomo/contrib/doe/tests/experiment_class_example.py | 5 ----- pyomo/contrib/doe/tests/experiment_class_example_flags.py | 5 ----- 2 files changed, 10 deletions(-) diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index 56fdda6a4a9..57bc7b424a1 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -73,11 +73,6 @@ def create_model(self): # Model parameters m.R = pyo.Param(mutable=False, initialize=8.314) - # m.A1 = pyo.Param(mutable=True) - # m.E1 = pyo.Param(mutable=True) - # m.A2 = pyo.Param(mutable=True) - # m.E2 = pyo.Param(mutable=True) - # Define model variables ######################## # time diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 9b89d19d759..0869dee1570 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -78,11 +78,6 @@ def create_model(self): # Model parameters m.R = pyo.Param(mutable=False, initialize=8.314) - # m.A1 = pyo.Param(mutable=True) - # m.E1 = pyo.Param(mutable=True) - # m.A2 = pyo.Param(mutable=True) - # m.E2 = pyo.Param(mutable=True) - # Define model variables ######################## # time From 0625cec5cdd62bf0aa24a9034eed65fee70f3809 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 15 Jul 2024 09:50:53 -0600 Subject: [PATCH 076/203] Added ipopt check for build, which initializes the model using ipopt --- pyomo/contrib/doe/tests/test_doe_build.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index cfadecb867c..db009f32742 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -83,6 +83,7 @@ def get_FIM_FIMPrior_Q_L(doe_obj=None): class TestReactorExampleBuild(unittest.TestCase): + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_check_fd_eqns(self): fd_method = "central" @@ -138,6 +139,7 @@ def test_reactor_fd_central_check_fd_eqns(self): assert np.isclose(param_val, param_val_from_step) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_check_fd_eqns(self): fd_method = "backward" @@ -195,6 +197,7 @@ def test_reactor_fd_backward_check_fd_eqns(self): other_param_val = pyo.value(k) assert np.isclose(other_param_val, v) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_check_fd_eqns(self): fd_method = "forward" @@ -252,6 +255,7 @@ def test_reactor_fd_forward_check_fd_eqns(self): other_param_val = pyo.value(k) assert np.isclose(other_param_val, v) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_design_fixing(self): fd_method = "central" @@ -302,6 +306,7 @@ def test_reactor_fd_central_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_design_fixing(self): fd_method = "backward" @@ -352,6 +357,7 @@ def test_reactor_fd_backward_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_design_fixing(self): fd_method = "forward" From 767006305f97062a360a69aba3f71686a0ae9ae2 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 09:20:43 -0600 Subject: [PATCH 077/203] Added test for rescale FIM function --- pyomo/contrib/doe/tests/test_doe_solve.py | 67 ++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 78abb857717..bf24815fe50 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -7,9 +7,10 @@ from pyomo.contrib.doe.tests.experiment_class_example import * from pyomo.contrib.doe import * - +from pyomo.contrib.doe.utils import * import pyomo.common.unittest as unittest +import pyomo.environ as pyo from pyomo.opt import SolverFactory @@ -344,6 +345,70 @@ def test_reactor_grid_search(self): set(T_vals).issuperset(set([300, 500, 700])) ) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_rescale_FIM(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + # With parameter scaling + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + # Without parameter scaling + doe_obj2 = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=False, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + # Run both problems + doe_obj.run_doe() + doe_obj2.run_doe() + + # Extract FIM values + FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) + FIM2, Q2, L2, sigma_inv2 = get_FIM_Q_L(doe_obj=doe_obj2) + + # Get rescaled FIM from the scaled version + param_vals = np.array([[v for k, v in doe_obj.model.scenario_blocks[0].unknown_parameters.items()], ]) + + resc_FIM = rescale_FIM(FIM, param_vals) + + # Compare scaled and rescaled values + assert np.all(np.isclose(FIM2, resc_FIM)) + if __name__ == "__main__": unittest.main() From 7ad1005381baac066315cd4083e96681f598df1f Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 09:29:56 -0600 Subject: [PATCH 078/203] Fixed bug and added test for compute FIM seq with back/forw --- pyomo/contrib/doe/doe.py | 12 +++-- pyomo/contrib/doe/tests/test_doe_solve.py | 60 ++++++++++++++++++++++- 2 files changed, 67 insertions(+), 5 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 01f4edd8603..476d1fffb71 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -482,8 +482,6 @@ def _sequential_FIM(self, model=None): # In a loop..... # Calculate measurement values for each scenario for s in model.scenarios: - param = model.parameter_scenarios[s] - # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: diff = self.step * ( @@ -502,8 +500,14 @@ def _sequential_FIM(self, model=None): diff = 0 pass - # Update parameter values for the given finite difference scenario - param.set_value(model.unknown_parameters[param] * (1 + diff)) + # If we are doing forward/backward, no change for s=0 + skip_param_update = (self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]) and (s == 0) + if not skip_param_update: + param = model.parameter_scenarios[s] + # Update parameter values for the given finite difference scenario + param.set_value(model.unknown_parameters[param] * (1 + diff)) + else: + continue # Simulate the model self.solver.solve(model) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index bf24815fe50..6667418b13b 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -271,7 +271,7 @@ def test_reactor_obj_cholesky_solve(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_compute_FIM_seq(self): + def test_compute_FIM_seq_centr(self): fd_method = "central" obj_used = "det" @@ -298,6 +298,64 @@ def test_compute_FIM_seq(self): doe_obj.compute_FIM(method="sequential") + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_compute_FIM_seq_forward(self): + fd_method = "forward" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.compute_FIM(method="sequential") + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_compute_FIM_seq_backward(self): + fd_method = "backward" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.compute_FIM(method="sequential") + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") From 2b645c70793eb71a2fb1946173babad70c357c3f Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 10:14:23 -0600 Subject: [PATCH 079/203] Adding test for model that is poorly posed --- pyomo/contrib/doe/doe.py | 20 +++-- .../tests/experiment_class_example_flags.py | 13 +++ pyomo/contrib/doe/tests/test_doe_solve.py | 84 +++++++++++++++++++ 3 files changed, 112 insertions(+), 5 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 476d1fffb71..5a25c065dfb 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -510,7 +510,13 @@ def _sequential_FIM(self, model=None): continue # Simulate the model - self.solver.solve(model) + try: + res = self.solver.solve(model) + assert (res.solver.termination_condition == "optimal") + except: + raise RuntimeError( + "Model from experiment did not solve appropriately. Make sure the model is well-posed." + ) # Extract the measurement values for the scenario and append measurement_vals.append( @@ -1014,7 +1020,8 @@ def _generate_scenario_blocks(self, model=None): comp.fix() try: - self.solver.solve(model.base_model, tee=self.tee) + res = self.solver.solve(model.base_model, tee=self.tee) + assert (res.solver.termination_condition == "optimal") self.logger.info("Model from experiment solved.") except: raise RuntimeError( @@ -1479,7 +1486,10 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): self.logger.warning("failed count:", failures) self._computed_FIM = np.zeros(self.prior_FIM.shape) - iter_timer.tic(msg=None) + + iter_t = iter_timer.toc(msg=None) + time_set.append(iter_t) + FIM = self._computed_FIM @@ -1494,9 +1504,9 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): "Eigenvalue has imaginary component greater than 1e-6, contact developers if this issue persists." ) - # If the real value is less than or equal to zero, set the E_opt value to np.NaN + # If the real value is less than or equal to zero, set the E_opt value to nan if E_vals.real[E_ind] <= 0: - E_opt = np.NaN + E_opt = np.nan else: E_opt = np.log10(E_vals.real[E_ind]) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 0869dee1570..4d060328d8f 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -245,3 +245,16 @@ def label_experiment(self, flag=0): return self.label_experiment_impl( [[m.t_control], [m.t_control], [m.t_control]], flag=flag ) + +class FullReactorExperimentBad(ReactorExperiment): + def label_experiment(self, flag=0): + m = self.model + + self.label_experiment_impl( + [[m.t_control], [m.t_control], [m.t_control]], flag=flag + ) + + m.bad_con_1 = pyo.Constraint(expr=m.CA[0] >= 1.0) + m.bad_con_2 = pyo.Constraint(expr=m.CA[0] <= 0.0) + + return m \ No newline at end of file diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 6667418b13b..132df056822 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -6,6 +6,7 @@ ) from pyomo.contrib.doe.tests.experiment_class_example import * +from pyomo.contrib.doe.tests.experiment_class_example_flags import FullReactorExperimentBad from pyomo.contrib.doe import * from pyomo.contrib.doe.utils import * @@ -16,6 +17,8 @@ from pathlib import Path +import logging + ipopt_available = SolverFactory("ipopt").available() DATA_DIR = Path(__file__).parent @@ -467,6 +470,87 @@ def test_rescale_FIM(self): # Compare scaled and rescaled values assert np.all(np.isclose(FIM2, resc_FIM)) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_solve_bad_model(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperimentBad(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, + "Model from experiment did not solve appropriately. Make sure the model is well-posed.", + ): + doe_obj.run_doe() + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not pandas_available, "pandas is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_grid_search_bad_model(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperimentBad(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + logger_level=logging.ERROR, + ) + + design_ranges = {"CA[0]": [1, 5, 3], "T[0]": [300, 700, 3]} + + doe_obj.compute_FIM_full_factorial( + design_ranges=design_ranges, method="sequential" + ) + + # Check to make sure the lengths of the inputs in results object are indeed correct + CA_vals = doe_obj.fim_factorial_results["CA[0]"] + T_vals = doe_obj.fim_factorial_results["T[0]"] + + # Assert length is correct + assert (len(CA_vals) == 9) and (len(T_vals) == 9) + assert (len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3) + + # Assert unique values are correct + assert (set(CA_vals).issuperset(set([1, 3, 5]))) and ( + set(T_vals).issuperset(set([300, 500, 700])) + ) + if __name__ == "__main__": unittest.main() From f1ae5df9469e1c7fea38eaa9219e0b00607f9224 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 10:15:42 -0600 Subject: [PATCH 080/203] Ran Black --- pyomo/contrib/doe/doe.py | 10 ++++++---- .../tests/experiment_class_example_flags.py | 3 ++- pyomo/contrib/doe/tests/test_doe_solve.py | 19 +++++++++++++++---- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 5a25c065dfb..20fac470441 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -501,7 +501,10 @@ def _sequential_FIM(self, model=None): pass # If we are doing forward/backward, no change for s=0 - skip_param_update = (self.fd_formula in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward]) and (s == 0) + skip_param_update = ( + self.fd_formula + in [FiniteDifferenceStep.forward, FiniteDifferenceStep.backward] + ) and (s == 0) if not skip_param_update: param = model.parameter_scenarios[s] # Update parameter values for the given finite difference scenario @@ -512,7 +515,7 @@ def _sequential_FIM(self, model=None): # Simulate the model try: res = self.solver.solve(model) - assert (res.solver.termination_condition == "optimal") + assert res.solver.termination_condition == "optimal" except: raise RuntimeError( "Model from experiment did not solve appropriately. Make sure the model is well-posed." @@ -1021,7 +1024,7 @@ def _generate_scenario_blocks(self, model=None): try: res = self.solver.solve(model.base_model, tee=self.tee) - assert (res.solver.termination_condition == "optimal") + assert res.solver.termination_condition == "optimal" self.logger.info("Model from experiment solved.") except: raise RuntimeError( @@ -1490,7 +1493,6 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): iter_t = iter_timer.toc(msg=None) time_set.append(iter_t) - FIM = self._computed_FIM # Compute and record metrics on FIM diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 4d060328d8f..2a282023a0e 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -246,6 +246,7 @@ def label_experiment(self, flag=0): [[m.t_control], [m.t_control], [m.t_control]], flag=flag ) + class FullReactorExperimentBad(ReactorExperiment): def label_experiment(self, flag=0): m = self.model @@ -257,4 +258,4 @@ def label_experiment(self, flag=0): m.bad_con_1 = pyo.Constraint(expr=m.CA[0] >= 1.0) m.bad_con_2 = pyo.Constraint(expr=m.CA[0] <= 0.0) - return m \ No newline at end of file + return m diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 132df056822..e93e656f19d 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -6,7 +6,9 @@ ) from pyomo.contrib.doe.tests.experiment_class_example import * -from pyomo.contrib.doe.tests.experiment_class_example_flags import FullReactorExperimentBad +from pyomo.contrib.doe.tests.experiment_class_example_flags import ( + FullReactorExperimentBad, +) from pyomo.contrib.doe import * from pyomo.contrib.doe.utils import * @@ -463,7 +465,16 @@ def test_rescale_FIM(self): FIM2, Q2, L2, sigma_inv2 = get_FIM_Q_L(doe_obj=doe_obj2) # Get rescaled FIM from the scaled version - param_vals = np.array([[v for k, v in doe_obj.model.scenario_blocks[0].unknown_parameters.items()], ]) + param_vals = np.array( + [ + [ + v + for k, v in doe_obj.model.scenario_blocks[ + 0 + ].unknown_parameters.items() + ] + ] + ) resc_FIM = rescale_FIM(FIM, param_vals) @@ -498,8 +509,8 @@ def test_reactor_solve_bad_model(self): ) with self.assertRaisesRegex( - RuntimeError, - "Model from experiment did not solve appropriately. Make sure the model is well-posed.", + RuntimeError, + "Model from experiment did not solve appropriately. Make sure the model is well-posed.", ): doe_obj.run_doe() From 858aafcf74db4f598ff053ff03dbf6296ac805ca Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 10:36:00 -0600 Subject: [PATCH 081/203] Added tests for update_FIM --- pyomo/contrib/doe/doe.py | 16 +++++---- pyomo/contrib/doe/tests/test_doe_build.py | 41 ++++++++++++++++++++++- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 20fac470441..8ab014b24e5 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -878,7 +878,7 @@ def jacobian_rule(m, n, p): def read_prior(m, i, j): return fim_initial_dict[(i, j)] - model.priorFIM = pyo.Expression( + model.prior_FIM = pyo.Expression( model.parameter_names, model.parameter_names, rule=read_prior ) @@ -914,7 +914,7 @@ def fim_rule(m, p, q): * m.sensitivity_jacobian[n, q] for n in model.output_names ) - + m.priorFIM[p, q] + + m.prior_FIM[p, q] ) model.jacobian_constraint = pyo.Constraint( @@ -976,11 +976,11 @@ def _generate_scenario_blocks(self, model=None): # Check that the user input FIM and Jacobian are the correct dimension if self.prior_FIM is not None: - self.check_model_FIM(self.prior_FIM) + self.check_model_FIM(FIM=self.prior_FIM) else: self.prior_FIM = np.zeros((self.n_parameters, self.n_parameters)) if self.fim_initial is not None: - self.check_model_FIM(self.fim_initial) + self.check_model_FIM(FIM=self.fim_initial) else: self.fim_initial = np.eye(self.n_parameters) + self.prior_FIM if self.jac_initial is not None: @@ -1301,7 +1301,7 @@ def check_model_labels(self, model=None): self.logger.info("Model has expected labels.") # Check the FIM shape against what is expected from the model. - def check_model_FIM(self, FIM=None): + def check_model_FIM(self, model=None, FIM=None): """ Checks if the specified matrix, FIM, matches the shape expected from the model. This method should only be called after the @@ -1312,7 +1312,11 @@ def check_model_FIM(self, FIM=None): Parameters ---------- model: model for suffix checking, Default: None, (self.model) + FIM: FIM value to check on the model """ + if model is None: + model = self.model + if FIM.shape != (self.n_parameters, self.n_parameters): raise ValueError( "Shape of FIM provided should be n parameters by n parameters, or {} by {}, FIM provided has shape {} by {}".format( @@ -1362,7 +1366,7 @@ def update_FIM_prior(self, model=None, FIM=None): "``fim`` is not defined on the model provided. Please build the model first." ) - self.check_model_FIM(model, FIM) + self.check_model_FIM(model=model, FIM=FIM) # Update FIM prior for ind1, p1 in enumerate(model.parameter_names): diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index db009f32742..cfa4304fbe9 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -41,7 +41,7 @@ def get_FIM_FIMPrior_Q_L(doe_obj=None): for j in model.parameter_names ] FIM_prior_vals = [ - pyo.value(model.priorFIM[i, j]) + pyo.value(model.prior_FIM[i, j]) for i in model.parameter_names for j in model.parameter_names ] @@ -453,6 +453,45 @@ def test_reactor_check_user_initialization(self): assert np.array_equal(L_initial, L) assert np.array_equal(JAC_initial, Q) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_update_FIM(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + FIM_update = np.ones((4, 4)) * 10 + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.create_doe_model() + + doe_obj.update_FIM_prior(FIM=FIM_update) + + # Grab values to ensure we set the correct piece + FIM, FIM_prior_model, Q, L, sigma = get_FIM_FIMPrior_Q_L(doe_obj) + + # Make sure they match the inputs we gave + assert np.array_equal(FIM_update, FIM_prior_model) + if __name__ == "__main__": unittest.main() From 2555900285896e584b62725651e6357d21b82205 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 10:40:15 -0600 Subject: [PATCH 082/203] Add update_FIM error check --- pyomo/contrib/doe/tests/test_doe_errors.py | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 9977bffe94e..4289f2a9112 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -298,6 +298,41 @@ def test_reactor_check_unbuilt_update_FIM(self): ): doe_obj.update_FIM_prior(FIM=FIM_update) + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_check_none_update_FIM(self): + fd_method = "central" + obj_used = "trace" + flag_val = 0 # Value for faulty model build mode - 0: full model + + FIM_update = None + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + ValueError, + "FIM input for update_FIM_prior must be a 2D, square numpy array.", + ): + doe_obj.update_FIM_prior(FIM=FIM_update) + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_results_file_name(self): fd_method = "central" From ca32fc5d69be234d58b65a0b9b2061fd5ccc9b52 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 10:52:25 -0600 Subject: [PATCH 083/203] Added tests for get values functions without blocks --- pyomo/contrib/doe/tests/test_doe_build.py | 149 ++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index cfa4304fbe9..c5b76f2b1d3 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -492,6 +492,155 @@ def test_update_FIM(self): # Make sure they match the inputs we gave assert np.array_equal(FIM_update, FIM_prior_model) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_get_experiment_inputs_without_blocks(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + FIM_update = np.ones((4, 4)) * 10 + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.compute_FIM(method="sequential") + + stuff = doe_obj.get_experiment_input_values(model=doe_obj.compute_FIM_model) + + assert len(stuff) == len( + [k.name for k, v in doe_obj.compute_FIM_model.experiment_inputs.items()] + ) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_get_experiment_outputs_without_blocks(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + FIM_update = np.ones((4, 4)) * 10 + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.compute_FIM(method="sequential") + + stuff = doe_obj.get_experiment_output_values(model=doe_obj.compute_FIM_model) + + assert len(stuff) == len( + [k.name for k, v in doe_obj.compute_FIM_model.experiment_outputs.items()] + ) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_get_measurement_error_without_blocks(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + FIM_update = np.ones((4, 4)) * 10 + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.compute_FIM(method="sequential") + + stuff = doe_obj.get_measurement_error_values(model=doe_obj.compute_FIM_model) + + assert len(stuff) == len( + [k.name for k, v in doe_obj.compute_FIM_model.measurement_error.items()] + ) + + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_get_unknown_parameters_without_blocks(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + FIM_update = np.ones((4, 4)) * 10 + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.compute_FIM(method="sequential") + + # Make sure the values can be retrieved + stuff = doe_obj.get_unknown_parameter_values(model=doe_obj.compute_FIM_model) + + assert len(stuff) == len( + [k.name for k, v in doe_obj.compute_FIM_model.unknown_parameters.items()] + ) + if __name__ == "__main__": unittest.main() From 5864e68182b6c51e3d65563712bc3d59a05ce9a9 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 11:04:22 -0600 Subject: [PATCH 084/203] Adding tests for multi experiment not implemented and scenario building withoutmodel --- pyomo/contrib/doe/tests/test_doe_build.py | 37 +++++++++--- pyomo/contrib/doe/tests/test_doe_errors.py | 68 ++++++++++++++++++++++ 2 files changed, 97 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index c5b76f2b1d3..4c1541f088c 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -500,8 +500,6 @@ def test_get_experiment_inputs_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - FIM_update = np.ones((4, 4)) * 10 - doe_obj = DesignOfExperiments( experiment, fd_formula=fd_method, @@ -537,8 +535,6 @@ def test_get_experiment_outputs_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - FIM_update = np.ones((4, 4)) * 10 - doe_obj = DesignOfExperiments( experiment, fd_formula=fd_method, @@ -574,8 +570,6 @@ def test_get_measurement_error_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - FIM_update = np.ones((4, 4)) * 10 - doe_obj = DesignOfExperiments( experiment, fd_formula=fd_method, @@ -611,8 +605,6 @@ def test_get_unknown_parameters_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - FIM_update = np.ones((4, 4)) * 10 - doe_obj = DesignOfExperiments( experiment, fd_formula=fd_method, @@ -641,6 +633,35 @@ def test_get_unknown_parameters_without_blocks(self): [k.name for k, v in doe_obj.compute_FIM_model.unknown_parameters.items()] ) + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_generate_blocks_without_model(self): + fd_method = "forward" + obj_used = "trace" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj._generate_scenario_blocks() + if __name__ == "__main__": unittest.main() diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 4289f2a9112..639e4c690e4 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -888,6 +888,74 @@ def test_reactor_check_get_meas_error_without_model(self): ): doe_obj.get_measurement_error_values() + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_multiple_exp_not_implemented_seq(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + NotImplementedError, "Multiple experiment optimization not yet supported." + ): + doe_obj.run_multi_doe_sequential(N_exp=1) + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_multiple_exp_not_implemented_sim(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + NotImplementedError, "Multiple experiment optimization not yet supported." + ): + doe_obj.run_multi_doe_simultaneous(N_exp=1) + if __name__ == "__main__": unittest.main() From 11af0059c9f8a23afa2a3273c47a00a37fba42ae Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 11:28:40 -0600 Subject: [PATCH 085/203] Adding tests for bad FD values --- pyomo/contrib/doe/doe.py | 18 ++---- pyomo/contrib/doe/tests/test_doe_errors.py | 73 +++++++++++++++++++++- 2 files changed, 77 insertions(+), 14 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 8ab014b24e5..61bac7e6eb4 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -27,7 +27,6 @@ import pyomo.environ as pyo from pyomo.opt import SolverStatus -from pyomo.common import DeveloperError from pyomo.common.timing import TicTocTimer from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp @@ -415,7 +414,6 @@ def compute_FIM(self, model=None, method="sequential"): else: self.check_model_FIM(FIM=self.prior_FIM) - # ToDo: Decide where the FIM should be saved. if method == "sequential": self._sequential_FIM(model=model) self._computed_FIM = self.seq_FIM @@ -471,8 +469,9 @@ def _sequential_FIM(self, model=None): ) model.scenarios = range(len(model.unknown_parameters) + 1) else: - # To-Do: add an error message for this as not being implemented yet - pass + raise AttributeError( + "Finite difference option not recognized. Please contact the developers as you should not see this error." + ) # Fix design variables for comp, _ in model.experiment_inputs.items(): @@ -493,12 +492,6 @@ def _sequential_FIM(self, model=None): ) # Backward always negative perturbation; 0 at s = 0 elif self.fd_formula == FiniteDifferenceStep.forward: diff = self.step * (s != 0) # Forward always positive; 0 at s = 0 - else: - raise DeveloperError( - "Finite difference option not recognized. Please contact the developers as you should not see this error." - ) - diff = 0 - pass # If we are doing forward/backward, no change for s=0 skip_param_update = ( @@ -1012,7 +1005,7 @@ def _generate_scenario_blocks(self, model=None): ) model.scenarios = range(len(model.base_model.unknown_parameters) + 1) else: - raise DeveloperError( + raise AttributeError( "Finite difference option not recognized. Please contact the developers as you should not see this error." ) @@ -1247,8 +1240,7 @@ def det_general(m): # add dummy objective function model.objective = pyo.Objective(expr=0) else: - # something went wrong! - raise DeveloperError( + raise AttributeError( "Objective option not recognized. Please contact the developers as you should not see this error." ) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 639e4c690e4..15cf6b6373e 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -8,7 +8,6 @@ from pyomo.contrib.doe.tests.experiment_class_example_flags import * from pyomo.contrib.doe import * - import pyomo.common.unittest as unittest from pyomo.opt import SolverFactory @@ -956,6 +955,78 @@ def test_multiple_exp_not_implemented_sim(self): ): doe_obj.run_multi_doe_simultaneous(N_exp=1) + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_bad_FD_generate_scens(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + AttributeError, + "Finite difference option not recognized. Please contact the developers as you should not see this error.", + ): + doe_obj.fd_formula = "bad things" + doe_obj._generate_scenario_blocks() + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_bad_FD_seq_compute_FIM(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + AttributeError, + "Finite difference option not recognized. Please contact the developers as you should not see this error.", + ): + doe_obj.fd_formula = "bad things" + doe_obj.compute_FIM(method="sequential") + if __name__ == "__main__": unittest.main() From ae9d288099807c0e2431646eefa8dd6b4bc45bca Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 11:37:24 -0600 Subject: [PATCH 086/203] Added tests for bad objective builds --- pyomo/contrib/doe/doe.py | 18 ++++-- pyomo/contrib/doe/tests/test_doe_errors.py | 71 ++++++++++++++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 61bac7e6eb4..e5f5c41bcb9 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1116,6 +1116,20 @@ def create_objective_function(self, model=None): if model is None: model = self.model + if self.objective_option not in [ + ObjectiveLib.det, + ObjectiveLib.trace, + ObjectiveLib.zero, + ]: + raise AttributeError( + "Objective option not recognized. Please contact the developers as you should not see this error." + ) + + if not hasattr(model, "fim"): + raise RuntimeError( + "Model provided does not have variable `fim`. Please make sure the model is built properly before creating the objective." + ) + small_number = 1e-10 # Make objective block for constraints connected to objective @@ -1239,10 +1253,6 @@ def det_general(m): elif self.objective_option == ObjectiveLib.zero: # add dummy objective function model.objective = pyo.Objective(expr=0) - else: - raise AttributeError( - "Objective option not recognized. Please contact the developers as you should not see this error." - ) # Check to see if the model has all the required suffixes def check_model_labels(self, model=None): diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 15cf6b6373e..e2030162330 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -1027,6 +1027,77 @@ def test_bad_FD_seq_compute_FIM(self): doe_obj.fd_formula = "bad things" doe_obj.compute_FIM(method="sequential") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_bad_objective(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + AttributeError, + "Objective option not recognized. Please contact the developers as you should not see this error.", + ): + doe_obj.objective_option = "bad things" + doe_obj.create_objective_function() + + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_no_model_for_objective(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + RuntimeError, + "Model provided does not have variable `fim`. Please make sure the model is built properly before creating the objective.", + ): + doe_obj.create_objective_function() + if __name__ == "__main__": unittest.main() From 06a0f50eb58d55ea1fa1727404200646675b1de7 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 11:40:00 -0600 Subject: [PATCH 087/203] Changed one run to use objective type --- pyomo/contrib/doe/tests/test_doe_solve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index e93e656f19d..4ab9e275c7e 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -127,7 +127,7 @@ def test_reactor_fd_central_solve(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_solve(self): fd_method = "forward" - obj_used = "trace" + obj_used = "zero" experiment = FullReactorExperiment(data_ex, 10, 3) From cc4eec0df1a89deb789ff2e3b0e78c87cfd94d23 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 11:45:57 -0600 Subject: [PATCH 088/203] Added not implemented error for unknown parameter value updating --- pyomo/contrib/doe/doe.py | 4 ++- pyomo/contrib/doe/tests/test_doe_errors.py | 34 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index e5f5c41bcb9..9f31fdeb010 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1380,7 +1380,9 @@ def update_FIM_prior(self, model=None, FIM=None): # ToDo: Add an update function for the parameter values? --> closed loop parameter estimation? # Or leave this to the user????? def update_unknown_parameter_values(self, model=None, param_vals=None): - return + raise NotImplementedError( + "Updating unknown parameter values not yet supported." + ) # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index e2030162330..3df8355e528 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -955,6 +955,40 @@ def test_multiple_exp_not_implemented_sim(self): ): doe_obj.run_multi_doe_simultaneous(N_exp=1) + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_update_unknown_parameter_values_not_implemented_seq(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + NotImplementedError, "Updating unknown parameter values not yet supported." + ): + doe_obj.update_unknown_parameter_values() + @unittest.skipIf(not numpy_available, "Numpy is not available") def test_bad_FD_generate_scens(self): fd_method = "central" From a389d4f91881b72e6b051134ef88cd1f82c11682 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Thu, 18 Jul 2024 13:48:09 -0400 Subject: [PATCH 089/203] Delete pyomo/contrib/doe/examples directory Old files removed to make room for new examples directory --- pyomo/contrib/doe/examples/__init__.py | 10 - pyomo/contrib/doe/examples/dynamic.csv | 5 - .../doe/examples/fim_5_300_500_scale.csv | 5 - .../contrib/doe/examples/fim_5_300_scale.csv | 5 - .../doe/examples/fim_doe_tutorial.ipynb | 1868 ----------------- .../doe/examples/reactor_compute_FIM.py | 111 - pyomo/contrib/doe/examples/reactor_design.py | 236 --- .../doe/examples/reactor_grid_search.py | 140 -- .../contrib/doe/examples/reactor_kinetics.py | 247 --- .../doe/examples/reactor_optimize_doe.py | 123 -- 10 files changed, 2750 deletions(-) delete mode 100644 pyomo/contrib/doe/examples/__init__.py delete mode 100644 pyomo/contrib/doe/examples/dynamic.csv delete mode 100644 pyomo/contrib/doe/examples/fim_5_300_500_scale.csv delete mode 100644 pyomo/contrib/doe/examples/fim_5_300_scale.csv delete mode 100644 pyomo/contrib/doe/examples/fim_doe_tutorial.ipynb delete mode 100644 pyomo/contrib/doe/examples/reactor_compute_FIM.py delete mode 100644 pyomo/contrib/doe/examples/reactor_design.py delete mode 100644 pyomo/contrib/doe/examples/reactor_grid_search.py delete mode 100644 pyomo/contrib/doe/examples/reactor_kinetics.py delete mode 100644 pyomo/contrib/doe/examples/reactor_optimize_doe.py diff --git a/pyomo/contrib/doe/examples/__init__.py b/pyomo/contrib/doe/examples/__init__.py deleted file mode 100644 index a4a626013c4..00000000000 --- a/pyomo/contrib/doe/examples/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# ___________________________________________________________________________ diff --git a/pyomo/contrib/doe/examples/dynamic.csv b/pyomo/contrib/doe/examples/dynamic.csv deleted file mode 100644 index f54d798bda3..00000000000 --- a/pyomo/contrib/doe/examples/dynamic.csv +++ /dev/null @@ -1,5 +0,0 @@ -A1,A2,E1,E2 -6.209381770954067,7.719297166025923,-12.835153102965977,-38.540492455469554 -7.719297166025923,20.53859118830565,-14.829065563786362,-99.2962499942191 --12.835153102965977,-14.829065563786362,26.869188945470434,74.5001011185848 --38.540492455469554,-99.2962499942191,74.5001011185848,484.97578893372025 diff --git a/pyomo/contrib/doe/examples/fim_5_300_500_scale.csv b/pyomo/contrib/doe/examples/fim_5_300_500_scale.csv deleted file mode 100644 index 77c0424aa13..00000000000 --- a/pyomo/contrib/doe/examples/fim_5_300_500_scale.csv +++ /dev/null @@ -1,5 +0,0 @@ -A1,A2,E1,E2 -28.678928056936364,5.412497388906993,-81.73674601413501,-24.023773235011475 -5.412497388906993,26.409350356572013,-12.418164773953235,-139.2399253159117 --81.73674601413501,-12.418164773953235,240.46276003997696,58.764228064029076 --24.023773235011475,-139.2399253159117,58.764228064029076,767.255845082616 diff --git a/pyomo/contrib/doe/examples/fim_5_300_scale.csv b/pyomo/contrib/doe/examples/fim_5_300_scale.csv deleted file mode 100644 index 381e916b9d4..00000000000 --- a/pyomo/contrib/doe/examples/fim_5_300_scale.csv +++ /dev/null @@ -1,5 +0,0 @@ -A1,A2,E1,E2 -22.529430237938822,1.8403431417002734,-70.23273336318343,-11.094329617631416 -1.8403431417002734,18.098481155262718,-5.7356503398877745,-109.15866135211135 --70.23273336318343,-5.7356503398877745,218.9419284259853,34.576808479575064 --11.094329617631416,-109.15866135211135,34.576808479575064,658.3764463408718 diff --git a/pyomo/contrib/doe/examples/fim_doe_tutorial.ipynb b/pyomo/contrib/doe/examples/fim_doe_tutorial.ipynb deleted file mode 100644 index 36ec42fbe49..00000000000 --- a/pyomo/contrib/doe/examples/fim_doe_tutorial.ipynb +++ /dev/null @@ -1,1868 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pyomo.DoE Tutorial: Reaction Kinetics Example \n", - "\n", - "Jialu Wang (jwang44@nd.edu), Alex Dowling (adowling@nd.edu), and Hailey Lynch (hlynch@nd.edu)\n", - "\n", - "University of Notre Dame\n", - "\n", - "This notebook demonstrates the main features of Pyomo.DoE (model-based design of experiments) using a reaction kinetics example. See [Wang and Dowling (2022), AIChE J.](https://aiche.onlinelibrary.wiley.com/doi/full/10.1002/aic.17813), for more information.\n", - "\n", - "The user will be able to learn concepts involved with model-based design of experiments (MBDoE) and practice using Pyomo.DoE from methodology in the notebook. Results will be interpreted throughout the notebook to connect the material with the Pyomo implementation.\n", - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The general process that will follow throughout this notebook:\n", - "\n", - "Import Modules\n", - "\n", - "* Step 0: Import Pyomo and Pyomo.DoE Module\n", - "\n", - "Problem Statement\n", - "\n", - "* Step 1: Import Reaction Kinetics Example Mathematical Model\n", - "\n", - "Implementation in Pyomo\n", - "\n", - "* Step 2: Implement Mathematical Model in Pyomo\n", - "* Step 3: Define Inputs for the Model\n", - "\n", - "Methodology\n", - "\n", - "* Step 4: Method for Computing FIM\n", - "\n", - "* Step 5: Method for Optimization\n", - "\n", - "* Step 6: Method for Exploratory Analysis through Enumeration\n", - "\n", - "Visualizing Results\n", - "\n", - "* Step 7: Results through Heatmaps and Sensitivity Curves\n", - "\n", - "Key Takeaways\n", - "* MBDoE maximizes the information gained from experiments which reduces uncertainty (technical risk) and facilitates better decision-making.\n", - "\n", - "* FIM quantifies the information contained in a set of experiments (data) with respect to a mathematical model\n", - "\n", - "* MBDoE optimality criteria (e.g., A, D, E-optimal designs) compress the FIM into a scalar. The \"correct\" criterion depends on the DoE goal and model context.\n", - "\n", - "* Heatmaps provide visualizations of the most informative parameters using the MBDoE optimality criteria." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 0: Import Pyomo and Pyomo.DoE module" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Successfully loaded IDAES.\n" - ] - } - ], - "source": [ - "# Ipopt installer\n", - "import sys\n", - "\n", - "# If running on Google Colab, install Ipopt via IDAES\n", - "if \"google.colab\" in sys.modules:\n", - " !wget \"https://raw.githubusercontent.com/IDAES/idaes-pse/main/scripts/colab_helper.py\"\n", - " import colab_helper\n", - "\n", - " colab_helper.install_idaes()\n", - " colab_helper.install_ipopt()\n", - "\n", - "# Otherwise, attempt to load IDAES which should include Ipopt and k_aug\n", - "# See https://idaes-pse.readthedocs.io/en/stable/tutorials/getting_started/index.html\n", - "# for instructions on running IDAES get-extensions\n", - "else:\n", - " try:\n", - " import idaes\n", - "\n", - " # Provided IDAES extensions are installed, importing IDAES provides access to\n", - " # Ipopt with HSL and k_aug which are needed for this example\n", - " print(\"Successfully loaded IDAES.\")\n", - " except:\n", - " print(\n", - " \"IDAES is not installed. Make sure you have independently installed Ipopt with HSL and k_aug.\"\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Imports\n", - "import numpy as np\n", - "import pyomo.environ as pyo\n", - "from pyomo.dae import ContinuousSet, DerivativeVar\n", - "from pyomo.contrib.doe import (\n", - " ModelOptionLib,\n", - " DesignOfExperiments,\n", - " MeasurementVariables,\n", - " DesignVariables,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Check if Ipopt is available\n", - "ipopt_available = pyo.SolverFactory(\"ipopt\").available()\n", - "if not (ipopt_available):\n", - " raise RuntimeError(\"This Pyomo.DoE example requires Ipopt.\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 1: Import Reaction Kinetics Example Mathematical Model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Consider two chemical reactions that convert molecule $A$ to desired product $B$ and a less valuable side-product $C$.\n", - "\n", - "$$A \\overset{k_1}{\\rightarrow} B \\overset{k_2}{\\rightarrow} C$$\n", - "\n", - "Our ultimate goal is to design a large-scale continuous reactor that maximizes the production of $B$. This general sequential reactions problem is widely applicable to CO$_2$ capture and industry more broadly (petrochemicals, pharmaceuticals, etc.).\n", - "\n", - "The rate laws for these two chemical reactions are:\n", - "\n", - "$$r_A = -k_1 C_A$$\n", - "\n", - "$$r_B = k_1 C_A - k_2 C_B$$\n", - "\n", - "$$r_C = k_2 C_B$$\n", - "\n", - "Here, $C_A$, $C_B$, and $C_C$ are the concentrations of each species. \n", - "\n", - "The rate constants $k_1$ and $k_2$ depend on temperature as follows:\n", - "\n", - "$$k_1 = A_1 \\exp{\\frac{-E_1}{R T}}$$\n", - "\n", - "$$k_2 = A_2 \\exp{\\frac{-E_2}{R T}}$$\n", - "\n", - "where:\n", - "* $A_1$ [$s^{-1}$], $A_2$ [$s^{-1}$] , $E_1$ [kJ/mol], and $E_2$ [kJ/mol] are fitted model parameters\n", - "* $R$ [J/molK] is the ideal-gas constant\n", - "* $T$ [K] is absolute temperature\n", - "\n", - "Using the Pyomo ecosystem, we would like to perform **uncertainty quantification** and **design of experiments** on a small-scale batch reactor to infer parameters $A_1$, $A_2$, $E_1$, and $E_2$." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Batch Reactor\n", - "\n", - "The concentrations in a batch reactor evolve with time and are modeled by the following differential equations:\n", - "\n", - "$$ \\frac{d C_A}{dt} = r_A = -k_1 C_A $$\n", - "\n", - "$$ \\frac{d C_B}{dt} = r_B = k_1 C_A - k_2 C_B $$\n", - "\n", - "$$ \\frac{d C_C}{dt} = r_C = k_2 C_B $$\n", - "\n", - "We have now established a linear system of differential equations. Next, we can write the initial conditions assuming the feed is only species $A$ such that:\n", - "\n", - "$$C_A(t=0) = C_{A0}, \\quad C_B(t=0) = 0, \\quad C_C(t=0) = 0$$\n", - "\n", - "When $k_1$ and $k_2$ are at constant temperature, it leads to the following analytic solution:\n", - "\n", - "$$C_A(t) = C_{A0} \\exp(-k_1 t)$$\n", - "\n", - "$$C_B(t) = \\frac{k_1}{k_2 - k_1} C_{A0} \\left[\\exp(-k_1 t) - \\exp(-k_2 t) \\right]$$\n", - "\n", - "$$C_C(t) = C_{A0} - \\frac{k_2}{k_2 - k_1} C_{A0} \\exp(-k_1 t) + \\frac{k_1}{k_2 - k_1} \\exp(-k_2 t) C_{A0} = C_{A0} - C_{A}(t) - C_{B}(t)$$" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Implement Mathematical Model in Pyomo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The mathematical model is comprised of a system of differential-algebraic equations (DAEs) which will be solved using Pyomo.DAE." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "# Discretize using Pyomo.DAE\n", - "def disc_for_measure(m, nfe=32, block=True):\n", - " \"\"\"\n", - " Pyomo.DAE discretization\n", - "\n", - " Arguments\n", - " ---------\n", - " m: Pyomo model\n", - " nfe: number of finite elements b\n", - " block: if True, the input model has blocks\n", - " \"\"\"\n", - " # Discretization using collocation\n", - " discretizer = pyo.TransformationFactory(\"dae.collocation\")\n", - " if block:\n", - " for s in range(len(m.block)):\n", - " discretizer.apply_to(m.block[s], nfe=nfe, ncp=3, wrt=m.block[s].t)\n", - " else:\n", - " discretizer.apply_to(m, nfe=nfe, ncp=3, wrt=m.t)\n", - " return m" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, create the model." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# Create model\n", - "def create_model(\n", - " mod=None,\n", - " model_option=\"stage2\",\n", - " control_time=[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1],\n", - " control_val=None,\n", - " t_range=[0.0, 1],\n", - " CA_init=1,\n", - " C_init=0.1,\n", - "):\n", - " \"\"\"\n", - " This is an example user model provided to the DoE library.\n", - " It is a dynamic problem solved by Pyomo.DAE.\n", - "\n", - " Arguments\n", - " ---------\n", - " mod: Pyomo model. If None, a Pyomo concrete model is created\n", - " model_option: choose from the 3 options in model_option\n", - " if ModelOptionLib.parmest, create a process model.\n", - " if ModelOptionLib.stage1, create the global model.\n", - " if ModelOptionLib.stage2, add model variables and constraints for block.\n", - " control_time: a list of control timepoints\n", - " control_val: control design variable values T at corresponding timepoints\n", - " t_range: time range, hours\n", - " CA_init: time-independent design (control) variable, an initial value for CA\n", - " C_init: An initial value for C\n", - "\n", - " Return\n", - " ------\n", - " m: a Pyomo.DAE model\n", - " \"\"\"\n", - " # Parameter initialization; results from parameter estimation\n", - " theta = {\"A1\": 84.79, \"A2\": 371.72, \"E1\": 7.78, \"E2\": 15.05}\n", - "\n", - " # Model option\n", - " model_option = ModelOptionLib(model_option)\n", - "\n", - " if model_option == ModelOptionLib.parmest:\n", - " mod = pyo.ConcreteModel()\n", - " return_m = True\n", - " elif model_option == ModelOptionLib.stage1 or model_option == ModelOptionLib.stage2:\n", - " if not mod:\n", - " raise ValueError(\n", - " \"If model option is stage1 or stage2, a created model needs to be provided.\"\n", - " )\n", - " return_m = False\n", - " else:\n", - " raise ValueError(\n", - " \"model_option needs to be defined as parmest, stage1, or stage2.\"\n", - " )\n", - "\n", - " # Control value\n", - " if not control_val:\n", - " control_val = [300] * 9\n", - "\n", - " # Control time\n", - " controls = {}\n", - " for i, t in enumerate(control_time):\n", - " controls[t] = control_val[i]\n", - "\n", - " mod.t0 = pyo.Set(initialize=[0])\n", - " mod.t_con = pyo.Set(initialize=control_time)\n", - " mod.CA0 = pyo.Var(\n", - " mod.t0, initialize=CA_init, bounds=(1.0, 5.0), within=pyo.NonNegativeReals\n", - " ) # mol/L\n", - "\n", - " # Check if control_time is in time range\n", - " assert (\n", - " control_time[0] >= t_range[0] and control_time[-1] <= t_range[1]\n", - " ), \"control time is outside time range.\"\n", - "\n", - " if model_option == ModelOptionLib.stage1:\n", - " mod.T = pyo.Var(\n", - " mod.t_con,\n", - " initialize=controls,\n", - " bounds=(300, 700),\n", - " within=pyo.NonNegativeReals,\n", - " )\n", - " return\n", - "\n", - " else:\n", - " para_list = [\"A1\", \"A2\", \"E1\", \"E2\"]\n", - "\n", - " # Add variables\n", - " mod.CA_init = CA_init\n", - " mod.para_list = para_list\n", - "\n", - " # Timepoints\n", - " mod.t = ContinuousSet(bounds=t_range, initialize=control_time)\n", - "\n", - " # Time-dependent design variable; initialized with the first control value\n", - " def T_initial(m, t):\n", - " if t in m.t_con:\n", - " return controls[t]\n", - " else:\n", - " # Count how many control points are before the current t;\n", - " # Locate the nearest neighbouring control point before this t\n", - " neighbour_t = max(tc for tc in control_time if tc < t)\n", - " return controls[neighbour_t]\n", - "\n", - " mod.T = pyo.Var(\n", - " mod.t, initialize=T_initial, bounds=(300, 700), within=pyo.NonNegativeReals\n", - " )\n", - "\n", - " # Gas constant\n", - " mod.R = 8.31446261815324 # J / K / mole\n", - "\n", - " # Define variables as Var\n", - " mod.A1 = pyo.Var(initialize=theta[\"A1\"])\n", - " mod.A2 = pyo.Var(initialize=theta[\"A2\"])\n", - " mod.E1 = pyo.Var(initialize=theta[\"E1\"])\n", - " mod.E2 = pyo.Var(initialize=theta[\"E2\"])\n", - "\n", - " # Concentration variables under perturbation\n", - " mod.C_set = pyo.Set(initialize=[\"CA\", \"CB\", \"CC\"])\n", - " mod.C = pyo.Var(\n", - " mod.C_set, mod.t, initialize=C_init, within=pyo.NonNegativeReals\n", - " )\n", - "\n", - " # Time derivative of C\n", - " mod.dCdt = DerivativeVar(mod.C, wrt=mod.t)\n", - "\n", - " # Kinetic parameters\n", - " def kp1_init(m, t):\n", - " return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def kp2_init(m, t):\n", - " return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", - "\n", - " mod.kp1 = pyo.Var(mod.t, initialize=kp1_init)\n", - " mod.kp2 = pyo.Var(mod.t, initialize=kp2_init)\n", - "\n", - " def T_control(m, t):\n", - " \"\"\"\n", - " Time is discretized for numeric integration. A subset of these time points are control time points.\n", - " Temperature is constant within each control time point.\n", - "\n", - " TODO: replace this function with reduce_collocation_points\n", - " https://pyomo.readthedocs.io/en/stable/modeling_extensions/dae.html\n", - "\n", - " \"\"\"\n", - " if t in m.t_con:\n", - " return pyo.Constraint.Skip\n", - " else:\n", - " neighbour_t = max(tc for tc in control_time if tc < t)\n", - " return m.T[t] == m.T[neighbour_t]\n", - "\n", - " def cal_kp1(m, t):\n", - " \"\"\"\n", - " Create the perturbation parameter sets for A --> B reaction\n", - "\n", - " m: model\n", - " t: time\n", - " \"\"\"\n", - " # LHS: 1/h\n", - " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", - " return m.kp1[t] == m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def cal_kp2(m, t):\n", - " \"\"\"\n", - " Create the perturbation parameter sets for B --> C reaction\n", - "\n", - " m: model\n", - " t: time\n", - " \"\"\"\n", - " # LHS: 1/h\n", - " # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K)\n", - " return m.kp2[t] == m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t]))\n", - "\n", - " def dCdt_control(m, y, t):\n", - " \"\"\"\n", - " Calculate CA in Jacobian matrix analytically\n", - "\n", - " y: CA, CB, CC\n", - " t: timepoints\n", - " \"\"\"\n", - " if y == \"CA\":\n", - " return m.dCdt[y, t] == -m.kp1[t] * m.C[\"CA\", t]\n", - " elif y == \"CB\":\n", - " return m.dCdt[y, t] == m.kp1[t] * m.C[\"CA\", t] - m.kp2[t] * m.C[\"CB\", t]\n", - " elif y == \"CC\":\n", - " return pyo.Constraint.Skip\n", - "\n", - " def alge(m, t):\n", - " \"\"\"\n", - " The algebraic equation for mole balance\n", - "\n", - " z: m.pert\n", - " t: time\n", - " \"\"\"\n", - " return m.C[\"CA\", t] + m.C[\"CB\", t] + m.C[\"CC\", t] == m.CA0[0]\n", - "\n", - " # Control time\n", - " mod.T_rule = pyo.Constraint(mod.t, rule=T_control)\n", - "\n", - " # Calculating C, Jacobian, FIM\n", - " mod.k1_pert_rule = pyo.Constraint(mod.t, rule=cal_kp1)\n", - " mod.k2_pert_rule = pyo.Constraint(mod.t, rule=cal_kp2)\n", - " mod.dCdt_rule = pyo.Constraint(mod.C_set, mod.t, rule=dCdt_control)\n", - "\n", - " mod.alge_rule = pyo.Constraint(mod.t, rule=alge)\n", - "\n", - " # Boundary conditions\n", - " mod.C[\"CB\", 0.0].fix(0.0)\n", - " mod.C[\"CC\", 0.0].fix(0.0)\n", - "\n", - " if return_m:\n", - " return mod" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# The above models are alternately available in the examples folder:\n", - "# from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 3: Define Inputs for the Model" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "# Control time set [h]\n", - "t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1]\n", - "# Define parameter nominal value\n", - "parameter_dict = {\"A1\": 84.79, \"A2\": 371.72, \"E1\": 7.78, \"E2\": 15.05}" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "measurement names: ['C[CA,0]', 'C[CA,0.125]', 'C[CA,0.25]', 'C[CA,0.375]', 'C[CA,0.5]', 'C[CA,0.625]', 'C[CA,0.75]', 'C[CA,0.875]', 'C[CA,1]', 'C[CB,0]', 'C[CB,0.125]', 'C[CB,0.25]', 'C[CB,0.375]', 'C[CB,0.5]', 'C[CB,0.625]', 'C[CB,0.75]', 'C[CB,0.875]', 'C[CB,1]', 'C[CC,0]', 'C[CC,0.125]', 'C[CC,0.25]', 'C[CC,0.375]', 'C[CC,0.5]', 'C[CC,0.625]', 'C[CC,0.75]', 'C[CC,0.875]', 'C[CC,1]']\n" - ] - } - ], - "source": [ - "# Pyomo.DoE defines measurements\n", - "# Measurements have at most 1 index besides the time index\n", - "variable_name = \"C\"\n", - "indices = {0: [\"CA\", \"CB\", \"CC\"], 1: t_control}\n", - "\n", - "# Measurement class\n", - "measure_class = MeasurementVariables()\n", - "measure_class.add_variables(variable_name, indices=indices, time_index_position=1)\n", - "print(\"measurement names:\", measure_class.variable_names)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Design variable names: ['CA0[0]', 'T[0]', 'T[0.125]', 'T[0.25]', 'T[0.375]', 'T[0.5]', 'T[0.625]', 'T[0.75]', 'T[0.875]', 'T[1]']\n" - ] - } - ], - "source": [ - "# Design variables\n", - "design_gen = DesignVariables()\n", - "\n", - "var_C = \"CA0\"\n", - "indices_C = {0: [0]}\n", - "exp1_C = [5]\n", - "\n", - "# Add design variable\n", - "design_gen.add_variables(\n", - " var_C,\n", - " indices=indices_C,\n", - " time_index_position=0,\n", - " values=exp1_C,\n", - " lower_bounds=1,\n", - " upper_bounds=5,\n", - ")\n", - "\n", - "\n", - "var_T = \"T\"\n", - "indices_T = {0: t_control}\n", - "exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300]\n", - "\n", - "design_gen.add_variables(\n", - " var_T,\n", - " indices=indices_T,\n", - " time_index_position=0,\n", - " values=exp1_T,\n", - " lower_bounds=300,\n", - " upper_bounds=700,\n", - ")\n", - "print(\"Design variable names:\", design_gen.variable_names)" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "# Parameter dictionary\n", - "param_dict = {\"A1\": 84.79, \"A2\": 371.72, \"E1\": 7.78, \"E2\": 15.05}" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 4: Method for Computing FIM \n", - "\n", - "This method computes an FIM-based MBDoE optimization problem with zero degrees of freedom." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Fisher Information Matrix (FIM)\n", - "The FIM measures the information content for the unknown parameters $\\theta$ from the model output $y_i$ given that:\n", - "\n", - "$$ y_i = f(\\psi_i, \\theta) $$\n", - "\n", - "where $\\psi$ is a design vector from a DAE system.\n", - "\n", - "In order to quantify the uncertainty of the estimated parameters for parameter estimation, consider the covariance matrix for the parameters:\n", - "\n", - "$$V(\\hat{\\theta},\\psi) = \\left[\\sum_{r}^{N_{r}}\\sum_{r'}^{N_{r}} \\tilde{\\sigma}_{(r,r')}Q_{r}^{T}Q_{r'}+V_{\\theta}(\\hat{\\theta})^{-1}\\right]^{-1}$$\n", - "\n", - "where:\n", - "* $\\hat{\\theta}$: estimated parameters\n", - "* $\\tilde{\\sigma}$: element in the inverse of the observational covariance matrix\n", - "* $r,$ $r'$: measurements\n", - "* $Q$: dynamic sensitivity\n", - "* $V_{\\theta}$: prior information\n", - "* $N_r$: number of measurements\n", - "\n", - "The inverse of $V$ estimates the FIM such that:\n", - "\n", - "$$V(\\hat{\\theta},\\psi) \\approx [M(\\hat{\\theta},\\psi)]^{-1}$$\n", - "\n", - "For sequential design of experiments, consider prior information such that after $N_e$ dynamic experiments, the FIM is calculated by:\n", - "$$M= \\sum_{k=1}^{N_e-1}M_k+M_{N_e}(\\hat{\\theta},\\psi_{N_e}) = K+M_{N_e}(\\hat{\\theta},\\psi_{N_e})$$\n", - "\n", - "where:\n", - "* $N_e - 1$: previous experiments\n", - "* $K$: constant matrix encoding information from all $N_e - 1$\n", - "\n", - "**Key Takeaway**:\n", - "A **large** FIM value denotes **more** information about $\\theta$ is gained from the model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Model-Based Design of Experiments\n", - "The objective of MBDoE changes the conditions of one or more experiments based on a specific purpose such as:\n", - "\n", - "1. Model identification\n", - " * Discriminates between possible models while omitting inadequate models\n", - "2. Parameter estimation\n", - " * Improves parameter estimation precision\n", - "\n", - "**Key Takeaways:**\n", - "Given an estimate for an unknown parameter and one or more mathematical models, MBDoE:\n", - "1. Determines a set of experimental conditions to maximize the precision of the unknown model parameters\n", - "2. Discriminates between the given models\n", - "3. Or both (1) and (2)\n", - "\n", - "Currently, Pyomo.DoE supports MBDoE for parameter precision." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "# Choose from 'sequential_finite', 'direct_kaug'\n", - "# sensi_opt = \"direct_kaug\"\n", - "sensi_opt = \"sequential_finite\"\n", - "\n", - "# Define experiments\n", - "design_names = design_gen.variable_names\n", - "exp1 = [5, 470, 300, 300, 300, 300, 300, 300, 300, 300]\n", - "exp1_design_dict = dict(zip(design_names, exp1))\n", - "\n", - "# Update values\n", - "design_gen.update_values(exp1_design_dict)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 25344\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2320\n", - "\n", - "Total number of variables............................: 6968\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 6968\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 1.67e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (239448)\n", - " 1 0.0000000e+00 3.23e+01 3.85e+02 -1.0 1.67e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 6.16e+00 8.61e+01 -1.0 3.87e+01 - 1.11e-01 9.90e-01h 1\n", - " 3 0.0000000e+00 5.12e-02 9.97e+00 -1.0 4.16e+00 - 9.60e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 1.20e-06 7.52e+01 -1.0 3.62e-02 - 9.97e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (287125)\n", - " 5 0.0000000e+00 2.25e-13 1.00e-06 -1.0 7.68e-07 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 9.3507738837536098e-14 2.2537527399890678e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 9.3507738837536098e-14 2.2537527399890678e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.468\n", - "Total CPU secs in NLP function evaluations = 0.017\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "INFO: elapsed time: 2.9\n" - ] - } - ], - "source": [ - "# Create doe_object using DesignOfExperiments\n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict, # dictionary of parameters\n", - " design_gen, # design variable\n", - " measure_class, # measurement variable\n", - " create_model, # model\n", - " discretize_model=disc_for_measure, # discretized model\n", - ")\n", - "\n", - "# Computing the FIM\n", - "result = doe_object.compute_FIM(\n", - " mode=sensi_opt, # solver option for sensitivity optimization\n", - " FIM_store_name=\"dynamic.csv\", # csv file that stores FIM data\n", - " read_output=None, # outputs from stored file; do not have to rerun since there are measurement values already\n", - " scale_nominal_param_value=True, # scale the Jacobian with the parameter values\n", - " formula=\"central\", # finite difference - central method\n", - ")\n", - "\n", - "# Results\n", - "result.result_analysis()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "======Results Summary======\n", - "Four design criteria log10() value:\n", - "A-optimality: 2.989724462425373\n", - "D-optimality: 3.3010989022733894\n", - "E-optimality: -0.9193349136200465\n", - "Modified E-optimality: 3.87680755495709\n", - "[[ 17.22096879 13.67125453 -37.1471375 -68.68858407]\n", - " [ 13.67125453 34.5737961 -26.37449298 -170.10871631]\n", - " [ -37.1471375 -26.37449298 81.32448107 133.30724227]\n", - " [ -68.68858407 -170.10871631 133.30724227 843.49816474]]\n" - ] - } - ], - "source": [ - "# Results summary\n", - "print(\"======Results Summary======\")\n", - "print(\"Four design criteria log10() value:\")\n", - "print(\"A-optimality:\", np.log10(result.trace))\n", - "print(\"D-optimality:\", np.log10(result.det))\n", - "print(\"E-optimality:\", np.log10(result.min_eig))\n", - "print(\"Modified E-optimality:\", np.log10(result.cond))\n", - "print(result.FIM)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Optimality Conditions\n", - "**D-Optimality:** Maximizes the determinant of $M$ or minimizes the determinant of $V$ \t\n", - "* Computation: Determinant\n", - "* Geometric interpretation: Minimizes the volume of the confidence ellipsoid \n", - "\n", - "**A-Optimality:** Maximizes the trace of $M$ or minimizes the trace of $V$ \t\n", - "* Computation: Trace \t\n", - "* Geometric interpretation: Minimizes the dimensions of the enclosing box around the confidence ellipsoid \t\n", - "\n", - "**E-Optimality:** Minimizes the variance of the most uncertain parameter \t \n", - "* Computation: Eigenvalue \t\n", - "* Geometric interpretiation: Minimizes the size of the major axis of the confidence ellipsoid \n", - "\n", - "**Modified E-Optimality:** Reduces the correlations between parameters \t \n", - "* Computation: Condition number \t \n", - "* Geometric interpretation: Transforms the confidence ellipsoid into a round sphere " - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['C[CB,0.125]', 'C[CB,0.25]', 'C[CB,0.5]', 'C[CB,0.75]', 'C[CB,0.875]', 'C[CC,0.125]', 'C[CC,0.25]', 'C[CC,0.5]', 'C[CC,0.75]', 'C[CC,0.875]']\n" - ] - } - ], - "source": [ - "# Choose a subset of measurements and get the results without resolving the model\n", - "sub_name = \"C\"\n", - "sub_indices = {0: [\"CB\", \"CC\"], 1: [0.125, 0.25, 0.5, 0.75, 0.875]}\n", - "\n", - "# Measurement subset\n", - "measure_subset = MeasurementVariables()\n", - "measure_subset.add_variables(sub_name, indices=sub_indices, time_index_position=1)\n", - "print(measure_subset.variable_names)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "======Subset Results Summary======\n", - "Four design criteria log10() value:\n", - "A-optimality: 2.7312606650205398\n", - "D-optimality: 1.8213450338458799\n", - "E-optimality: -1.430816119614162\n", - "Modified E-optimality: 4.147090377578492\n" - ] - } - ], - "source": [ - "# Subset results summary\n", - "sub_result = result.subset(measure_subset)\n", - "sub_result.result_analysis()\n", - "print(\"======Subset Results Summary======\")\n", - "print(\"Four design criteria log10() value:\")\n", - "print(\"A-optimality:\", np.log10(sub_result.trace))\n", - "print(\"D-optimality:\", np.log10(sub_result.det))\n", - "print(\"E-optimality:\", np.log10(sub_result.min_eig))\n", - "print(\"Modified E-optimality:\", np.log10(sub_result.cond))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 5: Method for Optimization\n", - "Gradient-based optimization with Ipopt using stochastic_program().\n", - "\n", - "We first fix the experiment design decisions and solve the simulation problem (zero degrees of freedom). This facilitates initialization.\n", - "\n", - "Next, we unfix the experiment design variables and resolve the optimization problem (positive number of degrees of freedom).\n", - "\n", - "This allows us to compute the best time-varying piecewise-constant temperature profile for the batch reactor experiment." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "# Experiment\n", - "exp1 = [5, 500, 300, 300, 300, 300, 300, 300, 300, 300]\n", - "exp1_design_dict = dict(zip(design_names, exp1))\n", - "design_gen.update_values(exp1_design_dict)\n", - "\n", - "# Add prior information (scaled FIM with T=500 and T=300 experiments)\n", - "prior = np.asarray(\n", - " [\n", - " [28.67892806, 5.41249739, -81.73674601, -24.02377324],\n", - " [5.41249739, 26.40935036, -12.41816477, -139.23992532],\n", - " [-81.73674601, -12.41816477, 240.46276004, 58.76422806],\n", - " [-24.02377324, -139.23992532, 58.76422806, 767.25584508],\n", - " ]\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26424\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2590\n", - "\n", - "Total number of variables............................: 7092\n", - " variables with only lower bounds: 2312\n", - " variables with lower and upper bounds: 784\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7092\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 0.0000000e+00 7.67e+02 1.00e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (296034)\n", - " 1 0.0000000e+00 6.31e+02 3.85e+02 -1.0 7.66e+02 - 2.54e-03 9.90e-01f 1\n", - " 2 0.0000000e+00 1.42e+02 1.31e+02 -1.0 9.10e+02 - 9.17e-02 9.90e-01h 1\n", - " 3 0.0000000e+00 2.07e+01 1.75e+01 -1.0 1.43e+02 - 9.37e-01 9.90e-01h 1\n", - " 4 0.0000000e+00 1.52e-03 1.41e+02 -1.0 1.86e+01 - 9.94e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (393945)\n", - " 5 0.0000000e+00 4.55e-13 1.00e-06 -1.0 1.55e-03 - 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 5\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Dual infeasibility......: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Constraint violation....: 2.2737367544323206e-13 4.5474735088646412e-13\n", - "Complementarity.........: 0.0000000000000000e+00 0.0000000000000000e+00\n", - "Overall NLP error.......: 2.2737367544323206e-13 4.5474735088646412e-13\n", - "\n", - "\n", - "Number of objective function evaluations = 6\n", - "Number of objective gradient evaluations = 6\n", - "Number of equality constraint evaluations = 6\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 6\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 5\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 0.584\n", - "Total CPU secs in NLP function evaluations = 0.017\n", - "\n", - "EXIT: Optimal Solution Found.\n", - "Ipopt 3.13.2: linear_solver=ma57\n", - "halt_on_ampl_error=yes\n", - "max_iter=3000\n", - "\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit http://projects.coin-or.org/Ipopt\n", - "\n", - "This version of Ipopt was compiled from source code available at\n", - " https://github.com/IDAES/Ipopt as part of the Institute for the Design of\n", - " Advanced Energy Systems Process Systems Engineering Framework (IDAES PSE\n", - " Framework) Copyright (c) 2018-2019. See https://github.com/IDAES/idaes-pse.\n", - "\n", - "This version of Ipopt was compiled using HSL, a collection of Fortran codes\n", - " for large-scale scientific computation. All technical papers, sales and\n", - " publicity material resulting from use of the HSL codes within IPOPT must\n", - " contain the following acknowledgement:\n", - " HSL, a collection of Fortran codes for large-scale scientific\n", - " computation. See http://www.hsl.rl.ac.uk.\n", - "******************************************************************************\n", - "\n", - "This is Ipopt version 3.13.2, running with linear solver ma57.\n", - "\n", - "Number of nonzeros in equality constraint Jacobian...: 26544\n", - "Number of nonzeros in inequality constraint Jacobian.: 0\n", - "Number of nonzeros in Lagrangian Hessian.............: 2610\n", - "\n", - "Reallocating memory for MA57: lfact (273960)\n", - "Total number of variables............................: 7112\n", - " variables with only lower bounds: 2316\n", - " variables with lower and upper bounds: 794\n", - " variables with only upper bounds: 0\n", - "Total number of equality constraints.................: 7102\n", - "Total number of inequality constraints...............: 0\n", - " inequality constraints with only lower bounds: 0\n", - " inequality constraints with lower and upper bounds: 0\n", - " inequality constraints with only upper bounds: 0\n", - "\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 0 -1.1850752e+01 7.70e+02 1.75e+00 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0\n", - "Reallocating memory for MA57: lfact (303416)\n", - " 1 -1.3675099e+01 2.82e+02 1.02e+00 -1.0 1.74e+01 - 5.78e-01 5.20e-01h 1\n", - " 2 -1.4089220e+01 2.17e+01 1.63e+00 -1.0 1.13e+01 - 9.61e-01 1.00e+00f 1\n", - " 3 -1.3921907e+01 1.69e+00 3.69e+00 -1.0 6.63e+01 - 9.32e-01 1.00e+00f 1\n", - " 4 -1.3336947e+01 2.31e+01 1.65e+01 -1.0 1.77e+02 - 1.00e+00 1.00e+00f 1\n", - " 5 -1.3222146e+01 1.86e+01 1.00e+01 -1.0 1.99e+02 - 1.00e+00 1.00e+00h 1\n", - " 6 -1.3243949e+01 2.13e-01 6.39e-01 -1.0 1.01e+01 - 1.00e+00 1.00e+00h 1\n", - " 7 -1.3252911e+01 1.32e-03 1.78e-02 -1.7 5.37e-01 - 1.00e+00 1.00e+00h 1\n", - " 8 -1.3275341e+01 5.50e-02 1.07e+00 -3.8 4.82e+00 - 9.24e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (319294)\n", - " 9 -1.3682468e+01 1.73e+01 2.63e+01 -3.8 8.88e+01 - 5.41e-01 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 10 -1.4419541e+01 8.07e+01 9.14e+01 -3.8 5.70e+02 - 2.57e-01 5.52e-01h 1\n", - " 11 -1.4227603e+01 2.35e+01 2.67e+00 -3.8 7.85e+01 - 7.14e-01 1.00e+00h 1\n", - " 12 -1.4224985e+01 3.88e-01 5.16e-01 -3.8 2.90e+01 - 1.00e+00 1.00e+00h 1\n", - " 13 -1.4226481e+01 2.67e-02 5.57e-03 -3.8 6.57e+00 - 1.00e+00 1.00e+00h 1\n", - " 14 -1.4226282e+01 1.91e-05 5.93e-06 -3.8 1.11e-01 - 1.00e+00 1.00e+00h 1\n", - " 15 -1.4292847e+01 1.06e+00 7.22e-01 -5.7 4.62e+01 - 7.74e-01 1.00e+00f 1\n", - "Reallocating memory for MA57: lfact (339585)\n", - " 16 -1.4306021e+01 5.87e-02 4.67e-02 -5.7 2.09e+01 - 1.00e+00 1.00e+00h 1\n", - " 17 -1.4307820e+01 1.18e-02 2.10e-03 -5.7 9.64e+00 - 1.00e+00 1.00e+00h 1\n", - " 18 -1.4307833e+01 3.56e-04 4.99e-06 -5.7 1.70e+00 - 1.00e+00 1.00e+00h 1\n", - " 19 -1.4307833e+01 2.54e-07 3.05e-09 -5.7 4.55e-02 - 1.00e+00 1.00e+00h 1\n", - "iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls\n", - " 20 -1.4309105e+01 8.75e-04 2.56e-04 -8.6 2.68e+00 - 9.92e-01 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (358657)\n", - "Reallocating memory for MA57: lfact (392921)\n", - " 21 -1.4309111e+01 2.81e-06 7.65e-08 -8.6 1.52e-01 - 1.00e+00 1.00e+00h 1\n", - " 22 -1.4309111e+01 8.54e-12 2.66e-08 -8.6 2.66e-04 -4.0 1.00e+00 1.00e+00h 1\n", - "Reallocating memory for MA57: lfact (450838)\n", - "Reallocating memory for MA57: lfact (477335)\n", - " 23 -1.4309111e+01 3.31e-12 5.52e-09 -8.6 1.66e-04 -4.5 1.00e+00 1.00e+00h 1\n", - "\n", - "Number of Iterations....: 23\n", - "\n", - " (scaled) (unscaled)\n", - "Objective...............: -1.4309111333867460e+01 -1.4309111333867460e+01\n", - "Dual infeasibility......: 5.5189781291491592e-09 5.5189781291491592e-09\n", - "Constraint violation....: 3.3140157285060923e-12 3.3140157285060923e-12\n", - "Complementarity.........: 2.5059035851932608e-09 2.5059035851932608e-09\n", - "Overall NLP error.......: 5.5189781291491592e-09 5.5189781291491592e-09\n", - "\n", - "\n", - "Number of objective function evaluations = 24\n", - "Number of objective gradient evaluations = 24\n", - "Number of equality constraint evaluations = 24\n", - "Number of inequality constraint evaluations = 0\n", - "Number of equality constraint Jacobian evaluations = 24\n", - "Number of inequality constraint Jacobian evaluations = 0\n", - "Number of Lagrangian Hessian evaluations = 23\n", - "Total CPU secs in IPOPT (w/o function evaluations) = 2.472\n", - "Total CPU secs in NLP function evaluations = 0.059\n", - "\n", - "EXIT: Optimal Solution Found.\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO: elapsed time: 5.6\n" - ] - } - ], - "source": [ - "# Create doe_object using DesignOfExperiments\n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict, # dictionary of parameters\n", - " design_gen, # design variable\n", - " measure_class, # measurement variable\n", - " create_model, # model\n", - " prior_FIM=prior, # FIM of prior experiments\n", - " discretize_model=disc_for_measure, # discretized model\n", - ")\n", - "\n", - "# Stochastic programming for optimization; see above for how the function solves twice\n", - "square_result, optimize_result = doe_object.stochastic_program(\n", - " if_optimize=True, # optimize\n", - " if_Cholesky=True, # use Cholesky decomposition\n", - " scale_nominal_param_value=True, # scale model parameter value\n", - " objective_option=\"det\", # objective option\n", - " L_initial=np.linalg.cholesky(prior), # initial Cholesky decomposition\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "======Results Summary======\n", - "This optimization is solved with status: converged\n", - "C solution: 5.0\n", - "T solution:\n", - "579.3896781590472\n", - "300.00008825998646\n", - "300.0001449066281\n", - "300.0002011134464\n", - "300.00026910716224\n", - "300.00037503303196\n", - "300.00058304040493\n", - "300.00119444148544\n", - "300.00410830698996\n", - "The result FIM is: \n", - " [[ 46.26165475 24.02303687 -111.13766257 -98.84248628]\n", - " [ 24.02303687 56.00005105 -41.78107762 -257.31551935]\n", - " [-111.13766257 -41.78107762 290.39184707 177.30569633]\n", - " [ -98.84248628 -257.31551935 177.30569633 1245.5926873 ]]\n", - "Four design criteria log10() value:\n", - "A-optimality: 3.2143791799119263\n", - "D-optimality: 6.214368093237916\n", - "E-optimality: 0.007877626397731468\n", - "Modified E-optimality: 3.1198074131681715\n" - ] - } - ], - "source": [ - "# Results summary\n", - "print(\"======Results Summary======\")\n", - "print(\"This optimization is solved with status:\", optimize_result.status)\n", - "print(\"C solution:\", pyo.value(optimize_result.model.CA0[0]))\n", - "print(\"T solution:\")\n", - "for t in t_control:\n", - " print(pyo.value(optimize_result.model.T[t]))\n", - "\n", - "print(\"The result FIM is: \\n\", optimize_result.FIM)\n", - "print(\"Four design criteria log10() value:\")\n", - "print(\"A-optimality:\", np.log10(optimize_result.trace))\n", - "print(\"D-optimality:\", np.log10(optimize_result.det))\n", - "print(\"E-optimality:\", np.log10(optimize_result.min_eig))\n", - "print(\"Modified E-optimality:\", np.log10(optimize_result.cond))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 6: Method for Exploratory Analysis through Enumeration\n", - "\n", - "This method conducts exploratory analysis using enumeration. \n", - "It allows a user to define any number (dimensions) of design variables." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Specify user inputs" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [], - "source": [ - "# Design variable ranges as lists\n", - "design_ranges = {\n", - " \"CA0[0]\": [1, 3, 5],\n", - " (\n", - " \"T[0]\",\n", - " \"T[0.125]\",\n", - " \"T[0.25]\",\n", - " \"T[0.375]\",\n", - " \"T[0.5]\",\n", - " \"T[0.625]\",\n", - " \"T[0.75]\",\n", - " \"T[0.875]\",\n", - " \"T[1]\",\n", - " ): [300, 500, 700],\n", - "}\n", - "\n", - "# Choose from 'sequential_finite', 'direct_kaug'\n", - "# sensi_opt = \"sequential_finite\"\n", - "sensi_opt = \"direct_kaug\"" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The prior information FIM:\n", - " [[22.52943024, 1.84034314, -70.23273336, -11.09432962], [1.84034314, 18.09848116, -5.73565034, -109.15866135], [-70.23273336, -5.73565034, 218.94192843, 34.57680848], [-11.09432962, -109.15866135, 34.57680848, 658.37644634]]\n", - "Prior Det: 1.9558434494323278e-08\n" - ] - } - ], - "source": [ - "# Add prior information\n", - "prior_pass = [\n", - " [22.52943024, 1.84034314, -70.23273336, -11.09432962],\n", - " [1.84034314, 18.09848116, -5.73565034, -109.15866135],\n", - " [-70.23273336, -5.73565034, 218.94192843, 34.57680848],\n", - " [-11.09432962, -109.15866135, 34.57680848, 658.37644634],\n", - "]\n", - "\n", - "# Print prior information\n", - "print(\"The prior information FIM:\\n\", prior_pass)\n", - "print(\"Prior Det:\", np.linalg.det(prior_pass))" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO: =======Iteration Number: 1 =====\n", - "INFO: elapsed time: 1.5\n", - "INFO: This is run 1 out of 9.\n", - "INFO: The code has run 1.4800095079999664 seconds.\n", - "INFO: Estimated remaining time: 5.180033277999883 seconds\n", - "INFO: =======Iteration Number: 2 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 2 out of 9.\n", - "INFO: The code has run 2.2786834119997366 seconds.\n", - "INFO: Estimated remaining time: 4.557366823999473 seconds\n", - "INFO: =======Iteration Number: 3 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 3 out of 9.\n", - "INFO: The code has run 3.0774706169995625 seconds.\n", - "INFO: Estimated remaining time: 3.846838271249453 seconds\n", - "INFO: =======Iteration Number: 4 =====\n", - "INFO: elapsed time: 0.6\n", - "INFO: This is run 4 out of 9.\n", - "INFO: The code has run 3.6389742199989996 seconds.\n", - "INFO: Estimated remaining time: 2.9111793759991995 seconds\n", - "INFO: =======Iteration Number: 5 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 5 out of 9.\n", - "INFO: The code has run 4.463020823998704 seconds.\n", - "INFO: Estimated remaining time: 2.231510411999352 seconds\n", - "INFO: =======Iteration Number: 6 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 6 out of 9.\n", - "INFO: The code has run 5.244051230999503 seconds.\n", - "INFO: Estimated remaining time: 1.4983003517141438 seconds\n", - "INFO: =======Iteration Number: 7 =====\n", - "INFO: elapsed time: 0.6\n", - "INFO: This is run 7 out of 9.\n", - "INFO: The code has run 5.848174373999427 seconds.\n", - "INFO: Estimated remaining time: 0.7310217967499284 seconds\n", - "INFO: =======Iteration Number: 8 =====\n", - "INFO: elapsed time: 0.7\n", - "INFO: This is run 8 out of 9.\n", - "INFO: The code has run 6.5564294039986635 seconds.\n", - "INFO: Estimated remaining time: 0.0 seconds\n", - "INFO: =======Iteration Number: 9 =====\n", - "INFO: elapsed time: 0.9\n", - "INFO: This is run 9 out of 9.\n", - "INFO: The code has run 7.479818032998082 seconds.\n", - "INFO: Estimated remaining time: -0.7479818032998082 seconds\n", - "INFO: Overall wall clock time [s]: 7.479818032998082\n" - ] - } - ], - "source": [ - "# Create doe_object using DesignOfExperiments\n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict, # dictionary of parameters\n", - " design_gen, # design variable\n", - " measure_class, # measurement variable\n", - " create_model, # model\n", - " prior_FIM=prior_pass, # FIM of prior experiments\n", - " discretize_model=disc_for_measure, # discretized model\n", - ")\n", - "# Grid search\n", - "all_fim = doe_object.run_grid_search(\n", - " design_ranges, # range of design variables\n", - " mode=sensi_opt, # solver option for sensitivity\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Step 7: Results through Sensitivity Curves and Heatmaps" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### 1D Sensitivity Curve\n", - "\n", - "1D sensitivity curves can be drawn by one design variable and fixing other design variables." - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " CA0[0] \\\n", - "0 1.0 \n", - "1 1.0 \n", - "2 1.0 \n", - "3 3.0 \n", - "4 3.0 \n", - "5 3.0 \n", - "6 5.0 \n", - "7 5.0 \n", - "8 5.0 \n", - "\n", - " (T[0], T[0.125], T[0.25], T[0.375], T[0.5], T[0.625], T[0.75], T[0.875], T[1]) \\\n", - "0 300.0 \n", - "1 500.0 \n", - "2 700.0 \n", - "3 300.0 \n", - "4 500.0 \n", - "5 700.0 \n", - "6 300.0 \n", - "7 500.0 \n", - "8 700.0 \n", - "\n", - " A D E ME \n", - "0 918.207526 5.129865 0.002829 2.402240e+05 \n", - "1 917.979819 0.052028 0.000288 2.358410e+06 \n", - "2 917.951300 0.000610 0.000020 3.457451e+07 \n", - "3 920.297448 415.446336 0.025426 2.676791e+04 \n", - "4 918.248082 4.208215 0.002590 2.624381e+05 \n", - "5 917.991412 0.048511 0.000174 3.907348e+06 \n", - "6 924.477291 3205.559576 0.070438 9.688727e+03 \n", - "7 918.784607 32.467061 0.007192 9.455956e+04 \n", - "8 918.071634 0.373747 0.000482 1.408681e+06 \n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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KbZ169Zh4sSJUCgU+O677/DRRx8p93311VcAgAcPHsDV1bVM9RNRxWLSRUTV2smTJwttCw4ORteuXYvdXxHWrFmDSZMmQQiB5cuXY8aMGVqJg4g0h0kXEZGOWbVqFaZMmQIA+OGHH/DBBx9oOSIi0gQmXUREOuSnn37C1KlTlX9///33tRwREWkKB9ITEemIlStXKlu1Vq9ezYSLqIph0kVEpAMCAwMxffp0yGQyrFu3DuPHj9d2SESkYexeJCLSstjYWMycOROSJGHjxo0YPXq0tkMionLAli4iIi0TQij/fPjwoZajIaLywqSLiEjL6tatq5x3a+7cufjhhx+0HBERlQcmXUREOmDu3LmYO3cuAGD69OkaXTKIiHQDky4iIh3x1VdfYfr06RBCYMKECdixY4e2QyIiDWLSRUSkQ5YvX45x48YhLy8PI0eOxIEDB7QdEhFpCJMuIiIdIkkS1qxZg2HDhiEnJweDBw/G8ePHtR0WEWkAky4iIh0jk8kQFBSEfv36ITMzEwMGDMDp06e1HRYRqYlJFxGRDjIwMMD27dvRrVs3pKWloU+fPoiIiNB2WESkBiZdREQ6ysjICH/88Qc6dOiA58+fo0ePHoiMjNR2WERURpyRnojoH7p06aKcsLQ8jR07FmPHji2xjKmpKU6dOlXusRBR+WPSRURUji5evAgfHx8AwPz589G7d2+N1Dtv3jyEhIQgKytLI/URUflj0kVEVI5SUlIQFhYGAHjy5InG6r1+/bqyXiKqHCRREW3oRERERNUcB9ITERERVQAmXUREREQVgEkXERERUQVg0kVERERUAZh0EREREVUAJl1EREREFYBJFxEREVEFYNJFREREVAGYdBERERFVACZdRERERBWASRcRERFRBfg/49AlAORjCQEAAAAASUVORK5CYII=\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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IlJNlXYEB4CoqCiMGDECV65ceb7TF/ouFO2+TZs22L59O9zd3TU9nF5iaKLa5kh4PD757SZSsvJhKJXgw15NMTnQHYYGGjdgExFVmSrtCA4ATZo0wT///IO///4bR48eRUREBDIzM2FpaQkPDw/06dMHPXr00MahiEjH0nIKEHwwHL9djQMANKtnhW+G+8GrgUzHlRERVS6ttDQRW5qodjgTmYTZe27gSVoupBLg3UB3fNirKUwMDXRdGhFRhVR6S1N4eDju3bsHBwcHtG/f/qXbX7hwAUlJSWjSpAk8PT0rckgi0qHsfDm++Os2tl18CABwszXH8mF+8Hetef0TiYjKonZoys7ORu/evZGcnIwTJ06o9BghBN544w00aNAAd+/ehYmJidqFEpFuXH7wFLN2hyImJRsAMKaDK+b0aw5zY63N901EVC2o3WNzx44dePLkCSZMmICOHTuq9JiOHTti4sSJiI2Nxc6dO9UukoiqXm5BIZb8dRtD111ATEo2GshM8cs77RD8ujcDExHVSmqHpv3790MikeD9999X63EffvghhBDYu3evuockoioWFpeGAavPYt3p+xACGOrfEIdndEWnJmUPYEtEVNOp/efitWvXUL9+fTRv3lytxzVt2hROTk64du2auockoipSUKjAmhP38N3xSMgVAnaWJlgy2AdBnvV0XRoRkc6pHZqSk5Ph5+dXoYM1aNAAN27cqNBjiahyRSZkYNbuUNx4lAYAeMXHEYsH+sDGwljHlRER6Qe1Q5OpqSlycnIqdLCcnBwYG/MDmEifFCoENp6NxldH7yJfroDMzAifve6FAX4NOMkuEdEL1A5N9evXx71795CXl6fWXXB5eXm4d+8eXFxc1D0kEVWShynZ+Gh3KEIePAUAdGtmj6VDfFHP2lTHlRER6R+1O4J36dIFubm52LNnj1qP2717N3JyctClSxd1D0lEWiaEwC+XYtB35WmEPHgKC2MDfDnYB5vGtmFgIiIqg9qhaezYsRBCYM6cOYiNjVXpMQ8fPsTs2bMhkUgwZswYtYskIu2JT8vFmE3/4NN9YcjOL0S7RjY4/GFXvNnWhZfjiIjKoXZo6tixI4YOHYrHjx+jXbt22L17NxQKRanbKhQK7Nq1C+3bt0dCQgKGDBmCTp06aVw0EalPCIH91+LQe8UpnI5IgomhFP951RM7JraH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MHDgwDL3Y2Fhgfr16yM6OhqFhYUl+jUV9WUq6tv0byYmJsXuuNOmxIzyA5O62xEREZHmql1omjBhQqnLT58+jcjISAwYMAD29vZwc3N76b4CAwOxc+dOnDt3Dl27di227siRI8ptqpqDVemBsKLbERERkeYkQojyus5UG2PHjsXmzZtx4cIFtG/fvti65ORkJCcnw87ODnZ2dsrlJ06cQI8ePdClSxf873//g7GxMQDg77//RlBQELp06aLy4Jbp6emQyWRIS0tTdiKvqEKFQOelxxGflltqvyYJAEeZKc7O6QEDqUSjYxEREdVm6nx/V7s+TRWxevVqtGjRAqtXry62vHv37njnnXdw5swZtGrVCrNnz8aYMWPQv39/WFtb44cfftBJvQZSCRa+5gngeUB6UdG/F77mycBERERUhWpFaCrPunXrsGrVKkgkEqxatQp//vknXnvtNYSEhMDT01NndfX1ro8fRraGo6z4JThHmSl+GNkafb3r66gyIiKi2qnGXJ7TNW1enntRaSOCs4WJiIhIO9T5/q52HcFrGwOpBB3cbXVdBhERUa1X6y/PEREREamCoYmIiIhIBQxNRERERCpgaCIiIiJSAUMTERERkQoYmoiIiIhUwNBEREREpAKGJiIiIiIVMDQRERERqYAjgmtJ0Ww06enpOq6EiIiIVFX0va3KrHIMTVqSkZEBAHB2dtZxJURERKSujIwMyGSycrfhhL1aolAo8PjxY1hZWUEi0e6Euunp6XB2dkZsbKxWJwOmqsNzWL3x/FV/PIfVX2WdQyEEMjIy0KBBA0il5fdaYkuTlkilUjRs2LBSj2Ftbc03ezXHc1i98fxVfzyH1V9lnMOXtTAVYUdwIiIiIhUwNBERERGpgKGpGjAxMcHChQthYmKi61KogngOqzeev+qP57D604dzyI7gRERERCpgSxMRERGRChiaiIiIiFTA0ERERESkAoYmIiIiIhUwNFWB1NRUvP/+++jQoQMcHR1hYmICJycn9OjRA3v37i11vpv09HTMnDkTrq6uMDExgaurK2bOnFnu3Hbbt29H27ZtYWFhgbp16+KVV17B5cuXK/Op1VrLli2DRCKBRCLBxYsXS92G51C/uLm5Kc/Zv38mT55cYnueP/21b98+BAUFwdbWFmZmZmjUqBFGjBiB2NjYYtvxHOqXn3/+ucz3YNFP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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Extract criteria from FIM\n", - "all_fim.extract_criteria()\n", - "print(all_fim.store_all_results_dataframe)\n", - "\n", - "# Draw 1D sensitivity curve\n", - "# This problem has two degrees of freedom; to draw a 1D curve, it needs to fix one dimension\n", - "fixed = {\"'CA0[0]'\": 5.0}\n", - "\n", - "all_fim.figure_drawing(\n", - " fixed,\n", - " [\n", - " (\n", - " \"T[0]\",\n", - " \"T[0.125]\",\n", - " \"T[0.25]\",\n", - " \"T[0.375]\",\n", - " \"T[0.5]\",\n", - " \"T[0.625]\",\n", - " \"T[0.75]\",\n", - " \"T[0.875]\",\n", - " \"T[1]\",\n", - " )\n", - " ],\n", - " \"Reactor case\",\n", - " \"T [K]\",\n", - " \"$C_{A0}$ [M]\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Heatmaps\n", - "\n", - "Heatmaps can be drawn using two design variables and fixing other design variables." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Interpreting Heatmaps\n", - "\n", - "A heatmap shows the change of the objective function (the experimental information content) in the design region. \n", - "\n", - "Horizontal and vertical axes are two design variables, while the color of each grid shows the experimental information content.\n", - "\n", - "The color of each grid is based on a gradient of information. A darker color refers to an area with more information content whereas the lighter color refers to an area with less information content." - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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cvD333+jXbt26NevH0xNTRXK/vXXXwAePxDg6elZbX2yxeU3btxQ2L9kyRLMnz8flZWVNfblyWAiPT0d5eXlaN++fZPlekpPT0dlZSV0dHRgb29fbZkePXoAgPyHqqpnn322Qe3W91oEQcA777yDVatW1Vruyc+sf//+eP7553Hy5ElYWVnB19cXL774Iry9vdGnTx+lheay+7lz504cO3as2vozMzMBKN/P5nLjxg0cOnQIgHJg9vLLL8PU1BS5ubmIi4vDK6+8olKdsntpbW0NAwODass09L7L9td0XmM4ODgo7evYsaNKx4uLixX2N+T71FwMDQ0xZswYbNy4Edu3b8esWbMAAHfu3MHevXuhra2N8ePHN3s/iFoLjpi1MbI8ZomJibh69SqOHj0KIyMjfPjhh4iOjlYoW1BQAAD4559/kJiYWO0me8KypKREfl5CQgI++eQTSCQSLFmyBKmpqSguLkZlZSUEQUBwcDAAoLy8XH6O7GlAWQ6rpiD7serYsWONr8Lp1KkTAKCoqKja4zX9sNemIdeyZcsWrFq1CgYGBli1ahXS0tLw4MEDCI+XG8hHj578zDQ0NPD7779j9uzZ0NPTw6+//ooPPvgAffv2hZ2dncITgcC/9zM9Pb3G+3n9+nUAivezJjk5OfIRmCe32p7Aq2rr1q2orKxEnz59lIJYbW1tjBkzRv75qEp23y0sLGosU9d9r+ncus5rDH19faV9T35vazsuCILC/oZ8n5rTlClTAPw7QgY8fuq1vLwcw4YNg5mZWYv0g6g14IhZGzdgwACsW7cOr732GmbPno1hw4bB2NgYwON/6QKPp5SqBm21kaU4+Oijj/Dxxx8rHa8uRYVsaq269A4NJev/P//8A0EQqg3Obt++rdB+U2jItcg+s5UrV2LatGlKx2tK62FqaoqIiAh88cUXOHv2LBISEhATE4NDhw4hICAAhoaGGD16NIB/P49169bJp+Qao7S0FImJiUr7tbRU/2tFFnCdPn261vdI/vrrrygsLJR/N2sju87c3Nway9R13//55x906dJFab+szqb8vjSHhn6fmounpyecnJxw+vRpnD9/Hj179uQ0JlENOGJGGDFiBF544QXk5eUhPDxcvr979+4AoJS7qS6yXGgeHh7VHn9ybZmMo6MjtLW1kZ+fj8uXL6vUTl0vhO7atSs0NDRQ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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAj8AAAHcCAYAAAA5lMuGAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABZxElEQVR4nO3deVxUVeM/8M8wwLAjiIgiiwtuuOCGqSii4lJ9za1cQUXc0lx7zK1An1zSUstKywVUFDNLK5dcUiJRMypNRXN5BFHDnU1kP78//M3kCOgwM8xlmM/79bov5c6995x7Z2Q+nnPuuTIhhAARERGRiTCTugJEREREhsTwQ0RERCaF4YeIiIhMCsMPERERmRSGHyIiIjIpDD9ERERkUhh+iIiIyKQw/BAREZFJYfghIiIik8LwQ0RkAMnJyZDJZPD29pa6Ks81atQoyGQyREdHq62Pjo6GTCbDqFGjJKkXkT4x/JgAb29vyGQytcXKygp169bFiBEj8Ntvv0ldxXJLT09HZGQkVq1aJXVVSEvPfi7NzMzg4OAADw8PBAcHY/78+UhKSpK6mhpbtWoVIiMjkZ6eLnVVDIr/FskYMfyYEB8fH3Tq1AmdOnWCj48P0tLSsHXrVnTo0AFbtmyRunrlkp6ejgULFvAXbhWg/Fx27NgRDRs2hFwux+HDh7Fo0SL4+vpi0KBBuH//vtTVfKFVq1ZhwYIFZYYfCwsLNGrUCPXr1zdsxfTE0dERjRo1Qq1atdTW898iGSNzqStAhjN37ly1JuuHDx9i3Lhx2LlzJyZNmoRXX30VTk5O0lWQTNKzn0sAuHfvHrZu3Yr3338f33zzDc6fP4+TJ0/C0dFRmkrqgbu7Oy5evCh1NbTWv39/9O/fX+pqEOkFW35MmJOTEzZs2ABbW1tkZWXh4MGDUleJCADg4uKCqVOnIjExEbVq1cLFixcxbdo0qatFRFUEw4+Jc3BwQMOGDQE8GZBZmgMHDqBv376oWbMmFAoF6tSpg9GjR+Pq1aulbn/y5EnMmjULbdu2haurKxQKBTw8PBASEoLz588/tz5///03xo0bhwYNGsDa2hrVq1dHmzZtEBERgX/++QfAkwGZdevWBQCkpKSUGM/0rL1796J3795wcXGBQqFA3bp18eabbyI1NbXUOijHoiQnJ+Po0aPo06cPXFxcIJPJEBcX99z6l/dclA4dOoTJkyejZcuWcHZ2hpWVFerXr4+JEyfi+vXrpR6/sLAQH3/8Mfz9/WFvbw+FQoHatWujY8eOiIiIKLX7pbCwEGvXrkVAQACqVasGKysrNG7cGPPnz0dmZqbG52YoXl5e+PzzzwEAMTExZb5nZSkoKMDq1avh7+8PBwcH2NraomXLlli0aBFycnJKbP/0oGQhBFavXo3mzZvDxsYGrq6uCAkJKfF+KAcCp6SkAADq1q2r9nlUfmaeN+D56c/url270LFjR9jZ2aFmzZoYOXIk0tLSVNtGRUWhTZs2sLW1haurKyZMmICMjIwSxywqKsJ3332HsLAw+Pr6wtHRETY2NmjSpAlmzZqFe/fuletaljbgWZN/i0OGDIFMJsNHH31U5rF37twJmUyGdu3alatORFoTVOV5eXkJACIqKqrU1xs1aiQAiE8++aTEa1OnThUABADh6uoqWrVqJRwcHAQA4eDgIBISEkrsU79+fQFAVK9eXTRr1ky0bNlSODo6CgDC2tpaHD16tNR6xMTECEtLS9V2rVu3Fo0bNxYKhUKt/osWLRJt27YVAIRCoRCdOnVSW542e/ZsVf3r1Kkj2rRpI2xsbAQA4eTkJH777bcyr9fixYuFmZmZcHJyEu3atRN16tQps+7anouSXC4XMplMuLq6Cj8/P9GsWTNha2uruo7nz58vUcbAgQNV51a/fn3Rrl074eHhIeRyuQAg/vzzT7XtMzIyRJcuXQQAYWZmJry8vESzZs1U9WzSpIm4ffu2RuenDy/6XCoVFRWJ2rVrCwBi/fr1Gh8/JydHdOvWTXWNmjRpIlq0aCHMzMwEAOHn5yfu3bunts+1a9cEAOHl5SUmTpwoAAhPT0/Rpk0bYWVlJQCIGjVqiIsXL6r22bdvn+jUqZPqvW3btq3a5/GPP/4ocexnKev4ySefqD6rLVu2VB2zadOm4vHjx2LKlCkCgKhXr57w9fUV5ubmAoAIDAwUxcXFasdMTU1Vvde1atVSfQaV5+Ht7S3S0tJK1GXkyJGlvi9RUVECgBg5cqRqnSb/Fg8cOCAAiObNm5f5Xr366qsCgPj000/L3IZInxh+TMDzvmQuXbqk+gUaHx+v9tratWsFAFG3bl21L/3CwkLx/vvvq35JP378WG2/TZs2iatXr6qtKygoEOvXrxfm5uaiXr16oqioSO313377TVhYWAgAYtasWSI7O1v1Wn5+voiNjRW//PKLat3zvkiUfvjhBwFAmJubi5iYGNX6jIwM0b9/f9UXQE5OTqnXSy6XiwULFoiCggIhhBDFxcUiNze3zPK0PRchhPjiiy/EzZs31dbl5OSIRYsWCQCia9euaq8lJiYKAMLDw0MkJSWpvZaRkSHWrVsnrl+/rrZ+yJAhAoDo3r272vvz4MEDMWDAAAFADBo06IXnpy+ahh8h/g1648eP1/j4M2fOFABE7dq1xe+//65af/nyZdG4cWMBQLzxxhtq+yg/V+bm5sLCwkLExsaqXrt3757o0aOHACD8/f1LhA3l+Vy7dq3U+mgSfmxtbcW2bdtU61NTU0WDBg0EANGvXz/h6OgoDh8+rHr9r7/+Es7OzgKA2Ldvn9ox09PTRXR0tLh//77a+ocPH4rJkycLAGLUqFEl6lKe8POi8xLiSXj19PQUAFRB8Gm3b98W5ubmwtLSskRdiSoKw48JKO1LJiMjQxw6dEg0bdpUACjRYpKXlyfc3NyEXC4v9ReWEP9+IW3evFnjuowYMUIAKNFi9PLLLwsAIiwsTKPjaBJ+OnXqJACIqVOnlnjt0aNHwsXFRQAQGzZsUHtNeb3+7//+T6O6PKu85/IiAQEBAoC4ceOGal1sbKwAIKZPn67RMc6cOaO6XpmZmSVef/TokfDw8BAymUwkJyfrpd4vUp7wM23aNAFA9O/fX6NjZ2RkqFr4du3aVeL1U6dOCQBCJpOJK1euqNYrP1cAxJQpU0rsd/v2bVXLyZEjR0o9H13CT2mf1S+++EL1+sqVK0u8rmzdLK2+z+Ph4SFsbGxU4V5J3+FHCCHefffdMs9vxYoVBg/eRBzzY0JGjx6t6ot3dHREcHAwLl68iMGDB+OHH35Q2/bEiRNIS0tD69at0apVq1KP17dvXwDAzz//XOK1ixcvIiIiAgMGDEDXrl0REBCAgIAA1bZnzpxRbfv48WMcOnQIADBr1iy9nGt2djZOnDgBAHjrrbdKvG5jY4OxY8cCQJkDvUNDQ8tdri7nkpiYiNmzZ6Nv374IDAxUXbNLly4BAP766y/Vth4eHgCAn376CQ8ePHjhsXft2gUAeOONN2Bvb1/idRsbG/To0QNCCPzyyy/lqrch2NraAgCysrI02v7YsWPIycmBp6cnXnvttRKvt2vXDh06dIAQQvV+PWvSpEkl1rm6umLQoEEAnoyF07cxY8aUWOfn56f6e1hYWInXlf8+//e//5V6zCNHjmD69Ol45ZVX0KVLF9XnKiMjAzk5Obh8+bJ+Kv8cyt8927ZtQ0FBgdprmzZtAgBOnkgGxVvdTYiPjw9cXV0hhEBaWhr+97//wcLCAu3atStxi/vZs2cBPBmkGRAQUOrxlANqb968qbZ+yZIlmD9/PoqLi8usy9Nf2FeuXEFBQQGqVauGRo0aaXNqJVy5cgXFxcVQKBSoV69eqdv4+voCgCpcPKtJkyZalVvecxFCYPLkyaqBvWV5+pp16NAB7du3x6+//qqaFLBLly4IDAxE69atSwz8Vr6fu3btwvHjx0s9vnLA7rPvZ2WQnZ0N4MkAfU0o39PGjRuXOggeePL+nzhxotT338LCAg0aNCh1P+XnoqzPjS5KmwOoRo0aqj9LO3/l68prpJSfn4/Bgwdj9+7dzy1Tk/Csq7p166Jr1644evQo9u/fr/qP05kzZ3DmzBm4ubmhd+/eFV4PIiWGHxPy7HwqCQkJ6NevH95++23UrFkTI0aMUL2mvHvk7t27uHv37nOP+/jxY9Xf4+PjMXfuXMjlcixZsgR9+/aFl5cXbGxsIJPJMH/+fCxatEjtf3/Ku4yqVaumh7N8QvlFUKNGjTK//GrWrAmg7NYEZWtDeWhzLlu2bMHnn38OW1tbLF++HMHBwXB3d4e1tTUAYMSIEdi6davaNTMzM8P+/fuxYMECxMTE4LvvvsN3330H4MkdUpGRkWrvtfL9vHLlCq5cufLc+jz9fpYlLS1N1QLytFatWmH16tUv3L+8lHdYubq6arS98v1/3vbPe/+rV68OM7PSG8Zf9LnRhY2NTYl1ys9vaa89/boQQm390qVLsXv3bri5uWHZsmXo0qUL3NzcoFAoAAABAQFISEgo0RJTUcLCwnD06FFs2rRJFX6UrT4jRoyAXC43SD2IAIYfk9apUyesW7cO/fv3x9SpU9G3b1/V/yzt7OwAAMOHD0dMTIzGx9y6dSsA4D//+Q9mz55d4vXSblVWdsPo87EAyvrfvXsXQohSA9Dt27fVytcHbc5Fec0++ugjjB8/vsTrZd3e7eTkhFWrVmHlypU4c+YM4uPjsXv3bhw9ehSjR4+GnZ2dKqAor8e6desQHh5enlMqVW5uLhISEkqsNzfX/6+U4uJiVRemv7+/Rvsoz/fOnTtlbvO89//+/fsoLi4uNQApj6nPz01FUH6uoqOj0atXrxKvl3faAF0NHDgQkydPxp49e3D//n04Ojpi27ZtANjlRYbHMT8mrl+/fnjppZfw4MEDrFixQrW+adOmAIBz586V63jKuYI6duxY6utPj/VR8vHxgaWlJdLT0/H3339rVE5ZrTlKDRo0gJmZGfLy8socC6Gcc0g5z5E+aHMuz7tmBQUFuHDhwnP3l8lk8PPzw5QpU3DkyBFV6Fy3bp1qG23fz7Io58F5dinPPEia2r17N9LS0mBhYYGePXtqtI/yPb1w4UKJFhGl573/BQUFZc5jpXw/nt3vRZ9JQ3ve5+r+/ft6697U9Lytra0xZMgQ5OfnIzY2Fvv378ft27fRtm1bVRc0kaEw/JDqy/KTTz5RdRd07twZLi4uOHPmTLm+0JRdNcr/VT/t4MGDpYYfa2tr1Zfahx9+WK5yyuqisbOzU/3SL60b5vHjx1i/fj0AlPq/Ym3pci6lXbOoqKgXdjs+66WXXgIA3Lp1S7VO+ViCmJgYo3hOllJKSgomT54M4MkAdHd3d432CwgIgI2NDVJTU1XdgU9LTEzEiRMnIJPJEBwcXOoxShuDdffuXXz99dcAUCKIvegzaWjP+1x99NFHKCoq0ms5mpy3csD2pk2bONCZpCXNTWZkSC+6pbi4uFg0adJEABDLli1Trf/8888FAOHi4iK+/fbbEvOanD17VsyaNUscO3ZMtW758uWqSff+97//qdafOnVKuLu7q24TjoiIUDvW03PjzJkzRzx69Ej1Wn5+vti+fbva3DjFxcXC3t5eACgxz42Scp4fCwsLsXXrVtX6zMxMMWjQoBfO81PWLcsvUt5zmTRpkgAg2rdvL+7cuaNav3//fuHg4KC6Zk+/fzExMWLhwoUl6njv3j3VxH6hoaFqr73xxhsCgGjVqlWJ6QsKCwvF0aNHxbBhwzSay0gfnve5vHv3rvj4449V0xE0bdpUZGRklOv4ynl+3N3d1c73ypUrqikeBg8erLbP0/P8WFpaih07dqheu3//vujZs6dqIsNn/z288sorAoBYs2ZNqfXR5Fb38u4nhBBHjx5VTXRYWn369u0rsrKyhBBP/t1s2rRJWFhYqD5Xz07cWd5b3TX5t/i0Zs2aqV1jzu1DUmD4MQGazKeyYcMGAUC4ubmpTVr49AzJzs7Ool27dqJ169aqidUAiP3796u2z8jIEPXq1RMAhKWlpWjevLlqBummTZuKGTNmlBp+hBBiy5YtqtBgY2MjWrduLZo0aVLql78QQoSFhQkAwsrKSrRt21YEBgaW+AJ4uv4eHh6ibdu2qpmTnZycxKlTp8q8XtqGn/KeS0pKiup6WltbCz8/P+Ht7S0AiKCgIDF8+PAS+6xcuVJ1Xu7u7qJdu3ZqszW7u7uLlJQUtTplZWWJ4OBg1X6enp6iffv2onnz5sLa2lq1/tlJKyuK8jr7+PioZgRu27at6tyVy+uvv67VF2ROTo4ICgpSHadp06aiZcuWqhmwW7ZsqdEMz15eXqJt27aqa1S9evVSv+Q3b96sKqtZs2aqz6Nypm1Dh5/ExETVDNEODg6iTZs2qpmyQ0JCRGBgoF7CjxCa/VtU+uijj1Tny7l9SCoMPyZAk/CTl5en+sX42Wefqb2WkJAghg0bJjw8PISlpaVwdnYWLVq0EGFhYWLv3r0iPz9fbftbt26J0NBQ4eLiIiwtLUXdunXFjBkzREZGhoiIiCgz/AghxPnz58Xo0aOFp6ensLS0FC4uLqJNmzYiMjJS/PPPP2rbZmVlialTpwpvb29V0CjtC+SHH34QwcHBwsnJSVhaWgovLy8xYcKEEjMgP3u9dAk/5T2Xv//+WwwYMEA4OjoKKysr0bhxY7FgwQKRl5dX6pfR9evXxQcffCCCg4OFp6ensLKyEtWrVxetW7cW77//vnj48GGpdSoqKhJbt24VvXr1Ei4uLsLCwkLUqlVLtG/fXrzzzjulhsGKorzOTy92dnaiTp06okePHmLevHkatSQ8T35+vvj4449Vodfa2lo0b95cvP/++2otckpPB43i4mLx8ccfi2bNmgkrKyvh4uIihg8f/txJID/++GPRokULtTCpDBeGDj9CCPHrr7+K4OBgYWdnJ2xtbYWfn5/45JNPRHFxsV7Dj6b/FoUQ4s6dO6oAumfPnlK3IapoMiHKGA1IRGRikpOTUbduXXh5eZX5oF/SzcWLF9GkSRO4ubnhxo0bvMWdJMEBz0REZDAbNmwAAISEhDD4kGQYfoiIyCCuXbuGL774AnK5vNQ5rYgMhZMcEhFRhZo2bRpOnTqFM2fOICcnB+PGjSv1UR5EhsKWHyIiqlCnT5/GiRMnYG9vjylTpmDVqlVSV4lMHAc8ExERkUlhyw8RERGZFI750bPi4mLcunUL9vb2le5ZP0RE9GJCCGRlZaF27dqlPtxWX3Jzc5Gfn6/zcSwtLWFlZaWHGpkOhh89u3XrFjw8PKSuBhER6Sg1NRV16tSpkGPn5ubCxtoa+hh34ubmhmvXrjEAlQPDj57Z29sDAFI9AAd2KlZ5b6ZIXQMypG+lrgAZhACQi39/n1eE/Px8CADWAHTpIxAA0tLSkJ+fz/BTDgw/eqbs6nIwY/gxBZZSV4AMih3ZpsUQQxfk0D38UPkx/BAREUmE4UcabJsgIiIik8KWHyIiIomYgS0/UmD4ISIikogZdOuCKdZXRUwMww8REZFE5NAt/HAQvnY45oeIiIhMClt+iIiIJKJrtxdph+GHiIhIIuz2kgYDJxEREZkUtvwQERFJhC0/0mD4ISIikgjH/EiD15yIiIhMClt+iIiIJGKGJ11fZFgMP0RERBLRtduLj7fQDru9iIiIyKSw5YeIiEgicrDbSwoMP0RERBJh+JEGww8REZFEOOZHGhzzQ0RERCaF4YeIiEgicj0s5ZGeno4pU6agQ4cOcHNzg0KhgLu7O7p164ZvvvkGQphGWxLDDxERkUQMHX7u3buHjRs3wtbWFv369cPMmTPRp08fnD9/HoMGDcL48eP1cl6VHcf8EBERmYi6desiPT0d5ubqX/9ZWVl46aWXsG7dOkydOhW+vr4S1dAw2PJDREQkERn+HfSszVLeB5vK5fISwQcA7O3t0atXLwDAlStXtDgT48KWHyIiIonoequ7vkbo5Obm4siRI5DJZGjatKmejlp5MfwQEREZuczMTLWfFQoFFApFmdunp6dj1apVKC4uxp07d7Bv3z6kpqYiIiICPj4+FV1dyTH8EBERSUTXeX6U+3p4eKitj4iIQGRkZJn7paenY8GCBaqfLSwssHz5csycOVOH2hgPhh8iIiKJ6KvbKzU1FQ4ODqr1z2v1AQBvb28IIVBUVITU1FRs374d8+bNw/Hjx7Fjx45SxwVVJVX77IiIiEyAg4ODWvjRlFwuh7e3N2bPng25XI5Zs2Zh3bp1mDhxYgXUsvLg3V5EREQSMfQ8P8/Ts2dPAEBcXJwej1o5seWHiIhIIvoa86MPt27dAoAq3+UFsOWHiIhIMoZu+Tl9+jQyMjJKrH/w4AHmzp0LAOjTp48WZ2Jcqn68IyIiIgBAdHQ01q9fj6CgIHh5ecHW1hYpKSnYu3cvsrOzMXDgQAwbNkzqalY4hh8iIiKJmEG3cTvF5dx+0KBByMjIwMmTJxEfH4+cnBw4OzsjICAAoaGhGDJkCGSy8s4bbXwYfoiIiCRi6DE/AQEBCAgI0KHEqoFjfoiIiMiksOWHiIhIIrrerl7ebi96guGHiIhIIpXpVndTwutGREREJoUtP0RERBJht5c0GH6IiIgkwvAjDXZ7ERERkUlhyw8REZFEOOBZGgw/REREEtF1hucifVXExDD8EBERSUTXMT+67GvK2GJGREREJoUtP0RERBLhmB9pMPwQERFJhN1e0mBoJCIiIpPClh8iIiKJsNtLGgw/REREEmG3lzQYGomIiMiksOWHiIhIImz5kUalb/lJT0/HlClT0KFDB7i5uUGhUMDd3R3dunXDN998AyFEiX0yMzMxY8YMeHl5QaFQwMvLCzNmzEBmZmaZ5Wzbtg3+/v6wtbWFk5MTXn75ZSQmJlbkqRERkYmT4d9xP9osMsNXuUqo9OHn3r172LhxI2xtbdGvXz/MnDkTffr0wfnz5zFo0CCMHz9ebftHjx4hMDAQK1euRKNGjTB9+nQ0bdoUK1euRGBgIB49elSijMWLF2P48OG4ffs2JkyYgDfeeAMJCQno1KkT4uLiDHSmREREZAgyUVrTSSVSVFQEIQTMzdV76LKysvDSSy8hKSkJ586dg6+vLwAgIiICCxcuxKxZs/DBBx+otleuf++997BgwQLV+suXL6Np06aoV68eTp06BUdHRwDA+fPn4e/vj1q1auHixYslyi9LZmYmHB0dkeEFOFT6aEm6CrsmdQ3IkL6SugJkEALAYwAZGRlwcHCokDKU3xVvAlDocJw8AJ+jYutaFVX6r2e5XF5q8LC3t0evXr0AAFeuXAEACCGwfv162NnZ4b333lPbfs6cOXBycsKGDRvUusqioqJQWFiIefPmqYIPAPj6+iI0NBRXr17FkSNHKuLUiIjIxMn1sFD5VfrwU5bc3FwcOXIEMpkMTZs2BfCkFefWrVvo1KkTbG1t1ba3srJCly5dcPPmTVVYAqDq1urZs2eJMpTh6ueff66gsyAiIlOmy3gfXecIMmVGc7dXeno6Vq1aheLiYty5cwf79u1DamoqIiIi4OPjA+BJ+AGg+vlZT2/39N/t7Ozg5ub23O2JiIioajCq8PP0WB0LCwssX74cM2fOVK3LyMgAALXuq6cp+0OV2yn/7urqqvH2z8rLy0NeXp7q5+fdUUZERPQ03uouDaNpMfP29oYQAoWFhbh27RoWLlyIefPmYeDAgSgsLJSsXkuWLIGjo6Nq8fDwkKwuRERkXNjtJQ2ju25yuRze3t6YPXs23n//fezatQvr1q0D8G+LT1ktNcpWmadbhhwdHcu1/bPmzJmDjIwM1ZKamlr+kyIiIiKDMbrw8zTlIGXloOUXjdEpbUyQj48PsrOzkZaWptH2z1IoFHBwcFBbiIiINMG7vaRh1OHn1q1bAKC6Fd7Hxwe1a9dGQkJCickMc3NzER8fj9q1a6NBgwaq9YGBgQCAgwcPljj+gQMH1LYhIiLSJzPoFnyM+ktcQpX+up0+fbrUbqkHDx5g7ty5AIA+ffoAAGQyGcLDw5GdnY2FCxeqbb9kyRI8fPgQ4eHhkMn+nRB89OjRMDc3x6JFi9TKOX/+PDZv3oz69eujW7duFXFqREREJIFKf7dXdHQ01q9fj6CgIHh5ecHW1hYpKSnYu3cvsrOzMXDgQAwbNky1/axZs/D9999j2bJl+PPPP9GmTRucOXMG+/fvh5+fH2bNmqV2/IYNGyIyMhLz589HixYtMGjQIDx69AixsbEoKCjAunXrNJ7dmYiIqDx0HbRc6VswKqlK/60+aNAgZGRk4OTJk4iPj0dOTg6cnZ0REBCA0NBQDBkyRK0lx9bWFnFxcViwYAF27tyJuLg4uLm5Yfr06YiIiCgx+SEAzJs3D97e3li1ahXWrFkDS0tLdOzYEQsXLkS7du0MebpERGRCeKu7NCr9s72MDZ/tZVr4bC/Twmd7mQZDPtvrPQBWOhwnF8BC8Nle5VXpW36IiIiqKrb8SIPhh4iISCIc8yMNhh8iIiKJsOVHGgyNREREZFLY8kNERCQRdntJg+GHiIhIIsoZnnXZn8qP142IiIhMCsMPERGRRAz9YNObN29i1apV6NmzJzw9PWFpaQk3NzcMHDgQv/76q17OyRiw24uIiEgihh7zs3r1anzwwQeoX78+goOD4erqisuXL2P37t3YvXs3YmNj8cYbb+hQI+PA8ENERGQi/P39ER8fj86dO6ut/+WXX9C9e3dMnDgRr732GhQKhUQ1NAx2exEREUnE0N1eAwYMKBF8AKBz584ICgrCgwcPcPbsWe1Oxoiw5YeIiEgilWmSQwsLCwCAuXnVjwZV/wyJiIiquMzMTLWfFQpFubqurl+/jsOHD8PNzQ3NmzfXd/UqHXZ7ERERScRMDwsAeHh4wNHRUbUsWbJE4zoUFBQgJCQEeXl5WLZsGeTyqv/QDLb8EBERSURf3V6pqalwcHBQrde01ae4uBhhYWGIj4/H2LFjERISokNtjAfDDxERkURk0K0LRvb//3RwcFALP5oQQmDs2LGIiYnBiBEjsHbtWh1qYlzY7UVERGRiiouLMWbMGGzcuBFDhw5FdHQ0zMxMJxKw5YeIiEgiUtztVVxcjPDwcERFRWHw4MHYsmWLSYzzeRrDDxERkUQMHX6ULT7R0dF4/fXXERMTY3LBB2D4ISIiMhkLFy5EdHQ07Ozs0LBhQ7z//vsltunXrx/8/PwMXzkDYvghIiKSiKGf7ZWcnAwAyM7OxqJFi0rdxtvbm+GHiIiIKoahu72io6MRHR2tQ4lVg+kM7SYiIiICW36IiIgkU5me7WVKGH6IiIgkYugxP/QErxsRERGZFLb8EBERScQMunVdsQVDOww/REREEmG3lzQYfoiIiCTCAc/SYGgkIiIik8KWHyIiIomw5UcaDD9EREQS4ZgfafC6ERERkUlhyw8REZFE2O0lDYYfIiIiiTD8SIPhh4iIiCRXUFCA3377DceOHUNKSgru3r2Lx48fw8XFBTVq1EDr1q3RuXNnuLu761wWww8REZFEZNBt8K1MXxWR0NGjR7F+/Xrs3r0bubm5AAAhRIntZLInZ9ukSROEhYUhNDQULi4uWpXJ8ENERCQRU+72+uGHHzBnzhxcuHABQgiYm5vDz88P7dq1Q61ateDs7Axra2s8ePAADx48QFJSEn777TckJSXh7bffxty5czFu3Di8++67qFGjRrnKZvghIiIig+rSpQsSEhJgbW2NN954A0OGDEGvXr1gZWX1wn2vXr2K7du3IzY2Fp9++ik2bdqEzZs347XXXtO4fN7qTkREJBEzPSzG6Ny5c3j33Xdx48YNxMbG4rXXXtMo+ABA/fr1MW/ePJw7dw4//fQT2rRpg7/++qtc5bPlh4iISCKm2u2VkpICe3t7nY8TFBSEoKAgZGVllWs/hh8iIiKJmGr40Ufw0eV4xtpiRkRERKQVtvwQERFJhM/2KltOTg4eP34MZ2dn1W3u+sLwQ0REJBFT7fZ6VmZmJr7//nvEx8erJjlUzvkjk8ng7OysmuSwZ8+eaNeunU7lyURpMwmR1jIzM+Ho6IgML8ChKkdyAgCEXZO6BmRIX0ldATIIAeAxgIyMDDg4OFRIGcrvij8A2OlwnGwArVGxda1Ip06dwmeffYZvvvkGjx8/LnVyw6cpW4CaNWuG8PBwjBkzBjY2NuUuly0/REREEjGDbq03xvp/7EuXLmHOnDnYvXs3hBBwcXFB//794e/v/9xJDk+dOoWEhAQcP34c06ZNw+LFixEZGYmxY8fCzEzzq8HwQ0REJBFTHfPj6+sLABg8eDBGjhyJHj16QC4vPQa6urrC1dUVjRs3xoABAwAAN2/eRGxsLNasWYM333wT9+/fx9y5czUun+GHiIiIDCo0NBRz585F/fr1tdrf3d0db7/9NqZPn46tW7eWe0A0ww8REZFETHXA84YNG/RyHLlcjtDQ0HLvx/BDREQkEVPt9pIaww8REZFETLXlR2oMP0RERGRw8fHxOh+jS5cuWu3H8FNRfgKg30eXUCW0savUNSBDmnJB6hqQIWQD6Gygsky55adr1646zdwsk8lQWFio1b4MP0RERBLhmB+gVq1asLa2NmiZDD9EREQkCSEEsrOz0atXL4wYMQJBQUEGKbcqhEYiIiKjpJzhWdvFmL/Ez5w5g5kzZ8LOzg5RUVHo0aMHvLy8MHfuXCQlJVVo2cZ83YiIiIyaLsFH1/FCUmvevDmWL1+O1NRUHDx4ECNGjEB6ejqWLl2K5s2bo3Xr1li5ciXS0tL0XjbDDxEREUlGJpOhR48e2LRpE9LS0hATE4OePXvi3LlzmDlzJjw8PNC7d29s3boVOTk5eimT4YeIiEgiZnpYqhJra2sMGzYM+/fvx40bN7BixQr4+fnh4MGDCA0NxaBBg/RSDgc8ExERScSUb3V/EVdXV4SGhsLS0hJ3797F9evXtb61/VkMP0RERFRp5Ofn4/vvv0dMTAx+/PFHFBQUAHgyL9Cbb76plzIYfoiIiCQixTw/MTEx+OWXX/D777/j7NmzyM/PR1RUFEaNGqVDTXQXHx+PmJgY7Ny5ExkZGRBCwNfXFyNGjMDw4cNRp04dvZXF8ENERCQRKbq95s+fj5SUFLi4uKBWrVpISUnRoQa6uXjxIrZs2YJt27bh+vXrEELAzc0No0ePRkhICPz8/CqkXIYfIiIiiUgRftavXw8fHx94eXlh6dKlmDNnjg410F67du3wxx9/AABsbGwwbNgwhISEoEePHjAzq9ih3Aw/REREJqRHjx5SVwEA8Pvvv0Mmk6FRo0bo378/bG1tkZiYiMTERI2PMXfuXK3KZvghIiKSiuz/L9oS/38xYhcvXsTSpUvLtY8QAjKZjOGHiIjI6Mihe/gpBDIzM9VWKxQKKBQKXWpW4UaOHClZ2Qw/RERERs7Dw0Pt54iICERGRkpTGQ1FRUVJVjbDDxERkVT01PKTmpoKBwcH1erK3uojNYYfIiIiqZhB9/ADwMHBQS380PMx/BAREZHBXb9+XedjeHp6arUfww8REZFU9NHtZaTq1q2r0/4ymUzrZ30x/BAREUnFhMOPELpVXpf9GX6IiIhMyPr163Hs2DEAwNmzZ1Xr4uLiAAD9+vVDv379Krwe165dq/AyysLwQ0REJBU9DXguj2PHjmHTpk1q6xISEpCQkAAA8Pb2Nkj48fLyqvAyysLwQ0REJBVdH+teXP5doqOjER0drUOhxq9inxxGREREZTPTw2KkPvnkE3zzzTeSlG3El42IiIiM1bRp0/Dxxx+X+lq3bt0wbdq0Ciub3V5ERERSkUO3ZghdxgtVYnFxcVrfxq4Jhh8iIiKpMPxIgt1eREREZFLY8kNERCQVIx+0bKwYfoiIiKTCbi9JMPwQERGRJO7cuYPNmzeX+zWl0NBQrcqVCV0frkFqMjMz4ejoiIwrgIO91LWhCtdV6gqQIZ2+IHUNyBCyAXQGkJGRAQcHhwopQ/VdUQ9wkOtwnCLA8X8VW9eKYmZmBplM+6YrPtiUiIjIGOk65seImy88PT11Cj+6YPghIiIig0tOTpasbIYfIiIiqcj//0IGxfBDREQkFRPu9pISZxcgIiKSilwPixHKycmR9HgMP0RERGRQ3t7e+OCDD5Cdna3TcY4fP47evXvjo48+Ktd+GnV71atXT6tKlUUmk+Hq1at6PSYREZHRMeLWG13Uq1cPc+bMwdKlSzFgwAAMGTIE3bp1g1z+4otx69YtfPXVV9i6dSv+/PNPWFtbY/z48eUqX6Pwo+8R2VLd2kZERFSpmOiYn5MnT+Lrr7/GvHnzEBUVhejoaFhZWaFVq1Zo06YNatWqBWdnZygUCqSnp+PBgwe4cOECEhMTkZKSAiEEzM3NER4ejgULFsDNza1c5Ws0yaGZmRnatWuHHTt2aH2iSq+//jp+//13FBUV6XysyoiTHJqYrlJXgAyJkxyaBoNOcthKD5Mc/mmckxwCgBACP/74I7788kvs27cPBQUFAEpvJFHGlbp16yIsLAxhYWGoVauWVuVqfLeXQqGAl5eXVoU8exwiIiLCk1YfXbq9jLTlR0kmk6FPnz7o06cPcnJycOLECRw/fhwpKSm4d+8ecnNz4ezsDFdXV/j5+SEgIAANGjTQuVyNwk/fvn3RrFkznQsDgM6dO8PFxUUvxyIiIjJquo75MfLw8zQbGxt0794d3bt3r/CyNAo/u3fv1luBixcv1tuxiIiIiMrLYLe6X7p0yVBFERERGQczPSxVRL169TBkyBCNth06dCjq16+vdVkaX7YPP/xQ60L++usvBAYGar0/ERFRlWSikxyWJjk5Gbdu3dJo27S0NJ3uRNc4/Lzzzjv4+OOPy13AqVOnEBQUhDt37pR7XyIiIqJn5ebmwtxc+yd0lavBbMaMGfjss8803v7nn39GcHAwHj58iA4dOpS7ckRERFUau73K7d69e0hKSkLNmjW1PobGsWnjxo0YM2YMpkyZAnNz8xfOpvjjjz9i4MCBePz4Mbp3747vvvtO60oSERFVSSZ8t9emTZuwadMmtXVnz55Ft27dytzn8ePHSEpKQnZ2NgYNGqR12RqHn5EjR6KoqAhjx47FpEmTIJfLER4eXuq23377LYYNG4b8/Hz83//9H3bs2MH5fYiIiJ5lwuEnOTkZcXFxqp9lMhkyMjLU1pWlW7duWLp0qdZll6vDLCwsDMXFxRg/fjwmTJgAc3NzjBo1Sm2bzZs3Izw8HIWFhRg8eDC2bNmiU78cERERVT2jRo1C165dATyZvblbt25o3rw5Pvnkk1K3l8lksLa2Rt26dXWeL7DcqSQ8PBxFRUV48803ER4eDrlcjpCQEADAmjVr8NZbb6G4uBhhYWFYt24dn+NFRERUFhl0G7djxF+xXl5eak+O6NKlC1q2bGmQu8O1apIZP348iouLMWnSJISFhcHc3BypqamYM2cOhBCYMmUKVq1apeeqEhERVTG6dnsV66si0tOku0tftO6PmjhxIoqKijBlyhSEhIRACAEhBObMmYNFixbps45ERERkQlJTU/HLL7/g5s2bePz4Md577z3VawUFBRBCwNLSUuvj6zQYZ/LkyRBCYOrUqZDJZFiyZAneeecdXQ5JRERkOtjyo+bevXuYNGkSvvnmG9VT3AGohZ/Ro0cjNjYWp06dQps2bbQqR+Oexnr16pW6rFy5EhYWFpDL5fjiiy/K3E6Xaai9vb0hk8lKXSZMmFBi+8zMTMyYMQNeXl6qp9HPmDEDmZmZZZaxbds2+Pv7w9bWFk5OTnj55ZeRmJiodZ2JiIheiPP8qGRlZSEwMBBff/013N3dMWrUKLi7u5fYLjw8HEIIfPvtt1qXpXHLjybTSD9vG10HPjs6OmLatGkl1rdt21bt50ePHiEwMBCnT59GcHAwhg4dijNnzmDlypU4evQojh07BltbW7V9Fi9ejHnz5sHT0xMTJkxAdnY2tm/fjk6dOuHAgQOq0ehERERUMZYtW4YLFy5g4MCB2Lx5M6ytrdG5c2fcvHlTbbsuXbrA2toaR48e1bosjcNPVFSU1oXoQ7Vq1RAZGfnC7ZYtW4bTp09j1qxZ+OCDD1TrIyIisHDhQixbtgwLFixQrb98+TIiIiLQsGFDnDp1Co6OjgCAKVOmwN/fH+Hh4bh48SJv1yciIv1jt5fKzp07oVAosH79elhbW5e5nZmZGRo0aIDr169rXVa5Jjms7IQQWL9+Pezs7NT6BwFgzpw5WL16NTZs2IDIyEhVS1RUVBQKCwsxb948VfABAF9fX4SGhmLt2rU4cuQIevbsadBzISIiE6Br11UV6vZKTk5Gw4YN1b6Ly2JjY4O///5b67KM5rLl5eVh06ZNWLx4MdasWYMzZ86U2Oby5cu4desWOnXqVKJry8rKCl26dMHNmzdx5coV1XrlrXWlhZtevXoBePKMMiIiIqo4VlZWyMrK0mjbf/75R6OQVBaj6ctJS0srMZt07969sWXLFtVMj5cvXwYA+Pj4lHoM5frLly+r/d3Ozg5ubm7P3b4seXl5yMvLU/38vEHVREREatjtpeLr64tff/0VKSkpapMfPuv06dO4fv06evfurXVZGrX8bN68GQcOHNC6kKcdOHAAmzdvLtc+YWFhiIuLw927d5GZmYmTJ0+iT58++PHHH9G3b1/V7XAZGRkAUGYadHBwUNtO+ffybP+sJUuWwNHRUbV4eHiU69yIiMiEmeHfAKTNYjT9Ny82YsQIFBUVYdy4ccjJySl1m4cPH2LMmDGQyWQIDQ3VuiyNLtuoUaP0NnHh+++/j9GjR5drn/feew+BgYFwcXGBvb092rdvjz179iAgIAAnTpzAvn379FI3bcyZMwcZGRmqJTU1VbK6EBGRkeGt7ipjx45F586dcejQITRv3hyzZ8/G7du3AQAbN27EjBkz0KhRI/z5558IDg7GkCFDtC7LaC+bmZmZKkQlJCQA+LfFp6yWGmWX1NMtPY6OjuXa/lkKhQIODg5qCxERUWX222+/4eWXX4aTkxNsbW3h7++Pbdu2SVonuVyOPXv2YPDgwbh27RqWL1+OK1euQAiBsWPHYtWqVbh37x7eeOMNfPPNNzqVpfGYn7Nnz6Jbt246FaY8jr4ox/oom8deNEantDFBPj4+OHHiBNLS0kqM+3nRGCIiIiKd6DrmR4t94+Li0KtXL1haWmLIkCFwdHTEt99+i+HDhyM5ORlz587VoUK6sbe3R2xsLObOnYtdu3bh7NmzyMjIgJ2dHZo2bYr+/ftrPavz0zQOPxkZGXp76Ji+nvT+66+/AngyAzTwJKTUrl0bCQkJePTokdodX7m5uYiPj0ft2rXRoEED1frAwECcOHECBw8eLNF/qBznZIgnzBIRkQkycPgpLCxEeHg4ZDIZ4uPj0apVKwBP5sLr0KEDIiIi8Prrr0v+n/7mzZujefPmFXZ8jcKPLrMo6iopKQm1a9dGtWrV1NYfO3YMK1asgEKhwIABAwA8CVXh4eFYuHAhFi5cqDbJ4ZIlS/Dw4UO89dZbauFr9OjR+PDDD7Fo0SK89tprqi6u8+fPY/Pmzahfv75eWryIiIikduTIEVy9ehWjR49WBR/gSYvLu+++iyFDhiAqKgqLFy+WsJYVT6PwI2XLx44dO7Bs2TJ0794d3t7eUCgUOHfuHA4ePAgzMzOsXbsWnp6equ1nzZqF77//HsuWLcOff/6JNm3a4MyZM9i/fz/8/Pwwa9YsteM3bNgQkZGRmD9/Plq0aIFBgwbh0aNHiI2NRUFBAdatW8fZnYmIqGIYeJLD581tp1xnCnPbVfpv9aCgIFy4cAF//PEHfv75Z+Tm5qJmzZoYPHgwpk+fDn9/f7XtbW1tERcXhwULFmDnzp2Ii4uDm5sbpk+fjoiIiBKTHwLAvHnz4O3tjVWrVmHNmjWwtLREx44dsXDhQrRr185Qp0pERKZGT91ez84xp1AooFAoSmz+vLGsTk5OcHFxee7cdvoil+ty0k/IZDIUFhZqt694+pnxpLPMzMwnd5BdARzspa4NVbiuUleADOn0BalrQIaQDaAznox1rag7eFXfFWMAB0sdjpMPOG4ouT4iIqLU52H27NkThw4dwuXLl9XGvyrVr18fN27cUJu8tyKYmennZvPiYu1meTTaW92JiIiMnp7m+UlNTVWbc27OnDmGPY9yKi4uLnVZtmwZLCws0LdvX/z4449ISUlBbm4url+/jgMHDqBv376wsLDA8uXLtQ4+gBF0exEREVVZyhmeddkf0HieOU3mw9PlmVm6+Oqrr/DOO+/go48+wrRp09Req1OnDurUqYPg4GB8/PHHmDFjBjw9PfH6669rVRZbfoiIiEzE8+bDe/jwIe7duyfZbe4rV66Em5tbieDzrKlTp6JmzZr46KOPtC6L4YeIiEgqujzXS4vB0sq7tw8ePFjiNeU6qe7wPn/+POrUqaPRth4eHkhKStK6LIYfIiIiqRj42V7du3dHvXr1sG3bNpw+fVq1PisrC//9739hbm6OUaNG6XRK2rKwsMClS5eQm5v73O1yc3Px999/6zQNjcaXrVu3bi9siiIiIqJyMHDLj7m5OdavX4/i4mJ07twZ48aNw9tvv42WLVvi/PnziIyMRMOGDfVzbuXUuXNnZGZm4s0330RRUVGp2xQVFWHSpEnIzMxEly5dtC5L49gUFxen9f30REREVDkEBQXh2LFjiIiIwI4dO5Cfnw9fX1/897//xfDhwyWr1/vvv4/Dhw9j06ZNOHz4MMaMGYMmTZqgRo0auHv3Li5evIgNGzbgxo0bsLKywsKFC7Uui3d7ERERSUWCB5sCgL+/P/bv369DwfrXvHlz7N+/H8OHD8eNGzdKDTdCCLi7u2PLli1o0aKF1mUx/BAREUnFwI+3qOy6dOmCv//+G9u3b8eBAwdw6dIlZGdnw87ODg0bNkTPnj0xdOhQ2NjY6FQOww8RERFVGjY2NggLC0NYWFiFlcHwQ0REJBWJur1MXbnCT0JCgtYPI9PlAWRERERVkgy6dV3J9FUR01KuSy6E0GkhIiIiatasGb766iuds8H169cxYcIEfPDBB+Xar1wtP82bN8cnn3xSrgKIiIioDCba7ZWVlYVhw4Zh/vz5CA0NxZAhQzR+rEZ+fj727t2LrVu34ocffkBRURHWrVtXrvLLFX4cHR0lm/aaiIioyjHR8HPp0iV88sknWLp0KSIiIhAZGYn69evD398fbdq0Qa1ateDs7AyFQoH09HQ8ePAAFy5cQGJiIhITE/Ho0SMIIRAcHIwPPvgAfn5+5SqfA56JiIjIoBQKBf7zn/9gwoQJiImJwbp163D69GlcuXIFsbGxpe6j7CKztbVFWFgYxo0bh3bt2mlVPsMPERGRVEx8nh97e3tMnDgREydOxOXLlxEfH4/jx48jJSUF9+7dQ25uLpydneHq6go/Pz8EBASgY8eOnOeHiIjIaJlot1dpfHx84OPjgzFjxlR4WQw/REREUmH4kYTG4ae4uLgi60FERERkEGz5ISIikoqJj/lRunv3Lr777jv8+uuvuHz5Mh4+fIjHjx/D2toaTk5O8PHxQfv27dG3b1+4urrqXB7DDxERkVTMoFvXlZGHn9zcXMyaNQtffvklCgoKypz0MD4+Hhs3bsTkyZMxduxYLFu2DNbW1lqXy/BDREREBpeXl4euXbvit99+gxACjRs3RqdOnVCvXj04OTlBoVAgLy8PDx8+xP/+9z8kJCTg4sWL+Pzzz3Hq1Cn88ssvsLS01Kpshh8iIiKpmHC31/Lly3Hq1Ck0atQIGzduRIcOHV64z/HjxxEWFobExEQsW7YM8+fP16psI75sRERERk6uh8VIxcbGwtLSEgcPHtQo+ABAx44dceDAAZibm2Pbtm1al83wQ0RERAZ37do1NGvWDB4eHuXaz8vLC82aNUNycrLWZbPbi4iISComPM+PnZ0d7ty5o9W+d+7cga2trdZls+WHiIhIKmZ6WIxUhw4dcPPmTaxYsaJc+3344Ye4efMmOnbsqHXZRnzZiIiIyFjNnj0bZmZm+M9//oOXX34ZO3fuxD///FPqtv/88w927tyJPn364J133oFcLsecOXO0LpvdXkRERFIx4W6vDh06IDo6GuHh4fjxxx9x4MABAE+e+F6tWjVYWloiPz8f6enpyMvLA/Dkye6WlpZYt24dXnrpJa3LZssPERGRVEy42wsAhg8fjosXL2LixIlwc3ODEAK5ublIS0vD9evXkZaWhtzcXAghULNmTUycOBEXL15ESEiITuWy5YeIiEgqJj7DM/Dk7q3PPvsMn332Ga5fv656vEVubi6srKxUj7fw9PTUW5kMP0RERFQpeHp66jXklIXhh4iISComPOZHSgw/REREUjHhx1vo4ubNmygqKtK6lYjhh4iIiIyKn58fHj58iMLCQq32Z/ghIiKSCru9tCaE0Hpfhh8iIiKpMPxIguGHiIiIDG7x4sVa7/v48WOdymb4ISIikooJD3ieP38+ZDKZVvsKIbTeF2D4ISIiko4Jd3vJ5XIUFxdjwIABsLOzK9e+27dvR35+vtZlM/wQERGRwfn6+uLs2bMYO3YsevbsWa599+zZgwcPHmhdthE3mBERERk5GXR7rpf2PT+S8/f3BwAkJiYavGyGHyIiIqnI9bAYKX9/fwgh8Ouvv5Z7X11ucwfY7UVERCQdEx7z06NHD0ydOhUuLi7l3vf7779HQUGB1mUz/BAREZHBeXt7Y+XKlVrt27FjR53KZvghIiKSignf6i4lhh8iIiKpmHC3l5SYGYmIiEgj8fHxePvttxEUFARHR0fIZDKMGjVK6mqVG1t+iIiIpGJkLT8bN27Epk2bYGNjA09PT2RmZurt2HK55idjZmYGe3t7eHt7IyAgAOHh4WjRooXm+2tTQSIiItIDXeb40XW8kBYmT56Mc+fOITMzE1FRUXo9thBC46WoqAjp6ek4ffo0Pv30U7Rp0wbLly/XuCyGHyIiItJI27Zt4evrW65WGk0VFxdjxYoVUCgUGDlyJOLi4vDgwQMUFBTgwYMH+PnnnzFq1CgoFAqsWLEC2dnZSExMxJtvvgkhBGbPno2ffvpJo7LY7VVRamQADg5S14IqWrwRT69K5eYXK3UNyBAyHwN4x0CFmUG3rqsq1ITxzTffYObMmfj0008xceJEtdeqVauGzp07o3PnzmjXrh0mT54Md3d3vP7662jdujXq1auHt99+G59++im6d+/+wrKq0GUjIiIyMnrq9srMzFRb8vLyDHseevDhhx+iVq1aJYLPsyZOnIhatWrho48+Uq2bMmUKHBwccPLkSY3KYvghIiIych4eHnB0dFQtS5YskbpK5Xbu3Dm4u7trtK27uzuSkpJUP5ubm6Nhw4YaP+yU3V5ERERS0dPdXqmpqXB4aqiFQqEocxcXFxfcv39f4yKOHj2Krl27altDjVlYWODSpUvIy8t7bv3z8vJw6dIlmJurR5jMzEzY29trVBbDDxERkVT0FH4cHBzUws/zDB06FFlZWRoX4ebmpk3Nyq1Tp07Yt28fJk+ejC+++AJmZiU7p4QQeOutt5CRkYFXX31VtT4/Px/Xrl1Do0aNNCqL4YeIiEgqEjzeYvXq1ToUWHEWLlyIw4cPY+PGjTh+/DhCQkLQokUL2NvbIzs7G3/99RdiYmKQlJQEhUKBhQsXqvbdtWsXCgoKEBQUpFFZDD9EREQkuVatWuGHH35ASEgILly4gHnz5pXYRggBNzc3bNmyBX5+fqr1NWvWRFRUFDp37qxRWQw/REREUjGyGZ4rWo8ePXD58mVs27YNhw4dwuXLl/Ho0SPY2tqiYcOGCA4OxtChQ2FnZ6e2X3nHJDH8EBERScXIws+xY8ewfv16AMDdu3dV65TP92rcuDFmz56tUxl2dnYYN24cxo0bp9Nxnofhh4iIiDRy5coVbNq0SW3d1atXcfXqVQBAYGCgzuHHEBh+iIiIpCKDbgOeDTzJ/KhRowzyFPdr167h0KFDuHTpErKysmBvb6/q9qpbt67Ox2f4ISIikoqRdXtVtIcPH+LNN9/E119/DSEEgCeDnGWyJylPJpNh8ODB+PTTT+Hk5KR1OQw/REREJLnHjx+je/fuOHPmDIQQ6NChA3x9fVGzZk3cvn0b58+fx4kTJ7B9+3ZcvHgRCQkJsLKy0qoshh8iIiKpSDDPT2W1cuVKnD59Go0bN8bmzZvRtm3bEtskJiZi5MiROH36NFatWqX1+KIqdNmIiIiMjFwPSxWxY8cOyOVy7Nmzp9TgAwBt27bF999/DzMzM2zfvl3rshh+iIiISHJXrlxBs2bNUK9eveduV79+fTRr1gxXrlzRuix2exEREUmFA55V5HI5CgoKNNq2oKCg1Gd/aYotP0RERFIx08NSRTRq1AgXLlzAmTNnnrvd6dOnkZSUhCZNmmhdVhW6bEREREaGY35UQkJCIITAq6++ih9++KHUbb7//nv07dsXMpkMISEhWpfFbi8iIiKS3MSJE7F7924cPXoU/fr1g6enJxo3bgxXV1fcuXMHFy5cQGpqKoQQ6NatGyZOnKh1WQw/REREUjGDbq03Vaj/xtzcHHv37sX8+fOxdu1apKSkICUlRW0bGxsbTJw4Ef/9738hl2t/4Rh+iIiIpMJ5ftRYWVnhww8/REREBI4dO4ZLly4hOzsbdnZ2aNiwIQICAmBvb69zOQw/REREVKnY29ujT58+6NOnT4Ucn+GHiIhIKiZ6q/v169f1chxPT0+t9mP4ISIikoqJdnt5e3urHlaqLZlMhsLCQq32ZfghIiIig/L09NQ5/OiC4YeIiEgqJtrtlZycLGn5DD9ERERSMdHwIzUj7S0kIiIi0g5bfoiIiKRiogOepcbwQ0REJBWZGaDLwF+ZAFCst+qYCoYfIiIiyZgD0OWuJwEgX091MR1sMCMiIiKTwpYfIiIiybDlRwoMP0RERJLRR/ih8mK3FxEREZkUtvwQERFJRg7d2iF4p5c2GH6IiIgkYw6GH8NjtxcRERGZFLb8EBERSYYtP1Jg+CEiIpIMw48U2O1FREREJoUtP0RERJLR9W4vXeYIMl0MP0RERJKR//9FW0X6qohJYfghIiKSjDl0Cz9s+dEGx/wQERGRSWHLDxERkWTY8iMFhh8iIiLJMPxIgd1eREREZFLY8kNERCQZtvxIgeGHiIhIMnLwq9jw2O1FREREL/To0SPExMTgjTfeQMOGDWFtbY1q1aohMDAQsbGxUlevXBg3iYiIJGMOY/kq/uWXXxASEoLq1auje/fuGDhwIO7cuYNvv/0Ww4YNw/Hjx7F69Wqpq6kR47jiREREVZLxhJ9atWph69ateP3112FhYaFav3jxYrRv3x6ffvopQkND0a5dOwlrqRl2exEREdELtWzZEsOGDVMLPgBQs2ZNjB8/HgDw888/S1G1cjOOuElERFQlGU/Lz/MoA5G5uXGcS6Vv+YmOjoZMJnvu0r17d7V9MjMzMWPGDHh5eUGhUMDLywszZsxAZmZmmeVs27YN/v7+sLW1hZOTE15++WUkJiZW9OkREZFJU97tpe3y5Db5zMxMtSUvL89gZ1BUVITNmzdDJpOhR48eBitXF5U+ovn5+SEiIqLU13bu3Inz58+jV69eqnWPHj1CYGAgTp8+jeDgYAwdOhRnzpzBypUrcfToURw7dgy2trZqx1m8eDHmzZsHT09PTJgwAdnZ2di+fTs6deqEAwcOoGvXrhV5ikREZLJ0bfkRAAAPDw+1tREREYiMjNThuJp79913cfbsWYSFhaFZs2YGKVNXMiGEkLoS2sjPz0ft2rWRkZGBGzduoGbNmgCevOELFy7ErFmz8MEHH6i2V65/7733sGDBAtX6y5cvo2nTpqhXrx5OnToFR0dHAMD58+fh7++PWrVq4eLFixo35WVmZsLR0REZGRlwcHDQ4xlTpXSPE4yZFOO6m5e0lPkYcHwHFfp7/N/vij5wcLB48Q5lHqcAjo77kZqaqlZXhUIBhUJR6j4uLi64f/++xmUcPXq0zEaAL7/8EuPHj0erVq0QHx8POzu7ctVfKpW+5acsu3btwv3799GvXz9V8BFCYP369bCzs8N7772ntv2cOXOwevVqbNiwAZGRkZDJnnxpRUVFobCwEPPmzVMFHwDw9fVFaGgo1q5diyNHjqBnz56GOzkiIjIR+mn5cXBw0DioDR06FFlZWRqX4ObmVur6qKgoTJgwAc2bN8ehQ4eMJvgARhx+NmzYAAAIDw9Xrbt8+TJu3bqFXr16lejasrKyQpcuXfDdd9/hypUr8PHxAQDExcUBQKnhplevXli7di1+/vlnhh8iIqoA+gk/5aGPuXg2btyIsWPHomnTpvjpp59QvXp1nY9pSJV+wHNpUlJS8NNPP8Hd3R29e/dWrb98+TIAqILNs5Trldsp/25nZ1dqsi1t+2fl5eWVGGhGRERUVW3cuBHh4eFo3Lgxjhw5gho1akhdpXIzyvATFRWF4uJijB49GnL5vw+Ey8jIAAC17qunKZsEldsp/16e7Z+1ZMkSODo6qpZnB50RERGVTZc7vQx/m/yGDRvUgo+rq6tBy9cXo+v2Ki4uRlRUFGQyGcLCwqSuDubMmYMZM2aofs7MzGQAIiIiDen6YNNifVXkhY4cOYKxY8dCCIEuXbpgzZo1Jbbx8/NDv379DFYnbRld+Dl06BCuX7+O7t27o27dumqvKVtwymqpUXZJPd3So7wzS9Ptn/W8EfVERERVxfXr16G8QfyLL74odZuRI0caRfgxum6v0gY6K71ojE5pY4J8fHyQnZ2NtLQ0jbYnIiLSH7keFsMYNWoUhBDPXaKjow1WH10YVfi5f/8+vvvuOzg7O6N///4lXvfx8UHt2rWRkJCAR48eqb2Wm5uL+Ph41K5dGw0aNFCtDwwMBAAcPHiwxPEOHDigtg0REZF+GdeYn6rCqMLPli1bkJ+fjxEjRpTa1SSTyRAeHo7s7GwsXLhQ7bUlS5bg4cOHCA8PV83xAwCjR4+Gubk5Fi1apNb9df78eWzevBn169dHt27dKu6kiIiIyKCMKjI+r8tLadasWfj++++xbNky/Pnnn2jTpg3OnDmD/fv3w8/PD7NmzVLbvmHDhoiMjMT8+fPRokULDBo0CI8ePUJsbCwKCgqwbt06o3lQGxERGRtdW28MN+C5KjGalp9Tp07h3Llz8Pf3R/PmzcvcztbWFnFxcZg+fTouXryIjz76COfOncP06dMRFxdXYvJDAJg3bx5iYmLg6uqKNWvWYPv27ejYsSMSEhIQFBRUkadFREQmjd1eUjDaZ3tVVny2l4nhs71MC5/tZRIM+2yvN+HgoP0dw5mZeXB0/JzfOeVkNC0/RERERPrA9jIiIiLJ6Np1VaSvipgUhh8iIiLJMPxIgd1eREREZFLY8kNERCQZtvxIgeGHiIhIMro+2LRQXxUxKez2IiIiIpPClh8iIiLJ6Nrtxa9xbfCqERERSYbhRwrs9iIiIiKTwshIREQkGbb8SIFXjYiISDIMP1LgVSMiIpKMrre6y/VVEZPCMT9ERERkUtjyQ0REJBl2e0mBV42IiEgyDD9SYLcXERERmRRGRiIiIsnIodugZQ541gbDDxERkWR4t5cU2O1FREREJoUtP0RERJLhgGcp8KoRERFJhuFHCuz2IiIiIpPCyEhERCQZtvxIgVeNiIhIMgw/UuBVIyIikgxvdZcCx/wQERGRSWHLDxERkWTY7SUFXjUiIiLJMPxIgd1eREREZFIYGYmIiCTDlh8p8KoRERFJhuFHCuz2IiIiIpPCyEhERCQZzvMjBYYfIiIiybDbSwrs9iIiIpKMuR4Ww1m6dCl69uwJDw8PWFtbo3r16mjbti1WrFiBnJwcg9ZFF4yMREREpJEvvvgCLi4uCA4OhqurK7KzsxEXF4eZM2di8+bNOH78OGxsbKSu5gsx/BAREUnGuLq9Lly4ACsrqxLrQ0NDsWXLFkRFRWHSpEkGrZM22O1FREQkGeWAZ20Xww54Li34AMCgQYMAAFeuXDFkdbTG8ENEREQ62bt3LwCgWbNmEtdEM+z2IiIikowcurXePNk3MzNTba1CoYBCodDhuM+3atUqpKenIz09HQkJCUhMTETPnj0RGhpaYWXqE8MPERGRZPQz5sfDw0NtbUREBCIjI3U47vOtWrUKKSkpqp9HjBiBNWvWwMLCosLK1Cd2exERERm51NRUZGRkqJY5c+aUua2LiwtkMpnGS1xcXIljJCcnQwiBf/75B9u2bUNcXBzat2+PGzduVOBZ6g9bfoiIiCSjn5YfBwcHODg4aLTH0KFDkZWVpXEJbm5uz31t6NChaNCgAfz9/TFz5kx89dVXGh9bKgw/REREkjH8re6rV6/WobzStWvXDk5OTqW2ElVG7PYiIiIinWRnZyMjIwPm5sbRpmIctSQiIqqSjOfBpikpKRBCwNvbW219QUEBpk2bhuLiYvTp08dg9dEFww8REZFkjGeG5z///BMDBw5E586d4ePjAxcXF9y+fRuHDx9GamoqGjVqhEWLFhmsPrpg+CEiIpKM8YSf1q1bY+rUqYiPj8euXbuQnp4OOzs7NGnSBJMnT8akSZNga2trsProguGHiIiIXsjT0xMrVqyQuhp6wfBDREQkGeNp+alKeNWIiIgkw/AjBV41PRNCACj5nBWqojSfJ4yqgsdSV4AMITP3yZ/K3+cVWpaO3xX8rtEOw4+eKWfNfPY5K0REZFyysrLg6OhYIce2tLSEm5ubXr4r3NzcYGlpqYdamQ6ZMES0NSHFxcW4desW7O3tIZPJpK6OwWRmZsLDwwOpqakaT7FOxonvtekw1fdaCIGsrCzUrl0bZmYVNxdwbm4u8vPzdT6OpaUlrKys9FAj08GWHz0zMzNDnTp1pK6GZMrzfBkybnyvTYcpvtcV1eLzNCsrK4YWifDxFkRERGRSGH6IiIjIpDD8kF4oFApERERAoVBIXRWqYHyvTQffa6qqOOCZiIiITApbfoiIiMikMPwQERGRSWH4ISIiIpPC8ENEREQmheGHtBYTE4Px48ejbdu2UCgUkMlkiI6OlrpapGfp6emYMmUKOnToADc3NygUCri7u6Nbt2745ptvDPL8IzIsb29vyGSyUpcJEyZIXT0inXGGZ9La/PnzkZKSAhcXF9SqVQspKSlSV4kqwL1797Bx40a89NJL6NevH5ydnXHnzh388MMPGDRoEMaOHYsvv/xS6mqSnjk6OmLatGkl1rdt29bwlSHSM97qTlo7fPgwfHx84OXlhaVLl2LOnDmIiorCqFGjpK4a6VFRURGEEDA3V/+/UlZWFl566SUkJSXh3Llz8PX1laiGpG/e3t4AgOTkZEnrQVRR2O1FWuvRowe8vLykrgZVMLlcXiL4AIC9vT169eoFALhy5Yqhq0VEpDV2exGRVnJzc3HkyBHIZDI0bdpU6uqQnuXl5WHTpk24efMmnJyc0LFjR7Rs2VLqahHpBcMPEWkkPT0dq1atQnFxMe7cuYN9+/YhNTUVERER8PHxkbp6pGdpaWklurB79+6NLVu2wMXFRZpKEekJww8RaSQ9PR0LFixQ/WxhYYHly5dj5syZEtaKKkJYWBgCAwPh6+sLhUKBpKQkLFiwAPv370ffvn2RkJAAmUwmdTWJtMYxP0SkEW9vbwghUFhYiGvXrmHhwoWYN28eBg4ciMLCQqmrR3r03nvvITAwEC4uLrC3t0f79u2xZ88eBAQE4MSJE9i3b5/UVSTSCcMPEZWLXC6Ht7c3Zs+ejffffx+7du3CunXrpK4WVTAzMzOMHj0aAJCQkCBxbYh0w/BDRFrr2bMnACAuLk7aipBBKMf65OTkSFwTIt0w/BCR1m7dugUApd4KT1XPr7/+CuDfeYCIjBXDDxE91+nTp5GRkVFi/YMHDzB37lwAQJ8+fQxdLaogSUlJSE9PL7H+2LFjWLFiBRQKBQYMGGD4ihHpEf+7Rlpbv349jh07BgA4e/asap2yC6Rfv37o16+fRLUjfYmOjsb69esRFBQELy8v2NraIiUlBXv37kV2djYGDhyIYcOGSV1N0pMdO3Zg2bJl6N69O7y9vaFQKHDu3DkcPHgQZmZmWLt2LTw9PaWuJpFOGH5Ia8eOHcOmTZvU1iUkJKgGQ3p7ezP8VAGDBg1CRkYGTp48ifj4eOTk5MDZ2RkBAQEIDQ3FkCFDeNtzFRIUFIQLFy7gjz/+wM8//4zc3FzUrFkTgwcPxvTp0+Hv7y91FYl0xmd7ERERkUnhmB8iIiIyKQw/REREZFIYfoiIiMikMPwQERGRSWH4ISIiIpPC8ENEREQmheGHiIiITArDDxEREZkUhh8iIiIyKQw/REREZFIYfohIL5KTkyGTydSWyMjICi3Tz89PrbyuXbtWaHlEVDUw/BAZkYSEBIwbNw6NGzeGo6MjFAoF3N3d8eqrr2L9+vV49OiR1FWEQqFAp06d0KlTp1Kf/u3t7a0KKzNnznzusT7++GO1cPOsVq1aoVOnTmjWrJne6k9EVR8fbEpkBHJycjB69Gjs2LEDAGBlZYX69evD2toaN2/exD///AMAqFWrFg4cOIDmzZsbvI7JycmoW7cuvLy8kJycXOZ23t7eSElJAQC4ubnhxo0bkMvlpW7brl07JCYmqn4u69dVXFwcgoKCEBgYiLi4OK3PgYhMA1t+iCq5goIC9OzZEzt27ICbmxs2bdqEBw8e4Ny5c/jtt99w69YtnD9/HuPHj8fdu3dx9epVqauskUaNGiEtLQ2HDx8u9fW///4biYmJaNSokYFrRkRVHcMPUSW3YMECJCQkoGbNmjhx4gRCQ0NhbW2ttk3Tpk2xdu1aHD16FK6urhLVtHxGjBgBAIiJiSn19S1btgAAQkJCDFYnIjINDD9ElVhGRgY++eQTAMCqVavg7e393O0DAgLQsWNHA9RMd4GBgfDw8MCuXbtKjFUSQmDr1q2wtrbGgAEDJKohEVVVDD9EldjevXuRlZWFGjVqYNCgQVJXR69kMhmGDx+OR48eYdeuXWqvHTt2DMnJyejXrx/s7e0lqiERVVUMP0SV2PHjxwEAnTp1grm5ucS10T9ll5ayi0uJXV5EVJEYfogqsZs3bwIA6tatK3FNKkbTpk3RqlUr/PTTT6o71vLy8vD111/D1dUVwcHBEteQiKoihh+iSiwrKwsAYGtrq9NxgoODIZPJSrSwPC05ORmvvfYa7O3t4eTkhJCQENy7d0+ncjUREhKCoqIixMbGAgD27NmD9PR0DB06tEq2dhGR9Bh+iCox5XgXXSYv/Oeff3DkyBEAZd9ZlZ2djaCgINy8eROxsbH48ssvcfz4cbzyyisoLi7WumxNDB06FHK5XBXMlH8q7wYjItI3/reKqBJzd3cHAFy7dk3rY2zbtg3FxcUIDg7GTz/9hLS0NLi5ualt88UXX+Cff/7B8ePHUatWLQBPJiP09/fHd999h/79+2t/Ei/g5uaGHj164MCBA4iPj8f+/fvRuHFjtG3btsLKJCLTxpYfokpMedv68ePHUVhYqNUxtmzZghYtWmDp0qVq3UtP27NnD4KCglTBB3gyu3LDhg3xww8/aFf5clAObA4JCUF+fj4HOhNRhWL4IarEXn75ZdjZ2eHOnTvYuXNnufc/f/48zpw5g+HDh6N169Zo2rRpqV1fSUlJ8PX1LbHe19cXFy5c0Kru5dG/f3/Y2dnh+vXrqlvgiYgqCsMPUSVWrVo1vPXWWwCAadOmPfeZWcCTB58qb48HnrT6yGQyDBs2DMCTcTR//PFHiUDz8OFDVKtWrcTxnJ2d8eDBA91OQgM2NjaYOXMmunfvjvHjx8PLy6vCyyQi08XwQ1TJRUZGokOHDrh9+zY6dOiALVu2IDc3V22bS5cuYdKkSejatSvu3LkD4Mksydu2bUNgYCDq1KkDABg+fDhkMlmprT+lPTXdkM89joyMxOHDh7FmzRqDlUlEponhh6iSs7S0xMGDBzFw4ECkpaUhNDQUzs7OaN68Ofz9/VGnTh00atQIn3/+Odzc3NCgQQMAT550npqaitdeew3p6elIT0+Hg4MD2rdvj61bt6oFGycnJzx8+LBE2Q8fPoSzs7PBzpWIyBAYfoiMgJ2dHXbu3In4+HiMGTMGHh4eSE5OxpkzZyCEwCuvvIINGzbg0qVLaNasGYB/b2ufPn06nJycVMvJkyeRkpKCY8eOqY7v6+uLpKSkEuUmJSWhSZMmhjlJIiID4a3uREakc+fO6Ny58wu3y83Nxc6dO9G7d2+88847aq8VFBSgb9++iImJUR3r1Vdfxbx589Rug//999/x999/Y8mSJXo9hxeNW3pWnTp1DNr9RkRVn0zwtwpRlbNjxw4MHjwYe/bswSuvvFLi9cGDB+PQoUNIS0uDpaUlsrKy0KJFC9SoUQMRERHIzc3FO++8g+rVq+PEiRMwM3txI3FycjLq1q0LhUKhmqMnLCwMYWFhej8/pdGjR+Py5cvIyMjAuXPnEBgYiLi4uAorj4iqBnZ7EVVBMTExcHNzQ+/evUt9ffTo0Xj48CH27t0L4MlM0keOHIGbmxsGDx6MMWPG4KWXXsKePXs0Cj5Py8vLQ0JCAhISEnD9+nWdz+V5/vzzTyQkJODcuXMVWg4RVS1s+SEiIiKTwpYfIiIiMikMP0RERGRSGH6IiIjIpDD8EBERkUlh+CEiIiKTwvBDREREJoXhh4iIiEwKww8RERGZFIYfIiIiMikMP0RERGRSGH6IiIjIpDD8EBERkUn5f8bp5tvt1XpeAAAAAElFTkSuQmCC\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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hdb9ym455XFVGVuCiIiIqrn09HS1MUHaWoGAx9PLgcczrr7//ns0aNAAANC9e3fs3LkTfn5++OijjzBt2rSKD/r/NWnSxOgyZDIZ/vzzT73P0ykJMkWATzI0WCIiohrFRGOCHBwcdBoYrWy98ff3VyVASq1bt0aTJk2QmpqKzMzMUgcfK8soraVH2TVXWkvR065evarTcdrIZDIIISCTGfYQNZ2SIGMC1MbQYImIiGoUE40J0lXz5s0BoNQER7n90aNHpR5ja2uL+vXr48qVKyguLtYYF6QcC6QcG1SeK1euaN3+9ddf49///jdatmyJ119/HS1btoSrqyvu3r2LixcvYtWqVbh48SL+85//YOTIkTrV9TSdu8M6duyIHTt2GFTJk1566SX8+uuvRpdDRERE+unVqxcA4OLFixr7CgsLkZqaCltbW9StW7fMcoKCgrB9+3YkJiZqTJGPiYlRHaMLT09PjW0///wzFixYgJkzZ2oM1Pbx8UG3bt3w2muvYe7cuXjnnXfQvn17reWUR+ckSC6XG1SBtnKIiIgIxq8YrWdLkLe3N/r27YsDBw5g7dq1CAkJUe17//33kZmZibFjx6rWD8rIyEBGRgZcXFzg4uKiOnbKlCnYvn07Fi5ciJ9//hnW1tYAHi+WGBMTgx49ehg1Pf69996Do6MjPvjggzKPW7p0KTZs2ID33nsPffr00bsenZKgIUOGwNfXV+/CtenevbvajSQiIjJbxo4JMmC541WrVqFr16547bXX8P3336NFixb47bffcPjwYXh6emL58uWqY6OiohAZGYnw8HBERESotvfq1QshISFYu3Yt2rVrh4EDB6oem+Hg4FDuDLPynDlzBs2bN9c6Bf9JVlZW8Pb2NriHSack6PvvvzeocG3ee+89k5VFRERE+vH29sbp06exaNEi7N+/HwcOHICbmxveeOMNLFq0CPXq1dOpnDVr1sDPzw9r1qzBypUrYWdnh8GDB+Pdd981epFEIQSuXLmCkpISWFiUPmiquLgYV65cgaEPv6i0x2YkJycbfVOqAz42w7zwsRlmho/NMAuV+tiMzoCDEYvVZBcBihMVG6sUnnvuORw5cgTz58/HkiVLSj1u0aJFWLJkCXr37o2ff/5Z73p0HpNe3gqSZfn99991HiBFRERkNky0WGJN8+9//xsymQxLly5Fly5dsGnT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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# This problem has two degrees of freedom. Fixing dimensions are not necessary for drawing a heatmap\n", - "\n", - "fixed = {}\n", - "all_fim.figure_drawing(\n", - " fixed, [\"CA0[0]\", \"T[0]\"], \"Reactor case\", \"$C_{A0}$ [M]\", \"T [K]\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Grid Search for 3 Design Variables" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [], - "source": [ - "# Define design ranges\n", - "design_ranges = {\n", - " \"CA0[0]\": list(np.linspace(1, 5, 2)),\n", - " \"T[0]\": list(np.linspace(300, 700, 2)),\n", - " (\n", - " \"T[0.125]\",\n", - " \"T[0.25]\",\n", - " \"T[0.375]\",\n", - " \"T[0.5]\",\n", - " \"T[0.625]\",\n", - " \"T[0.75]\",\n", - " \"T[0.875]\",\n", - " \"T[1]\",\n", - " ): [300, 500],\n", - "}\n", - "\n", - "# Choose from 'sequential_finite', 'direct_kaug'\n", - "sensi_opt = \"direct_kaug\"" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO: =======Iteration Number: 1 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 1 out of 8.\n", - "INFO: The code has run 0.8139118879998932 seconds.\n", - "INFO: Estimated remaining time: 2.4417356639996797 seconds\n", - "INFO: =======Iteration Number: 2 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 2 out of 8.\n", - "INFO: The code has run 1.6158038199992006 seconds.\n", - "INFO: Estimated remaining time: 2.693006366665334 seconds\n", - "INFO: =======Iteration Number: 3 =====\n", - "INFO: elapsed time: 0.6\n", - "INFO: This is run 3 out of 8.\n", - "INFO: The code has run 2.2149686929988093 seconds.\n", - "INFO: Estimated remaining time: 2.2149686929988093 seconds\n", - "INFO: =======Iteration Number: 4 =====\n", - "INFO: elapsed time: 1.0\n", - "INFO: This is run 4 out of 8.\n", - "INFO: The code has run 3.1933937759986293 seconds.\n", - "INFO: Estimated remaining time: 1.9160362655991774 seconds\n", - "INFO: =======Iteration Number: 5 =====\n", - "INFO: elapsed time: 0.6\n", - "INFO: This is run 5 out of 8.\n", - "INFO: The code has run 3.7590698399981193 seconds.\n", - "INFO: Estimated remaining time: 1.253023279999373 seconds\n", - "INFO: =======Iteration Number: 6 =====\n", - "INFO: elapsed time: 0.8\n", - "INFO: This is run 6 out of 8.\n", - "INFO: The code has run 4.590044279998438 seconds.\n", - "INFO: Estimated remaining time: 0.6557206114283483 seconds\n", - "INFO: =======Iteration Number: 7 =====\n", - "INFO: elapsed time: 0.7\n", - "INFO: This is run 7 out of 8.\n", - "INFO: The code has run 5.270455575998312 seconds.\n", - "INFO: Estimated remaining time: 0.0 seconds\n", - "INFO: =======Iteration Number: 8 =====\n", - "INFO: elapsed time: 0.7\n", - "INFO: This is run 8 out of 8.\n", - "INFO: The code has run 5.959630374997687 seconds.\n", - "INFO: Estimated remaining time: -0.6621811527775208 seconds\n", - "INFO: Overall wall clock time [s]: 5.959630374997687\n" - ] - } - ], - "source": [ - "# Create doe_object using DesignOfExperiments\n", - "doe_object = DesignOfExperiments(\n", - " parameter_dict, # dictionary of parameters\n", - " design_gen, # design variable\n", - " measure_class, # measurement variable\n", - " create_model, # model\n", - " prior_FIM=prior_pass, # FIM of prior experiments\n", - " discretize_model=disc_for_measure, # discretized model\n", - ")\n", - "\n", - "# Run grid search\n", - "all_fim = doe_object.run_grid_search(\n", - " design_ranges, # range of design variables\n", - " mode=sensi_opt, # solver option for sensitivity\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Draw 1D Sensitivity Curve" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "# FIM criteria\n", - "test = all_fim.extract_criteria()" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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2yIismLFCnnw4IFOWVJSkixevFgASKdOnXSWnTlzRgCIq6urXLlyRWdZbGysrFy5Uu7evatTPnz4cAEgXbt21Tk+T58+lcGDBwsAGTp0aJ7bV5zi4+O1ifipU6dERCQuLk7Mzc0FgJw5c6bAbS5btkwAiLW1tezfv19bHh4erk1W2rRpo7deVhJjYmIin3/+ufY7mpiYKK+88or2+/bP70vHjh0FQK6/FOSV+P2zz+joaGnbtq0AkD59+oiFhYVs2LBBu97du3elTp06AkC++eYbvXYL+n0SKVjil9d2Zcna31u3btVblpaWJg4ODgJALl26lGMbVDYx8aMSERUVJStWrJB+/fqJu7u7mJqaioODg/Ts2VP27t1b4PaePn0qM2fOlLp164qpqak4OjrKkCFD8vxP58CBA9K/f39xcnISU1NTqVmzpgwcOFDOnz+vraPRaGT37t3yxhtvSJMmTcTGxkbMzc2ladOmsnjx4mx/Ky8t2SV+sbGx8scff4iHh4f2N/bnpaamSvXq1cXIyEjOnj2bbbtZV5x++umnfMcyatQoAaB3pbB3794CQMaNG5evdvKT+GWddLKuJD0vMTFRHB0dBYCsXr1aZ1nW/urXr1++Yvmngm5LXnx9fQWA3L9/X1u2ceNGASDTp0/PVxvBwcHa/RUXF6e3PDExUVxdXUVRFLl9+3axxJ0fWVf36tWrp1P+0ksv5XjscqPRaMTV1VUAyJdffqm3/P79+9orf3/99ZfOsqwkpn///nrrZf08AJAffvhBZ1lxJH4DBgzQW7Zv3z7tetnth6xfzLKLNzfZfZ9ESibxW716dY7bt3XrVgEgLVu2LFD8VDYw8aMS8e233woAcXFxkdGjR8ucOXNk1KhR2qsBn376ab7bioqKkvr16wsA8fHxkRkzZsiIESPE1NRULCws5MSJE9mul3Vly9nZWSZOnChz586VcePGScOGDWXdunXaesnJydqhxx49esisWbPk7bff1vbZqlUrvSsFpSXr5JLdR6VSycsvvyxPnz7VWefgwYPauHOydu1aASDjx4/XW3b16lWZP3++DBo0SDp27KgdAso6KT9/lSIpKUl7hezatWv52qa8Er/4+HhRqVQCQG7cuJFtnblz5woAefnll3XKs/bXL7/8kq9YnleYbcly+vRpee+996Rfv37SoUMH7T6rWrWqANAZ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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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ixYtSi0UJ4QQX375pQAgXFxcxJQpU8S7774rrK2thZGRkTh48KA2T7fGeFbSxWuoX2bOnCnMzMzEq6++KsaPHy8++OAD0b17dyFJkjAwMCj1Jc7rp59u3rwpHBwcBADxyiuviA8++EB06dJFABCurq4iMTFRWZbXUL81a9ZMABCXLl0qt4w+XkMmXVVARESEGDFihPD29hbW1tbC0NBQODg4iB49eog1a9aUWFG3WFpamnj//feFs7OzMDIyEs7OzuL9998vs8es2KpVq0SrVq2EmZmZsLGxET169BCnT5+uzFOr0Z6VdAnBa6hPwsPDxaBBg4SHh4ewsrISRkZGwsnJSQwePFicOnWqzGN4/fRTfHy8GDFihKhXr57yuoSFhYmkpKRSZXkN9dOpU6cEANGmTZvnltW3a8gHXhMRERFpASfSExEREWkBky4iIiIiLWDSRURERKQFTLqIiIiItIBJFxEREZEWMOkiIiIi0gImXURERERawKSLiIiISAuYdBERVYLw8HBIklTi9eeff2qs/j59+pSou/iB20Skv5h0EVGN9t/ESJVXp06dVK7f2toaHTt2RMeOHVG3bt0S+/7888/nJkwrVqyAgYEBJEnCt99+q9zu4+ODjh07olWrVhU9ZSLSEUNdB0BEpEsdO3YstS09PR1RUVHl7vf19VW5fn9/f4SHh79QbMuXL8c777wDhUKBH374AVOmTFHumzNnDgAgNjYW7u7uL1Q/EWkXky4iqtGOHj1aalt4eDg6d+5c7n5t+P333zFmzBgIIbBgwQJMnDhRJ3EQkeYw6SIi0jO//vorxo0bBwBYsmQJ3nvvPR1HRESawKSLiEiP/PzzzwgLC1P++91339VxRESkKZxIT0SkJxYvXqzs1Vq6dCkTLqJqhkkXEZEeWLhwISZMmACZTIbly5fj7bff1nVIRKRhHF4kItKxe/fuYdKkSZAkCStWrEBoaKiuQyKiSsCeLiIiHRNCKP979+5dHUdDRJWFSRcRkY45OTkp192aPn06lixZouOIiKgyMOkiItID06dPx/Tp0wEAEyZM0Ogjg4hIPzDpIiLSE3PmzMGECRMghMDo0aOxadMmXYdERBrEpIuISI8sWLAAI0eOhFwux9ChQ7F7925dh0REGsKki4hIj0iShN9//x2DBg1CYWEh+vfvj0OHDuk6LCLSACZdRER6RiaTYdWqVXj11VeRl5eH3r174+TJk7oOi4jUxKSLiEgPGRkZYePGjejSpQuysrLQq1cvREZG6josIlIDky4iIj1lamqKv//+G+3bt0dqaiq6deuGmJgYXYdFRC+IK9ITEf1Hp06dlAuWVqYRI0ZgxIgRzyxjYWGB48ePV3osRFT5mHQREVWiCxcuIDAwEADwySefoGfPnhqpd8aMGThy5Ajy8/M1Uh8RVT4mXURElSgjIwPHjh0DACQlJWms3itXrijrJaKqQRLa6EMnIiIiquE4kZ6IiIhIC5h0EREREWkBky4iIiIiLWDSRURERKQFTLqIiIiItIBJFxEREZEWMOkiIiIi0gImXURERERawKSLiIiISAuYdBERERFpAZMuIiIiIi34f+QeRCpUXGt1AAAAAElFTkSuQmCC\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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lacX6OzZs1i6dClkMhkGDBig2h4XF4e4uDjY2NioeqJat26N1q1b51v/pk2bYG9vj40bN5baORQlJrnwhKm45YiIiEhzFW54bteuXahVqxbeeecdTJkyBZ988gl69OiBt956C1lZWVi1ahWcnJxU5VetWoWGDRti1apVOoy6eOzM1bsLTt1yREREpLkK19PUsWNH3L59G0FBQTh16hQyMjJQo0YNDB06FDNmzEDz5s11HaLGmtexRk1LIzxPzMh3XpMEgL2lEZrXsS7r0IiIiKqsSrPkgK4V55ZFdeTcPQcgV+KUs2b52pG+6NGopsbtEBERVWVVcsmByqZHo5pYO9IX9pa5h+DsLY2YMBEREelAhRueq0p6NKqJrh72uPwwHjHJGbAzfz0kpyeteM/IIyIiquiYNJVzelIJlxUgIiIqBzg8R0RERKQGJk1EREREamDSRERERKQGJk1EREREamDSRERERKQGJk1EREREamDSRERERKQGJk1EREREamDSRERERKQGrgiuJTnPPU5KStJxJERERKSunO/tnO/xwjBp0pLk5GQAgKOjo44jISIiouJKTk6GpaVloWUkQp3UioqkVCrx9OlTmJubQyLR7gN1k5KS4OjoiKioKFhYWGi1biobvIYVG69fxcdrWPGV1jUUQiA5ORm1atWCVFr4rCX2NGmJVCpF7dq1S7UNCwsLvtkrOF7Dio3Xr+LjNaz4SuMaFtXDlIMTwYmIiIjUwKSJiIiISA1MmioAmUyGuXPnQiaT6ToUKiFew4qN16/i4zWs+MrDNeREcCIiIiI1sKeJiIiISA1MmoiIiIjUwKSJiIiISA1MmoiIiIjUwKSpDCQkJGDq1Klo1aoV7O3tIZPJ4ODggE6dOuH333/P93k3SUlJmDlzJpydnSGTyeDs7IyZM2cW+my77du3o3nz5jA1NUW1atXw9ttv4+rVq6V5alXWokWLIJFIIJFIcPHixXzL8BqWLy4uLqpr9t/XxIkT85Tn9Su/9u7di65du6J69eowNjZGnTp1MHz4cERFReUqx2tYvvz8888FvgdzXp07d851THm7hrx7rgxERETA29sbLVu2RN26dWFtbY2YmBj8/fffiImJwfjx47F+/XpV+dTUVLRt2xbXr19H165d4evri5CQEBw6dAje3t44e/YsTE1Nc7Uxf/58/O9//4OTkxMG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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# Draw 1D sensitivity curve\n", - "# This problem has three degrees of freedom. To draw the 1D curve, it needs to fix two dimensions\n", - "fixed = {\n", - " \"'CA0[0]'\": 1.0,\n", - " \"('T[0.125]','T[0.25]','T[0.375]','T[0.5]','T[0.625]','T[0.75]','T[0.875]','T[1]')\": 300,\n", - "}\n", - "\n", - "all_fim.figure_drawing(fixed, [\"T[0]\"], \"Reactor case\", \"T [K]\", \"$C_{A0}$ [M]\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Draw 2D Sensitivity Curve" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": { - "tags": [] - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnkAAAHcCAYAAACqMLxhAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB5yklEQVR4nO3deXxMV/8H8M8kkX2RIEbILpHaEkpaSxpBouijdtUKQmKpolWPVnkk0aqllSaqdhUEbSlKqaBEiCVSja2WRCWxp0Q2spr7+8NvphkzSSaTyTLj83697ut53Hu2O3dqvs459xyRIAgCiIiIiEin6NV1A4iIiIhI8xjkEREREekgBnlEREREOohBHhEREZEOYpBHREREpIMY5BERERHpIAZ5RERERDqIQR4RERGRDmKQR0RERKSDGOQREWkRkUgEkUhU182oUFhYGEQiEcLCwuTOx8XFQSQSoUePHnXSLqKXDYM8qhInJyfZj4z0MDY2hrOzM0aNGoWzZ8/WdROrLDs7G2FhYYiMjKzrppCGtGvXDiKRCCYmJsjNza3r5qgsOjoaYWFhSEtLq+um1LqwsDCFoJCIqodBHqnFzc0N3bp1Q7du3eDm5ob79+9jy5Yt6NKlCzZv3lzXzauS7OxshIeHM8jTEcnJybh06RIAoLCwEDt27KjjFqkuOjoa4eHhFQZ5rVq1QqtWrWqvURpkamqKVq1awcHBQeFaeHg4wsPD66BVRLqLQR6p5bPPPsOJEydw4sQJXLx4EXfv3sXQoUPx7NkzTJkyBY8fP67rJtJLSvqPjIYNG8r9WVdcvXoVV69eretmqMXb2xtXr17Fpk2b6ropRC8FBnmkEdbW1li/fj3MzMyQl5eHgwcP1nWT6CX07NkzbNu2DQCwfPly6Ovr49ixY8jIyKjjlhER1T4GeaQxlpaWcHd3B4Byh5tiY2MxYMAANG3aFEZGRmjRogWCgoJw48YNpelPnz6NWbNmoVOnTrC1tYWRkRHs7e0RGBiIy5cvV9iea9euYcKECWjZsiVMTEzQqFEjvPrqqwgNDcW9e/cAAGPHjoWzszMAID09XWG+4Yv27duHN998E40bN4aRkRGcnZ3x/vvv49atW0rbIJ3DmJaWhqNHj6Jv375o3LgxRCIR4uLiKmx/Ve9F6tChQ/jggw/g6ekJGxsbGBsbw9XVFZMnTy432CktLUVUVBS8vb1hYWEBIyMj2NnZoWvXrggNDUV2drbSPKtWrUL37t3RsGFDGBsbw8PDA3Pnzq2zeXCHDx/GvXv3IBaL8c4776Bnz54QBAFbtmxRu0xBEBATEwNfX180bNgQJiYm8PDwwCeffIKsrCylecp+f7Zu3Qpvb2+Ym5vDxsYGAwcOlA0nS0lfSDh27BgAwM/PT+57GB0drbTsssp+144dO4bevXujYcOGsLGxwaBBg5CSkiJLu2fPHvj4+MDS0hLW1tYYOXIk7t69q/Re1Pk+lUfZixfSlzRevD/pkZaWhk8//RQikQhTp04tt+ykpCSIRCI0a9YMz549q1K7iHSWQFQFjo6OAgBhw4YNSq+3atVKACAsW7ZM4dr06dMFAAIAwdbWVujQoYNgaWkpABAsLS2FhIQEhTyurq4CAKFRo0ZC27ZtBU9PT8HKykoAIJiYmAhHjx5V2o6YmBjB0NBQlq5jx46Ch4eHYGRkJNf+BQsWCJ06dRIACEZGRkK3bt3kjrI+/fRTWftbtGghvPrqq4KpqakAQLC2thbOnj1b7uf15ZdfCnp6eoK1tbXQuXNnoUWLFuW2Xd17kdLX1xdEIpFga2sreHl5CW3bthXMzMxkn+Ply5cV6hgyZIjs3lxdXYXOnTsL9vb2gr6+vgBA+PPPP+XS5+TkCG+88YYAQNDT0xMcHR2Ftm3bytr5yiuvCA8ePFDp/jTp3XffFQAI06dPFwRBEKKjo2XtUYdEIpGVCUBwcXEROnbsKLtPR0dH4caNGwr5pOkXL14sABDEYrHQqVMnwcLCQvYcjx8/Lkt/7tw5oVu3brL/Htq2bSv3Pdy/f79C2S+SftciIiIEfX19wdbWVujYsaPs2Tdr1ky4d++eEBERIfsOe3p6yr5HrVq1EgoKChTKVef7FBoaKgAQQkND5c4fPXpUACD4+vrKzq1fv17o1q2b7L5e/G/w3r17wrVr12T1FRUVKX1WH3zwgQBAmDlzptLrRC8jBnlUJRUFedevXxcMDAwEAEJ8fLzctVWrVgkABGdnZ7ngprS0VPjiiy9kPzov/shs3LhR4Ue0pKREWLdunWBgYCC4uLgIz549k7t+9uxZoUGDBgIAYdasWUJ+fr7sWnFxsbBt2za5H9ibN2/KfrDLs3fvXgGAYGBgIMTExMjO5+TkCIMGDRIACE5OTsLTp0+Vfl76+vpCeHi4UFJSIgjC8+ChsLCw3PrUvRdBEITVq1cLd+7ckTv39OlTYcGCBQIAoUePHnLXkpKSBACCvb298Ndff8ldy8nJEdauXStkZGTInX/nnXcEAEKvXr3knk9WVpYwePBgAYAwdOjQSu9Pk/Ly8mRBd2JioiAIgpCbmyuYmJgIAISkpKQql/ntt98KAAQLCwvh4MGDsvP37t2TBSavvfaaQj5pwNKgQQNh6dKlsu/okydPhPfee0/2fXvx++Lr6ysAqPAfAJUFeS/W+fjxY+H1118XAAj9+/cXTE1NhS1btsjyZWRkCC4uLgIAYcWKFQrlVvX7JAhVC/Iquy8p6ee9c+dOhWvFxcVCo0aNBADCpUuXyi2D6GXDII+qRFmQl5OTIxw6dEho3bq17F/iZRUVFQlisVjQ19cXzp07p7RcaU/Spk2bVG7LqFGjBAAKPYD9+vUTAAjjxo1TqRxVgjzpD4y0h6isJ0+eCI0bNxYACOvXr5e7Jv28/vOf/6jUlhdV9V4q0717dwGAcPv2bdm5bdu2CQCEjz76SKUyzp8/L/u8cnNzFa4/efJEsLe3F0QikZCWlqaRdqtC2mvXsmVLufPDhg0r99lVRCKRCPb29gIA4ZtvvlG4fvv2bVmP3u+//y53TRqwDBgwQCGf9L8HAML3338vd00TQd7bb7+tcC02NlaWT9nnIP1HmLL2VkTZ90kQaibIW79+fbn3t3PnTgGA0KlTpyq1n0jXcU4eqSUoKEg2Z8bKygr+/v64evUqRowYgb1798qlPXXqFO7fv4+OHTuiQ4cOSssbMGAAAMjmJJV19epVhIaGYvDgwejRowe6d++O7t27y9KeP39elragoACHDh0CAMyaNUsj95qfn49Tp04BgNI5QaampggJCQGAcl84GT16dJXrrc69JCUl4dNPP8WAAQPg6+sr+8yuX78OALhw4YIsrb29PQDg999/L3eOWVm7du0CAAwfPhwWFhYK101NTdG7d28IgoDjx49Xqd3VIX2L9t1335U7/9577wEAtm3bhtLSUpXLu3LlCm7dugVjY2PZ8y2refPmGDJkCIDyn/uUKVMUzhkaGiI4OBjA8zmqmjZ+/HiFc15eXhVel/53+ffffystsyrfp5oyfPhwmJubY//+/fjnn3/krm3cuBHA8zm2RPQvg7puAGknNzc32NraQhAE3L9/H3///TcaNGiAzp07w9raWi7txYsXATx/GaN79+5Ky5NO7L9z547c+YULF2Lu3LmQSCTltqVsYJKamoqSkhI0bNhQY2uJpaamQiKRwMjICC4uLkrTtGnTBgBkP3oveuWVV9Sqt6r3IggCPvjgA6xYsaLCdGU/sy5duuC1117DmTNnYG9vD39/f7zxxhvw9fVFx44dFSb5S5/nrl27cPLkSaXlp6enA1B8njXlzp07OHr0KADFIK9v376wtrZGZmYmDh48iH79+qlUpvRZOjg4wMzMTGkadZ+79Hx5+arD1dVV4VyTJk1Uup6fny93Xp3vU00xNzfHsGHDsGHDBmzbtg3Tpk0DADx8+BD79++HoaEhRo4cWePtINIm7MkjtUjXyUtISMCNGzdw4sQJWFhYYObMmYiJiZFLm5OTAwD4559/kJCQoPSQvilbUFAgyxcfH4/PPvsMIpEICxcuxOXLl5Gfnw+JRAJBEDBnzhwAQElJiSyP9K1O6RppmiD94WvSpEm520k1bdoUAJCXl6f0enlBQkXUuZfNmzdjxYoVMDMzw4oVK5CSkoKnT59CeD41Q9arVfYz09PTw2+//Ybp06fDxMQEv/zyCz7++GN06tQJzs7Ocm92Av8+z9TU1HKf5+3btwHIP8/y3L9/X9YzVPao6E3KF23ZsgUSiQQdO3ZUCIgNDQ0xbNgw2eejKulzt7W1LTdNZc+9vLyV5asOU1NThXNlv7cVXRcEQe68Ot+nmjRu3DgA//bcAc/fXi4pKcGAAQNgY2NTK+0g0hbsySON6NatG9auXYtBgwZh+vTpGDBgACwtLQE8/xc48HzY7MUAsCLSZS/++9//4tNPP1W4rmzZEunwobIlP9Qlbf8///wDQRCUBnoPHjyQq18T1LkX6We2dOlSTJw4UeF6eUu9WFtbIzIyEt988w3Onz+P+Ph47N69G0ePHkVQUBDMzc0xdOhQAP9+HmvXrpUNO1ZHYWEhEhISFM4bGKj+15M0eDt37lyF+7r+8ssvyM3NlX03KyK9z8zMzHLTVPbc//nnH7Ro0ULhvLRMTX5faoK636ea0r17d7i7u+PcuXO4dOkS2rZty6FaogqwJ480ZuDAgXj99deRlZWFiIgI2fnWrVsDgMLaYJWRrrXXtWtXpdfLzsWTcnNzg6GhIbKzs3Ht2jWV6qlss/eWLVtCT08PRUVF5c5ZkvZEStcJ1AR17qWiz6ykpARXrlypML9IJIKXlxemTZuGI0eOyILrtWvXytKo+zzL4+TkJOsZKnuouo7gn3/+iUuXLkEkEqFp06blHoaGhigoKMDPP/+sUrnSZ5mRkaEwjClV2XMv7/OWnn8xX2XfxdpW3e9TTQgKCgLwfAu4S5cu4dy5cxCLxXjzzTdrvS1E9R2DPNIoaVCwbNky2Q+jj48PGjdujPPnz1dpAWATExMA//aWlHXw4EGlQZ6JiQkCAgIAAF9//XWV6ilvaNHc3Fz2I/ftt98qXC8oKMC6desAAH369FGpTlXbpe69KPvMNmzYoDBhvTKvv/46AMgtlDto0CAAQExMDB49elSl8mqCtBfvjTfewP3798s9Pv74Y7n0lXnllVfg4OCAwsJC2fMt6+7du7KAsbznrmwuW3FxMdavXw8AsucrVdl3sbZp+vukSl2V3fuYMWOgr6+PLVu2yJ7LqFGjoK+vr7G2EOmM2n+hl7RZZYshSyQS4ZVXXhEACEuWLJGdX7FihQBAaNy4sbBz505BIpHI5bt48aIwa9Ys4cSJE7JzX331lWxx3r///lt2PjExUWjevLlgbGysdJmGsmvLzZ49W3jy5InsWnFxsfDDDz/IrS0nkUhki9S+uE6clHSdvAYNGsitMZabmysMHTq00nXybt68qbTcylT1XqZMmSJbuy0zM1N2/rfffhMsLS1ln1nZ5xcTEyPMnz9foY0PHz4UevbsKQAQRo8eLXdt+PDhAgChQ4cOCsvilJaWCkePHhXeffddldYCrI7S0lLZciTr1q2rMO3ly5cFAIJIJFJY96880nXyLC0thcOHD8vO379/X/Dx8REACK+//rpCPpRZJy8yMlL2fX/69KkwevRo2bqEZZ+nIPz7/D755JNy24Rylhqp7LtWXj5BKH8ZIXW+T4Kg3hIqbdq0EQAIv/32m9I2ltW/f3/ZupXg2nhE5WKQR1VSWZAnCP+uZyUWi+UWNy67Y4SNjY3QuXNnoWPHjoKNjY3sfNm/4HNycmSLtBoaGgrt2rWT7ajRunVrYcaMGUp/SARBEDZv3iwLjkxNTYWOHTsKr7zySrk/SuPGjRMACMbGxkKnTp0EX19fhR+isu23t7cXOnXqJFv539raWrYAr7LPS90gr6r3kp6eLvs8TUxMBC8vL8HJyUkAIPj5+ckW4i2b55tvvpHdV/PmzYXOnTvL7V7RvHlzIT09Xa5NeXl5gr+/vyyfg4OD8Nprrwnt2rWTLT4MQOkOCpr022+/yZ5bdnZ2pek7dOggABAWLlyoUvkv7njRsmVLuR0vHBwcVN7xonPnzrIdLYyNjYVjx44p5IuPj5fldXd3F9544w3B19dX7r+L2gzy1Pk+CYJ6Qd78+fMF4PnC4R06dJD9N3jv3j2FtD///LPsfrg2HlH5GORRlagS5BUVFQl2dnYCAOG7776Tu5aQkCC8++67gr29vWBoaCjY2NgI7du3F8aNGyfs27dPKC4ulkt/9+5dYfTo0ULjxo0FQ0NDwdnZWZgxY4aQk5NT7g+J1OXLl4WgoCDBwcFBMDQ0FBo3biy8+uqrQlhYmMIPR15enjB9+nTByclJFlAp+0Hcu3ev4O/vL1hbWwuGhoaCo6OjMGnSpHJ7hjQR5FX1Xq5duyYMHjxYsLKyEoyNjQUPDw8hPDxcKCoqEsaMGaPw/DIyMoTFixcL/v7+goODg2BsbCw0atRI6Nixo/DFF18Ijx8/VtqmZ8+eCVu2bBH69OkjNG7cWGjQoIHQrFkz4bXXXhM++eQTpUGvpkkDsGHDhqmUfunSpbJ/JKhKIpEImzZtEnx8fARLS0vByMhIcHNzE/773/8KDx8+VJqn7Pdny5YtQufOnQVTU1PByspKGDBggHD+/Ply69u6davg7e0t+wfEi8+rNoM8Qaj690kQ1AvyiouLhdDQUKFVq1ayrdbKu5/i4mLZAuTLly9Xek9EJAgiQXjhnXkiIqqW8pYkIc3Izs6GWCyGIAi4d+8el04hKgdfvCAiIq2yZcsWFBUV4e2332aAR1QB9uQREWkYe/JqTlZWFjp06ICMjAwcPXoUPXr0qOsmEdVb7MkjIqJ6b9GiRfDx8YGrqysyMjIQEBDAAI+oEgzyiIio3rt69SpOnDgBfX19BAYGYuvWrXXdJKJ6j8O1RERERDqIPXlEREREOkj1HcCp1kkkEty9excWFhb1bk9LIiKqnCAIyMvLg52dHfT0aqZfpbCwEMXFxRopy9DQEMbGxhopi+oeg7x67O7du7C3t6/rZhARUTXdunULLVq00Hi5hYWFMDUxgabmXYnFYty8eZOBno5gkFePWVhYAABu3ToJS0vzOm4NUc0QW7Wv6yYQ1RgBQCH+/ftc04qLiyEAMAFQ3fEeAcD9+/dRXFzMIE9HMMirx6RDtJaW5rC0rJm/IIjqGici0Mugpqfc6EMzQR7pFgZ5REREWo5BHinDt2uJiIiIdBB78oiIiLScHtiTR4oY5BEREWk5PVR/aE6iiYZQvcIgj4iISMvpo/pBHl+C0j2ck0dERESkg9iTR0REpOU0MVxLuodBHhERkZbjcC0pw8CfiIiISAexJ4+IiEjLsSePlGGQR0REpOU4J4+U4XeCiIiISAexJ4+IiEjL6eH5kC1RWQzyiIiItJwmhmu5rZnu4XAtERERkQ5iTx4REZGW0weHa0kRgzwiIiItxyCPlGGQR0REpOU4J4+U4Zw8IiIiIh3EnjwiIiItx+FaUoZBHhERkZZjkEfKcLiWiIiISAexJ4+IiEjLiVD9XhuJJhpC9QqDPCIiIi2nieFavl2rezhcS0RERKSD2JNHRESk5TSxTh57fXQPgzwiIiItx+FaUoaBOxEREZEOYk8eERGRlmNPHinDII+IiEjLcU4eKcMgj4iISMuxJ4+UYeBOREREpIPYk0dERKTl9FD9njzueKF7GOQRERFpOc7JI2X4TImIiIh0EHvyiIiItJwmXrzgcK3uYZBHRESk5ThcS8rwmRIRERHpIPbkERERaTkO15Iy7MkjIiLScvoaOqrizp07iIyMREBAABwcHGBoaAixWIwhQ4bgzJkzVSrr9u3bmDhxoqwcOzs7BAUF4datWxXm27VrF/z9/dGoUSOYmJjA2dkZI0eOVMgXFhYGkUik9DA2NlYoNy0trdz0IpEIP/zwQ5Xur66wJ4+IiIiq7Ntvv8XixYvh6uoKf39/2NraIiUlBbt378bu3buxbds2DB8+vNJybty4ga5duyIzMxP+/v4YMWIEUlJSsHHjRuzfvx8nT56Eq6urXB5BEDBp0iSsWbMGrq6ueOedd2BhYYG7d+/i2LFjSE9Ph729vUJdY8aMgZOTk9w5A4PyQyFPT08MHDhQ4Xzbtm0rva/6gEEeERGRlquLFy+8vb0RHx8PHx8fufPHjx9Hr169MHnyZLz99tswMjKqsJzp06cjMzMTUVFRmDZtmuz89u3bMXz4cEyZMgUHDhyQy/Ptt99izZo1mDJlCqKioqCvL98PWVpaqrSusWPHokePHirfo5eXF8LCwlROX99wuJaIiEjLSXe8qM5R1YBg8ODBCgEeAPj4+MDPzw9ZWVm4ePFihWUUFhYiNjYWTZs2xdSpU+WuDRs2DF5eXoiNjcXff/8tO19QUIDw8HC4uLggMjJSIcADKu6de5nwUyAiItJymnjxorr5y2rQoAGAyoOtR48eobS0FI6OjhCJRArXnZ2dkZycjKNHj8LFxQUAcOjQIWRlZWHs2LF49uwZ9uzZg+vXr6Nhw4bo3bs3WrZsWW59x48fR2JiIvT19eHh4YHevXtX2NN49+5drFy5EtnZ2bCzs0OvXr3QokULVT6CeoFBHhEREcnk5ubK/dnIyKjSIdeyMjIycPjwYYjFYrRr167CtNbW1tDX10d6ejoEQVAI9G7evAkAuH79uuxcUlISgOcBpKenJ65duya7pqenh48++ghff/210vrmzZsn9+dmzZph48aN8Pf3V5r+0KFDOHTokOzPBgYGmDZtGr766ivo6dX/wdD630IiIiKqkJ6GDgCwt7eHlZWV7Fi4cKHK7SgpKUFgYCCKioqwZMkSpUOpZZmamsLX1xcPHjzAihUr5K7t3LkTycnJAIDs7GzZ+czMTADA0qVLYWlpicTEROTl5SE+Ph7u7u5YunQpVq5cKVeWl5cXNm7ciLS0NBQUFCAlJQWff/45srOzMWDAAJw/f16hXaGhoUhOTkZubi4yMzOxZ88euLm5ISIiAnPmzFH5M6lLIkEQhLpuBCmXm5sLKysr5ORcgKWlRV03h6hGmImc67oJRDVGAFAAICcnB5aWlhovX/o7MRqAYTXLKgawCcCtW7fk2qpqT55EIsGYMWMQExODkJAQrFmzRqV6z58/j+7duyM/Px99+vRB+/btkZqail9++QVt27bFhQsXMHnyZFkQOGHCBKxduxYmJiZITU2FnZ2drKzLly+jffv2cHZ2RmpqaqV1r127FhMmTMDQoUOxffv2StPfv38fbdu2RV5eHu7fvw9ra2uV7rGusCePiIiIZCwtLeUOVQI8QRAQEhKCmJgYjBo1CqtWrVK5Pk9PT5w9exbDhw/HuXPnEBUVhWvXrmH16tUIDAwEADRp0kSW3srKCgDQqVMnuQAPANq0aQMXFxfcuHFDrvevPGPGjIGBgQESEhJUaqtYLEa/fv1QXFyMs2fPqniHdYdz8oiIiLRcXe5dK5FIEBwcjA0bNmDkyJGIjo6u8nw1Dw8P/Pjjjwrnx44dC+B5QCfVqlUrAEDDhg2VliU9X1BQUG4aKUNDQ1hYWODp06cqt7Vx48YAUKU8dYU9eURERFquLna8AOQDvBEjRmDz5s2VzsNTVV5eHvbu3QsbGxu5FyP8/PwAAFeuXFHIU1JSgtTUVJiZmcn1/pUnJSUFjx8/VlgguSKJiYkAUKU8dYVBHhEREVWZRCLB+PHjsWHDBgwbNgwxMTEVBngPHz7E1atX8fDhQ7nzBQUFCosXFxUVYfz48cjKykJoaKjc1mOurq4ICAhAamoq1q1bJ5dv0aJFyM7OxqBBg2TLt+Tl5eHChQsK7Xn8+DHGjx8PABg5cqTctcTERJSUlCjkiYiIQEJCAlq3bg1PT89y77W+4IsX9RhfvKCXAV+8IF1WWy9eTIBmXrxYA9XbGhYWhvDwcJibm2P69OlK18QbOHAgvLy85NKHhobK7SJx4sQJDB48GP7+/rC3t0dubi727duHjIwMhISEYPXq1QpLq5TdCq1///7w8PDAn3/+iSNHjsDR0RGnT5+GWCwG8HwfWmdnZ3Tq1Ant2rWDra0t7ty5g99++w2PHj2Cv78/fv31Vxga/vsJ9ujRA1evXoWvry/s7e1RUFCAU6dO4c8//4S1tTUOHz6Mjh07Vvkzrm2ck0dERKTlRKj+0JziUsQVS0tLAwDk5+djwYIFStM4OTnJgrzyODg4oEePHjh+/DgePHgAU1NTdOzYERERERgyZIjSPK6urkhKSsK8efNw4MABHDx4EGKxGFOmTMG8efNga2srS2tjY4MpU6bg9OnT2Lt3L7Kzs2FmZoZ27dph1KhRCA4OVuiBHDVqFH7++WecPHlS1vPo6OiI6dOnY+bMmVqzIDJ78uox9uTRy4A9eaTLaqsnbyIA1ZcrVq4IwGrUXFup9rEnj4iISMvVt23NqH5gkEdERKTlGOSRMgzyiIiItFxdrpNH9RefKREREZEOYk8eERGRluNwLSnDII+IiEjLcbiWlOEzJSIiItJB7MkjIiLSchyuJWUY5BEREWk5PVQ/SOPQnu7hMyUiIiLSQezJIyIi0nJ88YKUYZBHRESk5Tgnj5Rh4E5ERESkg9iTR0REpOXYk0fKMMgjIiLScpyTR8owyCMiItJy7MkjZRi4ExEREekg9uQRERFpOQ7XkjIM8oiIiLQcd7wgZfhMiYiIiHQQe/KIiIi0HF+8IGUY5BEREWk5zskjZfhMiYiIiHQQe/KIiIi0HIdrSRkGeURERFqOQR4pw+FaIiIiIh3EnjwiIiItxxcvSBkGeURERFqOw7WkDIM8IiIiLSdC9XviRJpoCNUr9b53Njs7G9OmTUOXLl0gFothZGSE5s2bo2fPnvj5558hCIJCntzcXMyYMQOOjo4wMjKCo6MjZsyYgdzc3HLr2bp1K7y9vWFmZgZra2v069cPSUlJVW6vOnUTERERaZpIUBYl1SOpqanw8vLC66+/jpYtW8LGxgaZmZnYu3cvMjMzERISgjVr1sjSP3nyBN27d0dycjL8/f3RsWNHnD9/HgcOHICXlxdOnDgBMzMzuTq+/PJLzJkzBw4ODhg6dCjy8/Pxww8/oLCwELGxsejRo4dKbVWn7ork5ubCysoKOTkXYGlpoXI+Im1iJnKu6yYQ1RgBQAGAnJwcWFpaarx86e/E9wBMq1nWUwDjUHNtpdpX74drnZ2dkZ2dDQMD+abm5eXh9ddfx9q1azF9+nS0adMGALBkyRIkJydj1qxZWLx4sSx9aGgo5s+fjyVLliA8PFx2PiUlBaGhoXB3d0diYiKsrKwAANOmTYO3tzeCg4Nx9epVhfqVqWrdREREmsA5eaRMvR+u1dfXVxpgWVhYoE+fPgCe9/YBgCAIWLduHczNzTFv3jy59LNnz4a1tTXWr18vN8S7YcMGlJaWYs6cObIADwDatGmD0aNH48aNGzhy5Eil7VSnbiIiIqKaUu+DvPIUFhbiyJEjEIlEaN26NYDnvXJ3795Ft27dFIZFjY2N8cYbb+DOnTuyoBAA4uLiAAABAQEKdUiDyGPHjlXaHnXqJiIi0gQ9DR2kW+r9cK1UdnY2IiMjIZFIkJmZif379+PWrVsIDQ2Fm5sbgOeBFgDZn19UNl3Z/29ubg6xWFxh+sqoUzcREZEmcLiWlNGqIK/sfLYGDRrgq6++wscffyw7l5OTAwByw65lSSeSStNJ/7+tra3K6cujTt0vKioqQlFRkezPfCOXiIiI1KU1vbNOTk4QBAGlpaW4efMm5s+fjzlz5mDIkCEoLS2t6+ZpxMKFC2FlZSU77O3t67pJRESkBfQ1dJBu0ZqePCl9fX04OTnh008/hb6+PmbNmoW1a9di8uTJsl608nrLpD1jZXvbni9Ronr68qhT94tmz56NGTNmyOVhoEdERJXhtmbao6SkBGfPnsWJEyeQnp6Of/75BwUFBWjcuDGaNGmCjh07wsfHB82bN692XVoX5JUVEBCAWbNmIS4uDpMnT650Dp2yeXNubm44deoU7t+/rzAvr7J5dmWpU/eLjIyMYGRkVGldREREpF2OHj2KdevWYffu3SgsLAQApStuiETP9x555ZVXMG7cOIwePRqNGzdWq06tDvLu3r0LALIlVtzc3GBnZ4eEhAQ8efJE7i3XwsJCxMfHw87ODi1btpSd9/X1xalTp3Dw4EGMHj1arvzY2FhZmsqoUzcREZEm6KH6w63syasZe/fuxezZs3HlyhUIggADAwN4eXmhc+fOaNasGWxsbGBiYoKsrCxkZWXhr7/+wtmzZ/HXX39h5syZ+OyzzzBhwgT873//Q5MmTapUd71/psnJyUqHQLOysvDZZ58BAPr27QvgefQbHByM/Px8zJ8/Xy79woUL8fjxYwQHB8uiZAAICgqCgYEBFixYIFfP5cuXsWnTJri6uqJnz55yZWVkZODq1at4+vSp7Jw6dRMREWkCl1Cpn9544w0MHDgQaWlpGD58OHbt2oXc3Fz88ccfWLVqFUJDQzF16lQEBwdj1qxZWLRoEfbs2YN79+4hJSUFn3/+OVq2bInly5ejZcuW+OWXX6pUf73f1uzDDz/EunXr4OfnB0dHR5iZmSE9PR379u1Dfn4+hgwZgp9++gl6es+/ni9uLfbqq6/i/Pnz+O2338rdWmzBggWYO3eubFuzJ0+eYNu2bSgoKEBsbCz8/Pzk0vfo0QPHjh3D0aNH5bY8U6fuinBbM3oZcFsz0mW1ta3ZHgCq/7oo9wTAAHBbM02ysbHBtGnT8OGHH6Jhw4Zql3P06FF8/vnn8PPzw//+9z+V89X7IO/EiRNYv349Tp8+jbt37+Lp06ewsbFBx44dMXr0aLzzzjsKvWM5OTkIDw/Hjh07ZHPthg4ditDQ0HJffNiyZQsiIyNx+fJlGBoaokuXLpg/fz46d+6skLa8IE/dusvDII9eBgzySJcxyHu55eXlwcJCc7/fVS2v3gd5LzMGefQyYJBHuqy2grx90EyQ1x8M8nSJVr94QURERFxChZTjMyUiIqIqu3PnDiIjIxEQEAAHBwcYGhpCLBZjyJAhOHPmTJXKun37NiZOnCgrx87ODkFBQbh161aF+Xbt2gV/f380atQIJiYmcHZ2xsiRIxXyhYWFQSQSKT2MjY3LLX/r1q3w9vaGmZkZrK2t0a9fPyQlJVXp3irz9OlTPHr0SOlyKtXFnjwiIiItVxd713777bdYvHgxXF1d4e/vD1tbW6SkpGD37t3YvXs3tm3bhuHDh1dazo0bN9C1a1dkZmbC398fI0aMQEpKCjZu3Ij9+/fj5MmTcHV1lcsjCAImTZqENWvWwNXVFe+88w4sLCxw9+5dHDt2DOnp6Uo3ExgzZgycnJzkzkmXYXvRl19+iTlz5sDBwQGTJk1Cfn4+fvjhB3Tr1g2xsbEKc/JVkZubiz179iA+Pl62GLJ0zTyRSCR758DHxwcBAQFK3wuoCs7Jq8c4J49eBpyTR7qstubk/Q7NzMnrBdXbunPnTjRp0gQ+Pj5y548fP45evXrJgq7KFvl/6623sG/fPkRFRWHatGmy89u3b8fw4cPRp08fHDhwQC7PsmXLMH36dEyZMgVRUVHQ15cPUUtLS+WCt7CwMISHhyt9YVKZlJQUtG7dGi4uLkhMTJS9OHn58mV4e3ujWbNmuHr1arkB4osSExPx3Xff4eeff0ZBQUGlvXbSF0rbtm2L4OBgjB8/HqampirVVRaHa4mIiKjKBg8erBDgAYCPjw/8/PyQlZWFixcvVlhGYWEhYmNj0bRpU0ydOlXu2rBhw+Dl5YXY2Fj8/fffsvMFBQUIDw+Hi4sLIiMjFQI8oPzeOVVt2LABpaWlmDNnjtzKGG3atMHo0aNx48YNHDlypNJyrl+/jiFDhqBLly7YvHkzTE1N8e677yIqKgonT57EzZs3kZOTg+LiYty/fx9//fUXduzYgf/+97/o2rUrLl26hA8//BCurq5YvXo1JBJJle6Dw7VERERaToTq99pocqn+Bg0aAKg82Hr06BFKS0vh6OiodLMAZ2dnJCcn4+jRo3BxcQEAHDp0CFlZWRg7diyePXuGPXv24Pr162jYsCF69+5d4c5Sx48fR2JiIvT19eHh4YHevXsr7WmMi4sD8Hz71Bf16dMHq1atwrFjx5ReL6tNmzYAgBEjRmDMmDHo3bu30qAUAGxtbWFrawsPDw8MHjwYwPN5j9u2bcPKlSvx/vvv49GjR7KNIFTBII+IiEjLaXJOXm5urtz5qu6rnpGRgcOHD0MsFqNdu3YVprW2toa+vj7S09MhCIJCoHfz5k0Az3vEpKQvPhgYGMDT0xPXrl2TXdPT08NHH32Er7/+Wml98+bNk/tzs2bNsHHjRvj7+8udT0lJgbm5ucKe9kDle9WXNXr0aHz22WcKcwpV1bx5c8ycORMfffQRtmzZUuVdszhcS0RERDL29vawsrKSHQsXLlQ5b0lJCQIDA1FUVIQlS5aU22slZWpqCl9fXzx48AArVqyQu7Zz504kJycDALKzs2XnMzMzAQBLly6FpaUlEhMTkZeXh/j4eLi7u2Pp0qVYuXKlXFleXl7YuHEj0tLSUFBQINsyLDs7GwMGDMD58+fl0ufk5JS7gYF0vqKyLVdftH79erUDvLL09fUxevRoBAYGVikfe/KIiIi0nCbXybt165bcixeq9uJJJBKMGzcO8fHxCAkJUTkgiYiIQPfu3fHBBx9g7969aN++PVJTU/HLL7+gffv2uHDhglywKJ2XZmhoiN27d8POzg7A87mAO3bsQPv27bF06VJMnjxZlmfgwIFydbZs2RJz585F06ZNMWHCBHzxxRfYvn27Su3VJuzJIyIi0nL6GjqA5z1VZQ9VgjxBEBASEoKYmBiMGjUKq1atUrntnp6eOHv2LIYPH45z584hKioK165dw+rVq2WBYpMmTWTppT1snTp1kgV4Um3atIGLiwtu3Lgh1/tXnjFjxsDAwAAJCQly55+vbKG8p046nF3VrUrrAnvyiIiItFxdrJMnJZFIEBwcjA0bNmDkyJGIjo6Gnl7V+pA8PDzw448/KpwfO3YsgOcBnVSrVq0AAA0bNlRalvR8QUFBuWmkDA0NYWFhgadPn8qdd3Nzw6lTp2R70JclnYsnnZtXmfj4eJXSVeSNN95QKx+DPCIiIlJL2QBvxIgR2Lx5c6Xz8FSVl5eHvXv3wsbGRu7FCD8/PwDAlStXFPKUlJQgNTUVZmZmcr1/5UlJScHjx4/h6ekpd97X1xenTp3CwYMHMXr0aLlrsbGxsjSq6NGjR5VfmChLJBKhtLRUrbwM8oiIiLRcXexdK5FIMH78eERHR2PYsGGIiYmpMMB7+PAhHj58iMaNG6Nx48ay8wUFBWjQoIHccitFRUUYP348srKyEBUVJbf1mKurKwICAnDw4EGsW7cOwcHBsmuLFi1CdnY2Ro0aJSsvLy8PN2/eRPv27eXa8/jxY4wfPx4AMHLkSLlrQUFB+Prrr7FgwQK8/fbbcoshb9q0Ca6urujZs2eVPq9mzZrBxMSkSnmqizte1GPc8YJeBtzxgnRZbe14cQ6AeTXLygfQEaq3VbqLhLm5OaZPn650TbyBAwfCy8tLLn1oaCjCwsJkaU6cOIHBgwfD398f9vb2yM3Nxb59+5CRkYGQkBCsXr1aoSes7FZo/fv3h4eHB/78808cOXIEjo6OOH36tGyYNS0tDc7OzujUqRPatWsHW1tb3LlzB7/99hsePXoEf39//PrrrzA0NJSrY8GCBZg7dy4cHBwwdOhQPHnyBNu2bUNBQQFiY2NlPYqVkQ5dW1paYsiQIRg1apTKeauLPXlERERUZWlpaQCA/Px8LFiwQGkaJycnWZBXHgcHB/To0QPHjx/HgwcPYGpqio4dOyIiIgJDhgxRmsfV1RVJSUmYN28eDhw4gIMHD0IsFmPKlCmYN28ebG1tZWltbGwwZcoUnD59Gnv37kV2djbMzMzQrl07jBo1CsHBwUp7IOfMmQMnJydERkZi5cqVMDQ0RNeuXTF//vwq7Sl7/vx5bNq0Cdu2bcOGDRsQHR2NFi1a4L333sOoUaPQunVrlcuqKvbk1WPsyaOXAXvySJfVVk9eMoDq/krkAfBCzbX1ZScIAn7//Xds3rwZu3fvRl5eHkQiETw9PREYGIiRI0cqXXy5Ohjk1WMM8uhlwCCPdFltBXkXoJkgrz0Y5NWGgoIC7Nq1C5s3b8bvv/+O0tJS6Ovro1evXggMDMSgQYNgampa7Xq4Th4RERFRLTIxMcG7776L3377Dbdv30ZERAS8vLxkb/MOHTpUI/VwTh4REZGWq8t18qh6bG1tMXr0aBgaGuKff/5BRkaG2kumvIhBHhERkZariyVUqHqKi4uxZ88exMTE4MCBAygpKQHwfF29999/XyN1MMgjIiLScuzJ0x7x8fGIiYnBjh07kJOTA0EQ0KZNG4waNQrvvfceWrRoobG6GOQRERER1aCrV69i8+bN2Lp1KzIyMiAIAsRiMYKCghAYGFjpMjPqYpBHRESk5diTV3917twZ586dAwCYmpri3XffRWBgIHr37l3lPX6rikEeERGRluOcvPrrjz/+gEgkQqtWrTBo0CCYmZkhKSkJSUlJKpfx2WefqVU318mrx7hOHr0MuE4e6bLaWifvJjSzTp4zuE6epunp6UEkEkEQBIXt2SojzfPs2TO16mZPHhERkZbTQ/WHW9mTVzPGjBlTZ3UzyCMiItJynJNXf23YsKHO6mbgTkRERKSD2JNHRESk5fjiBSnDII+IiEjLcbi2/srIyKh2GQ4ODmrlY5BHREREVEOcnau3goBIJFJ7L1sGeURERFqOw7X1V3VXqqtOfgZ5REREWo7DtfXXzZs366xuBnlERERajkFe/eXo6FhndbN3loiIiEgHMcgjIiLSdiL8OzFP3aNqO26RipYtW4aff/65TupmkEdERKTt9DV0kMZ9+OGHiIqKUnqtZ8+e+PDDD2usbs7JIyIiIqoDcXFxai+PogoGeURERNpOH9UfbhUA1Fy8QXWAQR4REZG208Scuuot50b1EOfkEREREekg9uQRERFpO00N15JOYZBHRESk7Rjk1WuZmZnYtGlTla9JjR49Wq16RUJ1N1WjGpObmwsrKyvk5FyApaVFXTeHqEaYiaq3eTdRfSYAKACQk5MDS0tLjZcv+52wAiyrGeTlCoBVTs219WWlp6cHkUj9hyMSidR+A5c9eURERNqOL17UWw4ODtUK8qqDQR4REZG2k+5aUR0STTSEXpSWllZndTPIIyIi0naaCPJI5/ArQURERKSDGOQRERFpO+5dWy89ffq0TstjkEdERKTtGOTVS05OTli8eDHy8/OrVc7Jkyfx5ptvYunSpVXKxyCPiIiIqAa4uLhg9uzZsLe3x/jx43Ho0CE8e/ZMpbx3797FN998g06dOsHHxwcnTpxA27Ztq1Q/18mrx7hOHr0MuE4e6bJaWyfPHrCsZrdNrgSwusV18jRt+/btmDNnDlJTUyESiWBsbIwOHTrg1VdfRbNmzWBjYwMjIyNkZ2cjKysLV65cQVJSEtLT0yEIAgwMDBAUFITw8HCIxeIq1c0grx5jkEcvAwZ5pMtqLchz0lCQl8YgryYIgoADBw5gzZo12L9/P0pKSgBA6fp50rDM2dkZ48aNw7hx49CsWTO16uUSKkREREQ1SCQSoW/fvujbty+ePn2KU6dO4eTJk0hPT8fDhw9RWFgIGxsb2NrawsvLC927d0fLli2rXS+DPCIiIm2nB744oSVMTU3Rq1cv9OrVq8brYpBHRESk7TSxGDInb+kcBnlEREREdeTu3bu4c+cOCgoK8MYbb2i0bC6hQkREpO24Tp7WWblyJdzc3GBvb4/XX38dPXv2lLv+8ccfo2vXrsjIyFC7DgZ5RERE2k5PQwfVOEEQMGLECHzwwQf4+++/4eTkBHNzc7y42Mlrr72G06dPY+fOnWrXxUdKRESk7diTpzXWr1+P7du3o3Xr1khOTsaNGzfQvn17hXT9+/eHvr4+9u3bp3ZdnJNHREREVEvWr18PPT09bN++HR4eHuWmMzMzg6urK/7++2+161IpyHNxcVG7AmVEIhFu3Lih0TKJiIheWuyJ0xqXL1+Gi4tLhQGelLW1Nc6fP692XSoN16alpWn8ICIiIg2pgzl5d+7cQWRkJAICAuDg4ABDQ0OIxWIMGTIEZ86cqVJZt2/fxsSJE2Xl2NnZISgoCLdu3aow365du+Dv749GjRrBxMQEzs7OGDlyZKX5bt68CXNzc4hEIkyaNEnhelpaGkQiUbnHDz/8UKX7K0sikcDIyEiltLm5uSqnVUbl4drOnTvjp59+UrsiqWHDhuGPP/6odjlERERUd7799lssXrwYrq6u8Pf3h62tLVJSUrB7927s3r0b27Ztw/Dhwyst58aNG+jatSsyMzPh7++PESNGICUlBRs3bsT+/ftx8uRJuLq6yuURBAGTJk3CmjVr4OrqinfeeQcWFha4e/cujh07hvT0dNjb2yutTxAEBAUFqXSPnp6eGDhwoML5tm3bqpRfGWdnZ6SmpiI/Px/m5ublprt//z6uXbsGb29vtetSOcgzMjKCo6Oj2hWVLYeIiIg0SBM7XlRxMWRvb2/Ex8fDx8dH7vzx48fRq1cvTJ48GW+//Xalv/vTp09HZmYmoqKiMG3aNNn57du3Y/jw4ZgyZQoOHDggl+fbb7/FmjVrMGXKFERFRUFfX/7mS0tLy63v22+/RUJCApYsWYIZM2ZU2DYvLy+EhYVVmKaqBgwYgIULF2LevHmIiIgoN93HH38MQRAwaNAgtetSqXN2wIABGlugz8fHBwMGDNBIWURERIQ6ebt28ODBCgEe8Px33s/PD1lZWbh48WKFZRQWFiI2NhZNmzbF1KlT5a4NGzYMXl5eiI2NlXv5oKCgAOHh4XBxcUFkZKRCgAcABgbK+7BSU1Mxe/ZszJo1Cx06dFDlNjVu5syZsLOzQ1RUFIYNG4YDBw6gsLAQwPNh5D179qB3797Ytm0bnJ2d8f7776tdl0o9ebt371a7ghd9+eWXGiuLiIiI6p8GDRoAKD/Yknr06BFKS0vh6OgIkUikcN3Z2RnJyck4evSo7CXQQ4cOISsrC2PHjsWzZ8+wZ88eXL9+HQ0bNkTv3r3RsmVLpXVJJBIEBQXB0dER8+bNw6lTpyq9j7t372LlypXIzs6GnZ0devXqhRYtWlSaryLW1taIjY3F22+/jZ9//lluHTxp2wVBgIuLC/bt2wczMzO166q1JVSuX78Od3f32qqOiIjo5aGJxYz/P39ubq7caSMjoypNtcrIyMDhw4chFovRrl27CtNaW1tDX18f6enpEARBIdC7efMmgOcxhFRSUhKA5wGkp6cnrl279u8t6Onho48+wtdff61QV2RkJE6ePIkTJ06ofD+HDh3CoUOHZH82MDDAtGnT8NVXX0FPT/0PvE2bNrhw4QLWr1+PXbt24eLFi8jJyYG5uTlat26NwYMHY+LEidUK8IAqfCWUfWCqunDhAnx9fdXOT0RERBXQ4HCtvb09rKysZMfChQtVbkZJSQkCAwNRVFSEJUuWKB1KLcvU1BS+vr548OABVqxYIXdt586dSE5OBgBkZ2fLzmdmZgIAli5dCktLSyQmJiIvLw/x8fFwd3fH0qVLsXLlSrmyrl+/jrlz52L69Ono0qVLpfdhamqK0NBQJCcnIzc3F5mZmdizZw/c3NwQERGBOXPmqPBpVF7H1KlTceTIEfzzzz8oLi5GVlYWTpw4gRkzZlQ7wAMAkfDiPhrl0NfXR0REBKZPn16lChITE9G3b19kZ2fj2bNnajXyZZWbmwsrKyvk5FyApaVFXTeHqEaYiZzruglENUYAUAAgJycHlpaWGi9f9jvRDbCs5thcbilglQDcunVLrq2q9uRJJBKMGTMGMTExCAkJwZo1a1Sq9/z58+jevTvy8/PRp08ftG/fHqmpqfjll1/Qtm1bXLhwAZMnT5YFgRMmTMDatWthYmKC1NRU2NnZycq6fPky2rdvL3uDVdqu7t27IzMzExcuXICpqSkAIC4uDn5+fpg4cSJWrVqlUlvv37+Ptm3bIi8vD/fv34e1tbVK+epKlfoaZ8yYge+++07l9MeOHYO/vz8eP36sUuRMREREatDgOnmWlpZyhyoBniAICAkJQUxMDEaNGqVy0AQ8X6bk7NmzGD58OM6dO4eoqChcu3YNq1evRmBgIACgSZMmsvRWVlYAgE6dOskFeMDzYVAXFxfcuHFD1vu3bNkynD59GuvWrZMFeOoSi8Xo168fiouLcfbsWbXKePDgATZt2oSTJ09WmC4hIQGbNm2S9VyqQ+Ug7/vvv4dIJMK0adOwevXqStMfOHAA/fr1Q15eHnr16oWDBw+q3UgiIiKqQB3uXSuRSDB+/Hh8//33GDlyJKKjo6s8X83DwwM//vgjMjMzUVRUhMuXLyM4OBiXLl0C8Dygk2rVqhUAoGHDhkrLkp4vKCgAACQnJ0MQBPj5+cktaOzn5wcAWL16NUQikdL18JRp3LgxAODp06dVukeplStXIigoCLdv364w3Z07dxAUFKRyj6gyKnfujhkzBs+ePUNISAimTJkCfX19BAcHK027c+dOvPvuuyguLsZ//vMf/PTTT1wfj4iIqKZoYluzKq6TBzwP8IKDg7FhwwaMGDECmzdvrnQenqry8vKwd+9e2NjYwN/fX3ZeGpxduXJFIU9JSQlSU1NhZmYm6/3z9fVV+pbvvXv3sH//fnh4eKBbt24qL6mSmJgIAHBycqrqLQEAfv31VxgZGWHIkCEVphs8eDCMjIywZ88ezJ07V626qjSCP27cOEgkEkycOBGTJk2CgYEBxo4dK5dm06ZNCA4ORmlpqeyBV/YKNREREWkXaQ9edHQ0hg0bhpiYmAoDvIcPH+Lhw4do3LixrDcMeN7j1qBBA7lYoaioCOPHj0dWVhaioqJgbGwsu+bq6oqAgAAcPHgQ69atk+twWrRoEbKzszFq1ChZeUFBQUp3uIiLi8P+/fvh6+urMLycmJiIDh06yJaCkYqIiEBCQgJat24NT09PFT8peWlpaXB2dq40GDYwMICzszPS09PVqgdQYwmV4OBgPHv2DO+//z6Cg4Ohr68vGzNfuXIlpk6dColEgnHjxmHt2rVK170hIiIiDRKh+kuoVPHnev78+YiOjoa5uTnc3d3xxRdfKKQZOHAgvLy8AADLly9HeHg4QkND5XaR+OOPPzB48GD4+/vD3t4eubm52LdvHzIyMhASEqKwSDIArFixAl27dkVISAh2794NDw8P/Pnnnzhy5AgcHR3x1VdfVe1mXjBr1ixcvXoVvr6+sLe3R0FBAU6dOoU///wT1tbW2Lx5s9rxzdOnT1WeG2hiYqKwpE1VqNXFNnHiREgkEkyZMgXjxo2DgYEBbt26hdmzZ0MQBEybNg2RkZFqN4qIiIiqQBPDtZKqJU9LSwMA5OfnY8GCBUrTODk5yYK88jg4OKBHjx44fvw4Hjx4AFNTU3Ts2BERERHlDmm6uroiKSkJ8+bNw4EDB3Dw4EGIxWJMmTIF8+bNg62tbdVu5gWjRo3Czz//jJMnT+Lhw4cAAEdHR0yfPh0zZ86s1oLIzZs3x5UrV1BQUAATE5Ny0xUUFODq1asQi8Vq16XyEirKLF++HNOmTYOenh4EQYAgCJg9e3a5D5uqhkuo0MuAS6iQLqu1JVT6AJYNKk9fYVklgFVszbWVnpswYQLWr1+PTz75pMJdwObMmYOFCxdi3LhxWLdunVp1Vatz94MPPkBUVBQkkufh/8KFCxngERER1bY6fLuWqmbmzJlo0KABFi9ejAkTJiAlJUXuekpKCiZOnIhFixbB0NAQM2fOVLsulXvypHvGKXPnzh0IglBh96VIJMKNGzeq3sKXGHvy6GXAnjzSZbXWk/eWhnryfmVPXm3YsmULxo0bh9LSUgDPl31p2LAhsrOzkZ2dDUEQ0KBBA3z//fd477331K5H5Tl50rF3ddPwBQwiIiIi4L333kOrVq0QGhqKw4cP4/Hjx3j8+DEAwNDQEAEBAQgNDcWrr75arXpUDvI2bNhQrYqIiIiohtTBixdUPZ06dcK+fftQWFiI1NRU5ObmwsLCAm5ubnJLxlRHlRZDJiIionqozLZk1SqDap2xsTHatm1bI2XzkRIRERHpIG5FQUREpO04XKuVTp8+jfPnzyMrKwslJSVK04hEIvzvf/9Tq3yVgrxNmzahadOm6NOnj1qVlBUbG4sHDx5g9OjR1S7r5eEIgG86kW56IoTUdROIakxubjGsrDbWfEV6qH6Q90wTDSFVxMfHY/z48fj7778rTCcIQs0HeWPHjkX37t01EuR98cUXOHnyJIM8IiIiTeGcPK3x119/oW/fvigpKcF7772HY8eO4fbt2/jss89w69YtnD9/HufPn4eJiQkmT54MCwv1l1DjcC0RERFRLVm0aBEKCwuxbt06BAUFwcfHB7dv38bnn38uS3Pw4EGMHz8esbGxOHXqlNp1qRzkXbx4ET179lS7orLlEBERkQZpYk4ed7yoFXFxcbCysqpw1ZKAgADs3LkTr732GubPn48lS5aoVZfKQV5OTg7i4uLUquRFXBiZiIhIgxjkaY3MzEy0bt0aenrPx8cNDJ6HYgUFBTAxMZGl69y5M1q1aoWdO3fWbJB39OhRtQonIiIion9ZWVnh2bN/33KxsbEBAKSnp8PDw0MuraGhoUo7jpVHpSDP19dX7QqIiIiohvHFC63h4OCA9PR02Z/btWuH3bt3Y+/evXJBXlpaGq5duwYrKyu16+IjJSIi0nb6Gjqoxvn5+eHRo0eyHrqRI0dCJBJhzpw5mDt3Lvbt24fvv/8eAQEBKCkpQb9+/dSui2/XEhEREdWSIUOGYNeuXThx4gScnJzQqlUrfP7555gzZw4WLlwoSycIAlxcXLBo0SK162KQR0REpO04XKs1XnvtNaSkpMidmz17Nrp3744tW7YgLS0NJiYm6N69OyZMmMB18oiIiF5qmtjxgkFenfLx8YGPj49Gy+QjJSIiIqolPXv2RL9+/VBcXFzjdTHIIyIi0nZ88UJrnDp1CpmZmTA0NKzxujhcS0REpO04J09rODg4oLCwsFbqUvmR9uzZEx9++GENNoWIiIjUwp48rTFkyBBcvXoV169fr/G6VA7y4uLicO7cuZpsCxEREZFOmzt3Lry8vPD222/j/PnzNVoXh2uJiIi0Hfeu1RoffPAB3NzcsGPHDnTs2BFt2rTBK6+8AjMzM6XpRSIR1q9fr1ZdDPKIiIi0HefkaY3o6GiIRCIIggAAuHTpEi5dulRuegZ5RERERFpgw4YNtVYXgzwiIiJtx+FarTFmzJhaq6tKQV5CQgL09dX7FohEIpSWlqqVl4iIiCogQvWHW0WaaAhVJiMjA8bGxrC1ta00bWZmJgoLC+Hg4KBWXVX6SgiCUK2DiIiI6GXm5OSEYcOGqZR2xIgRcHFxUbuuKvXktWvXDsuWLVO7MiIiIqoBHK7VKlXp+KpOJ1mVgjwrKyv4+vqqXRkRERHVAAZ5Oik3NxdGRkZq5+eLF0RERET1SFFREY4dO4YLFy7Azc1N7XK4Kg4REZG209PQQRoXHh4OfX192QH8+yJreYepqSn69u2LZ8+e4Z133lG7bvbkERERaTsO19ZbL758WnYh5PKYmJjAxcUFI0aMwKeffqp23QzyiIiItB2DvHorLCwMYWFhsj/r6emhe/fuiI+Pr/G6VQ7yJBJJTbaDiIiISOeFhoaqve5dVbEnj4iISNtx71qtERoaWmt1McgjIiLSdnqo/nArgzydw0dKREREVAPatm2LH3/8sdq7fmVkZGDSpElYvHhxlfIxyCMiItJ2XEKlXsrLy8O7774Ld3d3fP7550hJSVE5b3FxMXbt2oWhQ4fCzc0N69atU2m/27I4XEtERKTt+HZtvXT9+nUsW7YMixYtQmhoKMLCwuDq6gpvb2+8+uqraNasGWxsbGBkZITs7GxkZWXhypUrSEpKQlJSEp48eQJBEODv74/FixfDy8urSvWLhOr2IVKNyc3NhZWVFXJycmBpaVnXzSGqIRPqugFENSY3txhWVhtr7O9x2e/EN4ClSTXLKgCsPgJ/c2pAXl4eYmJisHbtWiQnJwN4vl6eMtKwzMzMDO+88w4mTJiAzp07q1Uve/KIiIi0HXvy6jULCwtMnjwZkydPRkpKCuLj43Hy5Emkp6fj4cOHKCwshI2NDWxtbeHl5YXu3buja9euMDU1rVa9DPKIiIi0HZdQ0Rpubm5wc3PD+PHja7wuPlIiIiIiHcQgj4iISNvpa+iogjt37iAyMhIBAQFwcHCAoaEhxGIxhgwZgjNnzlSprNu3b2PixImycuzs7BAUFIRbt25VmG/Xrl3w9/dHo0aNYGJiAmdnZ4wcObLSfDdv3oS5uTlEIhEmTZpUbrqtW7fC29sbZmZmsLa2Rr9+/ZCUlFSle6tLHK4lIiLSdnUwXPvtt99i8eLFcHV1hb+/P2xtbZGSkoLdu3dj9+7d2LZtG4YPH15pOTdu3EDXrl2RmZkJf39/jBgxAikpKdi4cSP279+PkydPwtXVVS6PIAiYNGkS1qxZA1dXV7zzzjuwsLDA3bt3cezYMaSnp8Pe3l5pfYIgICgoqNJ2ffnll5gzZw4cHBwwadIk5Ofn44cffkC3bt0QGxuLHj16qPQ5lfXPP//gl19+wZkzZ5CSkoLHjx+joKAAJiYmsLa2hpubG1577TUMGDCgysulKMO3a+sxvl1LLwe+XUu6q9berl0LWFZvjj5ynwJWIaq/Xbtz5040adIEPj4+cuePHz+OXr16yYIuIyOjCst56623sG/fPkRFRWHatGmy89u3b8fw4cPRp08fHDhwQC7PsmXLMH36dEyZMgVRUVHQ15fvhiwtLYWBgfJ+rGXLluHjjz/GkiVLMGPGDEycOBGrVq2SS5OSkoLWrVvDxcUFiYmJsLKyAgBcvnwZ3t7eaNasGa5evVpuHS8qLCzErFmzsGbNGpSUlFS4OLJIJEKDBg0QEhKCJUuWwMRE/dem2ZNHREREVTZ48GCl5318fODn54eDBw/i4sWL6NSpU7llFBYWIjY2Fk2bNsXUqVPlrg0bNgxeXl6IjY3F33//DRcXFwBAQUEBwsPD4eLigsjISIUAD0C5wVdqaipmz56NWbNmoUOHDuW2a8OGDSgtLcWcOXNkAR4AtGnTBqNHj8aqVatw5MgRBAQElFuGVFFREXr06IGzZ89CEAR4eHigW7ducHFxgbW1NYyMjFBUVITHjx/j77//RkJCAq5evYoVK1YgMTERx48fh6GhYaX1KMMgj4iISNvVsyVUGjRoAKD8YEvq0aNHKC0thaOjo9J145ydnZGcnIyjR4/KgrxDhw4hKysLY8eOxbNnz7Bnzx5cv34dDRs2RO/evdGyZUuldUkkEgQFBcHR0RHz5s3DqVOnym1XXFwcACgN4vr06YNVq1bh2LFjKgV5X331FRITE9GqVSt8//336NKlS6V5Tp48iXHjxiEpKQlLlizB3LlzK82jDIM8IiIibafBOXm5ublyp42MjCodci0rIyMDhw8fhlgsRrt27SpMa21tDX19faSnp0MQBIVA7+bNmwCe7xwhJX3xwcDAAJ6enrh27dq/t6Cnh48++ghff/21Ql2RkZE4efIkTpw4Uen9pKSkwNzcHGKxWOGam5ubLI0qtm3bBkNDQxw8eLDceYIv6tq1K2JjY+Hu7o6tW7eqHeTx7VoiIiKSsbe3h5WVlexYuHChynlLSkoQGBiIoqIiLFmyROlQalmmpqbw9fXFgwcPsGLFCrlrO3fulO0OkZ2dLTufmZkJAFi6dCksLS2RmJiIvLw8xMfHw93dHUuXLsXKlSvlyrp+/Trmzp2L6dOnq9STlpOTIzdMW5Z0vmJOTk6l5QDPA9W2bduqHOBJOTo6om3btkhLS6tSvrLYk0dERKTtNDhce+vWLbkXL1TtxZNIJBg3bhzi4+MREhKCwMBAlfJFRESge/fu+OCDD7B37160b98eqamp+OWXX9C+fXtcuHBBLliUSCQAAENDQ+zevRt2dnYAns8F3LFjB9q3b4+lS5di8uTJsvRjx46FnZ0dvvjiC5XapEnm5uaywLSqMjMzYWZmpnbd7MkjIiLSdhpcJ8/S0lLuUCXIEwQBISEhiImJwahRoxTeVq2Ip6cnzp49i+HDh+PcuXOIiorCtWvXsHr1almg2KRJE1l6aQ9bp06dZAGeVJs2beDi4oIbN27Iev+WLVuG06dPY926dSpvEyZd2UIZ6XB2eT19L+rSpQvu3LmDiIgIldJLff3117hz5w66du1apXxlMcgjIiIitUkkEowfPx7ff/89Ro4ciejoaOjpVS288PDwwI8//ojMzEwUFRXh8uXLCA4OxqVLlwBA7g3dVq1aAQAaNmyotCzp+YKCAgBAcnIyBEGAn58fRCKR7PDz8wMArF69GiKRCAMHDpSV4ebmhvz8fNy/f1+hfOlcPOncvMp8+umn0NPTw3//+1/069cPO3bswL1795SmvXfvHnbs2IG+ffvik08+gb6+PmbPnq1SPcpwuJaIiEjb1dHetRKJBMHBwdiwYQNGjBiBzZs3VzoPT1V5eXnYu3cvbGxs4O/vLzsvDc6uXLmikKekpASpqakwMzOT9f75+voqfcv33r172L9/v2xJk7JLqvj6+uLUqVM4ePAgRo8eLZcvNjZWlkYVXbp0QXR0NIKDg3HgwAFZfiMjIzRs2BCGhoYoLi5GdnY2ioqKADzvGTU0NMTatWvx+uuvq1SPMgzyiIiItF0dLKEi7cGLjo7GsGHDEBMTU2GA9/DhQzx8+BCNGzdG48aNZecLCgrQoEEDuUCsqKgI48ePR1ZWFqKiomBsbCy75urqioCAABw8eBDr1q1DcHCw7NqiRYuQnZ2NUaNGycoLCgpSusNFXFwc9u/fD19fX4Xh5aCgIHz99ddYsGAB3n77bbnFkDdt2gRXV1f07NlT5c/qvffeQ/fu3bFkyRLs3r0b9+7dQ2FhodKeQrFYjEGDBuG///0vnJycVK5DGQZ5REREVGXz589HdHQ0zM3N4e7urvSlhoEDB8LLywsAsHz5coSHhyM0NBRhYWGyNH/88QcGDx4Mf39/2NvbIzc3F/v27UNGRgZCQkIUFkkGgBUrVqBr164ICQnB7t274eHhgT///BNHjhyBo6Mjvvrqq2rdm7u7O8LCwjB37ly0b98eQ4cOxZMnT7Bt2zaUlJRg7dq1Ku92IeXo6IjvvvsO3333HTIyMmTbmhUWFsLY2Fi2rZmDg0O12l4WgzwiIiJtJ0L1h2sV1yKukHRpj/z8fCxYsEBpGicnJ1mQVx4HBwf06NEDx48fx4MHD2BqaoqOHTsiIiICQ4YMUZrH1dUVSUlJmDdvHg4cOICDBw9CLBZjypQpmDdvnkb2fZ0zZw6cnJwQGRmJlStXwtDQEF27dsX8+fPRuXPnapXt4OCg0WCuPNy7th7j3rX0cuDetaS7am3v2l2ApforbTwv6wlgNUj1vWup/mNPHhERkbarZ9uakWbcuXMHz549U7vXj0EeERERUT3k5eWFx48fo7S0VK38DPKIiIi0XR0toUI1rzqz6hjkERERaTsO15ISDPKIiIiIasiXX36pdl7prh3qYpBHRESk7diTV2/NnTsXIlEV16f5f4IgqJ0XYJBHRESk/Tgnr97S19eHRCLB4MGDYW5uXqW8P/zwA4qLi9Wum0EeERERUQ1p06YNLl68iJCQEAQEBFQp76+//oqsrCy162bcTkREpO308O+QrboHI4Ia4e3tDQBISkqq9br5SImIiLSdnoYO0jhvb28IgoAzZ85UOW91NyXjcC0RERFRDenduzemT5+Oxo0bVznvnj17UFJSonbdDPKIiIi0Hd+urbecnJzwzTffqJW3a9eu1aqbQR4REZG2Y5BHSjDIIyIi0nZcQoWU4CMlIiIi0kHsySMiItJ2HK7VGvr6qn/Qenp6sLCwgJOTE7p3747g4GC0b99e9fzqNJCIiIjqkequkaeJIJFUIgiCysezZ8+QnZ2N5ORkLF++HK+++iq++uorletikEdERERUSyQSCSIiImBkZIQxY8YgLi4OWVlZKCkpQVZWFo4dO4axY8fCyMgIERERyM/PR1JSEt5//30IgoBPP/0Uv//+u0p1cbiWiIhI24lQ/W4bkSYaQpX5+eef8fHHH2P58uWYPHmy3LWGDRvCx8cHPj4+6Ny5Mz744AM0b94cw4YNQ8eOHeHi4oKZM2di+fLl6NWrV6V1iYTqLqdMNSY3NxdWVlbIycmBpaVlXTeHqIZMqOsGENWY3NxiWFltrLG/x2W/ExcAS4tqlpUHWLUHf3NqWJcuXXDr1i3cvn270rQtWrRAixYtcPr0aQBAaWkpGjduDBMTE9y7d6/S/ByuJSIiIqolly5dQvPmzVVK27x5c/z111+yPxsYGMDd3R1ZWVkq5edwLRERkbbjOnlao0GDBrh+/TqKiopgZGRUbrqioiJcv34dBgbyoVpubi4sLFTrtuUjJSIi0nZ8u1ZrdOvWDbm5ufjggw8gkUiUphEEAVOnTkVOTg66d+8uO19cXIybN2/Czs5OpbrYk0dERERUS+bPn4/Dhw/j+++/x8mTJxEYGIj27dvDwsIC+fn5uHDhAmJiYvDXX3/ByMgI8+fPl+XdtWsXSkpK4Ofnp1JdDPKIiIi0HRdD1hodOnTA3r17ERgYiCtXrmDOnDkKaQRBgFgsxubNm+Hl5SU737RpU2zYsAE+Pj4q1cUgj4iISNtxTp5W6d27N1JSUrB161YcOnQIKSkpePLkCczMzODu7g5/f3+MHDkS5ubmcvl69OhRpXoY5BEREWk79uRpHXNzc0yYMAETJtTcMlKM24mIiIh0EHvyiIiItJ0eqt8Tx26fWnfz5k0cOnQI169fR15eHiwsLGTDtc7OztUun0EeERGRtuOcPK3y+PFjvP/++9i+fTukG48JggCR6PneciKRCCNGjMDy5cthbW2tdj0M8oiIiIhqSUFBAXr16oXz589DEAR06dIFbdq0QdOmTfHgwQNcvnwZp06dwg8//ICrV68iISEBxsbGatXFII+IiEjb8cULrfHNN98gOTkZHh4e2LRpEzp16qSQJikpCWPGjEFycjIiIyPx6aefqlUXO2eJiIi0nZ6GDqpxP/30E/T19fHrr78qDfAAoFOnTtizZw/09PTwww8/qF1XvX+k0dHREIlEFR69evWSy5Obm4sZM2bA0dERRkZGcHR0xIwZM5Cbm1tuPVu3boW3tzfMzMxgbW2Nfv36ISkpqcrtVaduIiIiejmkpqaibdu2cHFxqTCdq6sr2rZti9TUVLXrqvfDtV5eXggNDVV6bceOHbh8+TL69OkjO/fkyRP4+voiOTlZtpjg+fPn8c033+Do0aM4ceIEzMzM5Mr58ssvMWfOHDg4OGDSpEnIz8/HDz/8gG7duiE2NlblxQfVqZuIiKjaOFyrNfT19VFSUqJS2pKSEujpqd8fpxVBXtktPaSKi4uxfPlyGBgYYMyYMbLzS5YsQXJyMmbNmoXFixfLzoeGhmL+/PlYsmQJwsPDZedTUlIQGhoKd3d3JCYmwsrKCgAwbdo0eHt7Izg4GFevXoWBQeUfVVXrJiIi0ggGeVqjVatW+OOPP3D+/Hl4enqWmy45ORl//fUXOnfurHZd9X64tjy7du3Co0eP8NZbb6Fp06YAnr9+vG7dOpibm2PevHly6WfPng1ra2usX79e9royAGzYsAGlpaWYM2eOLMADgDZt2mD06NG4ceMGjhw5Uml71KmbiIiIXi6BgYEQBAFvvfUW9u7dqzTNnj17MGDAAIhEIgQGBqpdl9YGeevXrwcABAcHy86lpKTg7t276Natm8KwqLGxMd544w3cuXNHbnw7Li4OABAQEKBQh3QY+NixY5W2R526iYiINIIvXmiNyZMnw8/PD3fu3MHAgQPh7OyMvn37YsyYMejbty+cnJwwaNAg3L59G35+fpg8ebLaddX74Vpl0tPT8fvvv6N58+Z48803ZedTUlIAAG5ubkrzSc+npKTI/X9zc3OIxeIK01dGnbpfVFRUhKKiItmf+bIGERGpRKQH/P9CuuqXIQCQaKQ5VD4DAwPs27cPc+fOxapVq5Ceno709HS5NKamppg8eTI+//xz6OurP46ulUHehg0bIJFIEBQUJHfzOTk5ACA37FqWpaWlXDrp/7e1tVU5fXnUqftFCxcu5Jw9IiJSgwGAagZ5EAAUa6AtVBljY2N8/fXXCA0NxYkTJ3D9+nXk5+fD3Nwc7u7u6N69OywsLKpdj9YFeRKJBBs2bIBIJMK4cePqujkaNXv2bMyYMUP259zcXNjb29dhi4iIiKimWFhYoG/fvujbt2+NlK91Qd6hQ4eQkZGBXr16KWzeK+1FK6+3TDr8Wba3zcrKqkrpy6NO3S8yMjKCkZFRpXURERHJY09efZSRkaGRchwcHNTKp3VBnrIXLqQqm0OnbN6cm5sbTp06hfv37yvMy6tsnl116yYiItIMTQV5pElOTk4QVXOupEgkQmlpqVp5tSrIe/ToEX755RfY2Nhg0KBBCtfd3NxgZ2eHhIQEPHnyRO4t18LCQsTHx8POzg4tW7aUnff19cWpU6dw8OBBjB49Wq682NhYWZrKqFM3ERER6S4HB4dqB3nVoVUvTG/evBnFxcUYNWqU0mFNkUiE4OBg5OfnY/78+XLXFi5ciMePHyM4OFjuAw8KCoKBgQEWLFggN9R6+fJlbNq0Ca6urujZs6dcWRkZGbh69SqePn1arbqJiIg0Qx/P+22qc3A1ZE1LS0vDzZs3q32oS6uCvIqGaqVmzZoFLy8vLFmyBAEBAZg9ezb69euH+fPnw8vLC7NmzZJL7+7ujrCwMFy/fh3t27fHxx9/jEmTJqFr164oKSnB2rVrFXa7GD16NF555RUkJiZWq24iIiLNqG6AJz1Ud+fOHURGRiIgIAAODg4wNDSEWCzGkCFDcObMmSqVdfv2bUycOFFWjp2dHYKCgnDr1q0K8+3atQv+/v5o1KgRTExM4OzsjJEjRyrkW7t2Lf7zn//A2dkZZmZmsLKygqenJ+bNm4esrCyFctPS0iASico9fvjhhyrdX13RmuHaxMREXLp0Cd7e3mjXrl256czMzBAXF4fw8HDs2LEDcXFxEIvF+OijjxAaGqp079g5c+bAyckJkZGRWLlyJQwNDdG1a1fMnz+/StuJqFM3ERGRNvr222+xePFiuLq6wt/fH7a2tkhJScHu3buxe/dubNu2DcOHD6+0nBs3bqBr167IzMyEv78/RowYgZSUFGzcuBH79+/HyZMn4erqKpdHEARMmjQJa9asgaurK9555x1YWFjg7t27OHbsGNLT0+VWp9i8eTMeP34MHx8fNGvWDEVFRTh9+jQ+//xzbNy4EWfOnFG6Xq6npycGDhyocL5t27ZV/8DqgEjgPlv1Vm5uruztX+k6e0S6Z0JdN4CoxuTmFsPKamON/T3+7+9EM1haVm9wLjdXAiureyq3defOnWjSpAl8fHzkzh8/fhy9evWSBV2VrRrx1ltvYd++fYiKisK0adNk57dv347hw4ejT58+OHDggFyeZcuWYfr06ZgyZQqioqIUFgwuLS2VG4UrLCyEsbGxQt3/+9//8MUXX2DmzJn46quvZOfT0tLg7OyMMWPGIDo6utLPor7SquFaIiIiUqb2h2sHDx6sEOABgI+PD/z8/JCVlYWLFy9WWEZhYSFiY2PRtGlTTJ06Ve7asGHD4OXlhdjYWPz999+y8wUFBQgPD4eLiwsiIyOV7gjx4jQrZQGetA4AOrvlqNYM1xIREZF2aNCgAQDFYOtFjx49QmlpKRwdHZW+mOjs7Izk5GQcPXoULi4uAJ6vl5uVlYWxY8fi2bNn2LNnD65fv46GDRuid+/eVVrFYt++fQDKH369e/cuVq5ciezsbNjZ2aFXr15o0aKFyuXXNQZ5REREWk8f1R+c08zqDxkZGTh8+DDEYnGFc+gBwNraGvr6+khPT4cgCAqBnvTN0uvXr8vOJSUlAXgeQHp6euLatWuya3p6evjoo4/w9ddfK60vOjoaaWlpyMvLw7lz5xAXF4cOHTrI7TZV1qFDh3Do0CHZnw0MDDBt2jR89dVX0NOr/4Oh9b+FREREVAnNLaGSm5srdxQVFancipKSEgQGBqKoqAhLlixROpRalqmpKXx9ffHgwQOsWLFC7trOnTuRnJwMAMjOzpadz8zMBAAsXboUlpaWSExMRF5eHuLj4+Hu7o6lS5di5cqVSuuLjo5GeHg4IiIiEBcXh4CAABw4cADW1tYK7QoNDUVycjJyc3ORmZmJPXv2wM3NDREREZgzZ47Kn0ldYpBHRESk9TQ3J8/e3h5WVlayY+HChSq1QCKRYNy4cYiPj0dISAgCAwNVyhcREQFzc3N88MEHePPNNzFr1iwMHjwYw4YNQ/v27QFALliUSCQAAENDQ+zevRudO3eGubk5fHx8sGPHDujp6WHp0qVK64qLi4MgCPjnn3/w66+/4vbt2+jYsSMuXLggl87W1hZhYWHw9PSEhYUFmjRpgv/85z84cuQIGjVqhIiICDx+/Fil+6tLDPKIiIhI5tatW8jJyZEds2fPrjSPIAgICQlBTEwMRo0ahVWrVqlcn6enJ86ePYvhw4fj3LlziIqKwrVr17B69WpZoNikSRNZeuke8J06dYKdnZ1cWW3atIGLiwtu3Lgh1/v3osaNG6N///44cOAAHj58iJCQEJXaKhaL0a9fPxQXF+Ps2bMq32Nd4Zw8IiIiraeJHSuez4eztLSs0nIvEokEwcHB2LBhA0aOHIno6Ogqz1fz8PDAjz/+qHB+7NixAJ4HdFKtWrUCADRs2FBpWdLzBQUF5aaRsre3xyuvvIKzZ8/i6dOnMDU1rbStjRs3BgC5Xa/qKwZ5REREWk9zQV5VlA3wRowYgc2bN1c6D09VeXl52Lt3L2xsbODv7y877+fnBwC4cuWKQp6SkhKkpqbCzMxMrvevIvfu3YNIJFK53dLdrpycnFRKX5c4XEtERERVJpFIMH78eGzYsAHDhg1DTExMhYHSw4cPcfXqVTx8+FDufEFBAUpLS+XOFRUVYfz48cjKykJoaKjcOneurq4ICAhAamoq1q1bJ5dv0aJFyM7OxqBBg2TLtzx69AiXL19WaI8gCAgLC8ODBw/g5+cnt2hzYmIiSkpKFPJEREQgISEBrVu3hqenZwWfTv3AnjwiIiKtV/s9efPnz0d0dDTMzc3h7u6OL774QiHNwIED4eXlBQBYvnw5wsPDERoairCwMFmaP/74A4MHD4a/vz/s7e2Rm5uLffv2ISMjAyEhIQqLJAPAihUr0LVrV4SEhGD37t3w8PDAn3/+iSNHjsDR0VFu94pbt26hQ4cO8Pb2RuvWrSEWi/Hw4UMcP34c165dg1gsxnfffSdX/qxZs3D16lX4+vrC3t4eBQUFOHXqFP78809YW1tj8+bNStf1q28Y5BEREWk96RIqtSctLQ0AkJ+fjwULFihN4+TkJAvyyuPg4IAePXrg+PHjePDgAUxNTdGxY0dERERgyJAhSvO4uroiKSkJ8+bNw4EDB3Dw4EGIxWJMmTIF8+bNg62trSyto6MjZs+ejbi4OOzfvx9ZWVkwNjaGm5sb5s6diw8//BCNGjWSK3/UqFH4+eefcfLkSVnPo6OjI6ZPn46ZM2dqzYLI3Lu2HuPetfRy4N61pLtqb+9ab1haVi/Iy80thZVVIn9zdAh78oiIiLRe1feeJd3HbwQREZHWY5BHivh2LREREZEOYthPRESk9diTR4r4jSAiItJ6mni7lu9h6hoGeURERFpPEz15DPJ0DefkEREREekg9uQRERFpPfbkkSIGeURERFqPQR4p4nAtERERkQ5iTx4REZHWY08eKWKQR0REpPU0sYSKRBMNoXqEw7VEREREOog9eURERFpP//+P6pZBuoRBHhERkdbTxJw8DtfqGg7XEhEREekg9uQRERFpPfbkkSIGeURERFqPQR4pYpBHRESk9TSxhMozTTSE6hHOySMiIiLSQezJIyIi0nqaGK5lT56uYZBHRESk9RjkkSIO1xIRERHpIPbkERERaT325JEiBnlERERaTxNv15ZqoiFUj3C4loiIiEgHsSePiIhI62liuJYhga7hEyUiItJ6DPJIEYdriYiIiHQQw3YiIiKtx548UsQnSkREpPUY5JEiPlEiIiKtp4klVPQ10RCqRzgnj4iIiEgHsSePiIhI63G4lhTxiRIREWk9BnmkiMO1RERERDqIYTsREZHW00f1X5zgixe6hkEeERGR1uPbtaSIw7VEREREOog9eURERFqPL16QIj5RIiIirccgjxRxuJaIiIhIBzFsJyIi0nrsySNFfKJERERaj0EeKeITJSIi0npcQoUUcU4eERERkQ5ikEdERKT1DDR0qO7OnTuIjIxEQEAAHBwcYGhoCLFYjCFDhuDMmTNVKuv27duYOHGirBw7OzsEBQXh1q1bFebbtWsX/P390ahRI5iYmMDZ2RkjR45UyLd27Vr85z//gbOzM8zMzGBlZQVPT0/MmzcPWVlZ5Za/detWeHt7w8zMDNbW1ujXrx+S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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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IiKStQcPHqBnz544fvw4hBBo2bIlQkJC0KRJE7i6ukKpVOLBgwe4d+8e/v77byQlJSE1NRWff/45jh07hl9//RU2NjYGl8sQRUREJHf1vDtv6dKlOHbsGFq0aIGvv/4aXbt2rfKYw4cPIzo6GsnJyViyZAnmzp1rcLkyvmVEREQE4H/fzjN2kanNmzfDxsYGe/bs0StAAUC3bt2we/duWFlZYdOmTZLKZYgiIiIiWbt8+TLatm0LHx8fg47z8/ND27ZtkZaWJqlcducRERHJXT2fJ8rR0RE3b96UdOzNmzfh4OAg6Vi2RBEREcmdhYkWmeratSuuXr2Kjz76yKDjPvzwQ1y9ehXdunWTVK6MbxkRERERMHPmTFhYWOCf//wnnnvuOWzduhXXr1/Xue/169exdetW9O/fH++88w4sLS0xa9YsSeWyO4+IiEju6nl3XteuXbF27VrExMTg559/xu7duwEASqUSTzzxBGxsbFBUVITs7Gw8ePAAACCEgI2NDVatWoVnnnlGUrlsiSIiIpK7et6dBwAjR45EamoqJk6cCE9PTwghUFhYiKysLGRkZCArKwuFhYUQQqBhw4aYOHEiUlNTERkZKblMtkQRERHJHWcsB/Dw23afffYZPvvsM2RkZGge+1JYWAhbW1vNY198fX1NUh5DFBEREdU5vr6+JgtLFWGIIiIikrt6PibKXBiiiIiI5K6eP/bFGFevXkVpaamkViuGKCIiIqq3goKCcO/ePZSUlBh8LEMUERGR3LE7zyhCCEnHMUQRERHJHUOUWTBEERERkay99957ko8tKCiQfCxDFBERkdzV84Hlc+fOhUKhkHSsEELysQxRREREclfPu/MsLS1RVlaGl156CY6OjgYd+80336CoqEhSuQxRREREJGtt2rTByZMnMW7cOPTt29egY3fu3Im7d+9KKlfGjXdEREQEAFDA+OfmSevRqhWCg4MBAMnJyTVaLkMUERGR3FmaaJGp4OBgCCHw22+/GXys1OkNAHbnERERyV89HxPVp08fTJkyBe7u7gYf+8MPP6C4uFhSuQxRREREJGv+/v74+OOPJR3brVs3yeUyRBEREcldPZ/iwFwYooiIiOSunnfnmQtzJxEREZEEbIkiIiKSO7ZEabG01P9iLCws4OTkBH9/f4SGhiImJgbt27fX71ipFSQiIqJawtg5okwx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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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PgGFKhYDsirs33//haurq767QUREWkpISICLi4vO683JyYGFuTl0tfbI0dERd+/eZVCmBwzIqjD58/ES+gM2xnruDFEFcdyj7x4QVRwBIAdQ+bxTXcjLy4MAYA5A23kUASAxMRF5eXkMyPSAAVkVJp+mtDFmQEbVFyfjqSao6GUnhtBNQEb6w4CMiIhI4hiQSR/vsiQiIiLSM46QERERSZwBOEImdQzIiIiIJM4A2k95FemiI1RuDMiIiIgkzhDaB2S8wUa/uIaMiIiISM84QkZERCRxupiyJP1iQEZERCRxnLKUPgbURERERHrGETIiIiKJ4wiZ9DEgIyIikjiuIZM+vn9EREREesYRMiIiIokzwLNpS5IuBmREREQSp4spSz46Sb84ZUlERESkZxwhIyIikjhDcMpS6hiQERERSRwDMuljQEZERCRxXEMmfVxDRkRERKRnHCEjIiKSOE5ZSh8DMiIiIoljQCZ9nLIkIiIi0jOOkBEREUmcDNqPsBTpoiNUbgzIiIiIJE4XU5a8y1K/OGVJREREpGccISMiIpI4XeQh4wiNfjEgIyIikjhOWUofA2IiIiIiPeMIGRERkcRxhEz6GJARERFJHNeQSR8DMiIiIonjCJn0MSAmIiIi0jOOkBEREUmcAbQfIWOmfv1iQEZERCRxXEMmfbz+RERERHrGETIiIiKJ08Wifk5Z6hcDMiIiIonjlKX08foTERFRpTtx4gRmzZqFgIAA2NraQiaTYcyYMeWqSyaTlfpatmyZbjteQThCRkREJHFSnLLcsGEDNm3aBAsLCzRo0ADp6ela1efm5qYyoPPz89Oq3srCgIyIiEjipBiQTZs2De+//z68vb1x7tw5dO7cWav63N3dERoaqpvO6QEDMiIiIqp07dq103cXqhQGZERERBLHRf1Aamoq1q1bh6SkJNSpUwc9evSAp6envrulNgZkREREEqeLTP2F///f59dymZqawtTUVMvaK97ly5cxceJExc8ymQwjR47EmjVrYGFhoceeqUfqATEREVGNZ6ijFwC4urrC1tZW8Vq6dGllnkq5zJo1C2fOnEFycjJSUlJw7NgxdOzYEVu3bsX48eP13T21cISMiIiIFBISEmBjY6P4uazRMQcHBzx58kTtuiMiItCjRw9tuqfS559/rvRzQEAAjh49itatW2PHjh1YsGABmjdv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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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atQIc+fOxcyZM+Hk5KRHzyof0yZUYUybQDUC0yZQNVZZaROGA7A0sK58AFuBCutrdccRKiIiIpkzxb38SB0DKiIiIpkz1ZQf/T8GpEREREQG4ggVERGRzHHKz/QYUBEREckcp/xMjwEpERERkYE4QkVERCRzHKEyPQZUREREMifB8CknyRgdqcE45UdERERkII5QERERyRyn/EyPARUREZHMMaAyPQZUREREMsc8VKbH60dERERkII5QERERyRyn/EyPARUREZHMccrP9Hj9iIiIiAzEESoiIiKZ45Sf6TGgIiIikjkzGB4QccrKMLx+RERERAbiCBUREZHMcVG66TGgIiIikjmuoTI9BqREREREBuIIFRERkcxxhMr0GFARERHJHNdQmR4DKiIiIpnjCJXpMSAlIiIiMhBHqIiIiGSOU36mx4CKiIhI5pgp3fR4/YiIiIgMxBEqIiIimeOidNNjQEVERCRzXENlerx+RERERAbiCBUREZHMccrP9BhQERERyRwDKtPjlB8RERGRgThCRUREJHNclG56DKiIiIhkjlN+pseAioiISOYkGD7CJBmjIzVYlR/hy8jIwLRp09ClSxe4ublBoVCgfv366NmzJ/773/9CCFHimKysLMyYMQPe3t5QKBTw9vbGjBkzkJWVpbWdLVu2oGPHjrCxsYGTkxOeffZZxMfHl7u/+rRNRERE8iYJTRFJFXLhwgW0adMGnTt3RqNGjeDs7Izbt29j165duH37NiZMmIBvv/1WVT4nJwfdunXDmTNnEBoainbt2iEhIQH79u1DmzZtEBsbCxsbG7U2Fi1ahLlz58LLywuDBw/G/fv3sW3bNuTm5iIyMhLBwcE69VWftkuTlZUFBwcHZA4B7GvpfBiRvGyq0h9BRAZRfY5nZsLe3r7C6v8OQG0D63oAYBxQYX2t7qr8lF+DBg2QkZEBCwv1rmZnZ6Nz585YvXo1pk+fjhYtWgAAlixZgjNnzmD27Nn4+OOPVeXDwsIwf/58LFmyBBEREartqampCAsLg5+fH06dOgUHBwcAwLRp09CxY0eMHz8eycnJJdrXpLxtExERGQPXUJlelZ/yMzc31xjM2NnZoU+fPgAejWIBgBACa9asga2tLT744AO18u+++y6cnJywdu1atWnCdevWobCwEHPnzlUFUwDQokULjBo1ChcvXsThw4fL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hz08PBwHDx7EihUrKq1NIqrZGFAR1SCWlpbYv38/XnzxRdy8eROjRo2Cs7MzWrZsiY4dO8LDwwNNmjTB8uXL4ebmhkaNGgEAoqKicPXqVTz//PPIyMhARkYG7O3t0alTJ2zevFktWHJycsK9e/dKtH3v3j04OztX2rkSEVUmBlRENYytrS127NiBmJgYvPrqq/D09MSlS5eQkJAAIQT69euHtWvXIiUlBf7+/gD+P0XCW2+9BScnJ9XjxIkTuHz5MmJjY1X1t2jRAufOnSvR7rlz59CsWbPKOUkiokrGtAlENVT37t3RvXv3Msvl5uZix44deOaZZ/DOO++o7SsoKMCAAQOwadMmVV3PPfcc5s6dq5ZS4ffff8f58+exePFio55DWevAnuTh4VGpU49EVHNIgp8uRFSK7du3Y+jQodi9ezf69etXYv/QoUNx4MAB3Lx5E5aWlsjOzkarVq1Qp04dhIWFITc3F++88w6eeuopHD9+HGZmZQ+MX7p0CQ0aNIBCoVDlkBo3bhzGjRtn9PNTGjt2LFJTU5GZmYnExEQEBQUhKiqqwtojouqFU35EVKpNmzbBzc0NzzzzjMb9Y8eOxb1797Bnzx4AjzKyHz58GG5ubhg6dCheffVVdO7cGbt379YpmHpcXl4e4uLiEBcXhytXrhh8LqX5448/EBcXh8TExApth4iqJ45QERERERmII1REREREBmJARURERGQgBlREREREBmJARURERGQgBlREREREBmJARURERGQgBlREREREBmJARURERGQgBlREREREBmJARURERGQgBlREREREBmJARURERGSg/wNLJnUzYAtbewAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# This problem has three degrees of freedom. To draw the heatmap, it needs to fix one dimension\n", - "fixed = {\n", - " \"('T[0.125]','T[0.25]','T[0.375]','T[0.5]','T[0.625]','T[0.75]','T[0.875]','T[1]')\": 300\n", - "}\n", - "\n", - "all_fim.figure_drawing(\n", - " fixed, [\"CA0[0]\", \"T[0]\"], \"Reactor case\", \"$C_{A0}$ [M]\", \"T [K]\"\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "As seen in the Reactor Case - A optimality figure, A-optimality shows that the most informative region is around $C_{A0}=5.0$ M, $T=300.0$ K, while the least informative region is around $C_{A0}=1.0$ M, $T=700.0$ K.\n", - "\n", - "As seen in the Reactor Case - D optimality figure, D-optimality shows that the most informative region is around $C_{A0}=5.0$ M, $T=300.0$ K, while the least informative region is around $C_{A0}=1.0$ M, $T=700.0$ K.\n", - "\n", - "As seen in the Reactor Case - E optimality figure, E-optimality shows that the most informative region is around $C_{A0}=5.0$ M, $T=300.0$ K, while the least informative region is around $C_{A0}=1.0$ M, $T=700.0$ K.\n", - "\n", - "As seen in the Reactor Case - Modified E optimality figure, ME-optimality shows that the most informative region is around $C_{A0}=1.0$ M, $T=700.0$ K, while the least informative region is around $C_{A0}=5.0$ M, $T=300.0$ K." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Key Takeaways\n", - "\n", - "* MBDoE maximizes the information gained from experiments which reduces uncertainty (technical risk) and facilitates better decision-making.\n", - "\n", - "* FIM quantifies the information contained in a set of experiments (data) with respect to a mathematical model\n", - "\n", - "* MBDoE optimality criteria (e.g., A, D, E-optimal designs) compress the FIM into a scalar. The \"correct\" criterion depends on the DoE goal and model context.\n", - "\n", - "* Heatmaps provide visualizations of the most informative parameters using the MBDoE optimality criteria." - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/pyomo/contrib/doe/examples/reactor_compute_FIM.py b/pyomo/contrib/doe/examples/reactor_compute_FIM.py deleted file mode 100644 index 108f5bd16a0..00000000000 --- a/pyomo/contrib/doe/examples/reactor_compute_FIM.py +++ /dev/null @@ -1,111 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -from pyomo.common.dependencies import numpy as np -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure -from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables - - -def main(): - ### Define inputs - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # Define parameter nominal value - parameter_dict = {"A1": 85, "A2": 370, "E1": 8, "E2": 15} - - # Define measurement object - measurements = MeasurementVariables() - measurements.add_variables( - "C", # measurement variable name - indices={ - 0: ["CA", "CB", "CC"], - 1: t_control, - }, # 0,1 are indices of the index sets - time_index_position=1, - ) - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - exp_design.add_variables( - "CA0", # design variable name - indices={0: [0]}, # index dictionary - time_index_position=0, # time index position - values=[5], # design variable values - lower_bounds=1, # design variable lower bounds - upper_bounds=5, # design variable upper bounds - ) - - # add T as design variable - exp_design.add_variables( - "T", # design variable name - indices={0: t_control}, # index dictionary - time_index_position=0, # time index position - values=[ - 570, - 300, - 300, - 300, - 300, - 300, - 300, - 300, - 300, - ], # same length with t_control - lower_bounds=300, # design variable lower bounds - upper_bounds=700, # design variable upper bounds - ) - - ### Compute the FIM of a square model-based Design of Experiments problem - doe_object = DesignOfExperiments( - parameter_dict, # parameter dictionary - exp_design, # DesignVariables object - measurements, # MeasurementVariables object - create_model, # create model function - discretize_model=disc_for_measure, # discretize model function - ) - - result = doe_object.compute_FIM( - mode="sequential_finite", # calculation mode - scale_nominal_param_value=True, # scale nominal parameter value - formula="central", # formula for finite difference - ) - - result.result_analysis() - - # test result - relative_error = abs(np.log10(result.trace) - 2.78) - assert relative_error < 0.01 - - relative_error = abs(np.log10(result.det) - 2.99) - assert relative_error < 0.01 - - -if __name__ == "__main__": - main() diff --git a/pyomo/contrib/doe/examples/reactor_design.py b/pyomo/contrib/doe/examples/reactor_design.py deleted file mode 100644 index 67d6ff02fd2..00000000000 --- a/pyomo/contrib/doe/examples/reactor_design.py +++ /dev/null @@ -1,236 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - -# from pyomo.contrib.parmest.examples.reactor_design import reactor_design_model -# if we refactor to use the same create_model function as parmest, -# we can just import instead of redefining the model - -import pyomo.environ as pyo -from pyomo.dae import ContinuousSet, DerivativeVar -from pyomo.contrib.doe import ( - ModelOptionLib, - DesignOfExperiments, - MeasurementVariables, - DesignVariables, -) -from pyomo.common.dependencies import numpy as np - - -def create_model_legacy(mod=None, model_option=None): - model_option = ModelOptionLib(model_option) - - model = mod - - if model_option == ModelOptionLib.parmest: - model = pyo.ConcreteModel() - return_m = True - elif model_option == ModelOptionLib.stage1 or model_option == ModelOptionLib.stage2: - if model is None: - raise ValueError( - "If model option is stage1 or stage2, a created model needs to be provided." - ) - return_m = False - else: - raise ValueError( - "model_option needs to be defined as parmest, stage1, or stage2." - ) - - model = _create_model_details(model) - - if return_m: - return model - - -def create_model(): - model = pyo.ConcreteModel() - return _create_model_details(model) - - -def _create_model_details(model): - - # Rate constants - model.k1 = pyo.Var(initialize=5.0 / 6.0, within=pyo.PositiveReals) # min^-1 - model.k2 = pyo.Var(initialize=5.0 / 3.0, within=pyo.PositiveReals) # min^-1 - model.k3 = pyo.Var( - initialize=1.0 / 6000.0, within=pyo.PositiveReals - ) # m^3/(gmol min) - - # Inlet concentration of A, gmol/m^3 - model.caf = pyo.Var(initialize=10000, within=pyo.PositiveReals) - - # Space velocity (flowrate/volume) - model.sv = pyo.Var(initialize=1.0, within=pyo.PositiveReals) - - # Outlet concentration of each component - model.ca = pyo.Var(initialize=5000.0, within=pyo.PositiveReals) - model.cb = pyo.Var(initialize=2000.0, within=pyo.PositiveReals) - model.cc = pyo.Var(initialize=2000.0, within=pyo.PositiveReals) - model.cd = pyo.Var(initialize=1000.0, within=pyo.PositiveReals) - - # Constraints - model.ca_bal = pyo.Constraint( - expr=( - 0 - == model.sv * model.caf - - model.sv * model.ca - - model.k1 * model.ca - - 2.0 * model.k3 * model.ca**2.0 - ) - ) - - model.cb_bal = pyo.Constraint( - expr=(0 == -model.sv * model.cb + model.k1 * model.ca - model.k2 * model.cb) - ) - - model.cc_bal = pyo.Constraint( - expr=(0 == -model.sv * model.cc + model.k2 * model.cb) - ) - - model.cd_bal = pyo.Constraint( - expr=(0 == -model.sv * model.cd + model.k3 * model.ca**2.0) - ) - - return model - - -def main(legacy_create_model_interface=False): - - # measurement object - measurements = MeasurementVariables() - measurements.add_variables("ca", indices=None, time_index_position=None) - measurements.add_variables("cb", indices=None, time_index_position=None) - measurements.add_variables("cc", indices=None, time_index_position=None) - measurements.add_variables("cd", indices=None, time_index_position=None) - - # design object - exp_design = DesignVariables() - exp_design.add_variables( - "sv", - indices=None, - time_index_position=None, - values=1.0, - lower_bounds=0.1, - upper_bounds=10.0, - ) - exp_design.add_variables( - "caf", - indices=None, - time_index_position=None, - values=10000, - lower_bounds=5000, - upper_bounds=15000, - ) - - theta_values = {"k1": 5.0 / 6.0, "k2": 5.0 / 3.0, "k3": 1.0 / 6000.0} - - if legacy_create_model_interface: - create_model_ = create_model_legacy - else: - create_model_ = create_model - - doe1 = DesignOfExperiments( - theta_values, exp_design, measurements, create_model_, prior_FIM=None - ) - - result = doe1.compute_FIM( - mode="sequential_finite", # calculation mode - scale_nominal_param_value=True, # scale nominal parameter value - formula="central", # formula for finite difference - ) - - # doe1.model.pprint() - - result.result_analysis() - - # print("FIM =\n",result.FIM) - # print("jac =\n",result.jaco_information) - # print("log10 Trace of FIM: ", np.log10(result.trace)) - # print("log10 Determinant of FIM: ", np.log10(result.det)) - - # test result - expected_log10_trace = 6.815 - log10_trace = np.log10(result.trace) - relative_error_trace = abs(log10_trace - 6.815) - assert relative_error_trace < 0.01, ( - "log10(tr(FIM)) regression test failed, answer " - + str(round(log10_trace, 3)) - + " does not match expected answer of " - + str(expected_log10_trace) - ) - - expected_log10_det = 18.719 - log10_det = np.log10(result.det) - relative_error_det = abs(log10_det - 18.719) - assert relative_error_det < 0.01, ( - "log10(det(FIM)) regression test failed, answer " - + str(round(log10_det, 3)) - + " does not match expected answer of " - + str(expected_log10_det) - ) - - doe2 = DesignOfExperiments( - theta_values, exp_design, measurements, create_model_, prior_FIM=None - ) - - square_result2, optimize_result2 = doe2.stochastic_program( - if_optimize=True, - if_Cholesky=True, - scale_nominal_param_value=True, - objective_option="det", - jac_initial=result.jaco_information.copy(), - step=0.1, - ) - - optimize_result2.result_analysis() - log_det = np.log10(optimize_result2.det) - print("log(det) = ", round(log_det, 3)) - log_det_expected = 19.266 - assert abs(log_det - log_det_expected) < 0.01, "log(det) regression test failed" - - doe3 = DesignOfExperiments( - theta_values, exp_design, measurements, create_model_, prior_FIM=None - ) - - square_result3, optimize_result3 = doe3.stochastic_program( - if_optimize=True, - scale_nominal_param_value=True, - objective_option="trace", - jac_initial=result.jaco_information.copy(), - step=0.1, - ) - - optimize_result3.result_analysis() - log_trace = np.log10(optimize_result3.trace) - log_trace_expected = 7.509 - print("log(trace) = ", round(log_trace, 3)) - assert ( - abs(log_trace - log_trace_expected) < 0.01 - ), "log(trace) regression test failed" - - -if __name__ == "__main__": - main(legacy_create_model_interface=False) diff --git a/pyomo/contrib/doe/examples/reactor_grid_search.py b/pyomo/contrib/doe/examples/reactor_grid_search.py deleted file mode 100644 index 1f5aae77f85..00000000000 --- a/pyomo/contrib/doe/examples/reactor_grid_search.py +++ /dev/null @@ -1,140 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -from pyomo.common.dependencies import numpy as np -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure -from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables - - -def main(): - ### Define inputs - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # Define parameter nominal value - parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} - - # measurement object - measurements = MeasurementVariables() - measurements.add_variables( - "C", # variable name - indices={0: ["CA", "CB", "CC"], 1: t_control}, # indices - time_index_position=1, - ) # position of time index - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - exp_design.add_variables( - "CA0", # variable name - indices={0: [0]}, # indices - time_index_position=0, # position of time index - values=[5], # nominal value - lower_bounds=1, # lower bound - upper_bounds=5, # upper bound - ) - - # add T as design variable - exp_design.add_variables( - "T", # variable name - indices={0: t_control}, # indices - time_index_position=0, # position of time index - values=[470, 300, 300, 300, 300, 300, 300, 300, 300], # nominal value - lower_bounds=300, # lower bound - upper_bounds=700, # upper bound - ) - - # For each variable, we define a list of possible values that are used - # in the sensitivity analysis - - design_ranges = { - "CA0[0]": [1, 3, 5], - ( - "T[0]", - "T[0.125]", - "T[0.25]", - "T[0.375]", - "T[0.5]", - "T[0.625]", - "T[0.75]", - "T[0.875]", - "T[1]", - ): [300, 500, 700], - } - ## choose from "sequential_finite", "direct_kaug" - sensi_opt = "direct_kaug" - - doe_object = DesignOfExperiments( - parameter_dict, # parameter dictionary - exp_design, # design variables - measurements, # measurement variables - create_model, # model function - discretize_model=disc_for_measure, # discretization function - ) - # run full factorial grid search - all_fim = doe_object.run_grid_search(design_ranges, mode=sensi_opt) - - all_fim.extract_criteria() - - ### 3 design variable example - # Define design ranges - design_ranges = { - "CA0[0]": list(np.linspace(1, 5, 2)), - "T[0]": list(np.linspace(300, 700, 2)), - ( - "T[0.125]", - "T[0.25]", - "T[0.375]", - "T[0.5]", - "T[0.625]", - "T[0.75]", - "T[0.875]", - "T[1]", - ): [300, 500], - } - - sensi_opt = "direct_kaug" - - doe_object = DesignOfExperiments( - parameter_dict, # parameter dictionary - exp_design, # design variables - measurements, # measurement variables - create_model, # model function - discretize_model=disc_for_measure, # discretization function - ) - # run the grid search for 3 dimensional case - all_fim = doe_object.run_grid_search(design_ranges, mode=sensi_opt) - - all_fim.extract_criteria() - - # see the criteria values - all_fim.store_all_results_dataframe - - -if __name__ == "__main__": - main() diff --git a/pyomo/contrib/doe/examples/reactor_kinetics.py b/pyomo/contrib/doe/examples/reactor_kinetics.py deleted file mode 100644 index ed2175085f2..00000000000 --- a/pyomo/contrib/doe/examples/reactor_kinetics.py +++ /dev/null @@ -1,247 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -import pyomo.environ as pyo -from pyomo.dae import ContinuousSet, DerivativeVar -from pyomo.contrib.doe import ModelOptionLib - - -def disc_for_measure(m, nfe=32, block=True): - """Pyomo.DAE discretization - - Arguments - --------- - m: Pyomo model - nfe: number of finite elements b - block: if True, the input model has blocks - """ - discretizer = pyo.TransformationFactory("dae.collocation") - if block: - for s in range(len(m.block)): - discretizer.apply_to(m.block[s], nfe=nfe, ncp=3, wrt=m.block[s].t) - else: - discretizer.apply_to(m, nfe=nfe, ncp=3, wrt=m.t) - return m - - -def create_model( - mod=None, - model_option="stage2", - control_time=[0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1], - control_val=None, - t_range=[0.0, 1], - CA_init=1, - C_init=0.1, -): - """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. - - Arguments - --------- - mod: Pyomo model. If None, a Pyomo concrete model is created - model_option: choose from the 3 options in model_option - if ModelOptionLib.parmest, create a process model. - if ModelOptionLib.stage1, create the global model. - if ModelOptionLib.stage2, add model variables and constraints for block. - control_time: a list of control timepoints - control_val: control design variable values T at corresponding timepoints - t_range: time range, h - CA_init: time-independent design (control) variable, an initial value for CA - C_init: An initial value for C - - Return - ------ - m: a Pyomo.DAE model - """ - - theta = {"A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} - - model_option = ModelOptionLib(model_option) - - if model_option == ModelOptionLib.parmest: - mod = pyo.ConcreteModel() - return_m = True - elif model_option == ModelOptionLib.stage1 or model_option == ModelOptionLib.stage2: - if not mod: - raise ValueError( - "If model option is stage1 or stage2, a created model needs to be provided." - ) - return_m = False - else: - raise ValueError( - "model_option needs to be defined as parmest,stage1, or stage2." - ) - - if not control_val: - control_val = [300] * 9 - - controls = {} - for i, t in enumerate(control_time): - controls[t] = control_val[i] - - mod.t0 = pyo.Set(initialize=[0]) - mod.t_con = pyo.Set(initialize=control_time) - mod.CA0 = pyo.Var( - mod.t0, initialize=CA_init, bounds=(1.0, 5.0), within=pyo.NonNegativeReals - ) # mol/L - - # check if control_time is in time range - assert ( - control_time[0] >= t_range[0] and control_time[-1] <= t_range[1] - ), "control time is outside time range." - - if model_option == ModelOptionLib.stage1: - mod.T = pyo.Var( - mod.t_con, - initialize=controls, - bounds=(300, 700), - within=pyo.NonNegativeReals, - ) - return - - else: - para_list = ["A1", "A2", "E1", "E2"] - - ### Add variables - mod.CA_init = CA_init - mod.para_list = para_list - - # timepoints - mod.t = ContinuousSet(bounds=t_range, initialize=control_time) - - # time-dependent design variable, initialized with the first control value - def T_initial(m, t): - if t in m.t_con: - return controls[t] - else: - # count how many control points are before the current t; - # locate the nearest neighbouring control point before this t - neighbour_t = max(tc for tc in control_time if tc < t) - return controls[neighbour_t] - - mod.T = pyo.Var( - mod.t, initialize=T_initial, bounds=(300, 700), within=pyo.NonNegativeReals - ) - - mod.R = 8.31446261815324 # J / K / mole - - # Define parameters as Param - mod.A1 = pyo.Var(initialize=theta["A1"]) - mod.A2 = pyo.Var(initialize=theta["A2"]) - mod.E1 = pyo.Var(initialize=theta["E1"]) - mod.E2 = pyo.Var(initialize=theta["E2"]) - - # Concentration variables under perturbation - mod.C_set = pyo.Set(initialize=["CA", "CB", "CC"]) - mod.C = pyo.Var( - mod.C_set, mod.t, initialize=C_init, within=pyo.NonNegativeReals - ) - - # time derivative of C - mod.dCdt = DerivativeVar(mod.C, wrt=mod.t) - - # kinetic parameters - def kp1_init(m, t): - return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) - - def kp2_init(m, t): - return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) - - mod.kp1 = pyo.Var(mod.t, initialize=kp1_init) - mod.kp2 = pyo.Var(mod.t, initialize=kp2_init) - - def T_control(m, t): - """ - T at interval timepoint equal to the T of the control time point at the beginning of this interval - Count how many control points are before the current t; - locate the nearest neighbouring control point before this t - """ - if t in m.t_con: - return pyo.Constraint.Skip - else: - neighbour_t = max(tc for tc in control_time if tc < t) - return m.T[t] == m.T[neighbour_t] - - def cal_kp1(m, t): - """ - Create the perturbation parameter sets - m: model - t: time - """ - # LHS: 1/h - # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K) - return m.kp1[t] == m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) - - def cal_kp2(m, t): - """ - Create the perturbation parameter sets - m: model - t: time - """ - # LHS: 1/h - # RHS: 1/h*(kJ/mol *1000J/kJ / (J/mol/K) / K) - return m.kp2[t] == m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) - - def dCdt_control(m, y, t): - """ - Calculate CA in Jacobian matrix analytically - y: CA, CB, CC - t: timepoints - """ - if y == "CA": - return m.dCdt[y, t] == -m.kp1[t] * m.C["CA", t] - elif y == "CB": - return m.dCdt[y, t] == m.kp1[t] * m.C["CA", t] - m.kp2[t] * m.C["CB", t] - elif y == "CC": - return pyo.Constraint.Skip - - def alge(m, t): - """ - The algebraic equation for mole balance - z: m.pert - t: time - """ - return m.C["CA", t] + m.C["CB", t] + m.C["CC", t] == m.CA0[0] - - # Control time - mod.T_rule = pyo.Constraint(mod.t, rule=T_control) - - # calculating C, Jacobian, FIM - mod.k1_pert_rule = pyo.Constraint(mod.t, rule=cal_kp1) - mod.k2_pert_rule = pyo.Constraint(mod.t, rule=cal_kp2) - mod.dCdt_rule = pyo.Constraint(mod.C_set, mod.t, rule=dCdt_control) - - mod.alge_rule = pyo.Constraint(mod.t, rule=alge) - - # B.C. - mod.C["CB", 0.0].fix(0.0) - mod.C["CC", 0.0].fix(0.0) - - if return_m: - return mod diff --git a/pyomo/contrib/doe/examples/reactor_optimize_doe.py b/pyomo/contrib/doe/examples/reactor_optimize_doe.py deleted file mode 100644 index f7b4a74c891..00000000000 --- a/pyomo/contrib/doe/examples/reactor_optimize_doe.py +++ /dev/null @@ -1,123 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - -from pyomo.common.dependencies import numpy as np -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure -from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables - - -def main(): - ### Define inputs - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # Define parameter nominal value - parameter_dict = {"A1": 85, "A2": 372, "E1": 8, "E2": 15} - - # measurement object - measurements = MeasurementVariables() - measurements.add_variables( - "C", # name of measurement - indices={0: ["CA", "CB", "CC"], 1: t_control}, # indices of measurement - time_index_position=1, - ) # position of time index - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - exp_design.add_variables( - "CA0", # name of design variable - indices={0: [0]}, # indices of design variable - time_index_position=0, # position of time index - values=[5], # nominal value of design variable - lower_bounds=1, # lower bound of design variable - upper_bounds=5, # upper bound of design variable - ) - - # add T as design variable - exp_design.add_variables( - "T", # name of design variable - indices={0: t_control}, # indices of design variable - time_index_position=0, # position of time index - values=[ - 470, - 300, - 300, - 300, - 300, - 300, - 300, - 300, - 300, - ], # nominal value of design variable - lower_bounds=300, # lower bound of design variable - upper_bounds=700, # upper bound of design variable - ) - - design_names = exp_design.variable_names - exp1 = [5, 570, 300, 300, 300, 300, 300, 300, 300, 300] - exp1_design_dict = dict(zip(design_names, exp1)) - exp_design.update_values(exp1_design_dict) - - # add a prior information (scaled FIM with T=500 and T=300 experiments) - prior = np.asarray( - [ - [28.67892806, 5.41249739, -81.73674601, -24.02377324], - [5.41249739, 26.40935036, -12.41816477, -139.23992532], - [-81.73674601, -12.41816477, 240.46276004, 58.76422806], - [-24.02377324, -139.23992532, 58.76422806, 767.25584508], - ] - ) - - doe_object2 = DesignOfExperiments( - parameter_dict, # dictionary of parameters - exp_design, # design variables - measurements, # measurement variables - create_model, # function to create model - prior_FIM=prior, # prior information - discretize_model=disc_for_measure, # function to discretize model - ) - - square_result, optimize_result = doe_object2.stochastic_program( - if_optimize=True, # if optimize - if_Cholesky=True, # if use Cholesky decomposition - scale_nominal_param_value=True, # if scale nominal parameter value - objective_option="det", # objective option - L_initial=np.linalg.cholesky(prior), # initial Cholesky decomposition - ) - - square_result, optimize_result = doe_object2.stochastic_program( - if_optimize=True, # if optimize - if_Cholesky=True, # if use Cholesky decomposition - scale_nominal_param_value=True, # if scale nominal parameter value - objective_option="trace", # objective option - L_initial=np.linalg.cholesky(prior), # initial Cholesky decomposition - ) - - -if __name__ == "__main__": - main() From e6feef6e20f8ff4acd03960efd435a2a2b526584 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 11:54:33 -0600 Subject: [PATCH 090/203] Add test for bad option in compute FIM method --- pyomo/contrib/doe/tests/test_doe_errors.py | 40 ++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 3df8355e528..00336ff0420 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -989,6 +989,7 @@ def test_update_unknown_parameter_values_not_implemented_seq(self): ): doe_obj.update_unknown_parameter_values() + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_bad_FD_generate_scens(self): fd_method = "central" @@ -1025,6 +1026,7 @@ def test_bad_FD_generate_scens(self): doe_obj.fd_formula = "bad things" doe_obj._generate_scenario_blocks() + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_bad_FD_seq_compute_FIM(self): fd_method = "central" @@ -1132,6 +1134,44 @@ def test_no_model_for_objective(self): ): doe_obj.create_objective_function() + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_bad_compute_FIM_option(self): + fd_method = "central" + obj_used = "trace" + flag_val = ( + 0 # Value for faulty model build mode - 5: Mismatch error and output length + ) + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args={"flag": flag_val}, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + with self.assertRaisesRegex( + ValueError, + "The method provided, {}, must be either `sequential` or `kaug`".format( + "Bad Method" + ), + ): + doe_obj.compute_FIM(method="Bad Method") + if __name__ == "__main__": unittest.main() From f1df9be77bf5cac91c4bf50d65213dc514ce033f Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 12:24:30 -0600 Subject: [PATCH 091/203] Removed bad files, have to rewrite OnlineDocs soon --- .../contributed_packages/doe/doe.rst | 53 +------------------ 1 file changed, 2 insertions(+), 51 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 8c22ff7370d..ce48da3e516 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -151,28 +151,7 @@ Pyomo.DoE Solver Interface .. autoclass:: pyomo.contrib.doe.doe.DesignOfExperiments - :members: __init__, stochastic_program, compute_FIM, run_grid_search - -.. Note:: - ``stochastic_program()`` includes the following steps: - #. Build two-stage stochastic programming optimization model where scenarios correspond to finite difference approximations for the Jacobian of the response variables with respect to calibrated model parameters - #. Fix the experiment design decisions and solve a square (i.e., zero degrees of freedom) instance of the two-stage DOE problem. This step is for initialization. - #. Unfix the experiment design decisions and solve the two-stage DOE problem. - -.. autoclass:: pyomo.contrib.doe.measurements.MeasurementVariables - :members: __init__, add_variables - -.. autoclass:: pyomo.contrib.doe.measurements.DesignVariables - :members: __init__, add_variables - -.. autoclass:: pyomo.contrib.doe.scenario.ScenarioGenerator - :special-members: __init__ - -.. autoclass:: pyomo.contrib.doe.result.FisherResults - :members: __init__, result_analysis - -.. autoclass:: pyomo.contrib.doe.result.GridSearchResult - :special-members: __init__ + :members: __init__, create_doe_model, compute_FIM, run_doe, compute_FIM_full_factorial Pyomo.DoE Usage Example @@ -211,7 +190,7 @@ Step 0: Import Pyomo and the Pyomo.DoE module >>> # === Required import === >>> import pyomo.environ as pyo >>> from pyomo.dae import ContinuousSet, DerivativeVar - >>> from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables + >>> from pyomo.contrib.doe import DesignOfExperiments >>> import numpy as np Step 1: Define the Pyomo process model @@ -219,26 +198,10 @@ Step 1: Define the Pyomo process model The process model for the reaction kinetics problem is shown below. -.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_kinetics.py - :language: python - :pyobject: create_model - -.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_kinetics.py - :language: python - :pyobject: disc_for_measure - -.. note:: - The model requires at least two options: "block" and "global". Both options requires the pass of a created empty Pyomo model. - With "global" option, only design variables and their time sets need to be defined; - With "block" option, a full model needs to be defined. Step 2: Define the inputs for Pyomo.DoE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_FIM.py - :language: python - :start-at: # Control time set - :end-before: ### Compute Step 3: Compute the FIM of a square MBDoE problem @@ -249,10 +212,6 @@ This method computes an MBDoE optimization problem with no degree of freedom. This method can be accomplished by two modes, ``direct_kaug`` and ``sequential_finite``. ``direct_kaug`` mode requires the installation of the solver `k_aug `_. -.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_FIM.py - :language: python - :start-after: ### Compute the FIM - :end-before: # test result Step 4: Exploratory analysis (Enumeration) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -266,14 +225,9 @@ It allows users to define any number of design decisions. Heatmaps can be drawn The function ``run_grid_search`` enumerates over the design space, each MBDoE problem accomplished by ``compute_FIM`` method. Therefore, ``run_grid_search`` supports only two modes: ``sequential_finite`` and ``direct_kaug``. -.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_grid_search.py - :language: python - :pyobject: main Successful run of the above code shows the following figure: -.. figure:: grid-1.png - :scale: 35 % A heatmap shows the change of the objective function, a.k.a. the experimental information content, in the design region. Horizontal and vertical axes are two design variables, while the color of each grid shows the experimental information content. Taking the Fig. Reactor case - A optimality as example, A-optimality shows that the most informative region is around $C_{A0}=5.0$ M, $T=300.0$ K, while the least informative region is around $C_{A0}=1.0$ M, $T=700.0$ K. @@ -284,8 +238,5 @@ Pyomo.DoE accomplishes gradient-based optimization with the ``stochastic_program This function solves twice: It solves the square version of the MBDoE problem first, and then unfixes the design variables as degree of freedoms and solves again. In this way the optimization problem can be well initialized. -.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_optimize_doe.py - :language: python - :pyobject: main From 76e06c55158ce3842b47ac3e8bc2075d58bab1ab Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 18 Jul 2024 15:26:13 -0600 Subject: [PATCH 092/203] Fixed determinant obj without cholesky, added tests. --- pyomo/contrib/doe/doe.py | 19 +++-- pyomo/contrib/doe/tests/test_doe_solve.py | 93 +++++++++++++++-------- 2 files changed, 75 insertions(+), 37 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 9f31fdeb010..4f147afef31 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -43,6 +43,7 @@ import logging import json +import math class CalculationMode(Enum): @@ -290,10 +291,9 @@ def run_doe(self, model=None, results_file=None): model.objective.activate() model.obj_cons.activate() - # ToDo: add a ``get FIM from model`` function # If the model has L, initialize it with the solved FIM if hasattr(model, "L"): - # Get the FIM values --> ToDo: add this as a function + # Get the FIM values fim_vals = [ pyo.value(model.fim[i, j]) for i in model.parameter_names @@ -308,6 +308,9 @@ def run_doe(self, model=None, results_file=None): for j, d in enumerate(model.parameter_names): model.L[c, d].value = L_vals_sq[i, j] + if hasattr(model, "det"): + model.det.value = np.linalg.det(np.array(self.get_FIM())) + # Solve the full model, which has now been initialized with the square solve res = self.solver.solve(model, tee=self.tee) @@ -1211,13 +1214,15 @@ def det_general(m): for y, element in enumerate(model.parameter_names): if x_order[x] == y: name_order.append(element) - # det(A) = sum_{\sigma \in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) det_perm = sum( self._sgn(list_p[d]) - * sum( - model.fim[each, name_order[b]] - for b, each in enumerate(model.parameter_names) + * math.prod( + model.fim[ + model.parameter_names.at(val + 1), + model.parameter_names.at(ind + 1), + ] + for ind, val in enumerate(list_p[d]) ) for d in range(len(list_p)) ) @@ -1239,7 +1244,7 @@ def det_general(m): ) model.obj_cons.det_rule = pyo.Constraint(rule=det_general) model.objective = pyo.Objective( - expr=pyo.log10(model.det), sense=pyo.maximize + expr=pyo.log10(model.det + 1e-6), sense=pyo.maximize ) elif self.objective_option == ObjectiveLib.trace: diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 4ab9e275c7e..c27e3946064 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -22,6 +22,7 @@ import logging ipopt_available = SolverFactory("ipopt").available() +k_aug_available = SolverFactory('k_aug', solver_io='nl', validate=False) DATA_DIR = Path(__file__).parent file_path = DATA_DIR / "result.json" @@ -203,36 +204,36 @@ def test_reactor_fd_backward_solve(self): # TODO: Fix determinant objective code, something is awry # Should only be using Cholesky=True - # @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - # @unittest.skipIf(not numpy_available, "Numpy is not available") - # def test_reactor_obj_det_solve(self): - # fd_method = "central" - # obj_used = "det" - - # experiment = FullReactorExperiment(data_ex, 10, 3) - - # doe_obj = DesignOfExperiments( - # experiment, - # fd_formula=fd_method, - # step=1e-3, - # objective_option=obj_used, - # scale_constant_value=1, - # scale_nominal_param_value=True, - # prior_FIM=None, - # jac_initial=None, - # fim_initial=None, - # L_initial=None, - # L_LB=1e-7, - # solver=None, - # tee=False, - # args=None, - # _Cholesky_option=False, - # _only_compute_fim_lower=False, - # ) - - # doe_obj.run_doe() - - # assert (doe_obj.results['Solver Status'] == "ok") + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_reactor_obj_det_solve(self): + fd_method = "central" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=False, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=False, + _only_compute_fim_lower=False, + ) + + doe_obj.run_doe() + + assert doe_obj.results['Solver Status'] == "ok" @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -332,6 +333,38 @@ def test_compute_FIM_seq_forward(self): doe_obj.compute_FIM(method="sequential") + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf( + not k_aug_available.available(False), "The 'k_aug' command is not available" + ) + @unittest.skipIf(not numpy_available, "Numpy is not available") + def test_compute_FIM_kaug(self): + fd_method = "forward" + obj_used = "det" + + experiment = FullReactorExperiment(data_ex, 10, 3) + + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_method, + step=1e-3, + objective_option=obj_used, + scale_constant_value=1, + scale_nominal_param_value=True, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.compute_FIM(method="kaug") + @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq_backward(self): From 930ac20fed8ba5b44131d8f73685b353aa0baf3b Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 11:50:31 -0400 Subject: [PATCH 093/203] Added scipy availability flag for kaug test --- pyomo/contrib/doe/tests/test_doe_solve.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index c27e3946064..f4b5729d9ac 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -3,6 +3,7 @@ numpy_available, pandas as pd, pandas_available, + scipy_available ) from pyomo.contrib.doe.tests.experiment_class_example import * @@ -334,6 +335,7 @@ def test_compute_FIM_seq_forward(self): doe_obj.compute_FIM(method="sequential") @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") + @unittest.skipIf(not scipy_available, "Scipy is not available") @unittest.skipIf( not k_aug_available.available(False), "The 'k_aug' command is not available" ) From 33121af6b98d397c4e3428a1aad6e921baa9f2ae Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 12:12:35 -0400 Subject: [PATCH 094/203] Fixed typo --- pyomo/contrib/doe/tests/test_doe_solve.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index f4b5729d9ac..92787ee8abb 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -3,7 +3,7 @@ numpy_available, pandas as pd, pandas_available, - scipy_available + scipy_available, ) from pyomo.contrib.doe.tests.experiment_class_example import * From 9b0d4161e043da834ea4c94bad6bc7cb3ada5980 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 13:32:19 -0400 Subject: [PATCH 095/203] Started updating documentation (doe.rst). --- .../contributed_packages/doe/doe.rst | 30 ++++--------------- 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index ce48da3e516..7ddddd64f13 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -116,32 +116,14 @@ In order to solve problems of the above, Pyomo.DoE implements the 2-stage stocha Pyomo.DoE Required Inputs -------------------------------- -The required inputs to the Pyomo.DoE solver are the following: +The required inputs to the Pyomo.DoE solver is an Experiment object. The experiment object must have a get_labeled_model function which returns a pyomo model with four special labeled components as suffixes on the pyomo model. This is in line with the convention used in the new interface for the ParmEst contribute packed to Pyomo. The four suffix components are: -* A function that creates the process model -* Dictionary of parameters and their nominal value -* A measurement object -* A design variables object -* A Numpy ``array`` containing the Prior FIM -* Optimization solver +* experiment_inputs - The experimental design decisions +* experiment_outputs - The values measured during the experiment +* measurement_error - The error associated with individual values measured during the experiment +* unknown_parameters - Those parameters in the model that are estimated using the measured values during the experiment -Below is a list of arguments that Pyomo.DoE expects the user to provide. - -parameter_dict : ``dictionary`` - A ``dictionary`` of parameter names and values. If they are an indexed variable, put the variable name and index in a nested ``Dictionary``. - -design_variables: ``DesignVariables`` - A ``DesignVariables`` of design variables, provided by the DesignVariables class. - If this design var is independent of time (constant), set the time to [0] - -measurement_variables : ``MeasurementVariables`` - A ``MeasurementVariables`` of the measurements, provided by the MeasurementVariables class. - -create_model : ``function`` - A ``function`` returning a deterministic process model. - -prior_FIM : ``array`` - An ``array`` defining the Fisher information matrix (FIM) for prior experiments, default is a zero matrix. +An example an Experiment object that builds and labels the model is shown below: Pyomo.DoE Solver Interface --------------------------- From 08884e31455990035e677f996eba22aa9b8cee8d Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 13:51:07 -0400 Subject: [PATCH 096/203] Updated ParmEst reference --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 7ddddd64f13..3ccd637d948 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -116,7 +116,7 @@ In order to solve problems of the above, Pyomo.DoE implements the 2-stage stocha Pyomo.DoE Required Inputs -------------------------------- -The required inputs to the Pyomo.DoE solver is an Experiment object. The experiment object must have a get_labeled_model function which returns a pyomo model with four special labeled components as suffixes on the pyomo model. This is in line with the convention used in the new interface for the ParmEst contribute packed to Pyomo. The four suffix components are: +The required inputs to the Pyomo.DoE solver is an Experiment object. The experiment object must have a get_labeled_model function which returns a pyomo model with four special labeled components as suffixes on the pyomo model. This is in line with the convention used in the new interface in the contributed pacakge, `Parmest `_. The four suffix components are: * experiment_inputs - The experimental design decisions * experiment_outputs - The values measured during the experiment From 29d8d437b97d17285c123a8c4436a53d0658b49b Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 14:38:21 -0400 Subject: [PATCH 097/203] Fixed typo in doe.rst --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 3ccd637d948..1a5c334394b 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -116,7 +116,7 @@ In order to solve problems of the above, Pyomo.DoE implements the 2-stage stocha Pyomo.DoE Required Inputs -------------------------------- -The required inputs to the Pyomo.DoE solver is an Experiment object. The experiment object must have a get_labeled_model function which returns a pyomo model with four special labeled components as suffixes on the pyomo model. This is in line with the convention used in the new interface in the contributed pacakge, `Parmest `_. The four suffix components are: +The required inputs to the Pyomo.DoE solver is an Experiment object. The experiment object must have a get_labeled_model function which returns a pyomo model with four special labeled components as suffixes on the pyomo model. This is in line with the convention used in the new interface in the contributed package, `Parmest `_. The four suffix components are: * experiment_inputs - The experimental design decisions * experiment_outputs - The values measured during the experiment From f7b5f57649b7c398ddb1cba5d18b2ef6faa30a6f Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 18:20:37 -0400 Subject: [PATCH 098/203] Added examples and figure saving capabilities --- pyomo/contrib/doe/doe.py | 75 +++++-- .../examples/reactor_compute_factorial_FIM.py | 88 ++++++++ pyomo/contrib/doe/examples/reactor_example.py | 84 ++++++++ .../doe/examples/reactor_experiment.py | 204 ++++++++++++++++++ 4 files changed, 436 insertions(+), 15 deletions(-) create mode 100644 pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py create mode 100644 pyomo/contrib/doe/examples/reactor_example.py create mode 100644 pyomo/contrib/doe/examples/reactor_experiment.py diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 4f147afef31..359b0c051cc 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1549,9 +1549,9 @@ def draw_factorial_figure( sensitivity_design_variables=None, fixed_design_variables=None, full_design_variable_names=None, - title_text=None, - xlabel_text=None, - ylabel_text=None, + title_text="", + xlabel_text="", + ylabel_text="", figure_file_name=None, font_axes=16, font_tick=14, @@ -1668,10 +1668,6 @@ def draw_factorial_figure( self.figure_sens_des_vars = sensitivity_design_variables self.figure_fixed_des_vars = fixed_design_variables - # ToDo: Add figure saving capabilities - if figure_file_name is not None: - self.logger.warning("File saving for drawing is not yet implemented.") - # if one design variable name is given as DOF, draw 1D sensitivity curve if len(self.figure_sens_des_vars) == 1: self._curve1D( @@ -1722,6 +1718,10 @@ def _curve1D( -------- 4 Figures of 1D sensitivity curves for each criteria """ + if figure_file_name is not None: + show_fig = False + else: + show_fig = True # extract the range of the DOF design variable x_range = self.figure_result_data[self.figure_sens_des_vars[0]].values.tolist() @@ -1754,7 +1754,12 @@ def _curve1D( ax.set_ylabel("$log_{10}$ Trace") ax.set_xlabel(xlabel_text) plt.pyplot.title(title_text + ": A-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_A_opt.png"), format="png", dpi=450 + ) # Draw D-optimality fig = plt.pyplot.figure() @@ -1770,7 +1775,12 @@ def _curve1D( ax.set_ylabel("$log_{10}$ Determinant") ax.set_xlabel(xlabel_text) plt.pyplot.title(title_text + ": D-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_D_opt.png"), format="png", dpi=450 + ) # Draw E-optimality fig = plt.pyplot.figure() @@ -1786,7 +1796,12 @@ def _curve1D( ax.set_ylabel("$log_{10}$ Minimal eigenvalue") ax.set_xlabel(xlabel_text) plt.pyplot.title(title_text + ": E-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_E_opt.png"), format="png", dpi=450 + ) # Draw Modified E-optimality fig = plt.pyplot.figure() @@ -1802,7 +1817,12 @@ def _curve1D( ax.set_ylabel("$log_{10}$ Condition number") ax.set_xlabel(xlabel_text) plt.pyplot.title(title_text + ": Modified E-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_ME_opt.png"), format="png", dpi=450 + ) def _heatmap( self, @@ -1832,6 +1852,11 @@ def _heatmap( -------- 4 Figures of 2D heatmap for each criteria """ + if figure_file_name is not None: + show_fig = False + else: + show_fig = True + des_names = [k for k, v in self.figure_fixed_des_vars.items()] sens_ranges = {} for i in self.figure_sens_des_vars: @@ -1892,7 +1917,12 @@ def _heatmap( ba = plt.pyplot.colorbar(im) ba.set_label("log10(trace(FIM))") plt.pyplot.title(title_text + ": A-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_A_opt.png"), format="png", dpi=450 + ) # D-optimality fig = plt.pyplot.figure() @@ -1913,7 +1943,12 @@ def _heatmap( ba = plt.pyplot.colorbar(im) ba.set_label("log10(det(FIM))") plt.pyplot.title(title_text + ": D-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_D_opt.png"), format="png", dpi=450 + ) # E-optimality fig = plt.pyplot.figure() @@ -1934,7 +1969,12 @@ def _heatmap( ba = plt.pyplot.colorbar(im) ba.set_label("log10(minimal eig(FIM))") plt.pyplot.title(title_text + ": E-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_E_opt.png"), format="png", dpi=450 + ) # Modified E-optimality fig = plt.pyplot.figure() @@ -1955,7 +1995,12 @@ def _heatmap( ba = plt.pyplot.colorbar(im) ba.set_label("log10(cond(FIM))") plt.pyplot.title(title_text + ": Modified E-optimality") - plt.pyplot.show() + if show_fig: + plt.pyplot.show() + else: + plt.pyplot.savefig( + Path(figure_file_name + "_ME_opt.png"), format="png", dpi=450 + ) # Gets the FIM from an existing model def get_FIM(self, model=None): diff --git a/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py new file mode 100644 index 00000000000..b482fc319f0 --- /dev/null +++ b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py @@ -0,0 +1,88 @@ +from pyomo.common.dependencies import numpy as np + +from pyomo.contrib.doe.examples.reactor_experiment import ReactorExperiment +from pyomo.contrib.doe import DesignOfExperiments + +import pyomo.environ as pyo + +import json +from pathlib import Path + + +# Example to run a DOE on the reactor +def run_reactor_doe(): + # Read in file + DATA_DIR = Path(__file__).parent + file_path = DATA_DIR / "result.json" + + f = open(file_path) + data_ex = json.load(f) + + # Process control data points into correct format for reactor experiment + data_ex["control_points"] = { + float(k): v for k, v in data_ex["control_points"].items() + } + + # Create a ReactorExperiment object; data and discretization information are part + # of the constructor of this object + experiment = ReactorExperiment(data=data_ex, nfe=10, ncp=3) + + # Use a central difference, with step size 1e-3 + fd_formula = "central" + step_size = 1e-3 + + # Use the determinant objective with scaled sensitivity matrix + objective_option = "det" + scale_nominal_param_value = True + + # Create the DesignOfExperiments object + # We will not be passing any prior information in this example + # and allow the experiment object and the DesignOfExperiments + # call of ``run_doe`` perform model initialization. + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_formula, + step=step_size, + objective_option=objective_option, + scale_constant_value=1, + scale_nominal_param_value=scale_nominal_param_value, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + # Make design ranges to compute the full factorial design + design_ranges = {"CA[0]": [1, 5, 9], "T[0]": [300, 700, 9]} + + # Compute the full factorial design with the sequential FIM calculation + doe_obj.compute_FIM_full_factorial(design_ranges=design_ranges, method="sequential") + + # Plot the results + doe_obj.draw_factorial_figure( + sensitivity_design_variables=["CA[0]", "T[0]"], + fixed_design_variables={ + "T[0.125]": 300, + "T[0.25]": 300, + "T[0.375]": 300, + "T[0.5]": 300, + "T[0.625]": 300, + "T[0.75]": 300, + "T[0.875]": 300, + "T[1]": 300, + }, + title_text="Reactor Example", + xlabel_text="Concentration of A (M)", + ylabel_text="Initial Temperature (K)", + figure_file_name="example_reactor_compute_FIM", + ) + + +if __name__ == "__main__": + run_reactor_doe() diff --git a/pyomo/contrib/doe/examples/reactor_example.py b/pyomo/contrib/doe/examples/reactor_example.py new file mode 100644 index 00000000000..f673d4a3750 --- /dev/null +++ b/pyomo/contrib/doe/examples/reactor_example.py @@ -0,0 +1,84 @@ +from pyomo.common.dependencies import numpy as np + +from pyomo.contrib.doe.examples.reactor_experiment import ReactorExperiment +from pyomo.contrib.doe import DesignOfExperiments + +import pyomo.environ as pyo + +import json +from pathlib import Path + + +# Example to run a DOE on the reactor +def run_reactor_doe(): + # Read in file + DATA_DIR = Path(__file__).parent + file_path = DATA_DIR / "result.json" + + f = open(file_path) + data_ex = json.load(f) + + # Process control data points into correct format for reactor experiment + data_ex["control_points"] = { + float(k): v for k, v in data_ex["control_points"].items() + } + + # Create a ReactorExperiment object; data and discretization information are part + # of the constructor of this object + experiment = ReactorExperiment(data=data_ex, nfe=10, ncp=3) + + # Use a central difference, with step size 1e-3 + fd_formula = "central" + step_size = 1e-3 + + # Use the determinant objective with scaled sensitivity matrix + objective_option = "det" + scale_nominal_param_value = True + + # Create the DesignOfExperiments object + # We will not be passing any prior information in this example + # and allow the experiment object and the DesignOfExperiments + # call of ``run_doe`` perform model initialization. + doe_obj = DesignOfExperiments( + experiment, + fd_formula=fd_formula, + step=step_size, + objective_option=objective_option, + scale_constant_value=1, + scale_nominal_param_value=scale_nominal_param_value, + prior_FIM=None, + jac_initial=None, + fim_initial=None, + L_initial=None, + L_LB=1e-7, + solver=None, + tee=False, + args=None, + _Cholesky_option=True, + _only_compute_fim_lower=True, + ) + + doe_obj.run_doe() + + # Print out a results summary + print("Optimal experiment values: ") + print( + "\tInitial concentration: {:.2f}".format( + doe_obj.results["Experiment Design"][0] + ) + ) + print( + ("\tTemperature values: [" + "{:.2f}, " * 8 + "{:.2f}]").format( + *doe_obj.results["Experiment Design"][1:] + ) + ) + print("FIM at optimal design:\n {}".format(np.array(doe_obj.results["FIM"]))) + print( + "Objective value at optimal design: {:.2f}".format( + pyo.value(doe_obj.model.objective) + ) + ) + + +if __name__ == "__main__": + run_reactor_doe() diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py new file mode 100644 index 00000000000..912cecefc96 --- /dev/null +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -0,0 +1,204 @@ +# === Required imports === +import pyomo.environ as pyo +from pyomo.dae import ContinuousSet, DerivativeVar, Simulator + +# ======================== + + +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) + + +class ReactorExperiment(object): + def __init__(self, data, nfe, ncp): + self.data = data + self.nfe = nfe + self.ncp = ncp + self.model = None + + def get_labeled_model(self): + if self.model is None: + self.create_model() + self.finalize_model() + self.label_experiment() + return self.model + + def create_model(self): + """ + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. + + Return + ------ + m: a Pyomo.DAE model + """ + + m = self.model = pyo.ConcreteModel() + + # Model parameters + m.R = pyo.Param(mutable=False, initialize=8.314) + + # Define model variables + ######################## + # time + m.t = ContinuousSet(bounds=[0, 1]) + + # Concentrations + m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Temperature + m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Arrhenius rate law equations + m.A1 = pyo.Var(within=pyo.NonNegativeReals) + m.E1 = pyo.Var(within=pyo.NonNegativeReals) + m.A2 = pyo.Var(within=pyo.NonNegativeReals) + m.E2 = pyo.Var(within=pyo.NonNegativeReals) + + # Differential variables (Conc.) + m.dCAdt = DerivativeVar(m.CA, wrt=m.t) + m.dCBdt = DerivativeVar(m.CB, wrt=m.t) + + ######################## + # End variable def. + + # Equation def'n + ######################## + + # Expression for rate constants + @m.Expression(m.t) + def k1(m, t): + return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) + + @m.Expression(m.t) + def k2(m, t): + return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) + + # Concentration odes + @m.Constraint(m.t) + def CA_rxn_ode(m, t): + return m.dCAdt[t] == -m.k1[t] * m.CA[t] + + @m.Constraint(m.t) + def CB_rxn_ode(m, t): + return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] + + # algebraic balance for concentration of C + # Valid because the reaction system (A --> B --> C) is equimolar + @m.Constraint(m.t) + def CC_balance(m, t): + return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] + + ######################## + # End equation def'n + + def finalize_model(self): + """ + Example finalize model function. There are two main tasks + here: + 1. Extracting useful information for the model to align + with the experiment. (Here: CA0, t_final, t_control) + 2. Discretizing the model subject to this information. + + Arguments + --------- + m: Pyomo model + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ + m = self.model + + # Unpacking data before simulation + control_points = self.data["control_points"] + + m.CA[0].value = self.data["CA0"] + m.CB[0].fix(self.data["CB0"]) + m.t.update(self.data["t_range"]) + m.t.update(control_points) + m.A1.fix(self.data["A1"]) + m.A2.fix(self.data["A2"]) + m.E1.fix(self.data["E1"]) + m.E2.fix(self.data["E2"]) + + m.CA[0].setlb(self.data["CA_bounds"][0]) + m.CA[0].setub(self.data["CA_bounds"][1]) + + m.t_control = control_points + + # Discretizing the model + discr = pyo.TransformationFactory("dae.collocation") + discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) + + # Initializing Temperature in the model + cv = None + for t in m.t: + if t in control_points: + cv = control_points[t] + m.T[t].setlb(self.data["T_bounds"][0]) + m.T[t].setub(self.data["T_bounds"][1]) + m.T[t] = cv + + @m.Constraint(m.t - control_points) + def T_control(m, t): + """ + Piecewise constant Temperature between control points + """ + neighbour_t = max(tc for tc in control_points if tc < t) + return m.T[t] == m.T[neighbour_t] + + # sim.initialize_model() + + def label_experiment(self): + """ + Example for annotating (labeling) the model with a + full experiment. + + Arguments + --------- + + """ + m = self.model + + # Grab measurement labels + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + # Add CA to experiment outputs + m.experiment_outputs.update((m.CA[t], None) for t in m.t) + # Add CB to experiment outputs + m.experiment_outputs.update((m.CB[t], None) for t in m.t) + # Add CC to experiment outputs + m.experiment_outputs.update((m.CC[t], None) for t in m.t) + + # Adding no error for measurements currently + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + concentration_error = 1e-2 # Error in concentration measurement + # Add measurement error for CA + m.measurement_error.update((m.CA[t], concentration_error) for t in m.t) + # Add measurement error for CB + m.measurement_error.update((m.CB[t], concentration_error) for t in m.t) + # Add measurement error for CC + m.measurement_error.update((m.CC[t], concentration_error) for t in m.t) + + # Grab design variables + m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + # Add experimental input label for initial concentration + m.experiment_inputs.update( + (m.CA[t], pyo.ComponentUID(m.CA[t])) for t in [m.t.first()] + ) + # Add experimental input label for Temperature + m.experiment_inputs.update( + (m.T[t], pyo.ComponentUID(m.T[t])) for t in m.t_control + ) + + # Add unknown parameter labels + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + # Add labels to all unknown parameters with nominal value as the value + m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) From 3211d4d0e260c38858dea6ddc5130d5cf7627e10 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 18:54:28 -0400 Subject: [PATCH 099/203] Fixed documentation, cleaned example files --- .../doe/FIM_sensitivity.png | Bin 0 -> 194054 bytes .../contributed_packages/doe/doe.rst | 81 +++++++++++------- .../doe/examples/reactor_experiment.py | 2 - 3 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 doc/OnlineDocs/contributed_packages/doe/FIM_sensitivity.png diff --git a/doc/OnlineDocs/contributed_packages/doe/FIM_sensitivity.png b/doc/OnlineDocs/contributed_packages/doe/FIM_sensitivity.png new file mode 100644 index 0000000000000000000000000000000000000000..af6b75cbbea900c72a1a2f289bed88f7b21dfa1e GIT binary patch literal 194054 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

8c*Ru>bK9l!!k2 zG|7IS(e`)G1;#NQTM{fmfo}_HYD-B{N4-~85y$>vLAW}!6vW=3#1^r{#-m7!B6LbMbT?=`TH8EVP*USD`*iDaZa1UO~ZQYmj?QivqB|K$$7F|iC!X(ESbwmAQCfr7_ zL5gumIIQJhsUWH7GF}C~y>Oa1w-f2~^jVP&HBtYl1H;->)Ys!IvAf&GQ^8h>-Y`3JIVdR3W{Twz`&0y!^@dB7hC#c8ms~-gpd>dYPw?w~pI=j`r`P5OiIe1s` zI1A%*noi{ zk-Prcv5Vjn!%URInECFQau1>re2e1vN+1)Y@LNoM#XldTot4vV^xCif#fi;mM1SJCwve#El}L3lg7*wVb-Y&U6JSP<8~ z@E3doASSU2tXKHu@pJ&Cbp;&hYtB%<2gU%ZC~6=HSTnX5UU}P%?X^`hSu~S&)0syB z%DW$y1x;yc)|7bpJ^U7>;}Ii%=8kTllUr79WVKiK()$)~g?8*aAkm4W=O4gsz2`_J zNGcY@N4Y2?Wr)`q%VT3uO_O>-xL{T>ZNPI43k%UXlpim{L7Xc4s7z(5J=eJQQ~FQ5 zjEvu#xlPPB`$TXi4d@aS?G|WNeEAOfm#>y%^2Bw zT?VFSo%Rn$FcpJ_h#gJ@QxHLoC4r*9mK4mgC4MyP{B%5FewW z;T^w&GujI#U^I~;8uZGm=>Hc310NzJAGG4u$P|>wjP>l^;aens>s^BLYXC4##Z(<( zWEK?YeYh0(0uRV|-o%>e)0Dja%BxRN{g?~BtJPy8qVj`F5Vpk2)# z?H=cDpfsmgnSwWpj{gbCf*(sJdwWkt%8yb=@YuR2$R+q&pLp&=HPPY^cxyPKPZ~jn zktad(0+3nQBu_WH0@Ph+X2YOiCriThU?i99lrEVM^YYKH8=#To!KB0-8fa%Bq1OOL z%+IgHh1@Z?5fY>H0R=XKsa?Nl=li>vd9u`a0g#A-(pMrEI%NQvWalg{N*Q{uy;Tf* zW#6Xc^JLoYWAZ=t1|PBNXNm#C{kN*o>pDQB&wp6ecoEuF+QZy1W$<**_CTT%2~l;r z+AbvW45@3e`o(I>C&mtBiXw%0A5-}~w~12Y5eF4`+wNRThzIq`z`=?xdX?Ai97o3) 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%0A>A|68fit4F{t{Cw6>&8^RiVyztb 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%0A>dR22?P+=33 zAOZk35sqWW2IJ{8X46TnWU`4Qf>(*|H5Ab57k2pe9vlO4RexqSaXlPJM3ToBzfKgneg z0J&Agn6dAs9@f0CHFLl4ufu&rNt|utA$hA-OQRJ`ukrN1C!P@y;D|U4agcYs8INI4 z6}XxIeqxKLwr5Sdz)1b2!{fYvXP1MP0oJaY_~&DjbYMYDGI)Cb{_p;e-gG0R9*(*2 zz5Z>R(Jb@X#!~a&FB=vCEG+d+*?|u`%$8Z{k&cBf!|SB>TaJEC#H5rBDSn-fZ} z44`RW%a_DTAM2e12--xeRNMS&bO&hxfGw#tn*}Jx?9u?%Y!kSKl-))otPKD()Z{jh zIt^PcRtEx)*Zbmq+d#{}Z`%=o`=kBXL-ns?FeRfk#rvw&X;?teE{M=lpbg5Tdfzff zJEZ)t%R~iBkRpDSr8vnDCXKL6GIV_^xg0_}fvvj=tHlz}i8~hoOJO=TnO42vI`~by z8;dt~2YSE@oC5!RceLs3s{!b>`JEI}LuG}e_Od|SFUb9OMQ^^z<(96aIJWC)5w z^SVFUR}t*}>aSobP`#0$F1dL}j6@wsCt~BfU(wnoeWL(2YF)(pV67T}ROJB(aDM6i zF4|2XTc{$nTW66f>R@2tvzb@S|4s0(SaXn|QnnTn%nh7e!Q^rZOh>@#$DH4PPVo2T zrVRWs@eN`!%inC)f@ue!*u(+wC9jjWX@Hxac3?*5rNcUb7{VHxC!GfaMd?9@_m4LS>Fg29m=u)Zghl@? zLeyZiFcb*d(xNnU80U|E2?==5O~yzULbJ-0_+1Be;gl~zi-N<<7+6cb_THoIiKW-SUP}K|t53(|xG#E$h zPwY4IJkD)uanzZG!P$>sxvj_hV}f-(hF31Vn1I&kX;X~u#)@yqw0elYKX_2@ai!a2 zKP1BQ=b|IR&QFVmqHn0-chWz*Lti3l?8OxP0sF(MJH znrDkPBsX5N)@0kKF#I%g>+;%l8&`4OPiIg1FkyuBu?4k`f&dcqn91CRU@%puPoV|; zVF|=eaS>XncLj`pG>AtY%btI@!`C8VsrV#MYV*by`I)}5-16;_Fc4Tsz>Mj({K4<_ zDE#B0vL5nB4Fqr^Yj{a5sw+C+(Hb&VV^kj5Mes`z*+4UpwEkgsA?o9J9gYwm$NsUE)q&=?nAtVz%SyagMIi4X) zzHvp6`(oX%f4(RS3Mh11n}ZL~1MRJ77Z-2Ce33!4u&Z9TPHuU<{$N6Qh3pf1ZL|2~ z`CCZQ`u-p|Sdo}Me3aYIl@Tg3$$R-1UeMq;c)!L$7j<9bt1`kmSTQ<=#1_S7ea&Rg ztp_}*ozUm(9pcLNy}CKcGq{>UW&IU=be%pePsHBTYD z9;ac1&hxNl)yihO_;h2Vf$je`p7?9wP&g)ylvjQK)XRDJI zAKY_U2__tX&It5aJNb20xV3#L!C(xmD}pMXD4d;sh5tFjt76{Oi2|#==2aDX%=9Pyy!kI~%U)<0Q#@^EBE*wJ zJ&c4qT`1?CsU~vAHed8jTX=U{f|URIdsa*j*6JN)xZoaEASM~NZXV0kn(9`=l+UA> z(FpIIjAE_fry1eBa67%O0n3CVmWo7!cPmQLB)|1Mky&~ki%pj;^?ZZKEXD&|#-S@a zS?Him;Ul!WcRmC2*;lE_Yra=W<6+`%DPM$0n9uv853FAFx^M%MCO@l^!%G(Oa_57- zoOii>>arsG{|-;`g%IUR72Ecy50-ztI2A7*h9Ph8nax!F?;G$Usae%UlO`XhtHCSZ zo*svoje+4wB3mmmcr-Z4{O#TL+_D^L7Z}I?0XhT+3SYU91b%~o;$F`n4VRPqAgO7b zy#h`RZ;||7OQR;Ibi#dcr%yov{IhMeU=nig@pkvR6#vH|WHLl>@w%AC(Hi{u%_RF^ zP7~kD__kCNUHt1SiyTdHT&FUxcVMz+0$TR@ELmSW5pqnYBwQytDZ#@m5E!!{vkjA| zR|kJ3bsgrf5KdZ#55KzgBY=|a8Zvw>AU2)pJkh&H!=`-rq)%?qq#J!F!0@K{1X6<_ zotemRg2O<3%g6%oWUt^E2ODhO3u7USxeKJ;Fi76HVzZfeT-*kh*(qc6`8Q_+WNv|6 zW>aL#h$sI_zW4~(diQd)GpP_H5+sV>;BCAf`n!{@3=)|<1;q9N@mV?kU=A@yHo>OG z&1!GFqIKuo4aPtYr&U^Ul-WRMbj=CVl>~-tJOjL^M&j~vH<+YOptEj24tHo26?O$9 z#Je9!dk5FxLPqa)zA^x(^$qfd?Zux9kvIG{M1{pi)m-gNlWVod7eJPTdRU*|QsD;k z9TLxqUm$}6oT+p^59Y7wZ7>NCrWQ{eRPoE}=Jqi5bqz-UZPm&e=Sy-f?38?|8!d@vBhid?OU_Cu8uyYl)OPM&b?%Zweod- z!9D)TZQU!w;7qepf&Hjm442e3iOfUPq`^1U7YF?OJH+phc}l|v6%6H z#ofzqT9m*3G^;wwj~sfpEhShiZaI!nqk~NpH67Qjf61N+x~pmMplT_ODdV(VP|%%& z?N9Yxj8nxug_gq{X11Tz^YnHo=9|*gX7da#-Z-4L*iASHI#u&4nt*7OlPr)L;if)ifmBSsT8shkl z-|SVpRjFuWexT^hOC+Oc+Lc=LpiC zF~S}^$3aaqk_;_6v3{NZUqOmkW64NQ#>A;xk2T13hy_;5DgGqZ6;AE~}jZ&;T=GhmaIzU5VuA;uE^+~xC1 z{1X-mowm>0F=b(ryA?~=l3D8O6OTE!-pMei=dOrZtLJE7e;o$D(D_#_9M=wSg!!70 zQIxx`seOLjNoGIseA4HvT4i?H?ed#@1H^wXz<;0p8dc=0nzz}>AxaU69WSolEa8o6 z#Yq?VL2?H3Du!C4sH~9dV5wrga$TqrGKy93UFT4)!NM*Co1#&uQD(yYdtP9Y3615} zp1Q|z2ktUyxh(cJ4W-D`hLdJS3b!8>My}`P%AXgnU$8`!w)(ByegqDmhS4$C-c<@H zdD8ig#UKANqn2U}T}~Z?dAgb+ZZTrT^5q?iZbi{gwlLpm7`(4db08}`^gC|D>paO&d>RTIf2By3 zh%wK)AETFU-2Xb>xDmmNALsFB$rQ0U!DjG)?-Jwj0I}%`#Vm)q$_gfX z7gjhek3cr@lu9ZrA4b@8v(3W%sCDZ*^^P#KMQ)x4ebA3d4_?GFj*|Iw|L$&OTrUpxt+{k~V|Ll)+X+diz->yO z?}c~6NTdeeD`X$u<(q*#ZW=#ivkT)p6iUWW^yF3psM3W-Ab{@~apR$$V3-?nn{PyN zSqyX#t!_+HRS}5B(Zo$64gXsk2RCq?`Jwey=UqI!#Lsn>CH3D!j7y_=q3|hW-hCsB zip?n1yO+S%MmZ4vzEVx1L6{1C*!z&r{-dS&4GI?jMFZ{-{ZOvPRHB8gyqBWuqc5X3 z@?OSib6*ai?_f?-$PN_5C1sd{vEH!*xw`yu%O+rMVXYRcCLdz!TBl;u5zqd((%Fh1 zviqc|2xHe%#FEV!JflV+nyulo;AX?zo>4ZGHTb_rzFRX3$SR$oJBA+RBE6XFrpI2d!*@r;#wheHiTflU$Ga__lcU~Uo{F44Co~@2X^6u=#8GZ0? zw|sG(n~v+15Zo}c!oDm~0`p#b!8$Dw2R_UdC`gQGr9ttLi23#w`@?o$ZTiEn9L0`* zY-qGZBNqZTlgi?EV>qi$qqD$+Ge-IM;JRqR(OI{}lW=UDPMS2YA)(cqdj zpvgF*hqlPSyGQ?Q7xE0k=7veiH;MvBNOc#T=rtSsihIRQXxH%gb$nZXrj0Lh@lwnF zI-`tGI5nT^)qj+{fSq8R8^WWw`HpdVKBih^tTq=ngH)=K4X2s>B}$+=38{xFhWK!B zF-oZK8qBwG?xT#Mpxb%YpB-ClIouoWTM)snvtXZ}hFq$+s2Ag+o|7eM9#3gvr8;6G zA3u`v;%Ut(_Hf~sOPLuqI4|z4&qRbPj{KqIqX?|#b6Ohuq?D1Pl<|_^MTD&^>ga|- zg@&JZn;n@H@#pJDhr6rGA%~q2vz29Gq0SxPxiD|WggV$vMKo7;?j~3oUAlUs2`hh-oT!{J-|HiS>=OTyq`!$=>OhV$fmsD3%k&^Xb_o>ME}21?KVO{wQi{@53)03Mh_IK^RD=Kp=VoS-A36fV045gAh9tyP4I z%e`+sswci6}=x)JOL(tU({68Kl1S#e`Gkr23u5WdE1G zVfh*X81$8J&HiAJu0ii0?5Eh@EKvkinew?33yGvGsfW)L%-T!Q4Y-FxbL+GKO881O zBm0W~H%>P-9?EB?xk~-Rk?s2YAdWL|6C^T?G3$t*V#v(Tvzuv_;+=)b{*yF%J8`>z z2KA94duCwz@a2f&m#);={>)8nWVAvPUUoU^?-nwjA|O6H06q7ndYm}4etL3LNw{TD zxiz7Xz}+boMrgQRbCmm;&;cAnhvBEJVuJqh;R?|a1G zspmR%nOM-hD9i(Waq%xhhq-uSxYg;)czTqLyT<4=+mTP`} z!m`OR*g`q>j>{rUvIz3iiLU!Im>F8PV}Ht290Q@lpThoh&EhRURK=c`9No{~H3qP8 zIdpYVo-T|AQpO!P?L~-V8qpG6co-AZypMQ)#fK2F?W>0?6<}t&h zj=5?`^QK1iDf;&^yO}Y_{)UUNRaQg)xj@z+SbE#dLx*4vYtXnD=M@ z7C2+OF>Uy~&JH4tGvv?IR^&{aWzOf}X_n+-vZ{~Z7v%&#scNRN1pU$~HH-z#uUp@7?nNLuZNNFXcb(dY>S4aH7g> zTjwy$_tMo7S=Q>=iJ8@jH1VqzBSl$OkO`H53r@xLn?k*|D^M75Km9>o3DwdHOip#g zcnVW>&vYtY)t^3ITq=A3Zm`^o=9cH5*AfdUVe-K3&N9FI13MhfI5fh84XiNl9zQ>+ zR+a;IPw(Uf?wuC8p;XaJ^CVaTH2|K^f4l-@*oSxhIhuXIx-{W+R#Y%p&od# z{gO5&Zp;G*yY&hjxZ%`n_Vf5u58MLL8y&;lcK(J5xK|7bTiHs+VO5<$fWZs5;_7JJ z7=^$>>(^}v@B9sSlD#Z**7}6$LJ3$)QoIk_NN7>1=v0%@__psqYyd8*|<`ns$WgP=94E-{B}lOp)PyD z%$6bJS8#-{Ezo^39}-4FM08LjGi;h^QZJpSTn8fLYJz>GtlVClWNW5;4jrL)JWf&A zhmwGU<_5~h43%ow8PWt@Zvipu>R-Gq*}`tlY#oMd9>CJ+@?X=$(pnZgMlgtaOZ4qv z{4fju4Wpva`AumuOph>eLYtiLp5B%r&m=G$sPeF+gvDGIBMR6D?)P~8`HPK9kn^CY z-aGj5Qq@dmvP#=Y_77#h9;$u3NY6q-DE^3hxc$D=(|;4h(IGO+z0CY{<4I?}^up3j z;p1NhkF!dq7jLF5O}L##dW2I7?tz%1kISXuW;=edS+l< z319-tY0C_KMTUCu86;J6!AI* znAx*in7_*(bqU(9K9INo^j5p~&FDTJstU8=+!3n3w_c<)YE>8E+1ig_O%7)*?%fcqc#f_Fd4a><(qjx<-%+ z>NE*ldmMI$w^yxyhTO2M$FC<$Q3vxmK!k(c5LKKTlWdAoWS5!yF($iU}T;Lw)op#o|IC3Z|0=*yS24M z@BZHAxMc7znq0b#b?u}uJrKfk+;t{Amx1YEsS4{+NKZR)7K{viHkj*ua_9_P&`29Zr`fJ9<)H!OO-*67Z^4yp=iuGCS{m^9qTg&SpO=O=D(7)0iT+x&jP;Y*dsH@S z3q2W0?CXG$xsU+dxF+z&Rp=`kkI$*6dj1kzwZ(uqbyv8oTZ4P<8!pQsw(?t9YA|me zypcI=YOCJ;%|A_oMKr3}Eo+%{0|Vt>i)cN%==vtAJs0jdYc;s|T}ne)YlglQ0Ycxx z!b5Vf*h&^eI|(qBF$ur38OJwuith&)FzCH1>?@6_K^ecAKa?d&O1NMm*t)ZebyKK?G=AL;4>krjX;Q@()cd;P1djA|5a|NjY{ta(F#?x(!}W)O^DYJmf`hrJ)Asdj1ArCG&&qu z)h>aqkPV; z`webw01dI~shdeOvBRaGRSmY#U!< zvrv~p_K+)h;KkNz7`aog!87jodi$8FG(zE*E(AJ$U}3JazCcKd-=`E2lklU~Ag{@6 zU!QOJ@%e8GE;4m1GCg)o@a|Ps!(yiNsM}O{buZAx4IrCK6cSw%d|(L7%t35B4ZYXb z{F=cEV636e#6@BN<=e>_f9@47tC62eX^c=uyS=ikyqBoA*ZMLeIN5q1ozowRL#Sx) z8fGB553OmUWZHFF?4|kA{+lSwPC?lf`00m}OjS0;xiUy0&`S&7$}2G7p4ig{(&k)V zhq)oZ#}hbi+IJzM9A~HuDr;18@-P`sED`I*yo7#{cl*Xt@vB`C?PbU)< zVi4IN)BHHuK(S!~-^!ISkLV21mYPwKQ|y zQxg@I+0l9ABv9Nfh#cLCTZ;*%Z=XgW+W?meiQTS)?RpMcfr9mhZKBff;U2`$y6z)< zBa2dr*pu%WAO6wq2XZ25Wo_ev_A}AO2;`XiG%)XeN?6p*ykoev8q`|l*DTFrBVfVj zW_0@!&vPLLKSgO;8 zRx%xXX7E1QO|M7=M}F55-+LO#XdwDw=&5GDfiFg_7cj4hN)cjsP@_3Ha(ewU zeev}p|Aoh_r-FC5&)i>gFf!q>h@`5{0Ai1VlFPW*V$k`DP?+bb>&~C4e)X?UIv2(d zbqwHj@rSPW|2|LnP5j{j!VH*RiuQ7>h#J(M?0$u#s<}QcV#}ILQtYR;SpWD zs9|svm2|dPPEdyW`Q_zD{R{6)ep}e)E+c;0x1VW2q~>Ja`)LRi{YU{}dB@TXCu_XI zvp?a$;mlh9PtzEK)OYtHj80>AZLZcoxxqV&1vUuFD}(wz#a&7KqaYYqkB7e*R4Z)y zH26`TI8Hdo)AK*$7dl520fXv!-S|PV`I)?%d6nZXljER1Bq~L7g_w1_DJQpl?)E6q zWl4JzFj?0UfwbHM*E0vFDdBg^)=G09|E;jed0~6Ko>5)+(#yT#CUWTtW`3G@&m61$gVPNZpJGRz^);%X>Oh|3h;`>TteA29@gZY1h?1ur-AHlA9s5ko-QN zMO3A?L;VHack+SM874AIG=$lp>0Tg9wrg;>g_$RQSp;f?i(?YHe&?Z03aN_Fn*9i= zR~5&|1E6Xf9MJdiQm2p0zb&x;O6c%u<>JQ#ozrRqZGgKR7Wgpz9 z@0cs#{X~?CR`8Vzvs5xG*v7AtdH!ha(*n^g@ZPhK|Bwzpl|$Fd_xCit6v@4% zk#IN%Dcbak@FJTLW^duIx2)(21+sFf0UyzJ*v=-AarUFBO(y}ynpzCx6u=Z^UYlwNW`zBYG)ktI|=cVmX?7bnX7JY?<*6jbup zy3In8{w(&jR5&h1?<~SmmsZa-oNf#*0bX_#j3F(%1@|0FG64LE341aAQk7Zdqa6Fh z)zGXH5NJ5hMoGWPURUfbK%0DTI#dZZCaZu?K;2q*b0+z!kk_GOoCB-Y!Q5R%%S$sU ze{s|;zYCvbmZeY_8(2b3mno_G4%JQCC2K#l7L8T8{&>!;?(c?8nIQiaYjC;2R;Akd zkV86n7|y3D+_2<2R8AMM}UUsb`YF1rU}MVEO1MC)71C$De@iZ9-<7Z za#M*62G%^#!lmR`9{6Gb$+DwVDf+FuLtrvu0yu(qdFk7qRzrROP_SF{z7Jl76kr!B z&oWh}1rOuqumUib6}G+;=7wuV!fxc>4={I(`s7mo=Pz#Ca~vxt@&e2aq%5xqw`A-| zn2Bww?1Ft+5AR#Q={ZV2T6S2&-lsCsJo}vy!DMgjU~Mlf^<+oIq@8BwVkG&Wb{Li2 zh3DI66UE%#{q9FxyG>Xk&R)`4-)Z7mz)4#ia~!oj=h=S$N|4UGzDb8EkCJm=dK zZ!f2zSy%rV=+XUC{tb$zj_K!Ow>Fn=eQv+*=X!U%%EHkr@3| zO5ocTa2bw$e*ER#=kaf!T_`gmlnX_sSRX*tF9<_GS)#q;=WSK?oY|_ublA~VlpD*L zDI@b%qf$&yg-y5DRUXRi8#m*#^Ndur;?GGtzSkZ=z0_ad+HApcA`{eC8f7K_s*{m} zq{ZB6mMgSd7UvLvi~=X#yJ9o%YlX0j=yKDAMa_t~ql zdGqnj>xSro86bc1p(Y%&LYQmqCPXQ{3I%xS$?hmC?fjPqYM5{xYR*<2%{{p~_$u*v z?a%Wd=^KW<&zauiMf5;=_t~xveN~r+(%~G$vSm!GL6D9;m_@yziz}32zz|yan`rmP z9)nu;><+)p&lkKWE@O7m9#A8Ui?K?Hvrc&9j?G6b{$WLVMzs6M{`139$sM&2SFLHQ zU~GyGvIxs4BNoE!4dPC&2GYTfs$();p?SY=!9V0rFKh^@hdn*jhwP`HUxcFAHt;t6;6_-0Rg6*F^~BUfht3XFNqP?bYX(ZsfyL zk1h@7tv`N}}iSoi^w8ii5vI%t-*?`B&7F78}`i0(q_Nq98yS-)+k82@BJn zy<>FP-mY`~H922D7LOstFc%vt%pR}Ka$CpVNe^3x_s@xukluc-srG&8_;m~~1|#p` znp2Y&Gdz6L>vj1-(=uXDa5yt&FN?Dng%1P7jkNw5k@N~dAl*Wnoo*{YAz4L3{|`f5SLy$jO1iWr7qOb_7vU6Q?APn7Ol z7bm@Z58(m^_h2--6RFoJwf{^y?HV}e>;g*9r%?A%KB2<1J!D}c=G1=ZU|!`KWcX|R zSBvd`f2ZGJ7>&Vmtsz%!Lu6H|cYLq8cBzgv;U2toWOdlaz#8~&xhTcXr>zr|#W zJ^{?1YtDjwn@rOFGy)2!-}@fFe6Oy2%6PTa8G6W7)G|@@tk3dCs;D!FpR@*Zb*;cc z=3X>0Efuv$;|L$n0U5nSrXg2v+=-V{FaF0m_*Rks61P)HVhVZ8?zWP~pXfaDY~ZU| zcMOJwTL7zCvw4azk}`Hz_sacC8Iwi$fR&$Lk6J*(@9_>N9AsNb1HnWvek~d?$=&5q zr8}{wHA$0XCm|{X{SKK5DQot05CL~fOxkcfKb5Q{Dy6t zZ_h85z^C9dHra6tS#_{~Q%0!zNik@dI#xFDI`JH?{TP*99W}wVWY38o(sZ2)QGOWI z4R;%#e2<~e4Py_+22H~t2m1*7qfFiNTAMPG2h~#p^_ohySPG!Kf(p4sw2ej}t8>)O z?Rc==N&*>?!@S$T3%=)Gq~E)!01YOJ(=(T?;(F8Pa%IQDZ&AGkHJ zs2*1WwbUgQL23nv(U&BU^wY@e`J6cY6&TnJ0C-=yVc^*KG=r3+bl}_@2I?nWW$`igEZ0(lI+O&! z55CSC{ip;A1R=Fp4h#z>F6jPsD0wL|g)P!!bUBt;ZS&!682L-*3@;OULY%sMo-@6a zhL^b|7%TG~_E4O~P(zJ)%-r$8cDq~r18@U{2HP4&?Go6ugG>E}f1)k8WW)czX! zP{z0@mc*k!8g^f5WT*uBi#8+`tKj0~_~2GS;q(XTFeiZ764gn0hzK58Q(MRWZ(gm6 zVkmCju-mTwYSylt5eJ3Cs1Yr$nJRW!MD#tw+GPTr$cH?|ohq=Z+dIwAM$Wg0CKc9W z8@XaK?!Ri$y9&uG3`00qmIGSlF`cCE*!fSI3LkI0u#kRN0wfZDCYz-QlHW*j5C-YE z>CJT}%r^sDn>Htzd*pE^OW;Rhb^B(_BL&4-up7hahY}abMHF2iSmGZqpHInr$_DV>Yv6)p4{eZ(Nj|CYx<}A6F~t` zmT;b}_XERDnoj|mApvA6#a~KB7@qjeO59<)#tr3y(k+sI`a>jn_M-;M^)4SV7k=Ok z5_1K?KQV|AQ5Tvtb{I&N-s2jF+2X2yQOXG1oM;DG(J$pPT~OKNK52kbXJtni-yC5h zD$;X=s0lJi0&AhCra$TCx?t4~5R+4wFW$SpK9&>-6!g0FkE#Mw;)fFs`{BlX`B59wFfLJD#m=c9x?) z`PD#a3b#WU3h7O(us}%RoCj4(t#varWP~0}+}XIS$@#pn+D9GuSo7fhWo?1FjX)P&$~qAOrh4o=W-j6( z4hrZ?dIgnU*GIXxM*5zc0frjKixVVoUq3DgIlZtemS~xOcq>eM}bJy#;wPM z`JI+b00pjP9KB;nye@d)d-!MB419!YEb85|PzB6?(joNTj8mWY`E#RC|GMs&rKdII zos~?hKC+$jzW#Q1mtM6yjn4D-SY8X#CUFQgn`0Kbe_IG=seJR@jfcDsT3_;Jm?>MX zg6)@Wpun!7D)k2pDRD}fjj@IoH??s}NGwG`^;1A09;lHbY>8PqQu-L;c9F5h2#|Jrh{C z_V6B{%#5TMz{x6 zPW&~ngt<90%!KXxk6B*!JdYAe}&4E(vTPtOux|?71m-R2VjE zV6#8EnZ#!3XLrZrMpWV~j!7L6e>VtHEId|=`T5jSt(vbL_9#}KH&x51bFc>3br=?Mho@itFx^ot=9lKHd5^QxlX1>M z@t_-Py!=pEzyFvI7p28;;Rls>Y>fwiFFSv|cJ0TR+S$H z2443M{(7)Txyg4r6-`r6mNN7wCn!8+5oW+aFF%G33b*#vHV8!4aEssNXGK^ z&L1j3_Cm&;W&zSd!_tuS7ttKHzeEsbR{K3A6TUdvgfplZ9Up{*Y|Xux*WFtiw^|u0 z;08%gX;gzh!?WP6(L+09w-%3p(D`Z!REB5-;CuhY;au|WPZ6nb_#}S0U4pE)z;LJ% zYO8Td$82Ne{ypeBbu1>n0o^kkyP2vj?T?Rgo_(+Rj+Td;{z>`6!;!(~0ZxE!J45H5 z=E>ooq&?l8RKn@G?i8Erx9_oqsH0xat3o8aZrgwP3;v53Oo6=7R8q14BPaUWb|vx# zVwhFUMjXdepawfUhAsD#%@bRO;X&F>fg90TxqeE@=cz;FBx;o?Yyam|eMz@vct9JZ zh%MJCqLO~a)TZ9f`9=}7>IeJJsW$cGjg|WQt(5QJHACPvYoQS3IgnNHu6P?#5%(YJ zvxK@OIw^OO%`tfCNS1>;eyc0~lcJ297vr>RGqVigz$4)k$GE&#`F9=?&0q%^h#=sc zPI4t+K71dRGaA_`iW<4eoPH`<=V)B|RUkcV8s=VrX+kGNIDLHJMpLSogVRa4$PIQL zJbF2i`aa&xR2?r9eR^o#v0sS}!)_p7OX%?nLh09FBgL7icHJ}@)0WgBI*@$Qoooe7Vh+Jd-6?U71ZW3R(Xk7PBPK_&gDh`&^xeE1tMVayAG>4` z-+457O#d-g$K2o_G2Z$NWpUx%PAmkEF!z-xjSZ+K+3L0FvBR*huk+?bst6HYx@{;- zJ$IMLki&0k70hu{wu=Ddnory#ld9M7iwZX;9Bv)G#oXb0U~oZ#ZD^BsguI1a%m?if z|fxW84#HmgU28G+%7fQlQao6c#LGGFaMgVR$RD25GdHl$adL&aY*v;QI?J8KCHy zNzBWsc}^DMzgCt0Ub{QwlfP-uQg<=5No>NVY$}iirEmGouvUK8m4dL_y9l{V5X}da z+7Spc*vaWGJEmqz&(Qn#%)~ z&StLkX2OYBLz^K#Hh76|&9XW}wBqUEGc!YUft{Q3G_i&(j}TWnf^@a3yGp~(3c2t6 zE{`sr%d14Zu|<@wWia(zHC;Z6Wn6{pqwsPRiXv+JW>xAp$-Bzh5`hkWlrOMZ_?#|Z zWdyB%)j-<=*{Q58Ob>rvCjFYR@F2Ta(<%hIj!}CoVG0;QW>pC*j+JkDU{ zl~c^d+BKw>U;(S93^crMm0gcC8%P<#9_~g@Bb3;#pM&|~TvtaNJKbR%Pll*sc3^Z-0Z^}lzrW4kJ{MoSagEf2y63KoLLsOuN{0|V8>Xe| zT|=E1f~^@tIjRRd<=Y@*pYy(tCDd-7t8VKzPqFic?6MI2g_Cg3^Qm<{GwC%(D&ZVL z);CIBrA<^3WcOewgzj60>SKd?Vn0@NJ^!A1o%HQ3cD;M03*Lw4gA*bvQ5E0xZVnl@ zJ=2`!<>rW1FL^k7P{(&Zm~q8aK;d;*-Cjmtn=@vo$0PJ9&@YGKt% zTWEAozB0Nc=LJ?TYDvBt^PFI7EFh zqu7N59dkA>Iy9&rIJ0bWX}!LZpQdZ&81Ao%O;9 zEhDv5v$$`+J6T{u__u{C$B?NEpF}SF%zBMMoUNXh{5h&E!NXtchP5X(>hAV0L zSB0NW0QJYwm&PpoKc26Y%1=*{8aB0;lUfwe8HARvGk&9RxK20YU3~{(06&Pmb#k9q&f{zKg z%wrtp>Tj+4-+Gh}Wn`J8!-||x$m`2CBQyB{w}v5gTgUXBX^C(-TmfQ#6~Dk?sv>

?Tw5^j2|F7UlNIcESP9uzpmkq?c1ue(<5C? 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 # === Required import === >>> import pyomo.environ as pyo - >>> from pyomo.dae import ContinuousSet, DerivativeVar >>> from pyomo.contrib.doe import DesignOfExperiments >>> import numpy as np +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py + :language: python + :linenos: 8-23 + Step 1: Define the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The process model for the reaction kinetics problem is shown below. +The process model for the reaction kinetics problem is shown below. We build the model in without any data or discretization. +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py + :language: python + :linenos: 32-101 +Step 2: Finalize the Pyomo process model +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Step 2: Define the inputs for Pyomo.DoE -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Here we add data to the model and finalize the discretization. This step is required before the model can be labeled. +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py + :language: python + :linenos: 103-156 -Step 3: Compute the FIM of a square MBDoE problem -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Step 3: Label the important information for model on the DoE object +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We label the four important groups as defined before. -This method computes an MBDoE optimization problem with no degree of freedom. +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py + :language: python + :linenos: 158-202 -This method can be accomplished by two modes, ``direct_kaug`` and ``sequential_finite``. -``direct_kaug`` mode requires the installation of the solver `k_aug `_. +Step 4: We give the experiment object a get_labeled_model function +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +This function summarizes the previous 3 steps and is used by `Pyomo.DoE` to build the model to perform optimal experimental design. -Step 4: Exploratory analysis (Enumeration) +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py + :language: python + :linenos: 25-30 + +Step 5: Exploratory analysis (Enumeration) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Exploratory analysis is suggested to enumerate the design space to check if the problem is identifiable, i.e., ensure that D-, E-optimality metrics are not small numbers near zero, and Modified E-optimality is not a big number. -Pyomo.DoE accomplishes the exploratory analysis with the ``run_grid_search`` function. +Pyomo.DoE accomplishes the exploratory analysis with the ``compute_FIM_full_factorial`` function. It allows users to define any number of design decisions. Heatmaps can be drawn by two design variables, fixing other design variables. 1D curve can be drawn by one design variable, fixing all other variables. -The function ``run_grid_search`` enumerates over the design space, each MBDoE problem accomplished by ``compute_FIM`` method. -Therefore, ``run_grid_search`` supports only two modes: ``sequential_finite`` and ``direct_kaug``. +The function ``compute_FIM_full_factorial`` enumerates over the design space, each MBDoE problem accomplished by ``compute_FIM`` method. + +The following code executes the above problem description: +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py + :language: python + :linenos: 14-84 -Successful run of the above code shows the following figure: +An example output of the code above, a design exploration for the initial concentration and temperature as experimental design variables with 9 values, produces the four figures summarized below: +.. figure:: FIM_sensitivity.png + :scale: 35 % A heatmap shows the change of the objective function, a.k.a. the experimental information content, in the design region. Horizontal and vertical axes are two design variables, while the color of each grid shows the experimental information content. Taking the Fig. Reactor case - A optimality as example, A-optimality shows that the most informative region is around $C_{A0}=5.0$ M, $T=300.0$ K, while the least informative region is around $C_{A0}=1.0$ M, $T=700.0$ K. -Step 5: Gradient-based optimization -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Step 6: Performing an optimal experimental design +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Pyomo.DoE accomplishes gradient-based optimization with the ``stochastic_program`` function for A- and D-optimality design. +This is an example of running an experimental design to determine an optimal experiment for the reactor example. We utilize the determinant as the objective. -This function solves twice: It solves the square version of the MBDoE problem first, and then unfixes the design variables as degree of freedoms and solves again. In this way the optimization problem can be well initialized. +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_example.py + :language: python + :linenos: 14-80 +When run, the optimal design is an initial concentration of 5.0 mol/L and an initial temperature of 494 K with all other temperatures being 300 K. The corresponding log-10 determinant of the FIM is 13.75 diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 912cecefc96..2909727751c 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -155,8 +155,6 @@ def T_control(m, t): neighbour_t = max(tc for tc in control_points if tc < t) return m.T[t] == m.T[neighbour_t] - # sim.initialize_model() - def label_experiment(self): """ Example for annotating (labeling) the model with a From 462a75a6b17cff49fb5e4993e3e3c0b56dacab33 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 19:14:38 -0400 Subject: [PATCH 100/203] Fixing literalinclude statements --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index a9afa35e32b..8148d707359 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -165,7 +165,7 @@ Step 0: Import Pyomo and the Pyomo.DoE module and create an Experiment object .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :language: python - :linenos: 8-23 + :lines: 8-23 Step 1: Define the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -174,7 +174,7 @@ The process model for the reaction kinetics problem is shown below. We build the .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :language: python - :linenos: 32-101 + :lines: 32-101 Step 2: Finalize the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ Here we add data to the model and finalize the discretization. This step is requ .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :language: python - :linenos: 103-156 + :lines: 103-156 Step 3: Label the important information for model on the DoE object ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -192,7 +192,7 @@ We label the four important groups as defined before. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :language: python - :linenos: 158-202 + :lines: 158-202 Step 4: We give the experiment object a get_labeled_model function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -201,7 +201,7 @@ This function summarizes the previous 3 steps and is used by `Pyomo.DoE` to buil .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :language: python - :linenos: 25-30 + :lines: 25-30 Step 5: Exploratory analysis (Enumeration) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -218,12 +218,12 @@ The following code executes the above problem description: .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py :language: python - :linenos: 14-84 + :lines: 14-84 An example output of the code above, a design exploration for the initial concentration and temperature as experimental design variables with 9 values, produces the four figures summarized below: .. figure:: FIM_sensitivity.png - :scale: 35 % + :scale: 50 % A heatmap shows the change of the objective function, a.k.a. the experimental information content, in the design region. Horizontal and vertical axes are two design variables, while the color of each grid shows the experimental information content. Taking the Fig. Reactor case - A optimality as example, A-optimality shows that the most informative region is around $C_{A0}=5.0$ M, $T=300.0$ K, while the least informative region is around $C_{A0}=1.0$ M, $T=700.0$ K. @@ -234,7 +234,7 @@ This is an example of running an experimental design to determine an optimal exp .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_example.py :language: python - :linenos: 14-80 + :lines: 14-80 When run, the optimal design is an initial concentration of 5.0 mol/L and an initial temperature of 494 K with all other temperatures being 300 K. The corresponding log-10 determinant of the FIM is 13.75 From 087eaad99b0758a3295394a2473706c209c731cc Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 19:19:14 -0400 Subject: [PATCH 101/203] Fixing literalinclude statements again --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 8148d707359..291fe99821e 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -164,7 +164,6 @@ Step 0: Import Pyomo and the Pyomo.DoE module and create an Experiment object >>> import numpy as np .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :language: python :lines: 8-23 Step 1: Define the Pyomo process model @@ -173,7 +172,6 @@ Step 1: Define the Pyomo process model The process model for the reaction kinetics problem is shown below. We build the model in without any data or discretization. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :language: python :lines: 32-101 Step 2: Finalize the Pyomo process model @@ -182,7 +180,6 @@ Step 2: Finalize the Pyomo process model Here we add data to the model and finalize the discretization. This step is required before the model can be labeled. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :language: python :lines: 103-156 Step 3: Label the important information for model on the DoE object @@ -191,7 +188,6 @@ Step 3: Label the important information for model on the DoE object We label the four important groups as defined before. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :language: python :lines: 158-202 Step 4: We give the experiment object a get_labeled_model function @@ -200,7 +196,6 @@ Step 4: We give the experiment object a get_labeled_model function This function summarizes the previous 3 steps and is used by `Pyomo.DoE` to build the model to perform optimal experimental design. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :language: python :lines: 25-30 Step 5: Exploratory analysis (Enumeration) @@ -217,7 +212,6 @@ The function ``compute_FIM_full_factorial`` enumerates over the design space, ea The following code executes the above problem description: .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py - :language: python :lines: 14-84 An example output of the code above, a design exploration for the initial concentration and temperature as experimental design variables with 9 values, produces the four figures summarized below: @@ -233,7 +227,6 @@ Step 6: Performing an optimal experimental design This is an example of running an experimental design to determine an optimal experiment for the reactor example. We utilize the determinant as the objective. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_example.py - :language: python :lines: 14-80 When run, the optimal design is an initial concentration of 5.0 mol/L and an initial temperature of 494 K with all other temperatures being 300 K. The corresponding log-10 determinant of the FIM is 13.75 From 328bc83c1e07e217e5b9ff2709c87b6808542fc8 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 21:08:06 -0400 Subject: [PATCH 102/203] Added examples to init --- pyomo/contrib/doe/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index 6ce3ada420e..cbb1ee50f56 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -17,3 +17,4 @@ ) from .tests import experiment_class_example, experiment_class_example_flags from .utils import rescale_FIM +from .examples import reactor_experiment, reactor_example, reactor_compute_factorial_FIM From e3a00cfb627a8572ceccb9ed2b1f00094c923098 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 23 Jul 2024 21:30:18 -0400 Subject: [PATCH 103/203] Added missing init file --- pyomo/contrib/doe/examples/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 pyomo/contrib/doe/examples/__init__.py diff --git a/pyomo/contrib/doe/examples/__init__.py b/pyomo/contrib/doe/examples/__init__.py new file mode 100644 index 00000000000..e69de29bb2d From 070ab312863820f0cf182bcff340180e2b4e16d8 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:25:12 -0400 Subject: [PATCH 104/203] Add experiment and result json file for examples --- pyomo/contrib/doe/examples/result.json | 1 + pyomo/contrib/doe/experiment.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 pyomo/contrib/doe/examples/result.json create mode 100644 pyomo/contrib/doe/experiment.py diff --git a/pyomo/contrib/doe/examples/result.json b/pyomo/contrib/doe/examples/result.json new file mode 100644 index 00000000000..7e1b1a79a1b --- /dev/null +++ b/pyomo/contrib/doe/examples/result.json @@ -0,0 +1 @@ +{"CA0": 5.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file diff --git a/pyomo/contrib/doe/experiment.py b/pyomo/contrib/doe/experiment.py new file mode 100644 index 00000000000..d75b20e36e1 --- /dev/null +++ b/pyomo/contrib/doe/experiment.py @@ -0,0 +1,18 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) \ No newline at end of file From 45b7f87a7d22a820c3ebd9d8459a5c08c8a593e0 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:28:21 -0400 Subject: [PATCH 105/203] Add Pyomo disclaimer and clean examples codes --- pyomo/contrib/doe/__init__.py | 1 + pyomo/contrib/doe/examples/__init__.py | 10 +++++ .../examples/reactor_compute_factorial_FIM.py | 13 +++++- pyomo/contrib/doe/examples/reactor_example.py | 12 +++++- .../doe/examples/reactor_experiment.py | 40 +++++++++++-------- 5 files changed, 57 insertions(+), 19 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index cbb1ee50f56..fe71b7f5920 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -18,3 +18,4 @@ from .tests import experiment_class_example, experiment_class_example_flags from .utils import rescale_FIM from .examples import reactor_experiment, reactor_example, reactor_compute_factorial_FIM +from .experiment import Experiment diff --git a/pyomo/contrib/doe/examples/__init__.py b/pyomo/contrib/doe/examples/__init__.py index e69de29bb2d..dcaaeb3bde2 100644 --- a/pyomo/contrib/doe/examples/__init__.py +++ b/pyomo/contrib/doe/examples/__init__.py @@ -0,0 +1,10 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ \ No newline at end of file diff --git a/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py index b482fc319f0..c7f10d115b3 100644 --- a/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py +++ b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py @@ -1,3 +1,13 @@ +# ___________________________________________________________________________ +# +# 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 pyomo.common.dependencies import numpy as np from pyomo.contrib.doe.examples.reactor_experiment import ReactorExperiment @@ -18,7 +28,7 @@ def run_reactor_doe(): f = open(file_path) data_ex = json.load(f) - # Process control data points into correct format for reactor experiment + # Put temperature control time points into correct format for reactor experiment data_ex["control_points"] = { float(k): v for k, v in data_ex["control_points"].items() } @@ -81,6 +91,7 @@ def run_reactor_doe(): xlabel_text="Concentration of A (M)", ylabel_text="Initial Temperature (K)", figure_file_name="example_reactor_compute_FIM", + log_scale=False, ) diff --git a/pyomo/contrib/doe/examples/reactor_example.py b/pyomo/contrib/doe/examples/reactor_example.py index f673d4a3750..2f7cd7b43e3 100644 --- a/pyomo/contrib/doe/examples/reactor_example.py +++ b/pyomo/contrib/doe/examples/reactor_example.py @@ -1,3 +1,13 @@ +# ___________________________________________________________________________ +# +# 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 pyomo.common.dependencies import numpy as np from pyomo.contrib.doe.examples.reactor_experiment import ReactorExperiment @@ -18,7 +28,7 @@ def run_reactor_doe(): f = open(file_path) data_ex = json.load(f) - # Process control data points into correct format for reactor experiment + # Put temperature control time points into correct format for reactor experiment data_ex["control_points"] = { float(k): v for k, v in data_ex["control_points"].items() } diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 2909727751c..32d2342751f 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -1,21 +1,20 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ # === Required imports === import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator +from pyomo.contrib.doe.experiment import Experiment # ======================== - - -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) - - -class ReactorExperiment(object): +class ReactorExperiment(Experiment): def __init__(self, data, nfe, ncp): self.data = data self.nfe = nfe @@ -120,15 +119,21 @@ def finalize_model(self): # Unpacking data before simulation control_points = self.data["control_points"] + # Set initial concentration values for the experiment m.CA[0].value = self.data["CA0"] m.CB[0].fix(self.data["CB0"]) + + # Update model time `t` with time range and control time points m.t.update(self.data["t_range"]) m.t.update(control_points) + + # Fix the unknown parameter values m.A1.fix(self.data["A1"]) m.A2.fix(self.data["A2"]) m.E1.fix(self.data["E1"]) m.E2.fix(self.data["E2"]) + # Add upper and lower bounds to the design variable, CA[0] m.CA[0].setlb(self.data["CA_bounds"][0]) m.CA[0].setub(self.data["CA_bounds"][1]) @@ -147,10 +152,11 @@ def finalize_model(self): m.T[t].setub(self.data["T_bounds"][1]) m.T[t] = cv + # Make a constraint that holds temperature constant between control time points @m.Constraint(m.t - control_points) def T_control(m, t): """ - Piecewise constant Temperature between control points + Piecewise constant temperature between control points """ neighbour_t = max(tc for tc in control_points if tc < t) return m.T[t] == m.T[neighbour_t] @@ -166,7 +172,7 @@ def label_experiment(self): """ m = self.model - # Grab measurement labels + # Set measurement labels m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Add CA to experiment outputs m.experiment_outputs.update((m.CA[t], None) for t in m.t) @@ -175,7 +181,7 @@ def label_experiment(self): # Add CC to experiment outputs m.experiment_outputs.update((m.CC[t], None) for t in m.t) - # Adding no error for measurements currently + # Adding error for measurement values (assuming no covariance and constant error for all measurements) m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) concentration_error = 1e-2 # Error in concentration measurement # Add measurement error for CA @@ -185,7 +191,7 @@ def label_experiment(self): # Add measurement error for CC m.measurement_error.update((m.CC[t], concentration_error) for t in m.t) - # Grab design variables + # Identify design variables (experiment inputs) for the model m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Add experimental input label for initial concentration m.experiment_inputs.update( From b203356cb5c52f7361e7ed1a9432c6722971aa1b Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:30:23 -0400 Subject: [PATCH 106/203] Added Pyomo statement to test files --- pyomo/contrib/doe/tests/experiment_class_example.py | 10 ++++++++++ .../doe/tests/experiment_class_example_flags.py | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index 57bc7b424a1..97ba820880d 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -1,3 +1,13 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ # === Required imports === import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 2a282023a0e..adffbe40f16 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -1,3 +1,13 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ # === Required imports === import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator From 52557f2490de6232297ce54a3f9f2d706d797f00 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:31:10 -0400 Subject: [PATCH 107/203] Add more Pyomo statements to test files --- pyomo/contrib/doe/tests/test_doe_build.py | 10 ++++++++++ pyomo/contrib/doe/tests/test_doe_errors.py | 10 ++++++++++ pyomo/contrib/doe/tests/test_doe_solve.py | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 4c1541f088c..c38bdd54386 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -1,3 +1,13 @@ +# ___________________________________________________________________________ +# +# 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 pyomo.common.dependencies import ( numpy as np, numpy_available, diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 00336ff0420..ec2024ac5a6 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -1,3 +1,13 @@ +# ___________________________________________________________________________ +# +# 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 pyomo.common.dependencies import ( numpy as np, numpy_available, diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 92787ee8abb..bdef07c7fed 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -1,3 +1,13 @@ +# ___________________________________________________________________________ +# +# 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 pyomo.common.dependencies import ( numpy as np, numpy_available, From 24c4d6ea8d33710b77cd1bdda46abea17fa14242 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:41:40 -0400 Subject: [PATCH 108/203] Updated test files to use experiment class, Ran Black --- pyomo/contrib/doe/examples/__init__.py | 2 +- .../doe/examples/reactor_experiment.py | 4 ++- pyomo/contrib/doe/experiment.py | 2 +- .../doe/tests/experiment_class_example.py | 30 ++----------------- .../tests/experiment_class_example_flags.py | 14 ++------- 5 files changed, 11 insertions(+), 41 deletions(-) diff --git a/pyomo/contrib/doe/examples/__init__.py b/pyomo/contrib/doe/examples/__init__.py index dcaaeb3bde2..a4a626013c4 100644 --- a/pyomo/contrib/doe/examples/__init__.py +++ b/pyomo/contrib/doe/examples/__init__.py @@ -7,4 +7,4 @@ # 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. -# ___________________________________________________________________________ \ No newline at end of file +# ___________________________________________________________________________ diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 32d2342751f..68c33a4ca2b 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -13,6 +13,8 @@ from pyomo.dae import ContinuousSet, DerivativeVar, Simulator from pyomo.contrib.doe.experiment import Experiment + + # ======================== class ReactorExperiment(Experiment): def __init__(self, data, nfe, ncp): @@ -122,7 +124,7 @@ def finalize_model(self): # Set initial concentration values for the experiment m.CA[0].value = self.data["CA0"] m.CB[0].fix(self.data["CB0"]) - + # Update model time `t` with time range and control time points m.t.update(self.data["t_range"]) m.t.update(control_points) diff --git a/pyomo/contrib/doe/experiment.py b/pyomo/contrib/doe/experiment.py index d75b20e36e1..17a51cf667a 100644 --- a/pyomo/contrib/doe/experiment.py +++ b/pyomo/contrib/doe/experiment.py @@ -15,4 +15,4 @@ def __init__(self): def get_labeled_model(self): raise NotImplementedError( "Derived experiment class failed to implement get_labeled_model" - ) \ No newline at end of file + ) diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index 97ba820880d..b4cdd13b416 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -12,6 +12,8 @@ import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator +from pyomo.contrib.doe.experiment import Experiment + import itertools import json @@ -44,17 +46,7 @@ def expand_model_components(m, base_components, index_sets): yield val[j] -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) - - -class ReactorExperiment(object): +class ReactorExperiment(Experiment): def __init__(self, data, nfe, ncp): self.data = data self.nfe = nfe @@ -239,19 +231,3 @@ class FullReactorExperiment(ReactorExperiment): def label_experiment(self): m = self.model return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]]) - - -class PartialReactorExperiment(ReactorExperiment): - def label_experiment(self): - """ - Example for annotating (labeling) the model with a - "partial" experiment. - - Arguments - --------- - - """ - m = self.model - return self.label_experiment_impl( - [[m.t_control], [[m.t.last()]], [[m.t.last()]]] - ) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index adffbe40f16..c014f9f3065 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -12,6 +12,8 @@ import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator +from pyomo.contrib.doe.experiment import Experiment + import itertools import json @@ -49,17 +51,7 @@ def __init__(self): self.model = None -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) - - -class ReactorExperiment(object): +class ReactorExperiment(Experiment): def __init__(self, data, nfe, ncp): self.data = data self.nfe = nfe From 834088f3e8ab34275b0903829d39594c7ddeb79c Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:41:59 -0400 Subject: [PATCH 109/203] Updated documentation with recent changes --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 291fe99821e..e8b4d9ca2c7 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -164,7 +164,7 @@ Step 0: Import Pyomo and the Pyomo.DoE module and create an Experiment object >>> import numpy as np .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 8-23 + :lines: 19-24 Step 1: Define the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -172,7 +172,7 @@ Step 1: Define the Pyomo process model The process model for the reaction kinetics problem is shown below. We build the model in without any data or discretization. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 32-101 + :lines: 33-102 Step 2: Finalize the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -180,7 +180,7 @@ Step 2: Finalize the Pyomo process model Here we add data to the model and finalize the discretization. This step is required before the model can be labeled. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 103-156 + :lines: 104-157 Step 3: Label the important information for model on the DoE object ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -188,7 +188,7 @@ Step 3: Label the important information for model on the DoE object We label the four important groups as defined before. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 158-202 + :lines: 159-203 Step 4: We give the experiment object a get_labeled_model function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -196,7 +196,7 @@ Step 4: We give the experiment object a get_labeled_model function This function summarizes the previous 3 steps and is used by `Pyomo.DoE` to build the model to perform optimal experimental design. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 25-30 + :lines: 26-31 Step 5: Exploratory analysis (Enumeration) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -212,7 +212,7 @@ The function ``compute_FIM_full_factorial`` enumerates over the design space, ea The following code executes the above problem description: .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py - :lines: 14-84 + :lines: 24-95 An example output of the code above, a design exploration for the initial concentration and temperature as experimental design variables with 9 values, produces the four figures summarized below: @@ -227,7 +227,7 @@ Step 6: Performing an optimal experimental design This is an example of running an experimental design to determine an optimal experiment for the reactor example. We utilize the determinant as the objective. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_example.py - :lines: 14-80 + :lines: 24-90 When run, the optimal design is an initial concentration of 5.0 mol/L and an initial temperature of 494 K with all other temperatures being 300 K. The corresponding log-10 determinant of the FIM is 13.75 From 2371d1bd5747d3d23609ed94c99280cbc7db785f Mon Sep 17 00:00:00 2001 From: John Siirola Date: Thu, 25 Jul 2024 09:23:54 -0600 Subject: [PATCH 110/203] Remove NLv2 ActiveVisitor singleton --- pyomo/repn/plugins/nl_writer.py | 406 ++++++++++++++--------------- pyomo/repn/tests/ampl/test_nlv2.py | 6 +- 2 files changed, 201 insertions(+), 211 deletions(-) diff --git a/pyomo/repn/plugins/nl_writer.py b/pyomo/repn/plugins/nl_writer.py index 8fc82d21d30..bc0c44c93b6 100644 --- a/pyomo/repn/plugins/nl_writer.py +++ b/pyomo/repn/plugins/nl_writer.py @@ -122,6 +122,119 @@ ) +def _create_strict_inequality_map(vars_): + vars_['strict_inequality_map'] = { + True: vars_['less_than'], + False: vars_['less_equal'], + (True, True): (vars_['less_than'], vars_['less_than']), + (True, False): (vars_['less_than'], vars_['less_equal']), + (False, True): (vars_['less_equal'], vars_['less_than']), + (False, False): (vars_['less_equal'], vars_['less_equal']), + } + + +class text_nl_debug_template(object): + unary = { + 'log': 'o43\t#log\n', + 'log10': 'o42\t#log10\n', + 'sin': 'o41\t#sin\n', + 'cos': 'o46\t#cos\n', + 'tan': 'o38\t#tan\n', + 'sinh': 'o40\t#sinh\n', + 'cosh': 'o45\t#cosh\n', + 'tanh': 'o37\t#tanh\n', + 'asin': 'o51\t#asin\n', + 'acos': 'o53\t#acos\n', + 'atan': 'o49\t#atan\n', + 'exp': 'o44\t#exp\n', + 'sqrt': 'o39\t#sqrt\n', + 'asinh': 'o50\t#asinh\n', + 'acosh': 'o52\t#acosh\n', + 'atanh': 'o47\t#atanh\n', + 'ceil': 'o14\t#ceil\n', + 'floor': 'o13\t#floor\n', + } + + binary_sum = 'o0\t#+\n' + product = 'o2\t#*\n' + division = 'o3\t# /\n' + pow = 'o5\t#^\n' + abs = 'o15\t# abs\n' + negation = 'o16\t#-\n' + nary_sum = 'o54\t# sumlist\n%d\t# (n)\n' + exprif = 'o35\t# if\n' + and_expr = 'o21\t# and\n' + less_than = 'o22\t# lt\n' + less_equal = 'o23\t# le\n' + equality = 'o24\t# eq\n' + external_fcn = 'f%d %d%s\n' + # NOTE: to support scaling and substitutions, we do NOT include the + # 'v' or the EOL here: + var = '%s' + const = 'n%r\n' + string = 'h%d:%s\n' + monomial = product + const + var.replace('%', '%%') + multiplier = product + const + + _create_strict_inequality_map(vars()) + + +nl_operators = { + 0: (2, operator.add), + 2: (2, operator.mul), + 3: (2, operator.truediv), + 5: (2, operator.pow), + 15: (1, operator.abs), + 16: (1, operator.neg), + 54: (None, lambda *x: sum(x)), + 35: (3, lambda a, b, c: b if a else c), + 21: (2, operator.and_), + 22: (2, operator.lt), + 23: (2, operator.le), + 24: (2, operator.eq), + 43: (1, math.log), + 42: (1, math.log10), + 41: (1, math.sin), + 46: (1, math.cos), + 38: (1, math.tan), + 40: (1, math.sinh), + 45: (1, math.cosh), + 37: (1, math.tanh), + 51: (1, math.asin), + 53: (1, math.acos), + 49: (1, math.atan), + 44: (1, math.exp), + 39: (1, math.sqrt), + 50: (1, math.asinh), + 52: (1, math.acosh), + 47: (1, math.atanh), + 14: (1, math.ceil), + 13: (1, math.floor), +} + + +def _strip_template_comments(vars_, base_): + vars_['unary'] = { + k: v[: v.find('\t#')] + '\n' if v[-1] == '\n' else '' + for k, v in base_.unary.items() + } + for k, v in base_.__dict__.items(): + if type(v) is str and '\t#' in v: + v_lines = v.split('\n') + for i, l in enumerate(v_lines): + comment_start = l.find('\t#') + if comment_start >= 0: + v_lines[i] = l[:comment_start] + vars_[k] = '\n'.join(v_lines) + + +# The "standard" text mode template is the debugging template with the +# comments removed +class text_nl_template(text_nl_debug_template): + _strip_template_comments(vars(), text_nl_debug_template) + _create_strict_inequality_map(vars()) + + # TODO: make a proper base class class NLWriterInfo(object): """Return type for NLWriter.write() @@ -539,10 +652,6 @@ def __init__(self, ostream, rowstream, colstream, config): self.colstream = colstream self.config = config self.symbolic_solver_labels = config.symbolic_solver_labels - if self.symbolic_solver_labels: - self.template = text_nl_debug_template - else: - self.template = text_nl_template self.subexpression_cache = {} self.subexpression_order = None # set to [] later self.external_functions = {} @@ -551,7 +660,6 @@ def __init__(self, ostream, rowstream, colstream, config): self.var_id_to_nl_map = {} self.sorter = FileDeterminism_to_SortComponents(config.file_determinism) self.visitor = AMPLRepnVisitor( - self.template, self.subexpression_cache, self.external_functions, self.var_map, @@ -562,18 +670,15 @@ def __init__(self, ostream, rowstream, colstream, config): ) self.next_V_line_id = 0 self.pause_gc = None + self.template = self.visitor.Result.template def __enter__(self): - assert AMPLRepn.ActiveVisitor is None - AMPLRepn.ActiveVisitor = self.visitor self.pause_gc = PauseGC() self.pause_gc.__enter__() return self def __exit__(self, exc_type, exc_value, tb): self.pause_gc.__exit__(exc_type, exc_value, tb) - assert AMPLRepn.ActiveVisitor is self.visitor - AMPLRepn.ActiveVisitor = None def write(self, model): timing_logger = logging.getLogger('pyomo.common.timing.writer') @@ -1111,7 +1216,7 @@ def write(self, model): # Update any eliminated variables to point to the (potentially # scaled) substituted variables for _id, expr_info in list(eliminated_vars.items()): - nl, args, _ = expr_info.compile_repn(visitor) + nl, args, _ = expr_info.compile_repn() for _i in args: # It is possible that the eliminated variable could # reference another variable that is no longer part of @@ -1133,8 +1238,8 @@ def write(self, model): val = 0 else: val = lb if abs(lb) < abs(ub) else ub - eliminated_vars[_i] = AMPLRepn(val, {}, None) - nl_map[_i] = expr_info.compile_repn(visitor)[0] + eliminated_vars[_i] = visitor.Result(val, {}, None) + nl_map[_i] = expr_info.compile_repn()[0] logger.warning( "presolve identified an underdetermined independent " "linear subsystem that was removed from the model. " @@ -1792,7 +1897,7 @@ def _linear_presolve( a = x = None b, _ = var_bounds[_id] logger.debug("NL presolve: bounds fixed %s := %s", var_map[_id], b) - eliminated_vars[_id] = AMPLRepn(b, {}, None) + eliminated_vars[_id] = self.visitor.Result(b, {}, None) nl_map[_id] = template.const % b elif one_var: con_id, info = one_var.popitem() @@ -1994,9 +2099,7 @@ def _resolve_subexpression_args(self, nl, args): if arg in self.var_id_to_nl_map: final_args.append(self.var_id_to_nl_map[arg]) else: - _nl, _ids, _ = self.subexpression_cache[arg][1].compile_repn( - self.visitor - ) + _nl, _ids, _ = self.subexpression_cache[arg][1].compile_repn() final_args.append(self._resolve_subexpression_args(_nl, _ids)) return nl % tuple(final_args) @@ -2070,7 +2173,7 @@ def name(self): class AMPLRepn(object): __slots__ = ('nl', 'mult', 'const', 'linear', 'nonlinear', 'named_exprs') - ActiveVisitor = None + template = text_nl_template def __init__(self, const, linear, nonlinear): self.nl = None @@ -2094,7 +2197,7 @@ def __repr__(self): return str(self) def __eq__(self, other): - return other.__class__ is AMPLRepn and ( + return isinstance(other.__class__, AMPLRepn) and ( self.nl == other.nl and self.mult == other.mult and self.const == other.const @@ -2120,8 +2223,8 @@ def duplicate(self): ans.named_exprs = None if self.named_exprs is None else set(self.named_exprs) return ans - def compile_repn(self, visitor, prefix='', args=None, named_exprs=None): - template = visitor.template + def compile_repn(self, prefix='', args=None, named_exprs=None): + template = self.template if self.mult != 1: if self.mult == -1: prefix += template.negation @@ -2195,7 +2298,7 @@ def compile_repn(self, visitor, prefix='', args=None, named_exprs=None): else: # nterms == 0 return prefix + (template.const % 0), args, named_exprs - def compile_nonlinear_fragment(self, visitor): + def compile_nonlinear_fragment(self): if not self.nonlinear: self.nonlinear = None return @@ -2205,9 +2308,9 @@ def compile_nonlinear_fragment(self, visitor): deque(map(args.extend, map(itemgetter(1), self.nonlinear)), maxlen=0) if nterms > 2: - self.nonlinear = (visitor.template.nary_sum % nterms) + nl_sum, args + self.nonlinear = (self.template.nary_sum % nterms) + nl_sum, args elif nterms == 2: - self.nonlinear = visitor.template.binary_sum + nl_sum, args + self.nonlinear = self.template.binary_sum + nl_sum, args else: # nterms == 1: self.nonlinear = nl_sum, args @@ -2249,9 +2352,7 @@ def append(self, other): # it and append it (this both resolves the # multiplier, and marks the named expression as # having been used) - other = other.compile_repn( - self.ActiveVisitor, '', None, self.named_exprs - ) + other = other.compile_repn('', None, self.named_exprs) nl, nl_args, self.named_exprs = other self.nonlinear.append((nl, nl_args)) return @@ -2272,11 +2373,11 @@ def append(self, other): linear[v] = c * mult if other.nonlinear: if other.nonlinear.__class__ is list: - other.compile_nonlinear_fragment(self.ActiveVisitor) + other.compile_nonlinear_fragment() if mult == -1: - prefix = self.ActiveVisitor.template.negation + prefix = self.template.negation else: - prefix = self.ActiveVisitor.template.multiplier % mult + prefix = self.template.multiplier % mult self.nonlinear.append( (prefix + other.nonlinear[0], other.nonlinear[1]) ) @@ -2316,132 +2417,9 @@ def to_expr(self, var_map): return ans * self.mult -def _create_strict_inequality_map(vars_): - vars_['strict_inequality_map'] = { - True: vars_['less_than'], - False: vars_['less_equal'], - (True, True): (vars_['less_than'], vars_['less_than']), - (True, False): (vars_['less_than'], vars_['less_equal']), - (False, True): (vars_['less_equal'], vars_['less_than']), - (False, False): (vars_['less_equal'], vars_['less_equal']), - } - - -class text_nl_debug_template(object): - unary = { - 'log': 'o43\t#log\n', - 'log10': 'o42\t#log10\n', - 'sin': 'o41\t#sin\n', - 'cos': 'o46\t#cos\n', - 'tan': 'o38\t#tan\n', - 'sinh': 'o40\t#sinh\n', - 'cosh': 'o45\t#cosh\n', - 'tanh': 'o37\t#tanh\n', - 'asin': 'o51\t#asin\n', - 'acos': 'o53\t#acos\n', - 'atan': 'o49\t#atan\n', - 'exp': 'o44\t#exp\n', - 'sqrt': 'o39\t#sqrt\n', - 'asinh': 'o50\t#asinh\n', - 'acosh': 'o52\t#acosh\n', - 'atanh': 'o47\t#atanh\n', - 'ceil': 'o14\t#ceil\n', - 'floor': 'o13\t#floor\n', - } - - binary_sum = 'o0\t#+\n' - product = 'o2\t#*\n' - division = 'o3\t# /\n' - pow = 'o5\t#^\n' - abs = 'o15\t# abs\n' - negation = 'o16\t#-\n' - nary_sum = 'o54\t# sumlist\n%d\t# (n)\n' - exprif = 'o35\t# if\n' - and_expr = 'o21\t# and\n' - less_than = 'o22\t# lt\n' - less_equal = 'o23\t# le\n' - equality = 'o24\t# eq\n' - external_fcn = 'f%d %d%s\n' - # NOTE: to support scaling and substitutions, we do NOT include the - # 'v' or the EOL here: - var = '%s' - const = 'n%r\n' - string = 'h%d:%s\n' - monomial = product + const + var.replace('%', '%%') - multiplier = product + const - - _create_strict_inequality_map(vars()) - - -nl_operators = { - 0: (2, operator.add), - 2: (2, operator.mul), - 3: (2, operator.truediv), - 5: (2, operator.pow), - 15: (1, operator.abs), - 16: (1, operator.neg), - 54: (None, lambda *x: sum(x)), - 35: (3, lambda a, b, c: b if a else c), - 21: (2, operator.and_), - 22: (2, operator.lt), - 23: (2, operator.le), - 24: (2, operator.eq), - 43: (1, math.log), - 42: (1, math.log10), - 41: (1, math.sin), - 46: (1, math.cos), - 38: (1, math.tan), - 40: (1, math.sinh), - 45: (1, math.cosh), - 37: (1, math.tanh), - 51: (1, math.asin), - 53: (1, math.acos), - 49: (1, math.atan), - 44: (1, math.exp), - 39: (1, math.sqrt), - 50: (1, math.asinh), - 52: (1, math.acosh), - 47: (1, math.atanh), - 14: (1, math.ceil), - 13: (1, math.floor), -} - - -def _strip_template_comments(vars_, base_): - vars_['unary'] = { - k: v[: v.find('\t#')] + '\n' if v[-1] == '\n' else '' - for k, v in base_.unary.items() - } - for k, v in base_.__dict__.items(): - if type(v) is str and '\t#' in v: - v_lines = v.split('\n') - for i, l in enumerate(v_lines): - comment_start = l.find('\t#') - if comment_start >= 0: - v_lines[i] = l[:comment_start] - vars_[k] = '\n'.join(v_lines) - - -# The "standard" text mode template is the debugging template with the -# comments removed -class text_nl_template(text_nl_debug_template): - _strip_template_comments(vars(), text_nl_debug_template) - _create_strict_inequality_map(vars()) - - -def node_result_to_amplrepn(data): - if data[0] is _GENERAL: - return data[1] - elif data[0] is _MONOMIAL: - _, v, c = data - if c: - return AMPLRepn(0, {v: c}, None) - else: - return AMPLRepn(0, None, None) - elif data[0] is _CONSTANT: - return AMPLRepn(data[1], None, None) - else: - raise DeveloperError("unknown result type") +class DebugAMPLRepn(AMPLRepn): + __slots__ = () + template = text_nl_debug_template def handle_negation_node(visitor, node, arg1): @@ -2511,11 +2489,11 @@ def handle_product_node(visitor, node, arg1, arg2): _prod = 0 return (_CONSTANT, _prod) return (_CONSTANT, mult * arg2[1]) - nonlin = node_result_to_amplrepn(arg1).compile_repn( - visitor, visitor.template.product + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.product ) - nonlin = node_result_to_amplrepn(arg2).compile_repn(visitor, *nonlin) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_division_node(visitor, node, arg1, arg2): @@ -2540,11 +2518,11 @@ def handle_division_node(visitor, node, arg1, arg2): return _CONSTANT, apply_node_operation(node, (arg1[1], div)) elif arg1[0] is _CONSTANT and not arg1[1]: return _CONSTANT, 0 - nonlin = node_result_to_amplrepn(arg1).compile_repn( - visitor, visitor.template.division + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.division ) - nonlin = node_result_to_amplrepn(arg2).compile_repn(visitor, *nonlin) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_pow_node(visitor, node, arg1, arg2): @@ -2558,25 +2536,25 @@ def handle_pow_node(visitor, node, arg1, arg2): return _CONSTANT, 1 elif arg2[1] == 1: return arg1 - nonlin = node_result_to_amplrepn(arg1).compile_repn(visitor, visitor.template.pow) - nonlin = node_result_to_amplrepn(arg2).compile_repn(visitor, *nonlin) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.pow) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_abs_node(visitor, node, arg1): if arg1[0] is _CONSTANT: return (_CONSTANT, abs(arg1[1])) - nonlin = node_result_to_amplrepn(arg1).compile_repn(visitor, visitor.template.abs) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.abs) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_unary_node(visitor, node, arg1): if arg1[0] is _CONSTANT: return _CONSTANT, apply_node_operation(node, (arg1[1],)) - nonlin = node_result_to_amplrepn(arg1).compile_repn( - visitor, visitor.template.unary[node.name] + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.unary[node.name] ) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_exprif_node(visitor, node, arg1, arg2, arg3): @@ -2585,49 +2563,47 @@ def handle_exprif_node(visitor, node, arg1, arg2, arg3): return arg2 else: return arg3 - nonlin = node_result_to_amplrepn(arg1).compile_repn( - visitor, visitor.template.exprif - ) - nonlin = node_result_to_amplrepn(arg2).compile_repn(visitor, *nonlin) - nonlin = node_result_to_amplrepn(arg3).compile_repn(visitor, *nonlin) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.exprif) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + nonlin = visitor.node_result_to_amplrepn(arg3).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_equality_node(visitor, node, arg1, arg2): if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT: return (_CONSTANT, arg1[1] == arg2[1]) - nonlin = node_result_to_amplrepn(arg1).compile_repn( - visitor, visitor.template.equality + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.equality ) - nonlin = node_result_to_amplrepn(arg2).compile_repn(visitor, *nonlin) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_inequality_node(visitor, node, arg1, arg2): if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT: return (_CONSTANT, node._apply_operation((arg1[1], arg2[1]))) - nonlin = node_result_to_amplrepn(arg1).compile_repn( - visitor, visitor.template.strict_inequality_map[node.strict] + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.strict_inequality_map[node.strict] ) - nonlin = node_result_to_amplrepn(arg2).compile_repn(visitor, *nonlin) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_ranged_inequality_node(visitor, node, arg1, arg2, arg3): if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT and arg3[0] is _CONSTANT: return (_CONSTANT, node._apply_operation((arg1[1], arg2[1], arg3[1]))) op = visitor.template.strict_inequality_map[node.strict] - nl, args, named = node_result_to_amplrepn(arg1).compile_repn( - visitor, visitor.template.and_expr + op[0] + nl, args, named = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.and_expr + op[0] ) - nl2, args2, named = node_result_to_amplrepn(arg2).compile_repn( - visitor, '', None, named + nl2, args2, named = visitor.node_result_to_amplrepn(arg2).compile_repn( + '', None, named ) nl += nl2 + op[1] + nl2 args.extend(args2) args.extend(args2) - nonlin = node_result_to_amplrepn(arg3).compile_repn(visitor, nl, args, named) - return (_GENERAL, AMPLRepn(0, None, nonlin)) + nonlin = visitor.node_result_to_amplrepn(arg3).compile_repn(nl, args, named) + return (_GENERAL, visitor.Result(0, None, nonlin)) def handle_named_expression_node(visitor, node, arg1): @@ -2637,7 +2613,7 @@ def handle_named_expression_node(visitor, node, arg1): # to appear in the 'linear' portion of a constraint / objective # definition. We will return this as a "var" template, but # wrapped in the nonlinear portion of the expression tree. - repn = node_result_to_amplrepn(arg1) + repn = visitor.node_result_to_amplrepn(arg1) # A local copy of the expression source list. This will be updated # later if the same Expression node is encountered in another @@ -2669,7 +2645,7 @@ def handle_named_expression_node(visitor, node, arg1): # original (linear + nonlinear) V line (which will not happen if # the V line is part of a larger linear operator). if repn.nonlinear.__class__ is list: - repn.compile_nonlinear_fragment(visitor) + repn.compile_nonlinear_fragment() if not visitor.use_named_exprs: return _GENERAL, repn.duplicate() @@ -2693,7 +2669,7 @@ def handle_named_expression_node(visitor, node, arg1): # named subexpressions when appropriate. sub_node = NLFragment(repn, node) sub_id = id(sub_node) - sub_repn = AMPLRepn(0, None, None) + sub_repn = visitor.Result(0, None, None) sub_repn.nonlinear = repn.nonlinear sub_repn.nl = (visitor.template.var, (sub_id,)) sub_repn.named_exprs = set(repn.named_exprs) @@ -2801,11 +2777,11 @@ def handle_external_function_node(visitor, node, *args): arg_ids.append(_id) visitor.subexpression_cache[_id] = ( arg, - AMPLRepn( + visitor.Result( 0, None, - node_result_to_amplrepn(arg).compile_repn( - visitor, named_exprs=named_exprs + visitor.node_result_to_amplrepn(arg).compile_repn( + named_exprs=named_exprs ), ), (None, None, True), @@ -2814,7 +2790,7 @@ def handle_external_function_node(visitor, node, *args): named_exprs = None return ( _GENERAL, - AMPLRepn(0, None, (nl + '%s' * len(arg_ids), arg_ids, named_exprs)), + visitor.Result(0, None, (nl + '%s' * len(arg_ids), arg_ids, named_exprs)), ) @@ -2875,7 +2851,7 @@ def _record_var(visitor, var): @staticmethod def _before_string(visitor, child): visitor.encountered_string_arguments = True - ans = AMPLRepn(child, None, None) + ans = visitor.Result(child, None, None) ans.nl = (visitor.template.string % (len(child), child), ()) return False, (_GENERAL, ans) @@ -2996,7 +2972,7 @@ def _before_linear(visitor, child): return True, None if linear: - return False, (_GENERAL, AMPLRepn(const, linear, None)) + return False, (_GENERAL, visitor.Result(const, linear, None)) else: return False, (_CONSTANT, const) @@ -3021,7 +2997,6 @@ def _before_named_expression(visitor, child): class AMPLRepnVisitor(StreamBasedExpressionVisitor): def __init__( self, - template, subexpression_cache, external_functions, var_map, @@ -3031,7 +3006,6 @@ def __init__( sorter, ): super().__init__() - self.template = template self.subexpression_cache = subexpression_cache self.external_functions = external_functions self.active_expression_source = None @@ -3045,6 +3019,12 @@ def __init__( self.evaluate = self._eval_expr_visitor.dfs_postorder_stack self.sorter = sorter + if symbolic_solver_labels: + self.Result = DebugAMPLRepn + else: + self.Result = AMPLRepn + self.template = self.Result.template + def check_constant(self, ans, obj): if ans.__class__ not in native_numeric_types: # None can be returned from uninitialized Var/Param objects @@ -3088,6 +3068,20 @@ def cache_fixed_var(self, _id, child): ) self.fixed_vars[_id] = self.check_constant(child.value, child) + def node_result_to_amplrepn(self, data): + if data[0] is _GENERAL: + return data[1] + elif data[0] is _MONOMIAL: + _, v, c = data + if c: + return self.Result(0, {v: c}, None) + else: + return self.Result(0, None, None) + elif data[0] is _CONSTANT: + return self.Result(data[1], None, None) + else: + raise DeveloperError("unknown result type") + def initializeWalker(self, expr): expr, src, src_idx, self.expression_scaling_factor = expr self.active_expression_source = (src_idx, id(src)) @@ -3103,14 +3097,14 @@ def enterNode(self, node): # SumExpression are potentially large nary operators. Directly # populate the result if node.__class__ in sum_like_expression_types: - data = AMPLRepn(0, {}, None) + data = self.Result(0, {}, None) data.nonlinear = [] return node.args, data else: return node.args, [] def exitNode(self, node, data): - if data.__class__ is AMPLRepn: + if data.__class__ is self.Result: # If the summation resulted in a constant, return the constant if data.linear or data.nonlinear or data.nl: return (_GENERAL, data) @@ -3122,7 +3116,7 @@ def exitNode(self, node, data): return _operator_handles[node.__class__](self, node, *data) def finalizeResult(self, result): - ans = node_result_to_amplrepn(result) + ans = self.node_result_to_amplrepn(result) # Multiply the expression by the scaling factor provided by the caller ans.mult *= self.expression_scaling_factor @@ -3161,7 +3155,7 @@ def finalizeResult(self, result): ans.nl = None if ans.nonlinear.__class__ is list: - ans.compile_nonlinear_fragment(self) + ans.compile_nonlinear_fragment() if not ans.linear: ans.linear = {} diff --git a/pyomo/repn/tests/ampl/test_nlv2.py b/pyomo/repn/tests/ampl/test_nlv2.py index 4d7b5d9ab6c..336e96b93f3 100644 --- a/pyomo/repn/tests/ampl/test_nlv2.py +++ b/pyomo/repn/tests/ampl/test_nlv2.py @@ -64,7 +64,6 @@ def __init__(self, symbolic=False): self.symbolic_solver_labels = symbolic self.visitor = nl_writer.AMPLRepnVisitor( - self.template, self.subexpression_cache, self.external_functions, self.var_map, @@ -75,13 +74,10 @@ def __init__(self, symbolic=False): ) def __enter__(self): - assert nl_writer.AMPLRepn.ActiveVisitor is None - nl_writer.AMPLRepn.ActiveVisitor = self.visitor return self def __exit__(self, exc_type, exc_value, tb): - assert nl_writer.AMPLRepn.ActiveVisitor is self.visitor - nl_writer.AMPLRepn.ActiveVisitor = None + pass class Test_AMPLRepnVisitor(unittest.TestCase): From 2f4bc712885ada01fc73bf58a14e7970d945266e Mon Sep 17 00:00:00 2001 From: John Siirola Date: Thu, 25 Jul 2024 10:31:46 -0600 Subject: [PATCH 111/203] Track changes to AMPLRepnVisitor API --- pyomo/contrib/incidence_analysis/config.py | 3 +-- pyomo/contrib/incidence_analysis/incidence.py | 8 +------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/incidence_analysis/config.py b/pyomo/contrib/incidence_analysis/config.py index 9fac48c8a26..10bfb9133f7 100644 --- a/pyomo/contrib/incidence_analysis/config.py +++ b/pyomo/contrib/incidence_analysis/config.py @@ -14,7 +14,7 @@ import enum from pyomo.common.config import ConfigDict, ConfigValue, InEnum from pyomo.common.modeling import NOTSET -from pyomo.repn.plugins.nl_writer import AMPLRepnVisitor, text_nl_template +from pyomo.repn.plugins.nl_writer import AMPLRepnVisitor from pyomo.repn.util import FileDeterminism, FileDeterminism_to_SortComponents @@ -140,7 +140,6 @@ def get_config_from_kwds(**kwds): export_defined_variables = False sorter = FileDeterminism_to_SortComponents(FileDeterminism.ORDERED) amplvisitor = AMPLRepnVisitor( - text_nl_template, subexpression_cache, external_functions, var_map, diff --git a/pyomo/contrib/incidence_analysis/incidence.py b/pyomo/contrib/incidence_analysis/incidence.py index 030ee2b0f79..48160bc793e 100644 --- a/pyomo/contrib/incidence_analysis/incidence.py +++ b/pyomo/contrib/incidence_analysis/incidence.py @@ -17,7 +17,6 @@ from pyomo.core.expr.numvalue import value as pyo_value from pyomo.repn import generate_standard_repn from pyomo.util.subsystems import TemporarySubsystemManager -from pyomo.repn.plugins.nl_writer import AMPLRepn from pyomo.contrib.incidence_analysis.config import ( IncidenceMethod, get_config_from_kwds, @@ -95,12 +94,7 @@ def _nonlinear_var_id_collector(idlist): yield _id var_map = visitor.var_map - orig_activevisitor = AMPLRepn.ActiveVisitor - AMPLRepn.ActiveVisitor = visitor - try: - repn = visitor.walk_expression((expr, None, 0, 1.0)) - finally: - AMPLRepn.ActiveVisitor = orig_activevisitor + repn = visitor.walk_expression((expr, None, 0, 1.0)) nonlinear_var_id_set = set() unique_nonlinear_var_ids = [] From 89ef9606f6cc66fcd1d39ea54679d3a2597ad8e9 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Thu, 25 Jul 2024 11:40:32 -0600 Subject: [PATCH 112/203] Split the AMPLRepnVisitor from the NLv2 writer module --- pyomo/contrib/incidence_analysis/config.py | 4 +- pyomo/repn/ampl.py | 1261 ++++++++++++++++++++ pyomo/repn/plugins/nl_writer.py | 1257 +------------------ pyomo/repn/tests/ampl/test_ampl_nl.py | 4 +- pyomo/repn/tests/ampl/test_nlv2.py | 5 +- pyomo/repn/tests/nl_diff.py | 4 +- 6 files changed, 1278 insertions(+), 1257 deletions(-) create mode 100644 pyomo/repn/ampl.py diff --git a/pyomo/contrib/incidence_analysis/config.py b/pyomo/contrib/incidence_analysis/config.py index 10bfb9133f7..50ad4e48f3e 100644 --- a/pyomo/contrib/incidence_analysis/config.py +++ b/pyomo/contrib/incidence_analysis/config.py @@ -14,7 +14,7 @@ import enum from pyomo.common.config import ConfigDict, ConfigValue, InEnum from pyomo.common.modeling import NOTSET -from pyomo.repn.plugins.nl_writer import AMPLRepnVisitor +from pyomo.repn.ampl import AMPLRepnVisitor from pyomo.repn.util import FileDeterminism, FileDeterminism_to_SortComponents @@ -33,7 +33,7 @@ class IncidenceMethod(enum.Enum): """ ampl_repn = 3 - """Use ``pyomo.repn.plugins.nl_writer.AMPLRepnVisitor``""" + """Use ``pyomo.repn.ampl.AMPLRepnVisitor``""" class IncidenceOrder(enum.Enum): diff --git a/pyomo/repn/ampl.py b/pyomo/repn/ampl.py new file mode 100644 index 00000000000..7e949e37088 --- /dev/null +++ b/pyomo/repn/ampl.py @@ -0,0 +1,1261 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ + +import ctypes +import math +import operator + +from collections import deque +from operator import itemgetter + +from pyomo.common.deprecation import deprecation_warning +from pyomo.common.errors import DeveloperError, InfeasibleConstraintException, MouseTrap +from pyomo.common.numeric_types import ( + native_complex_types, + native_numeric_types, + native_types, + value, +) + + +from pyomo.core.base import Expression +from pyomo.core.expr import ( + NegationExpression, + ProductExpression, + DivisionExpression, + PowExpression, + AbsExpression, + UnaryFunctionExpression, + MonomialTermExpression, + LinearExpression, + SumExpression, + EqualityExpression, + InequalityExpression, + RangedExpression, + Expr_ifExpression, + ExternalFunctionExpression, +) +from pyomo.core.expr.visitor import StreamBasedExpressionVisitor, _EvaluationVisitor +from pyomo.repn.util import ( + BeforeChildDispatcher, + ExitNodeDispatcher, + ExprType, + InvalidNumber, + apply_node_operation, + complex_number_error, + nan, + sum_like_expression_types, +) + + +_CONSTANT = ExprType.CONSTANT +_MONOMIAL = ExprType.MONOMIAL +_GENERAL = ExprType.GENERAL + +# Feasibility tolerance for trivial (fixed) constraints +TOL = 1e-8 + + +def _create_strict_inequality_map(vars_): + vars_['strict_inequality_map'] = { + True: vars_['less_than'], + False: vars_['less_equal'], + (True, True): (vars_['less_than'], vars_['less_than']), + (True, False): (vars_['less_than'], vars_['less_equal']), + (False, True): (vars_['less_equal'], vars_['less_than']), + (False, False): (vars_['less_equal'], vars_['less_equal']), + } + + +class text_nl_debug_template(object): + unary = { + 'log': 'o43\t#log\n', + 'log10': 'o42\t#log10\n', + 'sin': 'o41\t#sin\n', + 'cos': 'o46\t#cos\n', + 'tan': 'o38\t#tan\n', + 'sinh': 'o40\t#sinh\n', + 'cosh': 'o45\t#cosh\n', + 'tanh': 'o37\t#tanh\n', + 'asin': 'o51\t#asin\n', + 'acos': 'o53\t#acos\n', + 'atan': 'o49\t#atan\n', + 'exp': 'o44\t#exp\n', + 'sqrt': 'o39\t#sqrt\n', + 'asinh': 'o50\t#asinh\n', + 'acosh': 'o52\t#acosh\n', + 'atanh': 'o47\t#atanh\n', + 'ceil': 'o14\t#ceil\n', + 'floor': 'o13\t#floor\n', + } + + binary_sum = 'o0\t#+\n' + product = 'o2\t#*\n' + division = 'o3\t# /\n' + pow = 'o5\t#^\n' + abs = 'o15\t# abs\n' + negation = 'o16\t#-\n' + nary_sum = 'o54\t# sumlist\n%d\t# (n)\n' + exprif = 'o35\t# if\n' + and_expr = 'o21\t# and\n' + less_than = 'o22\t# lt\n' + less_equal = 'o23\t# le\n' + equality = 'o24\t# eq\n' + external_fcn = 'f%d %d%s\n' + # NOTE: to support scaling and substitutions, we do NOT include the + # 'v' or the EOL here: + var = '%s' + const = 'n%r\n' + string = 'h%d:%s\n' + monomial = product + const + var.replace('%', '%%') + multiplier = product + const + + _create_strict_inequality_map(vars()) + + +nl_operators = { + 0: (2, operator.add), + 2: (2, operator.mul), + 3: (2, operator.truediv), + 5: (2, operator.pow), + 15: (1, operator.abs), + 16: (1, operator.neg), + 54: (None, lambda *x: sum(x)), + 35: (3, lambda a, b, c: b if a else c), + 21: (2, operator.and_), + 22: (2, operator.lt), + 23: (2, operator.le), + 24: (2, operator.eq), + 43: (1, math.log), + 42: (1, math.log10), + 41: (1, math.sin), + 46: (1, math.cos), + 38: (1, math.tan), + 40: (1, math.sinh), + 45: (1, math.cosh), + 37: (1, math.tanh), + 51: (1, math.asin), + 53: (1, math.acos), + 49: (1, math.atan), + 44: (1, math.exp), + 39: (1, math.sqrt), + 50: (1, math.asinh), + 52: (1, math.acosh), + 47: (1, math.atanh), + 14: (1, math.ceil), + 13: (1, math.floor), +} + + +def _strip_template_comments(vars_, base_): + vars_['unary'] = { + k: v[: v.find('\t#')] + '\n' if v[-1] == '\n' else '' + for k, v in base_.unary.items() + } + for k, v in base_.__dict__.items(): + if type(v) is str and '\t#' in v: + v_lines = v.split('\n') + for i, l in enumerate(v_lines): + comment_start = l.find('\t#') + if comment_start >= 0: + v_lines[i] = l[:comment_start] + vars_[k] = '\n'.join(v_lines) + + +# The "standard" text mode template is the debugging template with the +# comments removed +class text_nl_template(text_nl_debug_template): + _strip_template_comments(vars(), text_nl_debug_template) + _create_strict_inequality_map(vars()) + + +class NLFragment(object): + """This is a mock "component" for the nl portion of a named Expression. + + It is used internally in the writer when requesting symbolic solver + labels so that we can generate meaningful names for the nonlinear + portion of an Expression component. + + """ + + __slots__ = ('_repn', '_node') + + def __init__(self, repn, node): + self._repn = repn + self._node = node + + @property + def name(self): + return 'nl(' + self._node.name + ')' + + +class AMPLRepn(object): + __slots__ = ('nl', 'mult', 'const', 'linear', 'nonlinear', 'named_exprs') + + template = text_nl_template + + def __init__(self, const, linear, nonlinear): + self.nl = None + self.mult = 1 + self.const = const + self.linear = linear + if nonlinear is None: + self.nonlinear = self.named_exprs = None + else: + nl, nl_args, self.named_exprs = nonlinear + self.nonlinear = nl, nl_args + + def __str__(self): + return ( + f'AMPLRepn(mult={self.mult}, const={self.const}, ' + f'linear={self.linear}, nonlinear={self.nonlinear}, ' + f'nl={self.nl}, named_exprs={self.named_exprs})' + ) + + def __repr__(self): + return str(self) + + def __eq__(self, other): + return isinstance(other.__class__, AMPLRepn) and ( + self.nl == other.nl + and self.mult == other.mult + and self.const == other.const + and self.linear == other.linear + and self.nonlinear == other.nonlinear + and self.named_exprs == other.named_exprs + ) + + def __hash__(self): + # Approximation of the Python default object hash + # (4 LSB are rolled to the MSB to reduce hash collisions) + return id(self) // 16 + ( + (id(self) & 15) << 8 * ctypes.sizeof(ctypes.c_void_p) - 4 + ) + + def duplicate(self): + ans = self.__class__.__new__(self.__class__) + ans.nl = self.nl + ans.mult = self.mult + ans.const = self.const + ans.linear = None if self.linear is None else dict(self.linear) + ans.nonlinear = self.nonlinear + ans.named_exprs = None if self.named_exprs is None else set(self.named_exprs) + return ans + + def compile_repn(self, prefix='', args=None, named_exprs=None): + template = self.template + if self.mult != 1: + if self.mult == -1: + prefix += template.negation + else: + prefix += template.multiplier % self.mult + self.mult = 1 + if self.named_exprs is not None: + if named_exprs is None: + named_exprs = set(self.named_exprs) + else: + named_exprs.update(self.named_exprs) + if self.nl is not None: + # This handles both named subexpressions and embedded + # non-numeric (e.g., string) arguments. + nl, nl_args = self.nl + if prefix: + nl = prefix + nl + if args is not None: + assert args is not nl_args + args.extend(nl_args) + else: + args = list(nl_args) + if nl_args: + # For string arguments, nl_args is an empty tuple and + # self.named_exprs is None. For named subexpressions, + # we are guaranteed that named_exprs is NOT None. We + # need to ensure that the named subexpression that we + # are returning is added to the named_exprs set. + named_exprs.update(nl_args) + return nl, args, named_exprs + + if args is None: + args = [] + if self.linear: + nterms = -len(args) + _v_template = template.var + _m_template = template.monomial + # Because we are compiling this expression (into a NL + # expression), we will go ahead and filter the 0*x terms + # from the expression. Note that the args are accumulated + # by side-effect, which prevents iterating over the linear + # terms twice. + nl_sum = ''.join( + args.append(v) or (_v_template if c == 1 else _m_template % c) + for v, c in self.linear.items() + if c + ) + nterms += len(args) + else: + nterms = 0 + nl_sum = '' + if self.nonlinear: + if self.nonlinear.__class__ is list: + nterms += len(self.nonlinear) + nl_sum += ''.join(map(itemgetter(0), self.nonlinear)) + deque(map(args.extend, map(itemgetter(1), self.nonlinear)), maxlen=0) + else: + nterms += 1 + nl_sum += self.nonlinear[0] + args.extend(self.nonlinear[1]) + if self.const: + nterms += 1 + nl_sum += template.const % self.const + + if nterms > 2: + return (prefix + (template.nary_sum % nterms) + nl_sum, args, named_exprs) + elif nterms == 2: + return prefix + template.binary_sum + nl_sum, args, named_exprs + elif nterms == 1: + return prefix + nl_sum, args, named_exprs + else: # nterms == 0 + return prefix + (template.const % 0), args, named_exprs + + def compile_nonlinear_fragment(self): + if not self.nonlinear: + self.nonlinear = None + return + args = [] + nterms = len(self.nonlinear) + nl_sum = ''.join(map(itemgetter(0), self.nonlinear)) + deque(map(args.extend, map(itemgetter(1), self.nonlinear)), maxlen=0) + + if nterms > 2: + self.nonlinear = (self.template.nary_sum % nterms) + nl_sum, args + elif nterms == 2: + self.nonlinear = self.template.binary_sum + nl_sum, args + else: # nterms == 1: + self.nonlinear = nl_sum, args + + def append(self, other): + """Append a child result from acceptChildResult + + Notes + ----- + This method assumes that the operator was "+". It is implemented + so that we can directly use an AMPLRepn() as a data object in + the expression walker (thereby avoiding the function call for a + custom callback) + + """ + # Note that self.mult will always be 1 (we only call append() + # within a sum, so there is no opportunity for self.mult to + # change). Omitting the assertion for efficiency. + # assert self.mult == 1 + _type = other[0] + if _type is _MONOMIAL: + _, v, c = other + if v in self.linear: + self.linear[v] += c + else: + self.linear[v] = c + elif _type is _GENERAL: + _, other = other + if other.nl is not None and other.nl[1]: + if other.linear: + # This is a named expression with both a linear and + # nonlinear component. We want to merge it with + # this AMPLRepn, preserving the named expression for + # only the nonlinear component (merging the linear + # component with this AMPLRepn). + pass + else: + # This is a nonlinear-only named expression, + # possibly with a multiplier that is not 1. Compile + # it and append it (this both resolves the + # multiplier, and marks the named expression as + # having been used) + other = other.compile_repn('', None, self.named_exprs) + nl, nl_args, self.named_exprs = other + self.nonlinear.append((nl, nl_args)) + return + if other.named_exprs is not None: + if self.named_exprs is None: + self.named_exprs = set(other.named_exprs) + else: + self.named_exprs.update(other.named_exprs) + if other.mult != 1: + mult = other.mult + self.const += mult * other.const + if other.linear: + linear = self.linear + for v, c in other.linear.items(): + if v in linear: + linear[v] += c * mult + else: + linear[v] = c * mult + if other.nonlinear: + if other.nonlinear.__class__ is list: + other.compile_nonlinear_fragment() + if mult == -1: + prefix = self.template.negation + else: + prefix = self.template.multiplier % mult + self.nonlinear.append( + (prefix + other.nonlinear[0], other.nonlinear[1]) + ) + else: + self.const += other.const + if other.linear: + linear = self.linear + for v, c in other.linear.items(): + if v in linear: + linear[v] += c + else: + linear[v] = c + if other.nonlinear: + if other.nonlinear.__class__ is list: + self.nonlinear.extend(other.nonlinear) + else: + self.nonlinear.append(other.nonlinear) + elif _type is _CONSTANT: + self.const += other[1] + + def to_expr(self, var_map): + if self.nl is not None or self.nonlinear is not None: + # TODO: support converting general nonlinear expressiosn + # back to Pyomo expressions. This will require an AMPL + # parser. + raise MouseTrap("Cannot convert nonlinear AMPLRepn to Pyomo Expression") + if self.linear: + # Explicitly generate the LinearExpression. At time of + # writing, this is about 40% faster than standard operator + # overloading for O(1000) element sums + ans = LinearExpression( + [coef * var_map[vid] for vid, coef in self.linear.items()] + ) + ans += self.const + else: + ans = self.const + return ans * self.mult + + +class DebugAMPLRepn(AMPLRepn): + __slots__ = () + template = text_nl_debug_template + + +def handle_negation_node(visitor, node, arg1): + if arg1[0] is _MONOMIAL: + return (_MONOMIAL, arg1[1], -1 * arg1[2]) + elif arg1[0] is _GENERAL: + arg1[1].mult *= -1 + return arg1 + elif arg1[0] is _CONSTANT: + return (_CONSTANT, -1 * arg1[1]) + else: + raise RuntimeError("%s: %s" % (type(arg1[0]), arg1)) + + +def handle_product_node(visitor, node, arg1, arg2): + if arg2[0] is _CONSTANT: + arg2, arg1 = arg1, arg2 + if arg1[0] is _CONSTANT: + mult = arg1[1] + if not mult: + # simplify multiplication by 0 (if arg2 is zero, the + # simplification happens when we evaluate the constant + # below). Note that this is not IEEE-754 compliant, and + # will map 0*inf and 0*nan to 0 (and not to nan). We are + # including this for backwards compatibility with the NLv1 + # writer, but arguably we should deprecate/remove this + # "feature" in the future. + if arg2[0] is _CONSTANT: + _prod = mult * arg2[1] + if _prod: + deprecation_warning( + f"Encountered {mult}*{str(arg2[1])} in expression tree. " + "Mapping the NaN result to 0 for compatibility " + "with the nl_v1 writer. In the future, this NaN " + "will be preserved/emitted to comply with IEEE-754.", + version='6.4.3', + ) + _prod = 0 + return (_CONSTANT, _prod) + return arg1 + if mult == 1: + return arg2 + elif arg2[0] is _MONOMIAL: + if mult != mult: + # This catches mult (i.e., arg1) == nan + return arg1 + return (_MONOMIAL, arg2[1], mult * arg2[2]) + elif arg2[0] is _GENERAL: + if mult != mult: + # This catches mult (i.e., arg1) == nan + return arg1 + arg2[1].mult *= mult + return arg2 + elif arg2[0] is _CONSTANT: + if not arg2[1]: + # Simplify multiplication by 0; see note above about + # IEEE-754 incompatibility. + _prod = mult * arg2[1] + if _prod: + deprecation_warning( + f"Encountered {str(mult)}*{arg2[1]} in expression tree. " + "Mapping the NaN result to 0 for compatibility " + "with the nl_v1 writer. In the future, this NaN " + "will be preserved/emitted to comply with IEEE-754.", + version='6.4.3', + ) + _prod = 0 + return (_CONSTANT, _prod) + return (_CONSTANT, mult * arg2[1]) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.product + ) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_division_node(visitor, node, arg1, arg2): + if arg2[0] is _CONSTANT: + div = arg2[1] + if div == 1: + return arg1 + if arg1[0] is _MONOMIAL: + tmp = apply_node_operation(node, (arg1[2], div)) + if tmp != tmp: + # This catches if the coefficient division results in nan + return _CONSTANT, tmp + return (_MONOMIAL, arg1[1], tmp) + elif arg1[0] is _GENERAL: + tmp = apply_node_operation(node, (arg1[1].mult, div)) + if tmp != tmp: + # This catches if the multiplier division results in nan + return _CONSTANT, tmp + arg1[1].mult = tmp + return arg1 + elif arg1[0] is _CONSTANT: + return _CONSTANT, apply_node_operation(node, (arg1[1], div)) + elif arg1[0] is _CONSTANT and not arg1[1]: + return _CONSTANT, 0 + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.division + ) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_pow_node(visitor, node, arg1, arg2): + if arg2[0] is _CONSTANT: + if arg1[0] is _CONSTANT: + ans = apply_node_operation(node, (arg1[1], arg2[1])) + if ans.__class__ in native_complex_types: + ans = complex_number_error(ans, visitor, node) + return _CONSTANT, ans + elif not arg2[1]: + return _CONSTANT, 1 + elif arg2[1] == 1: + return arg1 + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.pow) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_abs_node(visitor, node, arg1): + if arg1[0] is _CONSTANT: + return (_CONSTANT, abs(arg1[1])) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.abs) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_unary_node(visitor, node, arg1): + if arg1[0] is _CONSTANT: + return _CONSTANT, apply_node_operation(node, (arg1[1],)) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.unary[node.name] + ) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_exprif_node(visitor, node, arg1, arg2, arg3): + if arg1[0] is _CONSTANT: + if arg1[1]: + return arg2 + else: + return arg3 + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.exprif) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + nonlin = visitor.node_result_to_amplrepn(arg3).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_equality_node(visitor, node, arg1, arg2): + if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT: + return (_CONSTANT, arg1[1] == arg2[1]) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.equality + ) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_inequality_node(visitor, node, arg1, arg2): + if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT: + return (_CONSTANT, node._apply_operation((arg1[1], arg2[1]))) + nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.strict_inequality_map[node.strict] + ) + nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_ranged_inequality_node(visitor, node, arg1, arg2, arg3): + if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT and arg3[0] is _CONSTANT: + return (_CONSTANT, node._apply_operation((arg1[1], arg2[1], arg3[1]))) + op = visitor.template.strict_inequality_map[node.strict] + nl, args, named = visitor.node_result_to_amplrepn(arg1).compile_repn( + visitor.template.and_expr + op[0] + ) + nl2, args2, named = visitor.node_result_to_amplrepn(arg2).compile_repn( + '', None, named + ) + nl += nl2 + op[1] + nl2 + args.extend(args2) + args.extend(args2) + nonlin = visitor.node_result_to_amplrepn(arg3).compile_repn(nl, args, named) + return (_GENERAL, visitor.Result(0, None, nonlin)) + + +def handle_named_expression_node(visitor, node, arg1): + _id = id(node) + # Note that while named subexpressions ('defined variables' in the + # ASL NL file vernacular) look like variables, they are not allowed + # to appear in the 'linear' portion of a constraint / objective + # definition. We will return this as a "var" template, but + # wrapped in the nonlinear portion of the expression tree. + repn = visitor.node_result_to_amplrepn(arg1) + + # A local copy of the expression source list. This will be updated + # later if the same Expression node is encountered in another + # expression tree. + # + # This is a 3-tuple [con_id, obj_id, substitute_expression]. If the + # expression is used by more than 1 constraint / objective, then the + # id is set to 0. If it is not used by any, then it is None. + # substitute_expression is a bool indicating if this named + # subexpression tree should be directly substituted into any + # expression tree that references this node (i.e., do NOT emit the V + # line). + expression_source = [None, None, False] + # Record this common expression + visitor.subexpression_cache[_id] = ( + # 0: the "component" that generated this expression ID + node, + # 1: the common subexpression (to be written out) + repn, + # 2: the source usage information for this subexpression: + # [(con_id, obj_id, substitute); see above] + expression_source, + ) + + # As we will eventually need the compiled form of any nonlinear + # expression, we will go ahead and compile it here. We do not + # do the same for the linear component as we will only need the + # linear component compiled to a dict if we are emitting the + # original (linear + nonlinear) V line (which will not happen if + # the V line is part of a larger linear operator). + if repn.nonlinear.__class__ is list: + repn.compile_nonlinear_fragment() + + if not visitor.use_named_exprs: + return _GENERAL, repn.duplicate() + + mult, repn.mult = repn.mult, 1 + if repn.named_exprs is None: + repn.named_exprs = set() + + # When converting this shared subexpression to a (nonlinear) + # node, we want to just reference this subexpression: + repn.nl = (visitor.template.var, (_id,)) + + if repn.nonlinear: + if repn.linear: + # If this expression has both linear and nonlinear + # components, we will follow the ASL convention and break + # the named subexpression into two named subexpressions: one + # that is only the nonlinear component and one that has the + # const/linear component (and references the first). This + # will allow us to propagate linear coefficients up from + # named subexpressions when appropriate. + sub_node = NLFragment(repn, node) + sub_id = id(sub_node) + sub_repn = visitor.Result(0, None, None) + sub_repn.nonlinear = repn.nonlinear + sub_repn.nl = (visitor.template.var, (sub_id,)) + sub_repn.named_exprs = set(repn.named_exprs) + + repn.named_exprs.add(sub_id) + repn.nonlinear = sub_repn.nl + + # See above for the meaning of this source information + nl_info = list(expression_source) + visitor.subexpression_cache[sub_id] = (sub_node, sub_repn, nl_info) + # It is important that the NL subexpression comes before the + # main named expression: re-insert the original named + # expression (so that the nonlinear sub_node comes first + # when iterating over subexpression_cache) + visitor.subexpression_cache[_id] = visitor.subexpression_cache.pop(_id) + else: + nl_info = expression_source + else: + repn.nonlinear = None + if repn.linear: + if ( + not repn.const + and len(repn.linear) == 1 + and next(iter(repn.linear.values())) == 1 + ): + # This Expression holds only a variable (multiplied by + # 1). Do not emit this as a named variable and instead + # just inject the variable where this expression is + # used. + repn.nl = None + expression_source[2] = True + else: + # This Expression holds only a constant. Do not emit this + # as a named variable and instead just inject the constant + # where this expression is used. + repn.nl = None + expression_source[2] = True + + if mult != 1: + repn.const *= mult + if repn.linear: + _lin = repn.linear + for v in repn.linear: + _lin[v] *= mult + if repn.nonlinear: + if mult == -1: + prefix = visitor.template.negation + else: + prefix = visitor.template.multiplier % mult + repn.nonlinear = prefix + repn.nonlinear[0], repn.nonlinear[1] + + if expression_source[2]: + if repn.linear: + assert len(repn.linear) == 1 and not repn.const + return (_MONOMIAL,) + next(iter(repn.linear.items())) + else: + return (_CONSTANT, repn.const) + + return (_GENERAL, repn.duplicate()) + + +def handle_external_function_node(visitor, node, *args): + func = node._fcn._function + # There is a special case for external functions: these are the only + # expressions that can accept string arguments. As we currently pass + # these as 'precompiled' GENERAL AMPLRepns, the normal trap for + # constant subexpressions will miss string arguments. We will catch + # that case here by looking for NL fragments with no variable + # references. Note that the NL fragment is NOT the raw string + # argument that we want to evaluate: the raw string is in the + # `const` field. + if all( + arg[0] is _CONSTANT or (arg[0] is _GENERAL and arg[1].nl and not arg[1].nl[1]) + for arg in args + ): + arg_list = [arg[1] if arg[0] is _CONSTANT else arg[1].const for arg in args] + return _CONSTANT, apply_node_operation(node, arg_list) + if func in visitor.external_functions: + if node._fcn._library != visitor.external_functions[func][1]._library: + raise RuntimeError( + "The same external function name (%s) is associated " + "with two different libraries (%s through %s, and %s " + "through %s). The ASL solver will fail to link " + "correctly." + % ( + func, + visitor.external_functions[func]._library, + visitor.external_functions[func]._library.name, + node._fcn._library, + node._fcn.name, + ) + ) + else: + visitor.external_functions[func] = (len(visitor.external_functions), node._fcn) + comment = f'\t#{node.local_name}' if visitor.symbolic_solver_labels else '' + nl = visitor.template.external_fcn % ( + visitor.external_functions[func][0], + len(args), + comment, + ) + arg_ids = [] + named_exprs = set() + for arg in args: + _id = id(arg) + arg_ids.append(_id) + visitor.subexpression_cache[_id] = ( + arg, + visitor.Result( + 0, + None, + visitor.node_result_to_amplrepn(arg).compile_repn( + named_exprs=named_exprs + ), + ), + (None, None, True), + ) + if not named_exprs: + named_exprs = None + return ( + _GENERAL, + visitor.Result(0, None, (nl + '%s' * len(arg_ids), arg_ids, named_exprs)), + ) + + +_operator_handles = ExitNodeDispatcher( + { + NegationExpression: handle_negation_node, + ProductExpression: handle_product_node, + DivisionExpression: handle_division_node, + PowExpression: handle_pow_node, + AbsExpression: handle_abs_node, + UnaryFunctionExpression: handle_unary_node, + Expr_ifExpression: handle_exprif_node, + EqualityExpression: handle_equality_node, + InequalityExpression: handle_inequality_node, + RangedExpression: handle_ranged_inequality_node, + Expression: handle_named_expression_node, + ExternalFunctionExpression: handle_external_function_node, + # These are handled explicitly in beforeChild(): + # LinearExpression: handle_linear_expression, + # SumExpression: handle_sum_expression, + # + # Note: MonomialTermExpression is only hit when processing NPV + # subexpressions that raise errors (e.g., log(0) * m.x), so no + # special processing is needed [it is just a product expression] + MonomialTermExpression: handle_product_node, + } +) + + +class AMPLBeforeChildDispatcher(BeforeChildDispatcher): + __slots__ = () + + def __init__(self): + # Special linear / summation expressions + self[MonomialTermExpression] = self._before_monomial + self[LinearExpression] = self._before_linear + self[SumExpression] = self._before_general_expression + + @staticmethod + def _record_var(visitor, var): + # We always add all indices to the var_map at once so that + # we can honor deterministic ordering of unordered sets + # (because the user could have iterated over an unordered + # set when constructing an expression, thereby altering the + # order in which we would see the variables) + vm = visitor.var_map + try: + _iter = var.parent_component().values(visitor.sorter) + except AttributeError: + # Note that this only works for the AML, as kernel does not + # provide a parent_component() + _iter = (var,) + for v in _iter: + if v.fixed: + continue + vm[id(v)] = v + + @staticmethod + def _before_string(visitor, child): + visitor.encountered_string_arguments = True + ans = visitor.Result(child, None, None) + ans.nl = (visitor.template.string % (len(child), child), ()) + return False, (_GENERAL, ans) + + @staticmethod + def _before_var(visitor, child): + _id = id(child) + if _id not in visitor.var_map: + if child.fixed: + if _id not in visitor.fixed_vars: + visitor.cache_fixed_var(_id, child) + return False, (_CONSTANT, visitor.fixed_vars[_id]) + _before_child_handlers._record_var(visitor, child) + return False, (_MONOMIAL, _id, 1) + + @staticmethod + def _before_monomial(visitor, child): + # + # The following are performance optimizations for common + # situations (Monomial terms and Linear expressions) + # + arg1, arg2 = child._args_ + if arg1.__class__ not in native_types: + try: + arg1 = visitor.check_constant(visitor.evaluate(arg1), arg1) + except (ValueError, ArithmeticError): + return True, None + + # Trap multiplication by 0 and nan. + if not arg1: + if arg2.fixed: + _id = id(arg2) + if _id not in visitor.fixed_vars: + visitor.cache_fixed_var(id(arg2), arg2) + arg2 = visitor.fixed_vars[_id] + if arg2 != arg2: + deprecation_warning( + f"Encountered {arg1}*{arg2} in expression tree. " + "Mapping the NaN result to 0 for compatibility " + "with the nl_v1 writer. In the future, this NaN " + "will be preserved/emitted to comply with IEEE-754.", + version='6.4.3', + ) + return False, (_CONSTANT, arg1) + + _id = id(arg2) + if _id not in visitor.var_map: + if arg2.fixed: + if _id not in visitor.fixed_vars: + visitor.cache_fixed_var(_id, arg2) + return False, (_CONSTANT, arg1 * visitor.fixed_vars[_id]) + _before_child_handlers._record_var(visitor, arg2) + return False, (_MONOMIAL, _id, arg1) + + @staticmethod + def _before_linear(visitor, child): + # Because we are going to modify the LinearExpression in this + # walker, we need to make a copy of the arg list from the original + # expression tree. + var_map = visitor.var_map + const = 0 + linear = {} + for arg in child.args: + if arg.__class__ is MonomialTermExpression: + arg1, arg2 = arg._args_ + if arg1.__class__ not in native_types: + try: + arg1 = visitor.check_constant(visitor.evaluate(arg1), arg1) + except (ValueError, ArithmeticError): + return True, None + + # Trap multiplication by 0 and nan. + if not arg1: + if arg2.fixed: + arg2 = visitor.check_constant(arg2.value, arg2) + if arg2 != arg2: + deprecation_warning( + f"Encountered {arg1}*{str(arg2.value)} in expression " + "tree. Mapping the NaN result to 0 for compatibility " + "with the nl_v1 writer. In the future, this NaN " + "will be preserved/emitted to comply with IEEE-754.", + version='6.4.3', + ) + continue + + _id = id(arg2) + if _id not in var_map: + if arg2.fixed: + if _id not in visitor.fixed_vars: + visitor.cache_fixed_var(_id, arg2) + const += arg1 * visitor.fixed_vars[_id] + continue + _before_child_handlers._record_var(visitor, arg2) + linear[_id] = arg1 + elif _id in linear: + linear[_id] += arg1 + else: + linear[_id] = arg1 + elif arg.__class__ in native_types: + const += arg + elif arg.is_variable_type(): + _id = id(arg) + if _id not in var_map: + if arg.fixed: + if _id not in visitor.fixed_vars: + visitor.cache_fixed_var(_id, arg) + const += visitor.fixed_vars[_id] + continue + _before_child_handlers._record_var(visitor, arg) + linear[_id] = 1 + elif _id in linear: + linear[_id] += 1 + else: + linear[_id] = 1 + else: + try: + const += visitor.check_constant(visitor.evaluate(arg), arg) + except (ValueError, ArithmeticError): + return True, None + + if linear: + return False, (_GENERAL, visitor.Result(const, linear, None)) + else: + return False, (_CONSTANT, const) + + @staticmethod + def _before_named_expression(visitor, child): + _id = id(child) + if _id in visitor.subexpression_cache: + obj, repn, info = visitor.subexpression_cache[_id] + if info[2]: + if repn.linear: + return False, (_MONOMIAL, next(iter(repn.linear)), 1) + else: + return False, (_CONSTANT, repn.const) + return False, (_GENERAL, repn.duplicate()) + else: + return True, None + + +_before_child_handlers = AMPLBeforeChildDispatcher() + + +class AMPLRepnVisitor(StreamBasedExpressionVisitor): + def __init__( + self, + subexpression_cache, + external_functions, + var_map, + used_named_expressions, + symbolic_solver_labels, + use_named_exprs, + sorter, + ): + super().__init__() + self.subexpression_cache = subexpression_cache + self.external_functions = external_functions + self.active_expression_source = None + self.var_map = var_map + self.used_named_expressions = used_named_expressions + self.symbolic_solver_labels = symbolic_solver_labels + self.use_named_exprs = use_named_exprs + self.encountered_string_arguments = False + self.fixed_vars = {} + self._eval_expr_visitor = _EvaluationVisitor(True) + self.evaluate = self._eval_expr_visitor.dfs_postorder_stack + self.sorter = sorter + + if symbolic_solver_labels: + self.Result = DebugAMPLRepn + else: + self.Result = AMPLRepn + self.template = self.Result.template + + def check_constant(self, ans, obj): + if ans.__class__ not in native_numeric_types: + # None can be returned from uninitialized Var/Param objects + if ans is None: + return InvalidNumber( + None, f"'{obj}' evaluated to a nonnumeric value '{ans}'" + ) + if ans.__class__ is InvalidNumber: + return ans + elif ans.__class__ in native_complex_types: + return complex_number_error(ans, self, obj) + else: + # It is possible to get other non-numeric types. Most + # common are bool and 1-element numpy.array(). We will + # attempt to convert the value to a float before + # proceeding. + # + # TODO: we should check bool and warn/error (while bool is + # convertible to float in Python, they have very + # different semantic meanings in Pyomo). + try: + ans = float(ans) + except: + return InvalidNumber( + ans, f"'{obj}' evaluated to a nonnumeric value '{ans}'" + ) + if ans != ans: + return InvalidNumber( + nan, f"'{obj}' evaluated to a nonnumeric value '{ans}'" + ) + return ans + + def cache_fixed_var(self, _id, child): + val = self.check_constant(child.value, child) + lb, ub = child.bounds + if (lb is not None and lb - val > TOL) or (ub is not None and ub - val < -TOL): + raise InfeasibleConstraintException( + "model contains a trivially infeasible " + f"variable '{child.name}' (fixed value " + f"{val} outside bounds [{lb}, {ub}])." + ) + self.fixed_vars[_id] = self.check_constant(child.value, child) + + def node_result_to_amplrepn(self, data): + if data[0] is _GENERAL: + return data[1] + elif data[0] is _MONOMIAL: + _, v, c = data + if c: + return self.Result(0, {v: c}, None) + else: + return self.Result(0, None, None) + elif data[0] is _CONSTANT: + return self.Result(data[1], None, None) + else: + raise DeveloperError("unknown result type") + + def initializeWalker(self, expr): + expr, src, src_idx, self.expression_scaling_factor = expr + self.active_expression_source = (src_idx, id(src)) + walk, result = self.beforeChild(None, expr, 0) + if not walk: + return False, self.finalizeResult(result) + return True, expr + + def beforeChild(self, node, child, child_idx): + return _before_child_handlers[child.__class__](self, child) + + def enterNode(self, node): + # SumExpression are potentially large nary operators. Directly + # populate the result + if node.__class__ in sum_like_expression_types: + data = self.Result(0, {}, None) + data.nonlinear = [] + return node.args, data + else: + return node.args, [] + + def exitNode(self, node, data): + if data.__class__ is self.Result: + # If the summation resulted in a constant, return the constant + if data.linear or data.nonlinear or data.nl: + return (_GENERAL, data) + else: + return (_CONSTANT, data.const) + # + # General expressions... + # + return _operator_handles[node.__class__](self, node, *data) + + def finalizeResult(self, result): + ans = self.node_result_to_amplrepn(result) + + # Multiply the expression by the scaling factor provided by the caller + ans.mult *= self.expression_scaling_factor + + # If this was a nonlinear named expression, and that expression + # has no linear portion, then we will directly use this as a + # named expression. We need to mark that the expression was + # used and return it as a simple nonlinear expression pointing + # to this named expression. In all other cases, we will return + # the processed representation (which will reference the + # nonlinear-only named subexpression - if it exists - but not + # this outer named expression). This prevents accidentally + # recharacterizing variables that only appear linearly as + # nonlinear variables. + if ans.nl is not None: + if not ans.nl[1]: + raise ValueError("Numeric expression resolved to a string constant") + # This *is* a named subexpression. If there is no linear + # component, then replace this expression with the named + # expression. The mult will be handled later. We know that + # the const is built into the nonlinear expression, because + # it cannot be changed "in place" (only through addition, + # which would have "cleared" the nl attribute) + if not ans.linear: + ans.named_exprs.update(ans.nl[1]) + ans.nonlinear = ans.nl + ans.const = 0 + else: + # This named expression has both a linear and a + # nonlinear component, and possibly a multiplier and + # constant. We will not include this named expression + # and instead will expose the components so that linear + # variables are not accidentally re-characterized as + # nonlinear. + pass + ans.nl = None + + if ans.nonlinear.__class__ is list: + ans.compile_nonlinear_fragment() + + if not ans.linear: + ans.linear = {} + if ans.mult != 1: + linear = ans.linear + mult, ans.mult = ans.mult, 1 + ans.const *= mult + if linear: + for k in linear: + linear[k] *= mult + if ans.nonlinear: + if mult == -1: + prefix = self.template.negation + else: + prefix = self.template.multiplier % mult + ans.nonlinear = prefix + ans.nonlinear[0], ans.nonlinear[1] + # + self.active_expression_source = None + return ans + + +def evaluate_ampl_nl_expression(nl, external_functions): + expr = nl.splitlines() + stack = [] + while expr: + line = expr.pop() + tokens = line.split() + # remove tokens after the first comment + for i, t in enumerate(tokens): + if t.startswith('#'): + tokens = tokens[:i] + break + if len(tokens) != 1: + # skip blank lines + if not tokens: + continue + if tokens[0][0] == 'f': + # external function + fid, nargs = tokens + fid = int(fid[1:]) + nargs = int(nargs) + fcn_id, ef = external_functions[fid] + assert fid == fcn_id + stack.append(ef.evaluate(tuple(stack.pop() for i in range(nargs)))) + continue + raise DeveloperError( + f"Unsupported line format _evaluate_constant_nl() " + f"(we expect each line to contain a single token): '{line}'" + ) + term = tokens[0] + # the "command" can be determined by the first character on the line + cmd = term[0] + # Note that we will unpack the line into the expected number of + # explicit arguments as a form of error checking + if cmd == 'n': + # numeric constant + stack.append(float(term[1:])) + elif cmd == 'o': + # operator + nargs, fcn = nl_operators[int(term[1:])] + if nargs is None: + nargs = int(stack.pop()) + stack.append(fcn(*(stack.pop() for i in range(nargs)))) + elif cmd in '1234567890': + # this is either a single int (e.g., the nargs in a nary + # sum) or a string argument. Preserve it as-is until later + # when we know which we are expecting. + stack.append(term) + elif cmd == 'h': + stack.append(term.split(':', 1)[1]) + else: + raise DeveloperError( + f"Unsupported NL operator in _evaluate_constant_nl(): '{line}'" + ) + assert len(stack) == 1 + return stack[0] diff --git a/pyomo/repn/plugins/nl_writer.py b/pyomo/repn/plugins/nl_writer.py index bc0c44c93b6..2e5a5484657 100644 --- a/pyomo/repn/plugins/nl_writer.py +++ b/pyomo/repn/plugins/nl_writer.py @@ -9,52 +9,26 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -import ctypes import logging -import math -import operator import os -from collections import deque, defaultdict, namedtuple +from collections import defaultdict, namedtuple from contextlib import nullcontext -from itertools import filterfalse, product, chain +from itertools import filterfalse, product from math import log10 as _log10 -from operator import itemgetter, attrgetter, setitem +from operator import itemgetter, attrgetter from pyomo.common.collections import ComponentMap, ComponentSet from pyomo.common.config import ( - ConfigBlock, + ConfigDict, ConfigValue, InEnum, document_kwargs_from_configdict, ) -from pyomo.common.deprecation import deprecation_warning -from pyomo.common.errors import DeveloperError, InfeasibleConstraintException, MouseTrap +from pyomo.common.deprecation import relocated_module_attribute +from pyomo.common.errors import DeveloperError, InfeasibleConstraintException from pyomo.common.gc_manager import PauseGC -from pyomo.common.numeric_types import ( - native_complex_types, - native_numeric_types, - native_types, - value, -) from pyomo.common.timing import TicTocTimer -from pyomo.core.expr import ( - NegationExpression, - ProductExpression, - DivisionExpression, - PowExpression, - AbsExpression, - UnaryFunctionExpression, - MonomialTermExpression, - LinearExpression, - SumExpression, - EqualityExpression, - InequalityExpression, - RangedExpression, - Expr_ifExpression, - ExternalFunctionExpression, -) -from pyomo.core.expr.visitor import StreamBasedExpressionVisitor, _EvaluationVisitor from pyomo.core.base import ( Block, Objective, @@ -80,21 +54,14 @@ from pyomo.core.pyomoobject import PyomoObject from pyomo.opt import WriterFactory +from pyomo.repn.ampl import AMPLRepnVisitor, evaluate_ampl_nl_expression, TOL from pyomo.repn.util import ( - BeforeChildDispatcher, - ExitNodeDispatcher, - ExprType, FileDeterminism, FileDeterminism_to_SortComponents, - InvalidNumber, - apply_node_operation, categorize_valid_components, - complex_number_error, initialize_var_map_from_column_order, int_float, ordered_active_constraints, - nan, - sum_like_expression_types, ) from pyomo.repn.plugins.ampl.ampl_ import set_pyomo_amplfunc_env @@ -107,134 +74,17 @@ logger = logging.getLogger(__name__) -# Feasibility tolerance for trivial (fixed) constraints -TOL = 1e-8 +relocated_module_attribute('AMPLRepn', 'pyomo.repn.ampl.AMPLRepn', version='6.4.0.dev0') + inf = float('inf') minus_inf = -inf allowable_binary_var_bounds = {(0, 0), (0, 1), (1, 1)} -_CONSTANT = ExprType.CONSTANT -_MONOMIAL = ExprType.MONOMIAL -_GENERAL = ExprType.GENERAL - ScalingFactors = namedtuple( 'ScalingFactors', ['variables', 'constraints', 'objectives'] ) -def _create_strict_inequality_map(vars_): - vars_['strict_inequality_map'] = { - True: vars_['less_than'], - False: vars_['less_equal'], - (True, True): (vars_['less_than'], vars_['less_than']), - (True, False): (vars_['less_than'], vars_['less_equal']), - (False, True): (vars_['less_equal'], vars_['less_than']), - (False, False): (vars_['less_equal'], vars_['less_equal']), - } - - -class text_nl_debug_template(object): - unary = { - 'log': 'o43\t#log\n', - 'log10': 'o42\t#log10\n', - 'sin': 'o41\t#sin\n', - 'cos': 'o46\t#cos\n', - 'tan': 'o38\t#tan\n', - 'sinh': 'o40\t#sinh\n', - 'cosh': 'o45\t#cosh\n', - 'tanh': 'o37\t#tanh\n', - 'asin': 'o51\t#asin\n', - 'acos': 'o53\t#acos\n', - 'atan': 'o49\t#atan\n', - 'exp': 'o44\t#exp\n', - 'sqrt': 'o39\t#sqrt\n', - 'asinh': 'o50\t#asinh\n', - 'acosh': 'o52\t#acosh\n', - 'atanh': 'o47\t#atanh\n', - 'ceil': 'o14\t#ceil\n', - 'floor': 'o13\t#floor\n', - } - - binary_sum = 'o0\t#+\n' - product = 'o2\t#*\n' - division = 'o3\t# /\n' - pow = 'o5\t#^\n' - abs = 'o15\t# abs\n' - negation = 'o16\t#-\n' - nary_sum = 'o54\t# sumlist\n%d\t# (n)\n' - exprif = 'o35\t# if\n' - and_expr = 'o21\t# and\n' - less_than = 'o22\t# lt\n' - less_equal = 'o23\t# le\n' - equality = 'o24\t# eq\n' - external_fcn = 'f%d %d%s\n' - # NOTE: to support scaling and substitutions, we do NOT include the - # 'v' or the EOL here: - var = '%s' - const = 'n%r\n' - string = 'h%d:%s\n' - monomial = product + const + var.replace('%', '%%') - multiplier = product + const - - _create_strict_inequality_map(vars()) - - -nl_operators = { - 0: (2, operator.add), - 2: (2, operator.mul), - 3: (2, operator.truediv), - 5: (2, operator.pow), - 15: (1, operator.abs), - 16: (1, operator.neg), - 54: (None, lambda *x: sum(x)), - 35: (3, lambda a, b, c: b if a else c), - 21: (2, operator.and_), - 22: (2, operator.lt), - 23: (2, operator.le), - 24: (2, operator.eq), - 43: (1, math.log), - 42: (1, math.log10), - 41: (1, math.sin), - 46: (1, math.cos), - 38: (1, math.tan), - 40: (1, math.sinh), - 45: (1, math.cosh), - 37: (1, math.tanh), - 51: (1, math.asin), - 53: (1, math.acos), - 49: (1, math.atan), - 44: (1, math.exp), - 39: (1, math.sqrt), - 50: (1, math.asinh), - 52: (1, math.acosh), - 47: (1, math.atanh), - 14: (1, math.ceil), - 13: (1, math.floor), -} - - -def _strip_template_comments(vars_, base_): - vars_['unary'] = { - k: v[: v.find('\t#')] + '\n' if v[-1] == '\n' else '' - for k, v in base_.unary.items() - } - for k, v in base_.__dict__.items(): - if type(v) is str and '\t#' in v: - v_lines = v.split('\n') - for i, l in enumerate(v_lines): - comment_start = l.find('\t#') - if comment_start >= 0: - v_lines[i] = l[:comment_start] - vars_[k] = '\n'.join(v_lines) - - -# The "standard" text mode template is the debugging template with the -# comments removed -class text_nl_template(text_nl_debug_template): - _strip_template_comments(vars(), text_nl_debug_template) - _create_strict_inequality_map(vars()) - - # TODO: make a proper base class class NLWriterInfo(object): """Return type for NLWriter.write() @@ -314,7 +164,7 @@ def __init__( @WriterFactory.register('nl_v2', 'Generate the corresponding AMPL NL file (version 2).') class NLWriter(object): - CONFIG = ConfigBlock('nlwriter') + CONFIG = ConfigDict('nlwriter') CONFIG.declare( 'show_section_timing', ConfigValue( @@ -894,7 +744,7 @@ def write(self, model): if any(vid not in nl_map for vid in args): constraints.append(info) continue - expr_info.const += _evaluate_constant_nl( + expr_info.const += evaluate_ampl_nl_expression( nl % tuple(nl_map[i] for i in args), self.external_functions ) expr_info.nonlinear = None @@ -2068,7 +1918,7 @@ def _linear_presolve( # variables. So, we will fall back on parsing the (now # constant) nonlinear fragment and evaluating it. info.nonlinear = None - info.const += _evaluate_constant_nl( + info.const += evaluate_ampl_nl_expression( nl % tuple(nl_map[i] for i in args), self.external_functions ) if not info.linear: @@ -2149,1086 +1999,3 @@ def _write_v_line(self, expr_id, k): self._write_nl_expression(info[1], True) self.next_V_line_id += 1 - -class NLFragment(object): - """This is a mock "component" for the nl portion of a named Expression. - - It is used internally in the writer when requesting symbolic solver - labels so that we can generate meaningful names for the nonlinear - portion of an Expression component. - - """ - - __slots__ = ('_repn', '_node') - - def __init__(self, repn, node): - self._repn = repn - self._node = node - - @property - def name(self): - return 'nl(' + self._node.name + ')' - - -class AMPLRepn(object): - __slots__ = ('nl', 'mult', 'const', 'linear', 'nonlinear', 'named_exprs') - - template = text_nl_template - - def __init__(self, const, linear, nonlinear): - self.nl = None - self.mult = 1 - self.const = const - self.linear = linear - if nonlinear is None: - self.nonlinear = self.named_exprs = None - else: - nl, nl_args, self.named_exprs = nonlinear - self.nonlinear = nl, nl_args - - def __str__(self): - return ( - f'AMPLRepn(mult={self.mult}, const={self.const}, ' - f'linear={self.linear}, nonlinear={self.nonlinear}, ' - f'nl={self.nl}, named_exprs={self.named_exprs})' - ) - - def __repr__(self): - return str(self) - - def __eq__(self, other): - return isinstance(other.__class__, AMPLRepn) and ( - self.nl == other.nl - and self.mult == other.mult - and self.const == other.const - and self.linear == other.linear - and self.nonlinear == other.nonlinear - and self.named_exprs == other.named_exprs - ) - - def __hash__(self): - # Approximation of the Python default object hash - # (4 LSB are rolled to the MSB to reduce hash collisions) - return id(self) // 16 + ( - (id(self) & 15) << 8 * ctypes.sizeof(ctypes.c_void_p) - 4 - ) - - def duplicate(self): - ans = self.__class__.__new__(self.__class__) - ans.nl = self.nl - ans.mult = self.mult - ans.const = self.const - ans.linear = None if self.linear is None else dict(self.linear) - ans.nonlinear = self.nonlinear - ans.named_exprs = None if self.named_exprs is None else set(self.named_exprs) - return ans - - def compile_repn(self, prefix='', args=None, named_exprs=None): - template = self.template - if self.mult != 1: - if self.mult == -1: - prefix += template.negation - else: - prefix += template.multiplier % self.mult - self.mult = 1 - if self.named_exprs is not None: - if named_exprs is None: - named_exprs = set(self.named_exprs) - else: - named_exprs.update(self.named_exprs) - if self.nl is not None: - # This handles both named subexpressions and embedded - # non-numeric (e.g., string) arguments. - nl, nl_args = self.nl - if prefix: - nl = prefix + nl - if args is not None: - assert args is not nl_args - args.extend(nl_args) - else: - args = list(nl_args) - if nl_args: - # For string arguments, nl_args is an empty tuple and - # self.named_exprs is None. For named subexpressions, - # we are guaranteed that named_exprs is NOT None. We - # need to ensure that the named subexpression that we - # are returning is added to the named_exprs set. - named_exprs.update(nl_args) - return nl, args, named_exprs - - if args is None: - args = [] - if self.linear: - nterms = -len(args) - _v_template = template.var - _m_template = template.monomial - # Because we are compiling this expression (into a NL - # expression), we will go ahead and filter the 0*x terms - # from the expression. Note that the args are accumulated - # by side-effect, which prevents iterating over the linear - # terms twice. - nl_sum = ''.join( - args.append(v) or (_v_template if c == 1 else _m_template % c) - for v, c in self.linear.items() - if c - ) - nterms += len(args) - else: - nterms = 0 - nl_sum = '' - if self.nonlinear: - if self.nonlinear.__class__ is list: - nterms += len(self.nonlinear) - nl_sum += ''.join(map(itemgetter(0), self.nonlinear)) - deque(map(args.extend, map(itemgetter(1), self.nonlinear)), maxlen=0) - else: - nterms += 1 - nl_sum += self.nonlinear[0] - args.extend(self.nonlinear[1]) - if self.const: - nterms += 1 - nl_sum += template.const % self.const - - if nterms > 2: - return (prefix + (template.nary_sum % nterms) + nl_sum, args, named_exprs) - elif nterms == 2: - return prefix + template.binary_sum + nl_sum, args, named_exprs - elif nterms == 1: - return prefix + nl_sum, args, named_exprs - else: # nterms == 0 - return prefix + (template.const % 0), args, named_exprs - - def compile_nonlinear_fragment(self): - if not self.nonlinear: - self.nonlinear = None - return - args = [] - nterms = len(self.nonlinear) - nl_sum = ''.join(map(itemgetter(0), self.nonlinear)) - deque(map(args.extend, map(itemgetter(1), self.nonlinear)), maxlen=0) - - if nterms > 2: - self.nonlinear = (self.template.nary_sum % nterms) + nl_sum, args - elif nterms == 2: - self.nonlinear = self.template.binary_sum + nl_sum, args - else: # nterms == 1: - self.nonlinear = nl_sum, args - - def append(self, other): - """Append a child result from acceptChildResult - - Notes - ----- - This method assumes that the operator was "+". It is implemented - so that we can directly use an AMPLRepn() as a data object in - the expression walker (thereby avoiding the function call for a - custom callback) - - """ - # Note that self.mult will always be 1 (we only call append() - # within a sum, so there is no opportunity for self.mult to - # change). Omitting the assertion for efficiency. - # assert self.mult == 1 - _type = other[0] - if _type is _MONOMIAL: - _, v, c = other - if v in self.linear: - self.linear[v] += c - else: - self.linear[v] = c - elif _type is _GENERAL: - _, other = other - if other.nl is not None and other.nl[1]: - if other.linear: - # This is a named expression with both a linear and - # nonlinear component. We want to merge it with - # this AMPLRepn, preserving the named expression for - # only the nonlinear component (merging the linear - # component with this AMPLRepn). - pass - else: - # This is a nonlinear-only named expression, - # possibly with a multiplier that is not 1. Compile - # it and append it (this both resolves the - # multiplier, and marks the named expression as - # having been used) - other = other.compile_repn('', None, self.named_exprs) - nl, nl_args, self.named_exprs = other - self.nonlinear.append((nl, nl_args)) - return - if other.named_exprs is not None: - if self.named_exprs is None: - self.named_exprs = set(other.named_exprs) - else: - self.named_exprs.update(other.named_exprs) - if other.mult != 1: - mult = other.mult - self.const += mult * other.const - if other.linear: - linear = self.linear - for v, c in other.linear.items(): - if v in linear: - linear[v] += c * mult - else: - linear[v] = c * mult - if other.nonlinear: - if other.nonlinear.__class__ is list: - other.compile_nonlinear_fragment() - if mult == -1: - prefix = self.template.negation - else: - prefix = self.template.multiplier % mult - self.nonlinear.append( - (prefix + other.nonlinear[0], other.nonlinear[1]) - ) - else: - self.const += other.const - if other.linear: - linear = self.linear - for v, c in other.linear.items(): - if v in linear: - linear[v] += c - else: - linear[v] = c - if other.nonlinear: - if other.nonlinear.__class__ is list: - self.nonlinear.extend(other.nonlinear) - else: - self.nonlinear.append(other.nonlinear) - elif _type is _CONSTANT: - self.const += other[1] - - def to_expr(self, var_map): - if self.nl is not None or self.nonlinear is not None: - # TODO: support converting general nonlinear expressiosn - # back to Pyomo expressions. This will require an AMPL - # parser. - raise MouseTrap("Cannot convert nonlinear AMPLRepn to Pyomo Expression") - if self.linear: - # Explicitly generate the LinearExpression. At time of - # writing, this is about 40% faster than standard operator - # overloading for O(1000) element sums - ans = LinearExpression( - [coef * var_map[vid] for vid, coef in self.linear.items()] - ) - ans += self.const - else: - ans = self.const - return ans * self.mult - - -class DebugAMPLRepn(AMPLRepn): - __slots__ = () - template = text_nl_debug_template - - -def handle_negation_node(visitor, node, arg1): - if arg1[0] is _MONOMIAL: - return (_MONOMIAL, arg1[1], -1 * arg1[2]) - elif arg1[0] is _GENERAL: - arg1[1].mult *= -1 - return arg1 - elif arg1[0] is _CONSTANT: - return (_CONSTANT, -1 * arg1[1]) - else: - raise RuntimeError("%s: %s" % (type(arg1[0]), arg1)) - - -def handle_product_node(visitor, node, arg1, arg2): - if arg2[0] is _CONSTANT: - arg2, arg1 = arg1, arg2 - if arg1[0] is _CONSTANT: - mult = arg1[1] - if not mult: - # simplify multiplication by 0 (if arg2 is zero, the - # simplification happens when we evaluate the constant - # below). Note that this is not IEEE-754 compliant, and - # will map 0*inf and 0*nan to 0 (and not to nan). We are - # including this for backwards compatibility with the NLv1 - # writer, but arguably we should deprecate/remove this - # "feature" in the future. - if arg2[0] is _CONSTANT: - _prod = mult * arg2[1] - if _prod: - deprecation_warning( - f"Encountered {mult}*{str(arg2[1])} in expression tree. " - "Mapping the NaN result to 0 for compatibility " - "with the nl_v1 writer. In the future, this NaN " - "will be preserved/emitted to comply with IEEE-754.", - version='6.4.3', - ) - _prod = 0 - return (_CONSTANT, _prod) - return arg1 - if mult == 1: - return arg2 - elif arg2[0] is _MONOMIAL: - if mult != mult: - # This catches mult (i.e., arg1) == nan - return arg1 - return (_MONOMIAL, arg2[1], mult * arg2[2]) - elif arg2[0] is _GENERAL: - if mult != mult: - # This catches mult (i.e., arg1) == nan - return arg1 - arg2[1].mult *= mult - return arg2 - elif arg2[0] is _CONSTANT: - if not arg2[1]: - # Simplify multiplication by 0; see note above about - # IEEE-754 incompatibility. - _prod = mult * arg2[1] - if _prod: - deprecation_warning( - f"Encountered {str(mult)}*{arg2[1]} in expression tree. " - "Mapping the NaN result to 0 for compatibility " - "with the nl_v1 writer. In the future, this NaN " - "will be preserved/emitted to comply with IEEE-754.", - version='6.4.3', - ) - _prod = 0 - return (_CONSTANT, _prod) - return (_CONSTANT, mult * arg2[1]) - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( - visitor.template.product - ) - nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_division_node(visitor, node, arg1, arg2): - if arg2[0] is _CONSTANT: - div = arg2[1] - if div == 1: - return arg1 - if arg1[0] is _MONOMIAL: - tmp = apply_node_operation(node, (arg1[2], div)) - if tmp != tmp: - # This catches if the coefficient division results in nan - return _CONSTANT, tmp - return (_MONOMIAL, arg1[1], tmp) - elif arg1[0] is _GENERAL: - tmp = apply_node_operation(node, (arg1[1].mult, div)) - if tmp != tmp: - # This catches if the multiplier division results in nan - return _CONSTANT, tmp - arg1[1].mult = tmp - return arg1 - elif arg1[0] is _CONSTANT: - return _CONSTANT, apply_node_operation(node, (arg1[1], div)) - elif arg1[0] is _CONSTANT and not arg1[1]: - return _CONSTANT, 0 - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( - visitor.template.division - ) - nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_pow_node(visitor, node, arg1, arg2): - if arg2[0] is _CONSTANT: - if arg1[0] is _CONSTANT: - ans = apply_node_operation(node, (arg1[1], arg2[1])) - if ans.__class__ in native_complex_types: - ans = complex_number_error(ans, visitor, node) - return _CONSTANT, ans - elif not arg2[1]: - return _CONSTANT, 1 - elif arg2[1] == 1: - return arg1 - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.pow) - nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_abs_node(visitor, node, arg1): - if arg1[0] is _CONSTANT: - return (_CONSTANT, abs(arg1[1])) - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.abs) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_unary_node(visitor, node, arg1): - if arg1[0] is _CONSTANT: - return _CONSTANT, apply_node_operation(node, (arg1[1],)) - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( - visitor.template.unary[node.name] - ) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_exprif_node(visitor, node, arg1, arg2, arg3): - if arg1[0] is _CONSTANT: - if arg1[1]: - return arg2 - else: - return arg3 - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn(visitor.template.exprif) - nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) - nonlin = visitor.node_result_to_amplrepn(arg3).compile_repn(*nonlin) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_equality_node(visitor, node, arg1, arg2): - if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT: - return (_CONSTANT, arg1[1] == arg2[1]) - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( - visitor.template.equality - ) - nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_inequality_node(visitor, node, arg1, arg2): - if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT: - return (_CONSTANT, node._apply_operation((arg1[1], arg2[1]))) - nonlin = visitor.node_result_to_amplrepn(arg1).compile_repn( - visitor.template.strict_inequality_map[node.strict] - ) - nonlin = visitor.node_result_to_amplrepn(arg2).compile_repn(*nonlin) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_ranged_inequality_node(visitor, node, arg1, arg2, arg3): - if arg1[0] is _CONSTANT and arg2[0] is _CONSTANT and arg3[0] is _CONSTANT: - return (_CONSTANT, node._apply_operation((arg1[1], arg2[1], arg3[1]))) - op = visitor.template.strict_inequality_map[node.strict] - nl, args, named = visitor.node_result_to_amplrepn(arg1).compile_repn( - visitor.template.and_expr + op[0] - ) - nl2, args2, named = visitor.node_result_to_amplrepn(arg2).compile_repn( - '', None, named - ) - nl += nl2 + op[1] + nl2 - args.extend(args2) - args.extend(args2) - nonlin = visitor.node_result_to_amplrepn(arg3).compile_repn(nl, args, named) - return (_GENERAL, visitor.Result(0, None, nonlin)) - - -def handle_named_expression_node(visitor, node, arg1): - _id = id(node) - # Note that while named subexpressions ('defined variables' in the - # ASL NL file vernacular) look like variables, they are not allowed - # to appear in the 'linear' portion of a constraint / objective - # definition. We will return this as a "var" template, but - # wrapped in the nonlinear portion of the expression tree. - repn = visitor.node_result_to_amplrepn(arg1) - - # A local copy of the expression source list. This will be updated - # later if the same Expression node is encountered in another - # expression tree. - # - # This is a 3-tuple [con_id, obj_id, substitute_expression]. If the - # expression is used by more than 1 constraint / objective, then the - # id is set to 0. If it is not used by any, then it is None. - # substitute_expression is a bool indicating if this named - # subexpression tree should be directly substituted into any - # expression tree that references this node (i.e., do NOT emit the V - # line). - expression_source = [None, None, False] - # Record this common expression - visitor.subexpression_cache[_id] = ( - # 0: the "component" that generated this expression ID - node, - # 1: the common subexpression (to be written out) - repn, - # 2: the source usage information for this subexpression: - # [(con_id, obj_id, substitute); see above] - expression_source, - ) - - # As we will eventually need the compiled form of any nonlinear - # expression, we will go ahead and compile it here. We do not - # do the same for the linear component as we will only need the - # linear component compiled to a dict if we are emitting the - # original (linear + nonlinear) V line (which will not happen if - # the V line is part of a larger linear operator). - if repn.nonlinear.__class__ is list: - repn.compile_nonlinear_fragment() - - if not visitor.use_named_exprs: - return _GENERAL, repn.duplicate() - - mult, repn.mult = repn.mult, 1 - if repn.named_exprs is None: - repn.named_exprs = set() - - # When converting this shared subexpression to a (nonlinear) - # node, we want to just reference this subexpression: - repn.nl = (visitor.template.var, (_id,)) - - if repn.nonlinear: - if repn.linear: - # If this expression has both linear and nonlinear - # components, we will follow the ASL convention and break - # the named subexpression into two named subexpressions: one - # that is only the nonlinear component and one that has the - # const/linear component (and references the first). This - # will allow us to propagate linear coefficients up from - # named subexpressions when appropriate. - sub_node = NLFragment(repn, node) - sub_id = id(sub_node) - sub_repn = visitor.Result(0, None, None) - sub_repn.nonlinear = repn.nonlinear - sub_repn.nl = (visitor.template.var, (sub_id,)) - sub_repn.named_exprs = set(repn.named_exprs) - - repn.named_exprs.add(sub_id) - repn.nonlinear = sub_repn.nl - - # See above for the meaning of this source information - nl_info = list(expression_source) - visitor.subexpression_cache[sub_id] = (sub_node, sub_repn, nl_info) - # It is important that the NL subexpression comes before the - # main named expression: re-insert the original named - # expression (so that the nonlinear sub_node comes first - # when iterating over subexpression_cache) - visitor.subexpression_cache[_id] = visitor.subexpression_cache.pop(_id) - else: - nl_info = expression_source - else: - repn.nonlinear = None - if repn.linear: - if ( - not repn.const - and len(repn.linear) == 1 - and next(iter(repn.linear.values())) == 1 - ): - # This Expression holds only a variable (multiplied by - # 1). Do not emit this as a named variable and instead - # just inject the variable where this expression is - # used. - repn.nl = None - expression_source[2] = True - else: - # This Expression holds only a constant. Do not emit this - # as a named variable and instead just inject the constant - # where this expression is used. - repn.nl = None - expression_source[2] = True - - if mult != 1: - repn.const *= mult - if repn.linear: - _lin = repn.linear - for v in repn.linear: - _lin[v] *= mult - if repn.nonlinear: - if mult == -1: - prefix = visitor.template.negation - else: - prefix = visitor.template.multiplier % mult - repn.nonlinear = prefix + repn.nonlinear[0], repn.nonlinear[1] - - if expression_source[2]: - if repn.linear: - assert len(repn.linear) == 1 and not repn.const - return (_MONOMIAL,) + next(iter(repn.linear.items())) - else: - return (_CONSTANT, repn.const) - - return (_GENERAL, repn.duplicate()) - - -def handle_external_function_node(visitor, node, *args): - func = node._fcn._function - # There is a special case for external functions: these are the only - # expressions that can accept string arguments. As we currently pass - # these as 'precompiled' GENERAL AMPLRepns, the normal trap for - # constant subexpressions will miss string arguments. We will catch - # that case here by looking for NL fragments with no variable - # references. Note that the NL fragment is NOT the raw string - # argument that we want to evaluate: the raw string is in the - # `const` field. - if all( - arg[0] is _CONSTANT or (arg[0] is _GENERAL and arg[1].nl and not arg[1].nl[1]) - for arg in args - ): - arg_list = [arg[1] if arg[0] is _CONSTANT else arg[1].const for arg in args] - return _CONSTANT, apply_node_operation(node, arg_list) - if func in visitor.external_functions: - if node._fcn._library != visitor.external_functions[func][1]._library: - raise RuntimeError( - "The same external function name (%s) is associated " - "with two different libraries (%s through %s, and %s " - "through %s). The ASL solver will fail to link " - "correctly." - % ( - func, - visitor.external_functions[func]._library, - visitor.external_functions[func]._library.name, - node._fcn._library, - node._fcn.name, - ) - ) - else: - visitor.external_functions[func] = (len(visitor.external_functions), node._fcn) - comment = f'\t#{node.local_name}' if visitor.symbolic_solver_labels else '' - nl = visitor.template.external_fcn % ( - visitor.external_functions[func][0], - len(args), - comment, - ) - arg_ids = [] - named_exprs = set() - for arg in args: - _id = id(arg) - arg_ids.append(_id) - visitor.subexpression_cache[_id] = ( - arg, - visitor.Result( - 0, - None, - visitor.node_result_to_amplrepn(arg).compile_repn( - named_exprs=named_exprs - ), - ), - (None, None, True), - ) - if not named_exprs: - named_exprs = None - return ( - _GENERAL, - visitor.Result(0, None, (nl + '%s' * len(arg_ids), arg_ids, named_exprs)), - ) - - -_operator_handles = ExitNodeDispatcher( - { - NegationExpression: handle_negation_node, - ProductExpression: handle_product_node, - DivisionExpression: handle_division_node, - PowExpression: handle_pow_node, - AbsExpression: handle_abs_node, - UnaryFunctionExpression: handle_unary_node, - Expr_ifExpression: handle_exprif_node, - EqualityExpression: handle_equality_node, - InequalityExpression: handle_inequality_node, - RangedExpression: handle_ranged_inequality_node, - Expression: handle_named_expression_node, - ExternalFunctionExpression: handle_external_function_node, - # These are handled explicitly in beforeChild(): - # LinearExpression: handle_linear_expression, - # SumExpression: handle_sum_expression, - # - # Note: MonomialTermExpression is only hit when processing NPV - # subexpressions that raise errors (e.g., log(0) * m.x), so no - # special processing is needed [it is just a product expression] - MonomialTermExpression: handle_product_node, - } -) - - -class AMPLBeforeChildDispatcher(BeforeChildDispatcher): - __slots__ = () - - def __init__(self): - # Special linear / summation expressions - self[MonomialTermExpression] = self._before_monomial - self[LinearExpression] = self._before_linear - self[SumExpression] = self._before_general_expression - - @staticmethod - def _record_var(visitor, var): - # We always add all indices to the var_map at once so that - # we can honor deterministic ordering of unordered sets - # (because the user could have iterated over an unordered - # set when constructing an expression, thereby altering the - # order in which we would see the variables) - vm = visitor.var_map - try: - _iter = var.parent_component().values(visitor.sorter) - except AttributeError: - # Note that this only works for the AML, as kernel does not - # provide a parent_component() - _iter = (var,) - for v in _iter: - if v.fixed: - continue - vm[id(v)] = v - - @staticmethod - def _before_string(visitor, child): - visitor.encountered_string_arguments = True - ans = visitor.Result(child, None, None) - ans.nl = (visitor.template.string % (len(child), child), ()) - return False, (_GENERAL, ans) - - @staticmethod - def _before_var(visitor, child): - _id = id(child) - if _id not in visitor.var_map: - if child.fixed: - if _id not in visitor.fixed_vars: - visitor.cache_fixed_var(_id, child) - return False, (_CONSTANT, visitor.fixed_vars[_id]) - _before_child_handlers._record_var(visitor, child) - return False, (_MONOMIAL, _id, 1) - - @staticmethod - def _before_monomial(visitor, child): - # - # The following are performance optimizations for common - # situations (Monomial terms and Linear expressions) - # - arg1, arg2 = child._args_ - if arg1.__class__ not in native_types: - try: - arg1 = visitor.check_constant(visitor.evaluate(arg1), arg1) - except (ValueError, ArithmeticError): - return True, None - - # Trap multiplication by 0 and nan. - if not arg1: - if arg2.fixed: - _id = id(arg2) - if _id not in visitor.fixed_vars: - visitor.cache_fixed_var(id(arg2), arg2) - arg2 = visitor.fixed_vars[_id] - if arg2 != arg2: - deprecation_warning( - f"Encountered {arg1}*{arg2} in expression tree. " - "Mapping the NaN result to 0 for compatibility " - "with the nl_v1 writer. In the future, this NaN " - "will be preserved/emitted to comply with IEEE-754.", - version='6.4.3', - ) - return False, (_CONSTANT, arg1) - - _id = id(arg2) - if _id not in visitor.var_map: - if arg2.fixed: - if _id not in visitor.fixed_vars: - visitor.cache_fixed_var(_id, arg2) - return False, (_CONSTANT, arg1 * visitor.fixed_vars[_id]) - _before_child_handlers._record_var(visitor, arg2) - return False, (_MONOMIAL, _id, arg1) - - @staticmethod - def _before_linear(visitor, child): - # Because we are going to modify the LinearExpression in this - # walker, we need to make a copy of the arg list from the original - # expression tree. - var_map = visitor.var_map - const = 0 - linear = {} - for arg in child.args: - if arg.__class__ is MonomialTermExpression: - arg1, arg2 = arg._args_ - if arg1.__class__ not in native_types: - try: - arg1 = visitor.check_constant(visitor.evaluate(arg1), arg1) - except (ValueError, ArithmeticError): - return True, None - - # Trap multiplication by 0 and nan. - if not arg1: - if arg2.fixed: - arg2 = visitor.check_constant(arg2.value, arg2) - if arg2 != arg2: - deprecation_warning( - f"Encountered {arg1}*{str(arg2.value)} in expression " - "tree. Mapping the NaN result to 0 for compatibility " - "with the nl_v1 writer. In the future, this NaN " - "will be preserved/emitted to comply with IEEE-754.", - version='6.4.3', - ) - continue - - _id = id(arg2) - if _id not in var_map: - if arg2.fixed: - if _id not in visitor.fixed_vars: - visitor.cache_fixed_var(_id, arg2) - const += arg1 * visitor.fixed_vars[_id] - continue - _before_child_handlers._record_var(visitor, arg2) - linear[_id] = arg1 - elif _id in linear: - linear[_id] += arg1 - else: - linear[_id] = arg1 - elif arg.__class__ in native_types: - const += arg - elif arg.is_variable_type(): - _id = id(arg) - if _id not in var_map: - if arg.fixed: - if _id not in visitor.fixed_vars: - visitor.cache_fixed_var(_id, arg) - const += visitor.fixed_vars[_id] - continue - _before_child_handlers._record_var(visitor, arg) - linear[_id] = 1 - elif _id in linear: - linear[_id] += 1 - else: - linear[_id] = 1 - else: - try: - const += visitor.check_constant(visitor.evaluate(arg), arg) - except (ValueError, ArithmeticError): - return True, None - - if linear: - return False, (_GENERAL, visitor.Result(const, linear, None)) - else: - return False, (_CONSTANT, const) - - @staticmethod - def _before_named_expression(visitor, child): - _id = id(child) - if _id in visitor.subexpression_cache: - obj, repn, info = visitor.subexpression_cache[_id] - if info[2]: - if repn.linear: - return False, (_MONOMIAL, next(iter(repn.linear)), 1) - else: - return False, (_CONSTANT, repn.const) - return False, (_GENERAL, repn.duplicate()) - else: - return True, None - - -_before_child_handlers = AMPLBeforeChildDispatcher() - - -class AMPLRepnVisitor(StreamBasedExpressionVisitor): - def __init__( - self, - subexpression_cache, - external_functions, - var_map, - used_named_expressions, - symbolic_solver_labels, - use_named_exprs, - sorter, - ): - super().__init__() - self.subexpression_cache = subexpression_cache - self.external_functions = external_functions - self.active_expression_source = None - self.var_map = var_map - self.used_named_expressions = used_named_expressions - self.symbolic_solver_labels = symbolic_solver_labels - self.use_named_exprs = use_named_exprs - self.encountered_string_arguments = False - self.fixed_vars = {} - self._eval_expr_visitor = _EvaluationVisitor(True) - self.evaluate = self._eval_expr_visitor.dfs_postorder_stack - self.sorter = sorter - - if symbolic_solver_labels: - self.Result = DebugAMPLRepn - else: - self.Result = AMPLRepn - self.template = self.Result.template - - def check_constant(self, ans, obj): - if ans.__class__ not in native_numeric_types: - # None can be returned from uninitialized Var/Param objects - if ans is None: - return InvalidNumber( - None, f"'{obj}' evaluated to a nonnumeric value '{ans}'" - ) - if ans.__class__ is InvalidNumber: - return ans - elif ans.__class__ in native_complex_types: - return complex_number_error(ans, self, obj) - else: - # It is possible to get other non-numeric types. Most - # common are bool and 1-element numpy.array(). We will - # attempt to convert the value to a float before - # proceeding. - # - # TODO: we should check bool and warn/error (while bool is - # convertible to float in Python, they have very - # different semantic meanings in Pyomo). - try: - ans = float(ans) - except: - return InvalidNumber( - ans, f"'{obj}' evaluated to a nonnumeric value '{ans}'" - ) - if ans != ans: - return InvalidNumber( - nan, f"'{obj}' evaluated to a nonnumeric value '{ans}'" - ) - return ans - - def cache_fixed_var(self, _id, child): - val = self.check_constant(child.value, child) - lb, ub = child.bounds - if (lb is not None and lb - val > TOL) or (ub is not None and ub - val < -TOL): - raise InfeasibleConstraintException( - "model contains a trivially infeasible " - f"variable '{child.name}' (fixed value " - f"{val} outside bounds [{lb}, {ub}])." - ) - self.fixed_vars[_id] = self.check_constant(child.value, child) - - def node_result_to_amplrepn(self, data): - if data[0] is _GENERAL: - return data[1] - elif data[0] is _MONOMIAL: - _, v, c = data - if c: - return self.Result(0, {v: c}, None) - else: - return self.Result(0, None, None) - elif data[0] is _CONSTANT: - return self.Result(data[1], None, None) - else: - raise DeveloperError("unknown result type") - - def initializeWalker(self, expr): - expr, src, src_idx, self.expression_scaling_factor = expr - self.active_expression_source = (src_idx, id(src)) - walk, result = self.beforeChild(None, expr, 0) - if not walk: - return False, self.finalizeResult(result) - return True, expr - - def beforeChild(self, node, child, child_idx): - return _before_child_handlers[child.__class__](self, child) - - def enterNode(self, node): - # SumExpression are potentially large nary operators. Directly - # populate the result - if node.__class__ in sum_like_expression_types: - data = self.Result(0, {}, None) - data.nonlinear = [] - return node.args, data - else: - return node.args, [] - - def exitNode(self, node, data): - if data.__class__ is self.Result: - # If the summation resulted in a constant, return the constant - if data.linear or data.nonlinear or data.nl: - return (_GENERAL, data) - else: - return (_CONSTANT, data.const) - # - # General expressions... - # - return _operator_handles[node.__class__](self, node, *data) - - def finalizeResult(self, result): - ans = self.node_result_to_amplrepn(result) - - # Multiply the expression by the scaling factor provided by the caller - ans.mult *= self.expression_scaling_factor - - # If this was a nonlinear named expression, and that expression - # has no linear portion, then we will directly use this as a - # named expression. We need to mark that the expression was - # used and return it as a simple nonlinear expression pointing - # to this named expression. In all other cases, we will return - # the processed representation (which will reference the - # nonlinear-only named subexpression - if it exists - but not - # this outer named expression). This prevents accidentally - # recharacterizing variables that only appear linearly as - # nonlinear variables. - if ans.nl is not None: - if not ans.nl[1]: - raise ValueError("Numeric expression resolved to a string constant") - # This *is* a named subexpression. If there is no linear - # component, then replace this expression with the named - # expression. The mult will be handled later. We know that - # the const is built into the nonlinear expression, because - # it cannot be changed "in place" (only through addition, - # which would have "cleared" the nl attribute) - if not ans.linear: - ans.named_exprs.update(ans.nl[1]) - ans.nonlinear = ans.nl - ans.const = 0 - else: - # This named expression has both a linear and a - # nonlinear component, and possibly a multiplier and - # constant. We will not include this named expression - # and instead will expose the components so that linear - # variables are not accidentally re-characterized as - # nonlinear. - pass - ans.nl = None - - if ans.nonlinear.__class__ is list: - ans.compile_nonlinear_fragment() - - if not ans.linear: - ans.linear = {} - if ans.mult != 1: - linear = ans.linear - mult, ans.mult = ans.mult, 1 - ans.const *= mult - if linear: - for k in linear: - linear[k] *= mult - if ans.nonlinear: - if mult == -1: - prefix = self.template.negation - else: - prefix = self.template.multiplier % mult - ans.nonlinear = prefix + ans.nonlinear[0], ans.nonlinear[1] - # - self.active_expression_source = None - return ans - - -def _evaluate_constant_nl(nl, external_functions): - expr = nl.splitlines() - stack = [] - while expr: - line = expr.pop() - tokens = line.split() - # remove tokens after the first comment - for i, t in enumerate(tokens): - if t.startswith('#'): - tokens = tokens[:i] - break - if len(tokens) != 1: - # skip blank lines - if not tokens: - continue - if tokens[0][0] == 'f': - # external function - fid, nargs = tokens - fid = int(fid[1:]) - nargs = int(nargs) - fcn_id, ef = external_functions[fid] - assert fid == fcn_id - stack.append(ef.evaluate(tuple(stack.pop() for i in range(nargs)))) - continue - raise DeveloperError( - f"Unsupported line format _evaluate_constant_nl() " - f"(we expect each line to contain a single token): '{line}'" - ) - term = tokens[0] - # the "command" can be determined by the first character on the line - cmd = term[0] - # Note that we will unpack the line into the expected number of - # explicit arguments as a form of error checking - if cmd == 'n': - # numeric constant - stack.append(float(term[1:])) - elif cmd == 'o': - # operator - nargs, fcn = nl_operators[int(term[1:])] - if nargs is None: - nargs = int(stack.pop()) - stack.append(fcn(*(stack.pop() for i in range(nargs)))) - elif cmd in '1234567890': - # this is either a single int (e.g., the nargs in a nary - # sum) or a string argument. Preserve it as-is until later - # when we know which we are expecting. - stack.append(term) - elif cmd == 'h': - stack.append(term.split(':', 1)[1]) - else: - raise DeveloperError( - f"Unsupported NL operator in _evaluate_constant_nl(): '{line}'" - ) - assert len(stack) == 1 - return stack[0] diff --git a/pyomo/repn/tests/ampl/test_ampl_nl.py b/pyomo/repn/tests/ampl/test_ampl_nl.py index 53a2d3cda82..53c34c4c5db 100644 --- a/pyomo/repn/tests/ampl/test_ampl_nl.py +++ b/pyomo/repn/tests/ampl/test_ampl_nl.py @@ -31,11 +31,9 @@ from ..nl_diff import load_and_compare_nl_baseline import pyomo.repn.plugins.ampl.ampl_ as ampl_ -import pyomo.repn.plugins.nl_writer as nl_writer +from pyomo.repn.ampl import text_nl_debug_template as template gsr = ampl_.generate_standard_repn -template = nl_writer.text_nl_debug_template - thisdir = this_file_dir() diff --git a/pyomo/repn/tests/ampl/test_nlv2.py b/pyomo/repn/tests/ampl/test_nlv2.py index 336e96b93f3..0bfdb22a2ba 100644 --- a/pyomo/repn/tests/ampl/test_nlv2.py +++ b/pyomo/repn/tests/ampl/test_nlv2.py @@ -53,10 +53,6 @@ class INFO(object): def __init__(self, symbolic=False): - if symbolic: - self.template = nl_writer.text_nl_debug_template - else: - self.template = nl_writer.text_nl_template self.subexpression_cache = {} self.external_functions = {} self.var_map = {} @@ -72,6 +68,7 @@ def __init__(self, symbolic=False): True, None, ) + self.template = self.visitor.template def __enter__(self): return self diff --git a/pyomo/repn/tests/nl_diff.py b/pyomo/repn/tests/nl_diff.py index aa2b4519db3..736be4f9606 100644 --- a/pyomo/repn/tests/nl_diff.py +++ b/pyomo/repn/tests/nl_diff.py @@ -15,9 +15,7 @@ from difflib import SequenceMatcher, unified_diff from pyomo.repn.tests.diffutils import compare_floats, load_baseline -import pyomo.repn.plugins.nl_writer as nl_writer - -template = nl_writer.text_nl_debug_template +from pyomo.repn.ampl import text_nl_debug_template as template _norm_whitespace = re.compile(r'[^\S\n]+') _norm_integers = re.compile(r'(?m)\.0+$') From 9c3f5bbb0efb1744c6ac53a18afbd2a14382dd50 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 26 Jul 2024 12:16:00 -0600 Subject: [PATCH 113/203] NFC: apply black --- pyomo/repn/plugins/nl_writer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pyomo/repn/plugins/nl_writer.py b/pyomo/repn/plugins/nl_writer.py index 2e5a5484657..6f340cc887f 100644 --- a/pyomo/repn/plugins/nl_writer.py +++ b/pyomo/repn/plugins/nl_writer.py @@ -1998,4 +1998,3 @@ def _write_v_line(self, expr_id, k): ostream.write(f'{column_order[_id]} {linear[_id]!s}\n') self._write_nl_expression(info[1], True) self.next_V_line_id += 1 - From 0ea60d254b433eb12ae8151410a31ede360b9830 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Fri, 26 Jul 2024 12:26:07 -0600 Subject: [PATCH 114/203] Promulgate pyros feasibility tolerance workaround to ampl repn visitor --- pyomo/contrib/pyros/util.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/pyros/util.py b/pyomo/contrib/pyros/util.py index ecabca8f115..5ade304c077 100644 --- a/pyomo/contrib/pyros/util.py +++ b/pyomo/contrib/pyros/util.py @@ -38,7 +38,8 @@ from pyomo.core.expr import value from pyomo.core.expr.numeric_expr import NPV_MaxExpression, NPV_MinExpression from pyomo.repn.standard_repn import generate_standard_repn -from pyomo.repn.plugins import nl_writer as pyomo_nl_writer +import pyomo.repn.plugins.nl_writer as pyomo_nl_writer +import pyomo.repn.ampl as pyomo_ampl_repn from pyomo.core.expr.visitor import ( identify_variables, identify_mutable_parameters, @@ -1824,8 +1825,9 @@ def call_solver(model, solver, config, timing_obj, timer_name, err_msg): # e.g., a Var fixed outside bounds beyond the Pyomo NL writer # tolerance, but still within the default IPOPT feasibility # tolerance - current_nl_writer_tol = pyomo_nl_writer.TOL + current_nl_writer_tol = pyomo_nl_writer.TOL, pyomo_ampl_repn.TOL pyomo_nl_writer.TOL = 1e-4 + pyomo_ampl_repn.TOL = 1e-4 try: results = solver.solve( @@ -1845,7 +1847,7 @@ def call_solver(model, solver, config, timing_obj, timer_name, err_msg): results.solver, TIC_TOC_SOLVE_TIME_ATTR, tt_timer.toc(msg=None, delta=True) ) finally: - pyomo_nl_writer.TOL = current_nl_writer_tol + pyomo_nl_writer.TOL, pyomo_ampl_repn.TOL = current_nl_writer_tol timing_obj.stop_timer(timer_name) revert_solver_max_time_adjustment( From b5992eca0cca6195d037b5eb037f184e0f7da1f8 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 31 Jul 2024 10:22:27 -0400 Subject: [PATCH 115/203] Updated documentation typo --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index e8b4d9ca2c7..4be5d0ad8dc 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -219,7 +219,7 @@ An example output of the code above, a design exploration for the initial concen .. figure:: FIM_sensitivity.png :scale: 50 % -A heatmap shows the change of the objective function, a.k.a. the experimental information content, in the design region. Horizontal and vertical axes are two design variables, while the color of each grid shows the experimental information content. Taking the Fig. Reactor case - A optimality as example, A-optimality shows that the most informative region is around $C_{A0}=5.0$ M, $T=300.0$ K, while the least informative region is around $C_{A0}=1.0$ M, $T=700.0$ K. +A heatmap shows the change of the objective function, a.k.a. the experimental information content, in the design space. Horizontal and vertical axes are the two experimental design variables, while the color of each grid shows the experimental information content. For A optimality (top left subfigure), the figure shows that the most informative region is around :math:`C_{A0}=5.0` M, :math:`T=300.0` K, while the least informative region is around :math:`C_{A0}=1.0` M, :math:`T=700.0` K. Step 6: Performing an optimal experimental design ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 735c9326e4fb51dcb21667a4881cfaeb7da98296 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 2 Aug 2024 10:59:14 -0400 Subject: [PATCH 116/203] Adding functionality to use Params instead of Vars --- pyomo/contrib/doe/__init__.py | 2 +- pyomo/contrib/doe/doe.py | 16 ++++++++- .../doe/examples/reactor_experiment.py | 26 +++++++++----- pyomo/contrib/doe/utils.py | 36 +++++++++++++++++++ 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index fe71b7f5920..aaca4db12fb 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -16,6 +16,6 @@ FiniteDifferenceStep, ) from .tests import experiment_class_example, experiment_class_example_flags -from .utils import rescale_FIM +from .utils import rescale_FIM, get_parameters_from_suffix from .examples import reactor_experiment, reactor_example, reactor_compute_factorial_FIM from .experiment import Experiment diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 359b0c051cc..550c5ab447e 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -30,6 +30,10 @@ from pyomo.common.timing import TicTocTimer from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp +from pyomo.contrib.parmest.utils.model_utils import convert_params_to_vars + +from pyomo.contrib.doe.utils import get_parameters_from_suffix + from pyomo.common.dependencies import ( numpy as np, numpy_available, @@ -1012,7 +1016,17 @@ def _generate_scenario_blocks(self, model=None): "Finite difference option not recognized. Please contact the developers as you should not see this error." ) - # To-Do: Fix parameter values if they are not Params? + # Search for unknown parameters that are Params, or Vars. Params are updated to be fixed Vars + unknown_parameter_Params = get_parameters_from_suffix(model.base_model.unknown_parameters, fix_vars=True) + print(unknown_parameter_Params) + + # Change the unknown parameters that are Params to be Vars and fix them + if len(unknown_parameter_Params) > 0: + print("GOT HERE!!!!") + model.base_model = convert_params_to_vars(model.base_model, unknown_parameter_Params, fix_vars=True) + + # Search for experiment inputs that are Params, or Vars. Params are updated to be unfixed vars + experiment_inputs_Params = get_parameters_from_suffix(model.base_model.experiment_inputs, fix_vars=False) # Run base model to get initialized model and check model function for comp, _ in model.base_model.experiment_inputs.items(): diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 68c33a4ca2b..9b4ddae2bf5 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -59,10 +59,15 @@ def create_model(self): m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) # Arrhenius rate law equations - m.A1 = pyo.Var(within=pyo.NonNegativeReals) - m.E1 = pyo.Var(within=pyo.NonNegativeReals) - m.A2 = pyo.Var(within=pyo.NonNegativeReals) - m.E2 = pyo.Var(within=pyo.NonNegativeReals) + # m.A1 = pyo.Var(within=pyo.NonNegativeReals) + # m.E1 = pyo.Var(within=pyo.NonNegativeReals) + # m.A2 = pyo.Var(within=pyo.NonNegativeReals) + # m.E2 = pyo.Var(within=pyo.NonNegativeReals) + + m.A1 = pyo.Param(mutable=True) + m.E1 = pyo.Param(mutable=True) + m.A2 = pyo.Param(mutable=True) + m.E2 = pyo.Param(mutable=True) # Differential variables (Conc.) m.dCAdt = DerivativeVar(m.CA, wrt=m.t) @@ -130,10 +135,15 @@ def finalize_model(self): m.t.update(control_points) # Fix the unknown parameter values - m.A1.fix(self.data["A1"]) - m.A2.fix(self.data["A2"]) - m.E1.fix(self.data["E1"]) - m.E2.fix(self.data["E2"]) + # m.A1.fix(self.data["A1"]) + # m.A2.fix(self.data["A2"]) + # m.E1.fix(self.data["E1"]) + # m.E2.fix(self.data["E2"]) + + m.A1.set_value(self.data["A1"]) + m.A2.set_value(self.data["A2"]) + m.E1.set_value(self.data["E1"]) + m.E2.set_value(self.data["E2"]) # Add upper and lower bounds to the design variable, CA[0] m.CA[0].setlb(self.data["CA_bounds"][0]) diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py index cb00dfcd67f..c7ec6f9d879 100644 --- a/pyomo/contrib/doe/utils.py +++ b/pyomo/contrib/doe/utils.py @@ -25,8 +25,13 @@ # publicly, and to permit other to do so. # ___________________________________________________________________________ +import pyomo.environ as pyo + from pyomo.common.dependencies import numpy as np, numpy_available +from pyomo.core.base.param import ParamData +from pyomo.core.base.var import VarData + # Rescale FIM (a scaling function to help rescale FIM from parameter values) def rescale_FIM(FIM, param_vals): @@ -58,3 +63,34 @@ def rescale_FIM(FIM, param_vals): scaling_mat = (1 / param_vals).transpose().dot((1 / param_vals)) scaled_FIM = np.multiply(FIM, scaling_mat) return scaled_FIM + +def get_parameters_from_suffix(suffix, fix_vars=False): + """ + Finds the Params within the suffix provided. It will also check to see + if there are Vars in the suffix provided. ``fix_vars`` will indicate + if we should fix all the Vars in the set or not. + + Parameters + ---------- + suffix: pyomo Suffix object, contains the components to be checked + as keys + fix_vars: boolean, whether or not to fix the Vars, default = False + + Returns + ------- + param_list: list of Param + """ + param_list = [] + + # FIX THE MODEL TREE ISSUE WHERE I GET base_model. INSTEAD OF + # Check keys if they are Param or Var. Fix the vars if ``fix_vars`` is True + for k, v in suffix.items(): + if isinstance(k, ParamData): + param_list.append(k.name) + elif isinstance(k, VarData): + if fix_vars: + k.fix() + else: + pass # ToDo: Write error for suffix keys that aren't ParamData or VarData + + return param_list \ No newline at end of file From f038bc22057dfbb09cd9050b4b75b43989f0e4ef Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:09:22 -0400 Subject: [PATCH 117/203] Commented out new Param to Var code Will discuss at meeting later today (8/2/2024). --- pyomo/contrib/doe/doe.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 550c5ab447e..566afe78853 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1016,17 +1016,27 @@ def _generate_scenario_blocks(self, model=None): "Finite difference option not recognized. Please contact the developers as you should not see this error." ) - # Search for unknown parameters that are Params, or Vars. Params are updated to be fixed Vars - unknown_parameter_Params = get_parameters_from_suffix(model.base_model.unknown_parameters, fix_vars=True) - print(unknown_parameter_Params) + # TODO: Allow Params for `unknown_parameters` and `experiment_inputs` + # May need to make a new converter Param to Var that allows non-string names/references to be passed - # Change the unknown parameters that are Params to be Vars and fix them - if len(unknown_parameter_Params) > 0: - print("GOT HERE!!!!") - model.base_model = convert_params_to_vars(model.base_model, unknown_parameter_Params, fix_vars=True) + # # Search for unknown parameters that are Params, or Vars. Params are updated to be fixed Vars + # unknown_parameter_Params = get_parameters_from_suffix(model.base_model.unknown_parameters, fix_vars=True) + + # # # Remove ``base_model`` precursor name on parameters + # # for ind, val in enumerate(unknown_parameter_Params): + # # base_model_ind = val.split(".").index("base_model") + # # unknown_parameter_Params[ind] = ".".join(val.split(".")[(base_model_ind + 1) :]) - # Search for experiment inputs that are Params, or Vars. Params are updated to be unfixed vars - experiment_inputs_Params = get_parameters_from_suffix(model.base_model.experiment_inputs, fix_vars=False) + # print(unknown_parameter_Params) + + # # Change the unknown parameters that are Params to be Vars and fix them + # if len(unknown_parameter_Params) > 0: + # model.base_model = convert_params_to_vars(model.base_model, unknown_parameter_Params, fix_vars=True) + + # model.base_model.unknown_parameters.pprint() + + # # Search for experiment inputs that are Params, or Vars. Params are updated to be unfixed vars + # experiment_inputs_Params = get_parameters_from_suffix(model.base_model.experiment_inputs, fix_vars=False) # Run base model to get initialized model and check model function for comp, _ in model.base_model.experiment_inputs.items(): From 087e7be754a9118e57c62d0468cc4d99fc83d7b2 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Fri, 2 Aug 2024 14:15:22 -0400 Subject: [PATCH 118/203] ran black and typos --- pyomo/contrib/doe/doe.py | 4 ++-- pyomo/contrib/doe/utils.py | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 566afe78853..597c058d728 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1019,9 +1019,9 @@ def _generate_scenario_blocks(self, model=None): # TODO: Allow Params for `unknown_parameters` and `experiment_inputs` # May need to make a new converter Param to Var that allows non-string names/references to be passed - # # Search for unknown parameters that are Params, or Vars. Params are updated to be fixed Vars + # # Search for unknown parameters that are Params, or Vars. Params are updated to be fixed Vars # unknown_parameter_Params = get_parameters_from_suffix(model.base_model.unknown_parameters, fix_vars=True) - + # # # Remove ``base_model`` precursor name on parameters # # for ind, val in enumerate(unknown_parameter_Params): # # base_model_ind = val.split(".").index("base_model") diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py index c7ec6f9d879..889bebbea33 100644 --- a/pyomo/contrib/doe/utils.py +++ b/pyomo/contrib/doe/utils.py @@ -64,15 +64,16 @@ def rescale_FIM(FIM, param_vals): scaled_FIM = np.multiply(FIM, scaling_mat) return scaled_FIM + def get_parameters_from_suffix(suffix, fix_vars=False): """ Finds the Params within the suffix provided. It will also check to see - if there are Vars in the suffix provided. ``fix_vars`` will indicate + if there are Vars in the suffix provided. ``fix_vars`` will indicate if we should fix all the Vars in the set or not. Parameters ---------- - suffix: pyomo Suffix object, contains the components to be checked + suffix: pyomo Suffix object, contains the components to be checked as keys fix_vars: boolean, whether or not to fix the Vars, default = False @@ -92,5 +93,5 @@ def get_parameters_from_suffix(suffix, fix_vars=False): k.fix() else: pass # ToDo: Write error for suffix keys that aren't ParamData or VarData - - return param_list \ No newline at end of file + + return param_list From e2e469bc32fcffaa3ec7698efa29d4aeda536f56 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:42:03 -0400 Subject: [PATCH 119/203] Revert reactor experiment for update --- .../doe/examples/reactor_experiment.py | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 9b4ddae2bf5..68c33a4ca2b 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -59,15 +59,10 @@ def create_model(self): m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) # Arrhenius rate law equations - # m.A1 = pyo.Var(within=pyo.NonNegativeReals) - # m.E1 = pyo.Var(within=pyo.NonNegativeReals) - # m.A2 = pyo.Var(within=pyo.NonNegativeReals) - # m.E2 = pyo.Var(within=pyo.NonNegativeReals) - - m.A1 = pyo.Param(mutable=True) - m.E1 = pyo.Param(mutable=True) - m.A2 = pyo.Param(mutable=True) - m.E2 = pyo.Param(mutable=True) + m.A1 = pyo.Var(within=pyo.NonNegativeReals) + m.E1 = pyo.Var(within=pyo.NonNegativeReals) + m.A2 = pyo.Var(within=pyo.NonNegativeReals) + m.E2 = pyo.Var(within=pyo.NonNegativeReals) # Differential variables (Conc.) m.dCAdt = DerivativeVar(m.CA, wrt=m.t) @@ -135,15 +130,10 @@ def finalize_model(self): m.t.update(control_points) # Fix the unknown parameter values - # m.A1.fix(self.data["A1"]) - # m.A2.fix(self.data["A2"]) - # m.E1.fix(self.data["E1"]) - # m.E2.fix(self.data["E2"]) - - m.A1.set_value(self.data["A1"]) - m.A2.set_value(self.data["A2"]) - m.E1.set_value(self.data["E1"]) - m.E2.set_value(self.data["E2"]) + m.A1.fix(self.data["A1"]) + m.A2.fix(self.data["A2"]) + m.E1.fix(self.data["E1"]) + m.E2.fix(self.data["E2"]) # Add upper and lower bounds to the design variable, CA[0] m.CA[0].setlb(self.data["CA_bounds"][0]) From ce6d92ea0e21ceb7e683dd6d9cb73559ae0d2c49 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:55:09 -0400 Subject: [PATCH 120/203] Updated experiment to be inherited from `parmest` --- pyomo/contrib/doe/examples/reactor_experiment.py | 2 +- pyomo/contrib/doe/tests/experiment_class_example.py | 2 +- pyomo/contrib/doe/tests/experiment_class_example_flags.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 68c33a4ca2b..0eb9dcd4833 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -12,7 +12,7 @@ import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator -from pyomo.contrib.doe.experiment import Experiment +from pyomo.contrib.parmest.experiment import Experiment # ======================== diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index b4cdd13b416..2c555a732a8 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -12,7 +12,7 @@ import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator -from pyomo.contrib.doe.experiment import Experiment +from pyomo.contrib.parmest.experiment import Experiment import itertools import json diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index c014f9f3065..324ab7461d0 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -12,7 +12,7 @@ import pyomo.environ as pyo from pyomo.dae import ContinuousSet, DerivativeVar, Simulator -from pyomo.contrib.doe.experiment import Experiment +from pyomo.contrib.parmest.experiment import Experiment import itertools import json From 4d23cd88b784986b77dbd80899fe0d07890364d9 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:16:32 -0400 Subject: [PATCH 121/203] Update experiment inputs key as None --- pyomo/contrib/doe/examples/reactor_experiment.py | 9 +++++---- pyomo/contrib/doe/tests/experiment_class_example.py | 2 +- .../contrib/doe/tests/experiment_class_example_flags.py | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 0eb9dcd4833..981c4a2c306 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -196,12 +196,13 @@ def label_experiment(self): # Identify design variables (experiment inputs) for the model m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Add experimental input label for initial concentration - m.experiment_inputs.update( - (m.CA[t], pyo.ComponentUID(m.CA[t])) for t in [m.t.first()] - ) + # m.experiment_inputs.update( + # (m.CA[t], None) for t in [m.t.first()] + # ) + m.experiment_inputs[m.CA[m.t.first()]] = None # Add experimental input label for Temperature m.experiment_inputs.update( - (m.T[t], pyo.ComponentUID(m.T[t])) for t in m.t_control + (m.T[t], None) for t in m.t_control ) # Add unknown parameter labels diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index 2c555a732a8..54ac4f32d3c 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -219,7 +219,7 @@ def label_experiment_impl(self, index_sets_meas): index_sets_des = [[[m.t.first()]], [m.t_control]] m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.experiment_inputs.update( - (k, pyo.ComponentUID(k)) + (k, None) for k in expand_model_components(m, base_comp_des, index_sets_des) ) diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index 324ab7461d0..e0d8363b20a 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -230,7 +230,7 @@ def label_experiment_impl(self, index_sets_meas, flag=0): index_sets_des = [[[m.t.first()]], [m.t_control]] m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.experiment_inputs.update( - (k, pyo.ComponentUID(k)) + (k, None) for k in expand_model_components(m, base_comp_des, index_sets_des) ) From 19251d5e7e3c2b044f8f6fc8c14a93d1b87aed10 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:17:32 -0400 Subject: [PATCH 122/203] Simplify component identification in doe Per advice, using the ``context`` keyword to find parameters without using their string trees as before. --- pyomo/contrib/doe/doe.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 597c058d728..848da7d4986 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1069,10 +1069,6 @@ def build_block_scenarios(b, s): param = model.parameter_scenarios[s] - # Grabbing the index of the parameter without the "base_model" precursor - base_model_ind = param.name.split(".").index("base_model") - param_loc = ".".join(param.name.split(".")[(base_model_ind + 1) :]) - # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: diff = self.step * ( @@ -1088,7 +1084,7 @@ def build_block_scenarios(b, s): pass # Update parameter values for the given finite difference scenario - pyo.ComponentUID(param_loc).find_component_on(b).set_value( + pyo.ComponentUID(param, context=model.base_model).find_component_on(b).set_value( model.base_model.unknown_parameters[param] * (1 + diff) ) @@ -1106,11 +1102,7 @@ def build_block_scenarios(b, s): def global_design_fixing(m, s): if s == 0: return pyo.Constraint.Skip - ref_design_var = model.scenario_blocks[0].experiment_inputs[d] - ref_design_var_loc = ".".join(ref_design_var.get_repr().split(".")[0:]) - block_design_var = pyo.ComponentUID( - ref_design_var_loc - ).find_component_on(model.scenario_blocks[s]) + block_design_var = pyo.ComponentUID(d, context=model.scenario_blocks[0]).find_component_on(model.scenario_blocks[s]) return d == block_design_var setattr( From e0978114332940d475b6b1df63deb9b5540d9467 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:23:04 -0400 Subject: [PATCH 123/203] Update variable fixing readability in doe --- pyomo/contrib/doe/doe.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 848da7d4986..b7aad640ffd 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -274,7 +274,7 @@ def run_doe(self, model=None, results_file=None): # Deactivate objective expression and objective constraints (on a block), and fix design variables model.objective.deactivate() model.obj_cons.deactivate() - for comp, _ in model.scenario_blocks[0].experiment_inputs.items(): + for comp in model.scenario_blocks[0].experiment_inputs: comp.fix() model.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) @@ -290,7 +290,7 @@ def run_doe(self, model=None, results_file=None): model.dummy_obj.deactivate() # Reactivate objective and unfix experimental design decisions - for comp, _ in model.scenario_blocks[0].experiment_inputs.items(): + for comp in model.scenario_blocks[0].experiment_inputs: comp.unfix() model.objective.activate() model.obj_cons.activate() @@ -481,7 +481,7 @@ def _sequential_FIM(self, model=None): ) # Fix design variables - for comp, _ in model.experiment_inputs.items(): + for comp in model.experiment_inputs: comp.fix() measurement_vals = [] @@ -605,7 +605,7 @@ def _kaug_FIM(self, model=None): # call k_aug get_dsdp function # Solve the square problem # Deactivate object and fix experimental design decisions to make square - for comp, _ in model.experiment_inputs.items(): + for comp in model.experiment_inputs: comp.fix() self.solver.solve(model, tee=self.tee) @@ -1039,7 +1039,7 @@ def _generate_scenario_blocks(self, model=None): # experiment_inputs_Params = get_parameters_from_suffix(model.base_model.experiment_inputs, fix_vars=False) # Run base model to get initialized model and check model function - for comp, _ in model.base_model.experiment_inputs.items(): + for comp in model.base_model.experiment_inputs: comp.fix() try: @@ -1051,7 +1051,7 @@ def _generate_scenario_blocks(self, model=None): "Model from experiment did not solve appropriately. Make sure the model is well-posed." ) - for comp, _ in model.base_model.experiment_inputs.items(): + for comp in model.base_model.experiment_inputs: comp.unfix() # Generate blocks for finite difference scenarios From 73140d8851e3199d84fcdb0e291a5e9a8f1fd6ec Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:26:32 -0400 Subject: [PATCH 124/203] Change setattr to add_component --- pyomo/contrib/doe/doe.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index b7aad640ffd..884f7f4df68 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1105,11 +1105,7 @@ def global_design_fixing(m, s): block_design_var = pyo.ComponentUID(d, context=model.scenario_blocks[0]).find_component_on(model.scenario_blocks[s]) return d == block_design_var - setattr( - model, - con_name, - pyo.Constraint(model.scenarios, rule=global_design_fixing), - ) + model.add_component(con_name, pyo.Constraint(model.scenarios, rule=global_design_fixing)) # Clean up the base model used to generate the scenarios model.del_component(model.base_model) From 96b0a99277e81a22cacdb5526a1e41c55dfbea1b Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:33:15 -0400 Subject: [PATCH 125/203] Update import order --- pyomo/contrib/doe/doe.py | 46 ++++++++++++---------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 884f7f4df68..311d7443dd5 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -25,14 +25,12 @@ # publicly, and to permit other to do so. # ___________________________________________________________________________ -import pyomo.environ as pyo -from pyomo.opt import SolverStatus -from pyomo.common.timing import TicTocTimer -from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp - -from pyomo.contrib.parmest.utils.model_utils import convert_params_to_vars - -from pyomo.contrib.doe.utils import get_parameters_from_suffix +from enum import Enum +from itertools import permutations, product +import json +import logging +import math +from pathlib import Path from pyomo.common.dependencies import ( numpy as np, @@ -41,13 +39,13 @@ matplotlib as plt, ) -from itertools import permutations, product -from enum import Enum -from pathlib import Path +from pyomo.common.timing import TicTocTimer -import logging -import json -import math +from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp + +import pyomo.environ as pyo + +from pyomo.opt import SolverStatus class CalculationMode(Enum): @@ -1018,25 +1016,7 @@ def _generate_scenario_blocks(self, model=None): # TODO: Allow Params for `unknown_parameters` and `experiment_inputs` # May need to make a new converter Param to Var that allows non-string names/references to be passed - - # # Search for unknown parameters that are Params, or Vars. Params are updated to be fixed Vars - # unknown_parameter_Params = get_parameters_from_suffix(model.base_model.unknown_parameters, fix_vars=True) - - # # # Remove ``base_model`` precursor name on parameters - # # for ind, val in enumerate(unknown_parameter_Params): - # # base_model_ind = val.split(".").index("base_model") - # # unknown_parameter_Params[ind] = ".".join(val.split(".")[(base_model_ind + 1) :]) - - # print(unknown_parameter_Params) - - # # Change the unknown parameters that are Params to be Vars and fix them - # if len(unknown_parameter_Params) > 0: - # model.base_model = convert_params_to_vars(model.base_model, unknown_parameter_Params, fix_vars=True) - - # model.base_model.unknown_parameters.pprint() - - # # Search for experiment inputs that are Params, or Vars. Params are updated to be unfixed vars - # experiment_inputs_Params = get_parameters_from_suffix(model.base_model.experiment_inputs, fix_vars=False) + # Waiting on updates to the parmest params_to_vars utility function..... # Run base model to get initialized model and check model function for comp in model.base_model.experiment_inputs: From 4679cb7a1c594d28665e2bf88c2da3135a489a0f Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:36:07 -0400 Subject: [PATCH 126/203] Added unique component naming if model is provided --- pyomo/contrib/doe/doe.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 311d7443dd5..e79ecf2baa9 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -27,9 +27,11 @@ from enum import Enum from itertools import permutations, product + import json import logging import math + from pathlib import Path from pyomo.common.dependencies import ( @@ -38,7 +40,7 @@ pandas as pd, matplotlib as plt, ) - +from pyomo.common.modeling import unique_component_name from pyomo.common.timing import TicTocTimer from pyomo.contrib.sensitivity_toolbox.sens import get_dsdp @@ -252,6 +254,8 @@ def run_doe(self, model=None, results_file=None): # Model is none, set it to self.model if model is None: model = self.model + else: + model = unique_component_name(model, "design_of_experiments_block") # ToDo: potentially work with this for more complicated models # Create the full DoE model (build scenarios for F.D. scheme) From 20e5ae61242c56490b70ddbc28e0395f2fdfd65d Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:44:40 -0400 Subject: [PATCH 127/203] Added unique block addition to user models for doe tasks --- pyomo/contrib/doe/doe.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index e79ecf2baa9..ad89004a1ff 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -255,7 +255,9 @@ def run_doe(self, model=None, results_file=None): if model is None: model = self.model else: - model = unique_component_name(model, "design_of_experiments_block") + doe_block = pyo.Block() + doe_block_name = unique_component_name(model, "design_of_experiments_block") + model.add_component(doe_block_name, doe_block) # ToDo: potentially work with this for more complicated models # Create the full DoE model (build scenarios for F.D. scheme) @@ -406,6 +408,11 @@ def compute_FIM(self, model=None, method="sequential"): **self.args ).clone() model = self.compute_FIM_model + else: + doe_block = pyo.Block() + doe_block_name = unique_component_name(model, "design_of_experiments_block") + model.add_component(doe_block_name, doe_block) + self.compute_FIM_model = model self.check_model_labels(model=model) @@ -696,6 +703,10 @@ def create_doe_model(self, model=None): """ if model is None: model = self.model + else: + doe_block = pyo.Block() + doe_block_name = unique_component_name(model, "design_of_experiments_block") + model.add_component(doe_block_name, doe_block) # Developer recommendation: use the Cholesky decomposition for D-optimality # The explicit formula is available for benchmarking purposes and is NOT recommended From c06bfa520a884b36eb237cfa89c2e2d8f96a491b Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:47:52 -0400 Subject: [PATCH 128/203] Fixed potential bug --- pyomo/contrib/doe/doe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index ad89004a1ff..9abbda91858 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -282,7 +282,7 @@ def run_doe(self, model=None, results_file=None): comp.fix() model.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) - self.solver.solve(self.model, tee=self.tee) + self.solver.solve(model, tee=self.tee) # Track time to initialize the DoE model initialization_time = sp_timer.toc(msg=None) From cba2b476b17c631d23f4306785127c279ab40d0b Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:51:38 -0400 Subject: [PATCH 129/203] Made L_LB more verbose --- pyomo/contrib/doe/doe.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 9abbda91858..bfaffa0391d 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -86,7 +86,7 @@ def __init__( jac_initial=None, fim_initial=None, L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -137,7 +137,7 @@ def __init__( 2D numpy array as the initial values for the FIM. L_initial: 2D numpy array as the initial values for the Cholesky matrix. - L_LB: + L_diagonal_lower_bound: Lower bound for the values of the lower triangular Cholesky factorization matrix. default: 1e-7 solver: @@ -187,7 +187,7 @@ def __init__( self.L_initial = L_initial # Set the lower bound on the Cholesky lower triangular matrix - self.L_LB = L_LB + self.L_diagonal_lower_bound = L_diagonal_lower_bound # check if user-defined solver is given if solver: @@ -829,9 +829,9 @@ def init_cho(m, i, j): if i < j: model.L[c, d].fix(0.0) # Give LB to the diagonal entries - if self.L_LB: + if self.L_diagonal_lower_bound: if c == d: - model.L[c, d].setlb(self.L_LB) + model.L[c, d].setlb(self.L_diagonal_lower_bound) # jacobian rule def jacobian_rule(m, n, p): From 93706d03d3d21ba8ba6d2e9241dc6fac90d458fc Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:07:00 -0400 Subject: [PATCH 130/203] Updated ``det`` to be more verbose --- pyomo/contrib/doe/doe.py | 67 ++++------- pyomo/contrib/doe/tests/test_doe_build.py | 45 +++---- pyomo/contrib/doe/tests/test_doe_errors.py | 134 ++++++++++----------- pyomo/contrib/doe/tests/test_doe_solve.py | 76 ++++++------ 4 files changed, 135 insertions(+), 187 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index bfaffa0391d..7854fd243f7 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -56,7 +56,7 @@ class CalculationMode(Enum): class ObjectiveLib(Enum): - det = "det" + determinant = "determinant" trace = "trace" zero = "zero" @@ -79,13 +79,12 @@ def __init__( experiment, fd_formula="central", step=1e-3, - objective_option="det", + objective_option="determinant", scale_constant_value=1.0, scale_nominal_param_value=False, prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -115,7 +114,7 @@ def __init__( default: 1e-3 objective_option: String representation of the objective option. Current available options are: - ``det`` (for determinant, or D-optimality) and ``trace`` (for trace or + ``determinant`` (for determinant, or D-optimality) and ``trace`` (for trace or A-optimality) scale_constant_value: Constant scaling for the sensitivity matrix. Every element will be multiplied by this @@ -135,8 +134,6 @@ def __init__( 2D numpy array as the initial values for the sensitivity matrix. fim_initial: 2D numpy array as the initial values for the FIM. - L_initial: - 2D numpy array as the initial values for the Cholesky matrix. L_diagonal_lower_bound: Lower bound for the values of the lower triangular Cholesky factorization matrix. default: 1e-7 @@ -184,7 +181,6 @@ def __init__( # Set the initial values for the jacobian, fim, and L matrices self.jac_initial = jac_initial self.fim_initial = fim_initial - self.L_initial = L_initial # Set the lower bound on the Cholesky lower triangular matrix self.L_diagonal_lower_bound = L_diagonal_lower_bound @@ -316,8 +312,8 @@ def run_doe(self, model=None, results_file=None): for j, d in enumerate(model.parameter_names): model.L[c, d].value = L_vals_sq[i, j] - if hasattr(model, "det"): - model.det.value = np.linalg.det(np.array(self.get_FIM())) + if hasattr(model, "determinant"): + model.determinant.value = np.linalg.det(np.array(self.get_FIM())) # Solve the full model, which has now been initialized with the square solve res = self.solver.solve(model, tee=self.tee) @@ -712,7 +708,7 @@ def create_doe_model(self, model=None): # The explicit formula is available for benchmarking purposes and is NOT recommended if ( self.only_compute_fim_lower - and self.objective_option == ObjectiveLib.det + and self.objective_option == ObjectiveLib.determinant and not self.Cholesky_option ): raise ValueError( @@ -794,33 +790,12 @@ def initialize_fim(m, j, d): # To-Do: Look into this functionality..... # if cholesky, define L elements as variables - if self.Cholesky_option and self.objective_option == ObjectiveLib.det: - - # move the L matrix initial point to a dictionary - if self.L_initial is not None: - dict_cho = { - (bu, un): self.L_initial[i][j] - for i, bu in enumerate(model.parameter_names) - for j, un in enumerate(model.parameter_names) - } - - # use the L dictionary to initialize L matrix - def init_cho(m, i, j): - return dict_cho[(i, j)] - - # Define elements of Cholesky decomposition matrix as Pyomo variables and either - # Initialize with L in L_initial - if self.L_initial is not None: - model.L = pyo.Var( - model.parameter_names, model.parameter_names, initialize=init_cho - ) - # or initialize with the identity matrix - else: - model.L = pyo.Var( - model.parameter_names, - model.parameter_names, - initialize=identity_matrix, - ) + if self.Cholesky_option and self.objective_option == ObjectiveLib.determinant: + model.L = pyo.Var( + model.parameter_names, + model.parameter_names, + initialize=identity_matrix, + ) # loop over parameter name for i, c in enumerate(model.parameter_names): @@ -1127,7 +1102,7 @@ def create_objective_function(self, model=None): model = self.model if self.objective_option not in [ - ObjectiveLib.det, + ObjectiveLib.determinant, ObjectiveLib.trace, ObjectiveLib.zero, ]: @@ -1156,7 +1131,7 @@ def create_objective_function(self, model=None): ) ### Initialize the Cholesky decomposition matrix - if self.Cholesky_option and self.objective_option == ObjectiveLib.det: + if self.Cholesky_option and self.objective_option == ObjectiveLib.determinant: # Calculate the eigenvalues of the FIM matrix eig = np.linalg.eigvals(fim) @@ -1201,7 +1176,7 @@ def trace_calc(m): """ return model.trace == sum(model.fim[j, j] for j in model.parameter_names) - def det_general(m): + def determinant_general(m): r"""Calculate determinant. Can be applied to FIM of any size. det(A) = \sum_{\sigma in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) Use permutation() to get permutations, sgn() to get signature @@ -1233,9 +1208,9 @@ def det_general(m): ) for d in range(len(list_p)) ) - return model.det == det_perm + return model.determinant == det_perm - if self.Cholesky_option and self.objective_option == ObjectiveLib.det: + if self.Cholesky_option and self.objective_option == ObjectiveLib.determinant: model.obj_cons.cholesky_cons = pyo.Constraint( model.parameter_names, model.parameter_names, rule=cholesky_imp ) @@ -1244,14 +1219,14 @@ def det_general(m): sense=pyo.maximize, ) - elif self.objective_option == ObjectiveLib.det: + elif self.objective_option == ObjectiveLib.determinant: # if not cholesky but determinant, calculating det and evaluate the OBJ with det - model.det = pyo.Var( + model.determinant = pyo.Var( initialize=np.linalg.det(fim), bounds=(small_number, None) ) - model.obj_cons.det_rule = pyo.Constraint(rule=det_general) + model.obj_cons.determinant_rule = pyo.Constraint(rule=determinant_general) model.objective = pyo.Objective( - expr=pyo.log10(model.det + 1e-6), sense=pyo.maximize + expr=pyo.log10(model.determinant + 1e-6), sense=pyo.maximize ) elif self.objective_option == ObjectiveLib.trace: diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index c38bdd54386..6611225036e 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -111,8 +111,7 @@ def test_reactor_fd_central_check_fd_eqns(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -167,8 +166,7 @@ def test_reactor_fd_backward_check_fd_eqns(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -225,8 +223,7 @@ def test_reactor_fd_forward_check_fd_eqns(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -283,8 +280,7 @@ def test_reactor_fd_central_design_fixing(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -334,8 +330,7 @@ def test_reactor_fd_backward_design_fixing(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -385,8 +380,7 @@ def test_reactor_fd_forward_design_fixing(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -422,16 +416,13 @@ def test_reactor_fd_forward_design_fixing(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_user_initialization(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) FIM_prior = np.ones((4, 4)) FIM_initial = np.eye(4) + FIM_prior JAC_initial = np.ones((27, 4)) * 2 - L_initial = np.tril( - np.ones((4, 4)) * 3 - ) # Must input lower triangular to get equality doe_obj = DesignOfExperiments( experiment, @@ -443,8 +434,7 @@ def test_reactor_check_user_initialization(self): prior_FIM=FIM_prior, jac_initial=JAC_initial, fim_initial=FIM_initial, - L_initial=L_initial, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -460,7 +450,6 @@ def test_reactor_check_user_initialization(self): # Make sure they match the inputs we gave assert np.array_equal(FIM, FIM_initial) assert np.array_equal(FIM_prior, FIM_prior_model) - assert np.array_equal(L_initial, L) assert np.array_equal(JAC_initial, Q) @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @@ -483,8 +472,7 @@ def test_update_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -520,8 +508,7 @@ def test_get_experiment_inputs_without_blocks(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -555,8 +542,7 @@ def test_get_experiment_outputs_without_blocks(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -590,8 +576,7 @@ def test_get_measurement_error_without_blocks(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -625,8 +610,7 @@ def test_get_unknown_parameters_without_blocks(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -661,8 +645,7 @@ def test_generate_blocks_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index ec2024ac5a6..49309c4d358 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -57,8 +57,7 @@ def test_reactor_check_no_get_labeled_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -84,8 +83,7 @@ def test_reactor_check_no_experiment_outputs(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -117,8 +115,7 @@ def test_reactor_check_no_measurement_error(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -150,8 +147,7 @@ def test_reactor_check_no_experiment_inputs(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -183,8 +179,7 @@ def test_reactor_check_no_unknown_parameters(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -218,8 +213,7 @@ def test_reactor_check_bad_prior_size(self): prior_FIM=prior_FIM, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -255,8 +249,7 @@ def test_reactor_check_bad_jacobian_init_size(self): prior_FIM=None, jac_initial=jac_init, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -292,8 +285,7 @@ def test_reactor_check_unbuilt_update_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -326,9 +318,8 @@ def test_reactor_check_none_update_FIM(self): scale_nominal_param_value=True, prior_FIM=None, jac_initial=None, - fim_initial=None, - L_initial=None, - L_LB=1e-7, + fim_initial=None, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -360,8 +351,8 @@ def test_reactor_check_results_file_name(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -394,8 +385,8 @@ def test_reactor_check_measurement_and_output_length_match(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -416,7 +407,7 @@ def test_reactor_check_measurement_and_output_length_match(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_grid_search_des_range_inputs(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -430,8 +421,8 @@ def test_reactor_grid_search_des_range_inputs(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -454,7 +445,7 @@ def test_reactor_grid_search_des_range_inputs(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_premature_figure_drawing(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -468,8 +459,8 @@ def test_reactor_premature_figure_drawing(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -488,7 +479,7 @@ def test_reactor_premature_figure_drawing(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_no_des_var_names(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -502,8 +493,8 @@ def test_reactor_figure_drawing_no_des_var_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -528,7 +519,7 @@ def test_reactor_figure_drawing_no_des_var_names(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_no_sens_names(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -542,8 +533,8 @@ def test_reactor_figure_drawing_no_sens_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -567,7 +558,7 @@ def test_reactor_figure_drawing_no_sens_names(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_no_fixed_names(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -581,8 +572,8 @@ def test_reactor_figure_drawing_no_fixed_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -606,7 +597,7 @@ def test_reactor_figure_drawing_no_fixed_names(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_bad_fixed_names(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -620,8 +611,8 @@ def test_reactor_figure_drawing_bad_fixed_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -649,7 +640,7 @@ def test_reactor_figure_drawing_bad_fixed_names(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_bad_sens_names(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -663,8 +654,8 @@ def test_reactor_figure_drawing_bad_sens_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -707,8 +698,8 @@ def test_reactor_check_get_FIM_without_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -742,8 +733,8 @@ def test_reactor_check_get_sens_mat_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -777,8 +768,8 @@ def test_reactor_check_get_exp_inputs_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -812,8 +803,8 @@ def test_reactor_check_get_exp_outputs_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -847,8 +838,8 @@ def test_reactor_check_get_unknown_params_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -882,8 +873,8 @@ def test_reactor_check_get_meas_error_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -917,8 +908,8 @@ def test_multiple_exp_not_implemented_seq(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -951,8 +942,8 @@ def test_multiple_exp_not_implemented_sim(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -985,8 +976,8 @@ def test_update_unknown_parameter_values_not_implemented_seq(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -1020,8 +1011,8 @@ def test_bad_FD_generate_scens(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -1057,8 +1048,8 @@ def test_bad_FD_seq_compute_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -1093,8 +1084,8 @@ def test_bad_objective(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -1129,8 +1120,8 @@ def test_no_model_for_objective(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, @@ -1165,8 +1156,7 @@ def test_bad_compute_FIM_option(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args={"flag": flag_val}, diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index bdef07c7fed..1c79225536c 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -113,8 +113,8 @@ def test_reactor_fd_central_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -153,8 +153,8 @@ def test_reactor_fd_forward_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -192,8 +192,8 @@ def test_reactor_fd_backward_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -219,7 +219,7 @@ def test_reactor_fd_backward_solve(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_obj_det_solve(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -233,8 +233,8 @@ def test_reactor_obj_det_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -250,7 +250,7 @@ def test_reactor_obj_det_solve(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_obj_cholesky_solve(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -264,8 +264,8 @@ def test_reactor_obj_cholesky_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -290,7 +290,7 @@ def test_reactor_obj_cholesky_solve(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq_centr(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -304,8 +304,8 @@ def test_compute_FIM_seq_centr(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -319,7 +319,7 @@ def test_compute_FIM_seq_centr(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq_forward(self): fd_method = "forward" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -333,8 +333,8 @@ def test_compute_FIM_seq_forward(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -352,7 +352,7 @@ def test_compute_FIM_seq_forward(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_kaug(self): fd_method = "forward" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -366,8 +366,8 @@ def test_compute_FIM_kaug(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -381,7 +381,7 @@ def test_compute_FIM_kaug(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq_backward(self): fd_method = "backward" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -395,8 +395,8 @@ def test_compute_FIM_seq_backward(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -411,7 +411,7 @@ def test_compute_FIM_seq_backward(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_grid_search(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -425,8 +425,8 @@ def test_reactor_grid_search(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -457,7 +457,7 @@ def test_reactor_grid_search(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_rescale_FIM(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperiment(data_ex, 10, 3) @@ -472,8 +472,8 @@ def test_rescale_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -492,8 +492,8 @@ def test_rescale_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -530,7 +530,7 @@ def test_rescale_FIM(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_solve_bad_model(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperimentBad(data_ex, 10, 3) @@ -544,8 +544,8 @@ def test_reactor_solve_bad_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, @@ -564,7 +564,7 @@ def test_reactor_solve_bad_model(self): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_grid_search_bad_model(self): fd_method = "central" - obj_used = "det" + obj_used = "determinant" experiment = FullReactorExperimentBad(data_ex, 10, 3) @@ -578,8 +578,8 @@ def test_reactor_grid_search_bad_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + + L_diagonal_lower_bound=1e-7, solver=None, tee=False, args=None, From c36cedbba72a72fa5f8464b3f9ba657b461ac3db Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:10:29 -0400 Subject: [PATCH 131/203] Made ``args`` more verbose ``args`` are additional arguments that go to the get_labeled_model function. So the name was changed to ``get_labeled_model_args``` --- pyomo/contrib/doe/doe.py | 22 ++++---- pyomo/contrib/doe/tests/test_doe_build.py | 26 ++++----- pyomo/contrib/doe/tests/test_doe_errors.py | 64 +++++++++++----------- pyomo/contrib/doe/tests/test_doe_solve.py | 28 +++++----- 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 7854fd243f7..361c4ccc51e 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -88,7 +88,7 @@ def __init__( L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, logger_level=logging.WARNING, _Cholesky_option=True, _only_compute_fim_lower=True, @@ -142,7 +142,7 @@ def __init__( If not specified, default solver is set to IPOPT with MA57. tee: Solver option to be passed for verbose output. - args: + get_labeled_model_args: Additional arguments for the ``get_labeled_model`` function on the Experiment object. _Cholesky_option: Boolean value of whether or not to use the choleskyn factorization to compute the @@ -198,10 +198,10 @@ def __init__( self.tee = tee - # Set args as an empty dict if no arguments are passed - if args is None: - args = {} - self.args = args + # Set get_labeled_model_args as an empty dict if no arguments are passed + if get_labeled_model_args is None: + get_labeled_model_args = {} + self.get_labeled_model_args = get_labeled_model_args # Revtrieve logger and set logging level self.logger = logging.getLogger(__name__) @@ -401,7 +401,7 @@ def compute_FIM(self, model=None, method="sequential"): """ if model is None: self.compute_FIM_model = self.experiment.get_labeled_model( - **self.args + **self.get_labeled_model_args ).clone() model = self.compute_FIM_model else: @@ -453,7 +453,7 @@ def _sequential_FIM(self, model=None): # Build a singular model instance if model is None: self.compute_FIM_model = self.experiment.get_labeled_model( - **self.args + **self.get_labeled_model_args ).clone() model = self.compute_FIM_model @@ -599,7 +599,7 @@ def _kaug_FIM(self, model=None): # compute_FIM_model needs to be the right version for function to work. if model is None: self.compute_FIM_model = self.experiment.get_labeled_model( - **self.args + **self.get_labeled_model_args ).clone() model = self.compute_FIM_model @@ -942,7 +942,7 @@ def _generate_scenario_blocks(self, model=None): model = self.model # Generate initial scenario to populate unknown parameter values - model.base_model = self.experiment.get_labeled_model(**self.args).clone() + model.base_model = self.experiment.get_labeled_model(**self.get_labeled_model_args).clone() # Check the model that labels are correct self.check_model_labels(model=model.base_model) @@ -1393,7 +1393,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): self.logger.info("Beginning Full Factorial Design.") # Make new model for factorial design - self.factorial_model = self.experiment.get_labeled_model(**self.args).clone() + self.factorial_model = self.experiment.get_labeled_model(**self.get_labeled_model_args).clone() model = self.factorial_model # Permute the inputs to be aligned with the experiment input indices diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 6611225036e..9751153aea8 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -114,7 +114,7 @@ def test_reactor_fd_central_check_fd_eqns(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -169,7 +169,7 @@ def test_reactor_fd_backward_check_fd_eqns(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -226,7 +226,7 @@ def test_reactor_fd_forward_check_fd_eqns(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -283,7 +283,7 @@ def test_reactor_fd_central_design_fixing(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -333,7 +333,7 @@ def test_reactor_fd_backward_design_fixing(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -383,7 +383,7 @@ def test_reactor_fd_forward_design_fixing(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -437,7 +437,7 @@ def test_reactor_check_user_initialization(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -475,7 +475,7 @@ def test_update_FIM(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -511,7 +511,7 @@ def test_get_experiment_inputs_without_blocks(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -545,7 +545,7 @@ def test_get_experiment_outputs_without_blocks(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -579,7 +579,7 @@ def test_get_measurement_error_without_blocks(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -613,7 +613,7 @@ def test_get_unknown_parameters_without_blocks(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -648,7 +648,7 @@ def test_generate_blocks_without_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 49309c4d358..9405a8eaf46 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -60,7 +60,7 @@ def test_reactor_check_no_get_labeled_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -86,7 +86,7 @@ def test_reactor_check_no_experiment_outputs(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -118,7 +118,7 @@ def test_reactor_check_no_measurement_error(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -150,7 +150,7 @@ def test_reactor_check_no_experiment_inputs(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -182,7 +182,7 @@ def test_reactor_check_no_unknown_parameters(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -216,7 +216,7 @@ def test_reactor_check_bad_prior_size(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -252,7 +252,7 @@ def test_reactor_check_bad_jacobian_init_size(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -288,7 +288,7 @@ def test_reactor_check_unbuilt_update_FIM(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -322,7 +322,7 @@ def test_reactor_check_none_update_FIM(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -355,7 +355,7 @@ def test_reactor_check_results_file_name(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -389,7 +389,7 @@ def test_reactor_check_measurement_and_output_length_match(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -425,7 +425,7 @@ def test_reactor_grid_search_des_range_inputs(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -463,7 +463,7 @@ def test_reactor_premature_figure_drawing(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -497,7 +497,7 @@ def test_reactor_figure_drawing_no_des_var_names(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -537,7 +537,7 @@ def test_reactor_figure_drawing_no_sens_names(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -576,7 +576,7 @@ def test_reactor_figure_drawing_no_fixed_names(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -615,7 +615,7 @@ def test_reactor_figure_drawing_bad_fixed_names(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -658,7 +658,7 @@ def test_reactor_figure_drawing_bad_sens_names(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -702,7 +702,7 @@ def test_reactor_check_get_FIM_without_FIM(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -737,7 +737,7 @@ def test_reactor_check_get_sens_mat_without_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -772,7 +772,7 @@ def test_reactor_check_get_exp_inputs_without_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -807,7 +807,7 @@ def test_reactor_check_get_exp_outputs_without_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -842,7 +842,7 @@ def test_reactor_check_get_unknown_params_without_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -877,7 +877,7 @@ def test_reactor_check_get_meas_error_without_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -912,7 +912,7 @@ def test_multiple_exp_not_implemented_seq(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -946,7 +946,7 @@ def test_multiple_exp_not_implemented_sim(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -980,7 +980,7 @@ def test_update_unknown_parameter_values_not_implemented_seq(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -1015,7 +1015,7 @@ def test_bad_FD_generate_scens(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -1052,7 +1052,7 @@ def test_bad_FD_seq_compute_FIM(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -1088,7 +1088,7 @@ def test_bad_objective(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -1124,7 +1124,7 @@ def test_no_model_for_objective(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -1159,7 +1159,7 @@ def test_bad_compute_FIM_option(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args={"flag": flag_val}, + get_labeled_model_args={"flag": flag_val}, _Cholesky_option=True, _only_compute_fim_lower=True, ) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 1c79225536c..07627a3d2aa 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -117,7 +117,7 @@ def test_reactor_fd_central_solve(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -157,7 +157,7 @@ def test_reactor_fd_forward_solve(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -196,7 +196,7 @@ def test_reactor_fd_backward_solve(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -237,7 +237,7 @@ def test_reactor_obj_det_solve(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=False, _only_compute_fim_lower=False, ) @@ -268,7 +268,7 @@ def test_reactor_obj_cholesky_solve(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -308,7 +308,7 @@ def test_compute_FIM_seq_centr(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -337,7 +337,7 @@ def test_compute_FIM_seq_forward(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -370,7 +370,7 @@ def test_compute_FIM_kaug(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -399,7 +399,7 @@ def test_compute_FIM_seq_backward(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -429,7 +429,7 @@ def test_reactor_grid_search(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -476,7 +476,7 @@ def test_rescale_FIM(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -496,7 +496,7 @@ def test_rescale_FIM(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -548,7 +548,7 @@ def test_reactor_solve_bad_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -582,7 +582,7 @@ def test_reactor_grid_search_bad_model(self): L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, logger_level=logging.ERROR, From ddc8ec8d3b55d01e099ee94efd664d65a5ef55e7 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:21:44 -0400 Subject: [PATCH 132/203] Added naming map for results object --- pyomo/contrib/doe/doe.py | 4 ++++ .../doe/examples/reactor_compute_factorial_FIM.py | 7 +++---- pyomo/contrib/doe/examples/reactor_example.py | 9 +++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 361c4ccc51e..ec790a8651b 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -342,9 +342,13 @@ def run_doe(self, model=None, results_file=None): self.results["FIM"] = fim_local self.results["Sensitivity Matrix"] = self.get_sensitivity_matrix() self.results["Experiment Design"] = self.get_experiment_input_values() + self.results["Experiment Design Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].experiment_inputs] self.results["Experiment Outputs"] = self.get_experiment_output_values() + self.results["Experiment Output Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].experiment_outputs] self.results["Unknown Parameters"] = self.get_unknown_parameter_values() + self.results["Unknown Parameter Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].unknown_parameters] self.results["Measurement Error"] = self.get_measurement_error_values() + self.results["Measurement Error Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].measurement_error] self.results["Prior FIM"] = [list(row) for row in list(self.prior_FIM)] diff --git a/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py index c7f10d115b3..0826a131bab 100644 --- a/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py +++ b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py @@ -42,7 +42,7 @@ def run_reactor_doe(): step_size = 1e-3 # Use the determinant objective with scaled sensitivity matrix - objective_option = "det" + objective_option = "determinant" scale_nominal_param_value = True # Create the DesignOfExperiments object @@ -59,11 +59,10 @@ def run_reactor_doe(): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) diff --git a/pyomo/contrib/doe/examples/reactor_example.py b/pyomo/contrib/doe/examples/reactor_example.py index 2f7cd7b43e3..c17bd097303 100644 --- a/pyomo/contrib/doe/examples/reactor_example.py +++ b/pyomo/contrib/doe/examples/reactor_example.py @@ -42,7 +42,7 @@ def run_reactor_doe(): step_size = 1e-3 # Use the determinant objective with scaled sensitivity matrix - objective_option = "det" + objective_option = "determinant" scale_nominal_param_value = True # Create the DesignOfExperiments object @@ -59,11 +59,10 @@ def run_reactor_doe(): prior_FIM=None, jac_initial=None, fim_initial=None, - L_initial=None, - L_LB=1e-7, + L_diagonal_lower_bound=1e-7, solver=None, tee=False, - args=None, + get_labeled_model_args=None, _Cholesky_option=True, _only_compute_fim_lower=True, ) @@ -89,6 +88,8 @@ def run_reactor_doe(): ) ) + print(doe_obj.results["Experiment Design Names"]) + if __name__ == "__main__": run_reactor_doe() From 2c22203a2d02eeb3ca9f4e60e840503882be99de Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:27:25 -0400 Subject: [PATCH 133/203] Updated import order for test files --- pyomo/contrib/doe/tests/test_doe_build.py | 10 ++++------ pyomo/contrib/doe/tests/test_doe_errors.py | 9 ++++----- pyomo/contrib/doe/tests/test_doe_solve.py | 10 +++++----- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 9751153aea8..6efe731c08b 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -8,23 +8,21 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ +from pathlib import Path + from pyomo.common.dependencies import ( numpy as np, numpy_available, pandas as pd, pandas_available, ) +import pyomo.common.unittest as unittest -from pyomo.contrib.doe.tests.experiment_class_example import * from pyomo.contrib.doe import * - - -import pyomo.common.unittest as unittest +from pyomo.contrib.doe.tests.experiment_class_example import * from pyomo.opt import SolverFactory -from pathlib import Path - ipopt_available = SolverFactory("ipopt").available() DATA_DIR = Path(__file__).parent diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 9405a8eaf46..025371ab8a7 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -8,22 +8,21 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ +from pathlib import Path + from pyomo.common.dependencies import ( numpy as np, numpy_available, pandas as pd, pandas_available, ) +import pyomo.common.unittest as unittest -from pyomo.contrib.doe.tests.experiment_class_example_flags import * from pyomo.contrib.doe import * - -import pyomo.common.unittest as unittest +from pyomo.contrib.doe.tests.experiment_class_example_flags import * from pyomo.opt import SolverFactory -from pathlib import Path - ipopt_available = SolverFactory("ipopt").available() DATA_DIR = Path(__file__).parent diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 07627a3d2aa..a3645fabbed 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -8,6 +8,9 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ +import logging +from pathlib import Path + from pyomo.common.dependencies import ( numpy as np, numpy_available, @@ -15,22 +18,19 @@ pandas_available, scipy_available, ) +import pyomo.common.unittest as unittest +from pyomo.contrib.doe import * from pyomo.contrib.doe.tests.experiment_class_example import * from pyomo.contrib.doe.tests.experiment_class_example_flags import ( FullReactorExperimentBad, ) -from pyomo.contrib.doe import * from pyomo.contrib.doe.utils import * -import pyomo.common.unittest as unittest import pyomo.environ as pyo from pyomo.opt import SolverFactory -from pathlib import Path - -import logging ipopt_available = SolverFactory("ipopt").available() k_aug_available = SolverFactory('k_aug', solver_io='nl', validate=False) From c2967cd3be355995e75a0b1e4c5274d75d41e16b Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 5 Aug 2024 13:33:24 -0400 Subject: [PATCH 134/203] Remove stale Enum structures --- pyomo/contrib/doe/__init__.py | 2 -- pyomo/contrib/doe/doe.py | 11 ----------- 2 files changed, 13 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index aaca4db12fb..c0dcce8596d 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -10,9 +10,7 @@ # ___________________________________________________________________________ from .doe import ( DesignOfExperiments, - CalculationMode, ObjectiveLib, - ModelOptionLib, FiniteDifferenceStep, ) from .tests import experiment_class_example, experiment_class_example_flags diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index ec790a8651b..f4ae4280ec6 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -50,23 +50,12 @@ from pyomo.opt import SolverStatus -class CalculationMode(Enum): - sequential_finite = "sequential_finite" - direct_kaug = "direct_kaug" - - class ObjectiveLib(Enum): determinant = "determinant" trace = "trace" zero = "zero" -class ModelOptionLib(Enum): - parmest = "parmest" - stage1 = "stage1" - stage2 = "stage2" - - class FiniteDifferenceStep(Enum): forward = "forward" central = "central" From 383cbc7c5e663e4df0c709a17d8a64be0228f192 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 5 Aug 2024 13:31:44 -0500 Subject: [PATCH 135/203] Ran black and typos --- pyomo/contrib/doe/__init__.py | 6 +-- pyomo/contrib/doe/doe.py | 46 +++++++++++++------ .../doe/examples/reactor_experiment.py | 4 +- .../doe/tests/experiment_class_example.py | 3 +- pyomo/contrib/doe/tests/test_doe_errors.py | 24 +--------- pyomo/contrib/doe/tests/test_doe_solve.py | 14 ------ 6 files changed, 36 insertions(+), 61 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index c0dcce8596d..72cad1cabdb 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -8,11 +8,7 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ -from .doe import ( - DesignOfExperiments, - ObjectiveLib, - FiniteDifferenceStep, -) +from .doe import DesignOfExperiments, ObjectiveLib, FiniteDifferenceStep from .tests import experiment_class_example, experiment_class_example_flags from .utils import rescale_FIM, get_parameters_from_suffix from .examples import reactor_experiment, reactor_example, reactor_compute_factorial_FIM diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index f4ae4280ec6..ab5d9df3faa 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -331,13 +331,25 @@ def run_doe(self, model=None, results_file=None): self.results["FIM"] = fim_local self.results["Sensitivity Matrix"] = self.get_sensitivity_matrix() self.results["Experiment Design"] = self.get_experiment_input_values() - self.results["Experiment Design Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].experiment_inputs] + self.results["Experiment Design Names"] = [ + str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) + for k in self.model.scenario_blocks[0].experiment_inputs + ] self.results["Experiment Outputs"] = self.get_experiment_output_values() - self.results["Experiment Output Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].experiment_outputs] + self.results["Experiment Output Names"] = [ + str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) + for k in self.model.scenario_blocks[0].experiment_outputs + ] self.results["Unknown Parameters"] = self.get_unknown_parameter_values() - self.results["Unknown Parameter Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].unknown_parameters] + self.results["Unknown Parameter Names"] = [ + str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) + for k in self.model.scenario_blocks[0].unknown_parameters + ] self.results["Measurement Error"] = self.get_measurement_error_values() - self.results["Measurement Error Names"] = [str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) for k in self.model.scenario_blocks[0].measurement_error] + self.results["Measurement Error Names"] = [ + str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) + for k in self.model.scenario_blocks[0].measurement_error + ] self.results["Prior FIM"] = [list(row) for row in list(self.prior_FIM)] @@ -785,9 +797,7 @@ def initialize_fim(m, j, d): # if cholesky, define L elements as variables if self.Cholesky_option and self.objective_option == ObjectiveLib.determinant: model.L = pyo.Var( - model.parameter_names, - model.parameter_names, - initialize=identity_matrix, + model.parameter_names, model.parameter_names, initialize=identity_matrix ) # loop over parameter name @@ -935,7 +945,9 @@ def _generate_scenario_blocks(self, model=None): model = self.model # Generate initial scenario to populate unknown parameter values - model.base_model = self.experiment.get_labeled_model(**self.get_labeled_model_args).clone() + model.base_model = self.experiment.get_labeled_model( + **self.get_labeled_model_args + ).clone() # Check the model that labels are correct self.check_model_labels(model=model.base_model) @@ -1047,9 +1059,9 @@ def build_block_scenarios(b, s): pass # Update parameter values for the given finite difference scenario - pyo.ComponentUID(param, context=model.base_model).find_component_on(b).set_value( - model.base_model.unknown_parameters[param] * (1 + diff) - ) + pyo.ComponentUID(param, context=model.base_model).find_component_on( + b + ).set_value(model.base_model.unknown_parameters[param] * (1 + diff)) model.scenario_blocks = pyo.Block(model.scenarios, rule=build_block_scenarios) @@ -1065,10 +1077,14 @@ def build_block_scenarios(b, s): def global_design_fixing(m, s): if s == 0: return pyo.Constraint.Skip - block_design_var = pyo.ComponentUID(d, context=model.scenario_blocks[0]).find_component_on(model.scenario_blocks[s]) + block_design_var = pyo.ComponentUID( + d, context=model.scenario_blocks[0] + ).find_component_on(model.scenario_blocks[s]) return d == block_design_var - model.add_component(con_name, pyo.Constraint(model.scenarios, rule=global_design_fixing)) + model.add_component( + con_name, pyo.Constraint(model.scenarios, rule=global_design_fixing) + ) # Clean up the base model used to generate the scenarios model.del_component(model.base_model) @@ -1386,7 +1402,9 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): self.logger.info("Beginning Full Factorial Design.") # Make new model for factorial design - self.factorial_model = self.experiment.get_labeled_model(**self.get_labeled_model_args).clone() + self.factorial_model = self.experiment.get_labeled_model( + **self.get_labeled_model_args + ).clone() model = self.factorial_model # Permute the inputs to be aligned with the experiment input indices diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 981c4a2c306..52056c01fa2 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -201,9 +201,7 @@ def label_experiment(self): # ) m.experiment_inputs[m.CA[m.t.first()]] = None # Add experimental input label for Temperature - m.experiment_inputs.update( - (m.T[t], None) for t in m.t_control - ) + m.experiment_inputs.update((m.T[t], None) for t in m.t_control) # Add unknown parameter labels m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index 54ac4f32d3c..03c8ca3a784 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -219,8 +219,7 @@ def label_experiment_impl(self, index_sets_meas): index_sets_des = [[[m.t.first()]], [m.t_control]] m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) m.experiment_inputs.update( - (k, None) - for k in expand_model_components(m, base_comp_des, index_sets_des) + (k, None) for k in expand_model_components(m, base_comp_des, index_sets_des) ) m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 025371ab8a7..ee3b0cc27be 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -317,7 +317,7 @@ def test_reactor_check_none_update_FIM(self): scale_nominal_param_value=True, prior_FIM=None, jac_initial=None, - fim_initial=None, + fim_initial=None, L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -350,7 +350,6 @@ def test_reactor_check_results_file_name(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -384,7 +383,6 @@ def test_reactor_check_measurement_and_output_length_match(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -420,7 +418,6 @@ def test_reactor_grid_search_des_range_inputs(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -458,7 +455,6 @@ def test_reactor_premature_figure_drawing(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -492,7 +488,6 @@ def test_reactor_figure_drawing_no_des_var_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -532,7 +527,6 @@ def test_reactor_figure_drawing_no_sens_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -571,7 +565,6 @@ def test_reactor_figure_drawing_no_fixed_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -610,7 +603,6 @@ def test_reactor_figure_drawing_bad_fixed_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -653,7 +645,6 @@ def test_reactor_figure_drawing_bad_sens_names(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -697,7 +688,6 @@ def test_reactor_check_get_FIM_without_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -732,7 +722,6 @@ def test_reactor_check_get_sens_mat_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -767,7 +756,6 @@ def test_reactor_check_get_exp_inputs_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -802,7 +790,6 @@ def test_reactor_check_get_exp_outputs_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -837,7 +824,6 @@ def test_reactor_check_get_unknown_params_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -872,7 +858,6 @@ def test_reactor_check_get_meas_error_without_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -907,7 +892,6 @@ def test_multiple_exp_not_implemented_seq(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -941,7 +925,6 @@ def test_multiple_exp_not_implemented_sim(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -975,7 +958,6 @@ def test_update_unknown_parameter_values_not_implemented_seq(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -1010,7 +992,6 @@ def test_bad_FD_generate_scens(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -1047,7 +1028,6 @@ def test_bad_FD_seq_compute_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -1083,7 +1063,6 @@ def test_bad_objective(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -1119,7 +1098,6 @@ def test_no_model_for_objective(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index a3645fabbed..6439b9f8c37 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -113,7 +113,6 @@ def test_reactor_fd_central_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -153,7 +152,6 @@ def test_reactor_fd_forward_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -192,7 +190,6 @@ def test_reactor_fd_backward_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -233,7 +230,6 @@ def test_reactor_obj_det_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -264,7 +260,6 @@ def test_reactor_obj_cholesky_solve(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -304,7 +299,6 @@ def test_compute_FIM_seq_centr(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -333,7 +327,6 @@ def test_compute_FIM_seq_forward(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -366,7 +359,6 @@ def test_compute_FIM_kaug(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -395,7 +387,6 @@ def test_compute_FIM_seq_backward(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -425,7 +416,6 @@ def test_reactor_grid_search(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -472,7 +462,6 @@ def test_rescale_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -492,7 +481,6 @@ def test_rescale_FIM(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -544,7 +532,6 @@ def test_reactor_solve_bad_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, @@ -578,7 +565,6 @@ def test_reactor_grid_search_bad_model(self): prior_FIM=None, jac_initial=None, fim_initial=None, - L_diagonal_lower_bound=1e-7, solver=None, tee=False, From c28d103fefc7937d22c48203722749eb5ed54106 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 6 Aug 2024 20:35:45 -0500 Subject: [PATCH 136/203] Clean up init file --- pyomo/contrib/doe/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index 72cad1cabdb..775fc6fb47d 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -9,7 +9,4 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ from .doe import DesignOfExperiments, ObjectiveLib, FiniteDifferenceStep -from .tests import experiment_class_example, experiment_class_example_flags from .utils import rescale_FIM, get_parameters_from_suffix -from .examples import reactor_experiment, reactor_example, reactor_compute_factorial_FIM -from .experiment import Experiment From 52433f43d52eb94ecfa0be4cfe000d72fb922fc3 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 6 Aug 2024 20:41:23 -0500 Subject: [PATCH 137/203] Updating example with feedback --- .../doe/examples/reactor_compute_factorial_FIM.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py index 0826a131bab..b6703606781 100644 --- a/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py +++ b/pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py @@ -19,14 +19,14 @@ from pathlib import Path -# Example to run a DOE on the reactor +# Example to run a DoE on the reactor def run_reactor_doe(): # Read in file DATA_DIR = Path(__file__).parent file_path = DATA_DIR / "result.json" - f = open(file_path) - data_ex = json.load(f) + with open(file_path) as f: + data_ex = json.load(f) # Put temperature control time points into correct format for reactor experiment data_ex["control_points"] = { @@ -46,9 +46,9 @@ def run_reactor_doe(): scale_nominal_param_value = True # Create the DesignOfExperiments object - # We will not be passing any prior information in this example - # and allow the experiment object and the DesignOfExperiments - # call of ``run_doe`` perform model initialization. + # We will not be passing any prior information in this example. + # We also will rely on the initialization routine within + # the DesignOfExperiments class. doe_obj = DesignOfExperiments( experiment, fd_formula=fd_formula, From 678b28d28b266b6844aab37770a2eca50de9f839 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Thu, 8 Aug 2024 19:01:36 -0500 Subject: [PATCH 138/203] Made imports explicit --- pyomo/contrib/doe/tests/test_doe_solve.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 6439b9f8c37..140e65288fc 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -8,6 +8,7 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ +import json import logging from pathlib import Path @@ -20,12 +21,12 @@ ) import pyomo.common.unittest as unittest -from pyomo.contrib.doe import * -from pyomo.contrib.doe.tests.experiment_class_example import * +from pyomo.contrib.doe import DesignOfExperiments +from pyomo.contrib.doe.tests.experiment_class_example import FullReactorExperiment from pyomo.contrib.doe.tests.experiment_class_example_flags import ( FullReactorExperimentBad, ) -from pyomo.contrib.doe.utils import * +from pyomo.contrib.doe.utils import rescale_FIM import pyomo.environ as pyo From 1920965df6933c8530b0bc88ebfcb71d266e4a07 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Fri, 9 Aug 2024 08:38:12 -0500 Subject: [PATCH 139/203] Made imports explicit in other tests --- pyomo/contrib/doe/tests/test_doe_build.py | 7 +++++-- pyomo/contrib/doe/tests/test_doe_errors.py | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 6efe731c08b..d1eb3c11412 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -8,6 +8,7 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ +import json from pathlib import Path from pyomo.common.dependencies import ( @@ -18,8 +19,10 @@ ) import pyomo.common.unittest as unittest -from pyomo.contrib.doe import * -from pyomo.contrib.doe.tests.experiment_class_example import * +from pyomo.contrib.doe import DesignOfExperiments +from pyomo.contrib.doe.tests.experiment_class_example import FullReactorExperiment + +import pyomo.environ as pyo from pyomo.opt import SolverFactory diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index ee3b0cc27be..986cdcb4f5c 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -8,6 +8,7 @@ # rights in this software. # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ +import json from pathlib import Path from pyomo.common.dependencies import ( @@ -18,8 +19,11 @@ ) import pyomo.common.unittest as unittest -from pyomo.contrib.doe import * -from pyomo.contrib.doe.tests.experiment_class_example_flags import * +from pyomo.contrib.doe import DesignOfExperiments +from pyomo.contrib.doe.tests.experiment_class_example_flags import ( + BadExperiment, + FullReactorExperiment, +) from pyomo.opt import SolverFactory From afd01bb0f8d5d463778e60e88ce157a07a8992d2 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Fri, 9 Aug 2024 09:17:02 -0500 Subject: [PATCH 140/203] Added shortcut function for test arguments --- pyomo/contrib/doe/tests/test_doe_build.py | 283 ++------- pyomo/contrib/doe/tests/test_doe_errors.py | 662 ++++----------------- pyomo/contrib/doe/tests/test_doe_solve.py | 305 +++------- 3 files changed, 247 insertions(+), 1003 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index d1eb3c11412..e35dab1bddb 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -93,6 +93,26 @@ def get_FIM_FIMPrior_Q_L(doe_obj=None): return FIM_vals_np, FIM_prior_vals_np, Q_vals_np, L_vals_np, sigma_inv_np +def get_standard_args(experiment, fd_method, obj_used): + args = {} + args['experiment'] = experiment + args['fd_formula'] = fd_method + args['step'] = 1e-3 + args['objective_option'] = obj_used + args['scale_constant_value'] = 1 + args['scale_nominal_param_value'] = True + args['prior_FIM'] = None + args['jac_initial'] = None + args['fim_initial'] = None + args['L_diagonal_lower_bound'] = 1e-7 + args['solver'] = None + args['tee'] = False + args['get_labeled_model_args'] = None + args['_Cholesky_option'] = True + args['_only_compute_fim_lower'] = True + return args + + class TestReactorExampleBuild(unittest.TestCase): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -102,23 +122,9 @@ def test_reactor_fd_central_check_fd_eqns(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -157,23 +163,9 @@ def test_reactor_fd_backward_check_fd_eqns(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -214,23 +206,9 @@ def test_reactor_fd_forward_check_fd_eqns(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -271,23 +249,9 @@ def test_reactor_fd_central_design_fixing(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -321,23 +285,9 @@ def test_reactor_fd_backward_design_fixing(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -371,23 +321,9 @@ def test_reactor_fd_forward_design_fixing(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -425,23 +361,12 @@ def test_reactor_check_user_initialization(self): FIM_initial = np.eye(4) + FIM_prior JAC_initial = np.ones((27, 4)) * 2 - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=FIM_prior, - jac_initial=JAC_initial, - fim_initial=FIM_initial, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + DoE_args['prior_FIM'] = FIM_prior + DoE_args['fim_initial'] = FIM_initial + DoE_args['jac_initial'] = JAC_initial + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -463,23 +388,9 @@ def test_update_FIM(self): FIM_update = np.ones((4, 4)) * 10 - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.create_doe_model() @@ -499,23 +410,9 @@ def test_get_experiment_inputs_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="sequential") @@ -533,23 +430,9 @@ def test_get_experiment_outputs_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="sequential") @@ -567,23 +450,9 @@ def test_get_measurement_error_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="sequential") @@ -601,23 +470,9 @@ def test_get_unknown_parameters_without_blocks(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="sequential") @@ -636,23 +491,9 @@ def test_generate_blocks_without_model(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj._generate_scenario_blocks() diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 986cdcb4f5c..2aa7886a65e 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -37,6 +37,26 @@ data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} +def get_standard_args(experiment, fd_method, obj_used, flag): + args = {} + args['experiment'] = experiment + args['fd_formula'] = fd_method + args['step'] = 1e-3 + args['objective_option'] = obj_used + args['scale_constant_value'] = 1 + args['scale_nominal_param_value'] = True + args['prior_FIM'] = None + args['jac_initial'] = None + args['fim_initial'] = None + args['L_diagonal_lower_bound'] = 1e-7 + args['solver'] = None + args['tee'] = False + args['get_labeled_model_args'] = {"flag": flag} + args['_Cholesky_option'] = True + args['_only_compute_fim_lower'] = True + return args + + class TestReactorExampleErrors(unittest.TestCase): @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_get_labeled_model(self): @@ -50,23 +70,9 @@ def test_reactor_check_no_get_labeled_model(self): ValueError, "The experiment object must have a ``get_labeled_model`` function", ): - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_experiment_outputs(self): @@ -76,23 +82,9 @@ def test_reactor_check_no_experiment_outputs(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -108,23 +100,9 @@ def test_reactor_check_no_measurement_error(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -140,23 +118,9 @@ def test_reactor_check_no_experiment_inputs(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -172,23 +136,9 @@ def test_reactor_check_no_unknown_parameters(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -206,23 +156,10 @@ def test_reactor_check_bad_prior_size(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=prior_FIM, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + DoE_args['prior_FIM'] = prior_FIM + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( ValueError, @@ -242,23 +179,10 @@ def test_reactor_check_bad_jacobian_init_size(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=jac_init, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + DoE_args['jac_initial'] = jac_init + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( ValueError, @@ -278,23 +202,9 @@ def test_reactor_check_unbuilt_update_FIM(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -312,23 +222,9 @@ def test_reactor_check_none_update_FIM(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( ValueError, @@ -344,23 +240,9 @@ def test_reactor_check_results_file_name(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( ValueError, "``results_file`` must be either a Path object or a string." @@ -377,23 +259,9 @@ def test_reactor_check_measurement_and_output_length_match(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( ValueError, @@ -412,23 +280,9 @@ def test_reactor_grid_search_des_range_inputs(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag=0) + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"not": [1, 5, 3], "correct": [300, 700, 3]} @@ -449,23 +303,9 @@ def test_reactor_premature_figure_drawing(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag=0) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -482,23 +322,9 @@ def test_reactor_figure_drawing_no_des_var_names(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag=0) + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} @@ -521,23 +347,9 @@ def test_reactor_figure_drawing_no_sens_names(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag=0) + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} @@ -559,23 +371,9 @@ def test_reactor_figure_drawing_no_fixed_names(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag=0) + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} @@ -597,23 +395,9 @@ def test_reactor_figure_drawing_bad_fixed_names(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag=0) + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} @@ -639,23 +423,9 @@ def test_reactor_figure_drawing_bad_sens_names(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag=0) + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"CA[0]": [1, 5, 2], "T[0]": [300, 700, 2]} @@ -682,23 +452,9 @@ def test_reactor_check_get_FIM_without_FIM(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -716,23 +472,9 @@ def test_reactor_check_get_sens_mat_without_model(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -750,23 +492,9 @@ def test_reactor_check_get_exp_inputs_without_model(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -784,23 +512,9 @@ def test_reactor_check_get_exp_outputs_without_model(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -818,23 +532,9 @@ def test_reactor_check_get_unknown_params_without_model(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -852,23 +552,9 @@ def test_reactor_check_get_meas_error_without_model(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -886,23 +572,9 @@ def test_multiple_exp_not_implemented_seq(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( NotImplementedError, "Multiple experiment optimization not yet supported." @@ -919,23 +591,9 @@ def test_multiple_exp_not_implemented_sim(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( NotImplementedError, "Multiple experiment optimization not yet supported." @@ -952,23 +610,9 @@ def test_update_unknown_parameter_values_not_implemented_seq(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( NotImplementedError, "Updating unknown parameter values not yet supported." @@ -986,23 +630,9 @@ def test_bad_FD_generate_scens(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( AttributeError, @@ -1022,23 +652,9 @@ def test_bad_FD_seq_compute_FIM(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( AttributeError, @@ -1057,23 +673,9 @@ def test_bad_objective(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( AttributeError, @@ -1092,23 +694,9 @@ def test_no_model_for_objective(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -1127,23 +715,9 @@ def test_bad_compute_FIM_option(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args={"flag": flag_val}, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used, flag_val) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( ValueError, diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 140e65288fc..3870cd9344c 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -95,6 +95,26 @@ def get_FIM_Q_L(doe_obj=None): return FIM_vals_np, Q_vals_np, L_vals_np, sigma_inv_np +def get_standard_args(experiment, fd_method, obj_used): + args = {} + args['experiment'] = experiment + args['fd_formula'] = fd_method + args['step'] = 1e-3 + args['objective_option'] = obj_used + args['scale_constant_value'] = 1 + args['scale_nominal_param_value'] = True + args['prior_FIM'] = None + args['jac_initial'] = None + args['fim_initial'] = None + args['L_diagonal_lower_bound'] = 1e-7 + args['solver'] = None + args['tee'] = False + args['get_labeled_model_args'] = None + args['_Cholesky_option'] = True + args['_only_compute_fim_lower'] = True + return args + + class TestReactorExampleSolving(unittest.TestCase): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not numpy_available, "Numpy is not available") @@ -104,23 +124,9 @@ def test_reactor_fd_central_solve(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.run_doe() @@ -143,23 +149,9 @@ def test_reactor_fd_forward_solve(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.run_doe() @@ -181,23 +173,9 @@ def test_reactor_fd_backward_solve(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.run_doe() @@ -221,23 +199,14 @@ def test_reactor_obj_det_solve(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=False, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=False, - _only_compute_fim_lower=False, + DoE_args = get_standard_args(experiment, fd_method, obj_used) + DoE_args['scale_nominal_param_value'] = ( + False # Vanilla determinant solve needs this ) + DoE_args['_Cholesky_option'] = False + DoE_args['_only_compute_fim_lower'] = False + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.run_doe() @@ -251,23 +220,9 @@ def test_reactor_obj_cholesky_solve(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.run_doe() @@ -290,23 +245,9 @@ def test_compute_FIM_seq_centr(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="sequential") @@ -318,23 +259,9 @@ def test_compute_FIM_seq_forward(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="sequential") @@ -350,23 +277,9 @@ def test_compute_FIM_kaug(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="kaug") @@ -378,23 +291,9 @@ def test_compute_FIM_seq_backward(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) doe_obj.compute_FIM(method="sequential") @@ -407,23 +306,9 @@ def test_reactor_grid_search(self): experiment = FullReactorExperiment(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"CA[0]": [1, 5, 3], "T[0]": [300, 700, 3]} @@ -453,43 +338,15 @@ def test_rescale_FIM(self): experiment = FullReactorExperiment(data_ex, 10, 3) # With parameter scaling - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) # Without parameter scaling - doe_obj2 = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=False, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args2 = get_standard_args(experiment, fd_method, obj_used) + DoE_args2['scale_nominal_param_value'] = False + doe_obj2 = DesignOfExperiments(**DoE_args2) # Run both problems doe_obj.run_doe() doe_obj2.run_doe() @@ -523,23 +380,9 @@ def test_reactor_solve_bad_model(self): experiment = FullReactorExperimentBad(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + + doe_obj = DesignOfExperiments(**DoE_args) with self.assertRaisesRegex( RuntimeError, @@ -556,24 +399,10 @@ def test_reactor_grid_search_bad_model(self): experiment = FullReactorExperimentBad(data_ex, 10, 3) - doe_obj = DesignOfExperiments( - experiment, - fd_formula=fd_method, - step=1e-3, - objective_option=obj_used, - scale_constant_value=1, - scale_nominal_param_value=True, - prior_FIM=None, - jac_initial=None, - fim_initial=None, - L_diagonal_lower_bound=1e-7, - solver=None, - tee=False, - get_labeled_model_args=None, - _Cholesky_option=True, - _only_compute_fim_lower=True, - logger_level=logging.ERROR, - ) + DoE_args = get_standard_args(experiment, fd_method, obj_used) + DoE_args['logger_level'] = logging.ERROR + + doe_obj = DesignOfExperiments(**DoE_args) design_ranges = {"CA[0]": [1, 5, 3], "T[0]": [300, 700, 3]} From b66a6c509964fe0964b0dd231a46f73960833460 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Fri, 9 Aug 2024 09:21:25 -0500 Subject: [PATCH 141/203] Simplified decorator to class --- pyomo/contrib/doe/tests/test_doe_build.py | 28 ++--------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index e35dab1bddb..50b7498a6d0 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -113,9 +113,9 @@ def get_standard_args(experiment, fd_method, obj_used): return args +@unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") +@unittest.skipIf(not numpy_available, "Numpy is not available") class TestReactorExampleBuild(unittest.TestCase): - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_check_fd_eqns(self): fd_method = "central" obj_used = "trace" @@ -155,8 +155,6 @@ def test_reactor_fd_central_check_fd_eqns(self): assert np.isclose(param_val, param_val_from_step) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_check_fd_eqns(self): fd_method = "backward" obj_used = "trace" @@ -198,8 +196,6 @@ def test_reactor_fd_backward_check_fd_eqns(self): other_param_val = pyo.value(k) assert np.isclose(other_param_val, v) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_check_fd_eqns(self): fd_method = "forward" obj_used = "trace" @@ -241,8 +237,6 @@ def test_reactor_fd_forward_check_fd_eqns(self): other_param_val = pyo.value(k) assert np.isclose(other_param_val, v) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_design_fixing(self): fd_method = "central" obj_used = "trace" @@ -277,8 +271,6 @@ def test_reactor_fd_central_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_design_fixing(self): fd_method = "backward" obj_used = "trace" @@ -313,8 +305,6 @@ def test_reactor_fd_backward_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_design_fixing(self): fd_method = "forward" obj_used = "trace" @@ -349,8 +339,6 @@ def test_reactor_fd_forward_design_fixing(self): # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) assert not hasattr(model, con_name_base + str(len(design_vars))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_user_initialization(self): fd_method = "central" obj_used = "determinant" @@ -378,8 +366,6 @@ def test_reactor_check_user_initialization(self): assert np.array_equal(FIM_prior, FIM_prior_model) assert np.array_equal(JAC_initial, Q) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_update_FIM(self): fd_method = "forward" obj_used = "trace" @@ -402,8 +388,6 @@ def test_update_FIM(self): # Make sure they match the inputs we gave assert np.array_equal(FIM_update, FIM_prior_model) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_get_experiment_inputs_without_blocks(self): fd_method = "forward" obj_used = "trace" @@ -422,8 +406,6 @@ def test_get_experiment_inputs_without_blocks(self): [k.name for k, v in doe_obj.compute_FIM_model.experiment_inputs.items()] ) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_get_experiment_outputs_without_blocks(self): fd_method = "forward" obj_used = "trace" @@ -442,8 +424,6 @@ def test_get_experiment_outputs_without_blocks(self): [k.name for k, v in doe_obj.compute_FIM_model.experiment_outputs.items()] ) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_get_measurement_error_without_blocks(self): fd_method = "forward" obj_used = "trace" @@ -462,8 +442,6 @@ def test_get_measurement_error_without_blocks(self): [k.name for k, v in doe_obj.compute_FIM_model.measurement_error.items()] ) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_get_unknown_parameters_without_blocks(self): fd_method = "forward" obj_used = "trace" @@ -483,8 +461,6 @@ def test_get_unknown_parameters_without_blocks(self): [k.name for k, v in doe_obj.compute_FIM_model.unknown_parameters.items()] ) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_generate_blocks_without_model(self): fd_method = "forward" obj_used = "trace" From c6aafd205df9876b8dcc648af33e4dce137e059e Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 10:09:01 -0400 Subject: [PATCH 142/203] Cleaned up reactor experiment example --- .../doe/examples/reactor_experiment.py | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 52056c01fa2..2202f26384b 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -18,6 +18,13 @@ # ======================== class ReactorExperiment(Experiment): def __init__(self, data, nfe, ncp): + """ + Arguments + --------- + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ self.data = data self.nfe = nfe self.ncp = ncp @@ -108,13 +115,6 @@ def finalize_model(self): 1. Extracting useful information for the model to align with the experiment. (Here: CA0, t_final, t_control) 2. Discretizing the model subject to this information. - - Arguments - --------- - m: Pyomo model - data: object containing vital experimental information - nfe: number of finite elements - ncp: number of collocation points for the finite elements """ m = self.model @@ -167,10 +167,6 @@ def label_experiment(self): """ Example for annotating (labeling) the model with a full experiment. - - Arguments - --------- - """ m = self.model @@ -196,9 +192,6 @@ def label_experiment(self): # Identify design variables (experiment inputs) for the model m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Add experimental input label for initial concentration - # m.experiment_inputs.update( - # (m.CA[t], None) for t in [m.t.first()] - # ) m.experiment_inputs[m.CA[m.t.first()]] = None # Add experimental input label for Temperature m.experiment_inputs.update((m.T[t], None) for t in m.t_control) From b8b911cd86d08abc3640ed6aca6b7bad789a15a1 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 10:12:54 -0400 Subject: [PATCH 143/203] Added else to rescale function, commented params function --- pyomo/contrib/doe/utils.py | 67 ++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/pyomo/contrib/doe/utils.py b/pyomo/contrib/doe/utils.py index 889bebbea33..649a87b6fe3 100644 --- a/pyomo/contrib/doe/utils.py +++ b/pyomo/contrib/doe/utils.py @@ -54,44 +54,49 @@ def rescale_FIM(FIM, param_vals): (len(param_vals.shape) == 2) and (param_vals.shape[0] != 1) ): raise ValueError( - "param_vals should be a vector of dimensions (1, n_params). The shape you provided is {}.".format( + "param_vals should be a vector of dimensions: 1 by `n_params`. The shape you provided is {}.".format( param_vals.shape ) ) if len(param_vals.shape) == 1: param_vals = np.array([param_vals]) + else: + raise ValueError( + "param_vals should be a list or numpy array of dimensions: 1 by `n_params`" + ) scaling_mat = (1 / param_vals).transpose().dot((1 / param_vals)) scaled_FIM = np.multiply(FIM, scaling_mat) return scaled_FIM -def get_parameters_from_suffix(suffix, fix_vars=False): - """ - Finds the Params within the suffix provided. It will also check to see - if there are Vars in the suffix provided. ``fix_vars`` will indicate - if we should fix all the Vars in the set or not. - - Parameters - ---------- - suffix: pyomo Suffix object, contains the components to be checked - as keys - fix_vars: boolean, whether or not to fix the Vars, default = False - - Returns - ------- - param_list: list of Param - """ - param_list = [] - - # FIX THE MODEL TREE ISSUE WHERE I GET base_model. INSTEAD OF - # Check keys if they are Param or Var. Fix the vars if ``fix_vars`` is True - for k, v in suffix.items(): - if isinstance(k, ParamData): - param_list.append(k.name) - elif isinstance(k, VarData): - if fix_vars: - k.fix() - else: - pass # ToDo: Write error for suffix keys that aren't ParamData or VarData - - return param_list +# TODO: Add swapping parameters for variables helper function +# def get_parameters_from_suffix(suffix, fix_vars=False): +# """ +# Finds the Params within the suffix provided. It will also check to see +# if there are Vars in the suffix provided. ``fix_vars`` will indicate +# if we should fix all the Vars in the set or not. +# +# Parameters +# ---------- +# suffix: pyomo Suffix object, contains the components to be checked +# as keys +# fix_vars: boolean, whether or not to fix the Vars, default = False +# +# Returns +# ------- +# param_list: list of Param +# """ +# param_list = [] +# +# # FIX THE MODEL TREE ISSUE WHERE I GET base_model. INSTEAD OF +# # Check keys if they are Param or Var. Fix the vars if ``fix_vars`` is True +# for k, v in suffix.items(): +# if isinstance(k, ParamData): +# param_list.append(k.name) +# elif isinstance(k, VarData): +# if fix_vars: +# k.fix() +# else: +# pass # ToDo: Write error for suffix keys that aren't ParamData or VarData +# +# return param_list From a9b1b032dcdfbfcc317ffc153cadb8d9db4796d2 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 10:33:52 -0400 Subject: [PATCH 144/203] Edited language in documentation --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 4be5d0ad8dc..516967f9245 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -116,14 +116,14 @@ In order to solve problems of the above, Pyomo.DoE implements the 2-stage stocha Pyomo.DoE Required Inputs -------------------------------- -The required inputs to the Pyomo.DoE solver is an Experiment object. The experiment object must have a get_labeled_model function which returns a pyomo model with four special labeled components as suffixes on the pyomo model. This is in line with the convention used in the new interface in the contributed package, `Parmest `_. The four suffix components are: +The required input to the Pyomo.DoE solver is an ``Experiment`` object. The experiment object must have a ``get_labeled_model`` function which returns a Pyomo model with four ``Suffix`` components identifying the parts of the model used in MBDoE analysis. This is in line with the convention used in the parameter estimation tool, `Parmest `_. The four ``Suffix`` components are: -* experiment_inputs - The experimental design decisions -* experiment_outputs - The values measured during the experiment -* measurement_error - The error associated with individual values measured during the experiment -* unknown_parameters - Those parameters in the model that are estimated using the measured values during the experiment +* ``experiment_inputs`` - The experimental design decisions +* ``experiment_outputs`` - The values measured during the experiment +* ``measurement_error`` - The error associated with individual values measured during the experiment +* ``unknown_parameters`` - Those parameters in the model that are estimated using the measured values during the experiment -An example an Experiment object that builds and labels the model is shown in the next few sections. +An example ``Experiment`` object that builds and labels the model is shown in the next few sections. Pyomo.DoE Usage Example ----------------------- @@ -162,6 +162,7 @@ Step 0: Import Pyomo and the Pyomo.DoE module and create an Experiment object >>> import pyomo.environ as pyo >>> from pyomo.contrib.doe import DesignOfExperiments >>> import numpy as np + >>> import idaes # Required to add ipopt linear solvers to path if not done manually .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :lines: 19-24 From 9d5fa4c9e42765cfcf1551aa8b065dea312dbd55 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 10:45:10 -0400 Subject: [PATCH 145/203] Fixed fragile line numbers for reactor exp in documentation --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 15 ++++++++++----- pyomo/contrib/doe/examples/reactor_experiment.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 516967f9245..e8f9660046b 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -165,7 +165,8 @@ Step 0: Import Pyomo and the Pyomo.DoE module and create an Experiment object >>> import idaes # Required to add ipopt linear solvers to path if not done manually .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 19-24 + :start-after: ======================== + :end-before: End constructor definition Step 1: Define the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -173,7 +174,8 @@ Step 1: Define the Pyomo process model The process model for the reaction kinetics problem is shown below. We build the model in without any data or discretization. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 33-102 + :start-after: Create flexible model without data + :end-before: End equation def'n Step 2: Finalize the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -181,7 +183,8 @@ Step 2: Finalize the Pyomo process model Here we add data to the model and finalize the discretization. This step is required before the model can be labeled. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 104-157 + :start-after: End equation def'n + :end-before: End model finalization Step 3: Label the important information for model on the DoE object ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +192,8 @@ Step 3: Label the important information for model on the DoE object We label the four important groups as defined before. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 159-203 + :start-after: End model finalization + :end-before: End model labeling Step 4: We give the experiment object a get_labeled_model function ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -197,7 +201,8 @@ Step 4: We give the experiment object a get_labeled_model function This function summarizes the previous 3 steps and is used by `Pyomo.DoE` to build the model to perform optimal experimental design. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :lines: 26-31 + :start-after: End constructor definition + :end-before: Create flexible model without data Step 5: Exploratory analysis (Enumeration) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 2202f26384b..8098deaf906 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -30,6 +30,9 @@ def __init__(self, data, nfe, ncp): self.ncp = ncp self.model = None + ############################# + # End constructor definition + def get_labeled_model(self): if self.model is None: self.create_model() @@ -37,6 +40,7 @@ def get_labeled_model(self): self.label_experiment() return self.model + # Create flexible model without data def create_model(self): """ This is an example user model provided to DoE library. @@ -163,6 +167,9 @@ def T_control(m, t): neighbour_t = max(tc for tc in control_points if tc < t) return m.T[t] == m.T[neighbour_t] + ######################### + # End model finalization + def label_experiment(self): """ Example for annotating (labeling) the model with a @@ -200,3 +207,6 @@ def label_experiment(self): m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Add labels to all unknown parameters with nominal value as the value m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) + + ######################### + # End model labeling From 8d954925485827347e5e3a465cbc49d875bb740e Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 10:52:50 -0400 Subject: [PATCH 146/203] Clarified text in documentation --- .../contributed_packages/doe/doe.rst | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index e8f9660046b..c297a141597 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -153,8 +153,8 @@ The goal of MBDoE is to optimize the experiment design variables :math:`\boldsym The observation errors are assumed to be independent both in time and across measurements with a constant standard deviation of 1 M for each species. -Step 0: Import Pyomo and the Pyomo.DoE module and create an Experiment object -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Step 0: Import Pyomo and the Pyomo.DoE module and create an ``Experiment`` class +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. doctest:: @@ -186,8 +186,8 @@ Here we add data to the model and finalize the discretization. This step is requ :start-after: End equation def'n :end-before: End model finalization -Step 3: Label the important information for model on the DoE object -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Step 3: Label the information needed for DoE analysis +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We label the four important groups as defined before. @@ -195,10 +195,10 @@ We label the four important groups as defined before. :start-after: End model finalization :end-before: End model labeling -Step 4: We give the experiment object a get_labeled_model function -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Step 4: Implement the ``get_labeled_model`` method +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This function summarizes the previous 3 steps and is used by `Pyomo.DoE` to build the model to perform optimal experimental design. +This method utilizes the previous 3 steps and is used by `Pyomo.DoE` to build the model to perform optimal experimental design. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :start-after: End constructor definition @@ -210,10 +210,8 @@ Step 5: Exploratory analysis (Enumeration) Exploratory analysis is suggested to enumerate the design space to check if the problem is identifiable, i.e., ensure that D-, E-optimality metrics are not small numbers near zero, and Modified E-optimality is not a big number. -Pyomo.DoE accomplishes the exploratory analysis with the ``compute_FIM_full_factorial`` function. -It allows users to define any number of design decisions. Heatmaps can be drawn by two design variables, fixing other design variables. -1D curve can be drawn by one design variable, fixing all other variables. -The function ``compute_FIM_full_factorial`` enumerates over the design space, each MBDoE problem accomplished by ``compute_FIM`` method. +Pyomo.DoE can perform exploratory sensitivity analysis with the ``compute_FIM_full_factorial`` function. +The ``compute_FIM_full_factorial`` function generates a grid over the design space as specified by the user. Each grid point represents an MBDoE problem solved using ``compute_FIM`` method. In this way, sensitivity of the FIM over the design space can be evaluated. The following code executes the above problem description: From 26921e0a2f77822e0415b0d8012066c36cd5fb70 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 10:55:48 -0400 Subject: [PATCH 147/203] Remove more line number fragility in documentation --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index c297a141597..43eb2b2a496 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -231,7 +231,8 @@ Step 6: Performing an optimal experimental design This is an example of running an experimental design to determine an optimal experiment for the reactor example. We utilize the determinant as the objective. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_example.py - :lines: 24-90 + :start-after: Read in file + :end-before: Print out a results summary When run, the optimal design is an initial concentration of 5.0 mol/L and an initial temperature of 494 K with all other temperatures being 300 K. The corresponding log-10 determinant of the FIM is 13.75 From 9462cee70d43cf1a7169278b422b69f4a4949d96 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 11:08:14 -0400 Subject: [PATCH 148/203] Combined example files and updated documentation with change --- .../contributed_packages/doe/doe.rst | 9 +++-- pyomo/contrib/doe/examples/reactor_example.py | 37 ++++++++++++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 43eb2b2a496..213c094d4b2 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -215,8 +215,9 @@ The ``compute_FIM_full_factorial`` function generates a grid over the design spa The following code executes the above problem description: -.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_compute_factorial_FIM.py - :lines: 24-95 +.. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_example.py + :start-after: Read in file + :end-before: End sensitivity analysis An example output of the code above, a design exploration for the initial concentration and temperature as experimental design variables with 9 values, produces the four figures summarized below: @@ -228,10 +229,10 @@ A heatmap shows the change of the objective function, a.k.a. the experimental in Step 6: Performing an optimal experimental design ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This is an example of running an experimental design to determine an optimal experiment for the reactor example. We utilize the determinant as the objective. +In step 5, the DoE object was constructed to perform an exploratory sensitivity analysis. The same object can be used to design an optimal experiment with a single line of code. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_example.py - :start-after: Read in file + :start-after: Begin optimal DoE :end-before: Print out a results summary When run, the optimal design is an initial concentration of 5.0 mol/L and an initial temperature of 494 K with all other temperatures being 300 K. The corresponding log-10 determinant of the FIM is 13.75 diff --git a/pyomo/contrib/doe/examples/reactor_example.py b/pyomo/contrib/doe/examples/reactor_example.py index c17bd097303..f3e08ce7cb2 100644 --- a/pyomo/contrib/doe/examples/reactor_example.py +++ b/pyomo/contrib/doe/examples/reactor_example.py @@ -19,7 +19,8 @@ from pathlib import Path -# Example to run a DOE on the reactor +# Example for sensitivity analysis on the reactor experiment +# After sensitivity analysis is done, we perform optimal DoE def run_reactor_doe(): # Read in file DATA_DIR = Path(__file__).parent @@ -67,6 +68,37 @@ def run_reactor_doe(): _only_compute_fim_lower=True, ) + # Make design ranges to compute the full factorial design + design_ranges = {"CA[0]": [1, 5, 9], "T[0]": [300, 700, 9]} + + # Compute the full factorial design with the sequential FIM calculation + doe_obj.compute_FIM_full_factorial(design_ranges=design_ranges, method="sequential") + + # Plot the results + doe_obj.draw_factorial_figure( + sensitivity_design_variables=["CA[0]", "T[0]"], + fixed_design_variables={ + "T[0.125]": 300, + "T[0.25]": 300, + "T[0.375]": 300, + "T[0.5]": 300, + "T[0.625]": 300, + "T[0.75]": 300, + "T[0.875]": 300, + "T[1]": 300, + }, + title_text="Reactor Example", + xlabel_text="Concentration of A (M)", + ylabel_text="Initial Temperature (K)", + figure_file_name="example_reactor_compute_FIM", + log_scale=False, + ) + + ########################### + # End sensitivity analysis + + # Begin optimal DoE + #################### doe_obj.run_doe() # Print out a results summary @@ -90,6 +122,9 @@ def run_reactor_doe(): print(doe_obj.results["Experiment Design Names"]) + ################### + # End optimal DoE + if __name__ == "__main__": run_reactor_doe() From d5d24a63e3a1e68b4e66c5d01479d01a8f8e624d Mon Sep 17 00:00:00 2001 From: John Siirola Date: Mon, 12 Aug 2024 09:24:35 -0600 Subject: [PATCH 149/203] Update NL template classes to match Pyomo naming convention --- pyomo/repn/ampl.py | 10 +++++----- pyomo/repn/tests/ampl/test_ampl_nl.py | 2 +- pyomo/repn/tests/nl_diff.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pyomo/repn/ampl.py b/pyomo/repn/ampl.py index 7e949e37088..876f579fb8d 100644 --- a/pyomo/repn/ampl.py +++ b/pyomo/repn/ampl.py @@ -75,7 +75,7 @@ def _create_strict_inequality_map(vars_): } -class text_nl_debug_template(object): +class TextNLDebugTemplate(object): unary = { 'log': 'o43\t#log\n', 'log10': 'o42\t#log10\n', @@ -172,8 +172,8 @@ def _strip_template_comments(vars_, base_): # The "standard" text mode template is the debugging template with the # comments removed -class text_nl_template(text_nl_debug_template): - _strip_template_comments(vars(), text_nl_debug_template) +class TextNLTemplate(TextNLDebugTemplate): + _strip_template_comments(vars(), TextNLDebugTemplate) _create_strict_inequality_map(vars()) @@ -200,7 +200,7 @@ def name(self): class AMPLRepn(object): __slots__ = ('nl', 'mult', 'const', 'linear', 'nonlinear', 'named_exprs') - template = text_nl_template + template = TextNLTemplate def __init__(self, const, linear, nonlinear): self.nl = None @@ -446,7 +446,7 @@ def to_expr(self, var_map): class DebugAMPLRepn(AMPLRepn): __slots__ = () - template = text_nl_debug_template + template = TextNLDebugTemplate def handle_negation_node(visitor, node, arg1): diff --git a/pyomo/repn/tests/ampl/test_ampl_nl.py b/pyomo/repn/tests/ampl/test_ampl_nl.py index 53c34c4c5db..38c9d5b9dd5 100644 --- a/pyomo/repn/tests/ampl/test_ampl_nl.py +++ b/pyomo/repn/tests/ampl/test_ampl_nl.py @@ -31,7 +31,7 @@ from ..nl_diff import load_and_compare_nl_baseline import pyomo.repn.plugins.ampl.ampl_ as ampl_ -from pyomo.repn.ampl import text_nl_debug_template as template +from pyomo.repn.ampl import TextNLDebugTemplate as template gsr = ampl_.generate_standard_repn thisdir = this_file_dir() diff --git a/pyomo/repn/tests/nl_diff.py b/pyomo/repn/tests/nl_diff.py index 736be4f9606..d94d50e82e6 100644 --- a/pyomo/repn/tests/nl_diff.py +++ b/pyomo/repn/tests/nl_diff.py @@ -15,7 +15,7 @@ from difflib import SequenceMatcher, unified_diff from pyomo.repn.tests.diffutils import compare_floats, load_baseline -from pyomo.repn.ampl import text_nl_debug_template as template +from pyomo.repn.ampl import TextNLDebugTemplate as template _norm_whitespace = re.compile(r'[^\S\n]+') _norm_integers = re.compile(r'(?m)\.0+$') From 77a1bc5d74423d305bd659994cb3e8fb6c08a620 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 11:25:05 -0400 Subject: [PATCH 150/203] Add context manager, remove np.isclose in tests --- pyomo/contrib/doe/__init__.py | 2 +- pyomo/contrib/doe/examples/reactor_example.py | 4 ++-- pyomo/contrib/doe/tests/test_doe_build.py | 17 +++++++++-------- pyomo/contrib/doe/tests/test_doe_errors.py | 4 ++-- pyomo/contrib/doe/tests/test_doe_solve.py | 4 ++-- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index 775fc6fb47d..04e237c18db 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -9,4 +9,4 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ from .doe import DesignOfExperiments, ObjectiveLib, FiniteDifferenceStep -from .utils import rescale_FIM, get_parameters_from_suffix +from .utils import rescale_FIM diff --git a/pyomo/contrib/doe/examples/reactor_example.py b/pyomo/contrib/doe/examples/reactor_example.py index f3e08ce7cb2..1570c870181 100644 --- a/pyomo/contrib/doe/examples/reactor_example.py +++ b/pyomo/contrib/doe/examples/reactor_example.py @@ -26,8 +26,8 @@ def run_reactor_doe(): DATA_DIR = Path(__file__).parent file_path = DATA_DIR / "result.json" - f = open(file_path) - data_ex = json.load(f) + with open(file_path) as f: + data_ex = json.load(f) # Put temperature control time points into correct format for reactor experiment data_ex["control_points"] = { diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 50b7498a6d0..465c6f5c8e0 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -31,8 +31,9 @@ DATA_DIR = Path(__file__).parent file_path = DATA_DIR / "result.json" -f = open(file_path) -data_ex = json.load(f) +with open(file_path) as f: + data_ex = json.load(f) + data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} @@ -151,9 +152,9 @@ def test_reactor_fd_central_check_fd_eqns(self): continue other_param_val = pyo.value(k) - assert np.isclose(other_param_val, v) + self.assertAlmostEqual(other_param_val, v) - assert np.isclose(param_val, param_val_from_step) + self.assertAlmostEqual(param_val, param_val_from_step) def test_reactor_fd_backward_check_fd_eqns(self): fd_method = "backward" @@ -182,7 +183,7 @@ def test_reactor_fd_backward_check_fd_eqns(self): param_val_from_step = model.scenario_blocks[0].unknown_parameters[ pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0]) ] * (1 + diff) - assert np.isclose(param_val, param_val_from_step) + self.assertAlmostEqual(param_val, param_val_from_step) for k, v in model.scenario_blocks[s].unknown_parameters.items(): name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") @@ -194,7 +195,7 @@ def test_reactor_fd_backward_check_fd_eqns(self): continue other_param_val = pyo.value(k) - assert np.isclose(other_param_val, v) + self.assertAlmostEqual(other_param_val, v) def test_reactor_fd_forward_check_fd_eqns(self): fd_method = "forward" @@ -223,7 +224,7 @@ def test_reactor_fd_forward_check_fd_eqns(self): param_val_from_step = model.scenario_blocks[0].unknown_parameters[ pyo.ComponentUID(param).find_component_on(model.scenario_blocks[0]) ] * (1 + diff) - assert np.isclose(param_val, param_val_from_step) + self.assertAlmostEqual(param_val, param_val_from_step) for k, v in model.scenario_blocks[s].unknown_parameters.items(): name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") @@ -235,7 +236,7 @@ def test_reactor_fd_forward_check_fd_eqns(self): continue other_param_val = pyo.value(k) - assert np.isclose(other_param_val, v) + self.assertAlmostEqual(other_param_val, v) def test_reactor_fd_central_design_fixing(self): fd_method = "central" diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 2aa7886a65e..eb6d268ccc8 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -32,8 +32,8 @@ DATA_DIR = Path(__file__).parent file_path = DATA_DIR / "result.json" -f = open(file_path) -data_ex = json.load(f) +with open(file_path) as f: + data_ex = json.load(f) data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 3870cd9344c..4dd15bc04df 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -39,8 +39,8 @@ DATA_DIR = Path(__file__).parent file_path = DATA_DIR / "result.json" -f = open(file_path) -data_ex = json.load(f) +with open(file_path) as f: + data_ex = json.load(f) data_ex["control_points"] = {float(k): v for k, v in data_ex["control_points"].items()} From ef5c9ba9baf45f272bb1efffcfd6f65feea38691 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 11:37:55 -0400 Subject: [PATCH 151/203] Reused reactor experiment in tests, fixed bug in experiment --- pyomo/contrib/doe/examples/reactor_experiment.py | 12 ++++++------ pyomo/contrib/doe/tests/test_doe_build.py | 4 +++- pyomo/contrib/doe/tests/test_doe_solve.py | 4 +++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 8098deaf906..37e97250a7e 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -180,21 +180,21 @@ def label_experiment(self): # Set measurement labels m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) # Add CA to experiment outputs - m.experiment_outputs.update((m.CA[t], None) for t in m.t) + m.experiment_outputs.update((m.CA[t], None) for t in m.t_control) # Add CB to experiment outputs - m.experiment_outputs.update((m.CB[t], None) for t in m.t) + m.experiment_outputs.update((m.CB[t], None) for t in m.t_control) # Add CC to experiment outputs - m.experiment_outputs.update((m.CC[t], None) for t in m.t) + m.experiment_outputs.update((m.CC[t], None) for t in m.t_control) # Adding error for measurement values (assuming no covariance and constant error for all measurements) m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) concentration_error = 1e-2 # Error in concentration measurement # Add measurement error for CA - m.measurement_error.update((m.CA[t], concentration_error) for t in m.t) + m.measurement_error.update((m.CA[t], concentration_error) for t in m.t_control) # Add measurement error for CB - m.measurement_error.update((m.CB[t], concentration_error) for t in m.t) + m.measurement_error.update((m.CB[t], concentration_error) for t in m.t_control) # Add measurement error for CC - m.measurement_error.update((m.CC[t], concentration_error) for t in m.t) + m.measurement_error.update((m.CC[t], concentration_error) for t in m.t_control) # Identify design variables (experiment inputs) for the model m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 465c6f5c8e0..22124d28f19 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -20,7 +20,9 @@ import pyomo.common.unittest as unittest from pyomo.contrib.doe import DesignOfExperiments -from pyomo.contrib.doe.tests.experiment_class_example import FullReactorExperiment +from pyomo.contrib.doe.examples.reactor_example import ( + ReactorExperiment as FullReactorExperiment, +) import pyomo.environ as pyo diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 4dd15bc04df..5f6f42d8ae3 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -22,7 +22,9 @@ import pyomo.common.unittest as unittest from pyomo.contrib.doe import DesignOfExperiments -from pyomo.contrib.doe.tests.experiment_class_example import FullReactorExperiment +from pyomo.contrib.doe.examples.reactor_example import ( + ReactorExperiment as FullReactorExperiment, +) from pyomo.contrib.doe.tests.experiment_class_example_flags import ( FullReactorExperimentBad, ) From 353e769b382ca627b3313ba040f600e8b0a052c1 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 11:38:19 -0400 Subject: [PATCH 152/203] Edited small phrase in documentation --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 213c094d4b2..e3f729e761f 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -171,7 +171,7 @@ Step 0: Import Pyomo and the Pyomo.DoE module and create an ``Experiment`` class Step 1: Define the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The process model for the reaction kinetics problem is shown below. We build the model in without any data or discretization. +The process model for the reaction kinetics problem is shown below. We build the model without any data or discretization. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :start-after: Create flexible model without data From b2106a08dc9fbf38974e2efd422ef52e48823aa8 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 11:41:20 -0400 Subject: [PATCH 153/203] Removing unused import --- pyomo/contrib/doe/tests/experiment_class_example.py | 1 - pyomo/contrib/doe/tests/experiment_class_example_flags.py | 1 - 2 files changed, 2 deletions(-) diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py index 03c8ca3a784..e31b0da8374 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -15,7 +15,6 @@ from pyomo.contrib.parmest.experiment import Experiment import itertools -import json # ======================== diff --git a/pyomo/contrib/doe/tests/experiment_class_example_flags.py b/pyomo/contrib/doe/tests/experiment_class_example_flags.py index e0d8363b20a..5a25bbf4b37 100644 --- a/pyomo/contrib/doe/tests/experiment_class_example_flags.py +++ b/pyomo/contrib/doe/tests/experiment_class_example_flags.py @@ -15,7 +15,6 @@ from pyomo.contrib.parmest.experiment import Experiment import itertools -import json # ======================== From 16873d024e9c3742ab4e77dc2fbc7b02683280f7 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 11:48:33 -0400 Subject: [PATCH 154/203] Remove tests result.json dependency --- pyomo/contrib/doe/tests/test_doe_build.py | 2 +- pyomo/contrib/doe/tests/test_doe_errors.py | 2 +- pyomo/contrib/doe/tests/test_doe_solve.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 22124d28f19..8d31b21ee81 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -31,7 +31,7 @@ ipopt_available = SolverFactory("ipopt").available() DATA_DIR = Path(__file__).parent -file_path = DATA_DIR / "result.json" +file_path = DATA_DIR / ".." / "examples" / "result.json" with open(file_path) as f: data_ex = json.load(f) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index eb6d268ccc8..76599d3c468 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -30,7 +30,7 @@ ipopt_available = SolverFactory("ipopt").available() DATA_DIR = Path(__file__).parent -file_path = DATA_DIR / "result.json" +file_path = DATA_DIR / ".." / "examples" / "result.json" with open(file_path) as f: data_ex = json.load(f) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 5f6f42d8ae3..34a01e8c0e4 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -39,7 +39,7 @@ k_aug_available = SolverFactory('k_aug', solver_io='nl', validate=False) DATA_DIR = Path(__file__).parent -file_path = DATA_DIR / "result.json" +file_path = DATA_DIR / ".." / "examples" / "result.json" with open(file_path) as f: data_ex = json.load(f) From 2b2c33f4b9d1af544983eb228309d69772c437ba Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 11:50:38 -0400 Subject: [PATCH 155/203] Delete pyomo/contrib/doe/tests/experiment_class_example.py Remove deprecated file --- .../doe/tests/experiment_class_example.py | 231 ------------------ 1 file changed, 231 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/experiment_class_example.py diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py deleted file mode 100644 index e31b0da8374..00000000000 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ /dev/null @@ -1,231 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# ___________________________________________________________________________ -# === Required imports === -import pyomo.environ as pyo -from pyomo.dae import ContinuousSet, DerivativeVar, Simulator - -from pyomo.contrib.parmest.experiment import Experiment - -import itertools - -# ======================== - - -def expand_model_components(m, base_components, index_sets): - """ - Takes model components and index sets and returns the - model component labels. - - Arguments - --------- - m: Pyomo model - base_components: list of variables from model 'm' - index_sets: list, same length as base_components, where each - element is a list of index sets, or None - """ - for val, indexes in itertools.zip_longest(base_components, index_sets): - # If the variable has no index, - # add just the model component - if not val.is_indexed(): - yield val - # If the component is indexed but no - # index supplied, add all indices - elif indexes is None: - yield from val.values() - else: - for j in itertools.product(*indexes): - yield val[j] - - -class ReactorExperiment(Experiment): - def __init__(self, data, nfe, ncp): - self.data = data - self.nfe = nfe - self.ncp = ncp - self.model = None - - def get_labeled_model(self): - if self.model is None: - self.create_model() - self.finalize_model() - self.label_experiment() - return self.model - - def create_model(self): - """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. - - Return - ------ - m: a Pyomo.DAE model - """ - - m = self.model = pyo.ConcreteModel() - - # Model parameters - m.R = pyo.Param(mutable=False, initialize=8.314) - - # Define model variables - ######################## - # time - m.t = ContinuousSet(bounds=[0, 1]) - - # Concentrations - m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Temperature - m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Arrhenius rate law equations - m.A1 = pyo.Var(within=pyo.NonNegativeReals) - m.E1 = pyo.Var(within=pyo.NonNegativeReals) - m.A2 = pyo.Var(within=pyo.NonNegativeReals) - m.E2 = pyo.Var(within=pyo.NonNegativeReals) - - # Differential variables (Conc.) - m.dCAdt = DerivativeVar(m.CA, wrt=m.t) - m.dCBdt = DerivativeVar(m.CB, wrt=m.t) - - ######################## - # End variable def. - - # Equation def'n - ######################## - - # Expression for rate constants - @m.Expression(m.t) - def k1(m, t): - return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) - - @m.Expression(m.t) - def k2(m, t): - return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) - - # Concentration odes - @m.Constraint(m.t) - def CA_rxn_ode(m, t): - return m.dCAdt[t] == -m.k1[t] * m.CA[t] - - @m.Constraint(m.t) - def CB_rxn_ode(m, t): - return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] - - # algebraic balance for concentration of C - # Valid because the reaction system (A --> B --> C) is equimolar - @m.Constraint(m.t) - def CC_balance(m, t): - return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] - - ######################## - # End equation def'n - - def finalize_model(self): - """ - Example finalize model function. There are two main tasks - here: - 1. Extracting useful information for the model to align - with the experiment. (Here: CA0, t_final, t_control) - 2. Discretizing the model subject to this information. - - Arguments - --------- - m: Pyomo model - data: object containing vital experimental information - nfe: number of finite elements - ncp: number of collocation points for the finite elements - """ - m = self.model - - # Unpacking data before simulation - control_points = self.data["control_points"] - - m.CA[0].value = self.data["CA0"] - m.CB[0].fix(self.data["CB0"]) - m.t.update(self.data["t_range"]) - m.t.update(control_points) - m.A1.fix(self.data["A1"]) - m.A2.fix(self.data["A2"]) - m.E1.fix(self.data["E1"]) - m.E2.fix(self.data["E2"]) - - m.CA[0].setlb(self.data["CA_bounds"][0]) - m.CA[0].setub(self.data["CA_bounds"][1]) - - m.t_control = control_points - - # Discretizing the model - discr = pyo.TransformationFactory("dae.collocation") - discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) - - # Initializing Temperature in the model - cv = None - for t in m.t: - if t in control_points: - cv = control_points[t] - m.T[t].setlb(self.data["T_bounds"][0]) - m.T[t].setub(self.data["T_bounds"][1]) - m.T[t] = cv - - @m.Constraint(m.t - control_points) - def T_control(m, t): - """ - Piecewise constant Temperature between control points - """ - neighbour_t = max(tc for tc in control_points if tc < t) - return m.T[t] == m.T[neighbour_t] - - # sim.initialize_model() - - def label_experiment_impl(self, index_sets_meas): - """ - Example for annotating (labeling) the model with a - full experiment. - - Arguments - --------- - - """ - m = self.model - - # Grab measurement labels - base_comp_meas = [m.CA, m.CB, m.CC] - m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.experiment_outputs.update( - (k, None) - for k in expand_model_components(m, base_comp_meas, index_sets_meas) - ) - - # Adding no error for measurements currently - m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.measurement_error.update( - (k, 1e-2) - for k in expand_model_components(m, base_comp_meas, index_sets_meas) - ) - - # Grab design variables - base_comp_des = [m.CA, m.T] - index_sets_des = [[[m.t.first()]], [m.t_control]] - m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.experiment_inputs.update( - (k, None) for k in expand_model_components(m, base_comp_des, index_sets_des) - ) - - m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) - - -class FullReactorExperiment(ReactorExperiment): - def label_experiment(self): - m = self.model - return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]]) From c18f2c6d6c10d04ffe878bbd6a9fa6c77c1c153c Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 11:50:55 -0400 Subject: [PATCH 156/203] Delete pyomo/contrib/doe/tests/result.json Remove deprecated file --- pyomo/contrib/doe/tests/result.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 pyomo/contrib/doe/tests/result.json diff --git a/pyomo/contrib/doe/tests/result.json b/pyomo/contrib/doe/tests/result.json deleted file mode 100644 index 7e1b1a79a1b..00000000000 --- a/pyomo/contrib/doe/tests/result.json +++ /dev/null @@ -1 +0,0 @@ -{"CA0": 5.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file From cb7d92536399f613f97b898b17a178da200c35b6 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 11:51:17 -0400 Subject: [PATCH 157/203] Delete pyomo/contrib/doe/experiment.py Remove deprecated file --- pyomo/contrib/doe/experiment.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 pyomo/contrib/doe/experiment.py diff --git a/pyomo/contrib/doe/experiment.py b/pyomo/contrib/doe/experiment.py deleted file mode 100644 index 17a51cf667a..00000000000 --- a/pyomo/contrib/doe/experiment.py +++ /dev/null @@ -1,18 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# ___________________________________________________________________________ -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) From e0226b07879c1647f682dd9aaf4f43ad50bb09c1 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 11:56:31 -0400 Subject: [PATCH 158/203] Update pyomo/contrib/doe/tests/test_doe_build.py Co-authored-by: Bethany Nicholson --- pyomo/contrib/doe/tests/test_doe_build.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 8d31b21ee81..78ad3b16ed9 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -265,14 +265,14 @@ def test_reactor_fd_central_design_fixing(self): continue con_name = con_name_base + str(ind) - assert hasattr(model, con_name) + self.assertTrue(hasattr(model, con_name)) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints - assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) + self.assertEqual(len(getattr(model, con_name)), (len(model.scenarios) - 1)) # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) - assert not hasattr(model, con_name_base + str(len(design_vars))) + self.assertFalse(hasattr(model, con_name_base + str(len(design_vars)))) def test_reactor_fd_backward_design_fixing(self): fd_method = "backward" From 27ed006b620cd801b90f3f99824370cc670dfac3 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 12:04:29 -0400 Subject: [PATCH 159/203] Revert "Update pyomo/contrib/doe/tests/test_doe_build.py" This reverts commit e0226b07879c1647f682dd9aaf4f43ad50bb09c1. --- pyomo/contrib/doe/tests/test_doe_build.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 78ad3b16ed9..8d31b21ee81 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -265,14 +265,14 @@ def test_reactor_fd_central_design_fixing(self): continue con_name = con_name_base + str(ind) - self.assertTrue(hasattr(model, con_name)) + assert hasattr(model, con_name) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints - self.assertEqual(len(getattr(model, con_name)), (len(model.scenarios) - 1)) + assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) - self.assertFalse(hasattr(model, con_name_base + str(len(design_vars)))) + assert not hasattr(model, con_name_base + str(len(design_vars))) def test_reactor_fd_backward_design_fixing(self): fd_method = "backward" From 451fdff3bdd6a20f88c98fbf73eae83ec8e26652 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 12:05:05 -0400 Subject: [PATCH 160/203] Revert "Delete pyomo/contrib/doe/tests/experiment_class_example.py" This reverts commit 2b2c33f4b9d1af544983eb228309d69772c437ba. --- .../doe/tests/experiment_class_example.py | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 pyomo/contrib/doe/tests/experiment_class_example.py diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py new file mode 100644 index 00000000000..e31b0da8374 --- /dev/null +++ b/pyomo/contrib/doe/tests/experiment_class_example.py @@ -0,0 +1,231 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ +# === Required imports === +import pyomo.environ as pyo +from pyomo.dae import ContinuousSet, DerivativeVar, Simulator + +from pyomo.contrib.parmest.experiment import Experiment + +import itertools + +# ======================== + + +def expand_model_components(m, base_components, index_sets): + """ + Takes model components and index sets and returns the + model component labels. + + Arguments + --------- + m: Pyomo model + base_components: list of variables from model 'm' + index_sets: list, same length as base_components, where each + element is a list of index sets, or None + """ + for val, indexes in itertools.zip_longest(base_components, index_sets): + # If the variable has no index, + # add just the model component + if not val.is_indexed(): + yield val + # If the component is indexed but no + # index supplied, add all indices + elif indexes is None: + yield from val.values() + else: + for j in itertools.product(*indexes): + yield val[j] + + +class ReactorExperiment(Experiment): + def __init__(self, data, nfe, ncp): + self.data = data + self.nfe = nfe + self.ncp = ncp + self.model = None + + def get_labeled_model(self): + if self.model is None: + self.create_model() + self.finalize_model() + self.label_experiment() + return self.model + + def create_model(self): + """ + This is an example user model provided to DoE library. + It is a dynamic problem solved by Pyomo.DAE. + + Return + ------ + m: a Pyomo.DAE model + """ + + m = self.model = pyo.ConcreteModel() + + # Model parameters + m.R = pyo.Param(mutable=False, initialize=8.314) + + # Define model variables + ######################## + # time + m.t = ContinuousSet(bounds=[0, 1]) + + # Concentrations + m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) + m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Temperature + m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) + + # Arrhenius rate law equations + m.A1 = pyo.Var(within=pyo.NonNegativeReals) + m.E1 = pyo.Var(within=pyo.NonNegativeReals) + m.A2 = pyo.Var(within=pyo.NonNegativeReals) + m.E2 = pyo.Var(within=pyo.NonNegativeReals) + + # Differential variables (Conc.) + m.dCAdt = DerivativeVar(m.CA, wrt=m.t) + m.dCBdt = DerivativeVar(m.CB, wrt=m.t) + + ######################## + # End variable def. + + # Equation def'n + ######################## + + # Expression for rate constants + @m.Expression(m.t) + def k1(m, t): + return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) + + @m.Expression(m.t) + def k2(m, t): + return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) + + # Concentration odes + @m.Constraint(m.t) + def CA_rxn_ode(m, t): + return m.dCAdt[t] == -m.k1[t] * m.CA[t] + + @m.Constraint(m.t) + def CB_rxn_ode(m, t): + return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] + + # algebraic balance for concentration of C + # Valid because the reaction system (A --> B --> C) is equimolar + @m.Constraint(m.t) + def CC_balance(m, t): + return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] + + ######################## + # End equation def'n + + def finalize_model(self): + """ + Example finalize model function. There are two main tasks + here: + 1. Extracting useful information for the model to align + with the experiment. (Here: CA0, t_final, t_control) + 2. Discretizing the model subject to this information. + + Arguments + --------- + m: Pyomo model + data: object containing vital experimental information + nfe: number of finite elements + ncp: number of collocation points for the finite elements + """ + m = self.model + + # Unpacking data before simulation + control_points = self.data["control_points"] + + m.CA[0].value = self.data["CA0"] + m.CB[0].fix(self.data["CB0"]) + m.t.update(self.data["t_range"]) + m.t.update(control_points) + m.A1.fix(self.data["A1"]) + m.A2.fix(self.data["A2"]) + m.E1.fix(self.data["E1"]) + m.E2.fix(self.data["E2"]) + + m.CA[0].setlb(self.data["CA_bounds"][0]) + m.CA[0].setub(self.data["CA_bounds"][1]) + + m.t_control = control_points + + # Discretizing the model + discr = pyo.TransformationFactory("dae.collocation") + discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) + + # Initializing Temperature in the model + cv = None + for t in m.t: + if t in control_points: + cv = control_points[t] + m.T[t].setlb(self.data["T_bounds"][0]) + m.T[t].setub(self.data["T_bounds"][1]) + m.T[t] = cv + + @m.Constraint(m.t - control_points) + def T_control(m, t): + """ + Piecewise constant Temperature between control points + """ + neighbour_t = max(tc for tc in control_points if tc < t) + return m.T[t] == m.T[neighbour_t] + + # sim.initialize_model() + + def label_experiment_impl(self, index_sets_meas): + """ + Example for annotating (labeling) the model with a + full experiment. + + Arguments + --------- + + """ + m = self.model + + # Grab measurement labels + base_comp_meas = [m.CA, m.CB, m.CC] + m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_outputs.update( + (k, None) + for k in expand_model_components(m, base_comp_meas, index_sets_meas) + ) + + # Adding no error for measurements currently + m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.measurement_error.update( + (k, 1e-2) + for k in expand_model_components(m, base_comp_meas, index_sets_meas) + ) + + # Grab design variables + base_comp_des = [m.CA, m.T] + index_sets_des = [[[m.t.first()]], [m.t_control]] + m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.experiment_inputs.update( + (k, None) for k in expand_model_components(m, base_comp_des, index_sets_des) + ) + + m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) + m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) + + +class FullReactorExperiment(ReactorExperiment): + def label_experiment(self): + m = self.model + return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]]) From 514a032dfd85b6730a7152f9e13ffd6b855fee26 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 12:05:18 -0400 Subject: [PATCH 161/203] Revert "Delete pyomo/contrib/doe/tests/result.json" This reverts commit c18f2c6d6c10d04ffe878bbd6a9fa6c77c1c153c. --- pyomo/contrib/doe/tests/result.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 pyomo/contrib/doe/tests/result.json diff --git a/pyomo/contrib/doe/tests/result.json b/pyomo/contrib/doe/tests/result.json new file mode 100644 index 00000000000..7e1b1a79a1b --- /dev/null +++ b/pyomo/contrib/doe/tests/result.json @@ -0,0 +1 @@ +{"CA0": 5.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file From d078c4fd3e1f499582fb6ad9253f732b0c48475f Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 12:05:28 -0400 Subject: [PATCH 162/203] Revert "Delete pyomo/contrib/doe/experiment.py" This reverts commit cb7d92536399f613f97b898b17a178da200c35b6. --- pyomo/contrib/doe/experiment.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 pyomo/contrib/doe/experiment.py diff --git a/pyomo/contrib/doe/experiment.py b/pyomo/contrib/doe/experiment.py new file mode 100644 index 00000000000..17a51cf667a --- /dev/null +++ b/pyomo/contrib/doe/experiment.py @@ -0,0 +1,18 @@ +# ___________________________________________________________________________ +# +# 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. +# ___________________________________________________________________________ +class Experiment(object): + def __init__(self): + self.model = None + + def get_labeled_model(self): + raise NotImplementedError( + "Derived experiment class failed to implement get_labeled_model" + ) From a8957a5a68cac0e66fb139bf1076c054e34c0bcb Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 12:24:55 -0400 Subject: [PATCH 163/203] Removed string-based location of components --- pyomo/contrib/doe/tests/test_doe_build.py | 24 +++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 8d31b21ee81..e4d61ca16a4 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -148,9 +148,9 @@ def test_reactor_fd_central_check_fd_eqns(self): ] * (1 + diff) for k, v in model.scenario_blocks[s].unknown_parameters.items(): - name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") - - if ".".join(k.name.split(".")[name_ind + 1 :]) == param.name: + if pyo.ComponentUID( + k, context=model.scenario_blocks[s] + ) == pyo.ComponentUID(param): continue other_param_val = pyo.value(k) @@ -188,12 +188,9 @@ def test_reactor_fd_backward_check_fd_eqns(self): self.assertAlmostEqual(param_val, param_val_from_step) for k, v in model.scenario_blocks[s].unknown_parameters.items(): - name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") - - if ( - not (s == 0) - and ".".join(k.name.split(".")[name_ind + 1 :]) == param.name - ): + if (s != 0) and pyo.ComponentUID( + k, context=model.scenario_blocks[s] + ) == pyo.ComponentUID(param): continue other_param_val = pyo.value(k) @@ -229,12 +226,9 @@ def test_reactor_fd_forward_check_fd_eqns(self): self.assertAlmostEqual(param_val, param_val_from_step) for k, v in model.scenario_blocks[s].unknown_parameters.items(): - name_ind = k.name.split(".").index("scenario_blocks[" + str(s) + "]") - - if ( - not (s == 0) - and ".".join(k.name.split(".")[name_ind + 1 :]) == param.name - ): + if (s != 0) and pyo.ComponentUID( + k, context=model.scenario_blocks[s] + ) == pyo.ComponentUID(param): continue other_param_val = pyo.value(k) From 3f57d1c6ef9d88b47cc6c253dc233edfb94e900e Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 12:35:50 -0400 Subject: [PATCH 164/203] Updated shoddy tests to check real values --- pyomo/contrib/doe/tests/test_doe_build.py | 63 ++++++++++++----------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index e4d61ca16a4..12c33df64a8 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -259,14 +259,12 @@ def test_reactor_fd_central_design_fixing(self): continue con_name = con_name_base + str(ind) - assert hasattr(model, con_name) - + self.assertTrue(hasattr(model, con_name)) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints - assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) - - # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) - assert not hasattr(model, con_name_base + str(len(design_vars))) + self.assertEqual(len(getattr(model, con_name)), (len(model.scenarios) - 1)) + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) + self.assertFalse(hasattr(model, con_name_base + str(len(design_vars)))) def test_reactor_fd_backward_design_fixing(self): fd_method = "backward" @@ -293,14 +291,12 @@ def test_reactor_fd_backward_design_fixing(self): continue con_name = con_name_base + str(ind) - assert hasattr(model, con_name) - + self.assertTrue(hasattr(model, con_name)) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints - assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) - - # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) - assert not hasattr(model, con_name_base + str(len(design_vars))) + self.assertEqual(len(getattr(model, con_name)), (len(model.scenarios) - 1)) + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) + self.assertFalse(hasattr(model, con_name_base + str(len(design_vars)))) def test_reactor_fd_forward_design_fixing(self): fd_method = "forward" @@ -327,14 +323,12 @@ def test_reactor_fd_forward_design_fixing(self): continue con_name = con_name_base + str(ind) - assert hasattr(model, con_name) - + self.assertTrue(hasattr(model, con_name)) # Ensure that each set of constraints has all blocks pairs with scenario 0 # i.e., (0, 1), (0, 2), ..., (0, N) --> N - 1 constraints - assert len(getattr(model, con_name)) == (len(model.scenarios) - 1) - - # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) - assert not hasattr(model, con_name_base + str(len(design_vars))) + self.assertEqual(len(getattr(model, con_name)), (len(model.scenarios) - 1)) + # Should not have any constraints sets beyond the length of design_vars - 1 (started with index 0) + self.assertFalse(hasattr(model, con_name_base + str(len(design_vars)))) def test_reactor_check_user_initialization(self): fd_method = "central" @@ -399,9 +393,10 @@ def test_get_experiment_inputs_without_blocks(self): stuff = doe_obj.get_experiment_input_values(model=doe_obj.compute_FIM_model) - assert len(stuff) == len( - [k.name for k, v in doe_obj.compute_FIM_model.experiment_inputs.items()] - ) + count = 0 + for k, v in doe_obj.compute_FIM_model.experiment_inputs.items(): + self.assertTrue(pyo.value(k) == stuff[count]) + count += 1 def test_get_experiment_outputs_without_blocks(self): fd_method = "forward" @@ -417,9 +412,10 @@ def test_get_experiment_outputs_without_blocks(self): stuff = doe_obj.get_experiment_output_values(model=doe_obj.compute_FIM_model) - assert len(stuff) == len( - [k.name for k, v in doe_obj.compute_FIM_model.experiment_outputs.items()] - ) + count = 0 + for k, v in doe_obj.compute_FIM_model.experiment_outputs.items(): + self.assertTrue(pyo.value(k) == stuff[count]) + count += 1 def test_get_measurement_error_without_blocks(self): fd_method = "forward" @@ -435,9 +431,10 @@ def test_get_measurement_error_without_blocks(self): stuff = doe_obj.get_measurement_error_values(model=doe_obj.compute_FIM_model) - assert len(stuff) == len( - [k.name for k, v in doe_obj.compute_FIM_model.measurement_error.items()] - ) + count = 0 + for k, v in doe_obj.compute_FIM_model.measurement_error.items(): + self.assertTrue(pyo.value(k) == stuff[count]) + count += 1 def test_get_unknown_parameters_without_blocks(self): fd_method = "forward" @@ -454,9 +451,10 @@ def test_get_unknown_parameters_without_blocks(self): # Make sure the values can be retrieved stuff = doe_obj.get_unknown_parameter_values(model=doe_obj.compute_FIM_model) - assert len(stuff) == len( - [k.name for k, v in doe_obj.compute_FIM_model.unknown_parameters.items()] - ) + count = 0 + for k, v in doe_obj.compute_FIM_model.unknown_parameters.items(): + self.assertTrue(pyo.value(k) == stuff[count]) + count += 1 def test_generate_blocks_without_model(self): fd_method = "forward" @@ -470,6 +468,11 @@ def test_generate_blocks_without_model(self): doe_obj._generate_scenario_blocks() + for i in doe_obj.model.parameter_scenarios: + self.assertTrue( + doe_obj.model.find_component("scenario_blocks[" + str(i) + "]") + ) + if __name__ == "__main__": unittest.main() From e0c9a0b61b66a9efd6194511ba026ca33c8e6449 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Mon, 12 Aug 2024 12:55:48 -0400 Subject: [PATCH 165/203] Added depracation error message --- pyomo/contrib/doe/doe.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index ab5d9df3faa..d001b309c77 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -65,7 +65,7 @@ class FiniteDifferenceStep(Enum): class DesignOfExperiments: def __init__( self, - experiment, + experiment=None, fd_formula="central", step=1e-3, objective_option="determinant", @@ -81,6 +81,7 @@ def __init__( logger_level=logging.WARNING, _Cholesky_option=True, _only_compute_fim_lower=True, + **kwargs ): """ This package enables model-based design of experiments analysis with Pyomo. @@ -145,6 +146,19 @@ def __init__( logger_level: Specify the level of the logger. Change to logging.DEBUG for all messages. """ + # Deprecation error + if 'create_model' in kwargs: + raise ValueError( + "DEPRECATION ERROR: Pyomo.DoE has been refactored. The current interface utilizes Experiment " + "objects that label unknown parameters, experiment inputs, experiment outputs and measurement " + "error. This avoids string-based naming which is fragile. For instruction to use the new " + "interface, please see Pyomo.DoE under the contributed packages documentation at " + "`https://pyomo.readthedocs.io/en/stable/`" + ) + + if experiment is None: + raise ValueError("Experiment object must be provided to perform DoE.") + # Check if the Experiment object has callable ``get_labeled_model`` function if not hasattr(experiment, "get_labeled_model"): raise ValueError( From a4d25c2abf4779775e02cfd804664429cced29f7 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:20:00 -0400 Subject: [PATCH 166/203] Fixed typo in doe.py --- pyomo/contrib/doe/doe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index d001b309c77..7e1ecde79c5 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -135,7 +135,7 @@ def __init__( get_labeled_model_args: Additional arguments for the ``get_labeled_model`` function on the Experiment object. _Cholesky_option: - Boolean value of whether or not to use the choleskyn factorization to compute the + Boolean value of whether or not to use the cholesky factorization to compute the determinant for the D-optimality criteria. This parameter should not be changed unless the user intends to make performance worse (i.e., compare an existing tool that uses the full FIM to this algorithm) From e78842a1880526bb9d6c969604c6a49aa75ea510 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:21:19 -0400 Subject: [PATCH 167/203] Delete pyomo/contrib/doe/tests/test_example.py Removing tests from deprecated code --- pyomo/contrib/doe/tests/test_example.py | 88 ------------------------- 1 file changed, 88 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/test_example.py diff --git a/pyomo/contrib/doe/tests/test_example.py b/pyomo/contrib/doe/tests/test_example.py deleted file mode 100644 index 47ce39d596a..00000000000 --- a/pyomo/contrib/doe/tests/test_example.py +++ /dev/null @@ -1,88 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -from pyomo.common.dependencies import ( - numpy as np, - numpy_available, - pandas as pd, - pandas_available, - scipy_available, -) - -import pyomo.common.unittest as unittest - -from pyomo.opt import SolverFactory - -ipopt_available = SolverFactory("ipopt").available() -k_aug_available = SolverFactory("k_aug").available(exception_flag=False) - - -class TestReactorExamples(unittest.TestCase): - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not scipy_available, "scipy is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_compute_FIM(self): - from pyomo.contrib.doe.examples import reactor_compute_FIM - - reactor_compute_FIM.main() - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_optimize_doe(self): - from pyomo.contrib.doe.examples import reactor_optimize_doe - - reactor_optimize_doe.main() - - @unittest.skipIf(not k_aug_available, "The 'k_aug' command is not available") - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_grid_search(self): - from pyomo.contrib.doe.examples import reactor_grid_search - - reactor_grid_search.main() - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_design_slim_create_model_interface(self): - from pyomo.contrib.doe.examples import reactor_design - - reactor_design.main(legacy_create_model_interface=False) - - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - def test_reactor_design_legacy_create_model_interface(self): - from pyomo.contrib.doe.examples import reactor_design - - reactor_design.main(legacy_create_model_interface=True) - - -if __name__ == "__main__": - unittest.main() From b036e269f2d531c1cf6bbb11d88e70328a7da5df Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:21:33 -0400 Subject: [PATCH 168/203] Delete pyomo/contrib/doe/tests/test_fim_doe.py Removing tests from deprecated code --- pyomo/contrib/doe/tests/test_fim_doe.py | 472 ------------------------ 1 file changed, 472 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/test_fim_doe.py diff --git a/pyomo/contrib/doe/tests/test_fim_doe.py b/pyomo/contrib/doe/tests/test_fim_doe.py deleted file mode 100644 index 9cae2fe6278..00000000000 --- a/pyomo/contrib/doe/tests/test_fim_doe.py +++ /dev/null @@ -1,472 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - -from pyomo.common.dependencies import numpy as np, numpy_available -import pyomo.common.unittest as unittest -from pyomo.contrib.doe import ( - MeasurementVariables, - DesignVariables, - ScenarioGenerator, - DesignOfExperiments, - VariablesWithIndices, -) -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure -from pyomo.environ import SolverFactory - -ipopt_available = SolverFactory("ipopt").available() - - -class TestMeasurementError(unittest.TestCase): - - def test_with_time_plus_one_extra_index(self): - """This tests confirms the typical usage with a time index plus one extra index. - - This test should execute without throwing any errors. - - """ - - MeasurementVariables().add_variables( - "C", indices={0: ["A", "B", "C"], 1: [0, 0.5, 1.0]}, time_index_position=1 - ) - - def test_with_time_plus_two_extra_indices(self): - """This tests confirms the typical usage with a time index plus two extra indices. - - This test should execute without throwing any errors. - - """ - - MeasurementVariables().add_variables( - "C", - indices={ - 0: ["A", "B", "C"], # species - 1: [0, 0.5, 1.0], # time - 2: [1, 2, 3], - }, # position - time_index_position=1, - ) - - def test_time_index_position_out_of_bounds(self): - """This test confirms that an error is thrown when the time index position is out of bounds.""" - - # if time index is not in indices, an value error is thrown. - with self.assertRaises(ValueError): - MeasurementVariables().add_variables( - "C", - indices={0: ["CA", "CB", "CC"], 1: [0, 0.5, 1.0]}, # species # time - time_index_position=2, # this is out of bounds - ) - - def test_single_measurement_variable(self): - """This test confirms we can specify a single measurement variable without - specifying the indices. - - The test should execute with no errors. - """ - measurements = MeasurementVariables() - measurements.add_variables("HelloWorld", indices=None, time_index_position=None) - - def test_without_time_index(self): - """This test confirms we can add a measurement variable without specifying the time index. - - The test should execute with no errors. - - """ - - MeasurementVariables().add_variables( - "C", - indices={0: ["CA", "CB", "CC"]}, # species as only index - time_index_position=None, # no time index - ) - - def test_only_time_index(self): - """This test confirms we can add a measurement variable without specifying the variable name. - - The test should execute with no errors. - - """ - - MeasurementVariables().add_variables( - "HelloWorld", # name of the variable - indices={0: [0, 0.5, 1.0]}, - time_index_position=0, - ) - - def test_with_no_measurement_name(self): - """This test confirms that an error is thrown when None is used as the measurement name.""" - - with self.assertRaises(TypeError): - MeasurementVariables().add_variables( - None, indices={0: [0, 0.5, 1.0]}, time_index_position=0 - ) - - def test_with_non_string_measurement_name(self): - """This test confirms that an error is thrown when a non-string is used as the measurement name.""" - - with self.assertRaises(TypeError): - MeasurementVariables().add_variables( - 1, indices={0: [0, 0.5, 1.0]}, time_index_position=0 - ) - - def test_non_integer_index_keys(self): - """This test confirms that strings can be used as keys for specifying the indices. - - Warning: it is possible this usage breaks something else in Pyomo.DoE. - There may be an implicit assumption that the order of the keys must match the order - of the indices in the Pyomo model. - - """ - - MeasurementVariables().add_variables( - "C", - indices={"species": ["CA", "CB", "CC"], "time": [0, 0.5, 1.0]}, - time_index_position="time", - ) - - def test_no_measurements(self): - """This test confirms that an error is thrown when the user forgets to add any measurements. - - It's okay to have no decision variables. With no measurement variables, the FIM is the zero matrix. - This (no measurements) is a common user mistake. - """ - - with self.assertRaises(ValueError): - decisions = DesignVariables() - measurements = MeasurementVariables() - DesignOfExperiments( - {}, decisions, measurements, create_model, disc_for_measure - ) - - -class TestDesignError(unittest.TestCase): - def test(self): - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # design object - exp_design = DesignVariables() - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - upper_bound = [ - 700, - 700, - 700, - 700, - 700, - 700, - 700, - 700, - 700, - 800, - ] # wrong upper bound since it has more elements than the length of variable names - lower_bound = [300, 300, 300, 300, 300, 300, 300, 300, 300] - - with self.assertRaises(ValueError): - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=lower_bound, - upper_bounds=upper_bound, - ) - - -@unittest.skipIf(not numpy_available, "Numpy is not available") -@unittest.skipIf(not ipopt_available, "ipopt is not available") -class TestPriorFIMError(unittest.TestCase): - def test(self): - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # measurement object - variable_name = "C" - indices = {0: ["CA", "CB", "CC"], 1: t_control} - - measurements = MeasurementVariables() - measurements.add_variables( - variable_name, indices=indices, time_index_position=1 - ) - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - exp_design.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - parameter_dict = {"A1": 1, "A2": 1, "E1": 1} - - # empty prior - prior_right = [[0] * 3 for i in range(3)] - prior_pass = [[0] * 5 for i in range(10)] - - # check if the error can be thrown when given a wrong shape of FIM prior - with self.assertRaises(ValueError): - doe_object = DesignOfExperiments( - parameter_dict, - exp_design, - measurements, - create_model, - prior_FIM=prior_pass, - discretize_model=disc_for_measure, - ) - - -class TestMeasurement(unittest.TestCase): - """Test the MeasurementVariables class, specify, add_element, update_variance, check_subset functions.""" - - def test_setup(self): - ### add_element function - - # control time for C [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # control time for T [h] - t_control2 = [0.2, 0.4, 0.6, 0.8] - - # measurement object - measurements = MeasurementVariables() - - # add variable C - variable_name = "C" - indices = {0: ["CA", "CB", "CC"], 1: t_control} - measurements.add_variables( - variable_name, indices=indices, time_index_position=1 - ) - - # add variable T - variable_name2 = "T" - indices2 = {0: [1, 3, 5], 1: t_control2} - measurements.add_variables( - variable_name2, indices=indices2, time_index_position=1, variance=10 - ) - - # check variable names - self.assertEqual(measurements.variable_names[0], "C[CA,0]") - self.assertEqual(measurements.variable_names[1], "C[CA,0.125]") - self.assertEqual(measurements.variable_names[-1], "T[5,0.8]") - self.assertEqual(measurements.variable_names[-2], "T[5,0.6]") - self.assertEqual(measurements.variance["T[5,0.4]"], 10) - self.assertEqual(measurements.variance["T[5,0.6]"], 10) - self.assertEqual(measurements.variance["T[5,0.4]"], 10) - self.assertEqual(measurements.variance["T[5,0.6]"], 10) - - ### specify function - var_names = [ - "C[CA,0]", - "C[CA,0.125]", - "C[CA,0.875]", - "C[CA,1]", - "C[CB,0]", - "C[CB,0.125]", - "C[CB,0.25]", - "C[CB,0.375]", - "C[CC,0]", - "C[CC,0.125]", - "C[CC,0.25]", - "C[CC,0.375]", - ] - - measurements2 = MeasurementVariables() - measurements2.set_variable_name_list(var_names) - - self.assertEqual(measurements2.variable_names[1], "C[CA,0.125]") - self.assertEqual(measurements2.variable_names[-1], "C[CC,0.375]") - - ### check_subset function - self.assertTrue(measurements.check_subset(measurements2)) - - -class TestDesignVariable(unittest.TestCase): - """Test the DesignVariable class, specify, add_element, add_bounds, update_values.""" - - def test_setup(self): - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - exp_design.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - self.assertEqual( - exp_design.variable_names, - [ - "CA0[0]", - "T[0]", - "T[0.125]", - "T[0.25]", - "T[0.375]", - "T[0.5]", - "T[0.625]", - "T[0.75]", - "T[0.875]", - "T[1]", - ], - ) - self.assertEqual(exp_design.variable_names_value["CA0[0]"], 5) - self.assertEqual(exp_design.variable_names_value["T[0]"], 470) - self.assertEqual(exp_design.upper_bounds["CA0[0]"], 5) - self.assertEqual(exp_design.upper_bounds["T[0]"], 700) - self.assertEqual(exp_design.lower_bounds["CA0[0]"], 1) - self.assertEqual(exp_design.lower_bounds["T[0]"], 300) - - design_names = exp_design.variable_names - exp1 = [4, 600, 300, 300, 300, 300, 300, 300, 300, 300] - exp1_design_dict = dict(zip(design_names, exp1)) - exp_design.update_values(exp1_design_dict) - self.assertEqual(exp_design.variable_names_value["CA0[0]"], 4) - self.assertEqual(exp_design.variable_names_value["T[0]"], 600) - - -class TestParameter(unittest.TestCase): - """Test the ScenarioGenerator class, generate_scenario function.""" - - def test_setup(self): - # set up parameter class - param_dict = {"A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} - - scenario_gene = ScenarioGenerator(param_dict, formula="central", step=0.1) - parameter_set = scenario_gene.ScenarioData - - self.assertAlmostEqual(parameter_set.eps_abs["A1"], 16.9582, places=1) - self.assertAlmostEqual(parameter_set.eps_abs["E1"], 1.5554, places=1) - self.assertEqual(parameter_set.scena_num["A2"], [2, 3]) - self.assertEqual(parameter_set.scena_num["E1"], [4, 5]) - self.assertAlmostEqual(parameter_set.scenario[0]["A1"], 93.2699, places=1) - self.assertAlmostEqual(parameter_set.scenario[2]["A2"], 408.8895, places=1) - self.assertAlmostEqual(parameter_set.scenario[-1]["E2"], 13.54, places=1) - self.assertAlmostEqual(parameter_set.scenario[-2]["E2"], 16.55, places=1) - - -class TestVariablesWithIndices(unittest.TestCase): - """Test the DesignVariable class, specify, add_element, add_bounds, update_values.""" - - def test_setup(self): - special = VariablesWithIndices() - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - ### add_element function - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - special.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - special.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - self.assertEqual( - special.variable_names, - [ - "CA0[0]", - "T[0]", - "T[0.125]", - "T[0.25]", - "T[0.375]", - "T[0.5]", - "T[0.625]", - "T[0.75]", - "T[0.875]", - "T[1]", - ], - ) - self.assertEqual(special.variable_names_value["CA0[0]"], 5) - self.assertEqual(special.variable_names_value["T[0]"], 470) - self.assertEqual(special.upper_bounds["CA0[0]"], 5) - self.assertEqual(special.upper_bounds["T[0]"], 700) - self.assertEqual(special.lower_bounds["CA0[0]"], 1) - self.assertEqual(special.lower_bounds["T[0]"], 300) - - -if __name__ == "__main__": - unittest.main() From c5a43018304bb20d8d615d5e194b917abf6ac00d Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:21:46 -0400 Subject: [PATCH 169/203] Delete pyomo/contrib/doe/tests/test_reactor_example.py Removing tests from deprecated code --- .../contrib/doe/tests/test_reactor_example.py | 234 ------------------ 1 file changed, 234 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/test_reactor_example.py diff --git a/pyomo/contrib/doe/tests/test_reactor_example.py b/pyomo/contrib/doe/tests/test_reactor_example.py deleted file mode 100644 index f88ae48db1a..00000000000 --- a/pyomo/contrib/doe/tests/test_reactor_example.py +++ /dev/null @@ -1,234 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# -# Pyomo.DoE was produced under the Department of Energy Carbon Capture Simulation -# Initiative (CCSI), and is copyright (c) 2022 by the software owners: -# TRIAD National Security, LLC., Lawrence Livermore National Security, LLC., -# Lawrence Berkeley National Laboratory, Pacific Northwest National Laboratory, -# Battelle Memorial Institute, University of Notre Dame, -# The University of Pittsburgh, The University of Texas at Austin, -# University of Toledo, West Virginia University, et al. All rights reserved. -# -# NOTICE. This Software was developed under funding from the -# U.S. Department of Energy and the U.S. Government consequently retains -# certain rights. As such, the U.S. Government has been granted for itself -# and others acting on its behalf a paid-up, nonexclusive, irrevocable, -# worldwide license in the Software to reproduce, distribute copies to the -# public, prepare derivative works, and perform publicly and display -# publicly, and to permit other to do so. -# ___________________________________________________________________________ - - -# import libraries -from pyomo.common.dependencies import numpy as np, numpy_available, pandas_available -import pyomo.common.unittest as unittest -from pyomo.contrib.doe import DesignOfExperiments, MeasurementVariables, DesignVariables -from pyomo.environ import value, ConcreteModel -from pyomo.contrib.doe.examples.reactor_kinetics import create_model, disc_for_measure -from pyomo.opt import SolverFactory - -ipopt_available = SolverFactory("ipopt").available() -k_aug_available = SolverFactory("k_aug").available(exception_flag=False) - - -class Test_Reaction_Kinetics_Example(unittest.TestCase): - def test_reaction_kinetics_create_model(self): - """Test the three options in the kinetics example.""" - # parmest option - mod = create_model(model_option="parmest") - - # global and block option - mod = ConcreteModel() - create_model(mod, model_option="stage1") - create_model(mod, model_option="stage2") - # both options need a given model, or raise errors - with self.assertRaises(ValueError): - create_model(model_option="stage1") - - with self.assertRaises(ValueError): - create_model(model_option="stage2") - - with self.assertRaises(ValueError): - create_model(model_option="NotDefined") - - @unittest.skipIf(not ipopt_available, "The 'ipopt' solver is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - @unittest.skipIf(not pandas_available, "Pandas is not available") - def test_kinetics_example_sequential_finite_then_optimize(self): - """Test the kinetics example with sequential_finite mode and then optimization""" - doe_object = self.specify_reaction_kinetics() - - # Test FIM calculation at nominal values - sensi_opt = "sequential_finite" - result = doe_object.compute_FIM( - mode=sensi_opt, scale_nominal_param_value=True, formula="central" - ) - result.result_analysis() - self.assertAlmostEqual(np.log10(result.trace), 2.7885, places=2) - self.assertAlmostEqual(np.log10(result.det), 2.8218, places=2) - self.assertAlmostEqual(np.log10(result.min_eig), -1.0123, places=2) - - ### check subset feature - sub_name = "C" - sub_indices = {0: ["CB", "CC"], 1: [0.125, 0.25, 0.5, 0.75, 0.875]} - - measure_subset = MeasurementVariables() - measure_subset.add_variables( - sub_name, indices=sub_indices, time_index_position=1 - ) - sub_result = result.subset(measure_subset) - sub_result.result_analysis() - - self.assertAlmostEqual(np.log10(sub_result.trace), 2.5535, places=2) - self.assertAlmostEqual(np.log10(sub_result.det), 1.3464, places=2) - self.assertAlmostEqual(np.log10(sub_result.min_eig), -1.5386, places=2) - - ### Test stochastic_program mode - # Prior information (scaled FIM with T=500 and T=300 experiments) - prior = np.asarray( - [ - [28.67892806, 5.41249739, -81.73674601, -24.02377324], - [5.41249739, 26.40935036, -12.41816477, -139.23992532], - [-81.73674601, -12.41816477, 240.46276004, 58.76422806], - [-24.02377324, -139.23992532, 58.76422806, 767.25584508], - ] - ) - doe_object2 = self.specify_reaction_kinetics(prior=prior) - - square_result, optimize_result = doe_object2.stochastic_program( - if_optimize=True, - if_Cholesky=True, - scale_nominal_param_value=True, - objective_option="det", - L_initial=np.linalg.cholesky(prior), - jac_initial=result.jaco_information.copy(), - tee_opt=True, - ) - - optimize_result.result_analysis() - ## 2024-May-26: changing this to test the objective instead of the optimal solution - ## It's possible the objective is flat and the optimal solution is not unique - # self.assertAlmostEqual(value(optimize_result.model.CA0[0]), 5.0, places=2) - # self.assertAlmostEqual(value(optimize_result.model.T[0.5]), 300, places=2) - self.assertAlmostEqual(np.log10(optimize_result.det), 5.744, places=2) - - square_result, optimize_result = doe_object2.stochastic_program( - if_optimize=True, - scale_nominal_param_value=True, - objective_option="trace", - jac_initial=result.jaco_information.copy(), - tee_opt=True, - ) - - optimize_result.result_analysis() - ## 2024-May-26: changing this to test the objective instead of the optimal solution - ## It's possible the objective is flat and the optimal solution is not unique - # self.assertAlmostEqual(value(optimize_result.model.CA0[0]), 5.0, places=2) - # self.assertAlmostEqual(value(optimize_result.model.T[0.5]), 300, places=2) - self.assertAlmostEqual(np.log10(optimize_result.trace), 3.340, places=2) - - @unittest.skipIf(not k_aug_available, "The 'k_aug' solver is not available") - @unittest.skipIf(not ipopt_available, "The 'ipopt' solver is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") - @unittest.skipIf(not pandas_available, "Pandas is not available") - def test_kinetics_example_direct_k_aug(self): - doe_object = self.specify_reaction_kinetics() - - # Test FIM calculation at nominal values - sensi_opt = "direct_kaug" - result = doe_object.compute_FIM( - mode=sensi_opt, scale_nominal_param_value=True, formula="central" - ) - result.result_analysis() - self.assertAlmostEqual(np.log10(result.trace), 2.789, places=2) - self.assertAlmostEqual(np.log10(result.det), 2.8247, places=2) - self.assertAlmostEqual(np.log10(result.min_eig), -1.0112, places=2) - - ### check subset feature - sub_name = "C" - sub_indices = {0: ["CB", "CC"], 1: [0.125, 0.25, 0.5, 0.75, 0.875]} - - measure_subset = MeasurementVariables() - measure_subset.add_variables( - sub_name, indices=sub_indices, time_index_position=1 - ) - sub_result = result.subset(measure_subset) - sub_result.result_analysis() - - self.assertAlmostEqual(np.log10(sub_result.trace), 2.5535, places=2) - self.assertAlmostEqual(np.log10(sub_result.det), 1.3464, places=2) - self.assertAlmostEqual(np.log10(sub_result.min_eig), -1.5386, places=2) - - def specify_reaction_kinetics(self, prior=None): - ### Define inputs - # Control time set [h] - t_control = [0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1] - # Define parameter nominal value - parameter_dict = {"A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} - - # measurement object - variable_name = "C" - indices = {0: ["CA", "CB", "CC"], 1: t_control} - - measurements = MeasurementVariables() - measurements.add_variables( - variable_name, indices=indices, time_index_position=1 - ) - - # design object - exp_design = DesignVariables() - - # add CAO as design variable - var_C = "CA0" - indices_C = {0: [0]} - exp1_C = [5] - exp_design.add_variables( - var_C, - indices=indices_C, - time_index_position=0, - values=exp1_C, - lower_bounds=1, - upper_bounds=5, - ) - - # add T as design variable - var_T = "T" - indices_T = {0: t_control} - exp1_T = [470, 300, 300, 300, 300, 300, 300, 300, 300] - - exp_design.add_variables( - var_T, - indices=indices_T, - time_index_position=0, - values=exp1_T, - lower_bounds=300, - upper_bounds=700, - ) - - design_names = exp_design.variable_names - exp1 = [5, 570, 300, 300, 300, 300, 300, 300, 300, 300] - exp1_design_dict = dict(zip(design_names, exp1)) - - exp_design.update_values(exp1_design_dict) - - doe_object = DesignOfExperiments( - parameter_dict, - exp_design, - measurements, - create_model, - discretize_model=disc_for_measure, - prior_FIM=prior, - ) - - return doe_object - - -if __name__ == "__main__": - unittest.main() From 8ec650080c0350bb24bdf62cf266212f60a6cde0 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:22:25 -0400 Subject: [PATCH 170/203] Delete pyomo/contrib/doe/tests/experiment_class_example.py Removing deprecated example file in favor of reusing example experiment file --- .../doe/tests/experiment_class_example.py | 231 ------------------ 1 file changed, 231 deletions(-) delete mode 100644 pyomo/contrib/doe/tests/experiment_class_example.py diff --git a/pyomo/contrib/doe/tests/experiment_class_example.py b/pyomo/contrib/doe/tests/experiment_class_example.py deleted file mode 100644 index e31b0da8374..00000000000 --- a/pyomo/contrib/doe/tests/experiment_class_example.py +++ /dev/null @@ -1,231 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# ___________________________________________________________________________ -# === Required imports === -import pyomo.environ as pyo -from pyomo.dae import ContinuousSet, DerivativeVar, Simulator - -from pyomo.contrib.parmest.experiment import Experiment - -import itertools - -# ======================== - - -def expand_model_components(m, base_components, index_sets): - """ - Takes model components and index sets and returns the - model component labels. - - Arguments - --------- - m: Pyomo model - base_components: list of variables from model 'm' - index_sets: list, same length as base_components, where each - element is a list of index sets, or None - """ - for val, indexes in itertools.zip_longest(base_components, index_sets): - # If the variable has no index, - # add just the model component - if not val.is_indexed(): - yield val - # If the component is indexed but no - # index supplied, add all indices - elif indexes is None: - yield from val.values() - else: - for j in itertools.product(*indexes): - yield val[j] - - -class ReactorExperiment(Experiment): - def __init__(self, data, nfe, ncp): - self.data = data - self.nfe = nfe - self.ncp = ncp - self.model = None - - def get_labeled_model(self): - if self.model is None: - self.create_model() - self.finalize_model() - self.label_experiment() - return self.model - - def create_model(self): - """ - This is an example user model provided to DoE library. - It is a dynamic problem solved by Pyomo.DAE. - - Return - ------ - m: a Pyomo.DAE model - """ - - m = self.model = pyo.ConcreteModel() - - # Model parameters - m.R = pyo.Param(mutable=False, initialize=8.314) - - # Define model variables - ######################## - # time - m.t = ContinuousSet(bounds=[0, 1]) - - # Concentrations - m.CA = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CB = pyo.Var(m.t, within=pyo.NonNegativeReals) - m.CC = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Temperature - m.T = pyo.Var(m.t, within=pyo.NonNegativeReals) - - # Arrhenius rate law equations - m.A1 = pyo.Var(within=pyo.NonNegativeReals) - m.E1 = pyo.Var(within=pyo.NonNegativeReals) - m.A2 = pyo.Var(within=pyo.NonNegativeReals) - m.E2 = pyo.Var(within=pyo.NonNegativeReals) - - # Differential variables (Conc.) - m.dCAdt = DerivativeVar(m.CA, wrt=m.t) - m.dCBdt = DerivativeVar(m.CB, wrt=m.t) - - ######################## - # End variable def. - - # Equation def'n - ######################## - - # Expression for rate constants - @m.Expression(m.t) - def k1(m, t): - return m.A1 * pyo.exp(-m.E1 * 1000 / (m.R * m.T[t])) - - @m.Expression(m.t) - def k2(m, t): - return m.A2 * pyo.exp(-m.E2 * 1000 / (m.R * m.T[t])) - - # Concentration odes - @m.Constraint(m.t) - def CA_rxn_ode(m, t): - return m.dCAdt[t] == -m.k1[t] * m.CA[t] - - @m.Constraint(m.t) - def CB_rxn_ode(m, t): - return m.dCBdt[t] == m.k1[t] * m.CA[t] - m.k2[t] * m.CB[t] - - # algebraic balance for concentration of C - # Valid because the reaction system (A --> B --> C) is equimolar - @m.Constraint(m.t) - def CC_balance(m, t): - return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] - - ######################## - # End equation def'n - - def finalize_model(self): - """ - Example finalize model function. There are two main tasks - here: - 1. Extracting useful information for the model to align - with the experiment. (Here: CA0, t_final, t_control) - 2. Discretizing the model subject to this information. - - Arguments - --------- - m: Pyomo model - data: object containing vital experimental information - nfe: number of finite elements - ncp: number of collocation points for the finite elements - """ - m = self.model - - # Unpacking data before simulation - control_points = self.data["control_points"] - - m.CA[0].value = self.data["CA0"] - m.CB[0].fix(self.data["CB0"]) - m.t.update(self.data["t_range"]) - m.t.update(control_points) - m.A1.fix(self.data["A1"]) - m.A2.fix(self.data["A2"]) - m.E1.fix(self.data["E1"]) - m.E2.fix(self.data["E2"]) - - m.CA[0].setlb(self.data["CA_bounds"][0]) - m.CA[0].setub(self.data["CA_bounds"][1]) - - m.t_control = control_points - - # Discretizing the model - discr = pyo.TransformationFactory("dae.collocation") - discr.apply_to(m, nfe=self.nfe, ncp=self.ncp, wrt=m.t) - - # Initializing Temperature in the model - cv = None - for t in m.t: - if t in control_points: - cv = control_points[t] - m.T[t].setlb(self.data["T_bounds"][0]) - m.T[t].setub(self.data["T_bounds"][1]) - m.T[t] = cv - - @m.Constraint(m.t - control_points) - def T_control(m, t): - """ - Piecewise constant Temperature between control points - """ - neighbour_t = max(tc for tc in control_points if tc < t) - return m.T[t] == m.T[neighbour_t] - - # sim.initialize_model() - - def label_experiment_impl(self, index_sets_meas): - """ - Example for annotating (labeling) the model with a - full experiment. - - Arguments - --------- - - """ - m = self.model - - # Grab measurement labels - base_comp_meas = [m.CA, m.CB, m.CC] - m.experiment_outputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.experiment_outputs.update( - (k, None) - for k in expand_model_components(m, base_comp_meas, index_sets_meas) - ) - - # Adding no error for measurements currently - m.measurement_error = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.measurement_error.update( - (k, 1e-2) - for k in expand_model_components(m, base_comp_meas, index_sets_meas) - ) - - # Grab design variables - base_comp_des = [m.CA, m.T] - index_sets_des = [[[m.t.first()]], [m.t_control]] - m.experiment_inputs = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.experiment_inputs.update( - (k, None) for k in expand_model_components(m, base_comp_des, index_sets_des) - ) - - m.unknown_parameters = pyo.Suffix(direction=pyo.Suffix.LOCAL) - m.unknown_parameters.update((k, pyo.value(k)) for k in [m.A1, m.A2, m.E1, m.E2]) - - -class FullReactorExperiment(ReactorExperiment): - def label_experiment(self): - m = self.model - return self.label_experiment_impl([[m.t_control], [m.t_control], [m.t_control]]) From f6c3fcb145ae566eb9b3c0d3e47c18b39a7c6998 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:22:51 -0400 Subject: [PATCH 171/203] Delete pyomo/contrib/doe/tests/result.json Removing result.json to have no duplicated file --- pyomo/contrib/doe/tests/result.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 pyomo/contrib/doe/tests/result.json diff --git a/pyomo/contrib/doe/tests/result.json b/pyomo/contrib/doe/tests/result.json deleted file mode 100644 index 7e1b1a79a1b..00000000000 --- a/pyomo/contrib/doe/tests/result.json +++ /dev/null @@ -1 +0,0 @@ -{"CA0": 5.0, "CA_bounds": [1.0, 5.0], "CB0": 0.0, "CC0": 0.0, "t_range": [0, 1], "control_points": {"0": 500, "0.125": 300, "0.25": 300, "0.375": 300, "0.5": 300, "0.625": 300, "0.75": 300, "0.875": 300, "1": 300}, "T_bounds": [300, 700], "A1": 84.79, "A2": 371.72, "E1": 7.78, "E2": 15.05} \ No newline at end of file From 31f93e5864619c900f4d7bbb08de58fbf3d9d22e Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:23:17 -0400 Subject: [PATCH 172/203] Delete pyomo/contrib/doe/experiment.py Removing experiment in favor of not duplicating the Experiment file in parmest. --- pyomo/contrib/doe/experiment.py | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 pyomo/contrib/doe/experiment.py diff --git a/pyomo/contrib/doe/experiment.py b/pyomo/contrib/doe/experiment.py deleted file mode 100644 index 17a51cf667a..00000000000 --- a/pyomo/contrib/doe/experiment.py +++ /dev/null @@ -1,18 +0,0 @@ -# ___________________________________________________________________________ -# -# 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. -# ___________________________________________________________________________ -class Experiment(object): - def __init__(self): - self.model = None - - def get_labeled_model(self): - raise NotImplementedError( - "Derived experiment class failed to implement get_labeled_model" - ) From 4e771ec0e0a9e78afa662bd32f2a7a0fd45f4ce3 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Mon, 12 Aug 2024 20:38:02 -0400 Subject: [PATCH 173/203] Remove idaes import from documentation --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index e3f729e761f..49931592ad1 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -162,7 +162,6 @@ Step 0: Import Pyomo and the Pyomo.DoE module and create an ``Experiment`` class >>> import pyomo.environ as pyo >>> from pyomo.contrib.doe import DesignOfExperiments >>> import numpy as np - >>> import idaes # Required to add ipopt linear solvers to path if not done manually .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :start-after: ======================== From 94e981dfb769dc505f4218f0c8b9a4288d435516 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:07:38 -0400 Subject: [PATCH 174/203] Update solving test file to have assertFoo --- .vs/CMakeWorkspaceSettings.json | 3 + pyomo/contrib/doe/doe.py | 2 - pyomo/contrib/doe/tests/test_doe_solve.py | 92 ++++++++--------------- 3 files changed, 36 insertions(+), 61 deletions(-) create mode 100644 .vs/CMakeWorkspaceSettings.json diff --git a/.vs/CMakeWorkspaceSettings.json b/.vs/CMakeWorkspaceSettings.json new file mode 100644 index 00000000000..d3e1057f48a --- /dev/null +++ b/.vs/CMakeWorkspaceSettings.json @@ -0,0 +1,3 @@ +{ + "enableCMake": false +} \ No newline at end of file diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 7e1ecde79c5..54e4749ec21 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1155,7 +1155,6 @@ def create_objective_function(self, model=None): ### Initialize the Cholesky decomposition matrix if self.Cholesky_option and self.objective_option == ObjectiveLib.determinant: - # Calculate the eigenvalues of the FIM matrix eig = np.linalg.eigvals(fim) @@ -1465,7 +1464,6 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): time_set = [] curr_point = 1 # Initial current point for design_point in factorial_points: - # Fix design variables at fixed experimental design point for i in range(len(design_point)): design_map[i][1].fix(design_point[i]) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 34a01e8c0e4..886d32a26b1 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -117,9 +117,9 @@ def get_standard_args(experiment, fd_method, obj_used): return args +@unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") +@unittest.skipIf(not numpy_available, "Numpy is not available") class TestReactorExampleSolving(unittest.TestCase): - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_central_solve(self): fd_method = "central" obj_used = "trace" @@ -132,19 +132,17 @@ def test_reactor_fd_central_solve(self): doe_obj.run_doe() - # Assert model solves - assert doe_obj.results["Solver Status"] == "ok" + # self.assertTrue(model solves + self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # Assert that Q, F, and L are the same. + # self.assertTrue(that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) + self.assertTrue(np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_forward_solve(self): fd_method = "forward" obj_used = "zero" @@ -157,18 +155,16 @@ def test_reactor_fd_forward_solve(self): doe_obj.run_doe() - assert doe_obj.results["Solver Status"] == "ok" + self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # Assert that Q, F, and L are the same. + # self.assertTrue(that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) + self.assertTrue(np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_fd_backward_solve(self): fd_method = "backward" obj_used = "trace" @@ -181,20 +177,16 @@ def test_reactor_fd_backward_solve(self): doe_obj.run_doe() - assert doe_obj.results["Solver Status"] == "ok" + self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # Assert that Q, F, and L are the same. + # self.assertTrue(that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) + self.assertTrue(np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - # TODO: Fix determinant objective code, something is awry - # Should only be using Cholesky=True - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_obj_det_solve(self): fd_method = "central" obj_used = "determinant" @@ -202,9 +194,9 @@ def test_reactor_obj_det_solve(self): experiment = FullReactorExperiment(data_ex, 10, 3) DoE_args = get_standard_args(experiment, fd_method, obj_used) - DoE_args['scale_nominal_param_value'] = ( - False # Vanilla determinant solve needs this - ) + DoE_args[ + 'scale_nominal_param_value' + ] = False # Vanilla determinant solve needs this DoE_args['_Cholesky_option'] = False DoE_args['_only_compute_fim_lower'] = False @@ -212,10 +204,8 @@ def test_reactor_obj_det_solve(self): doe_obj.run_doe() - assert doe_obj.results['Solver Status'] == "ok" + self.assertTrue(doe_obj.results['Solver Status'] == "ok") - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_obj_cholesky_solve(self): fd_method = "central" obj_used = "determinant" @@ -228,19 +218,17 @@ def test_reactor_obj_cholesky_solve(self): doe_obj.run_doe() - assert doe_obj.results["Solver Status"] == "ok" + self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # Assert that Q, F, and L are the same. + # self.assertTrue(that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Cholesky is used, there is comparison for FIM and L.T @ L - assert np.all(np.isclose(FIM, L @ L.T)) + self.assertTrue(np.all(np.isclose(FIM, L @ L.T))) # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) - assert np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q)) + self.assertTrue(np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq_centr(self): fd_method = "central" obj_used = "determinant" @@ -253,8 +241,6 @@ def test_compute_FIM_seq_centr(self): doe_obj.compute_FIM(method="sequential") - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq_forward(self): fd_method = "forward" obj_used = "determinant" @@ -267,12 +253,10 @@ def test_compute_FIM_seq_forward(self): doe_obj.compute_FIM(method="sequential") - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not scipy_available, "Scipy is not available") @unittest.skipIf( not k_aug_available.available(False), "The 'k_aug' command is not available" ) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_kaug(self): fd_method = "forward" obj_used = "determinant" @@ -285,8 +269,6 @@ def test_compute_FIM_kaug(self): doe_obj.compute_FIM(method="kaug") - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_compute_FIM_seq_backward(self): fd_method = "backward" obj_used = "determinant" @@ -299,9 +281,7 @@ def test_compute_FIM_seq_backward(self): doe_obj.compute_FIM(method="sequential") - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_grid_search(self): fd_method = "central" obj_used = "determinant" @@ -322,17 +302,15 @@ def test_reactor_grid_search(self): CA_vals = doe_obj.fim_factorial_results["CA[0]"] T_vals = doe_obj.fim_factorial_results["T[0]"] - # Assert length is correct - assert (len(CA_vals) == 9) and (len(T_vals) == 9) - assert (len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3) + # self.assertTrue(length is correct + self.assertTrue((len(CA_vals) == 9) and (len(T_vals) == 9)) + self.assertTrue((len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3)) - # Assert unique values are correct - assert (set(CA_vals).issuperset(set([1, 3, 5]))) and ( + # self.assertTrue(unique values are correct + self.assertTrue((set(CA_vals).issuperset(set([1, 3, 5]))) and ( set(T_vals).issuperset(set([300, 500, 700])) - ) + )) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_rescale_FIM(self): fd_method = "central" obj_used = "determinant" @@ -372,10 +350,8 @@ def test_rescale_FIM(self): resc_FIM = rescale_FIM(FIM, param_vals) # Compare scaled and rescaled values - assert np.all(np.isclose(FIM2, resc_FIM)) + self.assertTrue(np.all(np.isclose(FIM2, resc_FIM))) - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_solve_bad_model(self): fd_method = "central" obj_used = "determinant" @@ -392,9 +368,7 @@ def test_reactor_solve_bad_model(self): ): doe_obj.run_doe() - @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_grid_search_bad_model(self): fd_method = "central" obj_used = "determinant" @@ -416,14 +390,14 @@ def test_reactor_grid_search_bad_model(self): CA_vals = doe_obj.fim_factorial_results["CA[0]"] T_vals = doe_obj.fim_factorial_results["T[0]"] - # Assert length is correct - assert (len(CA_vals) == 9) and (len(T_vals) == 9) - assert (len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3) + # self.assertTrue(length is correct + self.assertTrue((len(CA_vals) == 9) and (len(T_vals) == 9)) + self.assertTrue((len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3)) - # Assert unique values are correct - assert (set(CA_vals).issuperset(set([1, 3, 5]))) and ( + # self.assertTrue(unique values are correct + self.assertTrue((set(CA_vals).issuperset(set([1, 3, 5]))) and ( set(T_vals).issuperset(set([300, 500, 700])) - ) + )) if __name__ == "__main__": From 324146da41e04fee5b1cf3f6a77f0858cb394945 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:11:58 -0400 Subject: [PATCH 175/203] Moved has numpy decorator to class level --- pyomo/contrib/doe/tests/test_doe_errors.py | 33 +--------------------- pyomo/contrib/doe/tests/test_doe_solve.py | 14 +++++---- 2 files changed, 9 insertions(+), 38 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 76599d3c468..40cc2ba10e5 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -57,8 +57,8 @@ def get_standard_args(experiment, fd_method, obj_used, flag): return args +@unittest.skipIf(not numpy_available, "Numpy is not available") class TestReactorExampleErrors(unittest.TestCase): - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_get_labeled_model(self): fd_method = "central" obj_used = "trace" @@ -74,7 +74,6 @@ def test_reactor_check_no_get_labeled_model(self): doe_obj = DesignOfExperiments(**DoE_args) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_experiment_outputs(self): fd_method = "central" obj_used = "trace" @@ -92,7 +91,6 @@ def test_reactor_check_no_experiment_outputs(self): ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_measurement_error(self): fd_method = "central" obj_used = "trace" @@ -110,7 +108,6 @@ def test_reactor_check_no_measurement_error(self): ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_experiment_inputs(self): fd_method = "central" obj_used = "trace" @@ -128,7 +125,6 @@ def test_reactor_check_no_experiment_inputs(self): ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_no_unknown_parameters(self): fd_method = "central" obj_used = "trace" @@ -146,7 +142,6 @@ def test_reactor_check_no_unknown_parameters(self): ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_bad_prior_size(self): fd_method = "central" obj_used = "trace" @@ -169,7 +164,6 @@ def test_reactor_check_bad_prior_size(self): ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_bad_jacobian_init_size(self): fd_method = "central" obj_used = "trace" @@ -192,7 +186,6 @@ def test_reactor_check_bad_jacobian_init_size(self): ): doe_obj.create_doe_model() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_unbuilt_update_FIM(self): fd_method = "central" obj_used = "trace" @@ -212,7 +205,6 @@ def test_reactor_check_unbuilt_update_FIM(self): ): doe_obj.update_FIM_prior(FIM=FIM_update) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_none_update_FIM(self): fd_method = "central" obj_used = "trace" @@ -232,7 +224,6 @@ def test_reactor_check_none_update_FIM(self): ): doe_obj.update_FIM_prior(FIM=FIM_update) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_results_file_name(self): fd_method = "central" obj_used = "trace" @@ -249,7 +240,6 @@ def test_reactor_check_results_file_name(self): ): doe_obj.run_doe(results_file=int(15)) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_measurement_and_output_length_match(self): fd_method = "central" obj_used = "trace" @@ -273,7 +263,6 @@ def test_reactor_check_measurement_and_output_length_match(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_grid_search_des_range_inputs(self): fd_method = "central" obj_used = "determinant" @@ -296,7 +285,6 @@ def test_reactor_grid_search_des_range_inputs(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_premature_figure_drawing(self): fd_method = "central" obj_used = "determinant" @@ -315,7 +303,6 @@ def test_reactor_premature_figure_drawing(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_no_des_var_names(self): fd_method = "central" obj_used = "determinant" @@ -340,7 +327,6 @@ def test_reactor_figure_drawing_no_des_var_names(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_no_sens_names(self): fd_method = "central" obj_used = "determinant" @@ -364,7 +350,6 @@ def test_reactor_figure_drawing_no_sens_names(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_no_fixed_names(self): fd_method = "central" obj_used = "determinant" @@ -388,7 +373,6 @@ def test_reactor_figure_drawing_no_fixed_names(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_bad_fixed_names(self): fd_method = "central" obj_used = "determinant" @@ -416,7 +400,6 @@ def test_reactor_figure_drawing_bad_fixed_names(self): @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") @unittest.skipIf(not pandas_available, "pandas is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_figure_drawing_bad_sens_names(self): fd_method = "central" obj_used = "determinant" @@ -442,7 +425,6 @@ def test_reactor_figure_drawing_bad_sens_names(self): fixed_design_variables={"CA[0]": 1}, ) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_FIM_without_FIM(self): fd_method = "central" obj_used = "trace" @@ -462,7 +444,6 @@ def test_reactor_check_get_FIM_without_FIM(self): ): doe_obj.get_FIM() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_sens_mat_without_model(self): fd_method = "central" obj_used = "trace" @@ -482,7 +463,6 @@ def test_reactor_check_get_sens_mat_without_model(self): ): doe_obj.get_sensitivity_matrix() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_exp_inputs_without_model(self): fd_method = "central" obj_used = "trace" @@ -502,7 +482,6 @@ def test_reactor_check_get_exp_inputs_without_model(self): ): doe_obj.get_experiment_input_values() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_exp_outputs_without_model(self): fd_method = "central" obj_used = "trace" @@ -522,7 +501,6 @@ def test_reactor_check_get_exp_outputs_without_model(self): ): doe_obj.get_experiment_output_values() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_unknown_params_without_model(self): fd_method = "central" obj_used = "trace" @@ -542,7 +520,6 @@ def test_reactor_check_get_unknown_params_without_model(self): ): doe_obj.get_unknown_parameter_values() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_reactor_check_get_meas_error_without_model(self): fd_method = "central" obj_used = "trace" @@ -562,7 +539,6 @@ def test_reactor_check_get_meas_error_without_model(self): ): doe_obj.get_measurement_error_values() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_multiple_exp_not_implemented_seq(self): fd_method = "central" obj_used = "trace" @@ -581,7 +557,6 @@ def test_multiple_exp_not_implemented_seq(self): ): doe_obj.run_multi_doe_sequential(N_exp=1) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_multiple_exp_not_implemented_sim(self): fd_method = "central" obj_used = "trace" @@ -600,7 +575,6 @@ def test_multiple_exp_not_implemented_sim(self): ): doe_obj.run_multi_doe_simultaneous(N_exp=1) - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_update_unknown_parameter_values_not_implemented_seq(self): fd_method = "central" obj_used = "trace" @@ -620,7 +594,6 @@ def test_update_unknown_parameter_values_not_implemented_seq(self): doe_obj.update_unknown_parameter_values() @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_bad_FD_generate_scens(self): fd_method = "central" obj_used = "trace" @@ -642,7 +615,6 @@ def test_bad_FD_generate_scens(self): doe_obj._generate_scenario_blocks() @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_bad_FD_seq_compute_FIM(self): fd_method = "central" obj_used = "trace" @@ -663,7 +635,6 @@ def test_bad_FD_seq_compute_FIM(self): doe_obj.fd_formula = "bad things" doe_obj.compute_FIM(method="sequential") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_bad_objective(self): fd_method = "central" obj_used = "trace" @@ -684,7 +655,6 @@ def test_bad_objective(self): doe_obj.objective_option = "bad things" doe_obj.create_objective_function() - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_no_model_for_objective(self): fd_method = "central" obj_used = "trace" @@ -705,7 +675,6 @@ def test_no_model_for_objective(self): doe_obj.create_objective_function() @unittest.skipIf(not ipopt_available, "The 'ipopt' command is not available") - @unittest.skipIf(not numpy_available, "Numpy is not available") def test_bad_compute_FIM_option(self): fd_method = "central" obj_used = "trace" diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 886d32a26b1..eee123f436a 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -307,9 +307,10 @@ def test_reactor_grid_search(self): self.assertTrue((len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3)) # self.assertTrue(unique values are correct - self.assertTrue((set(CA_vals).issuperset(set([1, 3, 5]))) and ( - set(T_vals).issuperset(set([300, 500, 700])) - )) + self.assertTrue( + (set(CA_vals).issuperset(set([1, 3, 5]))) + and (set(T_vals).issuperset(set([300, 500, 700]))) + ) def test_rescale_FIM(self): fd_method = "central" @@ -395,9 +396,10 @@ def test_reactor_grid_search_bad_model(self): self.assertTrue((len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3)) # self.assertTrue(unique values are correct - self.assertTrue((set(CA_vals).issuperset(set([1, 3, 5]))) and ( - set(T_vals).issuperset(set([300, 500, 700])) - )) + self.assertTrue( + (set(CA_vals).issuperset(set([1, 3, 5]))) + and (set(T_vals).issuperset(set([300, 500, 700]))) + ) if __name__ == "__main__": From 9c526903211d6d3b7fabfad4a9dde93a8726da28 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:15:24 -0400 Subject: [PATCH 176/203] Updated language in comments and URL Have to change this URL at some point in time. --- pyomo/contrib/doe/doe.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 54e4749ec21..b1d2dcabc24 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -87,7 +87,7 @@ def __init__( This package enables model-based design of experiments analysis with Pyomo. Both direct optimization and enumeration modes are supported. - The package has been refactored from its original form as of ##/##/##24. See + The package has been refactored from its original form as of August 24. See the documentation for more information. Parameters @@ -152,8 +152,8 @@ def __init__( "DEPRECATION ERROR: Pyomo.DoE has been refactored. The current interface utilizes Experiment " "objects that label unknown parameters, experiment inputs, experiment outputs and measurement " "error. This avoids string-based naming which is fragile. For instruction to use the new " - "interface, please see Pyomo.DoE under the contributed packages documentation at " - "`https://pyomo.readthedocs.io/en/stable/`" + "interface, please see the Pyomo.DoE under the contributed packages documentation at " + "`https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`" ) if experiment is None: From d8307a73941eab309397b8570d8bfca05a38e1ff Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:25:14 -0400 Subject: [PATCH 177/203] Removed safe naming for later discussion Also removed a potential bug for adding this in the future. --- pyomo/contrib/doe/doe.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index b1d2dcabc24..6775463ce95 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -254,9 +254,11 @@ def run_doe(self, model=None, results_file=None): if model is None: model = self.model else: - doe_block = pyo.Block() - doe_block_name = unique_component_name(model, "design_of_experiments_block") - model.add_component(doe_block_name, doe_block) + # TODO: Add safe naming when a model is passed by the user. + # doe_block = pyo.Block() + # doe_block_name = unique_component_name(model, "design_of_experiments_block") + # model.add_component(doe_block_name, doe_block) + pass # ToDo: potentially work with this for more complicated models # Create the full DoE model (build scenarios for F.D. scheme) @@ -346,23 +348,23 @@ def run_doe(self, model=None, results_file=None): self.results["Sensitivity Matrix"] = self.get_sensitivity_matrix() self.results["Experiment Design"] = self.get_experiment_input_values() self.results["Experiment Design Names"] = [ - str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) - for k in self.model.scenario_blocks[0].experiment_inputs + str(pyo.ComponentUID(k, context=model.scenario_blocks[0])) + for k in model.scenario_blocks[0].experiment_inputs ] self.results["Experiment Outputs"] = self.get_experiment_output_values() self.results["Experiment Output Names"] = [ - str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) - for k in self.model.scenario_blocks[0].experiment_outputs + str(pyo.ComponentUID(k, context=model.scenario_blocks[0])) + for k in model.scenario_blocks[0].experiment_outputs ] self.results["Unknown Parameters"] = self.get_unknown_parameter_values() self.results["Unknown Parameter Names"] = [ - str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) - for k in self.model.scenario_blocks[0].unknown_parameters + str(pyo.ComponentUID(k, context=model.scenario_blocks[0])) + for k in model.scenario_blocks[0].unknown_parameters ] self.results["Measurement Error"] = self.get_measurement_error_values() self.results["Measurement Error Names"] = [ - str(pyo.ComponentUID(k, context=self.model.scenario_blocks[0])) - for k in self.model.scenario_blocks[0].measurement_error + str(pyo.ComponentUID(k, context=model.scenario_blocks[0])) + for k in model.scenario_blocks[0].measurement_error ] self.results["Prior FIM"] = [list(row) for row in list(self.prior_FIM)] From ec93a2b583862e6804eed158991ed60ae38338a6 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:28:21 -0400 Subject: [PATCH 178/203] Added solver safeguarding TODO --- pyomo/contrib/doe/doe.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 6775463ce95..d4d361b3245 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -282,6 +282,13 @@ def run_doe(self, model=None, results_file=None): for comp in model.scenario_blocks[0].experiment_inputs: comp.fix() + # TODO: safeguard solver call to see if solver terminated successfully + # see below commented code: + # res = self.solver.solve(model, tee=self.tee, load_solutions=False) + # if pyo.check_optimal_termination(res): + # model.load_solution(res) + # else: + # # The solver was unsuccessful, might want to warn the user or terminate gracefully, etc. model.dummy_obj = pyo.Objective(expr=0, sense=pyo.minimize) self.solver.solve(model, tee=self.tee) From 3541460f8aa1f7996d4a5611664f9a72d4bbe80b Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:44:25 -0400 Subject: [PATCH 179/203] Added TODOs and added error to unreachable code --- pyomo/contrib/doe/doe.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index d4d361b3245..bc1157e1564 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -454,6 +454,9 @@ def compute_FIM(self, model=None, method="sequential"): else: self.check_model_FIM(FIM=self.prior_FIM) + # TODO: Add a check to see if the model has an objective and deactivate it. + # This solve should only be a square solve without any obj function. + if method == "sequential": self._sequential_FIM(model=model) self._computed_FIM = self.seq_FIM @@ -478,7 +481,7 @@ def _sequential_FIM(self, model=None): matrix to subsequently compute the FIM. """ - # Build a singular model instance + # Build a single model instance if model is None: self.compute_FIM_model = self.experiment.get_labeled_model( **self.get_labeled_model_args @@ -548,7 +551,7 @@ def _sequential_FIM(self, model=None): # Simulate the model try: res = self.solver.solve(model) - assert res.solver.termination_condition == "optimal" + pyo.assert_optimal_termination(res) except: raise RuntimeError( "Model from experiment did not solve appropriately. Make sure the model is well-posed." @@ -635,9 +638,7 @@ def _kaug_FIM(self, model=None): if not hasattr(model, "objective"): model.objective = pyo.Objective(expr=0, sense=pyo.minimize) - # call k_aug get_dsdp function - # Solve the square problem - # Deactivate object and fix experimental design decisions to make square + # Fix design variables to make the problem square for comp in model.experiment_inputs: comp.fix() @@ -789,8 +790,9 @@ def initialize_jac(m, i, j): return dict_jac_initialize[(i, j)] # Otherwise initialize to 0.1 (which is an arbitrary non-zero value) else: - # Add flag as this should never be reached. - return 0.1 + raise AttributeError( + "Jacobian being initialized when the jac_initial attribute is None. Please contact the developers as you should not see this error." + ) model.sensitivity_jacobian = pyo.Var( model.output_names, model.parameter_names, initialize=initialize_jac From b2899fb6fae26b948ed97978c4259c0c266d520d Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:52:49 -0400 Subject: [PATCH 180/203] Fixed out of scope 'model' references --- pyomo/contrib/doe/doe.py | 50 ++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index bc1157e1564..eabfd3302d0 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -845,7 +845,7 @@ def jacobian_rule(m, n, p): """ fd_step_mult = 1 cuid = pyo.ComponentUID(n) - param_ind = model.parameter_names.data().index(p) + param_ind = m.parameter_names.data().index(p) # Different FD schemes lead to different scenarios for the computation if self.fd_formula == FiniteDifferenceStep.central: @@ -862,11 +862,9 @@ def jacobian_rule(m, n, p): var_up = cuid.find_component_on(m.scenario_blocks[s1]) var_lo = cuid.find_component_on(m.scenario_blocks[s2]) - param = model.parameter_scenarios[max(s1, s2)] - param_loc = pyo.ComponentUID(param).find_component_on( - model.scenario_blocks[0] - ) - param_val = model.scenario_blocks[0].unknown_parameters[param_loc] + param = m.parameter_scenarios[max(s1, s2)] + param_loc = pyo.ComponentUID(param).find_component_on(m.scenario_blocks[0]) + param_val = m.scenario_blocks[0].unknown_parameters[param_loc] param_diff = param_val * fd_step_mult * self.step if self.scale_nominal_param_value: @@ -905,8 +903,8 @@ def fim_rule(m, p, q): p: unknown parameter q: unknown parameter """ - p_ind = list(model.parameter_names).index(p) - q_ind = list(model.parameter_names).index(q) + p_ind = list(m.parameter_names).index(p) + q_ind = list(m.parameter_names).index(q) # If the row is less than the column, skip the constraint # This logic is consistent with making the FIM a lower @@ -921,14 +919,12 @@ def fim_rule(m, p, q): m.fim[p, q] == sum( 1 - / model.scenario_blocks[0].measurement_error[ - pyo.ComponentUID(n).find_component_on( - model.scenario_blocks[0] - ) + / m.scenario_blocks[0].measurement_error[ + pyo.ComponentUID(n).find_component_on(m.scenario_blocks[0]) ] * m.sensitivity_jacobian[n, p] * m.sensitivity_jacobian[n, q] - for n in model.output_names + for n in m.output_names ) + m.prior_FIM[p, q] ) @@ -1057,7 +1053,8 @@ def _generate_scenario_blocks(self, model=None): # Generate blocks for finite difference scenarios def build_block_scenarios(b, s): # Generate model for the finite difference scenario - b.transfer_attributes_from(model.base_model.clone()) + m = b.model() + b.transfer_attributes_from(m.base_model.clone()) # Forward/Backward difference have a stationary case (s == 0), no parameter to perturb if self.fd_formula in [ @@ -1067,7 +1064,7 @@ def build_block_scenarios(b, s): if s == 0: return - param = model.parameter_scenarios[s] + param = m.parameter_scenarios[s] # Perturbation to be (1 + diff) * param_value if self.fd_formula == FiniteDifferenceStep.central: @@ -1084,9 +1081,9 @@ def build_block_scenarios(b, s): pass # Update parameter values for the given finite difference scenario - pyo.ComponentUID(param, context=model.base_model).find_component_on( + pyo.ComponentUID(param, context=m.base_model).find_component_on( b - ).set_value(model.base_model.unknown_parameters[param] * (1 + diff)) + ).set_value(m.base_model.unknown_parameters[param] * (1 + diff)) model.scenario_blocks = pyo.Block(model.scenarios, rule=build_block_scenarios) @@ -1103,8 +1100,8 @@ def global_design_fixing(m, s): if s == 0: return pyo.Constraint.Skip block_design_var = pyo.ComponentUID( - d, context=model.scenario_blocks[0] - ).find_component_on(model.scenario_blocks[s]) + d, context=m.scenario_blocks[0] + ).find_component_on(m.scenario_blocks[s]) return d == block_design_var model.add_component( @@ -1184,20 +1181,19 @@ def create_objective_function(self, model=None): for j, d in enumerate(model.parameter_names): model.L[c, d].value = L[i, j] - def cholesky_imp(m, c, d): + def cholesky_imp(b, c, d): """ Calculate Cholesky L matrix using algebraic constraints """ # If the row is greater than or equal to the column, we are in the # lower triangle region of the L and FIM matrices. # This region is where our equations are well-defined. - if list(model.parameter_names).index(c) >= list( - model.parameter_names - ).index(d): - return model.fim[c, d] == sum( - model.L[c, model.parameter_names.at(k + 1)] - * model.L[d, model.parameter_names.at(k + 1)] - for k in range(list(model.parameter_names).index(d) + 1) + m = b.model() + if list(m.parameter_names).index(c) >= list(m.parameter_names).index(d): + return m.fim[c, d] == sum( + m.L[c, m.parameter_names.at(k + 1)] + * m.L[d, m.parameter_names.at(k + 1)] + for k in range(list(m.parameter_names).index(d) + 1) ) else: # This is the empty half of L above the diagonal From 137572a0122f54b235fd32f11ac7e32ae3a56974 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 09:57:41 -0400 Subject: [PATCH 181/203] Fixed more out of scope `model` references --- pyomo/contrib/doe/doe.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index eabfd3302d0..e3f5a802c11 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1199,18 +1199,20 @@ def cholesky_imp(b, c, d): # This is the empty half of L above the diagonal return pyo.Constraint.Skip - def trace_calc(m): + def trace_calc(b): """ Calculate FIM elements. Can scale each element with 1000 for performance """ - return model.trace == sum(model.fim[j, j] for j in model.parameter_names) + m = b.model() + return m.trace == sum(m.fim[j, j] for j in m.parameter_names) - def determinant_general(m): + def determinant_general(b): r"""Calculate determinant. Can be applied to FIM of any size. det(A) = \sum_{\sigma in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) Use permutation() to get permutations, sgn() to get signature """ - r_list = list(range(len(model.parameter_names))) + m = b.model() + r_list = list(range(len(m.parameter_names))) # get all permutations object_p = permutations(r_list) list_p = list(object_p) @@ -1222,22 +1224,22 @@ def determinant_general(m): x_order = list_p[i] # sigma_i is the value in the i-th position after the reordering \sigma for x in range(len(x_order)): - for y, element in enumerate(model.parameter_names): + for y, element in enumerate(m.parameter_names): if x_order[x] == y: name_order.append(element) # det(A) = sum_{\sigma \in \S_n} (sgn(\sigma) * \Prod_{i=1}^n a_{i,\sigma_i}) det_perm = sum( self._sgn(list_p[d]) * math.prod( - model.fim[ - model.parameter_names.at(val + 1), - model.parameter_names.at(ind + 1), + m.fim[ + m.parameter_names.at(val + 1), + m.parameter_names.at(ind + 1), ] for ind, val in enumerate(list_p[d]) ) for d in range(len(list_p)) ) - return model.determinant == det_perm + return m.determinant == det_perm if self.Cholesky_option and self.objective_option == ObjectiveLib.determinant: model.obj_cons.cholesky_cons = pyo.Constraint( From b067bd1660dc97e7bd9dcffa5754359c1044dc10 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 10:02:21 -0400 Subject: [PATCH 182/203] Fixed check model labels function Also edited some incorrect docstrings to be correct. --- pyomo/contrib/doe/doe.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index e3f5a802c11..d6a7dc0a2d8 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1231,10 +1231,7 @@ def determinant_general(b): det_perm = sum( self._sgn(list_p[d]) * math.prod( - m.fim[ - m.parameter_names.at(val + 1), - m.parameter_names.at(ind + 1), - ] + m.fim[m.parameter_names.at(val + 1), m.parameter_names.at(ind + 1)] for ind, val in enumerate(list_p[d]) ) for d in range(len(list_p)) @@ -1280,12 +1277,9 @@ def check_model_labels(self, model=None): Parameters ---------- - model: model for suffix checking, Default: None, (self.model) + model: model for suffix checking """ - if model is None: - model = self.model.base_model - # Check that experimental outputs exist try: outputs = [k.name for k, v in model.experiment_outputs.items()] @@ -1403,7 +1397,9 @@ def update_unknown_parameter_values(self, model=None, param_vals=None): ) # Evaluates FIM and statistics for a full factorial space (same as run_grid_search) - def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): + def compute_FIM_full_factorial( + self, model=None, design_ranges=None, method="sequential" + ): """ Will run a simulation-based full factorial exploration of the experimental input space (i.e., a ``grid search`` or @@ -1452,7 +1448,7 @@ def compute_FIM_full_factorial(self, design_ranges=None, method="sequential"): "Design ranges keys must be a subset of experimental design names." ) - # ToDo: Add more objetive types? i.e., modified-E; G-opt; V-opt; etc? + # ToDo: Add more objective types? i.e., modified-E; G-opt; V-opt; etc? # ToDo: Also, make this a result object, or more user friendly. fim_factorial_results = {k.name: [] for k, v in model.experiment_inputs.items()} fim_factorial_results.update( From f71d4c7e7e504f9a62dc27d2fb1a12abfa24f900 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 10:03:55 -0400 Subject: [PATCH 183/203] Added missing docstring inputs --- pyomo/contrib/doe/doe.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index d6a7dc0a2d8..2fbc5fccd77 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1722,6 +1722,7 @@ def _curve1D( In a 1D sensitivity curve, it is the design variable by which the curve is drawn. font_axes: axes label font size font_tick: tick label font size + figure_file_name: string or Path, path to save the figure as log_scale: if True, the result matrix will be scaled by log10 Returns @@ -1856,6 +1857,7 @@ def _heatmap( In a 2D heatmap, it should be the first design variable in the dv_ranges font_axes: axes label font size font_tick: tick label font size + figure_file_name: string or Path, path to save the figure as log_scale: if True, the result matrix will be scaled by log10 Returns From 08e66187f4eb55661b9b6e7ca663a530c6b09dd4 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 10:08:11 -0400 Subject: [PATCH 184/203] Added TODO for solve failure message on user model --- pyomo/contrib/doe/doe.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 2fbc5fccd77..c721299f2be 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -553,6 +553,8 @@ def _sequential_FIM(self, model=None): res = self.solver.solve(model) pyo.assert_optimal_termination(res) except: + # TODO: Make error message more verbose, i.e., add unknown parameter values so the + # user can try to solve the model instance outside of the pyomo.DoE framework. raise RuntimeError( "Model from experiment did not solve appropriately. Make sure the model is well-posed." ) From fdd05835861413dfff4a619875c07b269f84c834 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Tue, 13 Aug 2024 11:52:04 -0400 Subject: [PATCH 185/203] Ran Black --- pyomo/contrib/doe/tests/test_doe_solve.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index eee123f436a..0c66ec0a8bf 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -194,9 +194,9 @@ def test_reactor_obj_det_solve(self): experiment = FullReactorExperiment(data_ex, 10, 3) DoE_args = get_standard_args(experiment, fd_method, obj_used) - DoE_args[ - 'scale_nominal_param_value' - ] = False # Vanilla determinant solve needs this + DoE_args['scale_nominal_param_value'] = ( + False # Vanilla determinant solve needs this + ) DoE_args['_Cholesky_option'] = False DoE_args['_only_compute_fim_lower'] = False From 1b9729a0bebc6944a8fb1b9060aad944b723b482 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Tue, 13 Aug 2024 12:32:58 -0400 Subject: [PATCH 186/203] Added more verbose TODO tasks --- pyomo/contrib/doe/doe.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index c721299f2be..47992df71c0 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1551,10 +1551,10 @@ def compute_FIM_full_factorial( self.fim_factorial_results = fim_factorial_results - # ToDo: add automated figure drawing as it was before (perhaps reuse the code) return self.fim_factorial_results - # Plotting + # TODO: Overhaul plotting functions to not use strings + # TODO: Make the plotting functionalities work for >2 design features def draw_factorial_figure( self, results=None, From 57a8a81e9b865b3eb2b86465a4304e6ad9190535 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Tue, 13 Aug 2024 13:17:09 -0400 Subject: [PATCH 187/203] Delete .vs directory Remove file that was accidentally added. --- .vs/CMakeWorkspaceSettings.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .vs/CMakeWorkspaceSettings.json diff --git a/.vs/CMakeWorkspaceSettings.json b/.vs/CMakeWorkspaceSettings.json deleted file mode 100644 index d3e1057f48a..00000000000 --- a/.vs/CMakeWorkspaceSettings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "enableCMake": false -} \ No newline at end of file From 0b08aefab711382c00a57bf67e30eb62c37b62e3 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 13:22:19 -0400 Subject: [PATCH 188/203] Remove other user-defined model unique naming Added to TODO list in #3345 --- pyomo/contrib/doe/doe.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 47992df71c0..005d9c0da52 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -433,10 +433,12 @@ def compute_FIM(self, model=None, method="sequential"): ).clone() model = self.compute_FIM_model else: - doe_block = pyo.Block() - doe_block_name = unique_component_name(model, "design_of_experiments_block") - model.add_component(doe_block_name, doe_block) - self.compute_FIM_model = model + # TODO: Add safe naming when a model is passed by the user. + # doe_block = pyo.Block() + # doe_block_name = unique_component_name(model, "design_of_experiments_block") + # model.add_component(doe_block_name, doe_block) + # self.compute_FIM_model = model + pass self.check_model_labels(model=model) @@ -731,9 +733,11 @@ def create_doe_model(self, model=None): if model is None: model = self.model else: - doe_block = pyo.Block() - doe_block_name = unique_component_name(model, "design_of_experiments_block") - model.add_component(doe_block_name, doe_block) + # TODO: Add safe naming when a model is passed by the user. + # doe_block = pyo.Block() + # doe_block_name = unique_component_name(model, "design_of_experiments_block") + # model.add_component(doe_block_name, doe_block) + pass # Developer recommendation: use the Cholesky decomposition for D-optimality # The explicit formula is available for benchmarking purposes and is NOT recommended From 7aab583f4809f4b83f94f4043ee353e6678c88d7 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 13:24:38 -0400 Subject: [PATCH 189/203] Revert accidental find and replace in tests --- pyomo/contrib/doe/tests/test_doe_solve.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 0c66ec0a8bf..61a7e3eafcc 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -132,10 +132,10 @@ def test_reactor_fd_central_solve(self): doe_obj.run_doe() - # self.assertTrue(model solves + # assert model solves self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # self.assertTrue(that Q, F, and L are the same. + # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L @@ -157,7 +157,7 @@ def test_reactor_fd_forward_solve(self): self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # self.assertTrue(that Q, F, and L are the same. + # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L @@ -179,7 +179,7 @@ def test_reactor_fd_backward_solve(self): self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # self.assertTrue(that Q, F, and L are the same. + # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Trace is used, no comparison for FIM and L.T @ L @@ -220,7 +220,7 @@ def test_reactor_obj_cholesky_solve(self): self.assertTrue(doe_obj.results["Solver Status"] == "ok") - # self.assertTrue(that Q, F, and L are the same. + # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) # Since Cholesky is used, there is comparison for FIM and L.T @ L @@ -302,11 +302,11 @@ def test_reactor_grid_search(self): CA_vals = doe_obj.fim_factorial_results["CA[0]"] T_vals = doe_obj.fim_factorial_results["T[0]"] - # self.assertTrue(length is correct + # assert length is correct self.assertTrue((len(CA_vals) == 9) and (len(T_vals) == 9)) self.assertTrue((len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3)) - # self.assertTrue(unique values are correct + # assert unique values are correct self.assertTrue( (set(CA_vals).issuperset(set([1, 3, 5]))) and (set(T_vals).issuperset(set([300, 500, 700]))) @@ -391,11 +391,11 @@ def test_reactor_grid_search_bad_model(self): CA_vals = doe_obj.fim_factorial_results["CA[0]"] T_vals = doe_obj.fim_factorial_results["T[0]"] - # self.assertTrue(length is correct + # assert length is correct self.assertTrue((len(CA_vals) == 9) and (len(T_vals) == 9)) self.assertTrue((len(set(CA_vals)) == 3) and (len(set(T_vals)) == 3)) - # self.assertTrue(unique values are correct + # assert unique values are correct self.assertTrue( (set(CA_vals).issuperset(set([1, 3, 5]))) and (set(T_vals).issuperset(set([300, 500, 700]))) From b1214a7185194725efb92628ac5ac0c5b3940174 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 13:28:31 -0400 Subject: [PATCH 190/203] Updated documentation comment to be more verbose --- doc/OnlineDocs/contributed_packages/doe/doe.rst | 4 ++-- pyomo/contrib/doe/examples/reactor_experiment.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/OnlineDocs/contributed_packages/doe/doe.rst b/doc/OnlineDocs/contributed_packages/doe/doe.rst index 49931592ad1..73aa160c130 100644 --- a/doc/OnlineDocs/contributed_packages/doe/doe.rst +++ b/doc/OnlineDocs/contributed_packages/doe/doe.rst @@ -174,7 +174,7 @@ The process model for the reaction kinetics problem is shown below. We build the .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py :start-after: Create flexible model without data - :end-before: End equation def'n + :end-before: End equation definition Step 2: Finalize the Pyomo process model ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -182,7 +182,7 @@ Step 2: Finalize the Pyomo process model Here we add data to the model and finalize the discretization. This step is required before the model can be labeled. .. literalinclude:: ../../../../pyomo/contrib/doe/examples/reactor_experiment.py - :start-after: End equation def'n + :start-after: End equation definition :end-before: End model finalization Step 3: Label the information needed for DoE analysis diff --git a/pyomo/contrib/doe/examples/reactor_experiment.py b/pyomo/contrib/doe/examples/reactor_experiment.py index 37e97250a7e..c94b89b026c 100644 --- a/pyomo/contrib/doe/examples/reactor_experiment.py +++ b/pyomo/contrib/doe/examples/reactor_experiment.py @@ -82,7 +82,7 @@ def create_model(self): ######################## # End variable def. - # Equation def'n + # Equation definition ######################## # Expression for rate constants @@ -110,7 +110,7 @@ def CC_balance(m, t): return m.CA[0] == m.CA[t] + m.CB[t] + m.CC[t] ######################## - # End equation def'n + # End equation definition def finalize_model(self): """ From 6db5023299e9385c8cc0c2ab7eb08101dc6b9b1c Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 13:32:09 -0400 Subject: [PATCH 191/203] Change assertTrue to assertEqual in test build --- pyomo/contrib/doe/tests/test_doe_build.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 12c33df64a8..6f0d1f3737d 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -395,7 +395,7 @@ def test_get_experiment_inputs_without_blocks(self): count = 0 for k, v in doe_obj.compute_FIM_model.experiment_inputs.items(): - self.assertTrue(pyo.value(k) == stuff[count]) + self.assertEqual(pyo.value(k), stuff[count]) count += 1 def test_get_experiment_outputs_without_blocks(self): @@ -414,7 +414,7 @@ def test_get_experiment_outputs_without_blocks(self): count = 0 for k, v in doe_obj.compute_FIM_model.experiment_outputs.items(): - self.assertTrue(pyo.value(k) == stuff[count]) + self.assertEqual(pyo.value(k), stuff[count]) count += 1 def test_get_measurement_error_without_blocks(self): @@ -433,7 +433,7 @@ def test_get_measurement_error_without_blocks(self): count = 0 for k, v in doe_obj.compute_FIM_model.measurement_error.items(): - self.assertTrue(pyo.value(k) == stuff[count]) + self.assertEqual(pyo.value(k), stuff[count]) count += 1 def test_get_unknown_parameters_without_blocks(self): @@ -453,7 +453,7 @@ def test_get_unknown_parameters_without_blocks(self): count = 0 for k, v in doe_obj.compute_FIM_model.unknown_parameters.items(): - self.assertTrue(pyo.value(k) == stuff[count]) + self.assertEqual(pyo.value(k), stuff[count]) count += 1 def test_generate_blocks_without_model(self): From 0c566c9e78ae057decacbb452d432e01a6bc8ddc Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 13:37:18 -0400 Subject: [PATCH 192/203] Change assertTrue to assertEqual in test solve --- pyomo/contrib/doe/tests/test_doe_solve.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 61a7e3eafcc..bf63862b345 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -133,7 +133,7 @@ def test_reactor_fd_central_solve(self): doe_obj.run_doe() # assert model solves - self.assertTrue(doe_obj.results["Solver Status"] == "ok") + self.assertEqual(doe_obj.results["Solver Status"], "ok") # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) @@ -155,7 +155,7 @@ def test_reactor_fd_forward_solve(self): doe_obj.run_doe() - self.assertTrue(doe_obj.results["Solver Status"] == "ok") + self.assertEqual(doe_obj.results["Solver Status"], "ok") # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) @@ -177,7 +177,7 @@ def test_reactor_fd_backward_solve(self): doe_obj.run_doe() - self.assertTrue(doe_obj.results["Solver Status"] == "ok") + self.assertEqual(doe_obj.results["Solver Status"], "ok") # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) @@ -204,7 +204,7 @@ def test_reactor_obj_det_solve(self): doe_obj.run_doe() - self.assertTrue(doe_obj.results['Solver Status'] == "ok") + self.assertEqual(doe_obj.results['Solver Status'], "ok") def test_reactor_obj_cholesky_solve(self): fd_method = "central" @@ -218,7 +218,7 @@ def test_reactor_obj_cholesky_solve(self): doe_obj.run_doe() - self.assertTrue(doe_obj.results["Solver Status"] == "ok") + self.assertEqual(doe_obj.results["Solver Status"], "ok") # assert that Q, F, and L are the same. FIM, Q, L, sigma_inv = get_FIM_Q_L(doe_obj=doe_obj) From 485e0fcc79f73778774e3ad15de0666737d4f0fb Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 15:11:12 -0400 Subject: [PATCH 193/203] Update test file with os.path and pyomo.fileutils --- pyomo/contrib/doe/tests/test_doe_build.py | 7 ++++--- pyomo/contrib/doe/tests/test_doe_errors.py | 7 ++++--- pyomo/contrib/doe/tests/test_doe_solve.py | 7 ++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_build.py b/pyomo/contrib/doe/tests/test_doe_build.py index 6f0d1f3737d..074ab58391c 100644 --- a/pyomo/contrib/doe/tests/test_doe_build.py +++ b/pyomo/contrib/doe/tests/test_doe_build.py @@ -9,7 +9,7 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ import json -from pathlib import Path +import os.path from pyomo.common.dependencies import ( numpy as np, @@ -17,6 +17,7 @@ pandas as pd, pandas_available, ) +from pyomo.common.fileutils import this_file_dir import pyomo.common.unittest as unittest from pyomo.contrib.doe import DesignOfExperiments @@ -30,8 +31,8 @@ ipopt_available = SolverFactory("ipopt").available() -DATA_DIR = Path(__file__).parent -file_path = DATA_DIR / ".." / "examples" / "result.json" +currdir = this_file_dir() +file_path = os.path.join(currdir, "..", "examples", "result.json") with open(file_path) as f: data_ex = json.load(f) diff --git a/pyomo/contrib/doe/tests/test_doe_errors.py b/pyomo/contrib/doe/tests/test_doe_errors.py index 40cc2ba10e5..52f6ef8cdb8 100644 --- a/pyomo/contrib/doe/tests/test_doe_errors.py +++ b/pyomo/contrib/doe/tests/test_doe_errors.py @@ -9,7 +9,7 @@ # This software is distributed under the 3-clause BSD License. # ___________________________________________________________________________ import json -from pathlib import Path +import os.path from pyomo.common.dependencies import ( numpy as np, @@ -17,6 +17,7 @@ pandas as pd, pandas_available, ) +from pyomo.common.fileutils import this_file_dir import pyomo.common.unittest as unittest from pyomo.contrib.doe import DesignOfExperiments @@ -29,8 +30,8 @@ ipopt_available = SolverFactory("ipopt").available() -DATA_DIR = Path(__file__).parent -file_path = DATA_DIR / ".." / "examples" / "result.json" +currdir = this_file_dir() +file_path = os.path.join(currdir, "..", "examples", "result.json") with open(file_path) as f: data_ex = json.load(f) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index bf63862b345..0bc5d7254c9 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -10,7 +10,7 @@ # ___________________________________________________________________________ import json import logging -from pathlib import Path +import os.path from pyomo.common.dependencies import ( numpy as np, @@ -19,6 +19,7 @@ pandas_available, scipy_available, ) +from pyomo.common.fileutils import this_file_dir import pyomo.common.unittest as unittest from pyomo.contrib.doe import DesignOfExperiments @@ -38,8 +39,8 @@ ipopt_available = SolverFactory("ipopt").available() k_aug_available = SolverFactory('k_aug', solver_io='nl', validate=False) -DATA_DIR = Path(__file__).parent -file_path = DATA_DIR / ".." / "examples" / "result.json" +currdir = this_file_dir() +file_path = os.path.join(currdir, "..", "examples", "result.json") with open(file_path) as f: data_ex = json.load(f) From 919f234017c40b218f8059b42bc0deb461674d22 Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Tue, 13 Aug 2024 17:01:25 -0400 Subject: [PATCH 194/203] Moving deprecation error away from doe.py --- pyomo/contrib/doe/doe.py | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 005d9c0da52..32036799a56 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -146,16 +146,6 @@ def __init__( logger_level: Specify the level of the logger. Change to logging.DEBUG for all messages. """ - # Deprecation error - if 'create_model' in kwargs: - raise ValueError( - "DEPRECATION ERROR: Pyomo.DoE has been refactored. The current interface utilizes Experiment " - "objects that label unknown parameters, experiment inputs, experiment outputs and measurement " - "error. This avoids string-based naming which is fragile. For instruction to use the new " - "interface, please see the Pyomo.DoE under the contributed packages documentation at " - "`https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`" - ) - if experiment is None: raise ValueError("Experiment object must be provided to perform DoE.") From ca1f39e87ed41620feeb2bb523ce8bc90edf852f Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Wed, 14 Aug 2024 09:14:42 -0400 Subject: [PATCH 195/203] Add comments to tests that don't assert anything --- pyomo/contrib/doe/tests/test_doe_solve.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index 0bc5d7254c9..feb1447f5ca 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -230,6 +230,8 @@ def test_reactor_obj_cholesky_solve(self): # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) self.assertTrue(np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) + # This test ensure that compute FIM runs without error using the + # `sequential` option with central finite differences def test_compute_FIM_seq_centr(self): fd_method = "central" obj_used = "determinant" @@ -242,6 +244,8 @@ def test_compute_FIM_seq_centr(self): doe_obj.compute_FIM(method="sequential") + # This test ensure that compute FIM runs without error using the + # `sequential` option with forward finite differences def test_compute_FIM_seq_forward(self): fd_method = "forward" obj_used = "determinant" @@ -254,6 +258,9 @@ def test_compute_FIM_seq_forward(self): doe_obj.compute_FIM(method="sequential") + # This test ensure that compute FIM runs without error using the + # `kaug` option. kaug computes the FIM directly so no finite difference + # scheme is needed. @unittest.skipIf(not scipy_available, "Scipy is not available") @unittest.skipIf( not k_aug_available.available(False), "The 'k_aug' command is not available" @@ -270,6 +277,8 @@ def test_compute_FIM_kaug(self): doe_obj.compute_FIM(method="kaug") + # This test ensure that compute FIM runs without error using the + # `sequential` option with backward finite differences def test_compute_FIM_seq_backward(self): fd_method = "backward" obj_used = "determinant" From f4ff8b7086b6c6675a10afb6bb25d42d2efe1a30 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:30:40 -0400 Subject: [PATCH 196/203] Ran Black --- pyomo/contrib/doe/tests/test_doe_solve.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pyomo/contrib/doe/tests/test_doe_solve.py b/pyomo/contrib/doe/tests/test_doe_solve.py index feb1447f5ca..c25eb8018f7 100644 --- a/pyomo/contrib/doe/tests/test_doe_solve.py +++ b/pyomo/contrib/doe/tests/test_doe_solve.py @@ -230,7 +230,7 @@ def test_reactor_obj_cholesky_solve(self): # Make sure FIM and Q.T @ sigma_inv @ Q are close (alternate definition of FIM) self.assertTrue(np.all(np.isclose(FIM, Q.T @ sigma_inv @ Q))) - # This test ensure that compute FIM runs without error using the + # This test ensure that compute FIM runs without error using the # `sequential` option with central finite differences def test_compute_FIM_seq_centr(self): fd_method = "central" @@ -244,7 +244,7 @@ def test_compute_FIM_seq_centr(self): doe_obj.compute_FIM(method="sequential") - # This test ensure that compute FIM runs without error using the + # This test ensure that compute FIM runs without error using the # `sequential` option with forward finite differences def test_compute_FIM_seq_forward(self): fd_method = "forward" @@ -258,7 +258,7 @@ def test_compute_FIM_seq_forward(self): doe_obj.compute_FIM(method="sequential") - # This test ensure that compute FIM runs without error using the + # This test ensure that compute FIM runs without error using the # `kaug` option. kaug computes the FIM directly so no finite difference # scheme is needed. @unittest.skipIf(not scipy_available, "Scipy is not available") @@ -277,7 +277,7 @@ def test_compute_FIM_kaug(self): doe_obj.compute_FIM(method="kaug") - # This test ensure that compute FIM runs without error using the + # This test ensure that compute FIM runs without error using the # `sequential` option with backward finite differences def test_compute_FIM_seq_backward(self): fd_method = "backward" From fc00af0aa099ab76e669d36367122f2618b58a0a Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 14 Aug 2024 09:50:47 -0400 Subject: [PATCH 197/203] Added deprecation warning/error for old interface --- pyomo/contrib/doe/__init__.py | 36 +++++++++++++++++++++++++++++++++++ pyomo/contrib/doe/doe.py | 1 - 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index 04e237c18db..ffb6df1a860 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -10,3 +10,39 @@ # ___________________________________________________________________________ from .doe import DesignOfExperiments, ObjectiveLib, FiniteDifferenceStep from .utils import rescale_FIM + +# Deprecation errors for old Pyomo.DoE interface classes and structures +from pyomo.common.deprecation import deprecated + +deprecation_message = ( + "Pyomo.DoE has been refactored. The current interface utilizes Experiment " + "objects that label unknown parameters, experiment inputs, experiment outputs " + "and measurement error. This avoids string-based naming which is fragile. For " + "instructions to use the new interface, please see the Pyomo.DoE under the contributed " + "packages documentation at `https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`" +) + + +@deprecated( + "Use of MeasurementVariables in Pyomo.DoE is no longer supported.", + version='6.7.4.dev0', +) +class MeasurementVariables: + def __init__(self, *args): + raise RuntimeError(deprecation_message) + + +@deprecated( + "Use of DesignVariables in Pyomo.DoE is no longer supported.", version='6.7.4.dev0' +) +class DesignVariables: + def __init__(self, *args): + raise RuntimeError(deprecation_message) + + +@deprecated( + "Use of ModelOptionLib in Pyomo.DoE is no longer supported.", version='6.7.4.dev0' +) +class ModelOptionLib: + def __init__(self, *args): + raise RuntimeError(deprecation_message) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 32036799a56..99f53de6262 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -81,7 +81,6 @@ def __init__( logger_level=logging.WARNING, _Cholesky_option=True, _only_compute_fim_lower=True, - **kwargs ): """ This package enables model-based design of experiments analysis with Pyomo. From 24bd55e2c2b85d7c679b6fee235bed89e981a8f5 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:10:11 -0400 Subject: [PATCH 198/203] Remove URL for URL checker for now Will add back before pushing --- pyomo/contrib/doe/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index ffb6df1a860..5a02eafbaa9 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -19,7 +19,8 @@ "objects that label unknown parameters, experiment inputs, experiment outputs " "and measurement error. This avoids string-based naming which is fragile. For " "instructions to use the new interface, please see the Pyomo.DoE under the contributed " - "packages documentation at `https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`" + "packages documentation at " + # "`https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`" ) From ecc24bfde8b15b63fccf1dd405c2aa50b37cf2f2 Mon Sep 17 00:00:00 2001 From: Daniel Laky <29078718+djlaky@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:01:40 -0400 Subject: [PATCH 199/203] Reverting previous change. --- pyomo/contrib/doe/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyomo/contrib/doe/__init__.py b/pyomo/contrib/doe/__init__.py index 5a02eafbaa9..ffb6df1a860 100644 --- a/pyomo/contrib/doe/__init__.py +++ b/pyomo/contrib/doe/__init__.py @@ -19,8 +19,7 @@ "objects that label unknown parameters, experiment inputs, experiment outputs " "and measurement error. This avoids string-based naming which is fragile. For " "instructions to use the new interface, please see the Pyomo.DoE under the contributed " - "packages documentation at " - # "`https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`" + "packages documentation at `https://pyomo.readthedocs.io/en/latest/contributed_packages/doe/doe.html`" ) From 6505f5baa4765ccb0b2adf6283ddfb04986f104a Mon Sep 17 00:00:00 2001 From: Daniel Laky Date: Fri, 16 Aug 2024 17:04:45 -0400 Subject: [PATCH 200/203] Add solve to help with initialization of DoE model --- pyomo/contrib/doe/doe.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pyomo/contrib/doe/doe.py b/pyomo/contrib/doe/doe.py index 99f53de6262..627eae3d3eb 100644 --- a/pyomo/contrib/doe/doe.py +++ b/pyomo/contrib/doe/doe.py @@ -1079,6 +1079,7 @@ def build_block_scenarios(b, s): pyo.ComponentUID(param, context=m.base_model).find_component_on( b ).set_value(m.base_model.unknown_parameters[param] * (1 + diff)) + res = self.solver.solve(b, tee=self.tee) model.scenario_blocks = pyo.Block(model.scenarios, rule=build_block_scenarios) From 1ed95c231a37522274e0ded3c0ddaa6b1a1f5c5e Mon Sep 17 00:00:00 2001 From: John Siirola Date: Mon, 19 Aug 2024 10:47:14 -0600 Subject: [PATCH 201/203] NFC: documenting the AMPLRepn / DebugAMPLRepn classes --- pyomo/repn/ampl.py | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/pyomo/repn/ampl.py b/pyomo/repn/ampl.py index 876f579fb8d..b1d963b9771 100644 --- a/pyomo/repn/ampl.py +++ b/pyomo/repn/ampl.py @@ -198,6 +198,58 @@ def name(self): class AMPLRepn(object): + """The "compiled" representation of an expression in AMPL NL format. + + This stores a compiled form of an expression in the AMPL "NL" + format. The data structure contains 6 fields: + + Attributes + ---------- + mult : float + + A constant multiplier applied to this expression. The + :py:class`AMPLRepn` returned by the :py:class`AMPLRepnVisitor` + should always have `mult` == 1. + + const : float + + The constant portion of this expression + + linear : Dict[int, float] or None + + Mapping of `id(VarData)` to linear coefficient + + nonlinear : Tuple[str, List[int]] or List[Tuple[str, List[int]]] or None + + The general nonlinear portion of the compiled expression as a + tuple of two parts: + - the nl template string: this is the NL string with + placeholders (`%s`) for all the variables that appear in + the expression. + - an iterable if the `VarData` IDs that correspond to the + placeholders in the nl template string + This is `None` if there is no general nonlinear part of the + expression. Note that this can be a list of tuple fragments + within AMPLRepnVisitor, but that list is concatenated to a + single tuple when exiting the `AMPLRepnVisitor`. + + named_exprs : Set[int] + + A set of IDs point to named expressions (:py:class:`Expression`) + objects appearing in this expression. + + nl : Tuple[str, Iterable[int]] + + This holds the complete compiled representation of this + expression (including multiplier, constant, linear terms, and + nonlinear fragment) using the same format as the `nonlinear` + attribute. This field (if not None) should be considered + authoritative, as there are NL fragments that are not + representable by {mult, const, linear, nonlinear} (e.g., string + arguments). + + """ + __slots__ = ('nl', 'mult', 'const', 'linear', 'nonlinear', 'named_exprs') template = TextNLTemplate @@ -445,6 +497,15 @@ def to_expr(self, var_map): class DebugAMPLRepn(AMPLRepn): + """An `AMPLRepn` that uses the "debug" (annotated) NL format + + This is identical to the :py:class:`AMPLRepn` class, except it is + built using the `TextNLDebugTemplate` formatting template. This + format includes descriptions of the operators and variable / + expression names in the NL text. + + """ + __slots__ = () template = TextNLDebugTemplate From ef0074ee8c26e8459664fd9066177fa589487065 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Mon, 19 Aug 2024 11:44:19 -0600 Subject: [PATCH 202/203] Fix deprecation version Co-authored-by: Bethany Nicholson --- pyomo/repn/plugins/nl_writer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/repn/plugins/nl_writer.py b/pyomo/repn/plugins/nl_writer.py index 6f340cc887f..2ed2ae82c61 100644 --- a/pyomo/repn/plugins/nl_writer.py +++ b/pyomo/repn/plugins/nl_writer.py @@ -74,7 +74,7 @@ logger = logging.getLogger(__name__) -relocated_module_attribute('AMPLRepn', 'pyomo.repn.ampl.AMPLRepn', version='6.4.0.dev0') +relocated_module_attribute('AMPLRepn', 'pyomo.repn.ampl.AMPLRepn', version='6.7.4.dev0') inf = float('inf') minus_inf = -inf From 6661d828f3f2572250153d4da6cabb99b6344e84 Mon Sep 17 00:00:00 2001 From: John Siirola Date: Mon, 19 Aug 2024 11:51:25 -0600 Subject: [PATCH 203/203] NFC: fix typo Co-authored-by: Bethany Nicholson --- pyomo/repn/ampl.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyomo/repn/ampl.py b/pyomo/repn/ampl.py index b1d963b9771..9e043290b68 100644 --- a/pyomo/repn/ampl.py +++ b/pyomo/repn/ampl.py @@ -479,7 +479,7 @@ def append(self, other): def to_expr(self, var_map): if self.nl is not None or self.nonlinear is not None: - # TODO: support converting general nonlinear expressiosn + # TODO: support converting general nonlinear expressions # back to Pyomo expressions. This will require an AMPL # parser. raise MouseTrap("Cannot convert nonlinear AMPLRepn to Pyomo Expression")