Beispiel #1
0
def test_model_checks():
    m = ConcreteModel()
    m.fs = Flowsheet(default={"dynamic": False})
    m.fs.pp = PhysicalParameterTestBlock()

    m.fs.sep = Separator(default={
            "property_package": m.fs.pp,
            "ideal_separation": False})

    m.fs.sep.model_check()

    assert m.fs.sep.outlet_1_state[0].check is True
    assert m.fs.sep.outlet_2_state[0].check is True
    assert m.fs.sep.mixed_state[0].check is True
Beispiel #2
0
def test_initialize():
    m = ConcreteModel()
    m.fs = Flowsheet(default={"dynamic": False})
    m.fs.pp = PhysicalParameterTestBlock()
    m.fs.sb = TestStateBlock(m.fs.time, default={"parameters": m.fs.pp})

    m.fs.sep = Separator(
        default={
            "property_package": m.fs.pp,
            "mixed_state_block": m.fs.sb,
            "ideal_separation": False,
            "split_basis": SplittingType.phaseComponentFlow
        })

    # Change one outlet pressure to check initialization calculations
    m.fs.sep.outlet_1_state[0].pressure = 8e4

    f = m.fs.sep.initialize(hold_state=True)

    assert m.fs.sep.outlet_1_state[0].init_test is True
    assert m.fs.sep.outlet_2_state[0].init_test is True
    assert m.fs.sb[0].init_test is True
    assert m.fs.sep.outlet_1_state[0].hold_state is False
    assert m.fs.sep.outlet_2_state[0].hold_state is False
    assert m.fs.sb[0].hold_state is True

    assert m.fs.sep.outlet_1.component_flow[0, "p1", "c1"].value == 0.5
    assert m.fs.sep.outlet_1.component_flow[0, "p1", "c2"].value == 0.5
    assert m.fs.sep.outlet_1.component_flow[0, "p2", "c1"].value == 0.5
    assert m.fs.sep.outlet_1.component_flow[0, "p2", "c2"].value == 0.5
    assert m.fs.sep.outlet_1.enthalpy[0, "p1"].value == 2
    assert m.fs.sep.outlet_1.enthalpy[0, "p2"].value == 2
    assert m.fs.sep.outlet_1.pressure[0].value == 1e5

    assert m.fs.sep.outlet_2.component_flow[0, "p1", "c1"].value == 0.5
    assert m.fs.sep.outlet_2.component_flow[0, "p1", "c2"].value == 0.5
    assert m.fs.sep.outlet_2.component_flow[0, "p2", "c1"].value == 0.5
    assert m.fs.sep.outlet_2.component_flow[0, "p2", "c2"].value == 0.5
    assert m.fs.sep.outlet_2.enthalpy[0, "p1"].value == 2
    assert m.fs.sep.outlet_2.enthalpy[0, "p2"].value == 2
    assert m.fs.sep.outlet_2.pressure[0].value == 1e5

    m.fs.sep.release_state(flags=f)

    assert m.fs.sep.outlet_1_state[0].hold_state is False
    assert m.fs.sep.outlet_2_state[0].hold_state is False
    assert m.fs.sb[0].hold_state is False
Beispiel #3
0
def test_initialize_inconsistent_keys():
    m = ConcreteModel()
    m.fs = Flowsheet(default={"dynamic": False})
    m.fs.pp = PhysicalParameterTestBlock()
    m.fs.sb = TestStateBlock(m.fs.time, default={"parameters": m.fs.pp})

    m.fs.sep = Separator(default={
            "property_package": m.fs.pp,
            "mixed_state_block": m.fs.sb,
            "ideal_separation": False,
            "split_basis": SplittingType.phaseFlow})

    # Change one outlet pressure to check initialization calculations
    m.fs.sep.outlet_1_state[0].pressure = 8e4

    with pytest.raises(KeyError):
        m.fs.sep.initialize()
