Ejemplo n.º 1
0
    def test_build(self, iron_oc):
        assert hasattr(iron_oc.fs.unit, "gas_inlet")
        assert len(iron_oc.fs.unit.gas_inlet.vars) == 4
        assert isinstance(iron_oc.fs.unit.gas_inlet.flow_mol, Var)
        assert isinstance(iron_oc.fs.unit.gas_inlet.mole_frac_comp, Var)
        assert isinstance(iron_oc.fs.unit.gas_inlet.temperature, Var)
        assert isinstance(iron_oc.fs.unit.gas_inlet.pressure, Var)

        assert hasattr(iron_oc.fs.unit, "solid_inlet")
        assert len(iron_oc.fs.unit.solid_inlet.vars) == 4
        assert isinstance(iron_oc.fs.unit.solid_inlet.flow_mass, Var)
        assert isinstance(iron_oc.fs.unit.solid_inlet.particle_porosity, Var)
        assert isinstance(iron_oc.fs.unit.solid_inlet.mass_frac_comp, Var)
        assert isinstance(iron_oc.fs.unit.solid_inlet.temperature, Var)

        assert hasattr(iron_oc.fs.unit, "gas_outlet")
        assert len(iron_oc.fs.unit.gas_outlet.vars) == 4
        assert isinstance(iron_oc.fs.unit.gas_outlet.flow_mol, Var)
        assert isinstance(iron_oc.fs.unit.gas_outlet.mole_frac_comp, Var)
        assert isinstance(iron_oc.fs.unit.gas_outlet.temperature, Var)
        assert isinstance(iron_oc.fs.unit.gas_outlet.pressure, Var)

        assert hasattr(iron_oc.fs.unit, "solid_outlet")
        assert len(iron_oc.fs.unit.solid_outlet.vars) == 4
        assert isinstance(iron_oc.fs.unit.solid_outlet.flow_mass, Var)
        assert isinstance(iron_oc.fs.unit.solid_outlet.particle_porosity, Var)
        assert isinstance(iron_oc.fs.unit.solid_outlet.mass_frac_comp, Var)
        assert isinstance(iron_oc.fs.unit.solid_outlet.temperature, Var)

        assert isinstance(iron_oc.fs.unit.isothermal_gas_phase, Constraint)
        assert isinstance(iron_oc.fs.unit.isothermal_solid_phase, Constraint)

        assert number_variables(iron_oc) == 589
        assert number_total_constraints(iron_oc) == 513
        assert number_unused_variables(iron_oc) == 55
        print(unused_variables_set(iron_oc))
Ejemplo n.º 2
0
    def test_build(self, iapws):
        assert len(iapws.fs.unit.inlet_1.vars) == 3
        assert hasattr(iapws.fs.unit.inlet_1, "flow_mol")
        assert hasattr(iapws.fs.unit.inlet_1, "enth_mol")
        assert hasattr(iapws.fs.unit.inlet_1, "pressure")

        assert hasattr(iapws.fs.unit, "outlet_1")
        assert len(iapws.fs.unit.outlet_1.vars) == 3
        assert hasattr(iapws.fs.unit.outlet_1, "flow_mol")
        assert hasattr(iapws.fs.unit.outlet_1, "enth_mol")
        assert hasattr(iapws.fs.unit.outlet_1, "pressure")

        assert len(iapws.fs.unit.inlet_2.vars) == 3
        assert hasattr(iapws.fs.unit.inlet_2, "flow_mol")
        assert hasattr(iapws.fs.unit.inlet_2, "enth_mol")
        assert hasattr(iapws.fs.unit.inlet_2, "pressure")

        assert hasattr(iapws.fs.unit, "outlet_2")
        assert len(iapws.fs.unit.outlet_2.vars) == 3
        assert hasattr(iapws.fs.unit.outlet_2, "flow_mol")
        assert hasattr(iapws.fs.unit.outlet_2, "enth_mol")
        assert hasattr(iapws.fs.unit.outlet_2, "pressure")

        assert isinstance(iapws.fs.unit.overall_heat_transfer_coefficient, Var)
        assert isinstance(iapws.fs.unit.area, Var)
        assert not hasattr(iapws.fs.unit, "crossflow_factor")
        assert isinstance(iapws.fs.unit.heat_duty, Var)
        assert isinstance(iapws.fs.unit.delta_temperature_in, Var)
        assert isinstance(iapws.fs.unit.delta_temperature_out, Var)
        assert isinstance(iapws.fs.unit.unit_heat_balance, Constraint)
        assert isinstance(iapws.fs.unit.delta_temperature, (Expression, Var))
        assert isinstance(iapws.fs.unit.heat_transfer_equation, Constraint)

        assert number_variables(iapws) == 18
        assert number_total_constraints(iapws) == 10
        assert number_unused_variables(iapws) == 0
Ejemplo n.º 3
0
    def test_build(self, NF_frame):
        m = NF_frame

        # test ports and variables
        port_lst = ["inlet", "retentate", "permeate"]
        port_vars_lst = ["flow_mass_phase_comp", "pressure", "temperature"]
        for port_str in port_lst:
            assert hasattr(m.fs.unit, port_str)
            port = getattr(m.fs.unit, port_str)
            assert len(port.vars) == 3
            assert isinstance(port, Port)
            for var_str in port_vars_lst:
                assert hasattr(port, var_str)
                var = getattr(port, var_str)
                assert isinstance(var, Var)

        # test unit objects (including parameters, variables, and constraints)
        unit_objs_lst = [
            "A_comp",
            "B_comp",
            "sigma",
            "dens_solvent",
            "flux_mass_phase_comp_in",
            "flux_mass_phase_comp_out",
            "avg_conc_mass_phase_comp_in",
            "avg_conc_mass_phase_comp_out",
            "area",
            "deltaP",
            "mass_transfer_phase_comp",
            "flux_mass_phase_comp_avg",
            "eq_mass_transfer_term",
            "eq_permeate_production",
            "eq_flux_in",
            "eq_flux_out",
            "eq_avg_conc_in",
            "eq_avg_conc_out",
            "eq_connect_mass_transfer",
            "eq_connect_enthalpy_transfer",
            "eq_permeate_isothermal",
        ]
        for obj_str in unit_objs_lst:
            assert hasattr(m.fs.unit, obj_str)

        # test state block objects
        cv_name = "feed_side"
        cv_stateblock_lst = ["properties_in", "properties_out"]
        stateblock_objs_lst = [
            "flow_mass_phase_comp",
            "pressure",
            "temperature",
            "pressure_osm",
            "osm_coeff",
            "mass_frac_phase_comp",
            "conc_mass_phase_comp",
            "dens_mass_phase",
            "enth_mass_phase",
            "eq_pressure_osm",
            "eq_osm_coeff",
            "eq_mass_frac_phase_comp",
            "eq_conc_mass_phase_comp",
            "eq_dens_mass_phase",
            "eq_enth_mass_phase",
        ]
        # control volume
        assert hasattr(m.fs.unit, cv_name)
        cv_blk = getattr(m.fs.unit, cv_name)
        for blk_str in cv_stateblock_lst:
            assert hasattr(cv_blk, blk_str)
            blk = getattr(cv_blk, blk_str)
            for obj_str in stateblock_objs_lst:
                assert hasattr(blk[0], obj_str)
        # permeate
        assert hasattr(m.fs.unit, "properties_permeate")
        blk = getattr(m.fs.unit, "properties_permeate")
        for var_str in stateblock_objs_lst:
            assert hasattr(blk[0], var_str)

        # test statistics
        assert number_variables(m) == 73
        assert number_total_constraints(m) == 45
        assert number_unused_variables(
            m) == 7  # vars from property package parameters
