예제 #1
0
    def test_has_consistent_initial_conditions(self):
        nmpc = self.make_nmpc()
        with pytest.raises(ValueError):
            # Model has not been properly initialized
            nmpc.has_consistent_initial_conditions(nmpc.plant)

        t0 = nmpc.plant_time.first()
        nmpc.plant.rate[t0, :].set_value(0.0)
        nmpc.plant.flow_out[t0].set_value(nmpc.plant.flow_in[t0].value)
        for j in nmpc.plant.components:
            calculate_variable_from_constraint(
                nmpc.plant.dcdt[t0, j],
                nmpc.plant.material_balance[t0, j],
            )
        assert nmpc.has_consistent_initial_conditions(nmpc.plant)

        nmpc.plant.flow_out[t0].set_value(0.0)
        assert not nmpc.has_consistent_initial_conditions(nmpc.plant)
예제 #2
0
    def test_solve_consistent_initial_conditions(self):
        # solve, assert has_consistent..., assert same dof
        nmpc = self.make_nmpc()
        dof_prior = degrees_of_freedom(nmpc.plant)

        # Just going to assume this model needs no additional
        # initialization before solving for initial conditions.
        nmpc.solve_consistent_initial_conditions(nmpc.plant)
        assert nmpc.has_consistent_initial_conditions(nmpc.plant)
        dof_post = degrees_of_freedom(nmpc.plant)
        assert dof_prior == dof_post

        nmpc.controller.flow_in.setlb(0.0)
        nmpc.controller.flow_out.setlb(0.0)
        nmpc.controller.flow_in.setub(10.0)
        nmpc.controller.flow_out.setub(10.0)
        nmpc.solve_consistent_initial_conditions(nmpc.controller,
                                                 strip_bounds=False)
        assert nmpc.has_consistent_initial_conditions(nmpc.controller)
예제 #3
0
def test_initialize_by_element_in_range(nmpc):

    plant = nmpc.plant
    controller = nmpc.controller
    time = plant.time
    sample_time = nmpc.sample_time

    nmpc.solve_consistent_initial_conditions(plant)
    assert nmpc.has_consistent_initial_conditions(plant, tolerance=1e-6)

    assert degrees_of_freedom(plant) == 0
    initialize_by_element_in_range(plant, time, 0, 3,
            dae_vars=plant._NMPC_NAMESPACE.dae_vars,
            time_linking_vars=plant._NMPC_NAMESPACE.diff_vars.varlist)
    assert degrees_of_freedom(plant) == 0

    for con in activated_equalities_generator(plant):
        if 'disc_eq' in con.local_name or 'balance' in con.local_name:
            # (know disc. and balance equations will be directly indexed
            # by time)
            index = con.index()
            if not type(index) is tuple:
                index = (index,)
            t_index = index[0]
            if t_index <= 3:
                # Equalities in simulated range should not be violated
                assert abs(value(con.body)-value(con.upper)) < 1e-6

    nmpc.simulate_plant(0)

    # Check that plant simulation matches controller simulation.
    # Only valid because there is no noise or plant-model-mismatch
    # and plant/controller have the same time discretizations
    p_varlist = (plant._NMPC_NAMESPACE.diff_vars.varlist +
                 plant._NMPC_NAMESPACE.alg_vars.varlist +
                 plant._NMPC_NAMESPACE.deriv_vars.varlist)
    c_varlist = (controller._NMPC_NAMESPACE.diff_vars.varlist +
                 controller._NMPC_NAMESPACE.alg_vars.varlist +
                 controller._NMPC_NAMESPACE.deriv_vars.varlist)
    for i, pvar in enumerate(p_varlist):
        for t in time:
            if t > sample_time or t == 0:
                continue
            cvar = c_varlist[i]
            assert pvar[t].value == approx(cvar[t].value, abs=1e-5)
예제 #4
0
def test_calculate_full_state_setpoint(nmpc):
    controller = nmpc.controller

    controller.mixer.E_inlet.flow_vol[0].fix(0.1)
    controller.mixer.S_inlet.flow_vol[0].fix(2.0)

    nmpc.solve_consistent_initial_conditions(controller)
    assert nmpc.has_consistent_initial_conditions(controller, tolerance=1e-6)

    # Deactivate tracking objective from previous tests
    #controller._NMPC_NAMESPACE.tracking_objective.deactivate()

    set_point = [(controller.cstr.outlet.conc_mol[0, 'P'], 0.4),
#                 (controller.cstr.outlet.conc_mol[0, 'S'], 0.0),
#                 (controller.cstr.control_volume.energy_holdup[0, 'aq'], 300),
                 (controller.mixer.E_inlet.flow_vol[0], 0.2),
                 (controller.mixer.S_inlet.flow_vol[0], 2.5)]

    weight_tolerance = 5e-7
    weight_override = [
            (controller.mixer.E_inlet.flow_vol[0.], 20.),
            (controller.mixer.S_inlet.flow_vol[0.], 2.),
            (controller.cstr.control_volume.energy_holdup[0., 'aq'], 0.1),
            (controller.cstr.outlet.conc_mol[0., 'P'], 1.),
            (controller.cstr.outlet.conc_mol[0., 'S'], 1.),
            ]
    # FIXME: This steady state setpoint solve is more sensitive than I 
    # would like.

    nmpc.calculate_full_state_setpoint(set_point,
            objective_weight_tolerance=weight_tolerance,
            objective_weight_override=weight_override)

    assert hasattr(controller._NMPC_NAMESPACE, 'user_setpoint')
    user_setpoint = controller._NMPC_NAMESPACE.user_setpoint
    assert hasattr(controller._NMPC_NAMESPACE, 'user_setpoint_weights')
    user_setpoint_weights = controller._NMPC_NAMESPACE.user_setpoint_weights
    assert hasattr(controller._NMPC_NAMESPACE, 'user_setpoint_vars')
    user_setpoint_vars = controller._NMPC_NAMESPACE.user_setpoint_vars

    for i, var in enumerate(user_setpoint_vars):
#        if var.local_name.startswith('conc'):
#            assert user_setpoint_weights[i] == 1.
#        elif var.local_name.startswith('energy'):
#            assert user_setpoint_weights[i] == 0.1
        if var.local_name.startswith('E_'):
            assert user_setpoint_weights[i] == 20.
        elif var.local_name.startswith('S_'):
            assert user_setpoint_weights[i] == 2.

    alg_vars = controller._NMPC_NAMESPACE.alg_vars
    diff_vars = controller._NMPC_NAMESPACE.diff_vars
    input_vars = controller._NMPC_NAMESPACE.input_vars
    categories = [
            VariableCategory.DIFFERENTIAL,
            VariableCategory.ALGEBRAIC,
            VariableCategory.DERIVATIVE,
            VariableCategory.INPUT,
            ]
    category_dict = controller._NMPC_NAMESPACE.category_dict
    for categ in categories:
        group = category_dict[categ]
        # Assert that setpoint has been populated with non-None values
        assert not any([sp is None for sp in group.setpoint])
        # Assert that setpoint (target) and reference (initial) values are
        # different in some way
        assert not all([sp == ref for sp, ref in
            zip(group.setpoint, group.reference)])
        # Assert that initial and reference values are the same
        assert all([ref == var[0].value for ref, var in
            zip(group.reference, group.varlist)])