Пример #1
0
    def return_expression(b, rblock, r_idx, T):
        e = None
        s = None

        if hasattr(b.params, "_electrolyte") and b.params._electrolyte:
            pc_set = b.params.true_phase_component_set
        else:
            pc_set = b.phase_component_set

        # Get reaction orders and construct power law expression
        for p, j in pc_set:
            p_obj = b.state_ref.params.get_phase(p)

            # First, build E
            o = rblock.reaction_order[p, j]

            if e is None and o.value != 0:
                e = get_concentration_term(b, r_idx)[p, j]**o
            elif e is not None and o.value != 0:
                e = e * get_concentration_term(b, r_idx)[p, j]**o

            if p_obj.is_solid_phase():
                # If solid phase, identify S
                r_config = b.params.config.equilibrium_reactions[r_idx]

                try:
                    stoic = r_config.stoichiometry[p, j]
                    if s is None and stoic != 0:
                        s = b.state_ref.flow_mol_phase_comp[p, j]
                    elif s is not None and stoic != 0:
                        s += b.state_ref.flow_mol_phase_comp[p, j]

                except KeyError:
                    pass

        if s is None:
            # Catch for not finding a solid phase
            raise ConfigurationError(
                "{} did not find a solid phase component for precipitation "
                "reaction {}. This is likely due to the reaction "
                "configuration.".format(b.name, r_idx))
        else:
            # Need to remove units as complementarity is not consistent
            sunits = pyunits.get_units(s)

            if sunits is not None:
                s = s / sunits

        Q = b.k_eq[r_idx] - e

        # Need to remove units again
        Qunits = pyunits.get_units(b.k_eq[r_idx])

        if Qunits is not None:
            Q = Q / Qunits

        return s - smooth_max(0, s - Q, rblock.eps) == 0
Пример #2
0
def delta_temperature_underwood_callback(b):
    r"""
    This is a callback for a temperature difference expression to calculate
    :math:`\Delta T` in the heat exchanger model using log-mean temperature
    difference (LMTD) approximation given by Underwood (1970).  It can be
    supplied to "delta_temperature_callback" HeatExchanger configuration option.
    This uses a cube root function that works with negative numbers returning
    the real negative root. This should always evaluate successfully. This form
    is

    .. math::

        \Delta T = \left(\frac{
            \Delta T_1^\frac{1}{3} + \Delta T_2^\frac{1}{3}}{2}\right)^3

    where :math:`\Delta T_1` is the temperature difference at the hot inlet end
    and :math:`\Delta T_2` is the temperature difference at the hot outlet end.
    """
    dT1 = b.delta_temperature_in
    dT2 = b.delta_temperature_out
    temp_units = pyunits.get_units(dT1[dT1.index_set().first()])

    # external function that ruturns the real root, for the cuberoot of negitive
    # numbers, so it will return without error for positive and negitive dT.
    b.cbrt = ExternalFunction(library=functions_lib(),
                              function="cbrt",
                              arg_units=[temp_units])

    @b.Expression(b.flowsheet().time)
    def delta_temperature(b, t):
        return ((b.cbrt(dT1[t]) + b.cbrt(dT2[t])) / 2.0)**3 * temp_units
Пример #3
0
 def test_module_example(self):
     from pyomo.environ import ConcreteModel, Var, Objective, units
     model = ConcreteModel()
     model.acc = Var()
     model.obj = Objective(expr=(model.acc * units.m / units.s**2 -
                                 9.81 * units.m / units.s**2)**2)
     self.assertEqual('m**2/s**4', str(units.get_units(model.obj.expr)))
Пример #4
0
 def return_log_expression(b, rblock, r_idx, T):
     units = pyunits.get_units(rblock.k_eq_ref)
     if units is None or units == pyunits.dimensionless:
         expr = rblock.k_eq_ref
     else:
         expr = rblock.k_eq_ref / units
     return b.log_k_eq[r_idx] == log(expr)
Пример #5
0
 def return_expression(blk, p, j, T):
     cobj = blk.params.get_component(j)
     return exp(
         cobj.diffus_phase_comp_coeff_1 + cobj.diffus_phase_comp_coeff_2 /
         T + cobj.diffus_phase_comp_coeff_3 *
         log(blk.visc_d_phase[p] / pyunits.get_units(blk.visc_d_phase[p]))
     ) * pyunits.m**2 / pyunits.s
Пример #6
0
def test_cp_mol_phase(build_model):
    m = build_model
    assert (str(pyunits.get_units(Cubic.cp_mol_phase(
        m.props, "Vap"))) == 'kg*m**2/K/mol/s**2')

    assert (pytest.approx(value(Cubic.cp_mol_phase(m.props, "Vap")),
                          rel=0.1) == data["cp_mol_phase"])