Ejemplo n.º 4
0
def test_build():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={'dynamic': False})
    m.fs.properties = props.SeawaterParameterBlock()
    m.fs.unit = PressureExchanger(
        default={'property_package': m.fs.properties})

    # test ports and state variables
    port_lst = [
        'low_pressure_inlet', 'low_pressure_outlet', 'high_pressure_inlet',
        'high_pressure_outlet'
    ]
    port_vars_lst = ['flow_mass_phase_comp', 'pressure', 'temperature']
    for port_str in port_lst:
        assert hasattr(m.fs.unit, port_str)
        port = getattr(m.fs.unit, port_str)
        assert len(port.vars) == 3
        assert isinstance(port, Port)
        for var_str in port_vars_lst:
            assert hasattr(port, var_str)
            var = getattr(port, var_str)
            assert isinstance(var, Var)

    # test unit variables
    assert hasattr(m.fs.unit, 'efficiency_pressure_exchanger')
    assert isinstance(m.fs.unit.efficiency_pressure_exchanger, Var)

    # test unit constraints
    unit_cons_lst = [
        'eq_pressure_transfer', 'eq_equal_flow_vol', 'eq_equal_low_pressure'
    ]
    for c in unit_cons_lst:
        assert hasattr(m.fs.unit, c)
        con = getattr(m.fs.unit, c)
        assert isinstance(con, Constraint)

    # test control volumes, only terms directly used by pressure exchanger
    cv_list = ['low_pressure_side', 'high_pressure_side']
    cv_var_lst = ['deltaP']
    cv_con_lst = ['eq_isothermal_temperature']
    cv_exp_lst = ['work']
    for cv_str in cv_list:
        assert hasattr(m.fs.unit, cv_str)
        cv = getattr(m.fs.unit, cv_str)
        for cv_var_str in cv_var_lst:
            cv_var = getattr(cv, cv_var_str)
            assert isinstance(cv_var, Var)
        for cv_con_str in cv_con_lst:
            cv_con = getattr(cv, cv_con_str)
            assert isinstance(cv_con, Constraint)
        for cv_exp_str in cv_exp_lst:
            cv_exp = getattr(cv, cv_exp_str)
            assert isinstance(cv_exp, Expression)

    # test state blocks, only terms directly used by pressure exchanger
    cv_stateblock_lst = ['properties_in', 'properties_out']
    stateblock_var_lst = ['pressure', 'temperature']
    stateblock_exp_lst = ['flow_vol']
    for cv_str in cv_list:
        cv = getattr(m.fs.unit, cv_str)
        for cv_sb_str in cv_stateblock_lst:
            assert hasattr(cv, cv_sb_str)
            cv_sb = getattr(cv, cv_sb_str)
            for sb_var_str in stateblock_var_lst:
                assert hasattr(cv_sb[0], sb_var_str)
                sb_var = getattr(cv_sb[0], sb_var_str)
                assert isinstance(sb_var, Var)
            for sb_exp_str in stateblock_exp_lst:
                assert hasattr(cv_sb[0], sb_exp_str)
                sb_exp = getattr(cv_sb[0], sb_exp_str)
                assert isinstance(sb_exp, Expression)

    # test statistics
    assert number_variables(m.fs.unit) == 39
    assert number_total_constraints(m.fs.unit) == 31
    assert number_unused_variables(m.fs.unit) == 0
