Module huracan.thermo.fluids

Huracan fluid models

Expand source code
# SPDX-FileCopyrightText: © 2021 Antonio López Rivera <antonlopezr99@gmail.com>
# SPDX-License-Identifier: GPL-3.0-only

"""
Huracan fluid models
--------------------
"""

from copy import deepcopy

from huracan.constants import R
from huracan.engine import stream, component
from huracan.thermo.processes import absolute, diffusion, compression, heat_exchange, expansion


class fluid:
    """
    Fluid
    -----
    """
    @classmethod
    def _diversion(cls, f, fr):
        """
        Fluid diversion.
        - Diverted flow mass flow:       fraction*mf
        - Main flow mass flow:       (1-fraction)*mf

        :param f:  Fluid to be diverted.
        :param fr: Fraction of diverted fluid.

        :type f:   mixture or fluid
        :type fr:  0 <= float <= 1

        :return:   [fluid] Main flow
                   [fluid] Diverted flow
        """
        mf, df = deepcopy(f), deepcopy(f)

        mf.mf *= 1 - fr
        df.mf *= fr

        return mf, df

    def __mul__(self, other):
        """
        Return two flows representing the diversion.
        """
        return self._diversion(self, other)

    def __rmul__(self, other):
        """
        Return two flows representing the diversion.
        """
        return self._diversion(self, other)


