Exemple #1
0
def test_Separator_3():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.params = PropertyInterrogatorBlock()

    m.fs.S01 = Separator(
        default={
            "property_package": m.fs.params,
            "material_balance_type": MaterialBalanceType.componentPhase,
            "split_basis": SplittingType.componentFlow,
            "outlet_list": ["a", "B", "c"],
            "ideal_separation": False,
            "has_phase_equilibrium": False
        })

    assert len(m.fs.params.required_properties) == 3
    for k in m.fs.params.required_properties.keys():
        assert k in ["material flow terms", "pressure", "temperature"]
Exemple #2
0
def test_ideal_Separator_3():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.params = PropertyInterrogatorBlock()

    m.fs.S01 = Separator(
        default={
            "property_package": m.fs.params,
            "num_outlets": 2,
            "ideal_separation": True,
            "split_basis": SplittingType.componentFlow,
            "ideal_split_map": {
                ("A"): "outlet_1",
                ("B"): "outlet_2"
            }
        })

    # Ideal Separator should require no property calls
    # Only dummy state variables are required
    assert len(m.fs.params.required_properties) == 0
def build_boiler(fs):

    # Add property packages to flowsheet library
    fs.prop_fluegas = FlueGasParameterBlock()

    # Create unit models
    # Boiler Economizer
    fs.ECON = BoilerHeatExchanger(
        default={
            "side_1_property_package": fs.prop_water,
            "side_2_property_package": fs.prop_fluegas,
            "has_pressure_change": True,
            "has_holdup": False,
            "delta_T_method": DeltaTMethod.counterCurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Liq",
            "has_radiation": False
        })
    # Primary Superheater
    fs.PrSH = BoilerHeatExchanger(
        default={
            "side_1_property_package": fs.prop_water,
            "side_2_property_package": fs.prop_fluegas,
            "has_pressure_change": True,
            "has_holdup": False,
            "delta_T_method": DeltaTMethod.counterCurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Vap",
            "has_radiation": True
        })

    # Finishing Superheater
    fs.FSH = BoilerHeatExchanger(
        default={
            "side_1_property_package": fs.prop_water,
            "side_2_property_package": fs.prop_fluegas,
            "has_pressure_change": True,
            "has_holdup": False,
            "delta_T_method": DeltaTMethod.counterCurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Vap",
            "has_radiation": True
        })

    # Reheater
    fs.RH = BoilerHeatExchanger(
        default={
            "side_1_property_package": fs.prop_water,
            "side_2_property_package": fs.prop_fluegas,
            "has_pressure_change": True,
            "has_holdup": False,
            "delta_T_method": DeltaTMethod.counterCurrent,
            "tube_arrangement": TubeArrangement.inLine,
            "side_1_water_phase": "Vap",
            "has_radiation": True
        })
    # Platen Superheater
    fs.PlSH = Heater(default={"property_package": fs.prop_water})

    # Boiler Water Wall
    fs.Water_wall = Heater(default={"property_package": fs.prop_water})

    # Boiler Splitter (splits FSH flue gas outlet to Reheater and PrSH)
    fs.Spl1 = Separator(
        default={
            "property_package": fs.prop_fluegas,
            "split_basis": SplittingType.totalFlow,
            "energy_split_basis": EnergySplittingType.equal_temperature
        })
    # Flue gas mixer (mixing FG from Reheater and Primary SH, inlet to ECON)
    fs.mix1 = Mixer(
        default={
            "property_package": fs.prop_fluegas,
            "inlet_list": ['Reheat_out', 'PrSH_out'],
            "dynamic": False
        })

    # Mixer for Attemperator #1 (between PrSH and PlSH)
    fs.ATMP1 = Mixer(
        default={
            "property_package": fs.prop_water,
            "inlet_list": ['Steam', 'SprayWater'],
            "dynamic": False
        })

    # Build connections (streams)

    # Steam Route (side 1 = tube side = steam/water side)
    # Boiler feed water to Economizer (to be imported in full plant model)
    #    fs.bfw2econ = Arc(source=fs.FWH8.outlet,
    #                           destination=fs.ECON.side_1_inlet)
    fs.econ2ww = Arc(source=fs.ECON.side_1_outlet,
                     destination=fs.Water_wall.inlet)
    fs.ww2prsh = Arc(source=fs.Water_wall.outlet,
                     destination=fs.PrSH.side_1_inlet)
    fs.prsh2plsh = Arc(source=fs.PrSH.side_1_outlet, destination=fs.PlSH.inlet)
    fs.plsh2fsh = Arc(source=fs.PlSH.outlet, destination=fs.FSH.side_1_inlet)
    fs.FSHtoATMP1 = Arc(source=fs.FSH.side_1_outlet,
                        destination=fs.ATMP1.Steam)
    #    fs.fsh2hpturbine=Arc(source=fs.ATMP1.outlet,
    #                           destination=fs.HPTinlet)
    # (to be imported in full plant model)

    # Flue gas route ---------------------------------------------------------
    # water wall connected with boiler block (to fix the heat duty)
    # platen SH connected with boiler block (to fix the heat duty)
    # Finishing superheater connected with a flowsheet level constraint
    fs.fg_fsh2_separator = Arc(source=fs.FSH.side_2_outlet,
                               destination=fs.Spl1.inlet)
    fs.fg_fsh2rh = Arc(source=fs.Spl1.outlet_1, destination=fs.RH.side_2_inlet)
    fs.fg_fsh2PrSH = Arc(source=fs.Spl1.outlet_2,
                         destination=fs.PrSH.side_2_inlet)
    fs.fg_rhtomix = Arc(source=fs.RH.side_2_outlet,
                        destination=fs.mix1.Reheat_out)
    fs.fg_prsh2mix = Arc(source=fs.PrSH.side_2_outlet,
                         destination=fs.mix1.PrSH_out)
    fs.fg_mix2econ = Arc(source=fs.mix1.outlet,
                         destination=fs.ECON.side_2_inlet)