Ejemplo n.º 5
0
    def test_build(self, Crystallizer_frame):
        m = Crystallizer_frame

        # test ports and variables
        port_lst = ["inlet", "outlet", "solids", "vapor"]
        port_vars_lst = ["flow_mass_phase_comp", "pressure", "temperature"]
        for port_str in port_lst:
            assert hasattr(m.fs.unit, port_str)
            port = getattr(m.fs.unit, port_str)
            assert len(port.vars) == 3
            assert isinstance(port, Port)
            for var_str in port_vars_lst:
                assert hasattr(port, var_str)
                var = getattr(port, var_str)
                assert isinstance(var, Var)

        # test unit objects (including parameters, variables, and constraints)
        # First, parameters
        unit_objs_params_lst = [
            "approach_temperature_heat_exchanger",
            "dimensionless_crystal_length",
        ]
        for obj_str in unit_objs_params_lst:
            assert hasattr(m.fs.unit, obj_str)
        # Next, variables
        unit_objs_vars_lst = [
            "crystal_growth_rate",
            "crystal_median_length",
            "crystallization_yield",
            "dens_mass_magma",
            "dens_mass_slurry",
            "diameter_crystallizer",
            "height_crystallizer",
            "height_slurry",
            "magma_circulation_flow_vol",
            "pressure_operating",
            "product_volumetric_solids_fraction",
            "relative_supersaturation",
            "souders_brown_constant",
            "t_res",
            "temperature_operating",
            "volume_suspension",
            "work_mechanical",
        ]
        for obj_str in unit_objs_vars_lst:
            assert hasattr(m.fs.unit, obj_str)
        # Next, expressions
        unit_objs_expr_lst = [
            "eq_max_allowable_velocity",
            "eq_minimum_height_diameter_ratio",
            "eq_vapor_space_height",
        ]
        for obj_str in unit_objs_expr_lst:
            assert hasattr(m.fs.unit, obj_str)
        # Finally, constraints
        unit_objs_cons_lst = [
            "eq_T_con1",
            "eq_T_con2",
            "eq_T_con3",
            "eq_crystallizer_height_constraint",
            "eq_dens_magma",
            "eq_dens_mass_slurry",
            "eq_enthalpy_balance",
            "eq_mass_balance_constraints",
            "eq_minimum_hex_circulation_rate_constraint",
            "eq_operating_pressure_constraint",
            "eq_p_con1",
            "eq_p_con2",
            "eq_p_con3",
            "eq_relative_supersaturation",
            "eq_removal_balance",
            "eq_residence_time",
            "eq_slurry_height_constraint",
            "eq_solubility_massfrac_equality_constraint",
            "eq_suspension_volume",
            "eq_vapor_head_diameter_constraint",
            "eq_vol_fraction_solids",
        ]
        for obj_str in unit_objs_cons_lst:
            assert hasattr(m.fs.unit, obj_str)

        # Test stateblocks
        # List olf attributes on all stateblocks
        stateblock_objs_lst = [
            "flow_mass_phase_comp",
            "pressure",
            "temperature",
            "solubility_mass_phase_comp",
            "solubility_mass_frac_phase_comp",
            "mass_frac_phase_comp",
            "dens_mass_solvent",
            "dens_mass_solute",
            "dens_mass_phase",
            "cp_phase",
            "cp_solvent",
            "flow_vol_phase",
            "flow_vol",
            "enth_flow",
            "enth_mass_solvent",
            "dh_crystallization",
            "eq_solubility_mass_phase_comp",
            "eq_solubility_mass_frac_phase_comp",
            "eq_mass_frac_phase_comp",
            "eq_dens_mass_solvent",
            "eq_dens_mass_solute",
            "eq_dens_mass_phase",
            "eq_cp_solute",
            "eq_cp_phase",
            "eq_flow_vol_phase",
            "eq_enth_mass_solvent",
        ]
        # List of attributes for liquid stateblocks only
        stateblock_objs_liq_lst = ["pressure_sat", "eq_pressure_sat"]
        # Inlet block
        assert hasattr(m.fs.unit, "properties_in")
        blk = getattr(m.fs.unit, "properties_in")
        for var_str in stateblock_objs_lst:
            assert hasattr(blk[0], var_str)
        for var_str in stateblock_objs_liq_lst:
            assert hasattr(blk[0], var_str)

        # Liquid outlet block
        assert hasattr(m.fs.unit, "properties_out")
        blk = getattr(m.fs.unit, "properties_out")
        for var_str in stateblock_objs_lst:
            assert hasattr(blk[0], var_str)
        for var_str in stateblock_objs_liq_lst:
            assert hasattr(blk[0], var_str)

        # Vapor outlet block
        assert hasattr(m.fs.unit, "properties_vapor")
        blk = getattr(m.fs.unit, "properties_vapor")
        for var_str in stateblock_objs_lst:
            assert hasattr(blk[0], var_str)

        # Liquid outlet block
        assert hasattr(m.fs.unit, "properties_solids")
        blk = getattr(m.fs.unit, "properties_solids")
        for var_str in stateblock_objs_lst:
            assert hasattr(blk[0], var_str)

        # test statistics
        assert number_variables(m) == 238
        assert number_total_constraints(m) == 124
        assert number_unused_variables(m) == 4
Ejemplo n.º 6
0
    def report(self, time_point=0, dof=False, ostream=None, prefix=""):

        time_point = float(time_point)

        if ostream is None:
            ostream = sys.stdout

        # Get DoF and model stats
        if dof:
            dof_stat = degrees_of_freedom(self)
            nv = number_variables(self)
            nc = number_activated_constraints(self)
            nb = number_activated_blocks(self)

        # Get components to report in performance section
        performance = self._get_performance_contents(time_point=time_point)

        # Get stream table
        stream_table = self._get_stream_table_contents(time_point=time_point)

        # Set model type output
        if hasattr(self, "is_flowsheet") and self.is_flowsheet:
            model_type = "Flowsheet"
        else:
            model_type = "Unit"

        # Write output
        max_str_length = 84
        tab = " " * 4
        ostream.write("\n" + "=" * max_str_length + "\n")

        lead_str = f"{prefix}{model_type} : {self.name}"
        trail_str = f"Time: {time_point}"
        mid_str = " " * (max_str_length - len(lead_str) - len(trail_str))
        ostream.write(lead_str + mid_str + trail_str)

        if dof:
            ostream.write("\n" + "=" * max_str_length + "\n")
            ostream.write(f"{prefix}{tab}Local Degrees of Freedom: {dof_stat}")
            ostream.write('\n')
            ostream.write(f"{prefix}{tab}Total Variables: {nv}{tab}"
                          f"Activated Constraints: {nc}{tab}"
                          f"Activated Blocks: {nb}")

        if performance is not None:
            ostream.write("\n" + "-" * max_str_length + "\n")
            ostream.write(f"{prefix}{tab}Unit Performance")
            ostream.write("\n" * 2)
            if "vars" in performance.keys() and len(performance["vars"]) > 0:
                ostream.write(f"{prefix}{tab}Variables: \n\n")

                tabular_writer(
                    ostream, prefix + tab,
                    ((k, v) for k, v in performance["vars"].items()),
                    ("Value", "Fixed", "Bounds"), lambda k, v:
                    ["{:#.5g}".format(value(v)), v.fixed, v.bounds])

            if "exprs" in performance.keys() and len(performance["exprs"]) > 0:
                ostream.write("\n")
                ostream.write(f"{prefix}{tab}Expressions: \n\n")

                tabular_writer(ostream, prefix + tab,
                               ((k, v)
                                for k, v in performance["exprs"].items()),
                               ("Value", ),
                               lambda k, v: ["{:#.5g}".format(value(v))])

            if ("params" in performance.keys()
                    and len(performance["params"]) > 0):
                ostream.write("\n")
                ostream.write(f"{prefix}{tab}Parameters: \n\n")

                tabular_writer(ostream, prefix + tab,
                               ((k, v)
                                for k, v in performance["params"].items()),
                               ("Value", "Mutable"),
                               lambda k, v: [value(v), not v.is_constant()])

        if stream_table is not None:
            ostream.write("\n" + "-" * max_str_length + "\n")
            ostream.write(f"{prefix}{tab}Stream Table")
            ostream.write('\n')
            ostream.write(
                textwrap.indent(stream_table_dataframe_to_string(stream_table),
                                prefix + tab))
        ostream.write("\n" + "=" * max_str_length + "\n")