Пример #7
0
    def test_build(self):
        model = ConcreteModel()

        model.param = GenericParameterBlock(default=configuration)

        assert isinstance(model.param.phase_list, Set)
        assert len(model.param.phase_list) == 2
        for i in model.param.phase_list:
            assert i in ["Liq", "Vap"]
        assert model.param.Liq.is_liquid_phase()
        assert model.param.Vap.is_vapor_phase()

        assert isinstance(model.param.component_list, Set)
        assert len(model.param.component_list) == 2
        for i in model.param.component_list:
            assert i in ['bmimPF6',
                         'carbon_dioxide']
            assert isinstance(model.param.get_component(i), Component)

        assert isinstance(model.param._phase_component_set, Set)
        assert len(model.param._phase_component_set) == 3
        for i in model.param._phase_component_set:
            assert i in [("Liq", "bmimPF6"), ("Liq", "carbon_dioxide"),
                         ("Vap", "carbon_dioxide")]

        assert model.param.config.state_definition == FTPx

        assertStructuredAlmostEqual(
            model.param.config.state_bounds,
            { "flow_mol": (0, 100, 1000, pyunits.mol/pyunits.s),
              "temperature": (10, 300, 500, pyunits.K),
              "pressure": (5e-4, 1e5, 1e10, pyunits.Pa) },
            item_callback=lambda x: value(x) * (
                pyunits.get_units(x) or pyunits.dimensionless)._get_pint_unit()
        )

        assert model.param.config.phase_equilibrium_state == {
            ("Vap", "Liq"): SmoothVLE}

        assert isinstance(model.param.phase_equilibrium_idx, Set)
        assert len(model.param.phase_equilibrium_idx) == 1
        for i in model.param.phase_equilibrium_idx:
            assert i in ["PE1"]

        assert model.param.phase_equilibrium_list == {
            "PE1": {"carbon_dioxide": ("Vap", "Liq")}}

        assert model.param.pressure_ref.value == 101325
        assert model.param.temperature_ref.value == 298.15

        assert model.param.bmimPF6.mw.value == 284.18E-3
        assert model.param.bmimPF6.pressure_crit.value == 24e5
        assert model.param.bmimPF6.temperature_crit.value == 860

        assert model.param.carbon_dioxide.mw.value == 44.010E-3
        assert model.param.carbon_dioxide.pressure_crit.value == 71.8e5
        assert model.param.carbon_dioxide.temperature_crit.value == 304.1

        assert_units_consistent(model)
Пример #8
0
    def return_expression(b, rblock, r_idx, T):
        e = None

        if hasattr(b.params, "_electrolyte") and b.params._electrolyte:
            pc_set = b.params.true_phase_component_set
        else:
            pc_set = b.phase_component_set

        # Get reaction orders and construct power law expression
        for p, j in pc_set:
            o = rblock.reaction_order[p, j]

            if e is None and o != 0:
                # Need to strip units from concentration term (if applicable)
                c = get_concentration_term(b, r_idx)[p, j]
                u = pyunits.get_units(c)
                if u is not None:
                    # Has units, so divide conc by units
                    expr = c / u
                else:
                    # Units is None, so just use conc
                    expr = c
                e = o * safe_log(expr, eps=rblock.eps)
            elif e is not None and o != 0:
                # Need to strip units from concentration term (if applicable)
                c = get_concentration_term(b, r_idx)[p, j]
                u = pyunits.get_units(c)
                if u is not None:
                    # Has units, so divide conc by units
                    expr = c / u
                else:
                    # Units is None, so just use conc
                    expr = c
                e = e + o * safe_log(expr, eps=rblock.eps)

        # Need to check units on k_eq as well
        u = pyunits.get_units(b.k_eq[r_idx])
        if u is not None:
            # Has units, so divide k_eq by units
            expr = b.k_eq[r_idx] / u
        else:
            # Units is None, so just use k_eq
            expr = b.k_eq[r_idx]

        return safe_log(expr, eps=rblock.eps) == e
Пример #9
0
def test_isentropic_speed_sound_phase(build_model):
    m = build_model
    assert (str(
        pyunits.get_units(Cubic.isentropic_speed_sound_phase(m.props,
                                                             "Vap"))) == 'm/s')

    assert (pytest.approx(value(
        Cubic.isentropic_speed_sound_phase(m.props, "Vap")),
                          rel=0.1) == data["isentropic_speed_sound_phase"])
Пример #10
0
def test_heat_capacity_ratio_phase(build_model):
    m = build_model
    assert (str(
        pyunits.get_units(Cubic.heat_capacity_ratio_phase(m.props,
                                                          "Vap"))) == 'None')

    assert (pytest.approx(value(Cubic.heat_capacity_ratio_phase(
        m.props, "Vap")),
                          rel=0.1) == data["heat_capacity_ratio_phase"])
Пример #11
0
    def test_build(self):
        model = ConcreteModel()
        model.params = GenericParameterBlock(default=config_dict)

        assert isinstance(model.params.phase_list, Set)
        assert len(model.params.phase_list) == 2
        for i in model.params.phase_list:
            assert i in ["Liq", "Vap"]
        assert model.params.Liq.is_liquid_phase()
        assert model.params.Vap.is_vapor_phase()

        assert isinstance(model.params.component_list, Set)
        assert len(model.params.component_list) == 2
        for i in model.params.component_list:
            assert i in ['benzene', 'toluene']
            assert isinstance(model.params.get_component(i), Component)

        assert isinstance(model.params._phase_component_set, Set)
        assert len(model.params._phase_component_set) == 4
        for i in model.params._phase_component_set:
            assert i in [("Liq", "benzene"), ("Liq", "toluene"),
                         ("Vap", "benzene"), ("Vap", "toluene")]

        assert model.params.config.state_definition == FPhx

        assertStructuredAlmostEqual(
            model.params.config.state_bounds, {
                "flow_mol": (0, 100, 1000, pyunits.mol / pyunits.s),
                "enth_mol": (1e4, 5e4, 2e5, pyunits.J / pyunits.mol),
                "temperature": (273.15, 300, 450, pyunits.K),
                "pressure": (5e4, 1e5, 1e6, pyunits.Pa)
            },
            item_callback=lambda x: value(x) *
            (pyunits.get_units(x) or pyunits.dimensionless)._get_pint_unit())

        assert model.params.config.phase_equilibrium_state == {
            ("Vap", "Liq"): SmoothVLE
        }

        assert isinstance(model.params.phase_equilibrium_idx, Set)
        assert len(model.params.phase_equilibrium_idx) == 2
        for i in model.params.phase_equilibrium_idx:
            assert i in ["PE1", "PE2"]

        assert model.params.phase_equilibrium_list == {
            "PE1": {
                "benzene": ("Vap", "Liq")
            },
            "PE2": {
                "toluene": ("Vap", "Liq")
            }
        }

        assert model.params.pressure_ref.value == 1e5
        assert model.params.temperature_ref.value == 300

        assert_units_consistent(model)
