Exemple #1
0
def build_model():
    m = ConcreteModel()

    # Properties
    comp_props = get_prop(components=["CO2", "H2O"], phases=["Vap", "Liq"])

    # Parameters block
    m.params = GenericParameterBlock(default=comp_props)

    m.props = m.params.build_state_block(
        default={
            "defined_state": True,
            "parameters": m.params,
            "has_phase_equilibrium": True
        })

    m.props.flow_mol.fix(100)
    m.props.pressure.fix(101325)
    m.props.mole_frac_comp["CO2"].fix(0.94)
    m.props.mole_frac_comp["H2O"].fix(0.06)

    m.props.temperature_constraint = Constraint(
        expr=m.props.temperature == m.props.temperature_dew["Vap", "Liq"])

    assert degrees_of_freedom(m) == 0

    m.props.initialize(state_vars_fixed=True)
    results = get_solver(options={"bound_push": 1e-8}).solve(m)

    assert check_optimal_termination(results)

    return m
Exemple #2
0
    def m(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={'dynamic': False})

        m.fs.props = GenericParameterBlock(default=get_prop(components=[
            'H2', 'CO', "H2O", 'CO2', 'CH4', "C2H6", "C3H8", "C4H10", 'N2',
            'O2', 'Ar'
        ]))
        m.fs.state = m.fs.props.build_state_block(
            [1], default={"defined_state": True})

        return m
Exemple #3
0
def test_construction_component_not_in_phase():
    m = ConcreteModel()
    m.fs = FlowsheetBlock()
    m.fs.prop_params = GenericParameterBlock(
        default=get_prop(["H2O", "H2"], ["Liq", "Vap"]))
    m.fs.inject1 = Mixer(
        default={
            "property_package": m.fs.prop_params,
            "inlet_list": ["in1", "in2"],
            "momentum_mixing_type": MomentumMixingType.none
        })
    iscale.calculate_scaling_factors(m)
Exemple #4
0
    def test_gibbs(self, m):
        m.fs.props = GenericParameterBlock(
            default=get_prop(components=['H2', 'CO', 'H2O', 'CO2',
                                         'O2', 'N2', 'Ar', 'CH4']))
        m.fs.reactor = GibbsReactor(default={
            "dynamic": False,
            "has_heat_transfer": True,
            "has_pressure_change": False,
            "property_package": m.fs.props})

        m.fs.reactor.inlet.flow_mol.fix(8000)  # mol/s
        m.fs.reactor.inlet.temperature.fix(600)  # K
        m.fs.reactor.inlet.pressure.fix(1e6)  # Pa

        m.fs.reactor.outlet.temperature.fix(600)  # K

        m.fs.reactor.inlet.mole_frac_comp[0, "H2"].fix(0)
        m.fs.reactor.inlet.mole_frac_comp[0, "CO"].fix(0)
        m.fs.reactor.inlet.mole_frac_comp[0, "H2O"].fix(0.3)
        m.fs.reactor.inlet.mole_frac_comp[0, "CO2"].fix(0)
        m.fs.reactor.inlet.mole_frac_comp[0, "O2"].fix(0.2)
        m.fs.reactor.inlet.mole_frac_comp[0, "N2"].fix(0.05)
        m.fs.reactor.inlet.mole_frac_comp[0, "Ar"].fix(0.05)
        m.fs.reactor.inlet.mole_frac_comp[0, "CH4"].fix(0.4)
        
        constraint_scaling_transform(m.fs.reactor.control_volume.enthalpy_balances[0.0],1E-6)
        m.fs.reactor.gibbs_scaling = 1E-6
        
        results = solver.solve(m, tee=True)

        assert results.solver.termination_condition == \
            TerminationCondition.optimal
        assert results.solver.status == SolverStatus.ok

        assert 0.017 == pytest.approx(value(
            m.fs.reactor.outlet.mole_frac_comp[0, 'H2']), 1e-1)
        assert 0.0001 == pytest.approx(value(
            m.fs.reactor.outlet.mole_frac_comp[0, 'CO']), 1)
        assert 0.487 == pytest.approx(value(
            m.fs.reactor.outlet.mole_frac_comp[0, 'H2O']), 1e-1)
        assert 0.103 == pytest.approx(value(
            m.fs.reactor.outlet.mole_frac_comp[0, 'CO2']), 1e-1)
        assert 0.293 == pytest.approx(value(
            m.fs.reactor.outlet.mole_frac_comp[0, 'CH4']), 1e-1)

        assert -634e6 == pytest.approx(value(
            m.fs.reactor.heat_duty[0]), 1e-3)
