def Tliquidus(Tms=None, ws=None, xs=None, CASRNs=None, AvailableMethods=False, Method=None): # pragma: no cover '''This function handles the retrival of a mixtures's liquidus point. This API is considered experimental, and is expected to be removed in a future release in favor of a more complete object-oriented interface. >>> Tliquidus(Tms=[250.0, 350.0], xs=[0.5, 0.5]) 350.0 >>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], Method='Simple') 300.0 >>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], AvailableMethods=True) ['Maximum', 'Simple', 'None'] ''' def list_methods(): methods = [] if none_and_length_check([Tms]): methods.append('Maximum') methods.append('Simple') methods.append('None') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] # This is the calculate, given the method section if Method == 'Maximum': _Tliq = max(Tms) elif Method == 'Simple': _Tliq = mixing_simple(xs, Tms) elif Method == 'None': return None else: raise Exception('Failure in in function') return _Tliq
def Tliquidus(Tms=None, ws=None, xs=None, CASRNs=None, AvailableMethods=False, Method=None): # pragma: no cover '''This function handles the retrival of a mixtures's liquidus point. This API is considered experimental, and is expected to be removed in a future release in favor of a more complete object-oriented interface. >>> Tliquidus(Tms=[250.0, 350.0], xs=[0.5, 0.5]) 350.0 >>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], Method='Simple') 300.0 >>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], AvailableMethods=True) ['Maximum', 'Simple', 'None'] ''' def list_methods(): methods = [] if none_and_length_check([Tms]): methods.append('Maximum') methods.append('Simple') methods.append('None') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] # This is the calculate, given the method section if Method == 'Maximum': _Tliq = max(Tms) elif Method == 'Simple': _Tliq = mixing_simple(xs, Tms) elif Method == 'None': return None else: raise Exception('Failure in in function') return _Tliq
def Winterfeld_Scriven_Davis(xs, sigmas, rhoms): r'''Calculates surface tension of a liquid mixture according to mixing rules in [1]_ and also in [2]_. .. math:: \sigma_M = \sum_i \sum_j \frac{1}{V_L^{L2}}\left(x_i V_i \right) \left( x_jV_j\right)\sqrt{\sigma_i\cdot \sigma_j} Parameters ---------- xs : array-like Mole fractions of all components, [-] sigmas : array-like Surface tensions of all components, [N/m] rhoms : array-like Molar densities of all components, [mol/m^3] Returns ------- sigma : float Air-liquid surface tension of mixture, [N/m] Notes ----- DIPPR Procedure 7C: Method for the Surface Tension of Nonaqueous Liquid Mixtures Becomes less accurate as liquid-liquid critical solution temperature is approached. DIPPR Evaluation: 3-4% AARD, from 107 nonaqueous binary systems, 1284 points. Internally, densities are converted to kmol/m^3. The Amgat function is used to obtain liquid mixture density in this equation. Raises a ZeroDivisionError if either molar volume are zero, and a ValueError if a surface tensions of a pure component is negative. Examples -------- >>> Winterfeld_Scriven_Davis([0.1606, 0.8394], [0.01547, 0.02877], ... [8610., 15530.]) 0.024967388450439817 References ---------- .. [1] Winterfeld, P. H., L. E. Scriven, and H. T. Davis. "An Approximate Theory of Interfacial Tensions of Multicomponent Systems: Applications to Binary Liquid-Vapor Tensions." AIChE Journal 24, no. 6 (November 1, 1978): 1010-14. doi:10.1002/aic.690240610. .. [2] Danner, Ronald P, and Design Institute for Physical Property Data. Manual for Predicting Chemical Process Design Data. New York, N.Y, 1982. ''' if not none_and_length_check([xs, sigmas, rhoms]): raise Exception('Function inputs are incorrect format') rhoms = [i/1E3 for i in rhoms] Vms = [(i)**-1 for i in rhoms] rho = 1./mixing_simple(xs, Vms) sigma = 0 for i in range(len(xs)): for j in range(len(xs)): sigma += rho**2*xs[i]/rhoms[i]*xs[j]/rhoms[j]*(sigmas[j]*sigmas[i])**0.5 return sigma
def Winterfeld_Scriven_Davis(xs, sigmas, rhoms): r'''Calculates surface tension of a liquid mixture according to mixing rules in [1]_ and also in [2]_. .. math:: \sigma_M = \sum_i \sum_j \frac{1}{V_L^{L2}}\left(x_i V_i \right) \left( x_jV_j\right)\sqrt{\sigma_i\cdot \sigma_j} Parameters ---------- xs : array-like Mole fractions of all components, [-] sigmas : array-like Surface tensions of all components, [N/m] rhoms : array-like Molar densities of all components, [mol/m^3] Returns ------- sigma : float Air-liquid surface tension of mixture, [N/m] Notes ----- DIPPR Procedure 7C: Method for the Surface Tension of Nonaqueous Liquid Mixtures Becomes less accurate as liquid-liquid critical solution temperature is approached. DIPPR Evaluation: 3-4% AARD, from 107 nonaqueous binary systems, 1284 points. Internally, densities are converted to kmol/m^3. The Amgat function is used to obtain liquid mixture density in this equation. Raises a ZeroDivisionError if either molar volume are zero, and a ValueError if a surface tensions of a pure component is negative. Examples -------- >>> Winterfeld_Scriven_Davis([0.1606, 0.8394], [0.01547, 0.02877], ... [8610., 15530.]) 0.024967388450439817 References ---------- .. [1] Winterfeld, P. H., L. E. Scriven, and H. T. Davis. "An Approximate Theory of Interfacial Tensions of Multicomponent Systems: Applications to Binary Liquid-Vapor Tensions." AIChE Journal 24, no. 6 (November 1, 1978): 1010-14. doi:10.1002/aic.690240610. .. [2] Danner, Ronald P, and Design Institute for Physical Property Data. Manual for Predicting Chemical Process Design Data. New York, N.Y, 1982. ''' if not none_and_length_check([xs, sigmas, rhoms]): raise Exception('Function inputs are incorrect format') rhoms = [i/1E3 for i in rhoms] Vms = [(i)**-1 for i in rhoms] rho = 1./mixing_simple(xs, Vms) sigma = 0 for i in range(len(xs)): for j in range(len(xs)): sigma += rho**2*xs[i]/rhoms[i]*xs[j]/rhoms[j]*(sigmas[j]*sigmas[i])**0.5 return sigma
def calculate(self, T, P, zs, ws, method): if method == SIMPLE: sigmas = [i(T) for i in self.SurfaceTensions] return mixing_simple(zs, sigmas) elif method == DIGUILIOTEJA: return Diguilio_Teja(T=T, xs=zs, sigmas_Tb=self.sigmas_Tb, Tbs=self.Tbs, Tcs=self.Tcs) elif method == WINTERFELDSCRIVENDAVIS: sigmas = [i(T) for i in self.SurfaceTensions] rhoms = [1. / i(T, P) for i in self.VolumeLiquids] return Winterfeld_Scriven_Davis(zs, sigmas, rhoms) else: raise Exception('Method not valid')
def calculate(self, T, P, zs, ws, method): r'''Method to calculate surface tension of a liquid mixture at temperature `T`, pressure `P`, mole fractions `zs` and weight fractions `ws` with a given method. This method has no exception handling; see `mixture_property` for that. Parameters ---------- T : float Temperature at which to calculate the property, [K] P : float Pressure at which to calculate the property, [Pa] zs : list[float] Mole fractions of all species in the mixture, [-] ws : list[float] Weight fractions of all species in the mixture, [-] method : str Name of the method to use Returns ------- sigma : float Surface tension of the liquid at given conditions, [N/m] ''' if method == SIMPLE: sigmas = [i(T) for i in self.SurfaceTensions] return mixing_simple(zs, sigmas) elif method == DIGUILIOTEJA: return Diguilio_Teja(T=T, xs=zs, sigmas_Tb=self.sigmas_Tb, Tbs=self.Tbs, Tcs=self.Tcs) elif method == WINTERFELDSCRIVENDAVIS: sigmas = [i(T) for i in self.SurfaceTensions] rhoms = [1. / i(T, P) for i in self.VolumeLiquids] return Winterfeld_Scriven_Davis(zs, sigmas, rhoms) else: raise Exception('Method not valid')
def omega_mixture(omegas, zs, CASRNs=None, Method=None, AvailableMethods=False): # TODO Use or remove CASRNs argument r'''This function handles the calculation of a mixture's acentric factor. Calculation is based on the omegas provided for each pure component. Will automatically select a method to use if no Method is provided; returns None if insufficient data is available. Examples -------- >>> omega_mixture([0.025, 0.12], [0.3, 0.7]) 0.0915 Parameters ---------- omegas : array-like acentric factors of each component, [-] zs : array-like mole fractions of each component, [-] CASRNs: list of strings CASRNs, not currently used [-] Returns ------- omega : float acentric factor of the mixture, [-] methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain omega with the given inputs Other Parameters ---------------- Method : string, optional The method name to use. Only 'SIMPLE' is accepted so far. All valid values are also held in the list omega_mixture_methods. AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain omega for the desired chemical, and will return methods instead of omega Notes ----- The only data used in the methods implemented to date are mole fractions and pure-component omegas. An alternate definition could be based on the dew point or bubble point of a multicomponent mixture, but this has not been done to date. References ---------- .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. ''' def list_methods(): ''' List methods available for calculating a mixture's acentric factor, omega ''' methods = [] if none_and_length_check([zs, omegas]): methods.append('SIMPLE') methods.append('NONE') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] if Method == 'SIMPLE': _omega = mixing_simple(zs, omegas) elif Method == 'NONE': _omega = None else: raise Exception('Failure in in function') return _omega
def Diguilio_Teja(T, xs, sigmas_Tb, Tbs, Tcs): r'''Calculates surface tension of a liquid mixture according to mixing rules in [1]_. .. math:: \sigma = 1.002855(T^*)^{1.118091} \frac{T}{T_b} \sigma_r T^* = \frac{(T_c/T)-1}{(T_c/T_b)-1} \sigma_r = \sum x_i \sigma_i T_b = \sum x_i T_{b,i} T_c = \sum x_i T_{c,i} Parameters ---------- T : float Temperature of fluid [K] xs : array-like Mole fractions of all components sigmas_Tb : array-like Surface tensions of all components at the boiling point, [N/m] Tbs : array-like Boiling temperatures of all components, [K] Tcs : array-like Critical temperatures of all components, [K] Returns ------- sigma : float Air-liquid surface tension of mixture, [N/m] Notes ----- Simple model, however it has 0 citations. Gives similar results to the `Winterfeld_Scriven_Davis` model. Raises a ValueError if temperature is greater than the mixture's critical temperature or if the given temperature is negative, or if the mixture's boiling temperature is higher than its critical temperature. Examples -------- >>> Diguilio_Teja(T=298.15, xs=[0.1606, 0.8394], ... sigmas_Tb=[0.01424, 0.02530], Tbs=[309.21, 312.95], Tcs=[469.7, 508.0]) 0.025716823875045505 References ---------- .. [1] Diguilio, Ralph, and Amyn S. Teja. "Correlation and Prediction of the Surface Tensions of Mixtures." The Chemical Engineering Journal 38, no. 3 (July 1988): 205-8. doi:10.1016/0300-9467(88)80079-0. ''' if not none_and_length_check([xs, sigmas_Tb, Tbs, Tcs]): raise Exception('Function inputs are incorrect format') Tc = mixing_simple(xs, Tcs) Tb = mixing_simple(xs, Tbs) sigmar = mixing_simple(xs, sigmas_Tb) Tst = (Tc / T - 1.) / (Tc / Tb - 1) sigma = 1.002855 * Tst**1.118091 * (T / Tb) * sigmar return sigma
def surface_tension_mixture(T=None, xs=[], sigmas=[], rhoms=[], Tcs=[], Tbs=[], sigmas_Tb=[], CASRNs=None, AvailableMethods=False, Method=None): r'''This function handles the calculation of a mixture's surface tension. Calculation is based on the surface tensions provided for each pure component. Will automatically select a method to use if no Method is provided; returns None if insufficient data is available. Prefered method is `Winterfeld_Scriven_Davis` which requires mole fractions, pure component surface tensions, and the molar density of each pure component. `Diguilio_Teja` is of similar accuracy, but requires the surface tensions of pure components at their boiling points, as well as boiling points and critical points and mole fractions. An ideal mixing rule based on mole fractions, `Simple`, is also available and is still relatively accurate. Examples -------- >>> surface_tension_mixture(xs=[0.1606, 0.8394], sigmas=[0.01547, 0.02877]) 0.02663402 Parameters ---------- T : float, optional Temperature of fluid [K] xs : array-like Mole fractions of all components sigmas : array-like, optional Surface tensions of all components, [N/m] rhoms : array-like, optional Molar densities of all components, [mol/m^3] Tcs : array-like, optional Critical temperatures of all components, [K] Tbs : array-like, optional Boiling temperatures of all components, [K] sigmas_Tb : array-like, optional Surface tensions of all components at the boiling point, [N/m] CASRNs : list of strings, optional CASRNs, not currently used [-] Returns ------- sigma : float Air-liquid surface tension of mixture, [N/m] methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain sigma with the given inputs Other Parameters ---------------- Method : string, optional A string for the method name to use, as defined by constants in surface_tension_mixture_methods AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain sigma for the desired chemical, and will return methods instead of sigma Notes ----- References ---------- .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. ''' def list_methods(): methods = [] if none_and_length_check([xs, sigmas, rhoms]): methods.append(WINTERFELDSCRIVENDAVIS) if T and none_and_length_check([xs, sigmas_Tb, Tbs, Tcs]): methods.append(DIGUILIOTEJA) if none_and_length_check([xs, sigmas]): methods.append(SIMPLE) methods.append(NONE) return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] if Method == SIMPLE: sigma = mixing_simple(xs, sigmas) elif Method == WINTERFELDSCRIVENDAVIS: sigma = Winterfeld_Scriven_Davis(xs, sigmas, rhoms) elif Method == DIGUILIOTEJA: sigma = Diguilio_Teja(T=T, xs=xs, sigmas_Tb=sigmas_Tb, Tbs=Tbs, Tcs=Tcs) elif Method == NONE: sigma = None else: raise Exception('Failure in in function') return sigma
def omega_mixture(omegas, zs, CASRNs=None, Method=None, AvailableMethods=False): r'''This function handles the calculation of a mixture's acentric factor. Calculation is based on the omegas provided for each pure component. Will automatically select a method to use if no Method is provided; returns None if insufficient data is available. Examples -------- >>> omega_mixture([0.025, 0.12], [0.3, 0.7]) 0.0915 Parameters ---------- omegas : array-like acentric factors of each component, [-] zs : array-like mole fractions of each component, [-] CASRNs: list of strings CASRNs, not currently used [-] Returns ------- omega : float acentric factor of the mixture, [-] methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain omega with the given inputs Other Parameters ---------------- Method : string, optional The method name to use. Only 'SIMPLE' is accepted so far. All valid values are also held in the list omega_mixture_methods. AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain omega for the desired chemical, and will return methods instead of omega Notes ----- The only data used in the methods implemented to date are mole fractions and pure-component omegas. An alternate definition could be based on the dew point or bubble point of a multicomponent mixture, but this has not been done to date. References ---------- .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. ''' def list_methods(): methods = [] if none_and_length_check([zs, omegas]): methods.append('SIMPLE') methods.append('NONE') return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] if Method == 'SIMPLE': _omega = mixing_simple(zs, omegas) elif Method == 'NONE': _omega = None else: raise Exception('Failure in in function') return _omega
def Diguilio_Teja(T, xs, sigmas_Tb, Tbs, Tcs): r'''Calculates surface tension of a liquid mixture according to mixing rules in [1]_. .. math:: \sigma = 1.002855(T^*)^{1.118091} \frac{T}{T_b} \sigma_r T^* = \frac{(T_c/T)-1}{(T_c/T_b)-1} \sigma_r = \sum x_i \sigma_i T_b = \sum x_i T_{b,i} T_c = \sum x_i T_{c,i} Parameters ---------- T : float Temperature of fluid [K] xs : array-like Mole fractions of all components sigmas_Tb : array-like Surface tensions of all components at the boiling point, [N/m] Tbs : array-like Boiling temperatures of all components, [K] Tcs : array-like Critical temperatures of all components, [K] Returns ------- sigma : float Air-liquid surface tension of mixture, [N/m] Notes ----- Simple model, however it has 0 citations. Gives similar results to the `Winterfeld_Scriven_Davis` model. Raises a ValueError if temperature is greater than the mixture's critical temperature or if the given temperature is negative, or if the mixture's boiling temperature is higher than its critical temperature. Examples -------- >>> Diguilio_Teja(T=298.15, xs=[0.1606, 0.8394], ... sigmas_Tb=[0.01424, 0.02530], Tbs=[309.21, 312.95], Tcs=[469.7, 508.0]) 0.025716823875045505 References ---------- .. [1] Diguilio, Ralph, and Amyn S. Teja. "Correlation and Prediction of the Surface Tensions of Mixtures." The Chemical Engineering Journal 38, no. 3 (July 1988): 205-8. doi:10.1016/0300-9467(88)80079-0. ''' if not none_and_length_check([xs, sigmas_Tb, Tbs, Tcs]): raise Exception('Function inputs are incorrect format') Tc = mixing_simple(xs, Tcs) Tb = mixing_simple(xs, Tbs) sigmar = mixing_simple(xs, sigmas_Tb) Tst = (Tc/T - 1.)/(Tc/Tb - 1) sigma = 1.002855*Tst**1.118091*(T/Tb)*sigmar return sigma
def surface_tension_mixture(T=None, xs=[], sigmas=[], rhoms=[], Tcs=[], Tbs=[], sigmas_Tb=[], CASRNs=None, AvailableMethods=False, Method=None): r'''This function handles the calculation of a mixture's surface tension. Calculation is based on the surface tensions provided for each pure component. Will automatically select a method to use if no Method is provided; returns None if insufficient data is available. Prefered method is `Winterfeld_Scriven_Davis` which requires mole fractions, pure component surface tensions, and the molar density of each pure component. `Diguilio_Teja` is of similar accuracy, but requires the surface tensions of pure components at their boiling points, as well as boiling points and critical points and mole fractions. An ideal mixing rule based on mole fractions, `Simple`, is also available and is still relatively accurate. Examples -------- >>> surface_tension_mixture(xs=[0.1606, 0.8394], sigmas=[0.01547, 0.02877]) 0.02663402 Parameters ---------- T : float, optional Temperature of fluid [K] xs : array-like Mole fractions of all components sigmas : array-like, optional Surface tensions of all components, [N/m] rhoms : array-like, optional Molar densities of all components, [mol/m^3] Tcs : array-like, optional Critical temperatures of all components, [K] Tbs : array-like, optional Boiling temperatures of all components, [K] sigmas_Tb : array-like, optional Surface tensions of all components at the boiling point, [N/m] CASRNs : list of strings, optional CASRNs, not currently used [-] Returns ------- sigma : float Air-liquid surface tension of mixture, [N/m] methods : list, only returned if AvailableMethods == True List of methods which can be used to obtain sigma with the given inputs Other Parameters ---------------- Method : string, optional A string for the method name to use, as defined by constants in surface_tension_mixture_methods AvailableMethods : bool, optional If True, function will determine which methods can be used to obtain sigma for the desired chemical, and will return methods instead of sigma Notes ----- References ---------- .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition. New York: McGraw-Hill Professional, 2000. ''' def list_methods(): methods = [] if none_and_length_check([xs, sigmas, rhoms]): methods.append(WINTERFELDSCRIVENDAVIS) if T and none_and_length_check([xs, sigmas_Tb, Tbs, Tcs]): methods.append(DIGUILIOTEJA) if none_and_length_check([xs, sigmas]): methods.append(SIMPLE) methods.append(NONE) return methods if AvailableMethods: return list_methods() if not Method: Method = list_methods()[0] if Method == SIMPLE: sigma = mixing_simple(xs, sigmas) elif Method == WINTERFELDSCRIVENDAVIS: sigma = Winterfeld_Scriven_Davis(xs, sigmas, rhoms) elif Method == DIGUILIOTEJA: sigma = Diguilio_Teja(T=T, xs=xs, sigmas_Tb=sigmas_Tb, Tbs=Tbs, Tcs=Tcs) elif Method == NONE: sigma = None else: raise Exception('Failure in in function') return sigma