if not none_and_length_check([fracs, props]):<EOL><INDENT>return None<EOL><DEDENT>return exp(sum(frac*log(prop) for frac, prop in zip(fracs, props)))<EOL>

r'''Simple function calculates a property based on weighted averages of
    logarithmic properties.

    .. math::
        y = \sum_i \text{frac}_i \cdot \log(\text{prop}_i)

    Parameters
    ----------
    fracs : array-like
        Fractions of a mixture
    props: array-like
        Properties

    Returns
    -------
    prop : value
        Calculated property

    Notes
    -----
    Does not work on negative values.
    Returns None if any fractions or properties are missing or are not of the
    same length.

    Examples
    --------
    >>> mixing_logarithmic([0.1, 0.9], [0.01, 0.02])
    0.01866065983073615


def phase_select_property(phase=None, s=None, l=None, g=None, V_over_F=None):

if phase == '<STR_LIT:s>':<EOL><INDENT>return s<EOL><DEDENT>elif phase == '<STR_LIT:l>':<EOL><INDENT>return l<EOL><DEDENT>elif phase == '<STR_LIT:g>':<EOL><INDENT>return g<EOL><DEDENT>elif phase == '<STR_LIT>':<EOL><INDENT>return None  <EOL><DEDENT>elif phase is None:<EOL><INDENT>return None<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>

r'''Determines which phase's property should be set as a default, given
    the phase a chemical is, and the property values of various phases. For the
    case of liquid-gas phase, returns None. If the property is not available
    for the current phase, or if the current phase is not known, returns None.

    Parameters
    ----------
    phase : str
        One of {'s', 'l', 'g', 'two-phase'}
    s : float
        Solid-phase property
    l : float
        Liquid-phase property
    g : float
        Gas-phase property
    V_over_F : float
        Vapor phase fraction

    Returns
    -------
    prop : float
        The selected/calculated property for the relevant phase

    Notes
    -----
    Could calculate mole-fraction weighted properties for the two phase regime.
    Could also implement equilibria with solid phases.

    Examples
    --------
    >>> phase_select_property(phase='g', l=1560.14, g=3312.)
    3312.0


if T == self.T_cached:<EOL><INDENT>return self.prop_cached<EOL><DEDENT>else:<EOL><INDENT>self.prop_cached = self.T_dependent_property(T)<EOL>self.T_cached = T<EOL>return self.prop_cached<EOL><DEDENT>

r'''Convenience method to calculate the property; calls
        :obj:`T_dependent_property`. Caches previously calculated value,
        which is an overhead when calculating many different values of
        a property. See :obj:`T_dependent_property` for more details as to the
        calculation procedure.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the property, [K]

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def set_user_methods(self, user_methods, forced=False):

<EOL>if isinstance(user_methods, str):<EOL><INDENT>user_methods = [user_methods]<EOL><DEDENT>self.user_methods = user_methods<EOL>self.forced = forced<EOL>if set(self.user_methods).difference(self.all_methods):<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>if not self.user_methods and self.forced:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>self.method = None<EOL>self.sorted_valid_methods = []<EOL>self.T_cached = None<EOL>

r'''Method used to select certain property methods as having a higher
        priority than were set by default. If `forced` is true, then methods
        which were not specified are excluded from consideration.

        As a side effect, `method` is removed to ensure than the new methods
        will be used in calculations afterwards.

        An exception is raised if any of the methods specified aren't available
        for the chemical. An exception is raised if no methods are provided.

        Parameters
        ----------
        user_methods : str or list
            Methods by name to be considered or prefered
        forced : bool, optional
            If True, only the user specified methods will ever be considered;
            if False other methods will be considered if no user methods
            suceed


<EOL>if self.forced:<EOL><INDENT>considered_methods = list(self.user_methods)<EOL><DEDENT>else:<EOL><INDENT>considered_methods = list(self.all_methods)<EOL><DEDENT>if self.user_methods:<EOL><INDENT>[considered_methods.remove(i) for i in self.user_methods]<EOL><DEDENT>preferences = sorted([self.ranked_methods.index(i) for i in considered_methods])<EOL>sorted_methods = [self.ranked_methods[i] for i in preferences]<EOL>if self.user_methods:<EOL><INDENT>[sorted_methods.insert(<NUM_LIT:0>, i) for i in reversed(self.user_methods)]<EOL><DEDENT>sorted_valid_methods = []<EOL>for method in sorted_methods:<EOL><INDENT>if self.test_method_validity(T, method):<EOL><INDENT>sorted_valid_methods.append(method)<EOL><DEDENT><DEDENT>return sorted_valid_methods<EOL>

r'''Method to obtain a sorted list of methods which are valid at `T`
        according to `test_method_validity`. Considers either only user methods
        if forced is True, or all methods. User methods are first tested
        according to their listed order, and unless forced is True, then all
        methods are tested and sorted by their order in `ranked_methods`.

        Parameters
        ----------
        T : float
            Temperature at which to test methods, [K]

        Returns
        -------
        sorted_valid_methods : list
            Sorted lists of methods valid at T according to
            `test_method_validity`


<EOL>if self.method:<EOL><INDENT>if self.test_method_validity(T, self.method):<EOL><INDENT>try:<EOL><INDENT>prop = self.calculate(T, self.method)<EOL>if self.test_property_validity(prop):<EOL><INDENT>return prop<EOL><DEDENT><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>self.sorted_valid_methods = self.select_valid_methods(T)<EOL>for method in self.sorted_valid_methods:<EOL><INDENT>try:<EOL><INDENT>prop = self.calculate(T, method)<EOL>if self.test_property_validity(prop):<EOL><INDENT>self.method = method<EOL>return prop<EOL><DEDENT><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate the property with sanity checking and without
        specifying a specific method. `select_valid_methods` is used to obtain
        a sorted list of methods to try. Methods are then tried in order until
        one succeeds. The methods are allowed to fail, and their results are
        checked with `test_property_validity`. On success, the used method
        is stored in the variable `method`.

        If `method` is set, this method is first checked for validity with
        `test_method_validity` for the specified temperature, and if it is
        valid, it is then used to calculate the property. The result is checked
        for validity, and returned if it is valid. If either of the checks fail,
        the function retrieves a full list of valid methods with
        `select_valid_methods` and attempts them as described above.

        If no methods are found which succeed, returns None.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the property, [K]

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def plot_T_dependent_property(self, Tmin=None, Tmax=None, methods=[],<EOL>pts=<NUM_LIT:50>, only_valid=True, order=<NUM_LIT:0>):

<EOL>if not has_matplotlib:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if Tmin is None:<EOL><INDENT>if self.Tmin is not None:<EOL><INDENT>Tmin = self.Tmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Tmax is None:<EOL><INDENT>if self.Tmax is not None:<EOL><INDENT>Tmax = self.Tmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if not methods:<EOL><INDENT>if self.user_methods:<EOL><INDENT>methods = self.user_methods<EOL><DEDENT>else:<EOL><INDENT>methods = self.all_methods<EOL><DEDENT><DEDENT>Ts = np.linspace(Tmin, Tmax, pts)<EOL>if order == <NUM_LIT:0>:<EOL><INDENT>for method in methods:<EOL><INDENT>if only_valid:<EOL><INDENT>properties, Ts2 = [], []<EOL>for T in Ts:<EOL><INDENT>if self.test_method_validity(T, method):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate(T=T, method=method)<EOL>if self.test_property_validity(p):<EOL><INDENT>properties.append(p)<EOL>Ts2.append(T)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>plt.semilogy(Ts2, properties, label=method)<EOL><DEDENT>else:<EOL><INDENT>properties = [self.calculate(T=T, method=method) for T in Ts]<EOL>plt.semilogy(Ts, properties, label=method)<EOL><DEDENT><DEDENT>plt.ylabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units)<EOL>plt.title(self.name + '<STR_LIT>' + self.CASRN)<EOL><DEDENT>elif order > <NUM_LIT:0>:<EOL><INDENT>for method in methods:<EOL><INDENT>if only_valid:<EOL><INDENT>properties, Ts2 = [], []<EOL>for T in Ts:<EOL><INDENT>if self.test_method_validity(T, method):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate_derivative(T=T, method=method, order=order)<EOL>properties.append(p)<EOL>Ts2.append(T)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>plt.semilogy(Ts2, properties, label=method)<EOL><DEDENT>else:<EOL><INDENT>properties = [self.calculate_derivative(T=T, method=method, order=order) for T in Ts]<EOL>plt.semilogy(Ts, properties, label=method)<EOL><DEDENT><DEDENT>plt.ylabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units + '<STR_LIT>' % (order, order))<EOL>plt.title(self.name + '<STR_LIT>' % order + '<STR_LIT>' + self.CASRN)<EOL><DEDENT>plt.legend(loc='<STR_LIT>')<EOL>plt.xlabel('<STR_LIT>')<EOL>plt.show()<EOL>

r'''Method to create a plot of the property vs temperature according to
        either a specified list of methods, or user methods (if set), or all
        methods. User-selectable number of points, and temperature range. If
        only_valid is set,`test_method_validity` will be used to check if each
        temperature in the specified range is valid, and
        `test_property_validity` will be used to test the answer, and the
        method is allowed to fail; only the valid points will be plotted.
        Otherwise, the result will be calculated and displayed as-is. This will
        not suceed if the method fails.

        Parameters
        ----------
        Tmin : float
            Minimum temperature, to begin calculating the property, [K]
        Tmax : float
            Maximum temperature, to stop calculating the property, [K]
        methods : list, optional
            List of methods to consider
        pts : int, optional
            A list of points to calculate the property at; if Tmin to Tmax
            covers a wide range of method validities, only a few points may end
            up calculated for a given method so this may need to be large
        only_valid : bool
            If True, only plot successful methods and calculated properties,
            and handle errors; if False, attempt calculation without any
            checking and use methods outside their bounds