class gas(fluid):
    """
    Ideal gas model
    ---------------

    All gas phenomena are modelled using its
    - Mass flow
    - Constant pressure specific heat capacity
    - Ratio of specific heat capacities
    """
    def __init__(self, mf, cp, k,
                 m, t_0, p_0):
        """
        :param mf:  [kg] Mass flow
        :param cp:  [-]  Constant pressure specific heat
        :param k:   [-]  Specific heat ratio
        :param m:   [M]  Flow Mach number      |
        :param t_0: [K]  Initial temperature   | -> Total pressure and temperature calculated from inputs
        :param p_0: [Pa] Initial pressure      |

        :type mf:   float
        :type cp:   (T: float) -> float
        :type k:    (T: float) -> float
        :type m:    float
        :type t_0:  float
        :type p_0:  float
        """
        self.mf  = mf
        self.cp  = cp
        self.k   = k

        self.m   = m
        self.v_0 = m*(k(t_0)*R*t_0)**0.5

        self.t_0 = t_0
        self.p_0 = p_0

        self.absolute()

        # Set the gas' initial entropy as 0
        self.S = 0

    def state(self):
        """
        Update gas state variables.
        - V - Specific volume
        - S - Specific entropy
        - H - Specific enthalpy
        """
        self.V  =  self.t0*R/self.p0
        self.E  =  self.cp(self.t0)/self.k(self.t0)*self.t0
        self.H  =  self.E + self.p0*self.V

    def __add__(self, other):
        """
        Mixture creation operator: <gas> + <gas>

        In the case of adding fuel to a gas, the
        following assumptions are considered:
        - Total temperature and pressure of gas are
          unaltered.
        - Constant pressure specific heat capacity Cp
          of gas is unaltered.
        - Ratio of specific heats k of gas is unaltered.

        :type other: gas or fuel
        """
        if isinstance(other, gas):
            return mixture(self, other)
        if isinstance(other, fuel):
            self.mf += other.mf
            return self

    def __sub__(self, other):
        """
        Stream creation operator: <gas> + <component/stream>

        :type other: component or stream

        :return:     stream instance
        """
        if isinstance(other, component):
            s = stream(self)-other
            return s
        elif isinstance(other, stream):
            other.gas = self
            return other

    def absolute(self):
        """
        Returns the absolute temperature and pressure of a gas
        flowing at a certain Mach number.

        :return: process data class instance
        """

        k   = self.k(self.t_0)

        p = absolute(k   = k,
                     m   = self.m,
                     t_0 = self.t_0,
                     p_0 = self.p_0)

        self.t0 = p.t0
        self.p0 = p.p0

        self.state()

        return p

    def diffusion(self, eta,
                  PI=None,
                  TAU=None):
        """
        Diffusion
        ---------

        Assumptions:
        - Adiabatic
        - Reversible
        - Temperature remains constant through process

        The absolute pressure change is determined by the total pressure ratio
        _PI_ if provided. Else, _PI_ is calculated using the isentropic
        efficiency _nu_.

        :param eta: [-]  Isentropic efficiency
        :param PI:  [-]  Pressure ratio

        :type eta:  float
        :type PI:   float

        :return:    process instance
        """

        k   = self.k(self.t0)
        cp  = self.cp(self.t0)

        p = diffusion(mf  = self.mf,
                      cp  = cp,
                      k   = k,
                      m   = self.m,
                      t_0 = self.t_0,
                      p_0 = self.p_0,
                      eta = eta,
                      PI  = PI,
                      TAU = TAU,
                      t0  = self.t0 if hasattr(self, 't0') else None,
                      p0  = self.p0 if hasattr(self, 'p0') else None
                      )

        self.t0 = p.t01
        self.p0 = p.p01

        self.state()

        return p

    def compression(self, eta,
                    PI=None,
                    TAU=None,
                    ):
        """
        Compression
        -----------

        Assumptions:
        - Adiabatic
        - Reversible

        Input pairs:
            - eta, PI
                - TAU is calculated
            - eta, TAU
                - PI is calculated

        :param eta: [-]  Isentropic efficiency
        :param PI:  [-]  Pressure ratio
        :param TAU: [-]  Temperature ratio

        :type eta:  float
        :type PI:   float
        :type TAU:  float

        :return:    process instance
        """

        k   = self.k(self.t0)
        cp  = self.cp(self.t0)

        p   = compression(mf  = self.mf,
                          cp  = cp,
                          k   = k,
                          t00 = self.t0,
                          p00 = self.p0,
                          eta = eta,
                          PI  = PI,
                          TAU = TAU,
                          )

        self.t0 = p.t01
        self.p0 = p.p01

        self.state()

        return p

    def expansion(self, eta,
                  PI=None,
                  TAU=None,
                  ):
        """
        Expansion
        ---------

        Assumptions:
        - Adiabatic
        - Reversible

        Input pairs:
            - PI, eta
                - TAU is calculated
            - TAU, eta
                - PI is calculated

        :param eta: [-]  Isentropic efficiency
        :param PI:  [-]  Pressure ratio
        :param TAU: [-]  Temperature ratio

        :type eta:  float
        :type PI:   float
        :type TAU:  float

        :return:    process instance
        """

        k   = self.k(self.t0)
        cp  = self.cp(self.t0)

        p   = expansion(mf  = self.mf,
                        cp  = cp,
                        k   = k,
                        t00 = self.t0,
                        p00 = self.p0,
                        eta = eta,
                        PI  = PI,
                        TAU = TAU,
                        )

        self.t0 = p.t01
        self.p0 = p.p01

        self.state()

        return p

    def heat_exchange(self,
                      eta,
                      cp,
                      Q_ex,
                      PI=1):
        """
        Isobaric heat exchange
        ----------------------

        Assumptions:
        - Perfect heat addition

        The pressure ratio is assumed to be constant,
        however a pressure ratio different than 1 can
        be input to the function in case the process
        cannot be assumed to be isobaric.

        :param eta:  Isentropic efficiency
        :param cp:   Specific heat of gas during heat addition
        :param Q_ex: Heat received by the gas in the heat exchange

        :type eta:   float
        :type cp:    float
        :type Q_ex:  float
        :type PI:    float
        """

        p = heat_exchange(mf       = self.mf,
                          cp       = cp,
                          t00      = self.t0,
                          p00      = self.p0,
                          Q_ex     = Q_ex,
                          eta      = eta,
                          PI       = PI)

        self.t0 = p.t01
        self.p0 = p.p01

        self.S  += Q_ex/self.t0

        self.state()

        return p


