def Pump_frame(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.SeawaterParameterBlock()

        m.fs.unit = Pump(default={"property_package": m.fs.properties})

        # fully specify system
        feed_flow_mass = 1
        feed_mass_frac_TDS = 0.035
        feed_pressure_in = 1e5
        feed_pressure_out = 5e5
        feed_temperature = 273.15 + 25
        efi_pump = 0.75

        feed_mass_frac_H2O = 1 - feed_mass_frac_TDS
        m.fs.unit.inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(
            feed_flow_mass * feed_mass_frac_TDS
        )
        m.fs.unit.inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(
            feed_flow_mass * feed_mass_frac_H2O
        )
        m.fs.unit.inlet.pressure[0].fix(feed_pressure_in)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.outlet.pressure[0].fix(feed_pressure_out)
        m.fs.unit.efficiency_pump.fix(efi_pump)
        return m
Example #2
0
    def unit_frame(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={'dynamic': False})
        m.fs.properties = props.SeawaterParameterBlock()
        m.fs.unit = PressureExchanger(
            default={'property_package': m.fs.properties})

        # Specify inlet conditions
        temperature = 25 + 273.15
        flow_vol = 1e-3
        lowP_mass_frac_TDS = 0.035
        lowP_pressure = 101325
        highP_mass_frac_TDS = 0.07
        highP_pressure = 50e5

        m.fs.unit.low_pressure_side.properties_in[0].flow_vol_phase['Liq'].fix(
            flow_vol)
        m.fs.unit.low_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].fix(lowP_mass_frac_TDS)
        m.fs.unit.low_pressure_side.properties_in[0].pressure.fix(
            lowP_pressure)
        m.fs.unit.low_pressure_side.properties_in[0].temperature.fix(
            temperature)

        m.fs.unit.high_pressure_side.properties_in[0].flow_vol_phase[
            'Liq'].fix(flow_vol)
        m.fs.unit.high_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].fix(highP_mass_frac_TDS)
        m.fs.unit.high_pressure_side.properties_in[0].pressure.fix(
            highP_pressure)
        m.fs.unit.high_pressure_side.properties_in[0].temperature.fix(
            temperature)

        # solve inlet conditions and only fix state variables (i.e. unfix flow_vol and mass_frac_phase)
        results = solver.solve(m.fs.unit.low_pressure_side.properties_in[0])
        assert results.solver.termination_condition == TerminationCondition.optimal
        m.fs.unit.low_pressure_side.properties_in[0].flow_mass_phase_comp[
            'Liq', 'TDS'].fix()
        m.fs.unit.low_pressure_side.properties_in[0].flow_vol_phase[
            'Liq'].unfix()
        m.fs.unit.low_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].unfix()

        results = solver.solve(m.fs.unit.high_pressure_side.properties_in[0])
        assert results.solver.termination_condition == TerminationCondition.optimal
        m.fs.unit.high_pressure_side.properties_in[0].flow_mass_phase_comp[
            'Liq', 'H2O'].fix()
        m.fs.unit.high_pressure_side.properties_in[0].flow_mass_phase_comp[
            'Liq', 'TDS'].fix()
        m.fs.unit.high_pressure_side.properties_in[0].flow_vol_phase[
            'Liq'].unfix()
        m.fs.unit.high_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].unfix()

        # Specify unit
        efficiency = 0.95
        m.fs.unit.efficiency_pressure_exchanger.fix(efficiency)
        return m
def test_config():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = props.SeawaterParameterBlock()
    m.fs.unit = PressureExchanger(
        default={"property_package": m.fs.properties})

    # check unit config arguments
    assert len(m.fs.unit.config) == 7

    assert not m.fs.unit.config.dynamic
    assert not m.fs.unit.config.has_holdup
    assert m.fs.unit.config.material_balance_type == MaterialBalanceType.useDefault
    assert m.fs.unit.config.energy_balance_type == EnergyBalanceType.useDefault
    assert m.fs.unit.config.momentum_balance_type == MomentumBalanceType.pressureTotal
    assert m.fs.unit.config.property_package is m.fs.properties
