Пример #1
0
 def from_abstract_state(cls, state: CoolProp.AbstractState):
     new_state = cls(state.backend_name(), '&'.join(state.fluid_names()))
     # Uses mass fraction to work with incompressible fluids
     masses = state.get_mass_fractions()
     if len(masses) > 1:
         new_state.set_mass_fractions(masses)
     try:
         rho = state.rhomolar()
         T = state.T()
         new_state.update(CoolProp.DmolarT_INPUTS, rho, T)
     except:
         pass
     return new_state
Пример #2
0
class Fluid:
    """Represents a fluid."""
    def __init__(self, name: str, eos: str = 'HEOS'):
        """Initiate a Fluid instance.

        :param ID: id of fluid
        """

        self.name = name
        self.eos = eos.upper()
        self.state = AbstractState(self.eos, self.name)

        if self.state.name() not in ["NitrousOxide"]:
            raise NotImplementedError(
                f'{self.state.name()} is not supported currently')
        self.Tmax = 309.5  # self.state.Tmax()
        self.Tmin = 182.23  # self.state.Tmin()
        self.pmax = self.state.pmax()
        self.pmin = 0

    def copy(self):
        fluid = Fluid(self.name, self.eos)
        fluid.set_state(P=self.state.p(), T=self.state.T())
        return fluid

    def set_state(self,
                  D: float = None,
                  P: float = None,
                  T: float = None,
                  Q: float = None,
                  H: float = None,
                  S: float = None,
                  U: float = None):

        args_present = {
            'D': D is not None,
            'P': P is not None,
            'T': T is not None,
            'Q': Q is not None,
            'H': H is not None,
            'S': S is not None,
            'U': U is not None
        }

        if sum(args_present.values()) != 2:
            raise ValueError(
                f'Must have exactly 2 arguments: {sum(args_present.values())} provided'
            )
        args = []
        if args_present['D']:
            if args_present['P']:
                args = CP.DmassP_INPUTS, D, P
            elif args_present['T']:
                args = CP.DmassT_INPUTS, D, T
            elif args_present['Q']:
                args = CP.DmassQ_INPUTS, D, Q
            elif args_present['H']:
                args = CP.DmassHmass_INPUTS, D, H
            elif args_present['S']:
                args = CP.DmassSmass_INPUTS, D, S
            elif args_present['U']:
                args = CP.DmassUmass_INPUTS, D, U
        elif args_present['P']:
            if args_present['T']:
                args = CP.PT_INPUTS, P, T
            elif args_present['Q']:
                args = CP.PQ_INPUTS, P, Q
            elif args_present['H']:
                args = CP.HmassP_INPUTS, H, P
            elif args_present['S']:
                args = CP.PSmass_INPUTS, P, S
            elif args_present['U']:
                args = CP.PUmass_INPUTS, P, U
        elif args_present['T']:
            if args_present['Q']:
                args = CP.QT_INPUTS, Q, T
            elif args_present['H']:
                args = CP.HmassT_INPUTS, H, T
            elif args_present['S']:
                args = CP.SmassT_INPUTS, S, T
            elif args_present['U']:
                args = CP.TUmass_INPUTS, T, U
        elif args_present['Q']:
            if args_present['H']:
                args = CP.HmassQ_INPUTS, H, Q
            elif args_present['S']:
                args = CP.QSmass_INPUTS, Q, S
            elif args_present['U']:
                raise ValueError('Invalid combination: Q and U')
        elif args_present['H']:
            if args_present['S']:
                args = CP.HmassSmass_INPUTS, H, S
            elif args_present['U']:
                raise ValueError('Invalid combination: H and U')
        elif args_present['S'] and args_present['U']:
            args = CP.SmassUmass_INPUTS, S, U
        else:
            raise ValueError('Invalid combination')

        try:
            self.state.update(*args)
        except ValueError:
            pass

    def Vf(self, S: float):
        x = self.chi()
        return 1 / (1 /
                    (1 + S * ((1 - x) / x) * self.rhog([self.state.T()])[0] /
                     self.rhol([self.state.T()])[0]))

    def chi(self):
        x = self.state.Q()
        if x >= 0:
            return x
        if self.state.rhomass() > self.rhol([self.state.T()])[0]:
            return 0
        else:
            return 1

    def viscosityl(self, T):
        b1 = 1.6089
        b2 = 2.0439
        b3 = 5.24
        b4 = 0.0293423
        theta = (self.state.T_critical() - b3) / (T - b3)
        return b4 * np.exp(b1 * (theta - 1)**(1 / 3) + b2 *
                           (theta - 1)**(4 / 3))

    def viscosityg(self, T):
        b1 = 3.3281
        b2 = -1.18237
        b3 = -0.055155
        Tr = T / self.state.T_critical()
        return 0.001 * np.exp(b1 + b2 * (1 / Tr - 1)**(1 / 3) + b3 *
                              (1 / Tr - 1)**(4 / 3)) if (
                                  self.Tmin < T < self.Tmax) else None

    def viscosity(self):
        T = self.state.T()
        mug = self.viscosityg(T)
        mul = self.viscosityl(T)
        x = self.chi()
        rho = self.state.rhomass()
        rhol = self.rhol([T])[0]
        rhog = self.rhog([T])[0]
        return mug * x * rho / rhog + mul * (1 - x) * rho / rhol

    def dvg_dP_saturation(self):
        dP = 0.002
        rho1 = PropsSI('D', 'P', self.state.p() + dP / 2, 'Q', 1, self.name)
        rho0 = PropsSI('D', 'P', self.state.p() - dP / 2, 'Q', 1, self.name)
        dvg = 1 / rho1 - 1 / rho0
        return dvg / dP

    def rhol(self, T: Iterable):
        return [
            PropsSI('D', 'T', t, 'Q', 0, self.eos + "::" + self.name)
            for t in T
        ]

    def rhog(self, T: Iterable):
        return [
            PropsSI('D', 'T', t, 'Q', 1, self.eos + "::" + self.name)
            for t in T
        ]

    def psat(self, T: Iterable):
        return [
            PropsSI('P', 'Q', 0.5, 'T', t, self.eos + "::" + self.name) if
            (self.Tmin < t < self.Tmax) else None for t in T
        ]

    def tsat(self, P: Iterable):
        return [
            PropsSI('T', 'P', P, 'Q', 0.5, self.eos + "::" + self.name) if
            (self.pmin < p < self.pmax) else None for p in P
        ]

    def hl(self, T: Iterable):
        return [
            PropsSI('H', 'T', t, 'Q', 0, self.eos + "::" + self.name) if
            (self.Tmin < t < self.Tmax) else None for t in T
        ]

    def hg(self, T: Iterable):
        return [
            PropsSI('H', 'T', t, 'Q', 1, self.eos + "::" + self.name) if
            (self.Tmin < t < self.Tmax) else None for t in T
        ]

    def sl(self, T: Iterable):
        return [
            PropsSI('S', 'T', t, 'Q', 0, self.eos + "::" + self.name) if
            (self.Tmin < t < self.Tmax) else None for t in T
        ]

    def sg(self, T: Iterable):
        return [
            PropsSI('S', 'T', t, 'Q', 1, self.eos + "::" + self.name) if
            (self.Tmin < t < self.Tmax) else None for t in T
        ]

    def __repr__(self):
        return f'Fluid({self.name}: p={self.state.p() / 100000:.1f}bar, t={self.state.T():.1f}K)'