Exemple #4
0
    def build(self):
        """
        Begin building model (pre-DAE transformation).

        Args:
            None

        Returns:
            None
        """
        # Call UnitModel.build to setup dynamics
        super(FlashData, self).build()

        # Build Control Volume
        self.control_volume = ControlVolume0DBlock(
            default={
                "dynamic": self.config.dynamic,
                "has_holdup": self.config.has_holdup,
                "property_package": self.config.property_package,
                "property_package_args": self.config.property_package_args
            })

        self.control_volume.add_state_blocks(has_phase_equilibrium=True)

        self.control_volume.add_material_balances(
            balance_type=self.config.material_balance_type,
            has_phase_equilibrium=True)

        self.control_volume.add_energy_balances(
            balance_type=self.config.energy_balance_type,
            has_heat_transfer=self.config.has_heat_transfer)

        self.control_volume.add_momentum_balances(
            balance_type=self.config.momentum_balance_type,
            has_pressure_change=self.config.has_pressure_change)

        # Add Ports
        self.add_inlet_port()

        split_map = {}
        for p in self.control_volume.properties_in.phase_list:
            p_obj = self.config.property_package.get_phase(p)
            if p_obj.is_vapor_phase():
                # Vapor leaves through Vap outlet
                split_map[p] = "Vap"
            else:
                # All other phases leave through Liq outlet
                split_map[p] = "Liq"

        self.split = Separator(
            default={
                "property_package": self.config.property_package,
                "property_package_args": self.config.property_package_args,
                "outlet_list": ["Vap", "Liq"],
                "split_basis": SplittingType.phaseFlow,
                "ideal_separation": self.config.ideal_separation,
                "ideal_split_map": split_map,
                "mixed_state_block": self.control_volume.properties_out,
                "has_phase_equilibrium": not self.config.ideal_separation,
                "energy_split_basis": self.config.energy_split_basis
            })
        if not self.config.ideal_separation:

            def split_frac_rule(b, t, o):
                return b.split.split_fraction[t, o, o] == 1

            self.split_fraction_eq = Constraint(self.flowsheet().config.time,
                                                self.split.outlet_idx,
                                                rule=split_frac_rule)

        self.vap_outlet = Port(extends=self.split.Vap)
        self.liq_outlet = Port(extends=self.split.Liq)

        # Add references
        if (self.config.has_heat_transfer is True
                and self.config.energy_balance_type != EnergyBalanceType.none):
            self.heat_duty = Reference(self.control_volume.heat[:])
        if (self.config.has_pressure_change is True and
                self.config.momentum_balance_type != MomentumBalanceType.none):
            self.deltaP = Reference(self.control_volume.deltaP[:])