Example #4
0
def build(m):
    # Properties
    m.fs.properties_feed = props_sw.SeawaterParameterBlock()
    m.fs.properties_vapor = props_w.WaterParameterBlock()

    # Evaporator
    m.fs.evaporator = Evaporator(
        default={
            "property_package_feed": m.fs.properties_feed,
            "property_package_vapor": m.fs.properties_vapor,
        })
    # Compressor
    m.fs.compressor = Compressor(
        default={"property_package": m.fs.properties_vapor})

    # Connections
    m.fs.s01 = Arc(source=m.fs.evaporator.outlet_vapor,
                   destination=m.fs.compressor.inlet)
    m.fs.s02 = Arc(source=m.fs.compressor.outlet,
                   destination=m.fs.evaporator.inlet_condenser)
    TransformationFactory("network.expand_arcs").apply_to(m)
Example #5
0
def test_evaporator():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties_feed = props_sw.SeawaterParameterBlock()
    m.fs.properties_vapor = props_w.WaterParameterBlock()
    m.fs.evaporator = Evaporator(
        default={
            "property_package_feed": m.fs.properties_feed,
            "property_package_vapor": m.fs.properties_vapor,
        })

    # scaling
    m.fs.properties_feed.set_default_scaling("flow_mass_phase_comp",
                                             1,
                                             index=("Liq", "H2O"))
    m.fs.properties_feed.set_default_scaling("flow_mass_phase_comp",
                                             1e2,
                                             index=("Liq", "TDS"))
    m.fs.properties_vapor.set_default_scaling("flow_mass_phase_comp",
                                              1,
                                              index=("Vap", "H2O"))
    m.fs.properties_vapor.set_default_scaling("flow_mass_phase_comp",
                                              1,
                                              index=("Liq", "H2O"))
    iscale.set_scaling_factor(m.fs.evaporator.area, 1e-3)
    iscale.set_scaling_factor(m.fs.evaporator.U, 1e-3)
    iscale.set_scaling_factor(m.fs.evaporator.delta_temperature_in, 1e-1)
    iscale.set_scaling_factor(m.fs.evaporator.delta_temperature_out, 1e-1)
    iscale.set_scaling_factor(m.fs.evaporator.lmtd, 1e-1)
    # iscale.set_scaling_factor(m.fs.evaporator.heat_transfer, 1e-6)
    iscale.calculate_scaling_factors(m)

    # assert False

    # state variables
    # Feed inlet
    m.fs.evaporator.inlet_feed.flow_mass_phase_comp[0, "Liq", "H2O"].fix(10)
    m.fs.evaporator.inlet_feed.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.05)
    m.fs.evaporator.inlet_feed.temperature[0].fix(273.15 + 50.52)  # K
    m.fs.evaporator.inlet_feed.pressure[0].fix(1e5)  # Pa

    # Condenser inlet
    m.fs.evaporator.inlet_condenser.flow_mass_phase_comp[0, "Vap",
                                                         "H2O"].fix(0.5)
    m.fs.evaporator.inlet_condenser.flow_mass_phase_comp[0, "Liq",
                                                         "H2O"].fix(1e-8)
    m.fs.evaporator.inlet_condenser.temperature[0].fix(400)  # K
    m.fs.evaporator.inlet_condenser.pressure[0].fix(0.5e5)  # Pa

    # Evaporator/condenser specifications
    m.fs.evaporator.outlet_brine.temperature[0].fix(273.15 + 60)
    m.fs.evaporator.U.fix(1e3)  # W/K-m^2
    m.fs.evaporator.area.fix(100)  # m^2

    # check build
    assert_units_consistent(m)
    assert degrees_of_freedom(m) == 0

    # initialize
    m.fs.evaporator.initialize()

    # solve
    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    # check values, TODO: make a report for the evaporator
    # m.fs.evaporator.display()
    vapor_blk = m.fs.evaporator.feed_side.properties_vapor[0]
    assert vapor_blk.flow_mass_phase_comp["Vap", "H2O"].value == pytest.approx(
        0.3540, rel=1e-3)
    assert m.fs.evaporator.lmtd.value == pytest.approx(12.30, rel=1e-3)
    assert m.fs.evaporator.feed_side.heat_transfer.value == pytest.approx(
        1.230e6, rel=1e-3)