def main(
    comps,
    rxns,
    phases,
    air_comp,
    ng_comp,
    m=None,
    initialize=True,
    flow_scale=0.896):
    """Generate and initialize the gas turbine flowsheet. This method returns
    a model and solver. The flow_scale argument can be used to scale the turnine
    up or down with the same relative performace.

    Args:
        comps: (set of str) a set of componets
        rxns: (dict) reactions with reaction name key and key component for
            conversion calculations
        phases: (list) phases potentially present
        air_comp: (dict) mole-fraction air composition
        ng_comp: (dict) mole-fraction natural gas composition
        m: (ConcreteModel) model to add flowsheet too.  If None create a new one.
        initialize: (bool) If true initialize the flowsheet
        flow_scale: (float) flow scale multiplier to scale the performace curves
            up or down. Original nominal volumetric flow/new nominal volumetric
            flow (default=0.896).

    Returns:
        (ConcreteModel) model, (Solver) solver
    """
    expand_arcs = pyo.TransformationFactory("network.expand_arcs")
    #
    # Model, flowsheet and properties
    #
    if m is None:
        m = pyo.ConcreteModel("Gas Turbine Model")
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.gas_prop_params = GenericParameterBlock(default=get_prop(comps, phases))
    m.fs.gas_prop_params.set_default_scaling("mole_frac_comp", 10)
    m.fs.gas_prop_params.set_default_scaling("mole_frac_phase_comp", 10)
    _mf_scale = {
        "Ar":100,
        "O2":100,
        "H2S":1000,
        "SO2":1000,
        "H2":1000,
        "CO":1000,
        "C2H4":1000,
        "CO2":1000}
    for c, s in _mf_scale.items():
        m.fs.gas_prop_params.set_default_scaling(
            "mole_frac_comp", s, index=c)
        m.fs.gas_prop_params.set_default_scaling(
            "mole_frac_phase_comp", s, index=("Vap", c))
    m.fs.gas_prop_params.set_default_scaling(
        "enth_mol_phase", 1e-3, index="Vap")

    m.fs.gas_combustion = GenericReactionParameterBlock(
        default=get_rxn(m.fs.gas_prop_params, rxns))
    # Variable for mole-fraction of O2 in the flue gas.  To initialize the model
    # will use a fixed value here.
    m.fs.cmbout_o2_mol_frac = pyo.Var(m.fs.config.time, initialize=0.1157)
    m.fs.cmbout_o2_mol_frac.fix()
    #
    # Unit models
    #
    # inlet/outlet blocks
    m.fs.feed_air1 = um.Feed(default={"property_package": m.fs.gas_prop_params})
    m.fs.feed_fuel1 = um.Feed(default={"property_package": m.fs.gas_prop_params})
    m.fs.exhaust_1 = um.Product(default={"property_package": m.fs.gas_prop_params})
    # Valve roughly approximating variable stator vanes to control air flow.
    m.fs.vsv = um.Valve(default={
        "valve_function_callback":um.ValveFunctionType.linear,
        "property_package": m.fs.gas_prop_params})
    # Comprssor for air
    m.fs.cmp1 = um.Compressor(default={
        "property_package": m.fs.gas_prop_params,
        "support_isentropic_performance_curves":True})
    # Blade cooling air splitter
    m.fs.splt1 = um.Separator(default={
        "property_package": m.fs.gas_prop_params,
        "outlet_list":["air04", "air05", "air07", "air09"]})
    # Three valves for blade cooling air.
    m.fs.valve01 = um.Valve(default={
        "valve_function_callback":um.ValveFunctionType.linear,
        "property_package": m.fs.gas_prop_params})
    m.fs.valve02 = um.Valve(default={
        "valve_function_callback":um.ValveFunctionType.linear,
        "property_package": m.fs.gas_prop_params})
    m.fs.valve03 = um.Valve(default={
        "valve_function_callback":um.ValveFunctionType.linear,
        "property_package": m.fs.gas_prop_params})
    # Mixer for fuel injection. Since this is a steady state model the pressure
    # drop on the fuel control valve is lumped into this mixer
    m.fs.inject1 = um.Mixer(default={
        "property_package": m.fs.gas_prop_params,
        "inlet_list":["gas", "air"],
        "momentum_mixing_type":um.MomentumMixingType.none})
    # Three blade cooling air mixers. The blade cooling isn't explicitly modeled
    # so these mainly just maintain the proper mass and enegy balance.
    m.fs.mx1 = um.Mixer(default={
        "property_package": m.fs.gas_prop_params,
        "inlet_list":["gas", "air"],
        "momentum_mixing_type":um.MomentumMixingType.equality})
    m.fs.mx2 = um.Mixer(default={
        "property_package": m.fs.gas_prop_params,
        "inlet_list":["gas", "air"],
        "momentum_mixing_type":um.MomentumMixingType.equality})
    m.fs.mx3 = um.Mixer(default={
        "property_package": m.fs.gas_prop_params,
        "inlet_list":["gas", "air"],
        "momentum_mixing_type":um.MomentumMixingType.equality})
    # Combustor, for now assuming complete reactions and no NOx
    m.fs.cmb1 = um.StoichiometricReactor(default={
        "property_package": m.fs.gas_prop_params,
        "reaction_package": m.fs.gas_combustion,
        "has_pressure_change": True})
    # Three gas turbine stages, with performance curves for all three added by
    # the performance_curves() fuctions.
    m.fs.gts1 = um.Turbine(default={
        "property_package": m.fs.gas_prop_params,
        "support_isentropic_performance_curves":True})
    m.fs.gts2 = um.Turbine(default={
        "property_package": m.fs.gas_prop_params,
        "support_isentropic_performance_curves":True})
    m.fs.gts3 = um.Turbine(default={
        "property_package": m.fs.gas_prop_params,
        "support_isentropic_performance_curves":True})
    performance_curves(m)
    #
    # Additional constraints/expressions
    #
    # to make this simpler, just deal with VSV valve-approximation pressure drop
    # and forget the opening
    m.fs.vsv.pressure_flow_equation.deactivate()
    # O2 fraction in combustor constraint (to set var)
    @m.fs.Constraint(m.fs.config.time)
    def o2_flow(b, t):
        return m.fs.cmb1.control_volume.properties_out[t].mole_frac_comp["O2"] \
            == m.fs.cmbout_o2_mol_frac[t]
    # Fuel injector pressure is the air pressure. This lumps in the gas valve
    @m.fs.inject1.Constraint(m.fs.config.time)
    def mxpress_eqn(b, t):
        return b.mixed_state[t].pressure == b.air_state[t].pressure
    # The pressure drop in the cumbustor is just a fixed 5%.
    @m.fs.cmb1.Constraint(m.fs.config.time)
    def pressure_drop_eqn(b, t):
        return (0.95 ==
            b.control_volume.properties_out[t].pressure /
            b.control_volume.properties_in[t].pressure)
    # Constraints for complete combustion, use key compoents and 100% conversion
    @m.fs.cmb1.Constraint(m.fs.config.time, rxns.keys())
    def reaction_extent(b, t, r):
        k = rxns[r]
        prp = b.control_volume.properties_in[t]
        stc = -m.fs.gas_combustion.rate_reaction_stoichiometry[r, "Vap", k]
        extent = b.rate_reaction_extent[t, r]
        return extent == prp.flow_mol*prp.mole_frac_comp[k]/stc
    # Calculate the total gas turnine gross power output.
    @m.fs.Expression(m.fs.config.time)
    def gt_power_expr(b, t):
        return (
            m.fs.cmp1.control_volume.work[t] +
            m.fs.gts1.control_volume.work[t] +
            m.fs.gts2.control_volume.work[t] +
            m.fs.gts3.control_volume.work[t])
    # Add a varable and constraint for gross power.  This allows fixing power
    # for simulations where a specific power output is desired.
    m.fs.gt_power = pyo.Var(m.fs.config.time)
    @m.fs.Constraint(m.fs.config.time)
    def gt_power_eqn(b, t):
        return b.gt_power[t] == b.gt_power_expr[t]
    #
    # Arcs
    #
    # Arc names are imoprtant here becuase they match the PFD and are used for
    # tagging stream quantities
    m.fs.fuel01 = Arc(source=m.fs.feed_fuel1.outlet, destination=m.fs.inject1.gas)
    m.fs.air01 = Arc(source=m.fs.feed_air1.outlet, destination=m.fs.vsv.inlet)
    m.fs.air02 = Arc(source=m.fs.vsv.outlet, destination=m.fs.cmp1.inlet)
    m.fs.air03 = Arc(source=m.fs.cmp1.outlet, destination=m.fs.splt1.inlet)
    m.fs.air04 = Arc(source=m.fs.splt1.air04, destination=m.fs.inject1.air)
    m.fs.air05 = Arc(source=m.fs.splt1.air05, destination=m.fs.valve01.inlet)
    m.fs.air06 = Arc(source=m.fs.valve01.outlet, destination=m.fs.mx1.air)
    m.fs.air07 = Arc(source=m.fs.splt1.air07, destination=m.fs.valve02.inlet)
    m.fs.air08 = Arc(source=m.fs.valve02.outlet, destination=m.fs.mx2.air)
    m.fs.air09 = Arc(source=m.fs.splt1.air09, destination=m.fs.valve03.inlet)
    m.fs.air10 = Arc(source=m.fs.valve03.outlet, destination=m.fs.mx3.air)
    m.fs.g01 = Arc(source=m.fs.inject1.outlet, destination=m.fs.cmb1.inlet)
    m.fs.g02 = Arc(source=m.fs.cmb1.outlet, destination=m.fs.gts1.inlet)
    m.fs.g03 = Arc(source=m.fs.gts1.outlet, destination=m.fs.mx1.gas)
    m.fs.g04 = Arc(source=m.fs.mx1.outlet, destination=m.fs.gts2.inlet)
    m.fs.g05 = Arc(source=m.fs.gts2.outlet, destination=m.fs.mx2.gas)
    m.fs.g06 = Arc(source=m.fs.mx2.outlet, destination=m.fs.gts3.inlet)
    m.fs.g07 = Arc(source=m.fs.gts3.outlet, destination=m.fs.mx3.gas)
    m.fs.g08 = Arc(source=m.fs.mx3.outlet, destination=m.fs.exhaust_1.inlet)
    # Create arc constraints
    expand_arcs.apply_to(m)
    #
    # Tag model
    #
    tags, tag_format = tag_model(m)
    #
    # Set some scaling
    #
    for i in ["air05", "air07", "air09"]:
        iscale.set_scaling_factor(m.fs.splt1.split_fraction[0.0, i], 100)
    iscale.set_scaling_factor(m.fs.valve01.control_volume.work, 1e-8)
    iscale.set_scaling_factor(m.fs.valve02.control_volume.work, 1e-8)
    iscale.set_scaling_factor(m.fs.valve03.control_volume.work, 1e-8)
    iscale.set_scaling_factor(m.fs.vsv.control_volume.work, 1e-8)
    iscale.set_scaling_factor(m.fs.cmp1.control_volume.work, 1e-8)
    iscale.set_scaling_factor(m.fs.gts1.control_volume.work, 1e-8)
    iscale.set_scaling_factor(m.fs.gts2.control_volume.work, 1e-8)
    iscale.set_scaling_factor(m.fs.gts3.control_volume.work, 1e-8)
    iscale.set_scaling_factor(
        m.fs.gts1.control_volume.properties_in[0].flow_mol, 1e-5)
    iscale.set_scaling_factor(
        m.fs.gts2.control_volume.properties_in[0].flow_mol, 1e-5)
    iscale.set_scaling_factor(
        m.fs.gts3.control_volume.properties_in[0].flow_mol, 1e-5)
    iscale.set_scaling_factor(
        m.fs.gts1.control_volume.properties_out[0].flow_mol, 1e-5)
    iscale.set_scaling_factor(
        m.fs.gts2.control_volume.properties_out[0].flow_mol, 1e-5)
    iscale.set_scaling_factor(
        m.fs.gts3.control_volume.properties_out[0].flow_mol, 1e-5)
    for i, v in m.fs.cmb1.control_volume.rate_reaction_extent.items():
        if i[1] == "ch4_cmb":
            iscale.set_scaling_factor(v, 1e-2)
        else:
            iscale.set_scaling_factor(v, 1)
    for i, c in m.fs.cmb1.reaction_extent.items():
            iscale.constraint_scaling_transform(c, 1e-2)
    for i, v in m.fs.cmb1.control_volume.rate_reaction_generation.items():
        if i[2] in ["O2", "CO2", "CH4", "H2O"]:
            iscale.set_scaling_factor(v, 0.001)
        else:
            iscale.set_scaling_factor(v, 0.1)
    for v in m.fs.cmp1.deltaP.values():
        iscale.set_scaling_factor(v, 1e-6)
    for v in m.fs.gts1.deltaP.values():
        iscale.set_scaling_factor(v, 1e-6)
    for v in m.fs.gts2.deltaP.values():
        iscale.set_scaling_factor(v, 1e-6)
    for v in m.fs.gts3.deltaP.values():
        iscale.set_scaling_factor(v, 1e-6)
    for v in m.fs.valve01.deltaP.values():
        iscale.set_scaling_factor(v, 1e-6)
    for v in m.fs.valve02.deltaP.values():
        iscale.set_scaling_factor(v, 1e-6)
    for v in m.fs.valve03.deltaP.values():
        iscale.set_scaling_factor(v, 1e-6)
    for c in m.fs.o2_flow.values():
        iscale.constraint_scaling_transform(c, 10)
    for c in m.fs.gt_power_eqn.values():
        iscale.constraint_scaling_transform(c, 1e-8)
    for c in m.fs.mx1.enthalpy_mixing_equations.values():
        iscale.constraint_scaling_transform(c, 1e-8)
    for c in m.fs.mx2.enthalpy_mixing_equations.values():
        iscale.constraint_scaling_transform(c, 1e-8)
    for c in m.fs.mx3.enthalpy_mixing_equations.values():
        iscale.constraint_scaling_transform(c, 1e-8)
    for c in m.fs.inject1.enthalpy_mixing_equations.values():
        iscale.constraint_scaling_transform(c, 1e-8)
    for c in m.fs.gts1.performance_curve.head_isen_eqn.values():
        iscale.constraint_scaling_transform(c, 1e-5)
    for c in m.fs.gts1.performance_curve.eff_isen_eqn.values():
        iscale.constraint_scaling_transform(c, 2)
    for c in m.fs.gts2.performance_curve.head_isen_eqn.values():
        iscale.constraint_scaling_transform(c, 1e-5)
    for c in m.fs.gts2.performance_curve.eff_isen_eqn.values():
        iscale.constraint_scaling_transform(c, 2)
    for c in m.fs.gts3.performance_curve.head_isen_eqn.values():
        iscale.constraint_scaling_transform(c, 1e-5)
    for c in m.fs.gts3.performance_curve.eff_isen_eqn.values():
        iscale.constraint_scaling_transform(c, 2)
    for c in m.fs.inject1.mxpress_eqn.values():
        iscale.constraint_scaling_transform(c, 1e-5)
    #
    # Calculate scaling factors/scaling transform of constraints
    #
    iscale.calculate_scaling_factors(m)
    #
    # Set basic model inputs for initialization
    #
    # compressor
    m.fs.vsv.deltaP.fix(-100)
    m.fs.cmp1.efficiency_isentropic.fix(0.9)
    m.fs.cmp1.ratioP.fix(19.075)
    # blabe cooling air valves use expected flow to calculate valve flow
    # coefficients, so here set expected flow and after init the opening will
    # be the fixed var.
    m.fs.valve01.control_volume.properties_in[0].flow_mol.fix(2315)
    m.fs.valve02.control_volume.properties_in[0].flow_mol.fix(509)
    m.fs.valve03.control_volume.properties_in[0].flow_mol.fix(354)
    m.fs.valve01.valve_opening.unfix()
    m.fs.valve02.valve_opening.unfix()
    m.fs.valve03.valve_opening.unfix()
    # Feed streams
    # Air at compressor inlet
    m.fs.feed_air1.flow_mol[:] = 34875.9
    m.fs.feed_air1.temperature.fix(288.15)
    m.fs.feed_air1.pressure.fix(101047)
    for i, v in air_comp.items():
        m.fs.feed_air1.mole_frac_comp[:,i].fix(v)
    # Gas at fuel injection
    m.fs.feed_fuel1.flow_mol.fix(1348.8)
    m.fs.feed_fuel1.temperature.fix(310.928)
    m.fs.feed_fuel1.pressure.fix(3.10264e6)
    for i, v in ng_comp.items():
        m.fs.feed_fuel1.mole_frac_comp[:,i].fix(v)
    #
    # Initialization
    #
    solver = pyo.SolverFactory('ipopt')
    if initialize:
        # feeds
        m.fs.feed_air1.initialize()
        m.fs.feed_fuel1.initialize()
        # compressor
        iutil.copy_port_values(m.fs.air01)
        m.fs.vsv.initialize()
        iutil.copy_port_values(m.fs.air02)
        m.fs.cmp1.initialize()
        # splitter
        iutil.copy_port_values(m.fs.air03)
        m.fs.splt1.split_fraction[0, "air05"].fix(0.0916985*0.73)
        m.fs.splt1.split_fraction[0, "air07"].fix(0.0916985*0.27*0.59)
        m.fs.splt1.split_fraction[0, "air09"].fix(0.0916985*0.27*0.41)
        m.fs.splt1.initialize()
        m.fs.splt1.split_fraction[0, "air05"].unfix()
        m.fs.splt1.split_fraction[0, "air07"].unfix()
        m.fs.splt1.split_fraction[0, "air09"].unfix()
        # inject
        iutil.copy_port_values(m.fs.air04)
        iutil.copy_port_values(m.fs.fuel01)
        m.fs.inject1.mixed_state[0].pressure = pyo.value(m.fs.inject1.air.pressure[0])
        m.fs.inject1.initialize()
        # combustor
        iutil.copy_port_values(m.fs.g01)
        m.fs.cmb1.initialize()
        # gas turbine stage 1
        iutil.copy_port_values(m.fs.g02)
        m.fs.gts1.ratioP[0] = 0.7
        m.fs.gts1.initialize()
        # blade cooling air valve01, and calculate a flow coefficent
        iutil.copy_port_values(m.fs.air05)
        m.fs.valve01.Cv = 2
        m.fs.valve01.Cv.unfix()
        m.fs.valve01.valve_opening.fix(0.85)
        m.fs.valve01.control_volume.properties_out[0].pressure.fix(
            pyo.value(m.fs.gts1.control_volume.properties_out[0].pressure))
        m.fs.valve01.initialize()
        m.fs.valve01.control_volume.properties_out[0].pressure.unfix()
        m.fs.valve01.Cv.fix()
        m.fs.valve01.valve_opening.unfix()
        # mixer 1
        iutil.copy_port_values(m.fs.air06)
        iutil.copy_port_values(m.fs.g03)
        m.fs.mx1.mixed_state[0].pressure = pyo.value(m.fs.mx1.gas.pressure[0])
        m.fs.mx1.initialize()
        # gas turbine stage 2
        iutil.copy_port_values(m.fs.g04)
        m.fs.gts2.ratioP[0] = 0.7
        m.fs.gts2.initialize()
        # blade cooling air valve02, and calculate a flow coefficent
        iutil.copy_port_values(m.fs.air07)
        m.fs.valve02.Cv = 2
        m.fs.valve02.Cv.unfix()
        m.fs.valve02.valve_opening.fix(0.85)
        m.fs.valve02.control_volume.properties_out[0].pressure.fix(
            pyo.value(m.fs.gts2.control_volume.properties_out[0].pressure))
        m.fs.valve02.initialize()
        m.fs.valve02.control_volume.properties_out[0].pressure.unfix()
        m.fs.valve02.Cv.fix()
        m.fs.valve02.valve_opening.unfix()
        # mixer 2
        iutil.copy_port_values(m.fs.air08)
        iutil.copy_port_values(m.fs.g05)
        m.fs.mx2.mixed_state[0].pressure = pyo.value(m.fs.mx2.gas.pressure[0])
        m.fs.mx2.initialize()
        # gas turbine stage 3
        iutil.copy_port_values(m.fs.g06)
        m.fs.gts3.ratioP[0] = 0.7
        m.fs.gts3.initialize()
        # blade cooling air valve03, and calculate a flow coefficent
        iutil.copy_port_values(m.fs.air09)
        m.fs.valve03.Cv = 2
        m.fs.valve03.Cv.unfix()
        m.fs.valve03.valve_opening.fix(0.85)
        m.fs.valve03.control_volume.properties_out[0].pressure.fix(
            pyo.value(m.fs.gts3.control_volume.properties_out[0].pressure))
        m.fs.valve03.initialize()
        m.fs.valve03.control_volume.properties_out[0].pressure.unfix()
        m.fs.valve03.Cv.fix()
        m.fs.valve03.valve_opening.unfix()
        # mixer 3
        iutil.copy_port_values(m.fs.air10)
        iutil.copy_port_values(m.fs.g07)
        m.fs.mx3.mixed_state[0].pressure = pyo.value(m.fs.mx3.gas.pressure[0])
        m.fs.mx3.initialize()    # product blocks
        # product blocks
        iutil.copy_port_values(m.fs.g08)
        m.fs.exhaust_1.initialize()
        # Solve
        solver.solve(m, tee=True)
    return m, solver