class fuel:
    """
    Fuel model
    ----------
    """
    def __init__(self, LHV,
                 mf=None):
        """
        :param LHV: Fuel Lower Heating Value (heat of combustion)
        :param mf:  Fuel mass flow
        """
        self.LHV = LHV
        self.mf = mf


class mixture(gas):
    """
    Mixture model
    -------------
    """

    @classmethod
    def _mix_t0(cls, gas1, gas2):
        """
        Total temperature of fluid mixture.
        """
        n = gas1.mf*gas1.cp(gas1.t0)*gas1.t0 + gas2.mf*gas2.cp(gas2.t0)*gas2.t0
        d = gas1.mf*gas1.cp(gas1.t0) + gas2.mf*gas2.cp(gas2.t0)
        t0_f = n / d
        return t0_f

    @classmethod
    def _mix_p0(cls, gas1, gas2):
        """
        Total pressure of fluid mixture.
        """
        n = gas1.p0*gas1.mf + gas2.p0*gas2.mf
        d = gas1.mf + gas2.mf
        p0_f = n / d
        return p0_f

    @classmethod
    def _mix_cp(cls, gas1, gas2):
        """
        Constant pressure specific heat at of fluid mixture.
        """
        cp_f = lambda t: (gas1.cp(t)*gas1.mf + gas2.cp(t)*gas2.mf) / (gas1.mf + gas2.mf)
        return cp_f

    @classmethod
    def _mix_k(cls, gas1, gas2):
        """
        Specific heat ratio of fluid mixture.
        """
        cp_f = lambda t: (gas1.k(t)*gas1.mf + gas2.k(t)*gas2.mf) / (gas1.mf + gas2.mf)
        return cp_f

    def __init__(self, gas1, gas2):
        """
        :param gas1: Mixture fluid 1
        :param gas2: Mixture fluid 2

        :type gas1:  gas or mixture
        :type gas2:  gas or mixture
        """

        mf = gas1.mf + gas2.mf
        super().__init__(mf  = mf,
                         cp  = self._mix_cp(gas1, gas2),
                         k   = self._mix_k(gas1, gas2),
                         m   = 0,
                         t_0 = self._mix_t0(gas1, gas2),
                         p_0 = self._mix_p0(gas1, gas2))

Classes

class fluid

Fluid

Expand source code
class fluid:
    """
    Fluid
    -----
    """
    @classmethod
    def _diversion(cls, f, fr):
        """
        Fluid diversion.
        - Diverted flow mass flow:       fraction*mf
        - Main flow mass flow:       (1-fraction)*mf

        :param f:  Fluid to be diverted.
        :param fr: Fraction of diverted fluid.

        :type f:   mixture or fluid
        :type fr:  0 <= float <= 1

        :return:   [fluid] Main flow
                   [fluid] Diverted flow
        """
        mf, df = deepcopy(f), deepcopy(f)

        mf.mf *= 1 - fr
        df.mf *= fr

        return mf, df

    def __mul__(self, other):
        """
        Return two flows representing the diversion.
        """
        return self._diversion(self, other)

    def __rmul__(self, other):
        """
        Return two flows representing the diversion.
        """
        return self._diversion(self, other)

Subclasses

class fuel (LHV, mf=None)

Fuel Model

:param LHV: Fuel Lower Heating Value (heat of combustion) :param mf: Fuel mass flow

Expand source code
class fuel:
    """
    Fuel model
    ----------
    """
    def __init__(self, LHV,
                 mf=None):
        """
        :param LHV: Fuel Lower Heating Value (heat of combustion)
        :param mf:  Fuel mass flow
        """
        self.LHV = LHV
        self.mf = mf
class gas (mf, cp, k, m, t_0, p_0)

Ideal Gas Model

All gas phenomena are modelled using its - Mass flow - Constant pressure specific heat capacity - Ratio of specific heat capacities

