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
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)
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
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
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
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
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