Ejemplo n.º 7
0
    def test_statistics(self, frame):
        m = frame

        assert number_variables(m) == 38
        assert number_total_constraints(m) == 16
        assert number_unused_variables(m) == 1  # pressure is unused
    def test_build(self, RO_frame):
        m = RO_frame

        # test ports
        port_lst = ["inlet", "retentate", "permeate"]
        for port_str in port_lst:
            port = getattr(m.fs.unit, port_str)
            assert (len(port.vars) == 3
                    )  # number of state variables for NaCl property package
            assert isinstance(port, Port)

        # test pyomo objects on unit
        unit_objs_type_dict = {
            "dens_solvent": Param,
            "A_comp": Var,
            "B_comp": Var,
            "flux_mass_phase_comp": Var,
            "area": Var,
            "recovery_vol_phase": Var,
            "recovery_mass_phase_comp": Var,
            "rejection_phase_comp": Var,
            "deltaP": Var,
            "cp_modulus": Var,
            "mass_transfer_phase_comp": Var,
            "flux_mass_phase_comp_avg": Expression,
            "over_pressure_ratio": Expression,
            "eq_mass_transfer_term": Constraint,
            "eq_permeate_production": Constraint,
            "eq_flux_mass": Constraint,
            "eq_connect_mass_transfer": Constraint,
            "eq_connect_enthalpy_transfer": Constraint,
            "eq_permeate_isothermal": Constraint,
            "eq_recovery_vol_phase": Constraint,
            "eq_recovery_mass_phase_comp": Constraint,
            "eq_rejection_phase_comp": Constraint,
            "eq_mass_frac_permeate": Constraint,
            "eq_permeate_outlet_isothermal": Constraint,
            "eq_permeate_outlet_isobaric": Constraint,
            "eq_flow_vol_permeate": Constraint,
            "nfe": Param,
        }
        for (obj_str, obj_type) in unit_objs_type_dict.items():
            obj = getattr(m.fs.unit, obj_str)
            assert isinstance(obj, obj_type)
        # check that all added unit objects are tested
        for obj in m.fs.unit.component_objects(
            [Param, Var, Expression, Constraint], descend_into=False):
            obj_str = obj.local_name
            if obj_str[0] == "_":
                continue  # do not test hidden references
            assert obj_str in unit_objs_type_dict

        # test feed-side control volume and associated stateblocks
        assert isinstance(m.fs.unit.feed_side, ControlVolume0DBlock)
        cv_stateblock_lst = [
            "properties_in",
            "properties_out",
            "properties_interface",
        ]
        for sb_str in cv_stateblock_lst:
            sb = getattr(m.fs.unit.feed_side, sb_str)
            assert isinstance(sb, props.NaClStateBlock)
        # test objects added to control volume
        cv_objs_type_dict = {
            "eq_concentration_polarization": Constraint,
            "eq_equal_temp_interface": Constraint,
            "eq_equal_pressure_interface": Constraint,
            "eq_equal_flow_vol_interface": Constraint,
        }
        for (obj_str, obj_type) in cv_objs_type_dict.items():
            obj = getattr(m.fs.unit.feed_side, obj_str)
            assert isinstance(obj, obj_type)

        # test statistics
        assert number_variables(m) == 125
        assert number_total_constraints(m) == 96
        assert number_unused_variables(
            m) == 7  # vars from property package parameters
Ejemplo n.º 9
0
    def test_build(self, btx_ftpz, btx_fctp):
        # General build
        assert hasattr(btx_ftpz.fs.unit, "material_mixing_equations")
        assert hasattr(btx_ftpz.fs.unit, "enthalpy_mixing_equations")
        assert hasattr(btx_ftpz.fs.unit, "pressure_drop_equation")

        assert btx_ftpz.fs.unit.config.has_heat_transfer
        assert hasattr(btx_ftpz.fs.unit, "heat_duty")

        assert btx_ftpz.fs.unit.config.has_pressure_change
        assert hasattr(btx_ftpz.fs.unit, "deltaP")

        # State blocks
        assert hasattr(btx_ftpz.fs.unit, "properties_in_liq")
        assert hasattr(btx_ftpz.fs.unit, "properties_in_vap")
        assert hasattr(btx_ftpz.fs.unit, "properties_out")

        # Ports
        assert hasattr(btx_ftpz.fs.unit, "liq_in")
        assert hasattr(btx_ftpz.fs.unit.liq_in, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.liq_in, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.liq_in, "temperature")
        assert hasattr(btx_ftpz.fs.unit.liq_in, "pressure")

        assert hasattr(btx_ftpz.fs.unit, "vap_in")
        assert hasattr(btx_ftpz.fs.unit.vap_in, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.vap_in, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.vap_in, "temperature")
        assert hasattr(btx_ftpz.fs.unit.vap_in, "pressure")

        assert hasattr(btx_ftpz.fs.unit, "liq_out")
        assert hasattr(btx_ftpz.fs.unit.liq_out, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.liq_out, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.liq_out, "temperature")
        assert hasattr(btx_ftpz.fs.unit.liq_out, "pressure")

        assert hasattr(btx_ftpz.fs.unit, "vap_out")
        assert hasattr(btx_ftpz.fs.unit.vap_out, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.vap_out, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.vap_out, "temperature")
        assert hasattr(btx_ftpz.fs.unit.vap_out, "pressure")

        assert not hasattr(btx_ftpz.fs.unit, "feed")

        assert not hasattr(btx_ftpz.fs.unit, "liq_side_draw")
        assert not hasattr(btx_ftpz.fs.unit, "liq_side_sf")

        assert not hasattr(btx_ftpz.fs.unit, "vap_side_draw")
        assert not hasattr(btx_ftpz.fs.unit, "vap_side_sf")

        assert number_variables(btx_ftpz.fs.unit) == 71
        assert number_total_constraints(btx_ftpz.fs.unit) == 59
        assert number_unused_variables(btx_ftpz) == 0

        # General build
        assert hasattr(btx_fctp.fs.unit, "material_mixing_equations")
        assert hasattr(btx_fctp.fs.unit, "enthalpy_mixing_equations")
        assert hasattr(btx_fctp.fs.unit, "pressure_drop_equation")

        assert btx_fctp.fs.unit.config.has_heat_transfer
        assert hasattr(btx_fctp.fs.unit, "heat_duty")

        assert btx_fctp.fs.unit.config.has_pressure_change
        assert hasattr(btx_fctp.fs.unit, "deltaP")

        # State blocks
        assert hasattr(btx_fctp.fs.unit, "properties_in_liq")
        assert hasattr(btx_fctp.fs.unit, "properties_in_vap")
        assert hasattr(btx_fctp.fs.unit, "properties_out")

        # Ports
        assert hasattr(btx_fctp.fs.unit, "liq_in")
        assert hasattr(btx_fctp.fs.unit.liq_in, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.liq_in, "temperature")
        assert hasattr(btx_fctp.fs.unit.liq_in, "pressure")

        assert hasattr(btx_fctp.fs.unit, "vap_in")
        assert hasattr(btx_fctp.fs.unit.vap_in, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.vap_in, "temperature")
        assert hasattr(btx_fctp.fs.unit.vap_in, "pressure")

        assert hasattr(btx_fctp.fs.unit, "liq_out")
        assert hasattr(btx_fctp.fs.unit.liq_out, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.liq_out, "temperature")
        assert hasattr(btx_fctp.fs.unit.liq_out, "pressure")

        assert hasattr(btx_fctp.fs.unit, "vap_out")
        assert hasattr(btx_fctp.fs.unit.vap_out, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.vap_out, "temperature")
        assert hasattr(btx_fctp.fs.unit.vap_out, "pressure")

        assert not hasattr(btx_fctp.fs.unit, "feed")

        assert not hasattr(btx_fctp.fs.unit, "liq_side_draw")
        assert not hasattr(btx_fctp.fs.unit, "liq_side_sf")

        assert not hasattr(btx_fctp.fs.unit, "vap_side_draw")
        assert not hasattr(btx_fctp.fs.unit, "vap_side_sf")

        assert number_variables(btx_fctp.fs.unit) == 74
        assert number_total_constraints(btx_fctp.fs.unit) == 64
        assert number_unused_variables(btx_fctp) == 0