Пример #12
0
    def check_units(self):
        """Check the expr units by exchanging the real model with unit model
        components
        
        :return: None

        """
        self.units = pyo_units.get_units(self.expression)
        return None
Пример #13
0
def print_HX_results(blk, exchanger_list):
    """
    Function to print results of Heat Exchangers
    Args:
        blk: flowsheet of the equipment
        exchanger_list: List of equipment to print data
    Returns:
        Printed List
    """
    # Initialize dictionary and fill with exchanger list
    exchangerdict = {}

    for i, el in enumerate(exchanger_list):
        exchangerdict[str(el)] = el

    # initialize null dictionaries for data to be printed
    Tin_ = {}
    Tout_ = {}
    f_ = {}
    Q_ = {}

    # Loop over heat exchangers
    for i in exchangerdict.keys():
        Tin_[i] = value(
            exchangerdict[i].control_volume.properties_in[0].temperature)
        Tout_[i] = value(
            exchangerdict[i].control_volume.properties_out[0].temperature)
        f_[i] = value(
            exchangerdict[i].control_volume.properties_out[0].flow_mol)
        Q_[i] = value(exchangerdict[i].control_volume.heat[0])
        T_units = pyunits.get_units(
            exchangerdict[i].control_volume.properties_in[0].temperature)
        DG_units = pyunits.get_units(exchangerdict[i].heat_duty[0])

    # Print the header
    print("Heat Exchanger Summary: ")

    # Print Inlet Temperature, Outlet Temperature and Heat
    for i in exchangerdict.keys():
        print("Heat exchanger: ", exchangerdict[i])
        print(f'Inlet T: {" "*3} {Tin_[i] : 0.3f} {T_units}')
        print(f'Outlet T: {" "*2} {Tout_[i] : 0.3f} {T_units}')
        print(f'Q : {" "*9} {Q_[i]: 0.3f} {DG_units}')
Пример #14
0
 def eq_lmtd(b, t):
     dT_in = b.delta_temperature_in
     dT_out = b.delta_temperature_out
     temp_units = pyunits.get_units(dT_in)
     dT_avg = (dT_in + dT_out) / 2
     # external function that ruturns the real root, for the cuberoot of negitive
     # numbers, so it will return without error for positive and negitive dT.
     b.cbrt = ExternalFunction(library=functions_lib(),
                               function="cbrt",
                               arg_units=[temp_units**3])
     return b.lmtd == b.cbrt((dT_in * dT_out * dT_avg)) * temp_units
Пример #15
0
    def return_log_expression(b, rblock, r_idx, T):
        units = rblock.parent_block().get_metadata().derived_units

        k_units = pyunits.get_units(rblock.k_eq_ref)

        if (k_units is None or k_units is pyunits.dimensionless):
            l_keq_ref = log(rblock.k_eq_ref)
        else:
            l_keq_ref = log(rblock.k_eq_ref / k_units)

        return (b.log_k_eq[r_idx] - l_keq_ref) == (
            -b.dh_rxn[r_idx] /
            pyunits.convert(c.gas_constant, to_units=units["gas_constant"]) *
            (1 / T - 1 / rblock.T_eq_ref))
Пример #16
0
    def check_term(self, term, convert_to):

        unit_term = pyo_units.get_units(term)
        _print(f'     Units: {unit_term} ==> {convert_to}\n')
        _changed_flag = False
        term_new = term

        if unit_term is not None:
            _print('Starting conversion and making the new term\n')
            term_new = pyo_units.convert(term,
                                         to_units=getattr(
                                             pyo_units, convert_to))

        return term_new
Пример #17
0
    def _check_term(term, convert_to):
        """This loops through terms in the expression to ensure the units are valid

        :param expression term: The term to check
        :param str convert_to: The units to convert to, if necessary

        :return term_new: The updated expression term
        :rtype: expression

        """
        unit_term = pyo_units.get_units(term)
        term_new = term

        if unit_term is not None:
            term_new = pyo_units.convert(term,
                                         to_units=getattr(
                                             pyo_units, convert_to))

        return term_new
Пример #18
0
 def check_units(self):  #, c_mod, c_mod_new):
     """Check the expr units by exchanging the real model with unit model
     components
     
     Args:
         key (str): component represented in ODE
         
         expr (Expression): Expression object of ODE
         
         c_mod (Comp): original Comp object used to declare the expressions
         
         c_mod_new (Comp_Check): dummy model with unit components
         
     Returns:
         pint_units (): Returns expression with unit model components
     
     """
     self.units = pyo_units.get_units(self.expression)
     return None