key = (name, self.interpolation_T, self.interpolation_property, self.interpolation_property_inv)<EOL><INDENT>if isinstance(self.tabular_data_interpolators, dict) and key in self.tabular_data_interpolators:<EOL><INDENT>extrapolator, spline = self.tabular_data_interpolators[key]<EOL><DEDENT><DEDENT>if key in self.tabular_data_interpolators:<EOL><INDENT>extrapolator, spline = self.tabular_data_interpolators[key]<EOL><DEDENT>else:<EOL><INDENT>Ts, properties = self.tabular_data[name]<EOL>if self.interpolation_T:  <EOL><INDENT>Ts2 = [self.interpolation_T(T2) for T2 in Ts]<EOL><DEDENT>else:<EOL><INDENT>Ts2 = Ts<EOL><DEDENT>if self.interpolation_property:  <EOL><INDENT>properties2 = [self.interpolation_property(p) for p in properties]<EOL><DEDENT>else:<EOL><INDENT>properties2 = properties<EOL><DEDENT>extrapolator = interp1d(Ts2, properties2, fill_value='<STR_LIT>')<EOL>if len(properties) >= <NUM_LIT:5>:<EOL><INDENT>spline = interp1d(Ts2, properties2, kind='<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>spline = None<EOL>

r'''Method to perform interpolation on a given tabular data set
        previously added via :obj:`set_tabular_data`. This method will create the
        interpolators the first time it is used on a property set, and store
        them for quick future use.

        Interpolation is cubic-spline based if 5 or more points are available,
        and linearly interpolated if not. Extrapolation is always performed
        linearly. This function uses the transforms `interpolation_T`,
        `interpolation_property`, and `interpolation_property_inv` if set. If
        any of these are changed after the interpolators were first created,
        new interpolators are created with the new transforms.
        All interpolation is performed via the `interp1d` function.

        Parameters
        ----------
        T : float
            Temperature at which to interpolate the property, [K]
        name : str
            The name assigned to the tabular data set

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def set_tabular_data(self, Ts, properties, name=None, check_properties=True):

<EOL>if check_properties:<EOL><INDENT>for p in properties:<EOL><INDENT>if not self.test_property_validity(p):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT><DEDENT>if not all(b > a for a, b in zip(Ts, Ts[<NUM_LIT:1>:])):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if name is None:<EOL><INDENT>name = '<STR_LIT>' + str(len(self.tabular_data))  <EOL><DEDENT>self.tabular_data[name] = (Ts, properties)<EOL>self.method = None<EOL>self.user_methods.insert(<NUM_LIT:0>, name)<EOL>self.all_methods.add(name)<EOL>self.set_user_methods(user_methods=self.user_methods, forced=self.forced)<EOL>

r'''Method to set tabular data to be used for interpolation.
        Ts must be in increasing order. If no name is given, data will be
        assigned the name 'Tabular data series #x', where x is the number of
        previously added tabular data series. The name is added to all
        methods and iserted at the start of user methods,

        Parameters
        ----------
        Ts : array-like
            Increasing array of temperatures at which properties are specified, [K]
        properties : array-like
            List of properties at Ts, [`units`]
        name : str, optional
            Name assigned to the data
        check_properties : bool
            If True, the properties will be checked for validity with
            `test_property_validity` and raise an exception if any are not
            valid


def solve_prop(self, goal, reset_method=True):

if self.Tmin is None or self.Tmax is None:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if not self.test_property_validity(goal):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>def error(T):<EOL><INDENT>if reset_method:<EOL><INDENT>self.method = None<EOL><DEDENT>return self.T_dependent_property(T) - goal<EOL><DEDENT>try:<EOL><INDENT>return brenth(error, self.Tmin, self.Tmax)<EOL><DEDENT>except ValueError:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>

r'''Method to solve for the temperature at which a property is at a
        specified value. `T_dependent_property` is used to calculate the value
        of the property as a function of temperature; if `reset_method` is True,
        the best method is used at each temperature as the solver seeks a
        solution. This slows the solution moderately.

        Checks the given property value with `test_property_validity` first
        and raises an exception if it is not valid. Requires that Tmin and
        Tmax have been set to know what range to search within.

        Search is performed with the brenth solver from SciPy.

        Parameters
        ----------
        goal : float
            Propoerty value desired, [`units`]
        reset_method : bool
            Whether or not to reset the method as the solver searches

        Returns
        -------
        T : float
            Temperature at which the property is the specified value [K]


def calculate_derivative(self, T, method, order=<NUM_LIT:1>):

return derivative(self.calculate, T, dx=<NUM_LIT>, args=[method], n=order, order=<NUM_LIT:1>+order*<NUM_LIT:2>)<EOL>

r'''Method to calculate a derivative of a property with respect to
        temperature, of a given order  using a specified method. Uses SciPy's
        derivative function, with a delta of 1E-6 K and a number of points
        equal to 2*order + 1.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        method : str
            Method for which to find the derivative
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        derivative : float
            Calculated derivative property, [`units/K^order`]


def T_dependent_property_derivative(self, T, order=<NUM_LIT:1>):

if self.method:<EOL><INDENT>if self.test_method_validity(T, self.method):<EOL><INDENT>try:<EOL><INDENT>return self.calculate_derivative(T, self.method, order)<EOL><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>sorted_valid_methods = self.select_valid_methods(T)<EOL>for method in sorted_valid_methods:<EOL><INDENT>try:<EOL><INDENT>return self.calculate_derivative(T, method, order)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to obtain a derivative of a property with respect to
        temperature, of a given order. Methods found valid by
        `select_valid_methods` are attempted until a method succeeds. If no
        methods are valid and succeed, None is returned.

        Calls `calculate_derivative` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d T}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        derivative : float
            Calculated derivative property, [`units/K^order`]


def calculate_integral(self, T1, T2, method):

return float(quad(self.calculate, T1, T2, args=(method))[<NUM_LIT:0>])<EOL>

r'''Method to calculate the integral of a property with respect to
        temperature, using a specified method. Uses SciPy's `quad` function
        to perform the integral, with no options.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T1 : float
            Lower limit of integration, [K]
        T2 : float
            Upper limit of integration, [K]
        method : str
            Method for which to find the integral

        Returns
        -------
        integral : float
            Calculated integral of the property over the given range,
            [`units*K`]


def T_dependent_property_integral(self, T1, T2):

Tavg = <NUM_LIT:0.5>*(T1+T2)<EOL>if self.method:<EOL><INDENT>if self.test_method_validity(Tavg, self.method):<EOL><INDENT>try:<EOL><INDENT>return self.calculate_integral(T1, T2, self.method)<EOL><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>sorted_valid_methods = self.select_valid_methods(Tavg)<EOL>for method in sorted_valid_methods:<EOL><INDENT>try:<EOL><INDENT>return self.calculate_integral(T1, T2, method)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate the integral of a property with respect to
        temperature, using a specified method. Methods found valid by
        `select_valid_methods` are attempted until a method succeeds. If no
        methods are valid and succeed, None is returned.

        Calls `calculate_integral` internally to perform the actual
        calculation.

        .. math::
            \text{integral} = \int_{T_1}^{T_2} \text{property} \; dT

        Parameters
        ----------
        T1 : float
            Lower limit of integration, [K]
        T2 : float
            Upper limit of integration, [K]
        method : str
            Method for which to find the integral

        Returns
        -------
        integral : float
            Calculated integral of the property over the given range,
            [`units*K`]


def calculate_integral_over_T(self, T1, T2, method):

return float(quad(lambda T: self.calculate(T, method)/T, T1, T2)[<NUM_LIT:0>])<EOL>

r'''Method to calculate the integral of a property over temperature
        with respect to temperature, using a specified method. Uses SciPy's
        `quad` function to perform the integral, with no options.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T1 : float
            Lower limit of integration, [K]
        T2 : float
            Upper limit of integration, [K]
        method : str
            Method for which to find the integral

        Returns
        -------
        integral : float
            Calculated integral of the property over the given range,
            [`units`]


def T_dependent_property_integral_over_T(self, T1, T2):

Tavg = <NUM_LIT:0.5>*(T1+T2)<EOL>if self.method:<EOL><INDENT>if self.test_method_validity(Tavg, self.method):<EOL><INDENT>try:<EOL><INDENT>return self.calculate_integral_over_T(T1, T2, self.method)<EOL><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>sorted_valid_methods = self.select_valid_methods(Tavg)<EOL>for method in sorted_valid_methods:<EOL><INDENT>try:<EOL><INDENT>return self.calculate_integral_over_T(T1, T2, method)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate the integral of a property over temperature
        with respect to temperature, using a specified method. Methods found
        valid by `select_valid_methods` are attempted until a method succeeds.
        If no methods are valid and succeed, None is returned.

        Calls `calculate_integral_over_T` internally to perform the actual
        calculation.

        .. math::
            \text{integral} = \int_{T_1}^{T_2} \frac{\text{property}}{T} \; dT

        Parameters
        ----------
        T1 : float
            Lower limit of integration, [K]
        T2 : float
            Upper limit of integration, [K]
        method : str
            Method for which to find the integral

        Returns
        -------
        integral : float
            Calculated integral of the property over the given range,
            [`units`]


self.CASRN = CASRN<EOL>self.load_all_methods()<EOL>self.ranked_methods = [TEST_METHOD_2, TEST_METHOD_1]  <EOL>self.tabular_data = {}<EOL>self.tabular_data_interpolators = {}<EOL>self.sorted_valid_methods = []<EOL>self.user_methods = []<EOL>

Create an instance of TDependentProperty. Should be overwritten by
        a method created specific to a property. Should take all constant
        properties on creation.

        Attributes
        ----------


methods = []<EOL>Tmins, Tmaxs = [], []<EOL>if self.CASRN in ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']:<EOL><INDENT>methods.append(TEST_METHOD_1)<EOL>self.TEST_METHOD_1_Tmin = <NUM_LIT><EOL>self.TEST_METHOD_1_Tmax = <NUM_LIT><EOL>self.TEST_METHOD_1_coeffs = [<NUM_LIT:1>, <NUM_LIT>]<EOL>Tmins.append(self.TEST_METHOD_1_Tmin); Tmaxs.append(self.TEST_METHOD_1_Tmax)<EOL><DEDENT>if self.CASRN in ['<STR_LIT>']:<EOL><INDENT>methods.append(TEST_METHOD_2)<EOL>self.TEST_METHOD_2_Tmin = <NUM_LIT><EOL>self.TEST_METHOD_2_Tmax = <NUM_LIT><EOL>self.TEST_METHOD_2_coeffs = [<NUM_LIT:1>, <NUM_LIT>]<EOL>Tmins.append(self.TEST_METHOD_2_Tmin); Tmaxs.append(self.TEST_METHOD_2_Tmax)<EOL><DEDENT>self.all_methods = set(methods)<EOL>if Tmins and Tmaxs:<EOL><INDENT>self.Tmin = min(Tmins)<EOL>self.Tmax = max(Tmaxs)<EOL><DEDENT>

r'''Method to load all data, and set all_methods based on the available
        data and properties. Demo function for testing only; must be
        implemented according to the methods available for each individual
        method.


if method == TEST_METHOD_1:<EOL><INDENT>prop = self.TEST_METHOD_1_coeffs[<NUM_LIT:0>] + self.TEST_METHOD_1_coeffs[<NUM_LIT:1>]*T<EOL><DEDENT>elif method == TEST_METHOD_2:<EOL><INDENT>prop = self.TEST_METHOD_2_coeffs[<NUM_LIT:0>] + self.TEST_METHOD_2_coeffs[<NUM_LIT:1>]*T<EOL><DEDENT>elif method in self.tabular_data:<EOL><INDENT>prop = self.interpolate(T, method)<EOL><DEDENT>return prop<EOL>

r'''Method to calculate a property with a specified method, with no
        validity checking or error handling. Demo function for testing only;
        must be implemented according to the methods available for each
        individual method. Include the interpolation call here.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the property, [K]
        method : str
            Method name to use

        Returns
        -------
        prop : float
            Calculated property, [`units`]


