예제 #1
0
    def trans(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties1 = SaponificationParameterBlock()
        m.fs.properties2 = BTXParameterBlock()

        m.fs.unit = Translator(
                default={"inlet_property_package": m.fs.properties1,
                         "outlet_property_package": m.fs.properties2})

        return m
예제 #2
0
def build_translator_from_RO_to_chlorination_block(model):
    # Translator inlet from RO and outlet goes to chlorination
    model.fs.RO_to_Chlor = Translator(
        default={
            "inlet_property_package": model.fs.prop_TDS,
            "outlet_property_package": model.fs.ideal_naocl_thermo_params
        })

    # Add constraints to define how the translator will function
    model.fs.RO_to_Chlor.eq_equal_temperature = Constraint(
        expr=model.fs.RO_to_Chlor.inlet.temperature[0] ==
        model.fs.RO_to_Chlor.outlet.temperature[0])
    model.fs.RO_to_Chlor.eq_equal_pressure = Constraint(
        expr=model.fs.RO_to_Chlor.inlet.pressure[0] ==
        model.fs.RO_to_Chlor.outlet.pressure[0])

    model.fs.RO_to_Chlor.total_flow_cons = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.flow_mol[0] ==
        (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'H2O'] /
         18e-3) +
        (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'TDS'] /
         58.4e-3))

    model.fs.RO_to_Chlor.H_con = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "H_+"] == 0)
    model.fs.RO_to_Chlor.OH_con = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "OH_-"] == 0)
    model.fs.RO_to_Chlor.HOCl_con = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "HOCl"] == 0)
    model.fs.RO_to_Chlor.OCl_con = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "OCl_-"] == 0)

    model.fs.RO_to_Chlor.Cl_con = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "Cl_-"] ==
        (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'TDS'] /
         58.4e-3) / model.fs.RO_to_Chlor.outlet.flow_mol[0])

    model.fs.RO_to_Chlor.Na_con = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "Na_+"] ==
        (model.fs.RO_to_Chlor.inlet.flow_mass_phase_comp[0, 'Liq', 'TDS'] /
         58.4e-3) / model.fs.RO_to_Chlor.outlet.flow_mol[0] +
        model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "OCl_-"])

    model.fs.RO_to_Chlor.H2O_con = Constraint(
        expr=model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, "H2O"] == 1 -
        sum(model.fs.RO_to_Chlor.outlet.mole_frac_comp[0, j]
            for j in ["H_+", "OH_-", "HOCl", "OCl_-", "Cl_-", "Na_+"]))

    iscale.calculate_scaling_factors(model.fs.RO_to_Chlor)
예제 #3
0
def test_config():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.properties = PhysicalParameterTestBlock()

    m.fs.unit = Translator(default={
            "inlet_property_package": m.fs.properties,
            "outlet_property_package": m.fs.properties})

    # Check unit config arguments
    assert len(m.fs.unit.config) == 8

    assert not m.fs.unit.config.dynamic
    assert not m.fs.unit.config.has_holdup
    assert m.fs.unit.config.inlet_property_package is m.fs.properties
    assert m.fs.unit.config.outlet_property_package is m.fs.properties
    assert m.fs.unit.config.outlet_state_defined
    assert not m.fs.unit.config.has_phase_equilibrium
예제 #4
0
    def trans(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties1 = SaponificationParameterBlock()
        m.fs.properties2 = BTXParameterBlock()

        m.fs.unit = Translator(
            default={
                "inlet_property_package": m.fs.properties1,
                "outlet_property_package": m.fs.properties2
            })

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

        return m
예제 #5
0
def build_tb(m, base_inlet='ion', base_outlet='TDS', name_str=None):
    """
    Build a translator block to convert for the specified base from inlet to outlet.
    """

    if name_str is None:
        name_str = 'tb_' + base_inlet + '_to_' + base_outlet

    if base_inlet not in ['ion', 'salt']:
        raise ValueError(
            'Unexpected property base inlet {base_inlet} for build_tb'
            ''.format(base_inlet=base_inlet))
    prop_inlet = property_models.get_prop(m, base=base_inlet)

    if base_outlet not in ['TDS']:
        raise ValueError(
            'Unexpected property base outlet {base_outlet} for build_tb'
            ''.format(base_outlet=base_outlet))
    prop_outlet = property_models.get_prop(m, base=base_outlet)

    # build translator block
    setattr(
        m.fs, name_str,
        Translator(
            default={
                "inlet_property_package": prop_inlet,
                "outlet_property_package": prop_outlet
            }))
    blk = getattr(m.fs, name_str)

    # scale translator block to get scaling factors
    calculate_scaling_factors(blk)

    # add translator block constraints
    blk.eq_equal_temperature = Constraint(
        expr=blk.inlet.temperature[0] == blk.outlet.temperature[0])
    constraint_scaling_transform(
        blk.eq_equal_temperature,
        get_scaling_factor(blk.properties_in[0].temperature))
    blk.eq_equal_pressure = Constraint(
        expr=blk.inlet.pressure[0] == blk.outlet.pressure[0])
    constraint_scaling_transform(
        blk.eq_equal_pressure,
        get_scaling_factor(blk.properties_in[0].pressure))

    if base_inlet == 'ion' and base_outlet == 'TDS':
        blk.eq_H2O_balance = Constraint(expr=blk.inlet.flow_mass_phase_comp[
            0, 'Liq', 'H2O'] == blk.outlet.flow_mass_phase_comp[0, 'Liq',
                                                                'H2O'])
        constraint_scaling_transform(
            blk.eq_H2O_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp['Liq', 'H2O']))

        blk.eq_TDS_balance = Constraint(expr=sum(
            blk.inlet.flow_mass_phase_comp[0, 'Liq', j]
            for j in ['Na', 'Ca', 'Mg', 'SO4', 'Cl'
                      ]) == blk.outlet.flow_mass_phase_comp[0, 'Liq', 'TDS'])
        constraint_scaling_transform(
            blk.eq_TDS_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp['Liq', 'TDS']))

    elif base_inlet == 'salt' and base_outlet == 'TDS':
        blk.eq_H2O_balance = Constraint(expr=blk.inlet.flow_mass_phase_comp[
            0, 'Liq', 'H2O'] == blk.outlet.flow_mass_phase_comp[0, 'Liq',
                                                                'H2O'])
        constraint_scaling_transform(
            blk.eq_H2O_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp['Liq', 'H2O']))

        blk.eq_TDS_balance = Constraint(expr=sum(
            blk.inlet.flow_mass_phase_comp[0, 'Liq', j]
            for j in ['NaCl', 'CaSO4', 'MgSO4', 'MgCl2'
                      ]) == blk.outlet.flow_mass_phase_comp[0, 'Liq', 'TDS'])
        constraint_scaling_transform(
            blk.eq_TDS_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp['Liq', 'TDS']))

    else:
        raise ValueError('Unexpected property base combination for build_tb')

    blk.properties_in[0].mass_frac_phase_comp  # touch for initialization
    blk.properties_out[0].mass_frac_phase_comp