Пример #19
0
def delta_temperature_chen_callback(b):
    r"""
    This is a callback for a temperature difference expression to calculate
    :math:`\Delta T` in the heat exchanger model using log-mean temperature
    difference (LMTD) approximation given by Chen (1987).  It can be
    supplied to "delta_temperature_callback" HeatExchanger configuration option.
    This uses a cube root function that works with negative numbers returning
    the real negative root. This should always evaluate successfully.
    """
    dT1 = b.delta_temperature_in
    dT2 = b.delta_temperature_out
    temp_units = pyunits.get_units(dT1)

    # external function that ruturns the real root, for the cuberoot of negitive
    # numbers, so it will return without error for positive and negitive dT.
    b.cbrt = ExternalFunction(library=functions_lib(),
                              function="cbrt",
                              arg_units=[temp_units**3])

    @b.Expression(b.flowsheet().time)
    def delta_temperature(b, t):
        return b.cbrt(dT1[t] * dT2[t] * 0.5 * (dT1[t] + dT2[t])) * temp_units
Пример #20
0
    def test_build(self):
        model = ConcreteModel()
        model.params = GenericParameterBlock(default=configuration)

        assert isinstance(model.params.phase_list, Set)
        assert len(model.params.phase_list) == 2
        for i in model.params.phase_list:
            assert i in ["Liq", "Vap"]
        assert model.params.Liq.is_liquid_phase()
        assert model.params.Vap.is_vapor_phase()

        assert isinstance(model.params.component_list, Set)
        assert len(model.params.component_list) == 2
        for i in model.params.component_list:
            assert i in ['H2O', 'CO2']
            assert isinstance(model.params.get_component(i), Component)

        assert isinstance(model.params._phase_component_set, Set)
        assert len(model.params._phase_component_set) == 3
        for i in model.params._phase_component_set:
            assert i in [("Liq", "H2O"), ("Vap", "H2O"), ("Vap", "CO2")]

        assert model.params.config.state_definition == FTPx

        assertStructuredAlmostEqual(
            model.params.config.state_bounds, {
                "flow_mol": (0, 10, 20, pyunits.mol / pyunits.s),
                "temperature": (273.15, 323.15, 1000, pyunits.K),
                "pressure": (5e4, 108900, 1e7, pyunits.Pa),
                "mole_frac_comp": {
                    "H2O": (0, 0.5, 1),
                    "CO2": (0, 0.5, 1)
                }
            },
            item_callback=lambda x: value(x) *
            (pyunits.get_units(x) or pyunits.dimensionless)._get_pint_unit())

        assert model.params.config.phase_equilibrium_state == {
            ("Vap", "Liq"): SmoothVLE
        }

        assert isinstance(model.params.phase_equilibrium_idx, Set)
        assert len(model.params.phase_equilibrium_idx) == 1
        for i in model.params.phase_equilibrium_idx:
            assert i in ["PE1"]

        assert model.params.phase_equilibrium_list == {
            "PE1": {
                "H2O": ("Vap", "Liq")
            }
        }

        assert model.params.pressure_ref.value == 101325
        assert model.params.temperature_ref.value == 298.15

        assert model.params.H2O.mw.value == 18.0153E-3
        assert model.params.H2O.pressure_crit.value == 220.64E5
        assert model.params.H2O.temperature_crit.value == 647

        assert model.params.CO2.mw.value == 44.0095E-3
        assert model.params.CO2.pressure_crit.value == 73.825E5
        assert model.params.CO2.temperature_crit.value == 304.23

        assert_units_consistent(model)