if (T, P) == self.TP_cached:<EOL><INDENT>return self.prop_cached<EOL><DEDENT>else:<EOL><INDENT>self.prop_cached = self.TP_or_T_dependent_property(T, P)<EOL>self.TP_cached = (T, P)<EOL>return self.prop_cached<EOL><DEDENT>

r'''Convenience method to calculate the property; calls
        :obj:`TP_dependent_property`. Caches previously calculated value,
        which is an overhead when calculating many different values of
        a property. See :obj:`TP_dependent_property` for more details as to the
        calculation procedure.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the property, [K]
        P : float
            Pressure at which to calculate the property, [Pa]

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def set_user_methods_P(self, user_methods_P, forced_P=False):

<EOL>if isinstance(user_methods_P, str):<EOL><INDENT>user_methods_P = [user_methods_P]<EOL><DEDENT>self.user_methods_P = user_methods_P<EOL>self.forced_P = forced_P<EOL>if set(self.user_methods_P).difference(self.all_methods_P):<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>if not self.user_methods_P and self.forced:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>self.method_P = None<EOL>self.sorted_valid_methods_P = []<EOL>self.TP_cached = None<EOL>

r'''Method to set the pressure-dependent property methods desired for
        consideration by the user. Can be used to exclude certain methods which
        might have unacceptable accuracy.

        As a side effect, the previously selected method is removed when
        this method is called to ensure user methods are tried in the desired
        order.

        Parameters
        ----------
        user_methods_P : str or list
            Methods by name to be considered or preferred for pressure effect.
        forced : bool, optional
            If True, only the user specified methods will ever be considered;
            if False other methods will be considered if no user methods
            suceed.


<EOL>if self.forced_P:<EOL><INDENT>considered_methods = list(self.user_methods_P)<EOL><DEDENT>else:<EOL><INDENT>considered_methods = list(self.all_methods_P)<EOL><DEDENT>if self.user_methods_P:<EOL><INDENT>[considered_methods.remove(i) for i in self.user_methods_P]<EOL><DEDENT>preferences = sorted([self.ranked_methods_P.index(i) for i in considered_methods])<EOL>sorted_methods = [self.ranked_methods_P[i] for i in preferences]<EOL>if self.user_methods_P:<EOL><INDENT>[sorted_methods.insert(<NUM_LIT:0>, i) for i in reversed(self.user_methods_P)]<EOL><DEDENT>sorted_valid_methods_P = []<EOL>for method in sorted_methods:<EOL><INDENT>if self.test_method_validity_P(T, P, method):<EOL><INDENT>sorted_valid_methods_P.append(method)<EOL><DEDENT><DEDENT>return sorted_valid_methods_P<EOL>

r'''Method to obtain a sorted list methods which are valid at `T`
        according to `test_method_validity`. Considers either only user methods
        if forced is True, or all methods. User methods are first tested
        according to their listed order, and unless forced is True, then all
        methods are tested and sorted by their order in `ranked_methods`.

        Parameters
        ----------
        T : float
            Temperature at which to test methods, [K]
        P : float
            Pressure at which to test methods, [Pa]

        Returns
        -------
        sorted_valid_methods_P : list
            Sorted lists of methods valid at T and P according to
            `test_method_validity`


<EOL>if self.method_P:<EOL><INDENT>if self.test_method_validity_P(T, P, self.method_P):<EOL><INDENT>try:<EOL><INDENT>prop = self.calculate_P(T, P, self.method_P)<EOL>if self.test_property_validity(prop):<EOL><INDENT>return prop<EOL><DEDENT><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>self.sorted_valid_methods_P = self.select_valid_methods_P(T, P)<EOL>for method_P in self.sorted_valid_methods_P:<EOL><INDENT>try:<EOL><INDENT>prop = self.calculate_P(T, P, method_P)<EOL>if self.test_property_validity(prop):<EOL><INDENT>self.method_P = method_P<EOL>return prop<EOL><DEDENT><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate the property with sanity checking and without
        specifying a specific method. `select_valid_methods_P` is used to obtain
        a sorted list of methods to try. Methods are then tried in order until
        one succeeds. The methods are allowed to fail, and their results are
        checked with `test_property_validity`. On success, the used method
        is stored in the variable `method_P`.

        If `method_P` is set, this method is first checked for validity with
        `test_method_validity_P` for the specified temperature, and if it is
        valid, it is then used to calculate the property. The result is checked
        for validity, and returned if it is valid. If either of the checks fail,
        the function retrieves a full list of valid methods with
        `select_valid_methods_P` and attempts them as described above.

        If no methods are found which succeed, returns None.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the property, [K]
        P : float
            Pressure at which to calculate the property, [Pa]

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def set_tabular_data_P(self, Ts, Ps, properties, name=None, check_properties=True):

<EOL>if check_properties:<EOL><INDENT>for p in np.array(properties).ravel():<EOL><INDENT>if not self.test_property_validity(p):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT><DEDENT>if not all(b > a for a, b in zip(Ts, Ts[<NUM_LIT:1>:])):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if not all(b > a for a, b in zip(Ps, Ps[<NUM_LIT:1>:])):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if name is None:<EOL><INDENT>name = '<STR_LIT>' + str(len(self.tabular_data))  <EOL><DEDENT>self.tabular_data[name] = (Ts, Ps, properties)<EOL>self.method_P = None<EOL>self.user_methods_P.insert(<NUM_LIT:0>, name)<EOL>self.all_methods_P.add(name)<EOL>self.set_user_methods_P(user_methods_P=self.user_methods_P, forced_P=self.forced_P)<EOL>

r'''Method to set tabular data to be used for interpolation.
        Ts and Psmust be in increasing order. If no name is given, data will be
        assigned the name 'Tabular data series #x', where x is the number of
        previously added tabular data series. The name is added to all
        methods and is inserted at the start of user methods,

        Parameters
        ----------
        Ts : array-like
            Increasing array of temperatures at which properties are specified, [K]
        Ps : array-like
            Increasing array of pressures at which properties are specified, [Pa]
        properties : array-like
            List of properties at Ts, [`units`]
        name : str, optional
            Name assigned to the data
        check_properties : bool
            If True, the properties will be checked for validity with
            `test_property_validity` and raise an exception if any are not
            valid


key = (name, self.interpolation_T, self.interpolation_P, self.interpolation_property, self.interpolation_property_inv)<EOL>if key in self.tabular_data_interpolators:<EOL><INDENT>extrapolator, spline = self.tabular_data_interpolators[key]<EOL><DEDENT>else:<EOL><INDENT>Ts, Ps, properties = self.tabular_data[name]<EOL>if self.interpolation_T:  <EOL><INDENT>Ts2 = [self.interpolation_T(T2) for T2 in Ts]<EOL><DEDENT>else:<EOL><INDENT>Ts2 = Ts<EOL><DEDENT>if self.interpolation_P:  <EOL><INDENT>Ps2 = [self.interpolation_P(P2) for P2 in Ps]<EOL><DEDENT>else:<EOL><INDENT>Ps2 = Ps<EOL><DEDENT>if self.interpolation_property:  <EOL><INDENT>properties2 = [self.interpolation_property(p) for p in properties]<EOL><DEDENT>else:<EOL><INDENT>properties2 = properties<EOL><DEDENT>extrapolator = interp2d(Ts2, Ps2, properties2)  <EOL>if len(properties) >= <NUM_LIT:5>:<EOL><INDENT>spline = interp2d(Ts2, Ps2, properties2, kind='<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>spline = None<EOL><DEDENT>self.tabular_data_interpolators[key] = (extrapolator, spline)<EOL><DEDENT>Ts, Ps, properties = self.tabular_data[name]<EOL>if T < Ts[<NUM_LIT:0>] or T > Ts[-<NUM_LIT:1>] or not spline or P < Ps[<NUM_LIT:0>] or P > Ps[-<NUM_LIT:1>]:<EOL><INDENT>tool = extrapolator<EOL><DEDENT>else:<EOL><INDENT>tool = spline<EOL><DEDENT>if self.interpolation_T:<EOL><INDENT>T = self.interpolation_T(T)<EOL><DEDENT>if self.interpolation_P:<EOL><INDENT>P = self.interpolation_T(P)<EOL><DEDENT>prop = tool(T, P)  <EOL>if self.interpolation_property:<EOL><INDENT>prop = self.interpolation_property_inv(prop)<EOL><DEDENT>return float(prop)<EOL>

r'''Method to perform interpolation on a given tabular data set
        previously added via `set_tabular_data_P`. This method will create the
        interpolators the first time it is used on a property set, and store
        them for quick future use.

        Interpolation is cubic-spline based if 5 or more points are available,
        and linearly interpolated if not. Extrapolation is always performed
        linearly. This function uses the transforms `interpolation_T`,
        `interpolation_P`,
        `interpolation_property`, and `interpolation_property_inv` if set. If
        any of these are changed after the interpolators were first created,
        new interpolators are created with the new transforms.
        All interpolation is performed via the `interp2d` function.

        Parameters
        ----------
        T : float
            Temperature at which to interpolate the property, [K]
        T : float
            Pressure at which to interpolate the property, [Pa]
        name : str
            The name assigned to the tabular data set

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def plot_isotherm(self, T, Pmin=None, Pmax=None, methods_P=[], pts=<NUM_LIT:50>,<EOL>only_valid=True):

<EOL>if not has_matplotlib:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if Pmin is None:<EOL><INDENT>if self.Pmin is not None:<EOL><INDENT>Pmin = self.Pmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Pmax is None:<EOL><INDENT>if self.Pmax is not None:<EOL><INDENT>Pmax = self.Pmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if not methods_P:<EOL><INDENT>if self.user_methods_P:<EOL><INDENT>methods_P = self.user_methods_P<EOL><DEDENT>else:<EOL><INDENT>methods_P = self.all_methods_P<EOL><DEDENT><DEDENT>Ps = np.linspace(Pmin, Pmax, pts)<EOL>for method_P in methods_P:<EOL><INDENT>if only_valid:<EOL><INDENT>properties, Ps2 = [], []<EOL>for P in Ps:<EOL><INDENT>if self.test_method_validity_P(T, P, method_P):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate_P(T, P, method_P)<EOL>if self.test_property_validity(p):<EOL><INDENT>properties.append(p)<EOL>Ps2.append(P)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>plt.plot(Ps2, properties, label=method_P)<EOL><DEDENT>else:<EOL><INDENT>properties = [self.calculate_P(T, P, method_P) for P in Ps]<EOL>plt.plot(Ps, properties, label=method_P)<EOL><DEDENT><DEDENT>plt.legend(loc='<STR_LIT>')<EOL>plt.ylabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units)<EOL>plt.xlabel('<STR_LIT>')<EOL>plt.title(self.name + '<STR_LIT>' + self.CASRN)<EOL>plt.show()<EOL>

r'''Method to create a plot of the property vs pressure at a specified
        temperature according to either a specified list of methods, or the
        user methods (if set), or all methods. User-selectable number of
        points, and pressure range. If only_valid is set,
        `test_method_validity_P` will be used to check if each condition in
        the specified range is valid, and `test_property_validity` will be used
        to test the answer, and the method is allowed to fail; only the valid
        points will be plotted. Otherwise, the result will be calculated and
        displayed as-is. This will not suceed if the method fails.

        Parameters
        ----------
        T : float
            Temperature at which to create the plot, [K]
        Pmin : float
            Minimum pressure, to begin calculating the property, [Pa]
        Pmax : float
            Maximum pressure, to stop calculating the property, [Pa]
        methods_P : list, optional
            List of methods to consider
        pts : int, optional
            A list of points to calculate the property at; if Pmin to Pmax
            covers a wide range of method validities, only a few points may end
            up calculated for a given method so this may need to be large
        only_valid : bool
            If True, only plot successful methods and calculated properties,
            and handle errors; if False, attempt calculation without any
            checking and use methods outside their bounds


def plot_isobar(self, P, Tmin=None, Tmax=None, methods_P=[], pts=<NUM_LIT:50>,<EOL>only_valid=True):

if not has_matplotlib:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if Tmin is None:<EOL><INDENT>if self.Tmin is not None:<EOL><INDENT>Tmin = self.Tmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Tmax is None:<EOL><INDENT>if self.Tmax is not None:<EOL><INDENT>Tmax = self.Tmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if not methods_P:<EOL><INDENT>if self.user_methods_P:<EOL><INDENT>methods_P = self.user_methods_P<EOL><DEDENT>else:<EOL><INDENT>methods_P = self.all_methods_P<EOL><DEDENT><DEDENT>Ts = np.linspace(Tmin, Tmax, pts)<EOL>for method_P in methods_P:<EOL><INDENT>if only_valid:<EOL><INDENT>properties, Ts2 = [], []<EOL>for T in Ts:<EOL><INDENT>if self.test_method_validity_P(T, P, method_P):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate_P(T, P, method_P)<EOL>if self.test_property_validity(p):<EOL><INDENT>properties.append(p)<EOL>Ts2.append(T)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>plt.plot(Ts2, properties, label=method_P)<EOL><DEDENT>else:<EOL><INDENT>properties = [self.calculate_P(T, P, method_P) for T in Ts]<EOL>plt.plot(Ts, properties, label=method_P)<EOL><DEDENT><DEDENT>plt.legend(loc='<STR_LIT>')<EOL>plt.ylabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units)<EOL>plt.xlabel('<STR_LIT>')<EOL>plt.title(self.name + '<STR_LIT>' + self.CASRN)<EOL>plt.show()<EOL>