예제 #6
0
def build_tb(m, base_inlet="ion", base_outlet="TDS", name_str=None):
    """
    Build a translator block to convert for the specified base from inlet to outlet.
    """

    if name_str is None:
        name_str = "tb_" + base_inlet + "_to_" + base_outlet

    if base_inlet not in ["ion", "salt"]:
        raise ValueError(
            "Unexpected property base inlet {base_inlet} for build_tb"
            "".format(base_inlet=base_inlet))
    prop_inlet = property_models.get_prop(m, base=base_inlet)

    if base_outlet not in ["TDS"]:
        raise ValueError(
            "Unexpected property base outlet {base_outlet} for build_tb"
            "".format(base_outlet=base_outlet))
    prop_outlet = property_models.get_prop(m, base=base_outlet)

    # build translator block
    setattr(
        m.fs,
        name_str,
        Translator(
            default={
                "inlet_property_package": prop_inlet,
                "outlet_property_package": prop_outlet,
            }),
    )
    blk = getattr(m.fs, name_str)

    # scale translator block to get scaling factors
    calculate_scaling_factors(blk)

    # add translator block constraints
    blk.eq_equal_temperature = Constraint(
        expr=blk.inlet.temperature[0] == blk.outlet.temperature[0])
    constraint_scaling_transform(
        blk.eq_equal_temperature,
        get_scaling_factor(blk.properties_in[0].temperature))
    blk.eq_equal_pressure = Constraint(
        expr=blk.inlet.pressure[0] == blk.outlet.pressure[0])
    constraint_scaling_transform(
        blk.eq_equal_pressure,
        get_scaling_factor(blk.properties_in[0].pressure))

    if base_inlet == "ion" and base_outlet == "TDS":
        blk.eq_H2O_balance = Constraint(expr=blk.inlet.flow_mass_phase_comp[
            0, "Liq", "H2O"] == blk.outlet.flow_mass_phase_comp[0, "Liq",
                                                                "H2O"])
        constraint_scaling_transform(
            blk.eq_H2O_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp["Liq", "H2O"]),
        )

        blk.eq_TDS_balance = Constraint(expr=sum(
            blk.inlet.flow_mass_phase_comp[0, "Liq", j]
            for j in ["Na", "Ca", "Mg", "SO4", "Cl"
                      ]) == blk.outlet.flow_mass_phase_comp[0, "Liq", "TDS"])
        constraint_scaling_transform(
            blk.eq_TDS_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp["Liq", "TDS"]),
        )

    elif base_inlet == "salt" and base_outlet == "TDS":
        blk.eq_H2O_balance = Constraint(expr=blk.inlet.flow_mass_phase_comp[
            0, "Liq", "H2O"] == blk.outlet.flow_mass_phase_comp[0, "Liq",
                                                                "H2O"])
        constraint_scaling_transform(
            blk.eq_H2O_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp["Liq", "H2O"]),
        )

        blk.eq_TDS_balance = Constraint(expr=sum(
            blk.inlet.flow_mass_phase_comp[0, "Liq", j]
            for j in ["NaCl", "CaSO4", "MgSO4", "MgCl2"
                      ]) == blk.outlet.flow_mass_phase_comp[0, "Liq", "TDS"])
        constraint_scaling_transform(
            blk.eq_TDS_balance,
            get_scaling_factor(
                blk.properties_out[0].flow_mass_phase_comp["Liq", "TDS"]),
        )

    else:
        raise ValueError("Unexpected property base combination for build_tb")

    blk.properties_in[0].mass_frac_phase_comp  # touch for initialization
    blk.properties_out[0].mass_frac_phase_comp
예제 #7
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