Example #6
0
def test_build():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={'dynamic': False})
    m.fs.properties = props.SeawaterParameterBlock()
    m.fs.unit = PressureExchanger(
        default={'property_package': m.fs.properties})

    # test ports and state variables
    port_lst = [
        'low_pressure_inlet', 'low_pressure_outlet', 'high_pressure_inlet',
        'high_pressure_outlet'
    ]
    port_vars_lst = ['flow_mass_phase_comp', 'pressure', 'temperature']
    for port_str in port_lst:
        assert hasattr(m.fs.unit, port_str)
        port = getattr(m.fs.unit, port_str)
        assert len(port.vars) == 3
        assert isinstance(port, Port)
        for var_str in port_vars_lst:
            assert hasattr(port, var_str)
            var = getattr(port, var_str)
            assert isinstance(var, Var)

    # test unit variables
    assert hasattr(m.fs.unit, 'efficiency_pressure_exchanger')
    assert isinstance(m.fs.unit.efficiency_pressure_exchanger, Var)

    # test unit constraints
    unit_cons_lst = [
        'eq_pressure_transfer', 'eq_equal_flow_vol', 'eq_equal_low_pressure'
    ]
    for c in unit_cons_lst:
        assert hasattr(m.fs.unit, c)
        con = getattr(m.fs.unit, c)
        assert isinstance(con, Constraint)

    # test control volumes, only terms directly used by pressure exchanger
    cv_list = ['low_pressure_side', 'high_pressure_side']
    cv_var_lst = ['deltaP']
    cv_con_lst = ['eq_isothermal_temperature']
    cv_exp_lst = ['work']
    for cv_str in cv_list:
        assert hasattr(m.fs.unit, cv_str)
        cv = getattr(m.fs.unit, cv_str)
        for cv_var_str in cv_var_lst:
            cv_var = getattr(cv, cv_var_str)
            assert isinstance(cv_var, Var)
        for cv_con_str in cv_con_lst:
            cv_con = getattr(cv, cv_con_str)
            assert isinstance(cv_con, Constraint)
        for cv_exp_str in cv_exp_lst:
            cv_exp = getattr(cv, cv_exp_str)
            assert isinstance(cv_exp, Expression)

    # test state blocks, only terms directly used by pressure exchanger
    cv_stateblock_lst = ['properties_in', 'properties_out']
    stateblock_var_lst = ['pressure', 'temperature']
    stateblock_exp_lst = ['flow_vol']
    for cv_str in cv_list:
        cv = getattr(m.fs.unit, cv_str)
        for cv_sb_str in cv_stateblock_lst:
            assert hasattr(cv, cv_sb_str)
            cv_sb = getattr(cv, cv_sb_str)
            for sb_var_str in stateblock_var_lst:
                assert hasattr(cv_sb[0], sb_var_str)
                sb_var = getattr(cv_sb[0], sb_var_str)
                assert isinstance(sb_var, Var)
            for sb_exp_str in stateblock_exp_lst:
                assert hasattr(cv_sb[0], sb_exp_str)
                sb_exp = getattr(cv_sb[0], sb_exp_str)
                assert isinstance(sb_exp, Expression)

    # test statistics
    assert number_variables(m.fs.unit) == 39
    assert number_total_constraints(m.fs.unit) == 31
    assert number_unused_variables(m.fs.unit) == 0