r'''Method to create a plot of the property vs temperature at a
        specific pressure according to
        either a specified list of methods, or user methods (if set), or all
        methods. User-selectable number of points, and temperature range. If
        only_valid is set,`test_method_validity_P` will be used to check if
        each condition in the specified range is valid, and
        `test_property_validity` will be used to test the answer, and the
        method is allowed to fail; only the valid points will be plotted.
        Otherwise, the result will be calculated and displayed as-is. This will
        not suceed if the method fails.

        Parameters
        ----------
        P : float
            Pressure for the isobar, [Pa]
        Tmin : float
            Minimum temperature, to begin calculating the property, [K]
        Tmax : float
            Maximum temperature, to stop calculating the property, [K]
        methods_P : list, optional
            List of methods to consider
        pts : int, optional
            A list of points to calculate the property at; if Tmin to Tmax
            covers a wide range of method validities, only a few points may end
            up calculated for a given method so this may need to be large
        only_valid : bool
            If True, only plot successful methods and calculated properties,
            and handle errors; if False, attempt calculation without any
            checking and use methods outside their bounds


def plot_TP_dependent_property(self, Tmin=None, Tmax=None, Pmin=None,<EOL>Pmax=None,  methods_P=[], pts=<NUM_LIT:15>, <EOL>only_valid=True):

if not has_matplotlib:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>from mpl_toolkits.mplot3d import axes3d<EOL>from matplotlib.ticker import FormatStrFormatter<EOL>import numpy.ma as ma<EOL>if Pmin is None:<EOL><INDENT>if self.Pmin is not None:<EOL><INDENT>Pmin = self.Pmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Pmax is None:<EOL><INDENT>if self.Pmax is not None:<EOL><INDENT>Pmax = self.Pmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Tmin is None:<EOL><INDENT>if self.Tmin is not None:<EOL><INDENT>Tmin = self.Tmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Tmax is None:<EOL><INDENT>if self.Tmax is not None:<EOL><INDENT>Tmax = self.Tmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if not methods_P:<EOL><INDENT>methods_P = self.user_methods_P if self.user_methods_P else self.all_methods_P<EOL><DEDENT>Ps = np.linspace(Pmin, Pmax, pts)<EOL>Ts = np.linspace(Tmin, Tmax, pts)<EOL>Ts_mesh, Ps_mesh = np.meshgrid(Ts, Ps)<EOL>fig = plt.figure()<EOL>ax = fig.gca(projection='<STR_LIT>')<EOL>handles = []<EOL>for method_P in methods_P:<EOL><INDENT>if only_valid:<EOL><INDENT>properties = []<EOL>for T in Ts:<EOL><INDENT>T_props = []<EOL>for P in Ps:<EOL><INDENT>if self.test_method_validity_P(T, P, method_P):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate_P(T, P, method_P)<EOL>if self.test_property_validity(p):<EOL><INDENT>T_props.append(p)<EOL><DEDENT>else:<EOL><INDENT>T_props.append(None)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>T_props.append(None)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>T_props.append(None)<EOL><DEDENT><DEDENT>properties.append(T_props)<EOL><DEDENT>properties = ma.masked_invalid(np.array(properties, dtype=np.float).T)<EOL>handles.append(ax.plot_surface(Ts_mesh, Ps_mesh, properties, cstride=<NUM_LIT:1>, rstride=<NUM_LIT:1>, alpha=<NUM_LIT:0.5>))<EOL><DEDENT>else:<EOL><INDENT>properties = [[self.calculate_P(T, P, method_P) for P in Ps] for T in Ts]<EOL>handles.append(ax.plot_surface(Ts_mesh, Ps_mesh, properties, cstride=<NUM_LIT:1>, rstride=<NUM_LIT:1>, alpha=<NUM_LIT:0.5>))<EOL><DEDENT><DEDENT>ax.yaxis.set_major_formatter(FormatStrFormatter('<STR_LIT>'))<EOL>ax.zaxis.set_major_formatter(FormatStrFormatter('<STR_LIT>'))<EOL>ax.xaxis.set_major_formatter(FormatStrFormatter('<STR_LIT>'))<EOL>ax.set_xlabel('<STR_LIT>')<EOL>ax.set_ylabel('<STR_LIT>')<EOL>ax.set_zlabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units)<EOL>plt.title(self.name + '<STR_LIT>' + self.CASRN)<EOL>plt.show(block=False)<EOL>ax.legend(handles, methods_P)<EOL>plt.show(block=False)<EOL>

r'''Method to create a plot of the property vs temperature and pressure
        according to either a specified list of methods, or user methods (if
        set), or all methods. User-selectable number of points for each
        variable. If only_valid is set,`test_method_validity_P` will be used to
        check if each condition in the specified range is valid, and
        `test_property_validity` will be used to test the answer, and the
        method is allowed to fail; only the valid points will be plotted.
        Otherwise, the result will be calculated and displayed as-is. This will
        not suceed if the any method fails for any point.

        Parameters
        ----------
        Tmin : float
            Minimum temperature, to begin calculating the property, [K]
        Tmax : float
            Maximum temperature, to stop calculating the property, [K]
        Pmin : float
            Minimum pressure, to begin calculating the property, [Pa]
        Pmax : float
            Maximum pressure, to stop calculating the property, [Pa]
        methods_P : list, optional
            List of methods to consider
        pts : int, optional
            A list of points to calculate the property at for both temperature
            and pressure; pts^2 points will be calculated.
        only_valid : bool
            If True, only plot successful methods and calculated properties,
            and handle errors; if False, attempt calculation without any
            checking and use methods outside their bounds


def calculate_derivative_T(self, T, P, method, order=<NUM_LIT:1>):

return derivative(self.calculate_P, T, dx=<NUM_LIT>, args=[P, method], n=order, order=<NUM_LIT:1>+order*<NUM_LIT:2>)<EOL>

r'''Method to calculate a derivative of a temperature and pressure
        dependent property with respect to  temperature at constant pressure,
        of a given order using a specified  method. Uses SciPy's  derivative
        function, with a delta of 1E-6 K and a number of points equal to
        2*order + 1.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        method : str
            Method for which to find the derivative
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_T_at_P : float
            Calculated derivative property at constant pressure,
            [`units/K^order`]


def calculate_derivative_P(self, P, T, method, order=<NUM_LIT:1>):

f = lambda P: self.calculate_P(T, P, method)<EOL>return derivative(f, P, dx=<NUM_LIT>, n=order, order=<NUM_LIT:1>+order*<NUM_LIT:2>)<EOL>

r'''Method to calculate a derivative of a temperature and pressure
        dependent property with respect to pressure at constant temperature,
        of a given order using a specified method. Uses SciPy's derivative
        function, with a delta of 0.01 Pa and a number of points equal to
        2*order + 1.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        P : float
            Pressure at which to calculate the derivative, [Pa]
        T : float
            Temperature at which to calculate the derivative, [K]
        method : str
            Method for which to find the derivative
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_P_at_T : float
            Calculated derivative property at constant temperature,
            [`units/Pa^order`]


def TP_dependent_property_derivative_T(self, T, P, order=<NUM_LIT:1>):

sorted_valid_methods_P = self.select_valid_methods_P(T, P)<EOL>for method in sorted_valid_methods_P:<EOL><INDENT>try:<EOL><INDENT>return self.calculate_derivative_T(T, P, method, order)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate a derivative of a temperature and pressure
        dependent property with respect to temperature at constant pressure,
        of a given order. Methods found valid by `select_valid_methods_P` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_T` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d T}|_{P}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_T_at_P : float
            Calculated derivative property, [`units/K^order`]


def TP_dependent_property_derivative_P(self, T, P, order=<NUM_LIT:1>):

sorted_valid_methods_P = self.select_valid_methods_P(T, P)<EOL>for method in sorted_valid_methods_P:<EOL><INDENT>try:<EOL><INDENT>return self.calculate_derivative_P(P, T, method, order)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate a derivative of a temperature and pressure
        dependent property with respect to pressure at constant temperature,
        of a given order. Methods found valid by `select_valid_methods_P` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_P` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d P}|_{T}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_P_at_T : float
            Calculated derivative property, [`units/Pa^order`]