Пример #21
0
def min_utility(blk,
                heating,
                cooling,
                DTmin,
                eps=1e-6,
                DG_units=pyunits.Mwatt):
    """
    Function for Duran-Grossmann for minimization of utilities
    This function adds variables and constraints to the flowsheet to
    minimize utilities

    Args:
        blk: flowsheet
        heating: Equipment that requires Heat
        cooling: Equipment from wich heat is being removed
        DTmin: HRAT (Heat Recovery Approximation Temperature)
        eps: Epsilon for smoothing operation

    Returns:
        Constraint and variable object representing the calculation
        for hot utility and cold utility
    """

    # Generate lists out of strings from Args
    exchanger_list = heating + cooling
    pinch_streams = exchanger_list

    # Generate dictionaries out of strings to convert to pyomo objects
    pinch_streamsdict = {}
    coolingdict = {}
    heatingdict = {}
    exchangerdict = {}

    for i, el in enumerate(exchanger_list):
        pinch_streamsdict[str(el)] = el

    for i, el in enumerate(cooling):
        coolingdict[str(el)] = el

    for i, el in enumerate(heating):
        heatingdict[str(el)] = el

    for i, el in enumerate(exchanger_list):
        exchangerdict[str(el)] = el

    Q = {}

    for i in exchangerdict:
        Q[i] = pyunits.convert(pinch_streamsdict[i].heat_duty[0],
                               to_units=DG_units)

    # Run function to fill exchanger data for pinch calculations for
    # initialization of variables
    exchangeData = heat_data(blk, heating, cooling, DG_units)

    # Call pinch calculation for initialization of variables in PD class
    PD = pinch_calc(heating, cooling, exchangeData, DTmin, eps)

    # Define dictionary for addition of DTmin to heating equipment
    dT = {}

    for i, el in enumerate(cooling):
        dT[str(el)] = 0

    for i, el in enumerate(heating):
        dT[str(el)] = DTmin

    def T_in(blk, i):
        return pinch_streamsdict[i].control_volume.properties_in[0].temperature

    blk.Tin = Expression(pinch_streamsdict.keys(),
                         rule=T_in,
                         doc='Inlet temperature in exchangers')

    def T_out(blk, i):
        return pinch_streamsdict[i].control_volume.properties_out[
            0].temperature

    blk.Tout = Expression(pinch_streamsdict.keys(),
                          rule=T_out,
                          doc='Outlet temperature in exchangers')

    # Expression for cp of equimpent with heat exchange
    def Theta_(blk, i):
        if i in heatingdict.keys():
            return (Q[i] / (0.5 * ((blk.Tout[i] - blk.Tin[i] +
                                    (EpsT)) + sqrt((blk.Tout[i] - blk.Tin[i] -
                                                    (EpsT))**2 + eps))))
        else:
            return (Q[i] /
                    (-0.5 * ((-(blk.Tout[i] - blk.Tin[i]) - (-EpsT)) + sqrt((
                        (-EpsT) - (blk.Tout[i] - blk.Tin[i]))**2 + eps))))

    blk.Theta = Expression(pinch_streamsdict.keys(),
                           rule=Theta_,
                           doc='FCp in exchangers')

    # Define expression for pinch candidate temperature
    def T_(blk, i):
        return (
            pinch_streamsdict[i].control_volume.properties_in[0].temperature +
            dT[i])

    blk.T_ = Expression(pinch_streamsdict.keys(),
                        rule=T_,
                        doc='Pinch candidate temperature')

    # Define variable for heat content above the pinch point
    blk.QAh = Var(pinch_streamsdict.keys(),
                  initialize=PD.initQAh,
                  bounds=(1e-8, None),
                  doc='Heat content above pinch',
                  units=pyunits.get_units(Q[str(pinch_streams[0])]))

    # Define a cpnstraint to calculate the varaible QAh
    def rule_heat_above_pinch(blk, p):
        return (blk.QAh[p] == sum(
            blk.Theta[i] * (0.5 * ((blk.Tin[i] - blk.T_[p]) + sqrt(
                (blk.Tin[i] - blk.T_[p])**2 + eps)) - 0.5 *
                            ((blk.Tout[i] - blk.T_[p]) + sqrt(
                                (blk.Tout[i] - blk.T_[p])**2 + eps)))
            for i in coolingdict.keys()))

    blk.heat_above_pinch = Constraint(pinch_streamsdict.keys(),
                                      rule=rule_heat_above_pinch)

    # Define variable for heat content below the pinch point
    blk.QAc = Var(pinch_streamsdict.keys(),
                  initialize=PD.initQAc,
                  bounds=(1e-8, None),
                  doc='Heat content bellow pinch',
                  units=pyunits.get_units(Q[str(pinch_streams[0])]))

    # Define a constraint to calculate the varaible QAc
    def rule_heat_below_pinch(blk, p):
        return (blk.QAc[p] == sum(
            blk.Theta[i] * (0.5 * ((blk.Tout[i] - blk.T_[p] + DTmin) + sqrt(
                (blk.Tout[i] - blk.T_[p] + DTmin)**2 + eps)) - 0.5 *
                            ((blk.Tin[i] - blk.T_[p] + DTmin) + sqrt(
                                (blk.Tin[i] - blk.T_[p] + DTmin)**2 + eps)))
            for i in heatingdict.keys()))

    blk.heat_below_pinch = Constraint(pinch_streamsdict.keys(),
                                      rule=rule_heat_below_pinch)

    # Define variable for Heat of hot utility
    blk.Qs = Var(initialize=PD.initQs,
                 bounds=(1e-8, None),
                 doc='Heating utilities',
                 units=pyunits.get_units(Q[str(pinch_streams[0])]))

    # Define a constraint to solve for Qs
    # Where 1E-6 is added to both sides of the constraint as a scaling factor
    def rule_heating_utility(blk, p):
        return (blk.Qs >= (blk.QAc[p] - blk.QAh[p]))

    blk.heating_utility = Constraint(pinch_streamsdict.keys(),
                                     rule=rule_heating_utility)

    # Define variable for Heat of cold utility
    blk.Qw = Var(initialize=PD.initQw,
                 bounds=(1e-8, None),
                 doc='Cooling utilities',
                 units=pyunits.get_units(Q[str(pinch_streams[0])]))

    # Define a constraint to solve for Qw
    # Where 1E-6 is added to both sides of the constraint as a scaling factor
    def rule_cooling_utility(blk):
        return blk.Qw == -sum(Q[i] for i in exchangerdict.keys()) + blk.Qs

    blk.cooling_utility = Constraint(rule=rule_cooling_utility)