:param mf: [kg] Mass flow :param cp: [-] Constant pressure specific heat :param k: [-] Specific heat ratio :param m: [M] Flow Mach number | :param t_0: [K] Initial temperature | -> Total pressure and temperature calculated from inputs :param p_0: [Pa] Initial pressure |

:type mf: float :type cp: (T: float) -> float :type k: (T: float) -> float :type m: float :type t_0: float :type p_0: float

Expand source code
class gas(fluid):
    """
    Ideal gas model
    ---------------

    All gas phenomena are modelled using its
    - Mass flow
    - Constant pressure specific heat capacity
    - Ratio of specific heat capacities
    """
    def __init__(self, mf, cp, k,
                 m, t_0, p_0):
        """
        :param mf:  [kg] Mass flow
        :param cp:  [-]  Constant pressure specific heat
        :param k:   [-]  Specific heat ratio
        :param m:   [M]  Flow Mach number      |
        :param t_0: [K]  Initial temperature   | -> Total pressure and temperature calculated from inputs
        :param p_0: [Pa] Initial pressure      |

        :type mf:   float
        :type cp:   (T: float) -> float
        :type k:    (T: float) -> float
        :type m:    float
        :type t_0:  float
        :type p_0:  float
        """
        self.mf  = mf
        self.cp  = cp
        self.k   = k

        self.m   = m
        self.v_0 = m*(k(t_0)*R*t_0)**0.5

        self.t_0 = t_0
        self.p_0 = p_0

        self.absolute()

        # Set the gas' initial entropy as 0
        self.S = 0

    def state(self):
        """
        Update gas state variables.
        - V - Specific volume
        - S - Specific entropy
        - H - Specific enthalpy
        """
        self.V  =  self.t0*R/self.p0
        self.E  =  self.cp(self.t0)/self.k(self.t0)*self.t0
        self.H  =  self.E + self.p0*self.V

    def __add__(self, other):
        """
        Mixture creation operator: <gas> + <gas>

        In the case of adding fuel to a gas, the
        following assumptions are considered:
        - Total temperature and pressure of gas are
          unaltered.
        - Constant pressure specific heat capacity Cp
          of gas is unaltered.
        - Ratio of specific heats k of gas is unaltered.

        :type other: gas or fuel
        """
        if isinstance(other, gas):
            return mixture(self, other)
        if isinstance(other, fuel):
            self.mf += other.mf
            return self

    def __sub__(self, other):
        """
        Stream creation operator: <gas> + <component/stream>

        :type other: component or stream

        :return:     stream instance
        """
        if isinstance(other, component):
            s = stream(self)-other
            return s
        elif isinstance(other, stream):
            other.gas = self
            return other

    def absolute(self):
        """
        Returns the absolute temperature and pressure of a gas
        flowing at a certain Mach number.

        :return: process data class instance
        """

        k   = self.k(self.t_0)

        p = absolute(k   = k,
                     m   = self.m,
                     t_0 = self.t_0,
                     p_0 = self.p_0)

        self.t0 = p.t0
        self.p0 = p.p0

        self.state()

        return p

    def diffusion(self, eta,
                  PI=None,
                  TAU=None):
        """
        Diffusion
        ---------

        Assumptions:
        - Adiabatic
        - Reversible
        - Temperature remains constant through process

        The absolute pressure change is determined by the total pressure ratio
        _PI_ if provided. Else, _PI_ is calculated using the isentropic
        efficiency _nu_.

        :param eta: [-]  Isentropic efficiency
        :param PI:  [-]  Pressure ratio

        :type eta:  float
        :type PI:   float

        :return:    process instance
        """

        k   = self.k(self.t0)
        cp  = self.cp(self.t0)

        p = diffusion(mf  = self.mf,
                      cp  = cp,
                      k   = k,
                      m   = self.m,
                      t_0 = self.t_0,
                      p_0 = self.p_0,
                      eta = eta,
                      PI  = PI,
                      TAU = TAU,
                      t0  = self.t0 if hasattr(self, 't0') else None,
                      p0  = self.p0 if hasattr(self, 'p0') else None
                      )

        self.t0 = p.t01
        self.p0 = p.p01

        self.state()

        return p

    def compression(self, eta,
                    PI=None,
                    TAU=None,
                    ):
        """
        Compression
        -----------

        Assumptions:
        - Adiabatic
        - Reversible

        Input pairs:
            - eta, PI
                - TAU is calculated
            - eta, TAU
                - PI is calculated

        :param eta: [-]  Isentropic efficiency
        :param PI:  [-]  Pressure ratio
        :param TAU: [-]  Temperature ratio

        :type eta:  float
        :type PI:   float
        :type TAU:  float

        :return:    process instance
        """

        k   = self.k(self.t0)
        cp  = self.cp(self.t0)

        p   = compression(mf  = self.mf,
                          cp  = cp,
                          k   = k,
                          t00 = self.t0,
                          p00 = self.p0,
                          eta = eta,
                          PI  = PI,
                          TAU = TAU,
                          )

        self.t0 = p.t01
        self.p0 = p.p01

        self.state()

        return p

    def expansion(self, eta,
                  PI=None,
                  TAU=None,
                  ):
        """
        Expansion
        ---------

        Assumptions:
        - Adiabatic
        - Reversible

        Input pairs:
            - PI, eta
                - TAU is calculated
            - TAU, eta
                - PI is calculated

        :param eta: [-]  Isentropic efficiency
        :param PI:  [-]  Pressure ratio
        :param TAU: [-]  Temperature ratio

        :type eta:  float
        :type PI:   float
        :type TAU:  float

        :return:    process instance
        """

        k   = self.k(self.t0)
        cp  = self.cp(self.t0)

        p   = expansion(mf  = self.mf,
                        cp  = cp,
                        k   = k,
                        t00 = self.t0,
                        p00 = self.p0,
                        eta = eta,
                        PI  = PI,
                        TAU = TAU,
                        )

        self.t0 = p.t01
        self.p0 = p.p01

        self.state()

        return p

    def heat_exchange(self,
                      eta,
                      cp,
                      Q_ex,
                      PI=1):
        """
        Isobaric heat exchange
        ----------------------

        Assumptions:
        - Perfect heat addition

        The pressure ratio is assumed to be constant,
        however a pressure ratio different than 1 can
        be input to the function in case the process
        cannot be assumed to be isobaric.

        :param eta:  Isentropic efficiency
        :param cp:   Specific heat of gas during heat addition
        :param Q_ex: Heat received by the gas in the heat exchange

        :type eta:   float
        :type cp:    float
        :type Q_ex:  float
        :type PI:    float
        """

        p = heat_exchange(mf       = self.mf,
                          cp       = cp,
                          t00      = self.t0,
                          p00      = self.p0,
                          Q_ex     = Q_ex,
                          eta      = eta,
                          PI       = PI)

        self.t0 = p.t01
        self.p0 = p.p01

        self.S  += Q_ex/self.t0

        self.state()

        return p