if (T, P, zs, ws) == self.TP_zs_ws_cached:<EOL><INDENT>return self.prop_cached<EOL><DEDENT>else:<EOL><INDENT>self.prop_cached = self.mixture_property(T, P, zs, ws)<EOL>self.TP_zs_ws_cached = (T, P, zs, ws)<EOL>return self.prop_cached<EOL><DEDENT>

r'''Convenience method to calculate the property; calls
        :obj:`mixture_property`. Caches previously calculated value,
        which is an overhead when calculating many different values of
        a property. See :obj:`mixture_property` for more details as to the
        calculation procedure.

        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, [-]

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def set_user_method(self, user_methods, forced=False):

<EOL>if isinstance(user_methods, str):<EOL><INDENT>user_methods = [user_methods]<EOL><DEDENT>self.user_methods = user_methods<EOL>self.forced = forced<EOL>if set(self.user_methods).difference(self.all_methods):<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>if not self.user_methods and self.forced:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>self.method = None<EOL>self.sorted_valid_methods = []<EOL>self.TP_zs_ws_cached = (None, None, None, None)<EOL>

r'''Method to set the T, P, and composition dependent property methods
        desired for consideration by the user. Can be used to exclude certain
        methods which might have unacceptable accuracy.

        As a side effect, the previously selected method is removed when
        this method is called to ensure user methods are tried in the desired
        order.

        Parameters
        ----------
        user_methods : str or list
            Methods by name to be considered for calculation of the mixture
            property, ordered by preference.
        forced : bool, optional
            If True, only the user specified methods will ever be considered;
            if False, other methods will be considered if no user methods
            suceed.


def select_valid_methods(self, T, P, zs, ws):

<EOL>considered_methods = list(self.user_methods) if self.forced else list(self.all_methods)<EOL>if self.user_methods:<EOL><INDENT>[considered_methods.remove(i) for i in self.user_methods]<EOL><DEDENT>preferences = sorted([self.ranked_methods.index(i) for i in considered_methods])<EOL>sorted_methods = [self.ranked_methods[i] for i in preferences]<EOL>if self.user_methods:<EOL><INDENT>[sorted_methods.insert(<NUM_LIT:0>, i) for i in reversed(self.user_methods)]<EOL><DEDENT>sorted_valid_methods = []<EOL>for method in sorted_methods:<EOL><INDENT>if self.test_method_validity(T, P, zs, ws, method):<EOL><INDENT>sorted_valid_methods.append(method)<EOL><DEDENT><DEDENT>return sorted_valid_methods<EOL>

r'''Method to obtain a sorted list of methods which are valid at `T`,
        `P`, `zs`, `ws`, and possibly `Vfls`, according to
        `test_method_validity`. Considers either only user methods
        if forced is True, or all methods. User methods are first tested
        according to their listed order, and unless forced is True, then all
        methods are tested and sorted by their order in `ranked_methods`.

        Parameters
        ----------
        T : float
            Temperature at which to test the methods, [K]
        P : float
            Pressure at which to test the methods, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]

        Returns
        -------
        sorted_valid_methods : list
            Sorted lists of methods valid at the given conditions according to
            `test_method_validity`


def mixture_property(self, T, P, zs, ws):

<EOL>if self.method:<EOL><INDENT>if self.test_method_validity(T, P, zs, ws, self.method):<EOL><INDENT>try:<EOL><INDENT>prop = self.calculate(T, P, zs, ws, self.method)<EOL>if self.test_property_validity(prop):<EOL><INDENT>return prop<EOL><DEDENT><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>self.sorted_valid_methods = self.select_valid_methods(T, P, zs, ws)<EOL>for method in self.sorted_valid_methods:<EOL><INDENT>try:<EOL><INDENT>prop = self.calculate(T, P, zs, ws, method)<EOL>if self.test_property_validity(prop):<EOL><INDENT>self.method = method<EOL>return prop<EOL><DEDENT><DEDENT>except:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate the property with sanity checking and without
        specifying a specific method. `select_valid_methods` is used to obtain
        a sorted list of methods to try. Methods are then tried in order until
        one succeeds. The methods are allowed to fail, and their results are
        checked with `test_property_validity`. On success, the used method
        is stored in the variable `method`.

        If `method` is set, this method is first checked for validity with
        `test_method_validity` for the specified temperature, and if it is
        valid, it is then used to calculate the property. The result is checked
        for validity, and returned if it is valid. If either of the checks fail,
        the function retrieves a full list of valid methods with
        `select_valid_methods` and attempts them as described above.

        If no methods are found which succeed, returns None.

        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, [-]

        Returns
        -------
        prop : float
            Calculated property, [`units`]


def calculate_derivative_T(self, T, P, zs, ws, method, order=<NUM_LIT:1>):

return derivative(self.calculate, T, dx=<NUM_LIT>, args=[P, zs, ws, method], n=order, order=<NUM_LIT:1>+order*<NUM_LIT:2>)<EOL>

r'''Method to calculate a derivative of a mixture property with respect
        to temperature at constant pressure and composition
        of a given order using a specified  method. Uses SciPy's derivative
        function, with a delta of 1E-6 K and a number of points equal to
        2*order + 1.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [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
            Method for which to find the derivative
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_T_at_P : float
            Calculated derivative property at constant pressure,
            [`units/K^order`]


def calculate_derivative_P(self, P, T, zs, ws, method, order=<NUM_LIT:1>):

f = lambda P: self.calculate(T, P, zs, ws, method)<EOL>return derivative(f, P, dx=<NUM_LIT>, n=order, order=<NUM_LIT:1>+order*<NUM_LIT:2>)<EOL>

r'''Method to calculate a derivative of a mixture property with respect
        to pressure at constant temperature and composition
        of a given order using a specified method. Uses SciPy's derivative
        function, with a delta of 0.01 Pa and a number of points equal to
        2*order + 1.

        This method can be overwritten by subclasses who may perfer to add
        analytical methods for some or all methods as this is much faster.

        If the calculation does not succeed, returns the actual error
        encountered.

        Parameters
        ----------
        P : float
            Pressure at which to calculate the derivative, [Pa]
        T : float
            Temperature at which to calculate the derivative, [K]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        method : str
            Method for which to find the derivative
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_P_at_T : float
            Calculated derivative property at constant temperature,
            [`units/Pa^order`]


def property_derivative_T(self, T, P, zs, ws, order=<NUM_LIT:1>):

sorted_valid_methods = self.select_valid_methods(T, P, zs, ws)<EOL>for method in sorted_valid_methods:<EOL><INDENT>try:<EOL><INDENT>return self.calculate_derivative_T(T, P, zs, ws, method, order)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate a derivative of a mixture property with respect
        to temperature at constant pressure and composition,
        of a given order. Methods found valid by `select_valid_methods` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_T` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d T}|_{P, z}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_T_at_P : float
            Calculated derivative property, [`units/K^order`]


def property_derivative_P(self, T, P, zs, ws, order=<NUM_LIT:1>):

sorted_valid_methods = self.select_valid_methods(T, P, zs, ws)<EOL>for method in sorted_valid_methods:<EOL><INDENT>try:<EOL><INDENT>return self.calculate_derivative_P(P, T, zs, ws, method, order)<EOL><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return None<EOL>

r'''Method to calculate a derivative of a mixture property with respect
        to pressure at constant temperature and composition,
        of a given order. Methods found valid by `select_valid_methods` are
        attempted until a method succeeds. If no methods are valid and succeed,
        None is returned.

        Calls `calculate_derivative_P` internally to perform the actual
        calculation.

        .. math::
            \text{derivative} = \frac{d (\text{property})}{d P}|_{T, z}

        Parameters
        ----------
        T : float
            Temperature at which to calculate the derivative, [K]
        P : float
            Pressure at which to calculate the derivative, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        order : int
            Order of the derivative, >= 1

        Returns
        -------
        d_prop_d_P_at_T : float
            Calculated derivative property, [`units/Pa^order`]


def plot_isotherm(self, T, zs, ws, Pmin=None, Pmax=None, methods=[], pts=<NUM_LIT:50>,<EOL>only_valid=True):

<EOL>if not has_matplotlib:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if Pmin is None:<EOL><INDENT>if self.Pmin is not None:<EOL><INDENT>Pmin = self.Pmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Pmax is None:<EOL><INDENT>if self.Pmax is not None:<EOL><INDENT>Pmax = self.Pmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if not methods:<EOL><INDENT>if self.user_methods:<EOL><INDENT>methods = self.user_methods<EOL><DEDENT>else:<EOL><INDENT>methods = self.all_methods<EOL><DEDENT><DEDENT>Ps = np.linspace(Pmin, Pmax, pts)<EOL>for method in methods:<EOL><INDENT>if only_valid:<EOL><INDENT>properties, Ps2 = [], []<EOL>for P in Ps:<EOL><INDENT>if self.test_method_validity(T, P, zs, ws, method):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate(T, P, zs, ws, method)<EOL>if self.test_property_validity(p):<EOL><INDENT>properties.append(p)<EOL>Ps2.append(P)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>plt.plot(Ps2, properties, label=method)<EOL><DEDENT>else:<EOL><INDENT>properties = [self.calculate(T, P, zs, ws, method) for P in Ps]<EOL>plt.plot(Ps, properties, label=method)<EOL><DEDENT><DEDENT>plt.legend(loc='<STR_LIT>')<EOL>plt.ylabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units)<EOL>plt.xlabel('<STR_LIT>')<EOL>plt.title(self.name + '<STR_LIT>' + '<STR_LIT:U+002CU+0020>'.join(self.CASs) <EOL>+ '<STR_LIT>' + '<STR_LIT:U+002CU+0020>'.join(str(round(i, <NUM_LIT:4>)) for i in zs) + '<STR_LIT:.>')<EOL>plt.show()<EOL>