Пример #22
0
def heat_ex_data(blk, heating, cooling):
    """
    Function for turning IDAES heat exchanging equipment into a class for
    use in plotting

    Args:
        blk: Flowsheet
        heating: Equipment that heats streams
        cooling: Equipment that cools streams
    Returns:
        CD: Class with heating and cooling equipment as arrays
    """
    # Generate dictionaries out of strings to convert to pyomo objects
    exchanger_list = heating + cooling
    pinch_streams = exchanger_list

    pinch_streamsdict = {}
    coolingdict = {}
    heatingdict = {}
    exchangerdict = {}

    T_units = pyunits.get_units(
        pinch_streams[0].control_volume.properties_in[0].temperature)
    DG_units = pyunits.get_units(blk.Qw)

    for i, el in enumerate(exchanger_list):
        pinch_streamsdict[str(el)] = el

    for i, el in enumerate(cooling):
        coolingdict[str(el)] = el

    for i, el in enumerate(heating):
        heatingdict[str(el)] = el

    for i, el in enumerate(exchanger_list):
        exchangerdict[str(el)] = el

    # Generate zero arrays from length of the cooling list
    CHX = len(coolingdict)
    CTin = np.zeros(CHX)
    CTout = np.zeros(CHX)
    CQ = np.zeros(CHX)

    # Convert Pyomo model values into arrays
    j = 0
    for i in coolingdict.keys():
        CTin[j] = value(
            coolingdict[i].control_volume.properties_in[0].temperature) + 1
        CTout[j] = value(
            coolingdict[i].control_volume.properties_out[0].temperature)
        CQ[j] = value(
            pyunits.convert(coolingdict[i].control_volume.heat[0],
                            to_units=DG_units))
        j += 1

    # Generate zero arrays from length of the heating list
    HHX = len(heatingdict)
    HTin = np.zeros(HHX)
    HTout = np.zeros(HHX)
    HQ = np.zeros(HHX)

    # Convert Pyomo model values into arrays
    j = 0
    for i in heatingdict.keys():
        HTin[j] = value(
            heatingdict[i].control_volume.properties_in[0].temperature)
        HTout[j] = value(
            heatingdict[i].control_volume.properties_out[0].temperature) + 1
        HQ[j] = value(
            pyunits.convert(heatingdict[i].control_volume.heat[0],
                            to_units=DG_units))
        j += 1

        # Fill class with values and arrays
    Qw = value(blk.Qw)
    CD = CurveData(Qw, T_units, DG_units)
    CD.Cooling_Tin = CTin
    CD.Cooling_Tout = CTout
    CD.Cooling_Q = CQ
    CD.Heating_Tin = HTin
    CD.Heating_Tout = HTout
    CD.Heating_Q = HQ
    return CD
Пример #23
0
 def test_module_example(self):
     from pyomo.environ import ConcreteModel, Var, Objective, units # import components and 'units' instance
     model = ConcreteModel()
     model.acc = Var()
     model.obj = Objective(expr=(model.acc*units.m/units.s**2 - 9.81*units.m/units.s**2)**2)
     self.assertEqual('m ** 2 / s ** 4', str(units.get_units(model.obj.expr)))
Пример #24
0
def Txy_data(model,
             component_1,
             component_2,
             pressure,
             num_points=20,
             temperature=298.15,
             print_level=idaeslog.NOTSET,
             solver=None,
             solver_op=None):
    """
    Function to generate T-x-y data. The function builds a state block and extracts
    bubble and dew temperatures at P pressure for N number of compositions.
    As N is increased increase the time of the calculation will increase and
    create a smoother looking plot.

    Args:
        component_1: Component 1
        component_2: Component 2
        pressure: Pressure at which the bubble and drew temperatures will be calculates
        temperature: Temperature at which to initialize state block
        num_points: Number of data point to be calculated
        model: Model wit intialized Property package which contains data to calculate
        bubble and dew temperatures for  component 1 and component 2
        print_level: printing level from initialization
        solver: solver to use (default=None, use IDAES default solver)
        solver_op: solver options

    Returns:
        (Class): A class containing the T-x-y data

    """

    components = list(model.params.component_list)
    components_used = [component_1, component_2]
    components_not_used = list(set(components) - set(components_used))

    # Add properties parameter blocks to the flowsheet with specifications

    model.props = model.params.build_state_block(
        [1], default={"defined_state": True})

    # Set intial concentration of component 1 close to 1
    x = 0.99

    # Set conditions for flash unit model
    model.props[1].mole_frac_comp[component_1].fix(x)

    for i in components_not_used:
        model.props[1].mole_frac_comp[i].fix(1e-5)

    xs = sum(
        value(model.props[1].mole_frac_comp[i]) for i in components_not_used)

    model.props[1].mole_frac_comp[component_2].fix(1 - x - xs)

    model.props[1].flow_mol.fix(1)
    model.props[1].temperature.fix(temperature)
    model.props[1].pressure.fix(pressure)

    # Initialize flash unit model
    model.props[1].calculate_scaling_factors()
    model.props.initialize(solver=solver, optarg=solver_op, outlvl=print_level)

    solver = get_solver(solver, solver_op)

    # Create an array of compositions with N number of points
    x_d = np.linspace(x, 1 - x - xs, num_points)

    # Create emprty arrays for concentration, bubble temperature and dew temperature
    X = []
    Tbubb = []
    Tdew = []

    # Obtain pressure and temperature units from the unit model
    Punit = pyunits.get_units(model.props[1].pressure)
    Tunit = pyunits.get_units(model.props[1].temperature)

    count = 1
    # Create and run loop to calculate temperatures at every composition
    for i in range(len(x_d)):
        model.props[1].mole_frac_comp[component_1].fix(x_d[i])
        model.props[1].mole_frac_comp[component_2].fix(1 - x_d[i] - xs)
        # solve the model
        status = solver.solve(model, tee=False)
        # If solution is optimal store the concentration, and calculated temperatures in the created arrays
        if (status.solver.status
                == SolverStatus.ok) and (status.solver.termination_condition
                                         == TerminationCondition.optimal):

            print('Case: ', count, ' Optimal. ', component_1,
                  'x = {:.2f}'.format(x_d[i]))

            if hasattr(model.props[1], "_mole_frac_tdew") and hasattr(
                    model.props[1], "_mole_frac_tbub"):
                Tbubb.append(
                    value(model.props[1].temperature_bubble['Vap', 'Liq']))
                Tdew.append(value(model.props[1].temperature_dew['Vap',
                                                                 'Liq']))

            elif hasattr(model.props[1], "_mole_frac_tdew"):
                print('One of the components only exists in vapor phase.')
                Tdew.append(value(model.props[1].temperature_dew['Vap',
                                                                 'Liq']))

            elif hasattr(model.props[1], "_mole_frac_tbub"):
                print('One of the components only exists in liquid phase.')
                Tbubb.append(
                    value(model.props[1].temperature_bubble['Vap', 'Liq']))

            X.append(x_d[i])

        # If the solver did not solve to an optimal solution, do not store the data point
        else:
            print('Case: ', count, ' No Result', component_1,
                  'x = {:.2f}'.format(x_d[i]))
        count += 1

    # Call TXYData function and store the data in TD class
    TD = TXYDataClass(component_1, component_2, Punit, Tunit, pressure)
    TD.TBubb = Tbubb
    TD.TDew = Tdew
    TD.x = X

    # Return the data class with all the information of the calculations
    return TD