Ejemplo n.º 10
0
    def test_Pdrop_fixed_per_unit_length(self):
        """ Testing 0D-RO with PressureChangeType.fixed_per_unit_length option.
        """
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

        m.fs.unit = ReverseOsmosis0D(default={
            "property_package": m.fs.properties,
            "has_pressure_change": True,
            "concentration_polarization_type": ConcentrationPolarizationType.calculated,
            "mass_transfer_coefficient": MassTransferCoefficient.calculated,
            "pressure_change_type": PressureChangeType.fixed_per_unit_length})

        # fully specify system
        feed_flow_mass = 1
        feed_mass_frac_NaCl = 0.035
        feed_mass_frac_H2O = 1 - feed_mass_frac_NaCl
        feed_pressure = 50e5
        feed_temperature = 273.15 + 25
        membrane_area = 50
        length = 20
        A = 4.2e-12
        B = 3.5e-8
        pressure_atmospheric = 101325
        membrane_pressure_drop = 3e5

        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'NaCl'].fix(
            feed_flow_mass * feed_mass_frac_NaCl)
        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'H2O'].fix(
            feed_flow_mass * feed_mass_frac_H2O)
        m.fs.unit.inlet.pressure[0].fix(feed_pressure)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.area.fix(membrane_area)
        m.fs.unit.A_comp.fix(A)
        m.fs.unit.B_comp.fix(B)
        m.fs.unit.permeate.pressure[0].fix(pressure_atmospheric)

        m.fs.unit.channel_height.fix(0.002)
        m.fs.unit.spacer_porosity.fix(0.75)
        m.fs.unit.length.fix(length)
        m.fs.unit.dP_dx.fix(-membrane_pressure_drop / length)

        # test statistics
        assert number_variables(m) == 142
        assert number_total_constraints(m) == 112
        assert number_unused_variables(m) == 0

        # test degrees of freedom
        assert degrees_of_freedom(m) == 0

        # test scaling
        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'))

        calculate_scaling_factors(m)

        # check that all variables have scaling factors.
        # TODO: see aforementioned TODO on revisiting scaling and associated testing for property models.
        unscaled_var_list = list(unscaled_variables_generator(m.fs.unit, include_fixed=True))
        assert len(unscaled_var_list) == 0

        # test initialization
        initialization_tester(m, fail_on_warning=True)

        # test variable scaling
        badly_scaled_var_lst = list(badly_scaled_var_generator(m))
        assert badly_scaled_var_lst == []

        # test solve
        results = solver.solve(m, tee=True)

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert (pytest.approx(-3.000e5, rel=1e-3) == value(m.fs.unit.deltaP[0]))
        assert (pytest.approx(4.562e-3, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.593e-6, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.2281, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'H2O']))
        assert (pytest.approx(7.963e-5, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(41.96, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0,0.].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(46.57, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(49.94, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 1.].conc_mass_phase_comp['Liq', 'NaCl']))
Ejemplo n.º 11
0
    def test_CP_calculation_with_kf_fixed(self):
        """ Testing 0D-RO with ConcentrationPolarizationType.calculated option enabled.
        This option makes use of an alternative constraint for the feed-side, membrane-interface concentration.
        Additionally, two more variables are created when this option is enabled: Kf - feed-channel
        mass transfer coefficients at the channel inlet and outlet.
        """
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

        m.fs.unit = ReverseOsmosis0D(default={
            "property_package": m.fs.properties,
            "has_pressure_change": True,
            "concentration_polarization_type": ConcentrationPolarizationType.calculated,
            "mass_transfer_coefficient": MassTransferCoefficient.fixed})

        # fully specify system
        feed_flow_mass = 1
        feed_mass_frac_NaCl = 0.035
        feed_pressure = 50e5
        feed_temperature = 273.15 + 25
        membrane_pressure_drop = 3e5
        membrane_area = 50
        A = 4.2e-12
        B = 3.5e-8
        pressure_atmospheric = 101325
        kf = 2e-5

        feed_mass_frac_H2O = 1 - feed_mass_frac_NaCl
        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'NaCl'].fix(
            feed_flow_mass * feed_mass_frac_NaCl)
        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'H2O'].fix(
            feed_flow_mass * feed_mass_frac_H2O)
        m.fs.unit.inlet.pressure[0].fix(feed_pressure)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.deltaP.fix(-membrane_pressure_drop)
        m.fs.unit.area.fix(membrane_area)
        m.fs.unit.A_comp.fix(A)
        m.fs.unit.B_comp.fix(B)
        m.fs.unit.permeate.pressure[0].fix(pressure_atmospheric)
        m.fs.unit.Kf[0, 0., 'NaCl'].fix(kf)
        m.fs.unit.Kf[0, 1., 'NaCl'].fix(kf)

        # test statistics
        assert number_variables(m) == 125
        assert number_total_constraints(m) == 96
        assert number_unused_variables(m) == 7  # vars from property package parameters

        # test degrees of freedom
        assert degrees_of_freedom(m) == 0

        # test scaling
        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'))
        calculate_scaling_factors(m)

        # check that all variables have scaling factors.
        # TODO: Setting the "include_fixed" arg as True reveals
        #  unscaled vars that weren't being accounted for previously. However, calling the whole block (i.e.,
        #  m) shows that several NaCl property parameters are unscaled. For now, we are just interested in ensuring
        #  unit variables are scaled (hence, calling m.fs.unit) but might need to revisit scaling and associated
        #  testing for property models.

        unscaled_var_list = list(unscaled_variables_generator(m.fs.unit, include_fixed=True))
        assert len(unscaled_var_list) == 0

        # # test initialization
        initialization_tester(m, fail_on_warning=True)

        # test variable scaling
        badly_scaled_var_lst = list(badly_scaled_var_generator(m))
        assert badly_scaled_var_lst == []

        # test solve
        results = solver.solve(m)

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert (pytest.approx(3.815e-3, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.668e-6, rel=1e-3) ==
                value(m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.1908, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'H2O']))
        assert (pytest.approx(8.337e-5, rel=1e-3) ==
                value(m.fs.unit.mixed_permeate[0].flow_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(46.07, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 0.].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(44.34, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(50.20, rel=1e-3) ==
                value(m.fs.unit.feed_side.properties_interface[0, 1.].conc_mass_phase_comp['Liq', 'NaCl']))
Ejemplo n.º 12
0
    def test_build(self, RO_frame):
        m = RO_frame

        # test ports
        port_lst = ['inlet', 'retentate', 'permeate']
        for port_str in port_lst:
            port = getattr(m.fs.unit, port_str)
            assert len(port.vars) == 3  # number of state variables for NaCl property package
            assert isinstance(port, Port)

        # test pyomo objects on unit
        unit_objs_type_dict = {'dens_solvent': Param,
                               'A_comp': Var,
                               'B_comp': Var,
                               'flux_mass_phase_comp': Var,
                               'area': Var,
                               'recovery_vol_phase': Var,
                               'recovery_mass_phase_comp': Var,
                               'rejection_phase_comp': Var,
                               'deltaP': Var,
                               'cp_modulus': Var,
                               'mass_transfer_phase_comp': Var,
                               'flux_mass_phase_comp_avg': Expression,
                               'over_pressure_ratio': Expression,
                               'eq_mass_transfer_term': Constraint,
                               'eq_permeate_production': Constraint,
                               'eq_flux_mass': Constraint,
                               'eq_connect_mass_transfer': Constraint,
                               'eq_connect_enthalpy_transfer': Constraint,
                               'eq_permeate_isothermal': Constraint,
                               'eq_recovery_vol_phase': Constraint,
                               'eq_recovery_mass_phase_comp': Constraint,
                               'eq_rejection_phase_comp': Constraint,
                               'eq_mass_frac_permeate': Constraint,
                               'eq_permeate_outlet_isothermal': Constraint,
                               'eq_permeate_outlet_isobaric': Constraint,
                               'eq_flow_vol_permeate': Constraint,
                               'nfe': Param,
                               }
        for (obj_str, obj_type) in unit_objs_type_dict.items():
            obj = getattr(m.fs.unit, obj_str)
            assert isinstance(obj, obj_type)
        # check that all added unit objects are tested
        for obj in m.fs.unit.component_objects(
                [Param, Var, Expression, Constraint], descend_into=False):
            obj_str = obj.local_name
            if obj_str[0] == '_':
                continue  # do not test hidden references
            assert obj_str in unit_objs_type_dict

        # test feed-side control volume and associated stateblocks
        assert isinstance(m.fs.unit.feed_side, ControlVolume0DBlock)
        cv_stateblock_lst = ['properties_in', 'properties_out',
                             'properties_interface',]
        for sb_str in cv_stateblock_lst:
            sb = getattr(m.fs.unit.feed_side, sb_str)
            assert isinstance(sb, props.NaClStateBlock)
        # test objects added to control volume
        cv_objs_type_dict = {'eq_concentration_polarization': Constraint,
                             'eq_equal_temp_interface': Constraint,
                             'eq_equal_pressure_interface': Constraint,
                             'eq_equal_flow_vol_interface': Constraint}
        for (obj_str, obj_type) in cv_objs_type_dict.items():
            obj = getattr(m.fs.unit.feed_side, obj_str)
            assert isinstance(obj, obj_type)

        # test statistics
        assert number_variables(m) == 125
        assert number_total_constraints(m) == 96
        assert number_unused_variables(m) == 7  # vars from property package parameters
Ejemplo n.º 13
0
 def test_stats(self, chlorination_obj):
     model = chlorination_obj
     assert (number_variables(model) == 278)
     assert (number_total_constraints(model) == 99)
     assert (number_unused_variables(model) == 43)
Ejemplo n.º 14
0
    def test_Pdrop_calculation(self):
        """Testing 0D-RO with PressureChangeType.calculated option."""
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

        m.fs.unit = ReverseOsmosis0D(
            default={
                "property_package": m.fs.properties,
                "has_pressure_change": True,
                "concentration_polarization_type":
                ConcentrationPolarizationType.calculated,
                "mass_transfer_coefficient":
                MassTransferCoefficient.calculated,
                "pressure_change_type": PressureChangeType.calculated,
            })

        # fully specify system
        feed_flow_mass = 1 / 3.6
        feed_mass_frac_NaCl = 0.035
        feed_mass_frac_H2O = 1 - feed_mass_frac_NaCl
        feed_pressure = 70e5
        feed_temperature = 273.15 + 25
        membrane_area = 19
        A = 4.2e-12
        B = 3.5e-8
        pressure_atmospheric = 101325

        m.fs.unit.inlet.flow_mass_phase_comp[0, "Liq", "NaCl"].fix(
            feed_flow_mass * feed_mass_frac_NaCl)
        m.fs.unit.inlet.flow_mass_phase_comp[0, "Liq", "H2O"].fix(
            feed_flow_mass * feed_mass_frac_H2O)
        m.fs.unit.inlet.pressure[0].fix(feed_pressure)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.area.fix(membrane_area)
        m.fs.unit.A_comp.fix(A)
        m.fs.unit.B_comp.fix(B)
        m.fs.unit.permeate.pressure[0].fix(pressure_atmospheric)
        m.fs.unit.channel_height.fix(0.001)
        m.fs.unit.spacer_porosity.fix(0.97)
        m.fs.unit.length.fix(16)

        # test statistics
        assert number_variables(m) == 147
        assert number_total_constraints(m) == 118
        assert number_unused_variables(
            m) == 0  # vars from property package parameters

        # test degrees of freedom
        assert degrees_of_freedom(m) == 0

        # test scaling
        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"))

        calculate_scaling_factors(m)

        # check that all variables have scaling factors.
        # TODO: see aforementioned TODO on revisiting scaling and associated testing for property models.
        unscaled_var_list = list(
            unscaled_variables_generator(m.fs.unit, include_fixed=True))
        assert len(unscaled_var_list) == 0

        # test initialization
        initialization_tester(m, fail_on_warning=True)

        # test variable scaling
        badly_scaled_var_lst = list(badly_scaled_var_generator(m))
        assert badly_scaled_var_lst == []

        # test solve
        results = solver.solve(m, tee=True)

        # Check for optimal solution
        assert_optimal_termination(results)

        # test solution
        assert pytest.approx(-1.661e5, rel=1e-3) == value(m.fs.unit.deltaP[0])
        assert pytest.approx(-1.038e4, rel=1e-3) == value(m.fs.unit.deltaP[0] /
                                                          m.fs.unit.length)
        assert pytest.approx(395.8, rel=1e-3) == value(m.fs.unit.N_Re[0, 0.0])
        assert pytest.approx(0.2361,
                             rel=1e-3) == value(m.fs.unit.velocity[0, 0.0])
        assert pytest.approx(191.1, rel=1e-3) == value(m.fs.unit.N_Re[0, 1.0])
        assert pytest.approx(0.1187,
                             rel=1e-3) == value(m.fs.unit.velocity[0, 1.0])
        assert pytest.approx(7.089e-3, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, "Liq", "H2O"])
        assert pytest.approx(2.188e-6, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, "Liq", "NaCl"])
        assert pytest.approx(0.1347, rel=1e-3) == value(
            m.fs.unit.mixed_permeate[0].flow_mass_phase_comp["Liq", "H2O"])
        assert pytest.approx(4.157e-5, rel=1e-3) == value(
            m.fs.unit.mixed_permeate[0].flow_mass_phase_comp["Liq", "NaCl"])
        assert pytest.approx(50.08, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface[
                0, 0.0].conc_mass_phase_comp["Liq", "NaCl"])
        assert pytest.approx(70.80, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp["Liq",
                                                                       "NaCl"])
        assert pytest.approx(76.32, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface[
                0, 1.0].conc_mass_phase_comp["Liq", "NaCl"])
