예제 #1
0
    def __init__(self, identifier: str = 'gas',
                 latex: Optional[str] = None,
                 comment: Optional[str] = None) -> None:
        """
        Args:
            identifier:
                Identifier of matter

            latex:
                Latex-version of identifier. If None, identical with identifier

            comment:
                Comment on matter

        Note:
            Do NOT define a self.__call__() method in this class
        """
        super().__init__(identifier=identifier, latex=latex, comment=comment)

        # self.a.calc = self._a
        self.D_in_air = Property('D_in_air', 'm2/s', 
                                 calc=lambda T, p=atm(), x=0.: None)
        self.T.ref = C2K(15.)        


        
예제 #2
0
    def _rho_el(self,
                T: float = C2K(20),
                p: float = atm(),
                x: float = 0.) -> float:
        """
        Reference:
            Rykalin, in Radaj: Heat Effects of Welding, Springer 1992, p.68
            T[deg C]  rho [Ohm*mm]
            0         1.26e-4
            400       4e-4
            800       10.2e-4
            1200      12e-4
            1600      12.6e-4
        """
        T_Celsius = max(K2C(T), 20.)

        # specific resistance in [Ohm m]
        if T_Celsius < 800:
            rho_el = (
                (1.081e-8 * T_Celsius + 2.53e-6) * T_Celsius + 1.26e-3) * 1e-4
        elif T < self.T_sol:
            rho_el = (
                (-3.75e-9 * T_Celsius + 1.2e-5) * T_Celsius + 3e-3) * 1e-4
        else:
            rho_el = 2 * 1.2e-6
        return rho_el
예제 #3
0
    def __init__(self, identifier: str = 'matter',
                 latex: Optional[str] = None,
                 comment: Optional[str] = None) -> None:
        """
        Args:
            identifier:
                Identifier of matter

            latex:
                Latex-version of identifier. 
                If None, latex is identical with identifier

            comment:
                Comment on matter

        Note:
            Do NOT define a self.__call__() method in this class
        """
        super().__init__(identifier=identifier, latex=latex, comment=comment)

        self.a = Property('a', 'm$^2$/s', comment='thermal diffusity',
                          calc = self._a)        
        self.beta = Property('beta', '1/K', latex=r'$\beta_{th}$',
                             comment='volumetric thermal expansion')
        self.c_p = Property('c_p', 'J/kg/K',
                            comment='specific heat capacity')
        self.c_sound = Property('c_sound', 'm/s', latex='$c_{sound}$')
        self.c_sound.calc = lambda T, p, x: None
        self.composition: Dict[str, float] = OrderedDict()
        self.compressible: bool = False
        self.E = Property('E', 'Pa', comment="Young's (elastic) modulus")
        self.h_melt: float = None
        self.h_vap: float = None
        self.k = Property('k', 'W/m/K', latex='$k$',
                                comment='thermal conductivity')
        self.M = Property('M', 'kmol/kg', comment='molar mass')
        self.M.calc = lambda T=0, p=0, x=0: None
        self.nu_mech: float = None
        self.rho = Property('rho', 'kg/m$^3$', latex=r'$\varrho$', ref=1.,
                            comment='density')
        self.rho.T.ref = C2K(20.)
        self.rho.p.ref = atm()
        self.rho_el = Property('rho_el', r'$\Omega$', latex=r'$\varrho_{el}$',
                               comment='electric resistance')
        self.T_boil: float = 0.
        self.T_flash_point: float = 0.
        self.T_liq: float = 0.
        self.T_melt: float = 0.
        self.T_sol: float = 0.

        if self.E() is None or np.abs(self.E()) < 1e-20:
            self.rho.calc = lambda T, p, x: self.rho.ref \
                / (1. + (T - self.rho.T.ref) * self.beta())
        else:
            self.rho.calc = lambda T, p, x: self.rho.ref \
                / (1. + (T - self.rho.T.ref) * self.beta()) \
                / (1. - (p - self.rho.p.ref) / self.E())
예제 #4
0
 def _nu(self, T: float, p: float = atm(), 
         x: float = 0.) -> Optional[float]:
     try:
         rho = self.rho(T, p, x)
         if rho is None or np.abs(rho) < 1e-10:
             return None
         return self.mu(T, p, x) / rho
     except:
         return None
예제 #5
0
 def _mu(self,
         T: float = C2K(20),
         p: float = atm(),
         x: float = 0.) -> float:
     """
     [JONE96]: eta = eta0 * exp(E / (R*T)), eta0 = 0.3699e-3 kg/(m s),
               E = 41.4e3 J/mol, and R = 8.3144 J/(K mol)
     """
     return 0.3699e-3 * np.exp(41.4e3 / (8.3144*T)) \
         if T > self.T_deform else 1e20
예제 #6
0
 def set_all_ref(self, T: float, p: float = atm(), x: float = 0.) -> bool:
     none_set = True 
     for attr in dir(self):
         if not attr.startswith('_'):
             val = getattr(self, attr)
             if isinstance(val, Property):
                 print(f'{attr=}, {val=}')
                 none_set = False
                 val.T.ref = T
                 val.p.ref = p
                 val.x.ref = x
     return not none_set