Ancestors

Subclasses

Methods

def absolute(self)

Returns the absolute temperature and pressure of a gas flowing at a certain Mach number.

:return: process data class instance

Expand source code
def absolute(self):
    """
    Returns the absolute temperature and pressure of a gas
    flowing at a certain Mach number.

    :return: process data class instance
    """

    k   = self.k(self.t_0)

    p = absolute(k   = k,
                 m   = self.m,
                 t_0 = self.t_0,
                 p_0 = self.p_0)

    self.t0 = p.t0
    self.p0 = p.p0

    self.state()

    return p
def compression(self, eta, PI=None, TAU=None)

Compression

Assumptions: - Adiabatic - Reversible

Input pairs: - eta, PI - TAU is calculated - eta, TAU - PI is calculated

:param eta: [-] Isentropic efficiency :param PI: [-] Pressure ratio :param TAU: [-] Temperature ratio

:type eta: float :type PI: float :type TAU: float

:return: process instance

Expand source code
def compression(self, eta,
                PI=None,
                TAU=None,
                ):
    """
    Compression
    -----------

    Assumptions:
    - Adiabatic
    - Reversible

    Input pairs:
        - eta, PI
            - TAU is calculated
        - eta, TAU
            - PI is calculated

    :param eta: [-]  Isentropic efficiency
    :param PI:  [-]  Pressure ratio
    :param TAU: [-]  Temperature ratio

    :type eta:  float
    :type PI:   float
    :type TAU:  float

    :return:    process instance
    """

    k   = self.k(self.t0)
    cp  = self.cp(self.t0)

    p   = compression(mf  = self.mf,
                      cp  = cp,
                      k   = k,
                      t00 = self.t0,
                      p00 = self.p0,
                      eta = eta,
                      PI  = PI,
                      TAU = TAU,
                      )

    self.t0 = p.t01
    self.p0 = p.p01

    self.state()

    return p