Пример #25
0
    def test_build(self):
        model = ConcreteModel()
        model.params = GenericParameterBlock(default=configuration)

        assert isinstance(model.params.phase_list, Set)
        assert len(model.params.phase_list) == 2
        for i in model.params.phase_list:
            assert i in ["Liq", "Vap"]
        assert model.params.Liq.is_liquid_phase()
        assert model.params.Vap.is_vapor_phase()

        assert isinstance(model.params.component_list, Set)
        assert len(model.params.component_list) == 13
        for i in model.params.component_list:
            assert i in ['hydrogen',
                         'methane',
                         'ethane',
                         'propane',
                         'nbutane',
                         'ibutane',
                         'ethylene',
                         'propene',
                         'butene',
                         'pentene',
                         'hexene',
                         'heptene',
                         'octene']

            assert isinstance(model.params.get_component(i), Component)

        assert isinstance(model.params._phase_component_set, Set)
        assert len(model.params._phase_component_set) == 24
        for i in model.params._phase_component_set:
            assert i in [
                ("Liq", "ethane"), ("Vap", "hydrogen"), ("Vap", "methane"),
                ("Vap", "ethane"), ("Liq", "propane"), ("Liq", "nbutane"),
                ("Liq", "ibutane"), ("Vap", "propane"), ("Vap", "nbutane"),
                ("Vap", "ibutane"), ("Liq", "ethylene"), ("Liq", "propene"),
                ("Liq", "butene"), ("Vap", "ethylene"), ("Vap", "propene"),
                ("Vap", "butene"), ("Liq", "pentene"), ("Liq", "hexene"),
                ("Liq", "heptene"), ("Vap", "pentene"), ("Vap", "hexene"),
                ("Vap", "heptene"), ("Liq", "octene"), ("Vap", "octene")]

        assert model.params.config.state_definition == FTPx

        assertStructuredAlmostEqual(
            model.params.config.state_bounds,
            { "flow_mol": (0, 100, 1000, pyunits.mol/pyunits.s),
              "temperature": (273.15, 300, 1500, pyunits.K),
              "pressure": (5e4, 1e5, 1e7, pyunits.Pa) },
            item_callback=lambda x: value(x) * (
                pyunits.get_units(x) or pyunits.dimensionless)._get_pint_unit()
        )

        assert model.params.config.phase_equilibrium_state == {
            ("Vap", "Liq"): SmoothVLE}

        assert isinstance(model.params.phase_equilibrium_idx, Set)
        assert len(model.params.phase_equilibrium_idx) == 11
        for i in model.params.phase_equilibrium_idx:
            assert i in ["PE1", "PE2", "PE3", "PE4", "PE5", "PE6",
                         "PE7", "PE8", "PE9", "PE10", "PE11"]

        assert model.params.phase_equilibrium_list == {
            "PE1": {"ethane": ("Vap", "Liq")},
            "PE2": {"propane": ("Vap", "Liq")},
            "PE3": {"nbutane": ("Vap", "Liq")},
            "PE4": {"ibutane": ("Vap", "Liq")},
            "PE5": {"ethylene": ("Vap", "Liq")},
            "PE6": {"propene": ("Vap", "Liq")},
            "PE7": {"butene": ("Vap", "Liq")},
            "PE8": {"pentene": ("Vap", "Liq")},
            "PE9": {"hexene": ("Vap", "Liq")},
            "PE10": {"heptene": ("Vap", "Liq")},
            "PE11": {"octene": ("Vap", "Liq")}}

        assert model.params.pressure_ref.value == 101325
        assert model.params.temperature_ref.value == 298.15

        assert model.params.hydrogen.mw.value == 2.016E-3
        assert model.params.hydrogen.pressure_crit.value == 12.9e5
        assert model.params.hydrogen.temperature_crit.value == 33.2

        assert model.params.methane.mw.value == 16.043E-3
        assert model.params.methane.pressure_crit.value == 46e5
        assert model.params.methane.temperature_crit.value == 190.4

        assert model.params.ethane.mw.value == 30.070E-3
        assert model.params.ethane.pressure_crit.value == 48.8e5
        assert model.params.ethane.temperature_crit.value == 305.4

        assert model.params.propane.mw.value == 44.094E-3
        assert model.params.propane.pressure_crit.value == 42.5e5
        assert model.params.propane.temperature_crit.value == 369.8

        assert model.params.nbutane.mw.value == 58.124E-3
        assert model.params.nbutane.pressure_crit.value == 38.0e5
        assert model.params.nbutane.temperature_crit.value == 425.2

        assert model.params.ibutane.mw.value == 58.124E-3
        assert model.params.ibutane.pressure_crit.value == 36.5e5
        assert model.params.ibutane.temperature_crit.value == 408.2

        assert model.params.ethylene.mw.value == 28.054E-3
        assert model.params.ethylene.pressure_crit.value == 50.5e5
        assert model.params.ethylene.temperature_crit.value == 282.4

        assert model.params.propene.mw.value == 42.081E-3
        assert model.params.propene.pressure_crit.value == 46.2e5
        assert model.params.propene.temperature_crit.value == 365.0

        assert model.params.butene.mw.value == 56.104E-3
        assert model.params.butene.pressure_crit.value == 40.2e5
        assert model.params.butene.temperature_crit.value == 419.3

        assert model.params.pentene.mw.value == 70.135E-3
        assert model.params.pentene.pressure_crit.value == 40.5e5
        assert model.params.pentene.temperature_crit.value == 464.7

        assert model.params.hexene.mw.value == 84.162E-3
        assert model.params.hexene.pressure_crit.value == 31.7e5
        assert model.params.hexene.temperature_crit.value == 504.0

        assert model.params.heptene.mw.value == 98.189E-3
        assert model.params.heptene.pressure_crit.value == 25.4e5
        assert model.params.heptene.temperature_crit.value == 537.2

        assert model.params.octene.mw.value == 112.216E-3
        assert model.params.octene.pressure_crit.value == 26.2e5
        assert model.params.octene.temperature_crit.value == 566.6
        assert_units_consistent(model)
