コード例 #1
0
    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
コード例 #2
0
    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
コード例 #3
0
    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."
                )
コード例 #4
0
    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)