diff --git a/idaes/models/unit_models/flash.py b/idaes/models/unit_models/flash.py index 4d9a6e3079..ebcfa627ec 100644 --- a/idaes/models/unit_models/flash.py +++ b/idaes/models/unit_models/flash.py @@ -360,39 +360,15 @@ def _get_stream_table_contents(self, time_point=0): stream_attributes = {} stream_attributes["Units"] = {} - sblocks = { - "Inlet": self.control_volume.properties_in, - } - if not self.config.ideal_separation: - # If not using ideal separation, we can get outlet state directly - # from the state blocks - sblocks["Vapor Outlet"] = self.split.Vap_state - sblocks["Liquid Outlet"] = self.split.Liq_state - - for n, v in sblocks.items(): - dvars = v[time_point].define_display_vars() - - stream_attributes[n] = {} - - for k in dvars: - for i in dvars[k].keys(): - stream_key = k if i is None else f"{k} {i}" - - quant = report_quantity(dvars[k][i]) - - stream_attributes[n][stream_key] = quant.m - stream_attributes["Units"][stream_key] = quant.u - if self.config.ideal_separation: - # If using ideal separation, get values from Ports and hope they map - # to names in Inlet - # TODO: Add a better way to map these if necessary - for n, v in { - "Vapor Outlet": "vap_outlet", - "Liquid Outlet": "liq_outlet", + # If using ideal separation, build the stream table from Ports so that + # all streams use the same naming convention (avoids mismatches with + # define_display_vars() across property packages). + for n, port_obj in { + "Inlet": self.inlet, + "Vapor Outlet": self.vap_outlet, + "Liquid Outlet": self.liq_outlet, }.items(): - port_obj = getattr(self, v) - stream_attributes[n] = {} for k in port_obj.vars: @@ -409,5 +385,27 @@ def _get_stream_table_contents(self, time_point=0): quant = report_quantity(port_obj.vars[k][time_point, i[1:]]) stream_attributes[n][k + " " + kname] = quant.m stream_attributes["Units"][k + " " + kname] = quant.u + else: + # If not using ideal separation, we can get outlet state directly + # from the state blocks + sblocks = { + "Inlet": self.control_volume.properties_in, + "Vapor Outlet": self.split.Vap_state, + "Liquid Outlet": self.split.Liq_state, + } + + for n, v in sblocks.items(): + dvars = v[time_point].define_display_vars() + + stream_attributes[n] = {} + + for k in dvars: + for i in dvars[k].keys(): + stream_key = k if i is None else f"{k} {i}" + + quant = report_quantity(dvars[k][i]) + + stream_attributes[n][stream_key] = quant.m + stream_attributes["Units"][stream_key] = quant.u return DataFrame.from_dict(stream_attributes, orient="columns") diff --git a/idaes/models/unit_models/tests/test_flash.py b/idaes/models/unit_models/tests/test_flash.py index 290ddae7ec..b4290ac0f8 100644 --- a/idaes/models/unit_models/tests/test_flash.py +++ b/idaes/models/unit_models/tests/test_flash.py @@ -255,7 +255,6 @@ def test_get_stream_table_contents(self, btx): "pressure": pytest.approx(101325.0, rel=1e-4), }, } - assert stable.to_dict() == expected @pytest.mark.solver @@ -406,49 +405,48 @@ def test_get_performance_contents(self, bt_modular): } } - # TODO the formatting for modular properties is broken (see #1684). - # This test can be fixed once that issue is fixed - # @pytest.mark.ui - # @pytest.mark.unit - # def test_get_stream_table_contents(self, bt_modular): - # stable = bt_modular.fs.unit._get_stream_table_contents() - - # expected = { - # "Units": { - # "flow_mol": getattr(pyunits.pint_registry, "mole/s"), - # "mole_frac_comp benzene": getattr( - # pyunits.pint_registry, "dimensionless" - # ), - # "mole_frac_comp toluene": getattr( - # pyunits.pint_registry, "dimensionless" - # ), - # "temperature": getattr(pyunits.pint_registry, "K"), - # "pressure": getattr(pyunits.pint_registry, "Pa"), - # }, - # "Inlet": { - # "flow_mol": pytest.approx(1.00, rel=1e-4), - # "mole_frac_comp benzene": pytest.approx(0.5, rel=1e-4), - # "mole_frac_comp toluene": pytest.approx(0.5, rel=1e-4), - # "temperature": pytest.approx(368, rel=1e-4), - # "pressure": pytest.approx(101325, rel=1e-4), - # }, - # "Vapor Outlet": { - # "flow_mol": pytest.approx(0.5, rel=1e-4), - # "mole_frac_comp benzene": pytest.approx(0.5, rel=1e-4), - # "mole_frac_comp toluene": pytest.approx(0.5, rel=1e-4), - # "temperature": pytest.approx(298.15, rel=1e-4), - # "pressure": pytest.approx(101325.0, rel=1e-4), - # }, - # "Liquid Outlet": { - # "flow_mol": pytest.approx(0.5, rel=1e-4), - # "mole_frac_comp benzene": pytest.approx(0.5, rel=1e-4), - # "mole_frac_comp toluene": pytest.approx(0.5, rel=1e-4), - # "temperature": pytest.approx(298.15, rel=1e-4), - # "pressure": pytest.approx(101325.0, rel=1e-4), - # }, - # } - - # assert stable.to_dict() == expected + @pytest.mark.ui + @pytest.mark.unit + def test_get_stream_table_contents(self, bt_modular): + stable = bt_modular.fs.unit._get_stream_table_contents() + + expected = { + "Units": { + "flow_mol": getattr(pyunits.pint_registry, "mole/s"), + "mole_frac_comp benzene": getattr( + pyunits.pint_registry, "dimensionless" + ), + "mole_frac_comp toluene": getattr( + pyunits.pint_registry, "dimensionless" + ), + "temperature": getattr(pyunits.pint_registry, "K"), + "pressure": getattr(pyunits.pint_registry, "Pa"), + }, + "Inlet": { + "flow_mol": pytest.approx( + 1.00, rel=1e-4 + ), # This is different from its property package's (BT_ideal) properties_out value of 100 + "mole_frac_comp benzene": pytest.approx(0.5, rel=1e-4), + "mole_frac_comp toluene": pytest.approx(0.5, rel=1e-4), + "temperature": pytest.approx(368, rel=1e-4), + "pressure": pytest.approx(101325, rel=1e-4), + }, + "Vapor Outlet": { + "flow_mol": pytest.approx(50, rel=1e-4), + "mole_frac_comp benzene": pytest.approx(0.5, rel=1e-4), + "mole_frac_comp toluene": pytest.approx(0.5, rel=1e-4), + "temperature": pytest.approx(300.0, rel=1e-4), + "pressure": pytest.approx(100000.0, rel=1e-4), + }, + "Liquid Outlet": { + "flow_mol": pytest.approx(50, rel=1e-4), + "mole_frac_comp benzene": pytest.approx(0.5, rel=1e-4), + "mole_frac_comp toluene": pytest.approx(0.5, rel=1e-4), + "temperature": pytest.approx(300.0, rel=1e-4), + "pressure": pytest.approx(100000.0, rel=1e-4), + }, + } + assert stable.to_dict() == expected @pytest.mark.solver @pytest.mark.skipif(solver is None, reason="Solver not available")