def test_heat_exchanger():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = props.SeawaterParameterBlock()
    m.fs.unit = HeatExchanger(
        default={
            "hot_side_name": "hot",
            "cold_side_name": "cold",
            "hot": {
                "property_package": m.fs.properties
            },
            "cold": {
                "property_package": m.fs.properties
            },
            "delta_temperature_callback": delta_temperature_chen_callback,
            "flow_pattern": HeatExchangerFlowPattern.countercurrent,
        })

    # scaling
    m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                        1,
                                        index=("Liq", "H2O"))
    m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                        1e2,
                                        index=("Liq", "TDS"))
    iscale.set_scaling_factor(m.fs.unit.hot.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.cold.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.overall_heat_transfer_coefficient,
                              1e-3)
    iscale.set_scaling_factor(m.fs.unit.area, 1)
    iscale.calculate_scaling_factors(m)

    # ---specifications---
    # state variables
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(1)
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.hot_inlet.temperature[0].fix(350)
    m.fs.unit.hot_inlet.pressure[0].fix(2e5)

    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(0.5)
    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.cold_inlet.temperature[0].fix(298)
    m.fs.unit.cold_inlet.pressure[0].fix(2e5)

    m.fs.unit.area.fix(5)
    m.fs.unit.overall_heat_transfer_coefficient.fix(1000)

    # solving
    assert_units_consistent(m)
    degrees_of_freedom(m)

    m.fs.unit.initialize()

    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    report_io = StringIO()
    m.fs.unit.report(ostream=report_io)
    output = """
====================================================================================
Unit : fs.unit                                                             Time: 0.0
------------------------------------------------------------------------------------
    Unit Performance

    Variables: 

    Key            : Value  : Fixed : Bounds
           HX Area : 5.0000 :  True : (0, None)
    HX Coefficient : 1000.0 :  True : (0, None)
         Heat Duty : 89050. : False : (None, None)

    Expressions: 

    Key             : Value
    Delta T Driving : 17.810
         Delta T In : 9.2239
        Delta T Out : 30.689

------------------------------------------------------------------------------------
    Stream Table
                                         Hot Inlet  Hot Outlet  Cold Inlet  Cold Outlet
    flow_mass_phase_comp ('Liq', 'H2O')     1.0000      1.0000     0.50000     0.50000 
    flow_mass_phase_comp ('Liq', 'TDS')   0.010000    0.010000    0.010000    0.010000 
    temperature                             350.00      328.69      298.00      340.78 
    pressure                            2.0000e+05  2.0000e+05  2.0000e+05  2.0000e+05 
====================================================================================
"""
    assert output == report_io.getvalue()
Example #8
0
def build_prop(m, base="TDS"):
    """
    Builds a property package for the specified base. Includes default scaling.
    Bases include: 'TDS', 'ion', 'salt'.
    """
    if base == "TDS":
        m.fs.prop_TDS = seawater_prop_pack.SeawaterParameterBlock()

        m.fs.prop_TDS.set_default_scaling("flow_mass_phase_comp",
                                          1,
                                          index=("Liq", "H2O"))
        m.fs.prop_TDS.set_default_scaling("flow_mass_phase_comp",
                                          1e2,
                                          index=("Liq", "TDS"))

    elif base == "ion":
        m.fs.prop_ion = seawater_ion_prop_pack.PropParameterBlock()

        m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp",
                                          1,
                                          index=("Liq", "H2O"))
        m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp",
                                          1e2,
                                          index=("Liq", "Na"))
        m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp",
                                          1e4,
                                          index=("Liq", "Ca"))
        m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp",
                                          1e3,
                                          index=("Liq", "Mg"))
        m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp",
                                          1e3,
                                          index=("Liq", "SO4"))
        m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp",
                                          1e2,
                                          index=("Liq", "Cl"))

    elif base == "salt":
        m.fs.prop_salt = seawater_salt_prop_pack.PropParameterBlock()

        m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp",
                                           1,
                                           index=("Liq", "H2O"))
        m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp",
                                           1e2,
                                           index=("Liq", "NaCl"))
        m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp",
                                           1e3,
                                           index=("Liq", "CaSO4"))
        m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp",
                                           1e3,
                                           index=("Liq", "MgSO4"))
        m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp",
                                           1e3,
                                           index=("Liq", "MgCl2"))

    elif base == "eNRTL":
        m.fs.prop_eNRTL = GenericParameterBlock(
            default=entrl_config_FpcTP.configuration)

        # default scaling in config file

    else:
        raise ValueError(
            "Unexpected property base {base} provided to build_prop"
            "".format(base=base))
