def model(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.water_props = WaterParameterBlock( default={"solute_list": ["A", "B", "C"]}) m.fs.unit = DerivedZO(default={"property_package": m.fs.water_props}) m.fs.unit.flow = Param(m.fs.time, initialize=1, units=pyunits.gallon / pyunits.minute) pump_electricity(m.fs.unit, m.fs.unit.flow) return m
def build(self): super().build() self._tech_type = "surface_discharge" build_pt(self) self._Q = Reference(self.properties[:].flow_vol) pump_electricity(self, self._Q) self.pipe_distance = Var(self.flowsheet().config.time, units=pyunits.miles, doc="Piping distance") self.pipe_diameter = Var(self.flowsheet().config.time, units=pyunits.inches, doc="Pipe diameter") self._fixed_perf_vars.append(self.pipe_distance) self._fixed_perf_vars.append(self.pipe_diameter) self._perf_var_dict["Pipe Distance"] = self.pipe_distance self._perf_var_dict["Pipe Diameter"] = self.pipe_diameter
def build(self): super().build() self._tech_type = "ion_exchange" build_sido(self) self._Q = Reference(self.properties_in[:].flow_vol) pump_electricity(self, self._Q) # mutable parameter; default value found in WT3 for anion exchange self.eta_pump.set_value(0.8) # mutable parameter; default value of 2 bar converted to feet head self.lift_height.set_value(69.91052 * pyunits.feet) # Add variables and constraints for material requirements self.NaCl_flowrate = Var( self.flowsheet().time, initialize=1, units=pyunits.kg / pyunits.s, bounds=(0, None), doc="Flowrate of NaCl addition", ) self.NaCl_dose = Var( units=pyunits.kg / pyunits.m**3, bounds=(0, None), doc="Dosage of NaCl addition", ) self._fixed_perf_vars.append(self.NaCl_dose) self._perf_var_dict["NaCl Addition"] = self.NaCl_flowrate @self.Constraint(self.flowsheet().time) def NaCl_constraint(blk, t): return blk.NaCl_flowrate[t] == blk.NaCl_dose * blk.properties_in[t].flow_vol self.resin_demand = Var( self.flowsheet().time, initialize=1, units=pyunits.kg / pyunits.s, bounds=(0, None), doc="Replacement rate of ion exchange resin", ) self.resin_replacement = Var( units=pyunits.kg / pyunits.m**3, bounds=(0, None), doc="Resin replacement as a function of flow", ) self._fixed_perf_vars.append(self.resin_replacement) self._perf_var_dict["Resin Demand"] = self.resin_demand @self.Constraint(self.flowsheet().time) def resin_constraint(blk, t): return ( blk.resin_demand[t] == blk.resin_replacement * blk.properties_in[t].flow_vol ) if self.config.process_subtype == "clinoptilolite": if "ammonium_as_nitrogen" in self.config.property_package.solute_set: self.nitrogen_clay_ratio = Var( self.flowsheet().config.time, units=pyunits.dimensionless, doc="Mass fraction of nitrogen in clay mixture", ) self._fixed_perf_vars.append(self.nitrogen_clay_ratio) self.final_solids_mass = Var( self.flowsheet().config.time, units=pyunits.kg / pyunits.s, doc="Solids mass flow in byproduct stream", ) @self.Constraint( self.flowsheet().time, doc="Solids mass flow in byproduct stream constraint", ) def solids_mass_flow_constraint(b, t): return ( b.final_solids_mass[t] == b.properties_byproduct[t].flow_mass_comp[ "ammonium_as_nitrogen" ] / b.nitrogen_clay_ratio[t] ) self._perf_var_dict[ "Nitrogen-Clay Mixture Ratio (kg/kg)" ] = self.nitrogen_clay_ratio self._perf_var_dict[ "Final mass flow of clay and nitrogen (kg/s)" ] = self.final_solids_mass else: raise KeyError( "ammonium_as_nitrogen should be defined in solute_list for this subtype." )
def build(self): super().build() self._tech_type = "gas_sparged_membrane" self._has_recovery_removal = True self._initialize = initialize_sido self._scaling = calculate_scaling_factors_gas_extraction # Create state blocks for inlet and outlets tmp_dict = dict(**self.config.property_package_args) tmp_dict["has_phase_equilibrium"] = False tmp_dict["defined_state"] = True self.properties_in = self.config.property_package.build_state_block( self.flowsheet().time, doc="Material properties at inlet", default=tmp_dict) tmp_dict_2 = dict(**tmp_dict) tmp_dict_2["defined_state"] = False self.properties_treated = self.config.property_package.build_state_block( self.flowsheet().time, doc="Material properties of treated water", default=tmp_dict_2, ) self.properties_byproduct = self.config.property_package.build_state_block( self.flowsheet().time, doc="Material properties of byproduct stream", default=tmp_dict_2, ) # Create Ports self.add_port("inlet", self.properties_in, doc="Inlet port") self.add_port("treated", self.properties_treated, doc="Treated water outlet port") self.add_port("byproduct", self.properties_byproduct, doc="Byproduct outlet port") # Add performance variables self.recovery_frac_mass_H2O = Var( self.flowsheet().time, initialize=0.8, domain=NonNegativeReals, units=pyunits.dimensionless, bounds=(1e-8, 1.0000001), doc="Mass recovery fraction of water in the treated stream", ) self.removal_frac_mass_solute = Var( self.flowsheet().time, self.config.property_package.solute_set, domain=NonNegativeReals, initialize=0.01, units=pyunits.dimensionless, doc="Solute removal fraction on a mass basis", ) self.gas_mass_influent_ratio = Var( self.flowsheet().time, domain=NonNegativeReals, units=pyunits.dimensionless, doc="Mass flow of gas extracted per mass flow of influent", ) self.flow_mass_gas_extraction = Var( self.flowsheet().time, domain=NonNegativeReals, units=pyunits.kg / pyunits.s, doc="Mass flow of hydrogen extracted", ) self._fixed_perf_vars.append(self.gas_mass_influent_ratio) self._perf_var_dict[ "Mass of gas extracted per mass flow of influent(kg/d/(kg/d)"] = self.gas_mass_influent_ratio self._perf_var_dict[ "Mass flow of gas extracted (kg/s))"] = self.flow_mass_gas_extraction # Add performance constraints # Water recovery @self.Constraint(self.flowsheet().time, doc="Water recovery equation") def water_recovery_equation(b, t): return (b.recovery_frac_mass_H2O[t] * b.properties_in[t].flow_mass_comp["H2O"] == b.properties_treated[t].flow_mass_comp["H2O"]) # Flow balance @self.Constraint(self.flowsheet().time, doc="Overall flow balance") def mass_balance(b, t): return (sum( b.properties_in[t].flow_mass_comp[j] for j in self.config.property_package.component_list) == sum( b.properties_treated[t].flow_mass_comp[j] for j in self.config.property_package.component_list) + sum(b.properties_byproduct[t].flow_mass_comp[j] for j in self.config.property_package.component_list) + b.flow_mass_gas_extraction[t]) # Gas extraction @self.Constraint(self.flowsheet().time, doc="Gas extraction equation") def mass_gas_extraction_equation(b, t): return b.flow_mass_gas_extraction[t] == b.gas_mass_influent_ratio[ t] * sum(b.properties_in[t].flow_mass_comp[j] for j in self.config.property_package.component_list) # Solute removal @self.Constraint( self.flowsheet().time, self.config.property_package.solute_set, doc="Solute removal equations", ) def solute_removal_equation(b, t, j): return (b.removal_frac_mass_solute[t, j] * b.properties_in[t].flow_mass_comp[j] == b.properties_byproduct[t].flow_mass_comp[j]) # Solute concentration of treated stream @self.Constraint( self.flowsheet().time, self.config.property_package.solute_set, doc="Constraint for solute concentration in treated " "stream.", ) def solute_treated_equation(b, t, j): return (1 - b.removal_frac_mass_solute[t, j] ) * b.properties_in[t].flow_mass_comp[ j] == b.properties_treated[t].flow_mass_comp[j] self._stream_table_dict = { "Inlet": self.inlet, "Treated": self.treated, "Byproduct": self.byproduct, } self._perf_var_dict["Water Recovery"] = self.recovery_frac_mass_H2O self._perf_var_dict["Solute Removal"] = self.removal_frac_mass_solute self._get_Q = _get_Q_gas_extraction self._Q = Reference(self.properties_in[:].flow_vol) pump_electricity(self, self._Q)