def test_chem_addition_costing(self, model): model.fs.unit2 = ChemicalAdditionZO(default={ "property_package": model.fs.params, "process_subtype": "alum", "database": model.db}) model.fs.unit2.inlet.flow_mass_comp[0, "H2O"].fix(1000) model.fs.unit2.inlet.flow_mass_comp[0, "sulfur"].fix(1) model.fs.unit2.inlet.flow_mass_comp[0, "toc"].fix(2) model.fs.unit2.inlet.flow_mass_comp[0, "tss"].fix(3) model.fs.unit2.load_parameters_from_database() assert degrees_of_freedom(model.fs.unit2) == 0 model.fs.unit2.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block": model.fs.costing}) assert isinstance( model.fs.costing.chemical_addition, Block) assert isinstance( model.fs.costing.chemical_addition.capital_a_parameter, Var) assert isinstance( model.fs.costing.chemical_addition.capital_b_parameter, Var) assert isinstance(model.fs.unit2.costing.capital_cost, Var) assert isinstance(model.fs.unit2.costing.capital_cost_constraint, Constraint) assert_units_consistent(model.fs) assert degrees_of_freedom(model.fs.unit2) == 0 assert model.fs.unit2.electricity[0] is \ model.fs.costing._registered_flows["electricity"][1] assert pytest.approx(1.006e3*10/0.5, rel=1e-8) == value(pyunits.convert( model.fs.costing._registered_flows["alum"][0], to_units=pyunits.mg/pyunits.s))
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["tss", "sulfate", "foo", "bar"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit = InjectionWellDisposalZO(default={ "property_package": m.fs.params, "database": m.db }) m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(123) m.fs.unit.inlet.flow_mass_comp[0, "tss"].fix(4) m.fs.unit.inlet.flow_mass_comp[0, "sulfate"].fix(0.005) m.fs.unit.inlet.flow_mass_comp[0, "foo"].fix(0.67) m.fs.unit.inlet.flow_mass_comp[0, "bar"].fix(8.9) m.fs.unit.load_parameters_from_database() assert degrees_of_freedom(m.fs.unit) == 0 initialization_tester(m) results = solver.solve(m) assert_optimal_termination(results) assert isinstance(m.fs.costing.injection_well_disposal, Block) assert isinstance(m.fs.costing.injection_well_disposal.capital_a_parameter, Var) assert isinstance(m.fs.costing.injection_well_disposal.capital_b_parameter, Var) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint)
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock(default={"solute_list": ["tss"]}) m.fs.unit = FilterPressZO( default={"property_package": m.fs.params, "database": m.db} ) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "tss"].fix(23) m.fs.costing = ZeroOrderCosting() m.fs.unit.load_parameters_from_database() m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing} ) assert isinstance(m.fs.costing.filter_press, Block) assert isinstance(m.fs.costing.filter_press.capital_a_parameter, Var) assert isinstance(m.fs.costing.filter_press.capital_b_parameter, Var) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0 assert m.fs.unit.electricity[0] in m.fs.costing._registered_flows["electricity"]
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 = PumpElectricityZO( default={"property_package": m.fs.params, "database": m.db} ) m.fs.unit1.inlet.flow_mass_comp[0, "H2O"].fix(1e-5) m.fs.unit1.inlet.flow_mass_comp[0, "sulfur"].fix(10) m.fs.unit1.inlet.flow_mass_comp[0, "toc"].fix(20) m.fs.unit1.inlet.flow_mass_comp[0, "tss"].fix(30) m.fs.unit1.load_parameters_from_database() 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.pump_electricity, Block) assert isinstance(m.fs.costing.pump_electricity.pump_cost, 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 test_nf_costing(self, model): model.fs.unit1 = NanofiltrationZO(default={ "property_package": model.fs.params, "database": model.db}) model.fs.unit1.inlet.flow_mass_comp[0, "H2O"].fix(10000) model.fs.unit1.inlet.flow_mass_comp[0, "sulfur"].fix(1) model.fs.unit1.inlet.flow_mass_comp[0, "toc"].fix(2) model.fs.unit1.inlet.flow_mass_comp[0, "tss"].fix(3) model.fs.unit1.load_parameters_from_database() assert degrees_of_freedom(model.fs.unit1) == 0 model.fs.unit1.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block": model.fs.costing}) assert isinstance(model.fs.costing.nanofiltration, Block) assert isinstance(model.fs.costing.nanofiltration.capital_a_parameter, Var) assert isinstance(model.fs.costing.nanofiltration.capital_b_parameter, Var) assert isinstance(model.fs.costing.nanofiltration.reference_state, Var) assert isinstance(model.fs.unit1.costing.capital_cost, Var) assert isinstance(model.fs.unit1.costing.capital_cost_constraint, Constraint) assert_units_consistent(model.fs) assert degrees_of_freedom(model.fs.unit1) == 0 assert model.fs.unit1.electricity[0] in \ model.fs.costing._registered_flows["electricity"]
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock(default={"solute_list": ["nitrogen"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit = PhotothermalMembraneZO(default={ "property_package": m.fs.params, "database": m.db }) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(120) m.fs.unit.inlet.flow_mass_comp[0, "nitrogen"].fix(1) m.fs.unit.load_parameters_from_database(use_default_removal=True) assert degrees_of_freedom(m.fs.unit) == 0 m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) assert isinstance(m.fs.costing.photothermal_membrane, Block) assert isinstance(m.fs.costing.photothermal_membrane.membrane_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0 initialization_tester(m) assert pytest.approx(4.719596, rel=1e-5) == value(m.fs.unit.costing.capital_cost)
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["nitrogen", "phosphorus", "struvite", "foo"]}) source_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "..", "..", "examples", "flowsheets", "case_studies", "wastewater_resource_recovery", "electrochemical_nutrient_removal", "case_1617.yaml", ) m.fs.costing = ZeroOrderCosting( default={"case_study_definition": source_file}) m.fs.unit = ElectroNPZO(default={ "property_package": m.fs.params, "database": m.db }) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(1000) m.fs.unit.inlet.flow_mass_comp[0, "nitrogen"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "phosphorus"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "struvite"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "foo"].fix(1) m.fs.unit.load_parameters_from_database(use_default_removal=True) assert degrees_of_freedom(m.fs.unit) == 0 m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) assert isinstance(m.fs.costing.electrochemical_nutrient_removal, Block) assert isinstance(m.fs.costing.electrochemical_nutrient_removal.HRT, Var) assert isinstance( m.fs.costing.electrochemical_nutrient_removal.sizing_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0 initialization_tester(m) results = solver.solve(m) assert_optimal_termination(results) assert m.fs.unit.electricity[0] in m.fs.costing._registered_flows[ "electricity"] assert (m.fs.unit.MgCl2_flowrate[0] in m.fs.costing._registered_flows["magnesium_chloride"])
def add_costing(m): source_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "biomembrane_filtration_global_costing.yaml", ) m.fs.costing = ZeroOrderCosting( default={"case_study_definition": source_file}) # typing aid costing_kwargs = {"default": {"flowsheet_costing_block": m.fs.costing}} m.fs.mabr.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.dmbr.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.pump.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.costing.cost_process() m.fs.costing.add_electricity_intensity( m.fs.product_H2O.properties[0].flow_vol) m.fs.costing.add_LCOW(m.fs.product_H2O.properties[0].flow_vol)
def test_costing(subtype): 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 = FixedBedZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype, }) 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.fixed_bed, Block) assert isinstance(m.fs.costing.fixed_bed.capital_a_parameter, Var) assert isinstance(m.fs.costing.fixed_bed.capital_b_parameter, Var) assert isinstance(m.fs.costing.fixed_bed.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"] assert (m.fs.unit1.acetic_acid_demand[0] in m.fs.costing._registered_flows["acetic_acid"]) assert (m.fs.unit1.phosphoric_acid_demand[0] in m.fs.costing._registered_flows["phosphoric_acid"]) assert (m.fs.unit1.ferric_chloride_demand[0] in m.fs.costing._registered_flows["ferric_chloride"]) assert (m.fs.unit1.activated_carbon_demand[0] in m.fs.costing._registered_flows["activated_carbon"]) assert m.fs.unit1.sand_demand[0] in m.fs.costing._registered_flows["sand"] assert (m.fs.unit1.anthracite_demand[0] in m.fs.costing._registered_flows["anthracite"]) assert (m.fs.unit1.cationic_polymer_demand[0] in m.fs.costing._registered_flows["cationic_polymer"])
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["iron", "manganese", "foo"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit1 = IronManganeseRemovalZO(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, "iron"].fix(250) m.fs.unit1.inlet.flow_mass_comp[0, "manganese"].fix(250) m.fs.unit1.inlet.flow_mass_comp[0, "foo"].fix(1) 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.iron_and_manganese_removal, Block) assert isinstance( m.fs.costing.iron_and_manganese_removal.capital_blower_a_parameter, Var) assert isinstance( m.fs.costing.iron_and_manganese_removal.capital_backwash_a_parameter, Var) assert isinstance( m.fs.costing.iron_and_manganese_removal.capital_backwash_b_parameter, Var) assert isinstance( m.fs.costing.iron_and_manganese_removal.capital_filter_a_parameter, Var) assert isinstance( m.fs.costing.iron_and_manganese_removal.capital_filter_b_parameter, Var) assert isinstance(m.fs.costing.iron_and_manganese_removal.flow_exponent, 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 test_costing(subtype): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["sulfur", "toc", "tds"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit1 = IonExchangeZO(default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype}) 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, "tds"].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.ion_exchange, Block) assert isinstance(m.fs.costing.ion_exchange.capital_a_parameter, Var) assert isinstance(m.fs.costing.ion_exchange.capital_b_parameter, Var) assert isinstance(m.fs.costing.ion_exchange.capital_c_parameter, Var) assert isinstance(m.fs.costing.ion_exchange.capital_d_parameter, 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"] assert m.fs.unit1.NaCl_flowrate[0] in \ m.fs.costing._registered_flows["sodium_chloride"] assert m.fs.unit1.resin_demand[0] in \ m.fs.costing._registered_flows["ion_exchange_resin"]
def test_initialize(self, Crystallizer_frame): # Add costing function, then initialize m = Crystallizer_frame m.fs.costing = WaterTAPCosting() m.fs.unit.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "cost_type": CrystallizerCostType.mass_basis }, }, ) m.fs.costing.cost_process() initialization_tester(Crystallizer_frame)
def test_costing_non_default_subtype(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock(default={"solute_list": ["tds", "dye"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit = NanofiltrationZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": "rHGO_dye_rejection", } ) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(10000) m.fs.unit.inlet.flow_mass_comp[0, "tds"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "dye"].fix(2) m.fs.unit.load_parameters_from_database(use_default_removal=True) assert degrees_of_freedom(m.fs.unit) == 0 m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing} ) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) assert isinstance(m.fs.costing.nanofiltration, Block) assert isinstance(m.fs.unit.costing.variable_operating_cost, Var) assert isinstance(m.fs.unit.costing.variable_operating_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0 initialization_tester(m) results = solver.solve(m) # Check for optimal solution assert check_optimal_termination(results) assert pytest.approx(39162.813807, rel=1e-5) == value(m.fs.unit.area) assert pytest.approx(0.58744, rel=1e-5) == value(m.fs.unit.costing.capital_cost) assert pytest.approx(0.088116, rel=1e-5) == value( m.fs.unit.costing.variable_operating_cost )
def test_costing(subtype): 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.unit = LandfillZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype, } ) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(1e-5) m.fs.unit.inlet.flow_mass_comp[0, "sulfur"].fix(1000) m.fs.unit.inlet.flow_mass_comp[0, "toc"].fix(2000) m.fs.unit.inlet.flow_mass_comp[0, "tss"].fix(3000) m.fs.unit.load_parameters_from_database() m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing} ) assert isinstance(m.fs.costing.landfill, Block) assert isinstance(m.fs.costing.landfill.capital_a_parameter, Var) assert isinstance(m.fs.costing.landfill.capital_b_parameter, Var) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0 initialization_tester(m) _ = solver.solve(m) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) if subtype == "default": assert pytest.approx(43.5627, rel=1e-5) == value(m.fs.unit.costing.capital_cost) if subtype == "landfill_zld": assert pytest.approx(20.09155, rel=1e-5) == value( m.fs.unit.costing.capital_cost ) assert m.fs.unit.electricity[0] in m.fs.costing._registered_flows["electricity"]
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={ "solute_list": ["tds", "magnesium", "calcium", "nitrate", "sulfate", "tss"] }) m.fs.costing = ZeroOrderCosting() m.fs.unit = EvaporationPondZO(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, "tds"].fix(123) m.fs.unit.inlet.flow_mass_comp[0, "magnesium"].fix(456) m.fs.unit.inlet.flow_mass_comp[0, "calcium"].fix(789) m.fs.unit.inlet.flow_mass_comp[0, "nitrate"].fix(10) m.fs.unit.inlet.flow_mass_comp[0, "sulfate"].fix(11) m.fs.unit.inlet.flow_mass_comp[0, "tss"].fix(12) m.fs.unit.load_parameters_from_database(use_default_removal=True) m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) assert isinstance(m.fs.costing.evaporation_pond, Block) assert isinstance(m.fs.costing.evaporation_pond.cost_per_acre_a_parameter, Var) assert isinstance(m.fs.costing.evaporation_pond.cost_per_acre_b_parameter, Var) assert isinstance(m.fs.costing.evaporation_pond.cost_per_acre_c_parameter, Var) assert isinstance(m.fs.costing.evaporation_pond.cost_per_acre_d_parameter, Var) assert isinstance(m.fs.costing.evaporation_pond.cost_per_acre_e_parameter, Var) assert isinstance(m.fs.costing.evaporation_pond.liner_thickness, Var) assert isinstance(m.fs.costing.evaporation_pond.land_cost, Var) assert isinstance(m.fs.costing.evaporation_pond.land_clearing_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0
def test_costing(subtype): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["toc", "nitrate", "sulfate", "bar", "crux"]} ) m.fs.costing = ZeroOrderCosting() m.fs.unit = WellFieldZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype, } ) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(120) m.fs.unit.inlet.flow_mass_comp[0, "toc"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "nitrate"].fix(2) m.fs.unit.inlet.flow_mass_comp[0, "sulfate"].fix(0.3) m.fs.unit.inlet.flow_mass_comp[0, "bar"].fix(40) m.fs.unit.inlet.flow_mass_comp[0, "crux"].fix(0.0005) m.fs.unit.load_parameters_from_database() assert degrees_of_freedom(m.fs.unit) == 0 m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing} ) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0 initialization_tester(m) _ = solver.solve(m) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) if subtype == "default": assert pytest.approx(1.665893, rel=1e-5) == value( m.fs.unit.costing.capital_cost ) if subtype == "emwd": assert pytest.approx(47.921893, rel=1e-5) == value( m.fs.unit.costing.capital_cost ) assert m.fs.unit.electricity[0] in m.fs.costing._registered_flows["electricity"]
def test_costing(subtype): print(subtype) 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 = ChemicalAdditionZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype, }) 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.chemical_addition, Block) assert isinstance(m.fs.costing.chemical_addition.capital_a_parameter, Var) assert isinstance(m.fs.costing.chemical_addition.capital_b_parameter, 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"] assert str(m.fs.unit1.chemical_dosage[0] * m.fs.unit1.properties[0].flow_vol / m.fs.unit1.ratio_in_solution) == str( m.fs.costing._registered_flows[subtype][0])
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["viruses_enteric", "toc", "cryptosporidium"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit1 = UVAOPZO(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, "viruses_enteric"].fix(1) m.fs.unit1.inlet.flow_mass_comp[0, "toc"].fix(2) m.fs.unit1.inlet.flow_mass_comp[0, "cryptosporidium"].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.unit1.chemical_flow_mass, Var) assert isinstance(m.fs.costing.uv_aop, Block) assert isinstance(m.fs.costing.uv_aop.uv_capital_a_parameter, Var) assert isinstance(m.fs.costing.uv_aop.uv_capital_b_parameter, Var) assert isinstance(m.fs.costing.uv_aop.uv_capital_c_parameter, Var) assert isinstance(m.fs.costing.uv_aop.uv_capital_d_parameter, Var) assert isinstance(m.fs.costing.uv_aop.aop_capital_a_parameter, Var) assert isinstance(m.fs.costing.uv_aop.aop_capital_b_parameter, 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"] assert str(m.fs.costing._registered_flows["hydrogen_peroxide"][0]) == str( m.fs.unit1.chemical_flow_mass[0])
def test_costing(subtype): 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 = SecondaryTreatmentWWTPZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype, }) 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.secondary_treatment_wwtp, Block) assert isinstance( m.fs.costing.secondary_treatment_wwtp.capital_a_parameter, Var) assert isinstance( m.fs.costing.secondary_treatment_wwtp.capital_b_parameter, Var) assert isinstance(m.fs.costing.secondary_treatment_wwtp.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 test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={ "solute_list": [ "nitrogen", "phosphates", "bioconcentrated_phosphorous", "nitrous_oxide", ] } ) m.fs.costing = ZeroOrderCosting() m.fs.unit = CANDOPZO(default={"property_package": m.fs.params, "database": m.db}) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(120) m.fs.unit.inlet.flow_mass_comp[0, "nitrogen"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "phosphates"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "bioconcentrated_phosphorous"].fix(0) m.fs.unit.inlet.flow_mass_comp[0, "nitrous_oxide"].fix(0) m.fs.unit.load_parameters_from_database(use_default_removal=True) assert degrees_of_freedom(m.fs.unit) == 0 m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing} ) assert isinstance(m.fs.costing.CANDO_P, Block) assert isinstance(m.fs.costing.CANDO_P.sizing_parameter, Var) assert isinstance(m.fs.costing.CANDO_P.sizing_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost, Var) assert isinstance(m.fs.unit.costing.capital_cost_constraint, Constraint) assert_units_consistent(m.fs) assert degrees_of_freedom(m.fs.unit) == 0 initialization_tester(m) assert pytest.approx(42.651167, rel=1e-5) == value(m.fs.unit.costing.capital_cost) assert m.fs.unit.electricity[0] in m.fs.costing._registered_flows["electricity"]
def model(self): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["cod", "methane"]}) source_file = os.path.join( os.path.dirname(os.path.abspath(__file__)), "..", "..", "..", "examples", "flowsheets", "case_studies", "wastewater_resource_recovery", "metab", "metab_global_costing.yaml", ) m.fs.costing = ZeroOrderCosting( default={"case_study_definition": source_file}) m.fs.unit = MetabZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": "methane", }) m.fs.unit.inlet.flow_mass_comp[0, "H2O"].fix(1) m.fs.unit.inlet.flow_mass_comp[0, "cod"].fix(0.01) m.fs.unit.inlet.flow_mass_comp[0, "methane"].fix(0) m.db.get_unit_operation_parameters("metab") m.fs.unit.load_parameters_from_database(use_default_removal=True) m.fs.unit.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) m.fs.costing.cost_process() return m
def test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock( default={"solute_list": ["tds", "toc", "tss"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit1 = ElectrodialysisReversalZO(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, "tds"].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.electrodialysis_reversal, Block) assert isinstance( m.fs.costing.electrodialysis_reversal.capital_a_parameter, Var) assert isinstance( m.fs.costing.electrodialysis_reversal.capital_b_parameter, Var) assert isinstance(m.fs.costing.electrodialysis_reversal.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 test_costing(): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock(default={ "solute_list": ["bod", "tss", "ammonium_as_nitrogen", "nitrate"] }) m.fs.costing = ZeroOrderCosting() m.fs.unit1 = MABRZO(default={ "property_package": m.fs.params, "database": m.db }) m.fs.unit1.inlet.flow_mass_comp[0, "H2O"].fix(10) m.fs.unit1.inlet.flow_mass_comp[0, "bod"].fix(5) m.fs.unit1.inlet.flow_mass_comp[0, "tss"].fix(5) m.fs.unit1.inlet.flow_mass_comp[0, "ammonium_as_nitrogen"].fix(2) m.fs.unit1.inlet.flow_mass_comp[0, "nitrate"].fix(1) 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.mabr, Block) assert isinstance(m.fs.costing.mabr.specific_removal, Var) assert isinstance(m.fs.costing.mabr.reactor_cost, Var) assert isinstance(m.fs.costing.mabr.specific_air_flow, Var) assert isinstance(m.fs.costing.mabr.blower_cost, 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 test_costing(subtype): m = ConcreteModel() m.db = Database() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.params = WaterParameterBlock(default={"solute_list": ["foo"]}) m.fs.costing = ZeroOrderCosting() m.fs.unit1 = WaterPumpingStationZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype, }) m.fs.unit1.inlet.flow_mass_comp[0, "H2O"].fix(10000) m.fs.unit1.inlet.flow_mass_comp[0, "foo"].fix(1) m.fs.unit1.load_parameters_from_database() 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.water_pumping_station, Block) assert isinstance(m.fs.costing.water_pumping_station.capital_a_parameter, Var) assert isinstance(m.fs.costing.water_pumping_station.capital_b_parameter, Var) assert isinstance(m.fs.costing.water_pumping_station.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 test_solution2_volumecosting(self, Crystallizer_frame): # Same problem as above, but different costing approach. # Other results should remain the same. m = Crystallizer_frame b = m.fs.unit b.crystal_growth_rate.fix(5e-8) b.souders_brown_constant.fix(0.0244) b.crystal_median_length.fix(0.4e-3) m.fs.unit.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "cost_type": CrystallizerCostType.volume_basis }, }, ) m.fs.costing.cost_process() results = solver.solve(m) # Test that report function works b.report() # Check for optimal solution assert results.solver.termination_condition == TerminationCondition.optimal assert results.solver.status == SolverStatus.ok # Residence time assert pytest.approx( value(b.crystal_median_length / (3.67 * 3600 * b.crystal_growth_rate)), rel=1e-3, ) == value(b.t_res) # Check crystallizer diameter assert pytest.approx(1.5427, rel=1e-3) == value(b.diameter_crystallizer) # Minimum active volume assert pytest.approx(0.959, rel=1e-3) == value(b.volume_suspension) # Volume-basis costing assert pytest.approx(199000, rel=1e-3) == value( m.fs.costing.total_capital_cost)
def test_costing(subtype): 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 = StorageTankZO( default={ "property_package": m.fs.params, "database": m.db, "process_subtype": subtype, }) 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.storage_tank, Block) assert isinstance(m.fs.costing.storage_tank.capital_a_parameter, Var) assert isinstance(m.fs.costing.storage_tank.capital_b_parameter, 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
def build(): # flowsheet set up m = ConcreteModel() m.fs = FlowsheetBlock(default={'dynamic': False}) m.fs.properties = props.NaClParameterBlock() m.fs.costing = WaterTAPCosting() # unit models m.fs.feed = Feed(default={'property_package': m.fs.properties}) m.fs.S1 = Separator(default={ "property_package": m.fs.properties, "outlet_list": ['P1', 'PXR'] }) m.fs.P1 = Pump(default={'property_package': m.fs.properties}) m.fs.PXR = PressureExchanger(default={'property_package': m.fs.properties}) m.fs.P2 = Pump(default={'property_package': m.fs.properties}) m.fs.M1 = Mixer( default={ "property_package": m.fs.properties, "momentum_mixing_type": MomentumMixingType.equality, # booster pump will match pressure "inlet_list": ['P1', 'P2'] }) m.fs.RO = ReverseOsmosis0D( default={ "property_package": m.fs.properties, "has_pressure_change": True, "pressure_change_type": PressureChangeType.calculated, "mass_transfer_coefficient": MassTransferCoefficient.calculated, "concentration_polarization_type": ConcentrationPolarizationType.calculated, }) m.fs.product = Product(default={'property_package': m.fs.properties}) m.fs.disposal = Product(default={'property_package': m.fs.properties}) # costing m.fs.costing.cost_flow( pyunits.convert(m.fs.P1.work_mechanical[0], to_units=pyunits.kW), "electricity") m.fs.costing.cost_flow( pyunits.convert(m.fs.P2.work_mechanical[0], to_units=pyunits.kW), "electricity") m.fs.P1.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) m.fs.P2.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) m.fs.RO.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) m.fs.PXR.costing = UnitModelCostingBlock( default={"flowsheet_costing_block": m.fs.costing}) m.fs.costing.cost_process() m.fs.costing.add_LCOW(m.fs.product.properties[0].flow_vol) m.fs.costing.add_specific_energy_consumption( m.fs.product.properties[0].flow_vol) # connections m.fs.s01 = Arc(source=m.fs.feed.outlet, destination=m.fs.S1.inlet) m.fs.s02 = Arc(source=m.fs.S1.P1, destination=m.fs.P1.inlet) m.fs.s03 = Arc(source=m.fs.P1.outlet, destination=m.fs.M1.P1) m.fs.s04 = Arc(source=m.fs.M1.outlet, destination=m.fs.RO.inlet) m.fs.s05 = Arc(source=m.fs.RO.permeate, destination=m.fs.product.inlet) m.fs.s06 = Arc(source=m.fs.RO.retentate, destination=m.fs.PXR.high_pressure_inlet) m.fs.s07 = Arc(source=m.fs.PXR.high_pressure_outlet, destination=m.fs.disposal.inlet) m.fs.s08 = Arc(source=m.fs.S1.PXR, destination=m.fs.PXR.low_pressure_inlet) m.fs.s09 = Arc(source=m.fs.PXR.low_pressure_outlet, destination=m.fs.P2.inlet) m.fs.s10 = Arc(source=m.fs.P2.outlet, destination=m.fs.M1.P2) TransformationFactory("network.expand_arcs").apply_to(m) # scaling # set default property values 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', 'NaCl')) # set unit model values iscale.set_scaling_factor(m.fs.P1.control_volume.work, 1e-3) iscale.set_scaling_factor(m.fs.P2.control_volume.work, 1e-3) iscale.set_scaling_factor(m.fs.PXR.low_pressure_side.work, 1e-3) iscale.set_scaling_factor(m.fs.PXR.high_pressure_side.work, 1e-3) # touch properties used in specifying and initializing the model m.fs.feed.properties[0].flow_vol_phase['Liq'] m.fs.feed.properties[0].mass_frac_phase_comp['Liq', 'NaCl'] m.fs.S1.mixed_state[0].mass_frac_phase_comp m.fs.S1.PXR_state[0].flow_vol_phase['Liq'] # unused scaling factors needed by IDAES base costing module # calculate and propagate scaling factors iscale.calculate_scaling_factors(m) return m
def build_costing(m, costing_package=WaterTAPCosting, **kwargs): """Add costing to a given flowsheet Args: m: model costing_package : FlowsheetCostingBlock """ # call get_costing for each unit model m.fs.costing = costing_package() # the full_treatment_train uses a lower than default value # for factor_maintenance_labor_chemical m.fs.costing.factor_maintenance_labor_chemical.fix(0.02) crf = m.fs.costing.factor_capital_annualization # Nanofiltration if hasattr(m.fs, "NF"): if kwargs["NF_type"] == "ZO": m.fs.NF.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, }) elif kwargs["NF_type"] == "Sep": raise NotImplementedError( "get_costing will not be implemented for the NF separator model." ) if hasattr(m.fs, "pump_NF"): m.fs.pump_NF.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "pump_type": PumpType.low_pressure }, }) # Reverse Osmosis if hasattr(m.fs, "RO"): if kwargs["RO_type"] == "0D" or kwargs["RO_type"] == "1D": m.fs.RO.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, }) elif kwargs["RO_type"] == "Sep": raise NotImplementedError( "get_costing will not be implemented for the RO separator model." ) # Stage 2 RO if hasattr(m.fs, "RO2"): m.fs.RO2.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "ro_type": ROType.high_pressure }, }) # Pump if hasattr(m.fs, "pump_RO"): m.fs.pump_RO.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "pump_type": PumpType.high_pressure }, }) # Stage 2 pump if hasattr(m.fs, "pump_RO2"): m.fs.pump_RO2.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "pump_type": PumpType.high_pressure }, }) # ERD if hasattr(m.fs, "ERD"): m.fs.ERD.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "energy_recovery_device_type": EnergyRecoveryDeviceType.pressure_exchanger }, }) # Pretreatment if hasattr(m.fs, "stoich_softening_mixer_unit"): m.fs.stoich_softening_mixer_unit.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "mixer_type": MixerType.CaOH2, "dosing_rate": m.fs.stoich_softening_mixer_unit.dosing_rate, }, }) # Post-treatment if hasattr(m.fs, "ideal_naocl_mixer_unit"): # print('FOUND CHLORINATION UNIT') m.fs.ideal_naocl_mixer_unit.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "mixer_type": MixerType.NaOCl, "dosing_rate": m.fs.ideal_naocl_mixer_unit.dosing_rate, }, }) if hasattr(m.fs, "mixer_permeate"): m.fs.mixer_permeate.costing = UnitModelCostingBlock( default={ "flowsheet_costing_block": m.fs.costing, "costing_method_arguments": { "mixer_type": MixerType.default }, }) # call get_system_costing for whole flowsheet m.fs.costing.cost_process() m.fs.costing.add_annual_water_production(m.fs.treated_flow_vol) m.fs.costing.add_LCOW(m.fs.treated_flow_vol) if hasattr(m.fs, "stoich_softening_mixer_unit"): m.fs.lime_softening_unit_capex = Expression( expr=m.fs.stoich_softening_mixer_unit.costing.capital_cost / m.fs.costing.annual_water_production * crf) else: m.fs.lime_softening_unit_capex = Expression(expr=0) if hasattr(m.fs, "ideal_naocl_mixer_unit"): m.fs.chlorination_unit_capex = Expression( expr=m.fs.ideal_naocl_mixer_unit.costing.capital_cost / m.fs.costing.annual_water_production * crf) else: m.fs.chlorination_unit_capex = Expression(expr=0) # apply scaling to cost variables and constraints scale_costing(m)
def build(number_of_stages=2): # ---building model--- m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = props.NaClParameterBlock() m.fs.costing = WaterTAPCosting() m.fs.NumberOfStages = Param(initialize=number_of_stages) m.fs.StageSet = RangeSet(m.fs.NumberOfStages) m.fs.LSRRO_StageSet = RangeSet(2, m.fs.NumberOfStages) m.fs.NonFinal_StageSet = RangeSet(m.fs.NumberOfStages-1) m.fs.feed = Feed(default={'property_package': m.fs.properties}) m.fs.product = Product(default={'property_package': m.fs.properties}) m.fs.disposal = Product(default={'property_package': m.fs.properties}) # Add the mixers m.fs.Mixers = Mixer(m.fs.NonFinal_StageSet, default={ "property_package": m.fs.properties, "momentum_mixing_type": MomentumMixingType.equality, # booster pump will match pressure "inlet_list": ['upstream', 'downstream']}) total_pump_work = 0 # Add the pumps m.fs.PrimaryPumps = Pump(m.fs.StageSet, default={"property_package": m.fs.properties}) for pump in m.fs.PrimaryPumps.values(): pump.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block":m.fs.costing}) m.fs.costing.cost_flow(pyunits.convert(pump.work_mechanical[0], to_units=pyunits.kW), "electricity") # Add the equalizer pumps m.fs.BoosterPumps = Pump(m.fs.LSRRO_StageSet, default={"property_package": m.fs.properties}) for pump in m.fs.BoosterPumps.values(): pump.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block":m.fs.costing}) m.fs.costing.cost_flow(pyunits.convert(pump.work_mechanical[0], to_units=pyunits.kW), "electricity") # Add the stages ROs m.fs.ROUnits = ReverseOsmosis0D(m.fs.StageSet, default={ "property_package": m.fs.properties, "has_pressure_change": True, "pressure_change_type": PressureChangeType.calculated, "mass_transfer_coefficient": MassTransferCoefficient.calculated, "concentration_polarization_type": ConcentrationPolarizationType.calculated}) for ro_unit in m.fs.ROUnits.values(): ro_unit.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block":m.fs.costing}) # Add EnergyRecoveryDevice m.fs.EnergyRecoveryDevice = Pump(default={"property_package": m.fs.properties}) m.fs.EnergyRecoveryDevice.costing = UnitModelCostingBlock(default={ "flowsheet_costing_block":m.fs.costing, "costing_method_arguments":{"pump_type":PumpType.energy_recovery_device}}) m.fs.costing.cost_flow(pyunits.convert(m.fs.EnergyRecoveryDevice.work_mechanical[0], to_units=pyunits.kW), "electricity") # additional variables or expressions # system water recovery m.fs.water_recovery = Var( initialize=0.5, bounds=(0, 1), domain=NonNegativeReals, units=pyunits.dimensionless, doc='System Water Recovery') m.fs.eq_water_recovery = Constraint(expr=\ sum(m.fs.feed.flow_mass_phase_comp[0,'Liq',:]) * m.fs.water_recovery == \ sum(m.fs.product.flow_mass_phase_comp[0,'Liq',:]) ) # costing m.fs.costing.cost_process() product_flow_vol_total = m.fs.product.properties[0].flow_vol m.fs.costing.add_LCOW(product_flow_vol_total) m.fs.costing.add_specific_energy_consumption(product_flow_vol_total) # objective m.fs.objective = Objective(expr=m.fs.costing.LCOW) # connections # Connect the feed to the first pump m.fs.feed_to_pump = Arc(source=m.fs.feed.outlet, destination=m.fs.PrimaryPumps[1].inlet) # Connect the primary RO permeate to the product m.fs.primary_RO_to_product = Arc(source=m.fs.ROUnits[1].permeate, destination=m.fs.product.inlet) # Connect the Pump n to the Mixer n m.fs.pump_to_mixer = Arc(m.fs.NonFinal_StageSet, rule=lambda fs,n : {'source':fs.PrimaryPumps[n].outlet, 'destination':fs.Mixers[n].upstream}) # Connect the Mixer n to the Stage n m.fs.mixer_to_stage = Arc(m.fs.NonFinal_StageSet, rule=lambda fs,n : {'source':fs.Mixers[n].outlet, 'destination':fs.ROUnits[n].inlet}) # Connect the Stage n to the Pump n+1 m.fs.stage_to_pump = Arc(m.fs.NonFinal_StageSet, rule=lambda fs,n : {'source':fs.ROUnits[n].retentate, 'destination':fs.PrimaryPumps[n+1].inlet}) # Connect the Stage n to the Eq Pump n m.fs.stage_to_eq_pump = Arc(m.fs.LSRRO_StageSet, rule=lambda fs,n : {'source':fs.ROUnits[n].permeate, 'destination':fs.BoosterPumps[n].inlet}) # Connect the Eq Pump n to the Mixer n-1 m.fs.eq_pump_to_mixer = Arc(m.fs.LSRRO_StageSet, rule=lambda fs,n : {'source':fs.BoosterPumps[n].outlet, 'destination':fs.Mixers[n-1].downstream}) # Connect the Pump N to the Stage N last_stage = m.fs.StageSet.last() m.fs.pump_to_stage = Arc(source=m.fs.PrimaryPumps[last_stage].outlet, destination=m.fs.ROUnits[last_stage].inlet) # Connect Final Stage to EnergyRecoveryDevice Pump m.fs.stage_to_erd = Arc(source=m.fs.ROUnits[last_stage].retentate, destination=m.fs.EnergyRecoveryDevice.inlet) # Connect the EnergyRecoveryDevice to the disposal m.fs.erd_to_disposal = Arc(source=m.fs.EnergyRecoveryDevice.outlet, destination=m.fs.disposal.inlet) # additional bounding for b in m.component_data_objects(Block, descend_into=True): # NaCl solubility limit if hasattr(b, 'mass_frac_phase_comp'): b.mass_frac_phase_comp['Liq', 'NaCl'].setub(0.26) TransformationFactory("network.expand_arcs").apply_to(m) return m
def add_costing(m): m.fs.costing = ZeroOrderCosting() # typing aid costing_kwargs = {"default": {"flowsheet_costing_block": m.fs.costing}} m.fs.intake_pump.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.coag_and_floc.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.sedimentation.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.ozonation.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.gravity_basin.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.gac.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.backwash_pump.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.uv.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.anion_exchange.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.chlorination.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.storage.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.recharge_pump.costing = UnitModelCostingBlock(**costing_kwargs) m.fs.costing.cost_process() m.fs.costing.add_electricity_intensity(m.fs.product.properties[0].flow_vol) m.fs.costing.add_LCOW(m.fs.product.properties[0].flow_vol)