예제 #7
0
 def _a(self, T: float, p: float = atm(), x: float = 0.) -> Optional[float]:
     try:
         k = self.k(T, p, x)
         c_p = self.c_p(T, p, x)
         rho = self.rho(T, p, x)
         if k is None or c_p is None or rho is None:
             return None
         c_p__rho = c_p * rho
         if np.abs(c_p__rho) < 1e-10:
             return None
         return k / c_p__rho
     except:
         return None
예제 #8
0
 def _c_p(self,
          T: float = C2K(20),
          p: float = atm(),
          x: float = 0.) -> float:
     Tp = [
         300, 600, 900, 1033, 1040, 1184, 1184.1, 1400, 1673, 1673.1, 1809,
         1809.1, 2000, 3000
     ]
     Up = [
         430, 580, 760, 1260, 1160, 720, 610, 640, 680, 730, 760, 790, 790,
         790
     ]
     return np.interp(T, Tp, Up)
예제 #9
0
    def _mu(self, T: float, p: float = atm(), x: float = 0.) -> float:
        y_all, M_all, mu_all = [], [], []

        for gas, mole_frac in self.components.items():
            if mole_frac < 1e-8:
                continue
            p_partial = mole_frac * p

            y_all.append(mole_frac)
            M_all.append(gas.M(T, p, x))
            mu_all.append(gas.mu(T, p_partial, x))

        return mix_mole(y=y_all, M=M_all, property_=mu_all)
예제 #10
0
    def _rho(self, T: float, p: float = atm(), x: float = 0.) -> float:
        rho = 0.
        for gas, mole_frac in self.components.items():
            if mole_frac < 1e-8:
                continue
            p_partial = mole_frac * p

            rho_i = gas.rho(T, p_partial, x)
            if rho_i is None:
                return None

            rho += mole_frac * rho_i

        return rho
예제 #11
0
 def _rho(self,
          T: float = C2K(20),
          p: float = atm(),
          x: float = 0.) -> float:
     """
     Reference for liquid iron:
     Steinberg, D. J.: Met. Trans. 5 (1974), 1341, in [Iida93]
     """
     T_Celsius = min(K2C(T), 1600)
     if T_Celsius > 1536:
         rho = 7030 + (-8.8e-1) * (T_Celsius - 1536)
     elif T_Celsius > 723:
         rho = (-1e-4 * T_Celsius - 0.2) * T_Celsius + 7852.3
     else:
         rho = (-1e-4 * T_Celsius - 0.3) * T_Celsius + 7849.1
     return rho
예제 #12
0
    def __init__(self,
                 identifier: str = 'Property',
                 unit: str = '/',
                 absolute: bool = True,
                 latex: Optional[str] = None,
                 val: Optional[Union[float, Iterable[float]]] = None,
                 ref: Optional[Union[float, Iterable[float]]] = None,
                 comment: Optional[str] = None,
                 calc: Optional[Callable[..., float]] = None) -> None:

        super().__init__(identifier=identifier,
                         unit=unit,
                         absolute=absolute,
                         latex=latex,
                         val=val,
                         ref=ref,
                         comment=comment)

        # reference temperature gases: 15C, solids: 20C or 25C, liquids: 20C
        T_Celsius = 20.

        self.T = Parameter(identifier='T', unit='K', absolute=True)
        self.T.ref = C2K(T_Celsius)
        self.T['operational'] = Range(C2K(-40.), C2K(200.))
        self.T.accuracy = Range('-1', '+1')

        self.p = Parameter(identifier='p', unit='Pa', absolute=True)
        self.p.ref = atm()
        self.p['operational'] = Range(0. + self.p.ref, 100e5 + self.p.ref)
        self.p.accuracy = Range('-1%FS', '+1%FS')

        self.x = Parameter(identifier='x', unit='/', absolute=True)
        self.x['operational'] = Range(0., 1.)
        self.x.ref = 0.

        self.accuracy = Range('-1%', '1%')
        self.repeatability = Range('-0.1', '+0.1', '95%')

        if calc is None:
            calc = lambda T, p, x: 1.
        self.calc = calc

        self.regression_coefficients: Optional[Iterable[float]] = None
예제 #13
0
    def _k(self, T: float, p: float = atm(), x: float = 0.) -> float:
        y_all, M_all, k_all, mu_all = [], [], [], []

        for gas, mole_frac in self.components.items():
            if mole_frac < 1e-8:
                continue
            p_partial = mole_frac * p

            y_all.append(mole_frac)
            M_all.append(gas.M(T, p, x))
            k_all.append(gas.k(T, p_partial, x))
            mu_all.append(gas.mu(T, p_partial, x))

        if self._k_mix_formula.startswith('mas'):
            k = mix_mason(y=y_all, M=M_all, k=k_all, mu=mu_all)
        else:
            k = mix_mole(y=y_all, M=M_all, property_=k_all)

        return k
예제 #14
0
 def _mu(self, T: float, p: float = atm(), 
         x: float = 0.) -> Optional[float]:
     try:
         return self.nu(T, p, x) * self.rho(T, p, x)
     except:
         return None
예제 #15
0
 def _k(self, T: float = C2K(20), p: float = atm(), x: float = 0.) -> float:
     Tp = [
         300, 600, 900, 1184, 1400, 1673, 1673.1, 1809, 1809.1, 2000, 3000
     ]
     Up = [59.6, 54.6, 37.4, 28.2, 30.6, 33.7, 33.4, 34.6, 40.3, 42.6, 48]
     return np.interp(T, Tp, Up)