diff --git a/property_packages/modular/builder/common_parsers.py b/property_packages/modular/builder/common_parsers.py index 145c456..73a1591 100644 --- a/property_packages/modular/builder/common_parsers.py +++ b/property_packages/modular/builder/common_parsers.py @@ -274,6 +274,12 @@ def serialise(compounds: List[Compound], valid_states: List[States]) -> Dict[str "temperature": (min_melting_point, 200, 400, pyunits.K), "pressure": (5e4, 1e5, 1e6, pyunits.Pa), } + elif (min_critical_temperature > 120): + return { + "flow_mol": (0, 100, 1000, pyunits.mol / pyunits.s), + "temperature": (min_melting_point, 150, 500, pyunits.K), + "pressure": (5e4, 1e5, 1e6, pyunits.Pa), + } else: return { "flow_mol": (0, 100, 1000, pyunits.mol / pyunits.s), diff --git a/property_packages/tests/test_heat_exchanger_bt_pr.py b/property_packages/tests/test_heat_exchanger_pr.py similarity index 58% rename from property_packages/tests/test_heat_exchanger_bt_pr.py rename to property_packages/tests/test_heat_exchanger_pr.py index 6be9506..dc2281b 100644 --- a/property_packages/tests/test_heat_exchanger_bt_pr.py +++ b/property_packages/tests/test_heat_exchanger_pr.py @@ -18,7 +18,7 @@ def assert_approx(value, expected_value, error_margin): tolerance = abs(percent_error * expected_value) assert approx(value, abs=tolerance) == expected_value -def test_heat_exchanger(): +def test_heat_exchanger_bt(): m = ConcreteModel() m.fs = FlowsheetBlock(dynamic=False) @@ -60,4 +60,48 @@ def test_heat_exchanger(): result = solver.solve(m) assert value(m.fs.heat_exchanger.shell.properties_out[0].temperature) == approx(373.13, abs=1e-2) - assert_approx(value(m.fs.heat_exchanger.tube.properties_out[0].temperature), 369.24, 0.5) \ No newline at end of file + assert_approx(value(m.fs.heat_exchanger.tube.properties_out[0].temperature), 369.24, 0.5) + +def test_heat_exchanger_asu(): + m = ConcreteModel() + m.fs = FlowsheetBlock(dynamic=False) + + m.fs.properties1 = build_package("helmholtz", ["h2o"], ["Liq", "Vap"]) + m.fs.properties2 = build_package("peng-robinson", ["oxygen", "argon", "nitrogen"], ["Liq", "Vap"]) + + m.fs.heat_exchanger = HeatExchanger( + delta_temperature_callback=delta_temperature_amtd_callback, + hot_side_name="shell", + cold_side_name="tube", + shell={"property_package": m.fs.properties1}, + tube={"property_package": m.fs.properties2}) + + assert degrees_of_freedom(m) == 11 + + h = htpx(473.15*units.K, P = 100000*units.Pa) # 200 C + m.fs.heat_exchanger.shell_inlet.flow_mol.fix(20*units.kilomol/units.hour) + m.fs.heat_exchanger.shell_inlet.pressure.fix(100000) # Pa + m.fs.heat_exchanger.shell_inlet.enth_mol.fix(h) # J/mol + + assert degrees_of_freedom(m) == 8 + + m.fs.heat_exchanger.tube_inlet.flow_mol.fix(1*units.kilomol/units.hour) # mol/s + m.fs.heat_exchanger.tube_inlet.mole_frac_comp[0, "oxygen"].fix(0.33) + m.fs.heat_exchanger.tube_inlet.mole_frac_comp[0, "argon"].fix(0.33) + m.fs.heat_exchanger.tube_inlet.mole_frac_comp[0, "nitrogen"].fix(0.33) + m.fs.heat_exchanger.tube_inlet.pressure.fix(100000) # Pa + m.fs.heat_exchanger.tube_inlet.temperature[0].fix((25 + 273.15)*units.K) + + assert degrees_of_freedom(m) == 2 + + m.fs.heat_exchanger.shell_outlet.pressure.fix(100000) + m.fs.heat_exchanger.heat_duty.fix(927.7) # W + + assert degrees_of_freedom(m) == 0 + + m.fs.heat_exchanger.initialize() + + solver = SolverFactory('ipopt') + result = solver.solve(m) + + assert_approx(value(m.fs.heat_exchanger.shell.properties_out[0].temperature), 195.3 + 273.15, 0.1) \ No newline at end of file diff --git a/property_packages/tests/test_heater_bt_pr.py b/property_packages/tests/test_heater_bt_pr.py deleted file mode 100644 index ea0cc94..0000000 --- a/property_packages/tests/test_heater_bt_pr.py +++ /dev/null @@ -1,42 +0,0 @@ -# Build and solve a heater block. -from ..build_package import build_package -from pytest import approx - -# Import objects from pyomo package -from pyomo.environ import ConcreteModel, SolverFactory, value, units - -# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model -from idaes.core import FlowsheetBlock -from idaes.core.util.model_statistics import degrees_of_freedom -from idaes.models.unit_models.heater import Heater -from idaes.core.util.tables import _get_state_from_port - -def assert_approx(value, expected_value, error_margin): - percent_error = error_margin / 100 - tolerance = abs(percent_error * expected_value) - assert approx(value, abs=tolerance) == expected_value - -def test_heater(): - m = ConcreteModel() - m.fs = FlowsheetBlock(dynamic=False) - m.fs.properties = build_package("peng-robinson", ["benzene", "toluene"], ["Liq", "Vap"]) - - m.fs.heater = Heater(property_package=m.fs.properties) - - m.fs.heater.inlet.flow_mol.fix(1000/3600) - m.fs.heater.inlet.mole_frac_comp[0, "benzene"].fix(0.4) - m.fs.heater.inlet.mole_frac_comp[0, "toluene"].fix(0.6) - m.fs.heater.inlet.pressure.fix(101325) - m.fs.heater.inlet.temperature.fix(353) - m.fs.heater.heat_duty.fix(459.10147722222354) - - m.fs.heater.initialize() - - assert degrees_of_freedom(m) == 0 - - solver = SolverFactory('ipopt') - solver.solve(m, tee=True) - - assert_approx(value(_get_state_from_port(m.fs.heater.outlet,0).temperature), 363, 0.2) - assert value(m.fs.heater.outlet.pressure[0]) == approx(101325) - assert value(m.fs.heater.outlet.flow_mol[0]) == approx(1000/3600) \ No newline at end of file diff --git a/property_packages/tests/test_heater_pr.py b/property_packages/tests/test_heater_pr.py new file mode 100644 index 0000000..06760e5 --- /dev/null +++ b/property_packages/tests/test_heater_pr.py @@ -0,0 +1,85 @@ +# Build and solve a heater block. +from ..build_package import build_package +from pytest import approx + +# Import objects from pyomo package +from pyomo.environ import ConcreteModel, SolverFactory, value, units + +# Import the main FlowsheetBlock from IDAES. The flowsheet block will contain the unit model +from idaes.core import FlowsheetBlock +from idaes.core.util.model_statistics import degrees_of_freedom +from idaes.models.unit_models.heater import Heater +from idaes.core.util.tables import _get_state_from_port + +def assert_approx(value, expected_value, error_margin): + percent_error = error_margin / 100 + tolerance = abs(percent_error * expected_value) + assert approx(value, abs=tolerance) == expected_value + +def test_heater_bt(): + m = ConcreteModel() + m.fs = FlowsheetBlock(dynamic=False) + m.fs.properties = build_package("peng-robinson", ["benzene", "toluene"], ["Liq", "Vap"]) + + m.fs.heater = Heater(property_package=m.fs.properties) + + m.fs.heater.inlet.flow_mol.fix(1000/3600) + m.fs.heater.inlet.mole_frac_comp[0, "benzene"].fix(0.4) + m.fs.heater.inlet.mole_frac_comp[0, "toluene"].fix(0.6) + m.fs.heater.inlet.pressure.fix(101325) + m.fs.heater.inlet.temperature.fix(353) + m.fs.heater.heat_duty.fix(459.10147722222354) + + m.fs.heater.initialize() + + assert degrees_of_freedom(m) == 0 + + solver = SolverFactory('ipopt') + solver.solve(m, tee=True) + + assert_approx(value(_get_state_from_port(m.fs.heater.outlet,0).temperature), 363, 0.2) + assert value(m.fs.heater.outlet.pressure[0]) == approx(101325) + assert value(m.fs.heater.outlet.flow_mol[0]) == approx(1000/3600) + +def test_heater_asu(): + m = ConcreteModel() + m.fs = FlowsheetBlock(dynamic=False) + m.fs.properties = build_package("peng-robinson", ["argon", "nitrogen", "oxygen"], ["Liq", "Vap"]) + + m.fs.heater = Heater(property_package=m.fs.properties) + + m.fs.heater.inlet.flow_mol.fix(units.convert(1 * units.kilomol/units.hour, units.mol/units.s)) # mol/s + m.fs.heater.inlet.mole_frac_comp[0, "argon"].fix(0.33) + m.fs.heater.inlet.mole_frac_comp[0, "nitrogen"].fix(0.33) + m.fs.heater.inlet.mole_frac_comp[0, "oxygen"].fix(0.33) + m.fs.heater.inlet.pressure.fix(100000) + m.fs.heater.inlet.temperature.fix(units.convert_temp_C_to_K(25)) + m.fs.heater.outlet.temperature.fix(units.convert_temp_C_to_K(50)) + + m.fs.heater.initialize() + + assert degrees_of_freedom(m) == 0 + + solver = SolverFactory('ipopt') + solver.solve(m, tee=True) + + assert_approx(value(m.fs.heater.heat_duty[0]), 183.856, 1) # 1% tolerance + + m.fs.heater2 = Heater(property_package=m.fs.properties) + + m.fs.heater2.inlet.flow_mol.fix(units.convert(1 * units.kilomol/units.hour, units.mol/units.s)) # mol/s + m.fs.heater2.inlet.mole_frac_comp[0, "argon"].fix(0.33) + m.fs.heater2.inlet.mole_frac_comp[0, "nitrogen"].fix(0.33) + m.fs.heater2.inlet.mole_frac_comp[0, "oxygen"].fix(0.33) + m.fs.heater2.inlet.pressure.fix(100000) + m.fs.heater2.inlet.temperature.fix(units.convert_temp_C_to_K(25)) + m.fs.heater2.outlet.temperature.fix(units.convert_temp_C_to_K(-15)) + + m.fs.heater2.initialize() + + assert degrees_of_freedom(m) == 0 + + solver = SolverFactory('ipopt') + solver.solve(m, tee=True) + + assert_approx(value(m.fs.heater2.heat_duty[0]), -292.5, 1) # 1% tolerance