Пример #26
0
 def input_rule(b, i):
     if units.get_units(input_map[i]) is None:
         return b.ROM_input[i] == input_map[i]
     else:
         unit_conversion = units.get_units(input_map[i])
         return b.ROM_input[i] == input_map[i]/unit_conversion
Пример #27
0
 def return_expression(b, rblock, r_idx, T):
     units = pyunits.get_units(rblock.k_eq_ref)
     if units is None or units is pyunits.dimensionless:
         return exp(b.log_k_eq[r_idx])
     else:
         return exp(b.log_k_eq[r_idx]) * units
Пример #28
0
def _as_quantity(x):
    unit = pyunits.get_units(x)
    if unit is None:
        unit = pyunits.dimensionless
    return value(x) * unit._get_pint_unit()
Пример #29
0
    def test_build(self):
        model = ConcreteModel()
        model.params = GenericParameterBlock(default=configuration)

        assert isinstance(model.params.phase_list, Set)
        assert len(model.params.phase_list) == 2
        for i in model.params.phase_list:
            assert i in ["Liq", "Vap"]
        assert model.params.Liq.is_liquid_phase()
        assert model.params.Vap.is_vapor_phase()

        assert isinstance(model.params.component_list, Set)
        assert len(model.params.component_list) == 3
        for i in model.params.component_list:
            assert i in ['nitrogen', 'argon', 'oxygen']
            assert isinstance(model.params.get_component(i), Component)

        assert isinstance(model.params._phase_component_set, Set)
        assert len(model.params._phase_component_set) == 6
        for i in model.params._phase_component_set:
            assert i in [("Liq", "nitrogen"), ("Liq", "argon"),
                         ("Liq", "oxygen"), ("Vap", "nitrogen"),
                         ("Vap", "argon"), ("Vap", "oxygen")]

        assert model.params.config.state_definition == FTPx

        assertStructuredAlmostEqual(
            model.params.config.state_bounds, {
                "flow_mol": (0, 100, 1000, pyunits.mol / pyunits.s),
                "temperature": (10, 300, 350, pyunits.K),
                "pressure": (5e4, 1e5, 1e7, pyunits.Pa)
            },
            item_callback=lambda x: value(x) *
            (pyunits.get_units(x) or pyunits.dimensionless)._get_pint_unit())

        assert model.params.config.phase_equilibrium_state == {
            ("Vap", "Liq"): SmoothVLE
        }

        assert isinstance(model.params.phase_equilibrium_idx, Set)
        assert len(model.params.phase_equilibrium_idx) == 3
        for i in model.params.phase_equilibrium_idx:
            assert i in ["PE1", "PE2", "PE3"]

        assert model.params.phase_equilibrium_list == {
            "PE1": {
                "nitrogen": ("Vap", "Liq")
            },
            "PE2": {
                "argon": ("Vap", "Liq")
            },
            "PE3": {
                "oxygen": ("Vap", "Liq")
            }
        }

        assert model.params.pressure_ref.value == 101325
        assert model.params.temperature_ref.value == 298.15

        assert model.params.nitrogen.mw.value == 28.0135E-3
        assert model.params.nitrogen.pressure_crit.value == 34e5
        assert model.params.nitrogen.temperature_crit.value == 126.2

        assert model.params.argon.mw.value == 39.948E-3
        assert model.params.argon.pressure_crit.value == 48.98e5
        assert model.params.argon.temperature_crit.value == 150.86

        assert model.params.oxygen.mw.value == 31.999E-3
        assert model.params.oxygen.pressure_crit.value == 50.43e5
        assert model.params.oxygen.temperature_crit.value == 154.58

        assert_units_consistent(model)