def diffusion(self, eta, PI=None, TAU=None)

Diffusion

Assumptions: - Adiabatic - Reversible - Temperature remains constant through process

The absolute pressure change is determined by the total pressure ratio PI if provided. Else, PI is calculated using the isentropic efficiency nu.

:param eta: [-] Isentropic efficiency :param PI: [-] Pressure ratio

:type eta: float :type PI: float

:return: process instance

Expand source code
def diffusion(self, eta,
              PI=None,
              TAU=None):
    """
    Diffusion
    ---------

    Assumptions:
    - Adiabatic
    - Reversible
    - Temperature remains constant through process

    The absolute pressure change is determined by the total pressure ratio
    _PI_ if provided. Else, _PI_ is calculated using the isentropic
    efficiency _nu_.

    :param eta: [-]  Isentropic efficiency
    :param PI:  [-]  Pressure ratio

    :type eta:  float
    :type PI:   float

    :return:    process instance
    """

    k   = self.k(self.t0)
    cp  = self.cp(self.t0)

    p = diffusion(mf  = self.mf,
                  cp  = cp,
                  k   = k,
                  m   = self.m,
                  t_0 = self.t_0,
                  p_0 = self.p_0,
                  eta = eta,
                  PI  = PI,
                  TAU = TAU,
                  t0  = self.t0 if hasattr(self, 't0') else None,
                  p0  = self.p0 if hasattr(self, 'p0') else None
                  )

    self.t0 = p.t01
    self.p0 = p.p01

    self.state()

    return p
def expansion(self, eta, PI=None, TAU=None)

Expansion

Assumptions: - Adiabatic - Reversible

Input pairs: - PI, eta - TAU is calculated - TAU, eta - PI is calculated

:param eta: [-] Isentropic efficiency :param PI: [-] Pressure ratio :param TAU: [-] Temperature ratio

:type eta: float :type PI: float :type TAU: float

:return: process instance

Expand source code
def expansion(self, eta,
              PI=None,
              TAU=None,
              ):
    """
    Expansion
    ---------

    Assumptions:
    - Adiabatic
    - Reversible

    Input pairs:
        - PI, eta
            - TAU is calculated
        - TAU, eta
            - PI is calculated

    :param eta: [-]  Isentropic efficiency
    :param PI:  [-]  Pressure ratio
    :param TAU: [-]  Temperature ratio

    :type eta:  float
    :type PI:   float
    :type TAU:  float

    :return:    process instance
    """

    k   = self.k(self.t0)
    cp  = self.cp(self.t0)

    p   = expansion(mf  = self.mf,
                    cp  = cp,
                    k   = k,
                    t00 = self.t0,
                    p00 = self.p0,
                    eta = eta,
                    PI  = PI,
                    TAU = TAU,
                    )

    self.t0 = p.t01
    self.p0 = p.p01

    self.state()

    return p
def heat_exchange(self, eta, cp, Q_ex, PI=1)

Isobaric Heat Exchange

Assumptions: - Perfect heat addition