Example #9
0
def build_prop(m, base='TDS'):
    """
    Builds a property package for the specified base. Includes default scaling.
    Bases include: 'TDS', 'ion', 'salt'.
    """
    if base == 'TDS':
        m.fs.prop_TDS = seawater_prop_pack.SeawaterParameterBlock()

        m.fs.prop_TDS.set_default_scaling('flow_mass_phase_comp',
                                          1,
                                          index=('Liq', 'H2O'))
        m.fs.prop_TDS.set_default_scaling('flow_mass_phase_comp',
                                          1e2,
                                          index=('Liq', 'TDS'))

    elif base == 'ion':
        m.fs.prop_ion = seawater_ion_prop_pack.PropParameterBlock()

        m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp',
                                          1,
                                          index=('Liq', 'H2O'))
        m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp',
                                          1e2,
                                          index=('Liq', 'Na'))
        m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp',
                                          1e4,
                                          index=('Liq', 'Ca'))
        m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp',
                                          1e3,
                                          index=('Liq', 'Mg'))
        m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp',
                                          1e3,
                                          index=('Liq', 'SO4'))
        m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp',
                                          1e2,
                                          index=('Liq', 'Cl'))

    elif base == 'salt':
        m.fs.prop_salt = seawater_salt_prop_pack.PropParameterBlock()

        m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp',
                                           1,
                                           index=('Liq', 'H2O'))
        m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp',
                                           1e2,
                                           index=('Liq', 'NaCl'))
        m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp',
                                           1e3,
                                           index=('Liq', 'CaSO4'))
        m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp',
                                           1e3,
                                           index=('Liq', 'MgSO4'))
        m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp',
                                           1e3,
                                           index=('Liq', 'MgCl2'))

    elif base == 'eNRTL':
        m.fs.prop_eNRTL = GenericParameterBlock(
            default=entrl_config_FpcTP.configuration)

        # default scaling in config file

    else:
        raise ValueError(
            'Unexpected property base {base} provided to build_prop'
            ''.format(base=base))
def test_heat_exchanger():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = props.SeawaterParameterBlock()
    m.fs.unit = HeatExchanger(
        default={
            "hot_side_name": "hot",
            "cold_side_name": "cold",
            "hot": {
                "property_package": m.fs.properties
            },
            "cold": {
                "property_package": m.fs.properties
            },
            "delta_temperature_callback": delta_temperature_chen_callback,
            "flow_pattern": HeatExchangerFlowPattern.countercurrent,
        })

    # scaling
    m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                        1,
                                        index=("Liq", "H2O"))
    m.fs.properties.set_default_scaling("flow_mass_phase_comp",
                                        1e2,
                                        index=("Liq", "TDS"))
    iscale.set_scaling_factor(m.fs.unit.hot.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.cold.heat, 1e-3)
    iscale.set_scaling_factor(m.fs.unit.overall_heat_transfer_coefficient,
                              1e-3)
    iscale.set_scaling_factor(m.fs.unit.area, 1)
    iscale.calculate_scaling_factors(m)

    # ---specifications---
    # state variables
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(1)
    m.fs.unit.hot_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.hot_inlet.temperature[0].fix(350)
    m.fs.unit.hot_inlet.pressure[0].fix(2e5)

    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(0.5)
    m.fs.unit.cold_inlet.flow_mass_phase_comp[0, "Liq", "TDS"].fix(0.01)
    m.fs.unit.cold_inlet.temperature[0].fix(298)
    m.fs.unit.cold_inlet.pressure[0].fix(2e5)

    m.fs.unit.area.fix(5)
    m.fs.unit.overall_heat_transfer_coefficient.fix(1000)

    # solving
    assert_units_consistent(m)
    degrees_of_freedom(m)

    m.fs.unit.initialize()

    solver = get_solver()
    results = solver.solve(m, tee=False)
    assert_optimal_termination(results)

    assert pytest.approx(89050.0, rel=1e-4) == value(m.fs.unit.heat_duty[0])
    assert pytest.approx(1.0, rel=1e-4) == value(
        m.fs.unit.hot_outlet.flow_mass_phase_comp[0, "Liq", "H2O"])
    assert pytest.approx(0.01, rel=1e-4) == value(
        m.fs.unit.hot_outlet.flow_mass_phase_comp[0, "Liq", "TDS"])
    assert pytest.approx(328.69, rel=1e-4) == value(
        m.fs.unit.hot_outlet.temperature[0])
    assert pytest.approx(2.0e5,
                         rel=1e-4) == value(m.fs.unit.hot_outlet.pressure[0])
    assert pytest.approx(0.5, rel=1e-4) == value(
        m.fs.unit.cold_outlet.flow_mass_phase_comp[0, "Liq", "H2O"])
    assert pytest.approx(0.01, rel=1e-4) == value(
        m.fs.unit.cold_outlet.flow_mass_phase_comp[0, "Liq", "TDS"])
    assert pytest.approx(340.78, rel=1e-4) == value(
        m.fs.unit.cold_outlet.temperature[0])
    assert pytest.approx(2.0e5,
                         rel=1e-4) == value(m.fs.unit.cold_outlet.pressure[0])

    m.fs.unit.report()