r'''Method to create a plot of the property vs pressure at a specified
        temperature and composition according to either a specified list of
        methods, or the  user methods (if set), or all methods. User-selectable
         number of  points, and pressure range. If only_valid is set,
        `test_method_validity` will be used to check if each condition in
        the specified range is valid, and `test_property_validity` will be used
        to test the answer, and the method is allowed to fail; only the valid
        points will be plotted. Otherwise, the result will be calculated and
        displayed as-is. This will not suceed if the method fails.

        Parameters
        ----------
        T : float
            Temperature at which to create the plot, [K]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        Pmin : float
            Minimum pressure, to begin calculating the property, [Pa]
        Pmax : float
            Maximum pressure, to stop calculating the property, [Pa]
        methods : list, optional
            List of methods to consider
        pts : int, optional
            A list of points to calculate the property at; if Pmin to Pmax
            covers a wide range of method validities, only a few points may end
            up calculated for a given method so this may need to be large
        only_valid : bool
            If True, only plot successful methods and calculated properties,
            and handle errors; if False, attempt calculation without any
            checking and use methods outside their bounds


def plot_isobar(self, P, zs, ws, Tmin=None, Tmax=None, methods=[], pts=<NUM_LIT:50>,<EOL>only_valid=True):

if not has_matplotlib:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if Tmin is None:<EOL><INDENT>if self.Tmin is not None:<EOL><INDENT>Tmin = self.Tmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Tmax is None:<EOL><INDENT>if self.Tmax is not None:<EOL><INDENT>Tmax = self.Tmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if not methods:<EOL><INDENT>if self.user_methods:<EOL><INDENT>methods = self.user_methods<EOL><DEDENT>else:<EOL><INDENT>methods = self.all_methods<EOL><DEDENT><DEDENT>Ts = np.linspace(Tmin, Tmax, pts)<EOL>for method in methods:<EOL><INDENT>if only_valid:<EOL><INDENT>properties, Ts2 = [], []<EOL>for T in Ts:<EOL><INDENT>if self.test_method_validity(T, P, zs, ws, method):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate(T, P, zs, ws, method)<EOL>if self.test_property_validity(p):<EOL><INDENT>properties.append(p)<EOL>Ts2.append(T)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>plt.plot(Ts2, properties, label=method)<EOL><DEDENT>else:<EOL><INDENT>properties = [self.calculate(T, P, zs, ws, method) for T in Ts]<EOL>plt.plot(Ts, properties, label=method)<EOL><DEDENT><DEDENT>plt.legend(loc='<STR_LIT>')<EOL>plt.ylabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units)<EOL>plt.xlabel('<STR_LIT>')<EOL>plt.title(self.name + '<STR_LIT>' + '<STR_LIT:U+002CU+0020>'.join(self.CASs) <EOL>+ '<STR_LIT>' + '<STR_LIT:U+002CU+0020>'.join(str(round(i, <NUM_LIT:4>)) for i in zs) + '<STR_LIT:.>')<EOL>plt.show()<EOL>

r'''Method to create a plot of the property vs temperature at a
        specific pressure and composition according to
        either a specified list of methods, or user methods (if set), or all
        methods. User-selectable number of points, and temperature range. If
        only_valid is set,`test_method_validity` will be used to check if
        each condition in the specified range is valid, and
        `test_property_validity` will be used to test the answer, and the
        method is allowed to fail; only the valid points will be plotted.
        Otherwise, the result will be calculated and displayed as-is. This will
        not suceed if the method fails.

        Parameters
        ----------
        P : float
            Pressure for the isobar, [Pa]
        zs : list[float]
            Mole fractions of all species in the mixture, [-]
        ws : list[float]
            Weight fractions of all species in the mixture, [-]
        Tmin : float
            Minimum temperature, to begin calculating the property, [K]
        Tmax : float
            Maximum temperature, to stop calculating the property, [K]
        methods : list, optional
            List of methods to consider
        pts : int, optional
            A list of points to calculate the property at; if Tmin to Tmax
            covers a wide range of method validities, only a few points may end
            up calculated for a given method so this may need to be large
        only_valid : bool
            If True, only plot successful methods and calculated properties,
            and handle errors; if False, attempt calculation without any
            checking and use methods outside their bounds


def plot_property(self, zs, ws, Tmin=None, Tmax=None, Pmin=<NUM_LIT>, Pmax=<NUM_LIT>, <EOL>methods=[], pts=<NUM_LIT:15>, only_valid=True):

if not has_matplotlib:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>from mpl_toolkits.mplot3d import axes3d<EOL>from matplotlib.ticker import FormatStrFormatter<EOL>import numpy.ma as ma<EOL>if Pmin is None:<EOL><INDENT>if self.Pmin is not None:<EOL><INDENT>Pmin = self.Pmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Pmax is None:<EOL><INDENT>if self.Pmax is not None:<EOL><INDENT>Pmax = self.Pmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Tmin is None:<EOL><INDENT>if self.Tmin is not None:<EOL><INDENT>Tmin = self.Tmin<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if Tmax is None:<EOL><INDENT>if self.Tmax is not None:<EOL><INDENT>Tmax = self.Tmax<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT><DEDENT>if not methods:<EOL><INDENT>methods = self.user_methods if self.user_methods else self.all_methods<EOL><DEDENT>Ps = np.linspace(Pmin, Pmax, pts)<EOL>Ts = np.linspace(Tmin, Tmax, pts)<EOL>Ts_mesh, Ps_mesh = np.meshgrid(Ts, Ps)<EOL>fig = plt.figure()<EOL>ax = fig.gca(projection='<STR_LIT>')<EOL>handles = []<EOL>for method in methods:<EOL><INDENT>if only_valid:<EOL><INDENT>properties = []<EOL>for T in Ts:<EOL><INDENT>T_props = []<EOL>for P in Ps:<EOL><INDENT>if self.test_method_validity(T, P, zs, ws, method):<EOL><INDENT>try:<EOL><INDENT>p = self.calculate(T, P, zs, ws, method)<EOL>if self.test_property_validity(p):<EOL><INDENT>T_props.append(p)<EOL><DEDENT>else:<EOL><INDENT>T_props.append(None)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>T_props.append(None)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>T_props.append(None)<EOL><DEDENT><DEDENT>properties.append(T_props)<EOL><DEDENT>properties = ma.masked_invalid(np.array(properties, dtype=np.float).T)<EOL>handles.append(ax.plot_surface(Ts_mesh, Ps_mesh, properties, cstride=<NUM_LIT:1>, rstride=<NUM_LIT:1>, alpha=<NUM_LIT:0.5>))<EOL><DEDENT>else:<EOL><INDENT>properties = [[self.calculate(T, P, zs, ws, method) for P in Ps] for T in Ts]<EOL>handles.append(ax.plot_surface(Ts_mesh, Ps_mesh, properties, cstride=<NUM_LIT:1>, rstride=<NUM_LIT:1>, alpha=<NUM_LIT:0.5>))<EOL><DEDENT><DEDENT>ax.yaxis.set_major_formatter(FormatStrFormatter('<STR_LIT>'))<EOL>ax.zaxis.set_major_formatter(FormatStrFormatter('<STR_LIT>'))<EOL>ax.xaxis.set_major_formatter(FormatStrFormatter('<STR_LIT>'))<EOL>ax.set_xlabel('<STR_LIT>')<EOL>ax.set_ylabel('<STR_LIT>')<EOL>ax.set_zlabel(self.name + '<STR_LIT:U+002CU+0020>' + self.units)<EOL>plt.title(self.name + '<STR_LIT>' + '<STR_LIT:U+002CU+0020>'.join(self.CASs) <EOL>+ '<STR_LIT>' + '<STR_LIT:U+002CU+0020>'.join(str(round(i, <NUM_LIT:4>)) for i in zs) + '<STR_LIT:.>')<EOL>plt.show(block=False)<EOL>ax.legend(handles, methods)<EOL>plt.show(block=False)<EOL>

r'''Method to create a plot of the property vs temperature and pressure
        according to either a specified list of methods, or user methods (if
        set), or all methods. User-selectable number of points for each
        variable. If only_valid is set,`test_method_validity` will be used to
        check if each condition in the specified range is valid, and
        `test_property_validity` will be used to test the answer, and the
        method is allowed to fail; only the valid points will be plotted.
        Otherwise, the result will be calculated and displayed as-is. This will
        not suceed if the any method fails for any point.

        Parameters
        ----------
        Tmin : float
            Minimum temperature, to begin calculating the property, [K]
        Tmax : float
            Maximum temperature, to stop calculating the property, [K]
        Pmin : float
            Minimum pressure, to begin calculating the property, [Pa]
        Pmax : float
            Maximum pressure, to stop calculating the property, [Pa]
        methods : list, optional
            List of methods to consider
        pts : int, optional
            A list of points to calculate the property at for both temperature
            and pressure; pts^2 points will be calculated.
        only_valid : bool
            If True, only plot successful methods and calculated properties,
            and handle errors; if False, attempt calculation without any
            checking and use methods outside their bounds


def REFPROP(T, Tc, sigma0, n0, sigma1=<NUM_LIT:0>, n1=<NUM_LIT:0>, sigma2=<NUM_LIT:0>, n2=<NUM_LIT:0>):

Tr = T/Tc<EOL>sigma = sigma0*(<NUM_LIT:1.>-Tr)**n0 + sigma1*(<NUM_LIT:1.>-Tr)**n1 + sigma2*(<NUM_LIT:1.>-Tr)**n2<EOL>return sigma<EOL>

r'''Calculates air-liquid surface tension  using the REFPROP [1]_
    regression-based method. Relatively recent, and most accurate.

    .. math::
        \sigma(T)=\sigma_0\left(1-\frac{T}{T_c}\right)^{n_0}+
        \sigma_1\left(1-\frac{T}{T_c}\right)^{n_1}+
        \sigma_2\left(1-\frac{T}{T_c}\right)^{n_2}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    sigma0 : float
        First emperical coefficient of a fluid
    n0 : float
        First emperical exponent of a fluid
    sigma1 : float, optional
        Second emperical coefficient of a fluid.
    n1 : float, optional
        Second emperical exponent of a fluid.
    sigma1 : float, optional
        Third emperical coefficient of a fluid.
    n2 : float, optional
        Third emperical exponent of a fluid.

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    Function as implemented in [1]_. No example necessary; results match
    literature values perfectly.
    Form of function returns imaginary results when T > Tc; None is returned
    if this is the case.

    Examples
    --------
    Parameters for water at 298.15 K

    >>> REFPROP(298.15, 647.096, -0.1306, 2.471, 0.2151, 1.233)
    0.07205503890847453

    References
    ----------
    .. [1] Diky, Vladimir, Robert D. Chirico, Chris D. Muzny, Andrei F.
       Kazakov, Kenneth Kroenlein, Joseph W. Magee, Ilmutdin Abdulagatov, and
       Michael Frenkel. "ThermoData Engine (TDE): Software Implementation of
       the Dynamic Data Evaluation Concept." Journal of Chemical Information
       and Modeling 53, no. 12 (2013): 3418-30. doi:10.1021/ci4005699.


X = (Tc-T)/Tc<EOL>sigma = (A*X**<NUM_LIT> + B*X**<NUM_LIT> + C*X**<NUM_LIT>)/<NUM_LIT><EOL>return sigma<EOL>