Ejemplo n.º 15
0
    def report(self,
               index=(0),
               true_state=False,
               dof=False,
               ostream=None,
               prefix=""):
        """
        Default report method for StateBlocks. Returns a Block report populated
        with either the display or state variables defined in the
        StateBlockData class.

        Args:
            index : tuple of Block indices indicating which point in time (and
                    space if applicable) to report state at.
            true_state : whether to report the display variables (False
                    default) or the actual state variables (True)
            dof : whether to show local degrees of freedom in the report
                    (default=False)
            ostream : output stream to write report to
            prefix : string to append to the beginning of all output lines

        Returns:
            Printed output to ostream
        """

        if ostream is None:
            ostream = sys.stdout

        # Get DoF and model stats
        if dof:
            dof_stat = degrees_of_freedom(self[index])
            nv = number_variables(self[index])
            nc = number_activated_constraints(self[index])
            nb = number_activated_blocks(self[index])

        # Create stream table
        if true_state:
            disp_dict = self[index].define_state_vars()
        else:
            disp_dict = self[index].define_display_vars()

        stream_attributes = {}

        for k in disp_dict:
            for i in disp_dict[k]:
                if i is None:
                    stream_attributes[k] = disp_dict[k][i]
                else:
                    stream_attributes[k + " " + i] = disp_dict[k][i]

        # Write output
        max_str_length = 84
        tab = " " * 4
        ostream.write("\n" + "=" * max_str_length + "\n")

        lead_str = f"{prefix}State : {self.name}"
        trail_str = f"Index: {index}"
        mid_str = " " * (max_str_length - len(lead_str) - len(trail_str))
        ostream.write(lead_str + mid_str + trail_str)

        if dof:
            ostream.write("\n" + "=" * max_str_length + "\n")
            ostream.write(f"{prefix}{tab}Local Degrees of Freedom: {dof_stat}")
            ostream.write('\n')
            ostream.write(f"{prefix}{tab}Total Variables: {nv}{tab}"
                          f"Activated Constraints: {nc}{tab}"
                          f"Activated Blocks: {nb}")

        ostream.write("\n" + "-" * max_str_length + "\n")
        ostream.write(f"{prefix}{tab}State Report")

        if any(isinstance(v, _VarData) for k, v in stream_attributes.items()):
            ostream.write("\n" * 2)
            ostream.write(f"{prefix}{tab}Variables: \n\n")
            tabular_writer(
                ostream, prefix + tab,
                ((k, v) for k, v in stream_attributes.items()
                 if isinstance(v, _VarData)), ("Value", "Fixed", "Bounds"),
                lambda k, v: ["{:#.5g}".format(value(v)), v.fixed, v.bounds])

        if any(
                isinstance(v, _ExpressionData)
                for k, v in stream_attributes.items()):
            ostream.write("\n" * 2)
            ostream.write(f"{prefix}{tab}Expressions: \n\n")
            tabular_writer(ostream, prefix + tab,
                           ((k, v) for k, v in stream_attributes.items()
                            if isinstance(v, _ExpressionData)), ("Value", ),
                           lambda k, v: ["{:#.5g}".format(value(v))])

        ostream.write("\n" + "=" * max_str_length + "\n")
 def test_stats_inherent(self, inherent_reactions_config):
     model = inherent_reactions_config
     assert (number_variables(model) == 281)
     assert (number_total_constraints(model) == 72)
