Esempio n. 1
0
def test_cbrt_values():
    m = pyo.ConcreteModel()
    flib = functions_lib()
    m.cbrt = pyo.ExternalFunction(library=flib, function="cbrt")
    assert (abs(pyo.value(m.cbrt(-27.0)) + 3.0) < 0.00001)
    assert (abs(pyo.value(m.cbrt(0.0))) < 0.00001)
    assert (abs(pyo.value(m.cbrt(27.0)) - 3.0) < 0.00001)
Esempio n. 2
0
def test_cbrt_hes():
    m = pyo.ConcreteModel()
    flib = functions_lib()
    m.cbrt = pyo.ExternalFunction(library=flib, function="cbrt")
    h = 1e-6
    tol = 1e-5
    for v in [-27.0, -0.5, 0.5, 27]:
        f1, g1, h1 = m.cbrt.evaluate_fgh(args=(v, ))
        f2, g2, h2 = m.cbrt.evaluate_fgh(args=(v + h, ))
        hfd = (g2[0] - g1[0]) / h
        assert (abs(h1[0] - hfd) < tol)
Esempio n. 3
0
def delta_temperature_underwood_callback(b):
    """
    This is a callback for a temperaure 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.
    """
    # 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")
    dT1 = b.delta_temperature_in
    dT2 = b.delta_temperature_out
    @b.Expression(b.flowsheet().config.time)
    def delta_temperature(b, t):
        return ((b.cbrt(dT1[t]) + b.cbrt(dT2[t]))/2.0)**3
Esempio n. 4
0
    def build(self):
        """
        Building model

        Args:
            None
        Returns:
            None
        """
        # Call UnitModel.build to setup dynamics
        super().build()
        config = self.config
        # Add variables
        self.overall_heat_transfer_coefficient = Var(
            self.flowsheet().config.time,
            domain=PositiveReals,
            initialize=100,
            doc="Overall heat transfer coefficient")
        self.overall_heat_transfer_coefficient.latex_symbol = "U"
        self.area = Var(domain=PositiveReals,
                        initialize=1000,
                        doc="Heat exchange area")
        self.area.latex_symbol = "A"
        if config.flow_pattern == HeatExchangerFlowPattern.crossflow:
            self.crossflow_factor = Var(
                self.flowsheet().config.time,
                initialize=1,
                doc="Factor to adjust coutercurrent flow heat transfer "
                "calculation for cross flow.")

        if config.delta_temperature_rule == delta_temperature_underwood2_rule:
            # Define a cube root function that return the real negative root
            # for the cube root of a negative number.
            self.cbrt = ExternalFunction(library=functions_lib(),
                                         function="cbrt")

        # Add Control Volumes
        _make_heater_control_volume(self,
                                    "side_1",
                                    config.side_1,
                                    dynamic=config.dynamic,
                                    has_holdup=config.has_holdup)
        _make_heater_control_volume(self,
                                    "side_2",
                                    config.side_2,
                                    dynamic=config.dynamic,
                                    has_holdup=config.has_holdup)
        # Add Ports
        self.add_inlet_port(name="inlet_1", block=self.side_1)
        self.add_inlet_port(name="inlet_2", block=self.side_2)
        self.add_outlet_port(name="outlet_1", block=self.side_1)
        self.add_outlet_port(name="outlet_2", block=self.side_2)
        # Add convienient references to heat duty.
        add_object_reference(self, "heat_duty", self.side_2.heat)
        self.side_1.heat.latex_symbol = "Q_1"
        self.side_2.heat.latex_symbol = "Q_2"

        @self.Expression(self.flowsheet().config.time,
                         doc="Temperature difference at the side 1 inlet end")
        def delta_temperature_in(b, t):
            if b.config.flow_pattern == \
                    HeatExchangerFlowPattern.countercurrent:
                return b.side_1.properties_in[t].temperature -\
                       b.side_2.properties_out[t].temperature
            elif b.config.flow_pattern == HeatExchangerFlowPattern.cocurrent:
                return b.side_1.properties_in[t].temperature -\
                       b.side_2.properties_in[t].temperature
            elif b.config.flow_pattern == HeatExchangerFlowPattern.crossflow:
                return b.side_1.properties_in[t].temperature -\
                       b.side_2.properties_out[t].temperature
            else:
                raise ConfigurationError(
                    "Flow pattern {} not supported".format(
                        b.config.flow_pattern))

        @self.Expression(self.flowsheet().config.time,
                         doc="Temperature difference at the side 1 outlet end")
        def delta_temperature_out(b, t):
            if b.config.flow_pattern == \
                    HeatExchangerFlowPattern.countercurrent:
                return b.side_1.properties_out[t].temperature -\
                       b.side_2.properties_in[t].temperature
            elif b.config.flow_pattern == HeatExchangerFlowPattern.cocurrent:
                return b.side_1.properties_out[t].temperature -\
                       b.side_2.properties_out[t].temperature
            elif b.config.flow_pattern == HeatExchangerFlowPattern.crossflow:
                return b.side_1.properties_out[t].temperature -\
                       b.side_2.properties_in[t].temperature

        # Add a unit level energy balance
        def unit_heat_balance_rule(b, t):
            return 0 == self.side_1.heat[t] + self.side_2.heat[t]

        self.unit_heat_balance = Constraint(self.flowsheet().config.time,
                                            rule=unit_heat_balance_rule)
        # Add heat transfer equation
        self.delta_temperature = Expression(
            self.flowsheet().config.time,
            rule=config.delta_temperature_rule,
            doc="Temperature difference driving force for heat transfer")
        self.delta_temperature.latex_symbol = "\\Delta T"

        if config.flow_pattern == HeatExchangerFlowPattern.crossflow:
            self.heat_transfer_equation = Constraint(
                self.flowsheet().config.time,
                rule=_cross_flow_heat_transfer_rule)
        else:
            self.heat_transfer_equation = Constraint(
                self.flowsheet().config.time, rule=_heat_transfer_rule)