r'''Calculates air-water surface tension  using the [1]_
    emperical (parameter-regressed) method. Well regressed, no recent data.

    .. math::
        \sigma=aX^{5/4}+bX^{9/4}+cX^{13/4}
        X=(T_c-T)/T_c

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    A : float
        Regression parameter
    B : float
        Regression parameter
    C : float
        Regression parameter

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    Presently untested, but matches expected values. Internal units are mN/m.
    Form of function returns imaginary results when T > Tc; None is returned
    if this is the case. Function is claimed valid from the triple to the
    critical point. Results can be evaluated beneath the triple point.

    Examples
    --------
    Water at 300 K

    >>> Somayajulu(300, 647.126, 232.713514, -140.18645, -4.890098)
    0.07166386387996757

    References
    ----------
    .. [1] Somayajulu, G. R. "A Generalized Equation for Surface Tension from
       the Triple Point to the Critical Point." International Journal of
       Thermophysics 9, no. 4 (July 1988): 559-66. doi:10.1007/BF00503154.


sigma = (a - b*(T-<NUM_LIT>))/<NUM_LIT:1000><EOL>return sigma<EOL>

r'''Calculates surface tension of a fluid given two parameters, a linear
    fit in Celcius from [1]_ with data reprinted in [2]_.

    .. math::
        \sigma = a - bT

    Parameters
    ----------
    T : float
        Temperature of fluid, [K]
    a : float
        Parameter for equation. Chemical specific.
    b : float
        Parameter for equation. Chemical specific.

    Returns
    -------
    sigma: float
        Surface tension [N/m]

    Notes
    -----
    Internal units are mN/m, and degrees Celcius.
    This function has been checked against several references.

    Examples
    --------
    >>> Jasper(298.15, 24, 0.0773)
    0.0220675

    References
    ----------
    .. [1] Jasper, Joseph J. "The Surface Tension of Pure Liquid Compounds."
       Journal of Physical and Chemical Reference Data 1, no. 4
       (October 1, 1972): 841-1010. doi:10.1063/1.3253106.
    .. [2] Speight, James. Lange's Handbook of Chemistry. 16 edition.
       McGraw-Hill Professional, 2005.


Tbr = Tb/Tc<EOL>Tr = T/Tc<EOL>Pc = Pc/<NUM_LIT>  <EOL>Q = <NUM_LIT>*(<NUM_LIT:1> + Tbr*log(Pc/<NUM_LIT>)/(<NUM_LIT:1>-Tbr))-<NUM_LIT><EOL>sigma = (Pc)**(<NUM_LIT:2>/<NUM_LIT>)*Tc**(<NUM_LIT:1>/<NUM_LIT>)*Q*(<NUM_LIT:1>-Tr)**(<NUM_LIT:11>/<NUM_LIT>)<EOL>sigma = sigma/<NUM_LIT:1000>  <EOL>return sigma<EOL>

r'''Calculates air-water surface tension  using the [1]_
    emperical method. Old and tested.

    .. math::
        \sigma = P_c^{2/3}T_c^{1/3}Q(1-T_r)^{11/9}

        Q = 0.1196 \left[ 1 + \frac{T_{br}\ln (P_c/1.01325)}{1-T_{br}}\right]-0.279

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tb : float
        Boiling temperature of the fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    Numerous arrangements of this equation are available.
    This is DIPPR Procedure 7A: Method for the Surface Tension of Pure,
    Nonpolar, Nonhydrocarbon Liquids
    The exact equation is not in the original paper.
    If the equation yields a negative result, return None.

    Examples
    --------
    p-dichloribenzene at 412.15 K, from DIPPR; value differs due to a slight
    difference in method.

    >>> Brock_Bird(412.15, 447.3, 685, 3.952E6)
    0.02208448325192495

    Chlorobenzene from Poling, as compared with a % error value at 293 K.

    >>> Brock_Bird(293.15, 404.75, 633.0, 4530000.0)
    0.032985686413713036

    References
    ----------
    .. [1] Brock, James R., and R. Byron Bird. "Surface Tension and the
       Principle of Corresponding States." AIChE Journal 1, no. 2
       (June 1, 1955): 174-77. doi:10.1002/aic.690010208


Tr = T/Tc<EOL>Pc = Pc/<NUM_LIT>  <EOL>sigma = Pc**(<NUM_LIT:2>/<NUM_LIT>)*Tc**(<NUM_LIT:1>/<NUM_LIT>)*(<NUM_LIT>+<NUM_LIT>*omega)/<NUM_LIT> * (<EOL>(<NUM_LIT>+<NUM_LIT>*omega)/(<NUM_LIT>-<NUM_LIT>*omega))**(<NUM_LIT:2>/<NUM_LIT>)*(<NUM_LIT:1>-Tr)**(<NUM_LIT:11>/<NUM_LIT>)<EOL>sigma = sigma/<NUM_LIT:1000>  <EOL>return sigma<EOL>

r'''Calculates air-water surface tension using the correlation derived
    by [1]_ from the works of [2]_ and [3]_. Based on critical property CSP
    methods.

    .. math::
        \sigma = P_c^{2/3}T_c^{1/3}\frac{1.86 + 1.18\omega}{19.05}
        \left[ \frac{3.75 + 0.91 \omega}{0.291 - 0.08 \omega}\right]^{2/3} (1-T_r)^{11/9}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor for fluid, [-]

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    The source of this equation has not been reviewed.
    Internal units of presure are bar, surface tension of mN/m.

    Examples
    --------
    Chlorobenzene from Poling, as compared with a % error value at 293 K.

    >>> Pitzer(293., 633.0, 4530000.0, 0.249)
    0.03458453513446387

    References
    ----------
    .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    .. [2] Curl, R. F., and Kenneth Pitzer. "Volumetric and Thermodynamic
       Properties of Fluids-Enthalpy, Free Energy, and Entropy." Industrial &
       Engineering Chemistry 50, no. 2 (February 1, 1958): 265-74.
       doi:10.1021/ie50578a047
    .. [3] Pitzer, K. S.: Thermodynamics, 3d ed., New York, McGraw-Hill,
       1995, p. 521.


def Sastri_Rao(T, Tb, Tc, Pc, chemicaltype=None):

if chemicaltype == '<STR_LIT>':<EOL><INDENT>k, x, y, z, m = <NUM_LIT>, <NUM_LIT>, <NUM_LIT>, <NUM_LIT:0>, <NUM_LIT><EOL><DEDENT>elif chemicaltype == '<STR_LIT>':<EOL><INDENT>k, x, y, z, m = <NUM_LIT>, <NUM_LIT>, -<NUM_LIT>, <NUM_LIT>, <NUM_LIT:11>/<NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>k, x, y, z, m = <NUM_LIT>, <NUM_LIT>, -<NUM_LIT>, <NUM_LIT>, <NUM_LIT:11>/<NUM_LIT><EOL><DEDENT>Tr = T/Tc<EOL>Tbr = Tb/Tc<EOL>Pc = Pc/<NUM_LIT>  <EOL>sigma = k*Pc**x*Tb**y*Tc**z*((<NUM_LIT:1> - Tr)/(<NUM_LIT:1> - Tbr))**m<EOL>sigma = sigma/<NUM_LIT:1000>  <EOL>return sigma<EOL>

r'''Calculates air-water surface tension using the correlation derived by
    [1]_ based on critical property CSP methods and chemical classes.

    .. math::
        \sigma = K P_c^xT_b^y T_c^z\left[\frac{1-T_r}{1-T_{br}}\right]^m

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tb : float
        Boiling temperature of the fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    The source of this equation has not been reviewed.
    Internal units of presure are bar, surface tension of mN/m.

    Examples
    --------
    Chlorobenzene from Poling, as compared with a % error value at 293 K.

    >>> Sastri_Rao(293.15, 404.75, 633.0, 4530000.0)
    0.03234567739694441

    References
    ----------
    .. [1] Sastri, S. R. S., and K. K. Rao. "A Simple Method to Predict
       Surface Tension of Organic Liquids." The Chemical Engineering Journal
       and the Biochemical Engineering Journal 59, no. 2 (October 1995): 181-86.
       doi:10.1016/0923-0467(94)02946-6.


Tc_1, Pc_1, omega_1 = <NUM_LIT>, <NUM_LIT>/<NUM_LIT>, <NUM_LIT><EOL>Tc_2, Pc_2, omega_2 = <NUM_LIT>, <NUM_LIT>/<NUM_LIT>, <NUM_LIT><EOL>Pc = Pc/<NUM_LIT><EOL>def ST_r(ST, Tc, Pc):<EOL><INDENT>return log(<NUM_LIT:1> + ST/(Tc**(<NUM_LIT:1>/<NUM_LIT>)*Pc**(<NUM_LIT:2>/<NUM_LIT>)))<EOL><DEDENT>ST_1 = <NUM_LIT>*(<NUM_LIT:1> - T/Tc)**<NUM_LIT>  <EOL>ST_2 = <NUM_LIT>*(<NUM_LIT:1> - T/Tc)**<NUM_LIT>  <EOL>ST_r_1, ST_r_2 = ST_r(ST_1, Tc_1, Pc_1), ST_r(ST_2, Tc_2, Pc_2)<EOL>sigma_r = ST_r_1 + (omega-omega_1)/(omega_2 - omega_1)*(ST_r_2-ST_r_1)<EOL>sigma = Tc**(<NUM_LIT:1>/<NUM_LIT>)*Pc**(<NUM_LIT:2>/<NUM_LIT>)*(exp(sigma_r)-<NUM_LIT:1>)<EOL>sigma = sigma/<NUM_LIT:1000>  <EOL>return sigma<EOL>

r'''Calculates air-water surface tension using the reference fluids
    methods of [1]_.

    .. math::
        \sigma^{(1)} = 40.520(1-T_r)^{1.287}
        \sigma^{(2)} = 52.095(1-T_r)^{1.21548}
        \sigma_r = \sigma_r^{(1)}+ \frac{\omega - \omega^{(1)}}
        {\omega^{(2)}-\omega^{(1)}} (\sigma_r^{(2)}-\sigma_r^{(1)})
        \sigma = T_c^{1/3}P_c^{2/3}[\exp{(\sigma_r)} -1]

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor for fluid, [-]

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    Presently untested. Have not personally checked the sources.
    I strongly believe it is broken.
    The reference values for methane and n-octane are from the DIPPR database.

    Examples
    --------
    Chlorobenzene

    >>> Zuo_Stenby(293., 633.0, 4530000.0, 0.249)
    0.03345569011871088

    References
    ----------
    .. [1] Zuo, You-Xiang, and Erling H. Stenby. "Corresponding-States and
       Parachor Models for the Calculation of Interfacial Tensions." The
       Canadian Journal of Chemical Engineering 75, no. 6 (December 1, 1997):
       1130-37. doi:10.1002/cjce.5450750617


def Hakim_Steinberg_Stiel(T, Tc, Pc, omega, StielPolar=<NUM_LIT:0>):