Ejemplo n.º 17
0
 def test_stats_stoich(self, water_stoich):
     m = water_stoich
     assert number_variables(m) == 123
     assert number_total_constraints(m) == 54
     assert number_unused_variables(m) == 59
 def test_stats_equilibrium(self, equilibrium_reactions_config):
     model = equilibrium_reactions_config
     assert (number_variables(model) == 233)
     assert (number_total_constraints(model) == 72)
Ejemplo n.º 19
0
    def test_build(self, btx_ftpz, btx_fctp):
        assert hasattr(btx_ftpz.fs.unit, "reflux_ratio")
        assert not hasattr(btx_ftpz.fs.unit, "eq_total_cond_spec")

        assert hasattr(btx_ftpz.fs.unit, "inlet")

        assert hasattr(btx_ftpz.fs.unit.inlet, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.inlet, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.inlet, "temperature")
        assert hasattr(btx_ftpz.fs.unit.inlet, "pressure")

        assert hasattr(btx_ftpz.fs.unit, "reflux")

        assert hasattr(btx_ftpz.fs.unit.reflux, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.reflux, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.reflux, "temperature")
        assert hasattr(btx_ftpz.fs.unit.reflux, "pressure")

        assert hasattr(btx_ftpz.fs.unit, "distillate")
        assert hasattr(btx_ftpz.fs.unit.distillate, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.distillate, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.distillate, "temperature")
        assert hasattr(btx_ftpz.fs.unit.distillate, "pressure")

        assert hasattr(btx_ftpz.fs.unit, "vapor_outlet")
        assert hasattr(btx_ftpz.fs.unit.vapor_outlet, "flow_mol")
        assert hasattr(btx_ftpz.fs.unit.vapor_outlet, "mole_frac_comp")
        assert hasattr(btx_ftpz.fs.unit.vapor_outlet, "temperature")
        assert hasattr(btx_ftpz.fs.unit.vapor_outlet, "pressure")

        assert number_variables(btx_ftpz.fs.unit) == 48
        assert number_total_constraints(btx_ftpz.fs.unit) == 40
        assert number_unused_variables(btx_ftpz) == 1

        assert hasattr(btx_fctp.fs.unit, "reflux_ratio")
        assert not hasattr(btx_fctp.fs.unit, "eq_total_cond_spec")

        assert hasattr(btx_fctp.fs.unit, "inlet")

        assert hasattr(btx_fctp.fs.unit.inlet, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.inlet, "temperature")
        assert hasattr(btx_fctp.fs.unit.inlet, "pressure")

        assert hasattr(btx_fctp.fs.unit, "reflux")

        assert hasattr(btx_fctp.fs.unit.reflux, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.reflux, "temperature")
        assert hasattr(btx_fctp.fs.unit.reflux, "pressure")

        assert hasattr(btx_fctp.fs.unit, "distillate")
        assert hasattr(btx_fctp.fs.unit.distillate, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.distillate, "temperature")
        assert hasattr(btx_fctp.fs.unit.distillate, "pressure")

        assert hasattr(btx_fctp.fs.unit, "vapor_outlet")
        assert hasattr(btx_fctp.fs.unit.vapor_outlet, "flow_mol_comp")
        assert hasattr(btx_fctp.fs.unit.vapor_outlet, "temperature")
        assert hasattr(btx_fctp.fs.unit.vapor_outlet, "pressure")

        assert number_variables(btx_fctp.fs.unit) == 50
        assert number_total_constraints(btx_fctp.fs.unit) == 43
        assert number_unused_variables(btx_fctp) == 1