The pressure ratio is assumed to be constant, however a pressure ratio different than 1 can be input to the function in case the process cannot be assumed to be isobaric.

:param eta: Isentropic efficiency :param cp: Specific heat of gas during heat addition :param Q_ex: Heat received by the gas in the heat exchange

:type eta: float :type cp: float :type Q_ex: float :type PI: float

Expand source code
def heat_exchange(self,
                  eta,
                  cp,
                  Q_ex,
                  PI=1):
    """
    Isobaric heat exchange
    ----------------------

    Assumptions:
    - Perfect heat addition

    The pressure ratio is assumed to be constant,
    however a pressure ratio different than 1 can
    be input to the function in case the process
    cannot be assumed to be isobaric.

    :param eta:  Isentropic efficiency
    :param cp:   Specific heat of gas during heat addition
    :param Q_ex: Heat received by the gas in the heat exchange

    :type eta:   float
    :type cp:    float
    :type Q_ex:  float
    :type PI:    float
    """

    p = heat_exchange(mf       = self.mf,
                      cp       = cp,
                      t00      = self.t0,
                      p00      = self.p0,
                      Q_ex     = Q_ex,
                      eta      = eta,
                      PI       = PI)

    self.t0 = p.t01
    self.p0 = p.p01

    self.S  += Q_ex/self.t0

    self.state()

    return p
def state(self)

Update gas state variables. - V - Specific volume - S - Specific entropy - H - Specific enthalpy

Expand source code
def state(self):
    """
    Update gas state variables.
    - V - Specific volume
    - S - Specific entropy
    - H - Specific enthalpy
    """
    self.V  =  self.t0*R/self.p0
    self.E  =  self.cp(self.t0)/self.k(self.t0)*self.t0
    self.H  =  self.E + self.p0*self.V
class mixture (gas1, gas2)

Mixture Model

:param gas1: Mixture fluid 1 :param gas2: Mixture fluid 2

:type gas1: gas or mixture :type gas2: gas or mixture

Expand source code
class mixture(gas):
    """
    Mixture model
    -------------
    """

    @classmethod
    def _mix_t0(cls, gas1, gas2):
        """
        Total temperature of fluid mixture.
        """
        n = gas1.mf*gas1.cp(gas1.t0)*gas1.t0 + gas2.mf*gas2.cp(gas2.t0)*gas2.t0
        d = gas1.mf*gas1.cp(gas1.t0) + gas2.mf*gas2.cp(gas2.t0)
        t0_f = n / d
        return t0_f

    @classmethod
    def _mix_p0(cls, gas1, gas2):
        """
        Total pressure of fluid mixture.
        """
        n = gas1.p0*gas1.mf + gas2.p0*gas2.mf
        d = gas1.mf + gas2.mf
        p0_f = n / d
        return p0_f

    @classmethod
    def _mix_cp(cls, gas1, gas2):
        """
        Constant pressure specific heat at of fluid mixture.
        """
        cp_f = lambda t: (gas1.cp(t)*gas1.mf + gas2.cp(t)*gas2.mf) / (gas1.mf + gas2.mf)
        return cp_f

    @classmethod
    def _mix_k(cls, gas1, gas2):
        """
        Specific heat ratio of fluid mixture.
        """
        cp_f = lambda t: (gas1.k(t)*gas1.mf + gas2.k(t)*gas2.mf) / (gas1.mf + gas2.mf)
        return cp_f

    def __init__(self, gas1, gas2):
        """
        :param gas1: Mixture fluid 1
        :param gas2: Mixture fluid 2

        :type gas1:  gas or mixture
        :type gas2:  gas or mixture
        """

        mf = gas1.mf + gas2.mf
        super().__init__(mf  = mf,
                         cp  = self._mix_cp(gas1, gas2),
                         k   = self._mix_k(gas1, gas2),
                         m   = 0,
                         t_0 = self._mix_t0(gas1, gas2),
                         p_0 = self._mix_p0(gas1, gas2))

Ancestors

Inherited members