Q = (<NUM_LIT> + <NUM_LIT>*omega - <NUM_LIT>*StielPolar - <NUM_LIT>*StielPolar**<NUM_LIT:2><EOL>- <NUM_LIT>*omega**<NUM_LIT:2> + <NUM_LIT>*StielPolar*omega)<EOL>m = (<NUM_LIT> + <NUM_LIT>*omega - <NUM_LIT>*StielPolar - <NUM_LIT>*StielPolar**<NUM_LIT:2><EOL>- <NUM_LIT>*omega**<NUM_LIT:2> + <NUM_LIT>*StielPolar*omega)<EOL>Tr = T/Tc<EOL>Pc = Pc/<NUM_LIT><EOL>sigma = Pc**(<NUM_LIT:2>/<NUM_LIT>)*Tc**(<NUM_LIT:1>/<NUM_LIT>)*Q*((<NUM_LIT:1> - Tr)/<NUM_LIT>)**m<EOL>sigma = sigma/<NUM_LIT>  <EOL>return sigma<EOL>

r'''Calculates air-water surface tension using the reference fluids methods
    of [1]_.

    .. math::
        \sigma = 4.60104\times 10^{-7} P_c^{2/3}T_c^{1/3}Q_p \left(\frac{1-T_r}{0.4}\right)^m

        Q_p = 0.1574+0.359\omega-1.769\chi-13.69\chi^2-0.51\omega^2+1.298\omega\chi

        m = 1.21+0.5385\omega-14.61\chi-32.07\chi^2-1.65\omega^2+22.03\omega\chi

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    omega : float
        Acentric factor for fluid, [-]
    StielPolar : float, optional
        Stiel Polar Factor, [-]

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    Original equation for m and Q are used. Internal units are atm and mN/m.

    Examples
    --------
    1-butanol, as compared to value in CRC Handbook of 0.02493.

    >>> Hakim_Steinberg_Stiel(298.15, 563.0, 4414000.0, 0.59, StielPolar=-0.07872)
    0.021907902575190447

    References
    ----------
    .. [1] Hakim, D. I., David Steinberg, and L. I. Stiel. "Generalized
       Relationship for the Surface Tension of Polar Fluids." Industrial &
       Engineering Chemistry Fundamentals 10, no. 1 (February 1, 1971): 174-75.
       doi:10.1021/i160037a032.


Vc = Vc*<NUM_LIT><EOL>t = <NUM_LIT:1.>-T/Tc<EOL>sigma = k*Tc*(N_A/Vc)**(<NUM_LIT:2>/<NUM_LIT>)*(<NUM_LIT> + <NUM_LIT>*omega)*t**<NUM_LIT>*(<NUM_LIT:1>+<NUM_LIT>*t**<NUM_LIT:0.5> - <NUM_LIT>*t)*<NUM_LIT><EOL>return sigma<EOL>

r'''Calculates air-water surface tension using the methods of [1]_.

    .. math::
        \sigma = k T_c \left( \frac{N_a}{V_c}\right)^{2/3}
        (4.35 + 4.14 \omega)t^{1.26}(1+0.19t^{0.5} - 0.487t)

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Vc : float
        Critical volume of fluid [m^3/mol]
    omega : float
        Acentric factor for fluid, [-]

    Returns
    -------
    sigma : float
        Liquid surface tension, N/m

    Notes
    -----
    Uses Avogadro's constant and the Boltsman constant.
    Internal units of volume are mL/mol and mN/m. However, either a typo
    is in the article or author's work, or my value of k is off by 10; this is
    corrected nonetheless.
    Created with 31 normal fluids, none polar or hydrogen bonded. Has an
    AARD of 3.5%.

    Examples
    --------
    Bromotrifluoromethane, 2.45 mN/m

    >>> Miqueu(300., 340.1, 0.000199, 0.1687)
    0.003474099603581931

    References
    ----------
    .. [1] Miqueu, C, D Broseta, J Satherley, B Mendiboure, J Lachaise, and
       A Graciaa. "An Extended Scaled Equation for the Temperature Dependence
       of the Surface Tension of Pure Compounds Inferred from an Analysis of
       Experimental Data." Fluid Phase Equilibria 172, no. 2 (July 5, 2000):
       169-82. doi:10.1016/S0378-3812(00)00384-8.


def Aleem(T, MW, Tb, rhol, Hvap_Tb, Cpl):

MW = MW/<NUM_LIT> <EOL>sphericity = <NUM_LIT:1.> - <NUM_LIT>*MW + <NUM_LIT>*MW*MW<EOL>return sphericity*MW**(<NUM_LIT:1>/<NUM_LIT>)/(<NUM_LIT>*N_A**(<NUM_LIT:1>/<NUM_LIT>))*rhol**(<NUM_LIT:2>/<NUM_LIT>)*(Hvap_Tb + Cpl*(Tb-T))<EOL>

r'''Calculates vapor-liquid surface tension using the correlation derived by
    [1]_ based on critical property CSP methods.

    .. math::
        \sigma = \phi \frac{MW^{1/3}} {6N_A^{1/3}}\rho_l^{2/3}\left[H_{vap}
        + C_{p,l}(T_b-T)\right]

        \phi = 1 - 0.0047MW + 6.8\times 10^{-6} MW^2

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    MW : float
        Molecular weight [g/mol]
    Tb : float
        Boiling temperature of the fluid [K]
    rhol : float
        Liquid density at T and P [kg/m^3]
    Hvap_Tb : float
        Mass enthalpy of vaporization at the normal boiling point [kg/m^3]
    Cpl : float
        Liquid heat capacity of the chemical at T [J/kg/K]

    Returns
    -------
    sigma : float
        Liquid-vapor surface tension [N/m]

    Notes
    -----
    Internal units of molecuar weight are kg/mol. This model is dimensionally
    consistent.

    This model does not use the critical temperature. After it predicts a
    surface tension of 0 at a sufficiently high temperature, it returns
    negative results. The temperature at which this occurs (the "predicted"
    critical temperature) can be calculated as follows:

    .. math::
        \sigma = 0 \to T_{c,predicted} \text{ at } T_b + \frac{H_{vap}}{Cp_l}

    Because of its dependence on density, it has the potential to model the
    effect of pressure on surface tension.

    Claims AAD of 4.3%. Developed for normal alkanes. Total of 472 data points.
    Behaves worse for higher alkanes. Behaves very poorly overall.

    Examples
    --------
    Methane at 90 K

    >>> Aleem(T=90, MW=16.04246, Tb=111.6, rhol=458.7, Hvap_Tb=510870.,
    ... Cpl=2465.)
    0.01669970221165325

    References
    ----------
    .. [1] Aleem, W., N. Mellon, S. Sufian, M. I. A. Mutalib, and D. Subbarao.
       "A Model for the Estimation of Surface Tension of Pure Hydrocarbon
       Liquids." Petroleum Science and Technology 33, no. 23-24 (December 17,
       2015): 1908-15. doi:10.1080/10916466.2015.1110593.


def Mersmann_Kind_surface_tension(T, Tm, Tb, Tc, Pc, n_associated=<NUM_LIT:1>):

Tr = T/Tc<EOL>sigma_star = ((Tb - Tm)/Tm)**(<NUM_LIT:1>/<NUM_LIT>)*(<NUM_LIT>*(<NUM_LIT:1.> - Tr) + <NUM_LIT>*(<NUM_LIT:1.> - Tr)**(<NUM_LIT:4>/<NUM_LIT>))<EOL>sigma = sigma_star*(k*Tc)**(<NUM_LIT:1>/<NUM_LIT>)*(Tm/Tc)*Pc**(<NUM_LIT:2>/<NUM_LIT>)*n_associated**(-<NUM_LIT:1>/<NUM_LIT>)<EOL>return sigma<EOL>

r'''Estimates the surface tension of organic liquid substances
    according to the method of [1]_.

    .. math::
        \sigma^* = \frac{\sigma n_{ass}^{1/3}} {(kT_c)^{1/3} T_{rm}P_c^{2/3}}

        \sigma^* = \left(\frac{T_b - T_m}{T_m}\right)^{1/3}
        \left[6.25(1-T_r) + 31.3(1-T_r)^{4/3}\right]

    Parameters
    ----------
    T : float
        Temperature of the fluid [K]
    Tm : float
        Melting temperature [K]
    Tb : float
        Boiling temperature of the fluid [K]
    Tc : float
        Critical temperature of the fluid [K]
    Pc : float
        Critical pressure of the fluid [Pa]
    n_associated : float
        Number of associated molecules in a cluster (2 for alcohols, 1
        otherwise), [-]

    Returns
    -------
    sigma : float
        Liquid-vapor surface tension [N/m]

    Notes
    -----
    In the equation, all quantities must be in SI units. `k` is the boltzman
    constant.

    Examples
    --------
    MTBE at STP (the actual value is 0.0181):

    >>> Mersmann_Kind_surface_tension(298.15, 164.15, 328.25, 497.1, 3430000.0)
    0.016744309508833335

    References
    ----------
    .. [1] Mersmann, Alfons, and Matthias Kind. "Prediction of Mechanical and
       Thermal Properties of Pure Liquids, of Critical Data, and of Vapor
       Pressure." Industrial & Engineering Chemistry Research, January 31,
       2017. https://doi.org/10.1021/acs.iecr.6b04323.


def Winterfeld_Scriven_Davis(xs, sigmas, rhoms):

if not none_and_length_check([xs, sigmas, rhoms]):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>rhoms = [i*<NUM_LIT> for i in rhoms]<EOL>Vms = [<NUM_LIT:1.>/i for i in rhoms]<EOL>rho = <NUM_LIT:1.>/mixing_simple(xs, Vms)<EOL>cmps = range(len(xs))<EOL>rho2 = rho*rho<EOL>return sum([rho2*xs[i]/rhoms[i]*xs[j]/rhoms[j]*(sigmas[j]*sigmas[i])**<NUM_LIT:0.5><EOL>for i in cmps for j in cmps])<EOL>

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.024967388450439824

    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.


def Diguilio_Teja(T, xs, sigmas_Tb, Tbs, Tcs):

if not none_and_length_check([xs, sigmas_Tb, Tbs, Tcs]):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>Tc = mixing_simple(xs, Tcs)<EOL>if T > Tc:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>Tb = mixing_simple(xs, Tbs)<EOL>sigmar = mixing_simple(xs, sigmas_Tb)<EOL>Tst = (Tc/T - <NUM_LIT:1.>)/(Tc/Tb - <NUM_LIT:1>)<EOL>return <NUM_LIT>*Tst**<NUM_LIT>*(T/Tb)*sigmar<EOL>

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.

    [1]_ claims a 4.63 percent average absolute error on 21 binary and 4
    ternary non-aqueous systems. [1]_ also considered Van der Waals mixing
    rules for `Tc`, but found it provided a higher error of 5.58%

    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.