Ejemplo n.º 20
0
    def test_Pdrop_calculation(self):
        """ Testing 0D-RO with PressureChangeType.calculated option.
        """
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={"dynamic": False})

        m.fs.properties = props.NaClParameterBlock()

        m.fs.unit = ReverseOsmosis0D(
            default={
                "property_package": m.fs.properties,
                "has_pressure_change": True,
                "concentration_polarization_type":
                ConcentrationPolarizationType.calculated,
                "mass_transfer_coefficient":
                MassTransferCoefficient.calculated,
                "pressure_change_type": PressureChangeType.calculated
            })

        # fully specify system
        feed_flow_mass = 1
        feed_mass_frac_NaCl = 0.035
        feed_mass_frac_H2O = 1 - feed_mass_frac_NaCl
        feed_pressure = 50e5
        feed_temperature = 273.15 + 25
        membrane_area = 50
        length = 20
        A = 4.2e-12
        B = 3.5e-8
        pressure_atmospheric = 101325

        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'NaCl'].fix(
            feed_flow_mass * feed_mass_frac_NaCl)
        m.fs.unit.inlet.flow_mass_phase_comp[0, 'Liq', 'H2O'].fix(
            feed_flow_mass * feed_mass_frac_H2O)
        m.fs.unit.inlet.pressure[0].fix(feed_pressure)
        m.fs.unit.inlet.temperature[0].fix(feed_temperature)
        m.fs.unit.area.fix(membrane_area)
        m.fs.unit.A_comp.fix(A)
        m.fs.unit.B_comp.fix(B)
        m.fs.unit.permeate.pressure[0].fix(pressure_atmospheric)

        m.fs.unit.channel_height.fix(0.002)
        m.fs.unit.spacer_porosity.fix(0.75)
        m.fs.unit.length.fix(length)

        # test statistics
        assert number_variables(m) == 115
        assert number_total_constraints(m) == 86
        assert number_unused_variables(
            m) == 0  # vars from property package parameters

        # test degrees of freedom
        assert degrees_of_freedom(m) == 0

        # test scaling
        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'))

        calculate_scaling_factors(m)

        # check that all variables have scaling factors.
        # TODO: see aforementioned TODO on revisiting scaling and associated testing for property models.
        unscaled_var_list = list(
            unscaled_variables_generator(m.fs.unit, include_fixed=True))
        assert len(unscaled_var_list) == 0

        # check that all constraints have been scaled
        unscaled_constraint_list = list(unscaled_constraints_generator(m))
        assert len(unscaled_constraint_list) == 0

        # test initialization
        initialization_tester(m)

        # test variable scaling
        badly_scaled_var_lst = list(badly_scaled_var_generator(m))
        assert badly_scaled_var_lst == []

        # test solve
        solver.options = {'nlp_scaling_method': 'user-scaling'}
        results = solver.solve(m, tee=True)

        # Check for optimal solution
        assert results.solver.termination_condition == \
               TerminationCondition.optimal
        assert results.solver.status == SolverStatus.ok

        # test solution
        assert (pytest.approx(-9.173e5,
                              rel=1e-3) == value(m.fs.unit.deltaP[0]))
        assert (pytest.approx(1.904e-3, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'H2O']))
        assert (pytest.approx(1.727e-6, rel=1e-3) == value(
            m.fs.unit.flux_mass_phase_comp_avg[0, 'Liq', 'NaCl']))
        assert (pytest.approx(0.0952, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].flow_mass_phase_comp['Liq',
                                                                  'H2O']))
        assert (pytest.approx(8.637e-5, rel=1e-3) == value(
            m.fs.unit.properties_permeate[0].flow_mass_phase_comp['Liq',
                                                                  'NaCl']))
        assert (pytest.approx(35.751, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_in[0].conc_mass_phase_comp['Liq',
                                                                      'NaCl']))
        assert (pytest.approx(53.561, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_interface_in[0].
            conc_mass_phase_comp['Liq', 'NaCl']))
        assert (pytest.approx(39.524, rel=1e-3) == value(
            m.fs.unit.feed_side.properties_out[0].conc_mass_phase_comp['Liq',
                                                                       'NaCl'])
                )
        assert (pytest.approx(
            46.958, rel=1e-3
        ) ==  # TODO: expected this value to be higher than interface concentration at inlet, but bypassing for now- has to do with pressure drop
                value(m.fs.unit.feed_side.properties_interface_out[0].
                      conc_mass_phase_comp['Liq', 'NaCl']))