def model(self): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["nonvolatile_toc", "tss"]}) m.fs.unit = CartridgeFiltrationZO(default={ "property_package": m.fs.params, "database": m.db }) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(10) m.fs.unit.inlet.flow_mass_comp[0, "nonvolatile_toc"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "tss"].fix(1) return m
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["sulfur", "toc", "tss"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit1 = CartridgeFiltrationZO(default={ "property_package": m.fs.params, "database": m.db }) m.fs.unit1.inlet.flow_mass_comp[0, "H2O"].fix(10000) m.fs.unit1.inlet.flow_mass_comp[0, "sulfur"].fix(1) m.fs.unit1.inlet.flow_mass_comp[0, "toc"].fix(2) m.fs.unit1.inlet.flow_mass_comp[0, "tss"].fix(3) m.fs.unit1.load_parameters_from_database(use_default_removal=True) assert degrees_of_freedom(m.fs.unit1) == 0 m.fs.unit1.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) assert isinstance(m.fs.costing.cartridge_filtration, Block) assert isinstance(m.fs.costing.cartridge_filtration.capital_a_parameter, Var) assert isinstance(m.fs.costing.cartridge_filtration.capital_b_parameter, Var) assert isinstance(m.fs.costing.cartridge_filtration.reference_state, Var) assert isinstance(m.fs.unit1.costing.capital_cost, Var) assert isinstance(m.fs.unit1.costing.capital_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit1) == 0 assert m.fs.unit1.electricity[0] in m.fs.costing._registered_flows[ "electricity"]
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