Beispiel #4
0
def test_build_default():
    m = ConcreteModel()
    m.fs = Flowsheet(default={"dynamic": False})
    m.fs.pp = PhysicalParameterTestBlock()

    m.fs.sep = Separator(default={"property_package": m.fs.pp,
                                  "ideal_separation": False})

    assert isinstance(m.fs.sep.material_splitting_eqn, Constraint)
    assert len(m.fs.sep.material_splitting_eqn) == 8
    assert isinstance(m.fs.sep.temperature_equality_eqn, Constraint)
    assert len(m.fs.sep.temperature_equality_eqn) == 2
    assert isinstance(m.fs.sep.pressure_equality_eqn, Constraint)
    assert len(m.fs.sep.pressure_equality_eqn) == 2

    assert isinstance(m.fs.sep.outlet_1, Port)
    assert isinstance(m.fs.sep.outlet_2, Port)
    assert isinstance(m.fs.sep.inlet, Port)
Beispiel #5
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": "Liq",
            "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": "Liq",
            "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": "Liq",
            "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)
Beispiel #6
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.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.phaseFlow,
                "ideal_separation": True,
                "ideal_split_map": split_map,
                "mixed_state_block": self.control_volume.properties_out
            })

        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 != '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)
Beispiel #7
0
def test_initialize_total_flow():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = SaponificationParameterBlock()

    m.fs.sb = Separator(default={
            "property_package": m.fs.properties,
            "ideal_separation": False,
            "split_basis": SplittingType.totalFlow})

    m.fs.sb.inlet.flow_vol.fix(1.0e-03)
    m.fs.sb.inlet.conc_mol_comp[0, "H2O"].fix(55388.0)
    m.fs.sb.inlet.conc_mol_comp[0, "NaOH"].fix(100.0)
    m.fs.sb.inlet.conc_mol_comp[0, "EthylAcetate"].fix(100.0)
    m.fs.sb.inlet.conc_mol_comp[0, "SodiumAcetate"].fix(0.0)
    m.fs.sb.inlet.conc_mol_comp[0, "Ethanol"].fix(0.0)

    m.fs.sb.inlet.temperature.fix(303.15)
    m.fs.sb.inlet.pressure.fix(101325.0)

    m.fs.sb.split_fraction[0, "outlet_1"].fix(0.2)

    assert degrees_of_freedom(m) == 0

    m.fs.sb.initialize(outlvl=5, optarg={'tol': 1e-6})

    assert (pytest.approx(0.2, abs=1e-3) ==
             m.fs.sb.split_fraction[0, "outlet_1"].value)
    assert (pytest.approx(0.8, abs=1e-3) ==
             m.fs.sb.split_fraction[0, "outlet_2"].value)

    assert (pytest.approx(101325.0, abs=1e-2) ==
            m.fs.sb.outlet_1.pressure[0].value)
    assert (pytest.approx(303.15, abs=1e-2) ==
            m.fs.sb.outlet_1.temperature[0].value)
    assert (pytest.approx(2e-4, abs=1e-6) ==
            m.fs.sb.outlet_1.flow_vol[0].value)
    assert (pytest.approx(55388.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "H2O"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "NaOH"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "EthylAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "SodiumAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_1.conc_mol_comp[0, "Ethanol"].value)

    assert (pytest.approx(101325.0, abs=1e-2) ==
            m.fs.sb.outlet_2.pressure[0].value)
    assert (pytest.approx(303.15, abs=1e-2) ==
            m.fs.sb.outlet_2.temperature[0].value)
    assert (pytest.approx(8e-4, abs=1e-6) ==
            m.fs.sb.outlet_2.flow_vol[0].value)
    assert (pytest.approx(55388.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "H2O"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "NaOH"].value)
    assert (pytest.approx(100.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "EthylAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "SodiumAcetate"].value)
    assert (pytest.approx(0.0, abs=1e-2) ==
            m.fs.sb.outlet_2.conc_mol_comp[0, "Ethanol"].value)