Exemple #5
0
    def build(self):
        """
        Begin building model (pre-DAE transformation).

        Args:
            None

        Returns:
            None
        """
        # Call UnitModel.build to setup dynamics
        super(WaterFlashData, self).build()

        # Build Control Volume
        self.control_volume = ControlVolume0DBlock(
            default={
                "dynamic": self.config.dynamic,
                "has_holdup": self.config.has_holdup,
                "property_package": self.config.property_package,
                "property_package_args": self.config.property_package_args
            })

        self.control_volume.add_state_blocks(
            has_phase_equilibrium=self.config.has_phase_equilibrium)

        self.control_volume.add_material_balances(
            balance_type=self.config.material_balance_type,
            has_phase_equilibrium=self.config.has_phase_equilibrium)

        self.control_volume.add_energy_balances(
            balance_type=self.config.energy_balance_type,
            has_heat_transfer=self.config.has_heat_transfer)

        self.control_volume.add_momentum_balances(
            balance_type=self.config.momentum_balance_type,
            has_pressure_change=self.config.has_pressure_change)

        # Add Ports
        self.add_inlet_port()

        #split_map = {}
        #for p in self.config.property_package.phase_list:
        #    split_map[p] = p

        self.split = Separator(
            default={
                "property_package": self.config.property_package,
                "property_package_args": self.config.property_package_args,
                "outlet_list": ["Vap", "Liq"],
                "split_basis": SplittingType.totalFlow,
                "ideal_separation": False,
                "mixed_state_block": self.control_volume.properties_out
            })

        add_object_reference(self, "vap_outlet", self.split.Vap)
        add_object_reference(self, "liq_outlet", self.split.Liq)

        # Add references
        if (self.config.has_heat_transfer is True
                and self.config.energy_balance_type != 'none'):
            add_object_reference(self, "heat_duty", self.control_volume.heat)
        if (self.config.has_pressure_change is True
                and self.config.momentum_balance_type != 'none'):
            add_object_reference(self, "deltaP", self.control_volume.deltaP)

        # Specify split fraction
        add_object_reference(self, "split_fraction", self.split.split_fraction)

        @self.Constraint(self.flowsheet().config.time,
                         doc="mol flow rate for vapor outlet")
        def flow_mol_vapor_eqn(b, t):
            return b.split_fraction[t, "Vap"] == \
                  b.control_volume.properties_in[t].vapor_frac

        # it seems that the temperature_splitting equation is defined in ports as default
        self.split.temperature_equality_eqn.deactivate()

        @self.Constraint(self.flowsheet().config.time,
                         doc="mol enthalpy for vapor outlet")
        def enth_mol_vapor_eqn(b, t):
            return b.vap_outlet.enth_mol[t] == b.control_volume.properties_in[
                t].enth_mol_sat_phase["Vap"]

        @self.Constraint(self.flowsheet().config.time,
                         doc="mol enthalpy for liquid outlet")
        def enth_mol_liquid_eqn(b, t):
            return b.liq_outlet.enth_mol[t] == b.control_volume.properties_in[
                t].enth_mol_sat_phase["Liq"]