Example #11
0
def build(erd_type=None):
    # flowsheet set up
    m = ConcreteModel()
    m.db = Database()
    m.erd_type = erd_type

    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.prop_prtrt = prop_ZO.WaterParameterBlock(
        default={"solute_list": ["tds", "tss"]}
    )
    density = 1023.5 * pyunits.kg / pyunits.m**3
    m.fs.prop_prtrt.dens_mass_default = density
    m.fs.prop_psttrt = prop_ZO.WaterParameterBlock(default={"solute_list": ["tds"]})
    m.fs.prop_desal = prop_SW.SeawaterParameterBlock()

    # block structure
    prtrt = m.fs.pretreatment = Block()
    desal = m.fs.desalination = Block()
    psttrt = m.fs.posttreatment = Block()

    # unit models
    m.fs.feed = FeedZO(default={"property_package": m.fs.prop_prtrt})
    # pretreatment
    prtrt.intake = SWOnshoreIntakeZO(default={"property_package": m.fs.prop_prtrt})
    prtrt.ferric_chloride_addition = ChemicalAdditionZO(
        default={
            "property_package": m.fs.prop_prtrt,
            "database": m.db,
            "process_subtype": "ferric_chloride",
        }
    )
    prtrt.chlorination = ChlorinationZO(
        default={"property_package": m.fs.prop_prtrt, "database": m.db}
    )
    prtrt.static_mixer = StaticMixerZO(
        default={"property_package": m.fs.prop_prtrt, "database": m.db}
    )
    prtrt.storage_tank_1 = StorageTankZO(
        default={"property_package": m.fs.prop_prtrt, "database": m.db}
    )
    prtrt.media_filtration = MediaFiltrationZO(
        default={"property_package": m.fs.prop_prtrt, "database": m.db}
    )
    prtrt.backwash_handling = BackwashSolidsHandlingZO(
        default={"property_package": m.fs.prop_prtrt, "database": m.db}
    )
    prtrt.anti_scalant_addition = ChemicalAdditionZO(
        default={
            "property_package": m.fs.prop_prtrt,
            "database": m.db,
            "process_subtype": "anti-scalant",
        }
    )
    prtrt.cartridge_filtration = CartridgeFiltrationZO(
        default={"property_package": m.fs.prop_prtrt, "database": m.db}
    )

    # desalination
    desal.P1 = Pump(default={"property_package": m.fs.prop_desal})
    desal.RO = ReverseOsmosis0D(
        default={
            "property_package": m.fs.prop_desal,
            "has_pressure_change": True,
            "pressure_change_type": PressureChangeType.calculated,
            "mass_transfer_coefficient": MassTransferCoefficient.calculated,
            "concentration_polarization_type": ConcentrationPolarizationType.calculated,
        }
    )
    desal.RO.width.setub(5000)
    desal.RO.area.setub(20000)
    if erd_type == "pressure_exchanger":
        desal.S1 = Separator(
            default={"property_package": m.fs.prop_desal, "outlet_list": ["P1", "PXR"]}
        )
        desal.M1 = Mixer(
            default={
                "property_package": m.fs.prop_desal,
                "momentum_mixing_type": MomentumMixingType.equality,  # booster pump will match pressure
                "inlet_list": ["P1", "P2"],
            }
        )
        desal.PXR = PressureExchanger(default={"property_package": m.fs.prop_desal})
        desal.P2 = Pump(default={"property_package": m.fs.prop_desal})
    elif erd_type == "pump_as_turbine":
        desal.ERD = EnergyRecoveryDevice(default={"property_package": m.fs.prop_desal})
    else:
        raise ConfigurationError(
            "erd_type was {}, but can only "
            "be pressure_exchanger or pump_as_turbine"
            "".format(erd_type)
        )

    # posttreatment
    psttrt.storage_tank_2 = StorageTankZO(
        default={"property_package": m.fs.prop_psttrt, "database": m.db}
    )
    psttrt.uv_aop = UVAOPZO(
        default={
            "property_package": m.fs.prop_psttrt,
            "database": m.db,
            "process_subtype": "hydrogen_peroxide",
        }
    )
    psttrt.co2_addition = CO2AdditionZO(
        default={"property_package": m.fs.prop_psttrt, "database": m.db}
    )
    psttrt.lime_addition = ChemicalAdditionZO(
        default={
            "property_package": m.fs.prop_psttrt,
            "database": m.db,
            "process_subtype": "lime",
        }
    )
    psttrt.storage_tank_3 = StorageTankZO(
        default={"property_package": m.fs.prop_psttrt, "database": m.db}
    )

    # product and disposal
    m.fs.municipal = MunicipalDrinkingZO(
        default={"property_package": m.fs.prop_psttrt, "database": m.db}
    )
    m.fs.landfill = LandfillZO(
        default={"property_package": m.fs.prop_prtrt, "database": m.db}
    )
    m.fs.disposal = Product(default={"property_package": m.fs.prop_desal})

    # translator blocks
    m.fs.tb_prtrt_desal = Translator(
        default={
            "inlet_property_package": m.fs.prop_prtrt,
            "outlet_property_package": m.fs.prop_desal,
        }
    )

    @m.fs.tb_prtrt_desal.Constraint(["H2O", "tds"])
    def eq_flow_mass_comp(blk, j):
        if j == "tds":
            jj = "TDS"
        else:
            jj = j
        return (
            blk.properties_in[0].flow_mass_comp[j]
            == blk.properties_out[0].flow_mass_phase_comp["Liq", jj]
        )

    m.fs.tb_desal_psttrt = Translator(
        default={
            "inlet_property_package": m.fs.prop_desal,
            "outlet_property_package": m.fs.prop_psttrt,
        }
    )

    @m.fs.tb_desal_psttrt.Constraint(["H2O", "TDS"])
    def eq_flow_mass_comp(blk, j):
        if j == "TDS":
            jj = "tds"
        else:
            jj = j
        return (
            blk.properties_in[0].flow_mass_phase_comp["Liq", j]
            == blk.properties_out[0].flow_mass_comp[jj]
        )

    # connections
    m.fs.s_feed = Arc(source=m.fs.feed.outlet, destination=prtrt.intake.inlet)
    prtrt.s01 = Arc(
        source=prtrt.intake.outlet, destination=prtrt.ferric_chloride_addition.inlet
    )
    prtrt.s02 = Arc(
        source=prtrt.ferric_chloride_addition.outlet,
        destination=prtrt.chlorination.inlet,
    )
    prtrt.s03 = Arc(
        source=prtrt.chlorination.treated, destination=prtrt.static_mixer.inlet
    )
    prtrt.s04 = Arc(
        source=prtrt.static_mixer.outlet, destination=prtrt.storage_tank_1.inlet
    )
    prtrt.s05 = Arc(
        source=prtrt.storage_tank_1.outlet, destination=prtrt.media_filtration.inlet
    )
    prtrt.s06 = Arc(
        source=prtrt.media_filtration.byproduct,
        destination=prtrt.backwash_handling.inlet,
    )
    prtrt.s07 = Arc(
        source=prtrt.media_filtration.treated,
        destination=prtrt.anti_scalant_addition.inlet,
    )
    prtrt.s08 = Arc(
        source=prtrt.anti_scalant_addition.outlet,
        destination=prtrt.cartridge_filtration.inlet,
    )
    m.fs.s_prtrt_tb = Arc(
        source=prtrt.cartridge_filtration.treated, destination=m.fs.tb_prtrt_desal.inlet
    )
    m.fs.s_landfill = Arc(
        source=prtrt.backwash_handling.byproduct, destination=m.fs.landfill.inlet
    )

    if erd_type == "pressure_exchanger":
        m.fs.s_tb_desal = Arc(
            source=m.fs.tb_prtrt_desal.outlet, destination=desal.S1.inlet
        )
        desal.s01 = Arc(source=desal.S1.P1, destination=desal.P1.inlet)
        desal.s02 = Arc(source=desal.P1.outlet, destination=desal.M1.P1)
        desal.s03 = Arc(source=desal.M1.outlet, destination=desal.RO.inlet)
        desal.s04 = Arc(
            source=desal.RO.retentate, destination=desal.PXR.high_pressure_inlet
        )
        desal.s05 = Arc(source=desal.S1.PXR, destination=desal.PXR.low_pressure_inlet)
        desal.s06 = Arc(
            source=desal.PXR.low_pressure_outlet, destination=desal.P2.inlet
        )
        desal.s07 = Arc(source=desal.P2.outlet, destination=desal.M1.P2)
        m.fs.s_disposal = Arc(
            source=desal.PXR.high_pressure_outlet, destination=m.fs.disposal.inlet
        )
    elif erd_type == "pump_as_turbine":
        m.fs.s_tb_desal = Arc(
            source=m.fs.tb_prtrt_desal.outlet, destination=desal.P1.inlet
        )
        desal.s01 = Arc(source=desal.P1.outlet, destination=desal.RO.inlet)
        desal.s02 = Arc(source=desal.RO.retentate, destination=desal.ERD.inlet)
        m.fs.s_disposal = Arc(source=desal.ERD.outlet, destination=m.fs.disposal.inlet)
    m.fs.s_desal_tb = Arc(
        source=desal.RO.permeate, destination=m.fs.tb_desal_psttrt.inlet
    )

    m.fs.s_tb_psttrt = Arc(
        source=m.fs.tb_desal_psttrt.outlet, destination=psttrt.storage_tank_2.inlet
    )
    psttrt.s01 = Arc(
        source=psttrt.storage_tank_2.outlet, destination=psttrt.uv_aop.inlet
    )
    psttrt.s02 = Arc(
        source=psttrt.uv_aop.treated, destination=psttrt.co2_addition.inlet
    )
    psttrt.s03 = Arc(
        source=psttrt.co2_addition.outlet, destination=psttrt.lime_addition.inlet
    )
    psttrt.s04 = Arc(
        source=psttrt.lime_addition.outlet, destination=psttrt.storage_tank_3.inlet
    )
    m.fs.s_municipal = Arc(
        source=psttrt.storage_tank_3.outlet, destination=m.fs.municipal.inlet
    )
    TransformationFactory("network.expand_arcs").apply_to(m)

    # scaling
    # set default property values
    m.fs.prop_desal.set_default_scaling(
        "flow_mass_phase_comp", 1e-3, index=("Liq", "H2O")
    )
    m.fs.prop_desal.set_default_scaling(
        "flow_mass_phase_comp", 1e-1, index=("Liq", "TDS")
    )
    # set unit model values
    iscale.set_scaling_factor(desal.P1.control_volume.work, 1e-5)
    iscale.set_scaling_factor(desal.RO.area, 1e-4)
    if erd_type == "pressure_exchanger":
        iscale.set_scaling_factor(desal.P2.control_volume.work, 1e-5)
        iscale.set_scaling_factor(desal.PXR.low_pressure_side.work, 1e-5)
        iscale.set_scaling_factor(desal.PXR.high_pressure_side.work, 1e-5)
    elif erd_type == "pump_as_turbine":
        iscale.set_scaling_factor(desal.ERD.control_volume.work, 1e-5)
    # calculate and propagate scaling factors
    iscale.calculate_scaling_factors(m)

    return m