def run_full_load(m, solver): """ Set the model up for off-design pressure driven flow. Run 480 MW case. Args: m: (ConcreteModel) model to run solver: (Solver) Returns: None """ m.fs.feed_fuel1.flow_mol.unfix() # For initialization, flow was specified and and valve opening calculated m.fs.valve01.control_volume.properties_in[0].flow_mol.unfix() m.fs.valve02.control_volume.properties_in[0].flow_mol.unfix() m.fs.valve03.control_volume.properties_in[0].flow_mol.unfix() # deltaP will be whatever is needed to satisfy the power requirment m.fs.vsv.deltaP.unfix() # The compressor efficiency is a little high since it doesn't include # throttling in the valve use to approximate VSV. m.fs.cmp1.efficiency_isentropic.fix(0.92) m.fs.cmp1.ratioP.fix(17.5) # lowering this ratio, just means less pressure # drop in the VSV valve, decresing throttle loss # Exhaust pressure will be a bit over ATM due to HRSG. This will come from # HRSG model when coupled to form NGCC model m.fs.gts3.control_volume.properties_out[0].pressure.fix(102594) # Don't know how much blade cooling air is needed for off desing case, but # full load flows were based on WVU model. For now just leave valves at # fixed opening. m.fs.valve01.valve_opening.fix() m.fs.valve02.valve_opening.fix() m.fs.valve03.valve_opening.fix() # Feeds # Air at compressor inlet m.fs.feed_air1.temperature.fix(288.15) m.fs.feed_air1.pressure.fix(103421) # Gas at fuel injection m.fs.feed_fuel1.temperature.fix(310.928) m.fs.feed_fuel1.pressure.fix(3.10264e6) # It looks like the O2 or air/fuel ratio is actually determined to roughly # get a constant exhaust temperature. In a real gas turbine there are # probably a lot of complex factors, but here we fix the exhaust temp. m.fs.cmbout_o2_mol_frac.unfix() m.fs.exhaust_1.temperature.fix(910) # Fix the gross power output m.fs.gt_power[0].fix(-480e6) # Watts negative because is power out # Solve iscale.constraint_autoscale_large_jac(m) return solver.solve(m, tee=True)
def test_scale_with_ignore_constraint_scale(self): """Make sure ignore_constraint_scaling ignores given scaling factors. """ m = pyo.ConcreteModel() m.a = pyo.Var([1, 2], initialize=1) m.c = pyo.Constraint(expr=(0, m.a[1] + m.a[2], 1)) m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT) m.scaling_factor[m.c] = 1e6 jac, jac_scaled, nlp = sc.constraint_autoscale_large_jac( m, ignore_constraint_scaling=True) assert m.scaling_factor[m.c] == pytest.approx(1)
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") if not hasattr(m, "fs"): m.fs = FlowsheetBlock(default={"dynamic": False}) air_species = {"CO2","Ar","H2O","O2","N2"} cmb_species = {"CH4","C2H6","C2H4","C3H8","C4H10","CO", "H2S","H2","O2","H2O","CO2","N2","Ar","SO2"} fuel_species = {"H2","CH4","C2H6","C2H4","C3H8","C4H10"} flue_species = {"CO2","Ar","H2O","O2","N2","SO2"} # Assuming the turbine runs lean, so there's still oxygen left after # combustion for comp,conc in air_comp.items(): if conc < 1E-12: air_species.remove(comp) cmb_species.remove(comp) flue_species.remove(comp) for comp,conc in ng_comp.items(): if conc < 1E-12: if comp in fuel_species: cmb_species.remove(comp) if comp == "H2S": cmb_species.remove("H2S") cmb_species.remove("SO2") flue_species.remove("SO2") for comp in fuel_species: if comp not in ng_comp.keys(): cmb_species.remove(comp) m.fs.air_prop_params = GenericParameterBlock( default=get_prop(air_species, phases)) m.fs.cmb_prop_params = GenericParameterBlock( default=get_prop(cmb_species, phases)) m.fs.flue_prop_params = GenericParameterBlock( default=get_prop(flue_species, phases)) prop_packages = {m.fs.air_prop_params,m.fs.cmb_prop_params, m.fs.flue_prop_params} 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, "C2H6":1000, "C3H8":1000, "C4H10":1000, "CO2":1000} for pp in prop_packages: pp.set_default_scaling("mole_frac_comp", 10) pp.set_default_scaling("mole_frac_phase_comp", 10) for c, s in _mf_scale.items(): if c in pp.component_list: pp.set_default_scaling( "mole_frac_comp", s, index=c) pp.set_default_scaling( "mole_frac_phase_comp", s, index=("Vap", c)) pp.set_default_scaling( "enth_mol_phase", 1e-3, index="Vap") m.fs.gas_combustion = GenericReactionParameterBlock( default=get_rxn(m.fs.cmb_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.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.air_prop_params}) m.fs.feed_fuel1 = um.Feed(default={"property_package": m.fs.cmb_prop_params}) m.fs.exhaust_1 = um.Product(default={"property_package": m.fs.flue_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.air_prop_params}) # Comprssor for air m.fs.cmp1 = um.Compressor(default={ "property_package": m.fs.air_prop_params, "support_isentropic_performance_curves":True}) # Blade cooling air splitter m.fs.splt1 = um.Separator(default={ "property_package": m.fs.air_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.air_prop_params}) m.fs.valve02 = um.Valve(default={ "valve_function_callback":um.ValveFunctionType.linear, "property_package": m.fs.air_prop_params}) m.fs.valve03 = um.Valve(default={ "valve_function_callback":um.ValveFunctionType.linear, "property_package": m.fs.air_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.inject_translator = um.Translator(default={"inlet_property_package": m.fs.air_prop_params, "outlet_property_package": m.fs.cmb_prop_params, "outlet_state_defined": False}) m.fs.inject1 = um.Mixer(default={ "property_package": m.fs.cmb_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.translator1 = um.Translator(default={"inlet_property_package": m.fs.air_prop_params, "outlet_property_package": m.fs.flue_prop_params, "outlet_state_defined": False}) m.fs.mx1 = um.Mixer(default={ "property_package": m.fs.flue_prop_params, "inlet_list":["gas", "air"], "momentum_mixing_type":um.MomentumMixingType.equality}) m.fs.translator2 = um.Translator(default={"inlet_property_package": m.fs.air_prop_params, "outlet_property_package": m.fs.flue_prop_params, "outlet_state_defined": False}) m.fs.mx2 = um.Mixer(default={ "property_package": m.fs.flue_prop_params, "inlet_list":["gas", "air"], "momentum_mixing_type":um.MomentumMixingType.equality}) m.fs.translator3 = um.Translator(default={"inlet_property_package": m.fs.air_prop_params, "outlet_property_package": m.fs.flue_prop_params, "outlet_state_defined": False}) m.fs.mx3 = um.Mixer(default={ "property_package": m.fs.flue_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.cmb_prop_params, "reaction_package": m.fs.gas_combustion, "has_pressure_change": True}) m.fs.flue_translator = um.Translator(default={"inlet_property_package": m.fs.cmb_prop_params, "outlet_property_package": m.fs.flue_prop_params, "outlet_state_defined": False}) # 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.flue_prop_params, "support_isentropic_performance_curves":True}) m.fs.gts2 = um.Turbine(default={ "property_package": m.fs.flue_prop_params, "support_isentropic_performance_curves":True}) m.fs.gts3 = um.Turbine(default={ "property_package": m.fs.flue_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.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.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.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.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.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.time) @m.fs.Constraint(m.fs.time) def gt_power_eqn(b, t): return b.gt_power[t] == b.gt_power_expr[t] # Rules for translator blocks def rule_flow_mol_comp(blk,t,j): return blk.properties_in[t].flow_mol_comp[j] == blk.properties_out[t].flow_mol_comp[j] def rule_temperature(blk,t): return blk.properties_in[t].temperature == blk.properties_out[t].temperature def rule_pressure(blk,t): return blk.properties_in[t].pressure == blk.properties_out[t].pressure def rule_zero_flow(blk,t,j): return blk.properties_out[t].flow_mol_comp[j] == 0 for blk in {m.fs.inject_translator, m.fs.translator1, m.fs.translator2, m.fs.translator3, m.fs.flue_translator}: blk.temperature_eqn = pyo.Constraint(m.fs.time, rule=rule_temperature) blk.pressure_eqn = pyo.Constraint(m.fs.time, rule=rule_pressure) m.fs.inject_translator.flow_mole_comp_eqn = pyo.Constraint(m.fs.time, air_species, rule = rule_flow_mol_comp) m.fs.inject_translator.zero_flow_eqn = pyo.Constraint(m.fs.time, cmb_species-air_species, rule = rule_zero_flow) for blk in {m.fs.translator1, m.fs.translator2, m.fs.translator3}: blk.flow_mole_comp_eqn = pyo.Constraint(m.fs.time, air_species, rule = rule_flow_mol_comp) blk.zero_flow_eqn = pyo.Constraint(m.fs.time, flue_species-air_species, rule = rule_zero_flow) m.fs.flue_translator.flow_mole_comp_eqn = pyo.Constraint(m.fs.time, flue_species, rule = rule_flow_mol_comp) # # 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.air04a = Arc(source=m.fs.splt1.air04, destination=m.fs.inject_translator.inlet) m.fs.air04b = Arc(source=m.fs.inject_translator.outlet, destination=m.fs.inject1.air) m.fs.air05 = Arc(source=m.fs.splt1.air05, destination=m.fs.valve01.inlet) m.fs.air06a = Arc(source=m.fs.valve01.outlet, destination=m.fs.translator1.inlet) m.fs.air06b = Arc(source=m.fs.translator1.outlet, destination=m.fs.mx1.air) m.fs.air07 = Arc(source=m.fs.splt1.air07, destination=m.fs.valve02.inlet) m.fs.air08a = Arc(source=m.fs.valve02.outlet, destination=m.fs.translator2.inlet) m.fs.air08b = Arc(source=m.fs.translator2.outlet, destination=m.fs.mx2.air) m.fs.air09 = Arc(source=m.fs.splt1.air09, destination=m.fs.valve03.inlet) m.fs.air10a = Arc(source=m.fs.valve03.outlet, destination=m.fs.translator3.inlet) m.fs.air10b = Arc(source=m.fs.translator3.outlet, destination=m.fs.mx3.air) m.fs.g01 = Arc(source=m.fs.inject1.outlet, destination=m.fs.cmb1.inlet) m.fs.g02a = Arc(source=m.fs.cmb1.outlet, destination=m.fs.flue_translator.inlet) m.fs.g02b = Arc(source=m.fs.flue_translator.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 propagate_state(m.fs.air01) m.fs.vsv.initialize() propagate_state(m.fs.air02) m.fs.cmp1.initialize() # splitter propagate_state(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 propagate_state(m.fs.air04a) m.fs.inject_translator.initialize() propagate_state(m.fs.air04b) propagate_state(m.fs.fuel01) m.fs.inject1.mixed_state[0].pressure = pyo.value(m.fs.inject1.air.pressure[0]) m.fs.inject1.initialize() # combustor propagate_state(m.fs.g01) m.fs.cmb1.initialize() # gas turbine stage 1 propagate_state(m.fs.g02a) m.fs.flue_translator.initialize() propagate_state(m.fs.g02b) m.fs.gts1.ratioP[0] = 0.7 m.fs.gts1.initialize() # blade cooling air valve01, and calculate a flow coefficent propagate_state(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 propagate_state(m.fs.air06a) m.fs.translator1.initialize() propagate_state(m.fs.air06b) propagate_state(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 propagate_state(m.fs.g04) m.fs.gts2.ratioP[0] = 0.7 m.fs.gts2.initialize() # blade cooling air valve02, and calculate a flow coefficent propagate_state(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 propagate_state(m.fs.air08a) m.fs.translator2.initialize() propagate_state(m.fs.air08b) propagate_state(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 propagate_state(m.fs.g06) m.fs.gts3.ratioP[0] = 0.7 m.fs.gts3.initialize() # blade cooling air valve03, and calculate a flow coefficent propagate_state(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 propagate_state(m.fs.air10a) m.fs.translator3.initialize() propagate_state(m.fs.air10b) propagate_state(m.fs.g07) m.fs.mx3.mixed_state[0].pressure = pyo.value(m.fs.mx3.gas.pressure[0]) m.fs.mx3.initialize() # product blocks propagate_state(m.fs.g08) m.fs.exhaust_1.initialize() # Solve iscale.constraint_autoscale_large_jac(m) solver.solve(m, tee=True) return m, solver