tolerance = <NUM_LIT>;<EOL>result = (self.__number_points == entry.number_points);<EOL>result &= ( (self.square_sum + tolerance > entry.square_sum) and (self.square_sum - tolerance < entry.square_sum) );<EOL>for index_dimension in range(<NUM_LIT:0>, len(self.linear_sum)):<EOL><INDENT>result &= ( (self.linear_sum[index_dimension] + tolerance > entry.linear_sum[index_dimension]) and (self.linear_sum[index_dimension] - tolerance < entry.linear_sum[index_dimension]) );<EOL><DEDENT>return result<EOL>

!
        @brief Overloaded operator eq.
        @details Performs comparison of two clustering features.

        @param[in] entry (cfentry): Entry that is used for comparison with current.

        @return (bool) True is both clustering features are equals in line with tolerance, otherwise False.


def show_feature_destibution(self, data = None):

visualizer = cluster_visualizer();<EOL>print("<STR_LIT>", self.__amount_nodes);<EOL>if (data is not None):<EOL><INDENT>visualizer.append_cluster(data, marker = '<STR_LIT:x>');<EOL><DEDENT>for level in range(<NUM_LIT:0>, self.height):<EOL><INDENT>level_nodes = self.get_level_nodes(level);<EOL>centers = [ node.feature.get_centroid() for node in level_nodes ];<EOL>visualizer.append_cluster(centers, None, markersize = (self.height - level + <NUM_LIT:1>) * <NUM_LIT:5>);<EOL><DEDENT>visualizer.show()<EOL>

!
        @brief Shows feature distribution.
        @details Only features in 1D, 2D, 3D space can be visualized.

        @param[in] data (list): List of points that will be used for visualization, if it not specified than feature will be displayed only.


def __insert_for_noneleaf_node(self, entry, search_node):

node_amount_updation = False;<EOL>min_key = lambda child_node: child_node.get_distance(search_node, self.__type_measurement);<EOL>nearest_child_node = min(search_node.successors, key = min_key);<EOL>child_node_updation = self.__recursive_insert(entry, nearest_child_node);<EOL>search_node.feature += entry;<EOL>if (len(search_node.successors) > self.__branch_factor):<EOL><INDENT>if (search_node is self.__root):<EOL><INDENT>self.__root = non_leaf_node(search_node.feature, None, [ search_node ], None);<EOL>search_node.parent = self.__root;<EOL>self.__amount_nodes += <NUM_LIT:1>;<EOL>self.__height += <NUM_LIT:1>;<EOL><DEDENT>[new_node1, new_node2] = self.__split_nonleaf_node(search_node);<EOL>parent = search_node.parent;<EOL>parent.successors.remove(search_node);<EOL>parent.successors.append(new_node1);<EOL>parent.successors.append(new_node2);<EOL>self.__amount_nodes += <NUM_LIT:1>;<EOL>node_amount_updation = True;<EOL><DEDENT>elif (child_node_updation is True):<EOL><INDENT>if (self.__merge_nearest_successors(search_node) is True):<EOL><INDENT>self.__amount_nodes -= <NUM_LIT:1>;<EOL><DEDENT><DEDENT>return node_amount_updation<EOL>

!
        @brief Recursive insert entry from none-leaf node to the tree.

        @param[in] entry (cfentry): Clustering feature.
        @param[in] search_node (cfnode): None-leaf node from that insertion should be started.

        @return (bool) True if number of nodes at the below level is changed, otherwise False.


number_points = self.number_points + entry.number_points;<EOL>result_linear_sum = list_math_addition(self.linear_sum, entry.linear_sum);<EOL>result_square_sum = self.square_sum + entry.square_sum;  <EOL>return cfentry(number_points, result_linear_sum, result_square_sum)<EOL>

!
        @brief Overloaded operator add. Performs addition of two clustering features.

        @param[in] entry (cfentry): Entry that is added to the current.

        @return (cfentry) Result of addition of two clustering features.


linear_part_12 = list_math_addition(self.linear_sum, entry.linear_sum);<EOL>variance_part_first = (self.square_sum + entry.square_sum) -<NUM_LIT> * sum(list_math_multiplication(linear_part_12, linear_part_12)) / (self.number_points + entry.number_points) +(self.number_points + entry.number_points) * sum(list_math_multiplication(linear_part_12, linear_part_12)) / (self.number_points + entry.number_points)**<NUM_LIT>;<EOL>linear_part_11 = sum(list_math_multiplication(self.linear_sum, self.linear_sum));<EOL>variance_part_second = -( self.square_sum - (<NUM_LIT> * linear_part_11 / self.number_points) + (linear_part_11 / self.number_points) );<EOL>linear_part_22 = sum(list_math_multiplication(entry.linear_sum, entry.linear_sum));<EOL>variance_part_third = -( entry.square_sum - (<NUM_LIT> / entry.number_points) * linear_part_22 + entry.number_points * (<NUM_LIT:1.0> / entry.number_points ** <NUM_LIT>) * linear_part_22 );<EOL>return (variance_part_first + variance_part_second + variance_part_third)<EOL>

!
        @brief Calculates variance increase distance between current and specified clusters.

        @param[in] entry (cfentry): Clustering feature to which distance should be obtained.

        @return (double) Variance increase distance.


return self.__branch_factor<EOL>

!
        @return (uint) Branching factor of the tree.
        @details Branching factor defines maximum number of successors in each non-leaf node.


return self.__repr__()<EOL>

!
        @return (string) String representation of CF node.


if (self.__centroid is not None):<EOL><INDENT>return self.__centroid;<EOL><DEDENT>self.__centroid = [<NUM_LIT:0>] * len(self.linear_sum);<EOL>for index_dimension in range(<NUM_LIT:0>, len(self.linear_sum)):<EOL><INDENT>self.__centroid[index_dimension] = self.linear_sum[index_dimension] / self.number_points;<EOL><DEDENT>return self.__centroid<EOL>

!
        @brief Calculates centroid of cluster that is represented by the entry.
        @details It's calculated once when it's requested after the last changes.

        @return (list) Centroid of cluster that is represented by the entry.


number_points = self.number_points - entry.number_points;<EOL>result_linear_sum = list_math_subtraction(self.linear_sum, entry.linear_sum);<EOL>result_square_sum = self.square_sum - entry.square_sum;<EOL>if ( (number_points < <NUM_LIT:0>) or (result_square_sum < <NUM_LIT:0>) ):<EOL><INDENT>raise NameError("<STR_LIT>");<EOL><DEDENT>return cfentry(number_points, result_linear_sum, result_square_sum)<EOL>

!
        @brief Overloaded operator sub. Performs substraction of two clustering features.
        @details Substraction can't be performed with clustering feature whose description is less then substractor.

        @param[in] entry (cfentry): Entry that is substracted from the current.

        @return (cfentry) Result of substraction of two clustering features.


return self.__successors<EOL>

!
        @return (list) List of successors of the node.


def __init__(self, number_points, linear_sum, square_sum):

self.__number_points = number_points;<EOL>self.__linear_sum = linear_sum;<EOL>self.__square_sum = square_sum;<EOL>self.__centroid = None;<EOL>self.__radius = None;<EOL>self.__diameter = None<EOL>

!
        @brief CF-entry constructor.

        @param[in] number_points (uint): Number of objects that is represented by the entry.
        @param[in] linear_sum (list): Linear sum of values that represent objects in each dimension.
        @param[in] square_sum (double): Square sum of values that represent objects.


return self.__linear_sum<EOL>

!
        @brief Returns linear sum.

        @return (list) Linear sum.


def __init__(self, feature, parent, payload):

<EOL>self.feature = copy(feature);<EOL>self.parent = parent;<EOL>self.type = cfnode_type.CFNODE_DUMMY;<EOL>self.payload = payload<EOL>

!
        @brief Constructor of abstract CF node.

        @param[in] feature (cfentry): Clustering feature of the created node.
        @param[in] parent (cfnode): Parent of the created node.
        @param[in] payload (*): Data that is stored by the node.


return self.__type_measurement<EOL>

!
        @return (measurement_type) Type that is used for measuring.


text_entries = "<STR_LIT:\n>";<EOL>for entry in self.entries:<EOL><INDENT>text_entries += "<STR_LIT:\t>" + str(entry) + "<STR_LIT:\n>";<EOL><DEDENT>return '<STR_LIT>' % ( hex(id(self)), self.parent, self.feature, len(self.entries), text_entries )<EOL>

!
        @return (string) Default leaf node represenation.


entry = cfentry(len(cluster), linear_sum(cluster), square_sum(cluster));<EOL>self.insert(entry)<EOL>

!
        @brief Insert cluster that is represented as list of points where each point is represented by list of coordinates.
        @details Clustering feature is created for that cluster and inserted to the tree.

        @param[in] cluster (list): Cluster that is represented by list of points that should be inserted to the tree.


def get_nearest_index_entry(self, entry, type_measurement):

minimum_distance = float('<STR_LIT>');<EOL>nearest_index = <NUM_LIT:0>;<EOL>for candidate_index in range(<NUM_LIT:0>, len(self.entries)):<EOL><INDENT>candidate_distance = self.entries[candidate_index].get_distance(entry, type_measurement);<EOL>if (candidate_distance < minimum_distance):<EOL><INDENT>nearest_index = candidate_index;<EOL><DEDENT><DEDENT>return nearest_index<EOL>

!
        @brief Find nearest index of nearest entry of node for the specified entry.

        @param[in] entry (cfentry): Entry that is used for calculation distance.
        @param[in] type_measurement (measurement_type): Measurement type that is used for obtaining nearest entry to the specified.

        @return (uint) Index of nearest entry of node for the specified entry.


[farthest_node1, farthest_node2] = node.get_farthest_successors(self.__type_measurement);<EOL>new_node1 = non_leaf_node(farthest_node1.feature, node.parent, [ farthest_node1 ], None);<EOL>new_node2 = non_leaf_node(farthest_node2.feature, node.parent, [ farthest_node2 ], None);<EOL>farthest_node1.parent = new_node1;<EOL>farthest_node2.parent = new_node2;<EOL>for successor in node.successors:<EOL><INDENT>if ( (successor is not farthest_node1) and (successor is not farthest_node2) ):<EOL><INDENT>distance1 = new_node1.get_distance(successor, self.__type_measurement);<EOL>distance2 = new_node2.get_distance(successor, self.__type_measurement);<EOL>if (distance1 < distance2):<EOL><INDENT>new_node1.insert_successor(successor);<EOL><DEDENT>else:<EOL><INDENT>new_node2.insert_successor(successor);<EOL><DEDENT><DEDENT><DEDENT>return [new_node1, new_node2]<EOL>

!
        @brief Performs splitting of the specified non-leaf node.

        @param[in] node (non_leaf_node): Non-leaf node that should be splitted.

        @return (list) New pair of non-leaf nodes [non_leaf_node1, non_leaf_node2].


def __recursive_insert(self, entry, search_node):

<EOL>if (search_node.type == cfnode_type.CFNODE_NONLEAF):<EOL><INDENT>return self.__insert_for_noneleaf_node(entry, search_node);<EOL><DEDENT>else:<EOL><INDENT>return self.__insert_for_leaf_node(entry, search_node);<EOL><DEDENT>

!
        @brief Recursive insert of the entry to the tree.
        @details It performs all required procedures during insertion such as splitting, merging.

        @param[in] entry (cfentry): Clustering feature.
        @param[in] search_node (cfnode): Node from that insertion should be started.

        @return (bool) True if number of nodes at the below level is changed, otherwise False.


linear_part_distance = sum(list_math_multiplication(self.linear_sum, entry.linear_sum));<EOL>return ( (entry.number_points * self.square_sum - <NUM_LIT> * linear_part_distance + self.number_points * entry.square_sum) / (self.number_points * entry.number_points) ) ** <NUM_LIT:0.5><EOL>

!
        @brief Calculates average inter cluster distance between current and specified clusters.

        @param[in] entry (cfentry): Clustering feature to which distance should be obtained.

        @return (double) Average inter cluster distance.


return self.__leafes<EOL>

!
        @return (list) List of all non-leaf nodes in the tree.


farthest_node1 = None;<EOL>farthest_node2 = None;<EOL>farthest_distance = <NUM_LIT:0>;<EOL>for i in range(<NUM_LIT:0>, len(self.successors)):<EOL><INDENT>candidate1 = self.successors[i];<EOL>for j in range(i + <NUM_LIT:1>, len(self.successors)):<EOL><INDENT>candidate2 = self.successors[j];<EOL>candidate_distance = candidate1.get_distance(candidate2, type_measurement);<EOL>if (candidate_distance > farthest_distance):<EOL><INDENT>farthest_distance = candidate_distance;<EOL>farthest_node1 = candidate1;<EOL>farthest_node2 = candidate2;        <EOL>return [farthest_node1, farthest_node2];<EOL><DEDENT><DEDENT><DEDENT>

!
        @brief Find pair of farthest successors of the node in line with measurement type.

        @param[in] type_measurement (measurement_type): Measurement type that is used for obtaining farthest successors.

        @return (list) Pair of farthest successors represented by list [cfnode1, cfnode2].


if (self.__diameter is not None):<EOL><INDENT>return self.__diameter;<EOL><DEDENT>diameter_part = <NUM_LIT:0.0>;<EOL>if (type(self.linear_sum) == list):<EOL><INDENT>diameter_part = self.square_sum * self.number_points - <NUM_LIT> * sum(list_math_multiplication(self.linear_sum, self.linear_sum)) + self.square_sum * self.number_points;<EOL><DEDENT>else:<EOL><INDENT>diameter_part = self.square_sum * self.number_points - <NUM_LIT> * self.linear_sum * self.linear_sum + self.square_sum * self.number_points;<EOL><DEDENT>self.__diameter = ( diameter_part / (self.number_points * (self.number_points - <NUM_LIT:1>)) ) ** <NUM_LIT:0.5>;<EOL>return self.__diameter<EOL>

!
        @brief Calculates diameter of cluster that is represented by the entry.
        @details It's calculated once when it's requested after the last changes.

        @return (double) Diameter of cluster that is represented by the entry.


return self.__amount_nodes<EOL>

!
        @return (unit) Number of nodes (leaf and non-leaf) in the tree.


def get_distance(self, entry, type_measurement):

if (type_measurement is measurement_type.CENTROID_EUCLIDEAN_DISTANCE):<EOL><INDENT>return euclidean_distance_square(entry.get_centroid(), self.get_centroid());<EOL><DEDENT>elif (type_measurement is measurement_type.CENTROID_MANHATTAN_DISTANCE):<EOL><INDENT>return manhattan_distance(entry.get_centroid(), self.get_centroid());<EOL><DEDENT>elif (type_measurement is measurement_type.AVERAGE_INTER_CLUSTER_DISTANCE):<EOL><INDENT>return self.__get_average_inter_cluster_distance(entry);<EOL><DEDENT>elif (type_measurement is measurement_type.AVERAGE_INTRA_CLUSTER_DISTANCE):<EOL><INDENT>return self.__get_average_intra_cluster_distance(entry);<EOL><DEDENT>elif (type_measurement is measurement_type.VARIANCE_INCREASE_DISTANCE):<EOL><INDENT>return self.__get_variance_increase_distance(entry);<EOL><DEDENT>else:<EOL><INDENT>assert <NUM_LIT:0>;<EOL><DEDENT>

!
        @brief Calculates distance between two clusters in line with measurement type.

        @details In case of usage CENTROID_EUCLIDIAN_DISTANCE square euclidian distance will be returned.
                 Square root should be taken from the result for obtaining real euclidian distance between
                 entries.

        @param[in] entry (cfentry): Clustering feature to which distance should be obtained.
        @param[in] type_measurement (measurement_type): Distance measurement algorithm between two clusters.

        @return (double) Distance between two clusters.


if node_parent.left is not None:<EOL><INDENT>yield node_parent.left<EOL><DEDENT>if node_parent.right is not None:<EOL><INDENT>yield node_parent.right<EOL><DEDENT>

!
        @brief Returns list of children of node.

        @param[in] node_parent (node): Node whose children are required.

        @return (list) Children of node. If node haven't got any child then None is returned.


def traverse(self, start_node = None, level = None):

if start_node is None:<EOL><INDENT>start_node  = self.__root<EOL>level = <NUM_LIT:0><EOL><DEDENT>if start_node is None:<EOL><INDENT>return []<EOL><DEDENT>items = [ (level, start_node) ]<EOL>for child in self.children(start_node):<EOL><INDENT>if child is not None:<EOL><INDENT>items += self.traverse(child, level + <NUM_LIT:1>)<EOL><DEDENT><DEDENT>return items<EOL>

!
        @brief Traverses all nodes of subtree that is defined by node specified in input parameter.

        @param[in] start_node (node): Node from that travering of subtree is performed.
        @param[in, out] level (uint): Should be ignored by application.

        @return (list) All nodes of the subtree.


<EOL>node_for_remove = None<EOL>if '<STR_LIT>' in kwargs:<EOL><INDENT>node_for_remove = self.find_node_with_payload(point, kwargs['<STR_LIT>'], None)<EOL><DEDENT>else:<EOL><INDENT>node_for_remove = self.find_node(point, None)<EOL><DEDENT>if node_for_remove is None:<EOL><INDENT>return None<EOL><DEDENT>parent = node_for_remove.parent<EOL>minimal_node = self.__recursive_remove(node_for_remove)<EOL>if parent is None:<EOL><INDENT>self.__root = minimal_node<EOL>if minimal_node is not None:<EOL><INDENT>minimal_node.parent = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if parent.left is node_for_remove:<EOL><INDENT>parent.left = minimal_node<EOL><DEDENT>elif parent.right is node_for_remove:<EOL><INDENT>parent.right = minimal_node<EOL><DEDENT><DEDENT>return self.__root<EOL>

!
        @brief Remove specified point from kd-tree.
        @details It removes the first found node that satisfy to the input parameters. Make sure that
                  pair (point, payload) is unique for each node, othewise the first found is removed.

        @param[in] point (list): Coordinates of the point of removed node.
        @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'payload').

        Keyword Args:

            - payload (any): Payload of the node that should be removed.

        @return (node) Root if node has been successfully removed, otherwise None.


if self.__root is None:<EOL><INDENT>self.__dimension = len(point)<EOL>self.__root = node(point, payload, None, None, <NUM_LIT:0>)<EOL>self.__point_comparator = self.__create_point_comparator(type(point))<EOL>return self.__root<EOL><DEDENT>cur_node = self.__root<EOL>while True:<EOL><INDENT>if cur_node.data[cur_node.disc] <= point[cur_node.disc]:<EOL><INDENT>if cur_node.right is None:<EOL><INDENT>discriminator = cur_node.disc + <NUM_LIT:1><EOL>if discriminator >= self.__dimension:<EOL><INDENT>discriminator = <NUM_LIT:0><EOL><DEDENT>cur_node.right = node(point, payload, None, None, discriminator, cur_node)<EOL>return cur_node.right<EOL><DEDENT>else: <EOL><INDENT>cur_node = cur_node.right<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if cur_node.left is None:<EOL><INDENT>discriminator = cur_node.disc + <NUM_LIT:1><EOL>if discriminator >= self.__dimension:<EOL><INDENT>discriminator = <NUM_LIT:0><EOL><DEDENT>cur_node.left = node(point, payload, None, None, discriminator, cur_node)<EOL>return cur_node.left<EOL><DEDENT>else:<EOL><INDENT>cur_node = cur_node.left<EOL><DEDENT><DEDENT><DEDENT>

!
        @brief Insert new point with payload to kd-tree.

        @param[in] point (list): Coordinates of the point of inserted node.
        @param[in] payload (any-type): Payload of inserted node. It can be identificator of the node or
                    some useful payload that belongs to the point.

        @return (node) Inserted node to the kd-tree.


def find_nearest_dist_node(self, point, distance, retdistance = False):

best_nodes = self.find_nearest_dist_nodes(point, distance)<EOL>if best_nodes == []:<EOL><INDENT>return None<EOL><DEDENT>nearest = min(best_nodes, key = lambda item: item[<NUM_LIT:0>])<EOL>if retdistance is True:<EOL><INDENT>return nearest<EOL><DEDENT>else:<EOL><INDENT>return nearest[<NUM_LIT:1>]<EOL><DEDENT>

!
        @brief Find nearest neighbor in area with radius = distance.

        @param[in] point (list): Maximum distance where neighbors are searched.
        @param[in] distance (double): Maximum distance where neighbors are searched.
        @param[in] retdistance (bool): If True - returns neighbors with distances to them, otherwise only neighbors is returned.

        @return (node|list) Nearest neighbor if 'retdistance' is False and list with two elements [node, distance] if 'retdistance' is True,
                 where the first element is pointer to node and the second element is distance to it.


if type_point == numpy.ndarray:<EOL><INDENT>return lambda obj1, obj2: numpy.array_equal(obj1, obj2)<EOL><DEDENT>return lambda obj1, obj2: obj1 == obj2<EOL>

!
        @brief Create point comparator.
        @details In case of numpy.array specific comparator is required.

        @param[in] type_point (data_type): Type of point that is stored in KD-node.

        @return (callable) Callable point comparator to compare to points.


kdnodes = self.__get_nodes()<EOL>level = kdnodes[<NUM_LIT:0>]<EOL>for kdnode in kdnodes:<EOL><INDENT>self.__print_node(level, kdnode)<EOL><DEDENT>self.__tree_text += self.__tree_level_text<EOL>if display is True:<EOL><INDENT>print(self.__tree_text)<EOL><DEDENT>return self.__tree_text<EOL>

!
        @brief Display KD-tree to console.

        @param[in] display (bool): If 'True' then tree will be shown in console.

        @return (string) Text representation of the KD-tree.


left = None<EOL>right = None<EOL>if self.left is not None:<EOL><INDENT>left = self.left.data<EOL><DEDENT>if self.right is not None:<EOL><INDENT>right = self.right.data<EOL><DEDENT>return "<STR_LIT>" % (self.data, left, right)<EOL>

!
        @return (string) Default representation of the node.


clusters = self.get_clusters()<EOL>return [len(cluster) for cluster in clusters]<EOL>

!
        @brief Read proper cluster lengths.
        @details Cluster length means amount of point in a cluster.

        @return (list) Cluster lengths where each length means amount of points in a cluster.


self.__answer_path = answer_path<EOL>self.__clusters = None<EOL>self.__noise = None<EOL>

!
        @brief Creates instance of answer reader to read proper clustering results of samples.

        @param[in] answer_path (string): Path to clustering results (answers).


def Hf(CASRN, AvailableMethods=False, Method=None):

def list_methods():<EOL><INDENT>methods = []<EOL>if CASRN in API_TDB_data.index:<EOL><INDENT>methods.append(API_TDB)<EOL><DEDENT>methods.append(NONE)<EOL>return methods<EOL><DEDENT>if AvailableMethods:<EOL><INDENT>return list_methods()<EOL><DEDENT>if not Method:<EOL><INDENT>Method = list_methods()[<NUM_LIT:0>]<EOL><DEDENT>if Method == API_TDB:<EOL><INDENT>_Hf = float(API_TDB_data.at[CASRN, '<STR_LIT>'])<EOL><DEDENT>elif Method == NONE:<EOL><INDENT>_Hf = None<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>return _Hf<EOL>

r'''This function handles the retrieval of a chemical's standard-phase
    heat of formation. The lookup is based on CASRNs. Selects the only
    data source available ('API TDB') if the chemical is in it.
    Returns None if the data is not available.

    Function has data for 571 chemicals.

    Parameters
    ----------
    CASRN : string
        CASRN [-]

    Returns
    -------
    Hf : float
        Standard-state heat of formation, [J/mol]
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain Hf with the given inputs

    Other Parameters
    ----------------
    Method : string, optional
        A string for the method name to use, as defined by constants in
        Hf_methods
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        Hf for the desired chemical, and will return methods instead of Hf

    Notes
    -----
    Only one source of information is available to this function. it is:

        * 'API_TDB', a compilation of heats of formation of unspecified phase.
          Not the original data, but as reproduced in [1]_. Some chemicals with
          duplicated CAS numbers were removed.

    Examples
    --------
    >>> Hf(CASRN='7732-18-5')
    -241820.0

    References
    ----------
    .. [1] Albahri, Tareq A., and Abdulla F. Aljasmi. "SGC Method for
       Predicting the Standard Enthalpy of Formation of Pure Compounds from
       Their Molecular Structures." Thermochimica Acta 568
       (September 20, 2013): 46-60. doi:10.1016/j.tca.2013.06.020.


def Hf_g(CASRN, AvailableMethods=False, Method=None):

def list_methods():<EOL><INDENT>methods = []<EOL>if CASRN in ATcT_g.index:<EOL><INDENT>methods.append(ATCT_G)<EOL><DEDENT>if CASRN in TRC_gas_data.index and not np.isnan(TRC_gas_data.at[CASRN, '<STR_LIT>']):<EOL><INDENT>methods.append(TRC)<EOL><DEDENT>methods.append(NONE)<EOL>return methods<EOL><DEDENT>if AvailableMethods:<EOL><INDENT>return list_methods()<EOL><DEDENT>if not Method:<EOL><INDENT>Method = list_methods()[<NUM_LIT:0>]<EOL><DEDENT>if Method == ATCT_G:<EOL><INDENT>_Hfg = float(ATcT_g.at[CASRN, '<STR_LIT>'])<EOL><DEDENT>elif Method == TRC:<EOL><INDENT>_Hfg = float(TRC_gas_data.at[CASRN, '<STR_LIT>'])<EOL><DEDENT>elif Method == NONE:<EOL><INDENT>return None<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>return _Hfg<EOL>

r'''This function handles the retrieval of a chemical's gas heat of
    formation. Lookup is based on CASRNs. Will automatically select a data
    source to use if no Method is provided; returns None if the data is not
    available.

    Prefered sources are 'Active Thermochemical Tables (g)' for high accuracy,
    and 'TRC' for less accuracy but more chemicals.
    Function has data for approximately 2000 chemicals.

    Parameters
    ----------
    CASRN : string
        CASRN [-]

    Returns
    -------
    _Hfg : float
        Gas phase heat of formation, [J/mol]
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain Hf(g) with the given inputs

    Other Parameters
    ----------------
    Method : string, optional
        A string for the method name to use, as defined by constants in
        Hf_g_methods
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        Hf(g) for the desired chemical, and will return methods instead of Hf(g)

    Notes
    -----
    Sources are:

        * 'ATCT_G', the Active Thermochemical Tables version 1.112.
        * 'TRC', from a 1994 compilation.

    Examples
    --------
    >>> Hf_g('67-56-1')
    -200700.0

    References
    ----------
    .. [1] Ruscic, Branko, Reinhardt E. Pinzon, Gregor von Laszewski, Deepti
       Kodeboyina, Alexander Burcat, David Leahy, David Montoy, and Albert F.
       Wagner. "Active Thermochemical Tables: Thermochemistry for the 21st
       Century." Journal of Physics: Conference Series 16, no. 1
       (January 1, 2005): 561. doi:10.1088/1742-6596/16/1/078.
    .. [2] Frenkelʹ, M. L, Texas Engineering Experiment Station, and
       Thermodynamics Research Center. Thermodynamics of Organic Compounds in
       the Gas State. College Station, Tex.: Thermodynamics Research Center,
       1994.


try:<EOL><INDENT>check = CASRN[-<NUM_LIT:1>]<EOL>CASRN = CASRN[::-<NUM_LIT:1>][<NUM_LIT:1>:]<EOL>productsum = <NUM_LIT:0><EOL>i = <NUM_LIT:1><EOL>for num in CASRN:<EOL><INDENT>if num == '<STR_LIT:->':<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>productsum += i*int(num)<EOL>i += <NUM_LIT:1><EOL><DEDENT><DEDENT>return (productsum % <NUM_LIT:10> == int(check))<EOL><DEDENT>except:<EOL><INDENT>return False<EOL><DEDENT>

Checks if a CAS number is valid. Returns False if the parser cannot
    parse the given string..

    Parameters
    ----------
    CASRN : string
        A three-piece, dash-separated set of numbers

    Returns
    -------
    result : bool
        Boolean value if CASRN was valid. If parsing fails, return False also.

    Notes
    -----
    Check method is according to Chemical Abstract Society. However, no lookup
    to their service is performed; therefore, this function cannot detect
    false positives.

    Function also does not support additional separators, apart from '-'.

    CAS numbers up to the series 1 XXX XXX-XX-X are now being issued.

    A long can hold CAS numbers up to 2 147 483-64-7

    Examples
    --------
    >>> checkCAS('7732-18-5')
    True
    >>> checkCAS('77332-18-5')
    False


return pubchem_db.search_CAS(CASRN).InChI<EOL>


return pubchem_db.search_CAS(CASRN).InChI_key<EOL>


return pubchem_db.search_CAS(CASRN).MW<EOL>

Given a CASRN in the database, obtain the Molecular weight of the
    compound, if it is in the database.

    Parameters
    ----------
    CASRN : string
        Valid CAS number in PubChem database

    Returns
    -------
    MolecularWeight : float

    Notes
    -----
    CASRN must be an indexing key in the pubchem database. No MW Calculation is
    performed; nor are any historical isotopic corrections applied.

    Examples
    --------
    >>> MW('7732-18-5')
    18.01528

    References
    ----------
    .. [1] Pubchem.


def Tm_depression_eutectic(Tm, Hm, x=None, M=None, MW=None):

if x:<EOL><INDENT>dTm = R*Tm**<NUM_LIT:2>*x/Hm<EOL><DEDENT>elif M and MW:<EOL><INDENT>MW = MW/<NUM_LIT> <EOL>dTm = R*Tm**<NUM_LIT:2>*MW*M/Hm<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>return dTm<EOL>

r'''Returns the freezing point depression caused by a solute in a solvent.
    Can use either the mole fraction of the solute or its molality and the
    molecular weight of the solvent. Assumes ideal system behavior.

    .. math::
        \Delta T_m = \frac{R T_m^2 x}{\Delta H_m}

        \Delta T_m = \frac{R T_m^2 (MW) M}{1000 \Delta H_m}

    Parameters
    ----------
    Tm : float
        Melting temperature of the solute [K]
    Hm : float
        Heat of melting at the melting temperature of the solute [J/mol]
    x : float, optional
        Mole fraction of the solute [-]
    M : float, optional
        Molality [mol/kg]
    MW: float, optional
        Molecular weight of the solvent [g/mol]

    Returns
    -------
    dTm : float
        Freezing point depression [K]

    Notes
    -----
    MW is the molecular weight of the solvent. M is the molality of the solute.

    Examples
    --------
    From [1]_, matching example.

    >>> Tm_depression_eutectic(353.35, 19110, .02)
    1.0864594900639515

    References
    ----------
    .. [1] Gmehling, Jurgen. Chemical Thermodynamics: For Process Simulation.
       Weinheim, Germany: Wiley-VCH, 2012.


def solubility_eutectic(T, Tm, Hm, Cpl=<NUM_LIT:0>, Cps=<NUM_LIT:0>, gamma=<NUM_LIT:1>):

dCp = Cpl-Cps<EOL>x = exp(- Hm/R/T*(<NUM_LIT:1>-T/Tm) + dCp*(Tm-T)/R/T - dCp/R*log(Tm/T))/gamma<EOL>return x<EOL>

r'''Returns the maximum solubility of a solute in a solvent.

    .. math::
        \ln x_i^L \gamma_i^L = \frac{\Delta H_{m,i}}{RT}\left(
        1 - \frac{T}{T_{m,i}}\right) - \frac{\Delta C_{p,i}(T_{m,i}-T)}{RT}
        + \frac{\Delta C_{p,i}}{R}\ln\frac{T_m}{T}

        \Delta C_{p,i} = C_{p,i}^L - C_{p,i}^S

    Parameters
    ----------
    T : float
        Temperature of the system [K]
    Tm : float
        Melting temperature of the solute [K]
    Hm : float
        Heat of melting at the melting temperature of the solute [J/mol]
    Cpl : float, optional
        Molar heat capacity of the solute as a liquid [J/mol/K]
    Cpls: float, optional
        Molar heat capacity of the solute as a solid [J/mol/K]
    gamma : float, optional
        Activity coefficient of the solute as a liquid [-]

    Returns
    -------
    x : float
        Mole fraction of solute at maximum solubility [-]

    Notes
    -----
    gamma is of the solute in liquid phase

    Examples
    --------
    From [1]_, matching example

    >>> solubility_eutectic(T=260., Tm=278.68, Hm=9952., Cpl=0, Cps=0, gamma=3.0176)
    0.24340068761677464

    References
    ----------
    .. [1] Gmehling, Jurgen. Chemical Thermodynamics: For Process Simulation.
       Weinheim, Germany: Wiley-VCH, 2012.


def solubility_parameter(T=<NUM_LIT>, Hvapm=None, Vml=None,<EOL>CASRN='<STR_LIT>', AvailableMethods=False, Method=None):

def list_methods():<EOL><INDENT>methods = []<EOL>if T and Hvapm and Vml:<EOL><INDENT>methods.append(DEFINITION)<EOL><DEDENT>methods.append(NONE)<EOL>return methods<EOL><DEDENT>if AvailableMethods:<EOL><INDENT>return list_methods()<EOL><DEDENT>if not Method:<EOL><INDENT>Method = list_methods()[<NUM_LIT:0>]<EOL><DEDENT>if Method == DEFINITION:<EOL><INDENT>if (not Hvapm) or (not T) or (not Vml):<EOL><INDENT>delta = None<EOL><DEDENT>else:<EOL><INDENT>if Hvapm < R*T or Vml < <NUM_LIT:0>:  <EOL><INDENT>delta = None<EOL><DEDENT>else:<EOL><INDENT>delta = ((Hvapm - R*T)/Vml)**<NUM_LIT:0.5><EOL><DEDENT><DEDENT><DEDENT>elif Method == NONE:<EOL><INDENT>delta = None<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>return delta<EOL>

r'''This function handles the calculation of a chemical's solubility
    parameter. Calculation is a function of temperature, but is not always
    presented as such. No lookup values are available; either `Hvapm`, `Vml`,
    and `T` are provided or the calculation cannot be performed.

    .. math::
        \delta = \sqrt{\frac{\Delta H_{vap} - RT}{V_m}}

    Parameters
    ----------
    T : float
        Temperature of the fluid [k]
    Hvapm : float
        Heat of vaporization [J/mol/K]
    Vml : float
        Specific volume of the liquid [m^3/mol]
    CASRN : str, optional
        CASRN of the fluid, not currently used [-]

    Returns
    -------
    delta : float
        Solubility parameter, [Pa^0.5]
    methods : list, only returned if AvailableMethods == True
        List of methods which can be used to obtain the solubility parameter
        with the given inputs

    Other Parameters
    ----------------
    Method : string, optional
        A string for the method name to use, as defined by constants in
        solubility_parameter_methods
    AvailableMethods : bool, optional
        If True, function will determine which methods can be used to obtain
        the solubility parameter for the desired chemical, and will return
        methods instead of the solubility parameter

    Notes
    -----
    Undefined past the critical point. For convenience, if Hvap is not defined,
    an error is not raised; None is returned instead. Also for convenience,
    if Hvapm is less than RT, None is returned to avoid taking the root of a
    negative number.

    This parameter is often given in units of cal/ml, which is 2045.48 times
    smaller than the value returned here.

    Examples
    --------
    Pentane at STP

    >>> solubility_parameter(T=298.2, Hvapm=26403.3, Vml=0.000116055)
    14357.681538173534

    References
    ----------
    .. [1] Barton, Allan F. M. CRC Handbook of Solubility Parameters and Other
       Cohesion Parameters, Second Edition. CRC Press, 1991.


methods = []<EOL>Tmins, Tmaxs = [], []<EOL>if self.CASRN in CRC_Permittivity_data.index:<EOL><INDENT>methods.append(CRC_CONSTANT)<EOL>_, self.CRC_CONSTANT_T, self.CRC_permittivity, A, B, C, D, Tmin, Tmax = _CRC_Permittivity_data_values[CRC_Permittivity_data.index.get_loc(self.CASRN)].tolist()<EOL>self.CRC_Tmin = Tmin<EOL>self.CRC_Tmax = Tmax<EOL>self.CRC_coeffs = [<NUM_LIT:0> if np.isnan(x) else x for x in [A, B, C, D] ]<EOL>if not np.isnan(Tmin):<EOL><INDENT>Tmins.append(Tmin); Tmaxs.append(Tmax)<EOL><DEDENT>if self.CRC_coeffs[<NUM_LIT:0>]:<EOL><INDENT>methods.append(CRC)<EOL><DEDENT><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 which picks out coefficients for the specified chemical
        from the various dictionaries and DataFrames storing it. All data is
        stored as attributes. This method also sets :obj:`Tmin`, :obj:`Tmax`,
        and :obj:`all_methods` as a set of methods for which the data exists for.

        Called on initialization only. See the source code for the variables at
        which the coefficients are stored. The coefficients can safely be
        altered once the class is initialized. This method can be called again
        to reset the parameters.


try:<EOL><INDENT>d = _VDISaturationDict[CASRN]<EOL><DEDENT>except KeyError:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>try:<EOL><INDENT>props, Ts = d[prop], d['<STR_LIT:T>']<EOL><DEDENT>except:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>Ts = [T for p, T in zip(props, Ts) if p]<EOL>props = [p for p in props if p]<EOL>if prop == '<STR_LIT>':<EOL><INDENT>Ts.append(d['<STR_LIT>'])<EOL>props.append(<NUM_LIT:0>)<EOL><DEDENT>return Ts, props<EOL>

r'''This function retrieves the tabular data available for a given chemical
    and a given property. Lookup is based on CASRNs. Length of data returned
    varies between chemicals. All data is at saturation condition from [1]_.

    Function has data for 58 chemicals.

    Parameters
    ----------
    CASRN : string
        CASRN [-]
    prop : string
        Property [-]

    Returns
    -------
    Ts : list
        Temperatures where property data is available, [K]
    props : list
        Properties at each temperature, [various]

    Notes
    -----
    The available properties are 'P', 'Density (l)', 'Density (g)', 'Hvap',
    'Cp (l)', 'Cp (g)', 'Mu (l)', 'Mu (g)', 'K (l)', 'K (g)', 'Pr (l)',
    'Pr (g)', 'sigma', 'Beta', 'Volume (l)', and 'Volume (g)'.

    Data is available for all properties and all chemicals; surface tension
    data was missing for mercury, but added as estimated from the a/b
    coefficients listed in Jasper (1972) to simplify the function.

    Examples
    --------
    >>> VDI_tabular_data('67-56-1', 'Mu (g)')
    ([337.63, 360.0, 385.0, 410.0, 435.0, 460.0, 500.0], [1.11e-05, 1.18e-05, 1.27e-05, 1.36e-05, 1.46e-05, 1.59e-05, 2.04e-05])

    References
    ----------
    .. [1] Gesellschaft, VDI, ed. VDI Heat Atlas. 2E. Berlin : Springer, 2010.


return R*Tc/Pc*Zc**(<NUM_LIT:1> + (<NUM_LIT:1> - T/Tc)**(<NUM_LIT:2>/<NUM_LIT>))<EOL>

r'''Calculates saturation liquid volume, using Rackett CSP method and
    critical properties.

    The molar volume of a liquid is given by:

    .. math::
        V_s = \frac{RT_c}{P_c}{Z_c}^{[1+(1-{T/T_c})^{2/7} ]}

    Units are all currently in m^3/mol - this can be changed to kg/m^3

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    Zc : float
        Critical compressibility of fluid, [-]

    Returns
    -------
    Vs : float
        Saturation liquid volume, [m^3/mol]

    Notes
    -----
    Units are dependent on gas constant R, imported from scipy
    According to Reid et. al, underpredicts volume for compounds with Zc < 0.22

    Examples
    --------
    Propane, example from the API Handbook

    >>> Vm_to_rho(Rackett(272.03889, 369.83, 4248000.0, 0.2763), 44.09562)
    531.3223212651092

    References
    ----------
    .. [1] Rackett, Harold G. "Equation of State for Saturated Liquids."
       Journal of Chemical & Engineering Data 15, no. 4 (1970): 514-517.
       doi:10.1021/je60047a012


if method == EOS:<EOL><INDENT>self.eos[<NUM_LIT:0>] = self.eos[<NUM_LIT:0>].to_TP(T=T, P=P)<EOL>Vm = self.eos[<NUM_LIT:0>].V_g<EOL><DEDENT>elif method == TSONOPOULOS_EXTENDED:<EOL><INDENT>B = BVirial_Tsonopoulos_extended(T, self.Tc, self.Pc, self.omega, dipole=self.dipole)<EOL>Vm = ideal_gas(T, P) + B<EOL><DEDENT>elif method == TSONOPOULOS:<EOL><INDENT>B = BVirial_Tsonopoulos(T, self.Tc, self.Pc, self.omega)<EOL>Vm = ideal_gas(T, P) + B<EOL><DEDENT>elif method == ABBOTT:<EOL><INDENT>B = BVirial_Abbott(T, self.Tc, self.Pc, self.omega)<EOL>Vm = ideal_gas(T, P) + B<EOL><DEDENT>elif method == PITZER_CURL:<EOL><INDENT>B = BVirial_Pitzer_Curl(T, self.Tc, self.Pc, self.omega)<EOL>Vm = ideal_gas(T, P) + B<EOL><DEDENT>elif method == CRC_VIRIAL:<EOL><INDENT>a1, a2, a3, a4, a5 = self.CRC_VIRIAL_coeffs<EOL>t = <NUM_LIT>/T - <NUM_LIT:1.><EOL>B = (a1 + a2*t + a3*t**<NUM_LIT:2> + a4*t**<NUM_LIT:3> + a5*t**<NUM_LIT:4>)/<NUM_LIT><EOL>Vm = ideal_gas(T, P) + B<EOL><DEDENT>elif method == IDEAL:<EOL><INDENT>Vm = ideal_gas(T, P)<EOL><DEDENT>elif method == COOLPROP:<EOL><INDENT>Vm = <NUM_LIT:1.>/PropsSI('<STR_LIT>', '<STR_LIT:T>', T, '<STR_LIT:P>', P, self.CASRN)<EOL><DEDENT>elif method in self.tabular_data:<EOL><INDENT>Vm = self.interpolate_P(T, P, method)<EOL><DEDENT>return Vm<EOL>

r'''Method to calculate pressure-dependent gas molar volume at
        temperature `T` and pressure `P` with a given method.

        This method has no exception handling; see `TP_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to calculate molar volume, [K]
        P : float
            Pressure at which to calculate molar volume, [K]
        method : str
            Name of the method to use

        Returns
        -------
        Vm : float
            Molar volume of the gas at T and P, [m^3/mol]


def Campbell_Thodos(T, Tb, Tc, Pc, M, dipole=None, hydroxyl=False):

Tr = T/Tc<EOL>Tbr = Tb/Tc<EOL>Pc = Pc/<NUM_LIT><EOL>s = Tbr * log(Pc)/(<NUM_LIT:1>-Tbr)<EOL>Lambda = Pc**(<NUM_LIT:1>/<NUM_LIT>)/(M**<NUM_LIT:0.5>*Tc**(<NUM_LIT:5>/<NUM_LIT>))<EOL>alpha = <NUM_LIT> - <NUM_LIT>*s<EOL>beta = <NUM_LIT>*s - <NUM_LIT> + <NUM_LIT>*Lambda**(<NUM_LIT>)<EOL>if dipole:<EOL><INDENT>theta = Pc*dipole**<NUM_LIT:2>/Tc**<NUM_LIT:2><EOL>alpha -= <NUM_LIT> * theta**<NUM_LIT><EOL>beta += <NUM_LIT> * theta**<NUM_LIT><EOL><DEDENT>if hydroxyl:<EOL><INDENT>beta = <NUM_LIT>*s - <NUM_LIT> + <NUM_LIT>*Lambda**(<NUM_LIT>) + <NUM_LIT>*theta**<NUM_LIT><EOL>alpha = (<NUM_LIT>*Tbr - <NUM_LIT> + <NUM_LIT>/Tbr**<NUM_LIT>)*Pc**<NUM_LIT><EOL><DEDENT>Zra = alpha + beta*(<NUM_LIT:1>-Tr)<EOL>Vs = R*Tc/(Pc*<NUM_LIT>)*Zra**(<NUM_LIT:1>+(<NUM_LIT:1>-Tr)**(<NUM_LIT:2>/<NUM_LIT>))<EOL>return Vs<EOL>

r'''Calculate saturation liquid density using the Campbell-Thodos [1]_
    CSP method.

    An old and uncommon estimation method.

    .. math::
        V_s = \frac{RT_c}{P_c}{Z_{RA}}^{[1+(1-T_r)^{2/7}]}

        Z_{RA} = \alpha + \beta(1-T_r)

        \alpha = 0.3883-0.0179s

        s = T_{br} \frac{\ln P_c}{(1-T_{br})}

        \beta = 0.00318s-0.0211+0.625\Lambda^{1.35}

        \Lambda = \frac{P_c^{1/3}} { M^{1/2} T_c^{5/6}}

    For polar compounds:

    .. math::
        \theta = P_c \mu^2/T_c^2

        \alpha = 0.3883 - 0.0179s - 130540\theta^{2.41}

        \beta = 0.00318s - 0.0211 + 0.625\Lambda^{1.35} + 9.74\times
        10^6 \theta^{3.38}

    Polar Combounds with hydroxyl groups (water, alcohols)

    .. math::
        \alpha = \left[0.690T_{br} -0.3342 + \frac{5.79\times 10^{-10}}
        {T_{br}^{32.75}}\right] P_c^{0.145}

        \beta = 0.00318s - 0.0211 + 0.625 \Lambda^{1.35} + 5.90\Theta^{0.835}

    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]
    M : float
        Molecular weight of the fluid [g/mol]
    dipole : float, optional
        Dipole moment of the fluid [debye]
    hydroxyl : bool, optional
        Swith to use the hydroxyl variant for polar fluids

    Returns
    -------
    Vs : float
        Saturation liquid volume

    Notes
    -----
    If a dipole is provided, the polar chemical method is used.
    The paper is an excellent read.
    Pc is internally converted to atm.

    Examples
    --------
    Ammonia, from [1]_.

    >>> Campbell_Thodos(T=405.45, Tb=239.82, Tc=405.45, Pc=111.7*101325, M=17.03, dipole=1.47)
    7.347363635885525e-05

    References
    ----------
    .. [1] Campbell, Scott W., and George Thodos. "Prediction of Saturated
       Liquid Densities and Critical Volumes for Polar and Nonpolar
       Substances." Journal of Chemical & Engineering Data 30, no. 1
       (January 1, 1985): 102-11. doi:10.1021/je00039a032.


if method == CRC_INORG_S:<EOL><INDENT>Vms = self.CRC_INORG_S_Vm<EOL>

r'''Method to calculate the molar volume of a solid at tempearture `T`
        with a given method.

        This method has no exception handling; see `T_dependent_property`
        for that.

        Parameters
        ----------
        T : float
            Temperature at which to calculate molar volume, [K]
        method : str
            Name of the method to use

        Returns
        -------
        Vms : float
            Molar volume of the solid at T, [m^3/mol]


methods = [SIMPLE]     <EOL>self.all_methods = set(methods)<EOL>

r'''Method to initialize the object by precomputing any values which
        may be used repeatedly and by retrieving mixture-specific variables.
        All data are stored as attributes. This method also sets :obj:`Tmin`,
        :obj:`Tmax`, and :obj:`all_methods` as a set of methods which should
        work to calculate the property.

        Called on initialization only. See the source code for the variables at
        which the coefficients are stored. The coefficients can safely be
        altered once the class is initialized. This method can be called again
        to reset the parameters.


return R*Tc/Pc*(<NUM_LIT> - <NUM_LIT>*omega)**(<NUM_LIT:1> + (<NUM_LIT:1> - T/Tc)**(<NUM_LIT:2>/<NUM_LIT>))<EOL>

r'''Calculates saturation liquid volume, using Yamada and Gunn CSP method
    and a chemical's critical properties and acentric factor.

    The molar volume of a liquid is given by:

    .. math::
        V_s = \frac{RT_c}{P_c}{(0.29056-0.08775\omega)}^{[1+(1-{T/T_c})^{2/7}]}

    Units are in m^3/mol.

    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
    -------
    Vs : float
        saturation liquid volume, [m^3/mol]

    Notes
    -----
    This equation is an improvement on the Rackett equation.
    This is often presented as the Rackett equation.
    The acentric factor is used here, instead of the critical compressibility
    A variant using a reference fluid also exists

    Examples
    --------
    >>> Yamada_Gunn(300, 647.14, 22048320.0, 0.245)
    2.1882836429895796e-05

    References
    ----------
    .. [1] Gunn, R. D., and Tomoyoshi Yamada. "A Corresponding States
        Correlation of Saturated Liquid Volumes." AIChE Journal 17, no. 6
        (1971): 1341-45. doi:10.1002/aic.690170613
    .. [2] Yamada, Tomoyoshi, and Robert D. Gunn. "Saturated Liquid Molar
        Volumes. Rackett Equation." Journal of Chemical & Engineering Data 18,
        no. 2 (1973): 234-36. doi:10.1021/je60057a006


return R*T/P<EOL>

r'''Calculates ideal gas molar volume.
    The molar volume of an ideal gas is given by:

    .. math::
        V = \frac{RT}{P}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    P : float
        Pressure of fluid [Pa]

    Returns
    -------
    V : float
        Gas volume, [m^3/mol]

    Examples
    --------
    >>> ideal_gas(298.15, 101325.)
    0.02446539540458919


Tr = T/Tc<EOL>V_delta = (-<NUM_LIT> + <NUM_LIT>*Tr - <NUM_LIT>*Tr**<NUM_LIT:2><EOL>- <NUM_LIT>*Tr**<NUM_LIT:3>)/(Tr - <NUM_LIT>)<EOL>V_0 = <NUM_LIT:1> - <NUM_LIT>*(<NUM_LIT:1>-Tr)**(<NUM_LIT:1>/<NUM_LIT>) + <NUM_LIT>*(<NUM_LIT:1>-Tr)**(<NUM_LIT:2>/<NUM_LIT>)- <NUM_LIT>*(<NUM_LIT:1>-Tr) + <NUM_LIT>*(<NUM_LIT:1>-Tr)**(<NUM_LIT:4>/<NUM_LIT>)<EOL>return Vc*V_0*(<NUM_LIT:1>-omega*V_delta)<EOL>

r'''Calculate saturation liquid density using the COSTALD CSP method.

    A popular and accurate estimation method. If possible, fit parameters are
    used; alternatively critical properties work well.

    The density of a liquid is given by:

    .. math::
        V_s=V^*V^{(0)}[1-\omega_{SRK}V^{(\delta)}]

        V^{(0)}=1-1.52816(1-T_r)^{1/3}+1.43907(1-T_r)^{2/3}
        - 0.81446(1-T_r)+0.190454(1-T_r)^{4/3}

        V^{(\delta)}=\frac{-0.296123+0.386914T_r-0.0427258T_r^2-0.0480645T_r^3}
        {T_r-1.00001}

    Units are that of critical or fit constant volume.

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Vc : float
        Critical volume of fluid [m^3/mol].
        This parameter is alternatively a fit parameter
    omega : float
        (ideally SRK) Acentric factor for fluid, [-]
        This parameter is alternatively a fit parameter.

    Returns
    -------
    Vs : float
        Saturation liquid volume

    Notes
    -----
    196 constants are fit to this function in [1]_.
    Range: 0.25 < Tr < 0.95, often said to be to 1.0

    This function has been checked with the API handbook example problem.

    Examples
    --------
    Propane, from an example in the API Handbook

    >>> Vm_to_rho(COSTALD(272.03889, 369.83333, 0.20008161E-3, 0.1532), 44.097)
    530.3009967969841

    References
    ----------
    .. [1] Hankinson, Risdon W., and George H. Thomson. "A New Correlation for
       Saturated Densities of Liquids and Their Mixtures." AIChE Journal
       25, no. 4 (1979): 653-663. doi:10.1002/aic.690250412


methods = []<EOL>methods_P = []<EOL>Tmins, Tmaxs = [], []<EOL>if has_CoolProp and self.CASRN in coolprop_dict:<EOL><INDENT>methods.append(COOLPROP); methods_P.append(COOLPROP)<EOL>self.CP_f = coolprop_fluids[self.CASRN]<EOL>Tmins.append(self.CP_f.Tt); Tmaxs.append(self.CP_f.Tc)<EOL><DEDENT>if self.CASRN in CRC_inorg_l_data.index:<EOL><INDENT>methods.append(CRC_INORG_L)<EOL>_, self.CRC_INORG_L_MW, self.CRC_INORG_L_rho, self.CRC_INORG_L_k, self.CRC_INORG_L_Tm, self.CRC_INORG_L_Tmax = _CRC_inorg_l_data_values[CRC_inorg_l_data.index.get_loc(self.CASRN)].tolist()<EOL>Tmins.append(self.CRC_INORG_L_Tm); Tmaxs.append(self.CRC_INORG_L_Tmax)<EOL><DEDENT>if self.CASRN in Perry_l_data.index:<EOL><INDENT>methods.append(PERRYDIPPR)<EOL>_, C1, C2, C3, C4, self.DIPPR_Tmin, self.DIPPR_Tmax = _Perry_l_data_values[Perry_l_data.index.get_loc(self.CASRN)].tolist()<EOL>self.DIPPR_coeffs = [C1, C2, C3, C4]<EOL>Tmins.append(self.DIPPR_Tmin); Tmaxs.append(self.DIPPR_Tmax)<EOL><DEDENT>if self.CASRN in VDI_PPDS_2.index:<EOL><INDENT>methods.append(VDI_PPDS)<EOL>_, MW, Tc, rhoc, A, B, C, D = _VDI_PPDS_2_values[VDI_PPDS_2.index.get_loc(self.CASRN)].tolist()<EOL>self.VDI_PPDS_coeffs = [A, B, C, D]<EOL>self.VDI_PPDS_MW = MW<EOL>self.VDI_PPDS_Tc = Tc<EOL>self.VDI_PPDS_rhoc = rhoc<EOL>Tmaxs.append(self.VDI_PPDS_Tc)<EOL><DEDENT>if self.CASRN in _VDISaturationDict:<EOL><INDENT>methods.append(VDI_TABULAR)<EOL>Ts, props = VDI_tabular_data(self.CASRN, '<STR_LIT>')<EOL>self.VDI_Tmin = Ts[<NUM_LIT:0>]<EOL>self.VDI_Tmax = Ts[-<NUM_LIT:1>]<EOL>self.tabular_data[VDI_TABULAR] = (Ts, props)<EOL>Tmins.append(self.VDI_Tmin); Tmaxs.append(self.VDI_Tmax)<EOL><DEDENT>if self.Tc and self.CASRN in COSTALD_data.index:<EOL><INDENT>methods.append(HTCOSTALDFIT)<EOL>self.COSTALD_Vchar = float(COSTALD_data.at[self.CASRN, '<STR_LIT>'])<EOL>self.COSTALD_omega_SRK = float(COSTALD_data.at[self.CASRN, '<STR_LIT>'])<EOL>Tmins.append(<NUM_LIT:0>); Tmaxs.append(self.Tc)<EOL><DEDENT>if self.Tc and self.Pc and self.CASRN in COSTALD_data.index and not np.isnan(COSTALD_data.at[self.CASRN, '<STR_LIT>']):<EOL><INDENT>methods.append(RACKETTFIT)<EOL>self.RACKETT_Z_RA = float(COSTALD_data.at[self.CASRN, '<STR_LIT>'])<EOL>Tmins.append(<NUM_LIT:0>); Tmaxs.append(self.Tc)<EOL><DEDENT>if self.CASRN in CRC_inorg_l_const_data.index:<EOL><INDENT>methods.append(CRC_INORG_L_CONST)<EOL>self.CRC_INORG_L_CONST_Vm = float(CRC_inorg_l_const_data.at[self.CASRN, '<STR_LIT>'])<EOL><DEDENT>if all((self.Tc, self.Vc, self.Zc)):<EOL><INDENT>methods.append(YEN_WOODS_SAT)<EOL>Tmins.append(<NUM_LIT:0>); Tmaxs.append(self.Tc)<EOL><DEDENT>if all((self.Tc, self.Pc, self.Zc)):<EOL><INDENT>methods.append(RACKETT)<EOL>Tmins.append(<NUM_LIT:0>); Tmaxs.append(self.Tc)<EOL><DEDENT>if all((self.Tc, self.Pc, self.omega)):<EOL><INDENT>methods.append(YAMADA_GUNN)<EOL>methods.append(BHIRUD_NORMAL)<EOL>Tmins.append(<NUM_LIT:0>); Tmaxs.append(self.Tc)<EOL><DEDENT>if all((self.Tc, self.Vc, self.omega)):<EOL><INDENT>methods.append(TOWNSEND_HALES)<EOL>methods.append(HTCOSTALD)<EOL>methods.append(MMSNM0)<EOL>if self.CASRN in SNM0_data.index:<EOL><INDENT>methods.append(MMSNM0FIT)<EOL>self.SNM0_delta_SRK = float(SNM0_data.at[self.CASRN, '<STR_LIT>'])<EOL><DEDENT>Tmins.append(<NUM_LIT:0>); Tmaxs.append(self.Tc)<EOL><DEDENT>if all((self.Tc, self.Vc, self.omega, self.Tb, self.MW)):<EOL><INDENT>methods.append(CAMPBELL_THODOS)<EOL>Tmins.append(<NUM_LIT:0>); Tmaxs.append(self.Tc)<EOL><DEDENT>if all((self.Tc, self.Pc, self.omega)):<EOL><INDENT>methods_P.append(COSTALD_COMPRESSED)<EOL>if self.eos:<EOL><INDENT>methods_P.append(EOS)<EOL><DEDENT><DEDENT>if Tmins and Tmaxs:<EOL><INDENT>self.Tmin, self.Tmax = min(Tmins), max(Tmaxs)<EOL><DEDENT>self.all_methods = set(methods)<EOL>self.all_methods_P = set(methods_P)<EOL>

r'''Method which picks out coefficients for the specified chemical
        from the various dictionaries and DataFrames storing it. All data is
        stored as attributes. This method also sets :obj:`Tmin`, :obj:`Tmax`,
        :obj:`all_methods` and obj:`all_methods_P` as a set of methods for
        which the data exists for.

        Called on initialization only. See the source code for the variables at
        which the coefficients are stored. The coefficients can safely be
        altered once the class is initialized. This method can be called again
        to reset the parameters.


<EOL><INDENT>return super(PR, self).solve_T(P, V, quick=quick) <EOL><DEDENT>Tc, a, b, kappa0, kappa1, kappa2, kappa3 = self.Tc, self.a, self.b, self.kappa0, self.kappa1, self.kappa2, self.kappa3<EOL>if quick:<EOL><INDENT>x0 = V - b<EOL>R_x0 = R/x0<EOL>x5 = (<NUM_LIT>*(V*(V + b) + b*x0))<EOL>x4 = <NUM_LIT>*kappa0<EOL>def to_solve(T):<EOL><INDENT>x1 = T/Tc<EOL>x2 = x1**<NUM_LIT:0.5><EOL>x3 = x2 - <NUM_LIT:1.><EOL>return (R_x0*T - a*(x3*(x4 - (kappa1 + kappa2*x3*(-kappa3 + x1))*(<NUM_LIT>*x1 - <NUM_LIT>)*(x2 + <NUM_LIT:1.>)) - <NUM_LIT>)**<NUM_LIT:2>/x5) - P<EOL><DEDENT><DEDENT>else:<EOL><INDENT>def to_solve(T):<EOL><INDENT>P_calc = R*T/(V - b) - a*((kappa0 + (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>))*(-sqrt(T/Tc) + <NUM_LIT:1>) + <NUM_LIT:1>)**<NUM_LIT:2>/(V*(V + b) + b*(V - b))<EOL>return P_calc - P<EOL><DEDENT><DEDENT>return newton(to_solve, Tc*<NUM_LIT:0.5>)<EOL>

r'''Method to calculate `T` from a specified `P` and `V` for the PRSV2
        EOS. Uses `Tc`, `a`, `b`, `kappa0`, `kappa1`, `kappa2`, and `kappa3`
        as well, obtained from the class's namespace.

        Parameters
        ----------
        P : float
            Pressure, [Pa]
        V : float
            Molar volume, [m^3/mol]
        quick : bool, optional
            Whether to use a SymPy cse-derived expression (somewhat faster) or
            individual formulas.

        Returns
        -------
        T : float
            Temperature, [K]

        Notes
        -----
        Not guaranteed to produce a solution. There are actually 8 solutions,
        six with an imaginary component at a tested point. The two temperature
        solutions are quite far apart, with one much higher than the other;
        it is possible the solver could converge on the higher solution, so use
        `T` inputs with care. This extra solution is a perfectly valid one
        however.


a, b, Tc, m = self.a, self.b, self.Tc, self.m<EOL>if quick:<EOL><INDENT>x0 = R*Tc<EOL>x1 = V*b<EOL>x2 = x0*x1<EOL>x3 = V*V<EOL>x4 = x0*x3<EOL>x5 = m*m<EOL>x6 = a*x5<EOL>x7 = b*x6<EOL>x8 = V*x6<EOL>x9 = (x2 + x4 + x7 - x8)**<NUM_LIT:2><EOL>x10 = x3*x3<EOL>x11 = R*R*Tc*Tc<EOL>x12 = a*a<EOL>x13 = x5*x5<EOL>x14 = x12*x13<EOL>x15 = b*b<EOL>x16 = x3*V<EOL>x17 = a*x0<EOL>x18 = x17*x5<EOL>x19 = <NUM_LIT>*b*x16<EOL>x20 = -<NUM_LIT>*V*b*x14 + <NUM_LIT>*V*x15*x18 + x10*x11 + x11*x15*x3 + x11*x19 + x14*x15 + x14*x3 - <NUM_LIT:2>*x16*x18<EOL>x21 = V - b<EOL>x22 = <NUM_LIT:2>*m*x17<EOL>x23 = P*x4<EOL>x24 = P*x8<EOL>x25 = x1*x17<EOL>x26 = P*R*Tc<EOL>x27 = x17*x3<EOL>x28 = V*x12<EOL>x29 = <NUM_LIT>*m*m*m<EOL>x30 = b*x12<EOL>return -Tc*(<NUM_LIT>*a*m*x9*(V*x21*x21*x21*(V + b)*(P*x2 + P*x7 + x17 + x18 + x22 + x23 - x24))**<NUM_LIT:0.5>*(m + <NUM_LIT:1.>) - x20*x21*(-P*x16*x6 + x1*x22 + x10*x26 + x13*x28 - x13*x30 + x15*x23 + x15*x24 + x19*x26 + x22*x3 + x25*x5 + x25 + x27*x5 + x27 + x28*x29 + x28*x5 - x29*x30 - x30*x5))/(x20*x9)<EOL><DEDENT>else:<EOL><INDENT>return Tc*(-<NUM_LIT:2>*a*m*sqrt(V*(V - b)**<NUM_LIT:3>*(V + b)*(P*R*Tc*V**<NUM_LIT:2> + P*R*Tc*V*b - P*V*a*m**<NUM_LIT:2> + P*a*b*m**<NUM_LIT:2> + R*Tc*a*m**<NUM_LIT:2> + <NUM_LIT:2>*R*Tc*a*m + R*Tc*a))*(m + <NUM_LIT:1>)*(R*Tc*V**<NUM_LIT:2> + R*Tc*V*b - V*a*m**<NUM_LIT:2> + a*b*m**<NUM_LIT:2>)**<NUM_LIT:2> + (V - b)*(R**<NUM_LIT:2>*Tc**<NUM_LIT:2>*V**<NUM_LIT:4> + <NUM_LIT:2>*R**<NUM_LIT:2>*Tc**<NUM_LIT:2>*V**<NUM_LIT:3>*b + R**<NUM_LIT:2>*Tc**<NUM_LIT:2>*V**<NUM_LIT:2>*b**<NUM_LIT:2> - <NUM_LIT:2>*R*Tc*V**<NUM_LIT:3>*a*m**<NUM_LIT:2> + <NUM_LIT:2>*R*Tc*V*a*b**<NUM_LIT:2>*m**<NUM_LIT:2> + V**<NUM_LIT:2>*a**<NUM_LIT:2>*m**<NUM_LIT:4> - <NUM_LIT:2>*V*a**<NUM_LIT:2>*b*m**<NUM_LIT:4> + a**<NUM_LIT:2>*b**<NUM_LIT:2>*m**<NUM_LIT:4>)*(P*R*Tc*V**<NUM_LIT:4> + <NUM_LIT:2>*P*R*Tc*V**<NUM_LIT:3>*b + P*R*Tc*V**<NUM_LIT:2>*b**<NUM_LIT:2> - P*V**<NUM_LIT:3>*a*m**<NUM_LIT:2> + P*V*a*b**<NUM_LIT:2>*m**<NUM_LIT:2> + R*Tc*V**<NUM_LIT:2>*a*m**<NUM_LIT:2> + <NUM_LIT:2>*R*Tc*V**<NUM_LIT:2>*a*m + R*Tc*V**<NUM_LIT:2>*a + R*Tc*V*a*b*m**<NUM_LIT:2> + <NUM_LIT:2>*R*Tc*V*a*b*m + R*Tc*V*a*b + V*a**<NUM_LIT:2>*m**<NUM_LIT:4> + <NUM_LIT:2>*V*a**<NUM_LIT:2>*m**<NUM_LIT:3> + V*a**<NUM_LIT:2>*m**<NUM_LIT:2> - a**<NUM_LIT:2>*b*m**<NUM_LIT:4> - <NUM_LIT:2>*a**<NUM_LIT:2>*b*m**<NUM_LIT:3> - a**<NUM_LIT:2>*b*m**<NUM_LIT:2>))/((R*Tc*V**<NUM_LIT:2> + R*Tc*V*b - V*a*m**<NUM_LIT:2> + a*b*m**<NUM_LIT:2>)**<NUM_LIT:2>*(R**<NUM_LIT:2>*Tc**<NUM_LIT:2>*V**<NUM_LIT:4> + <NUM_LIT:2>*R**<NUM_LIT:2>*Tc**<NUM_LIT:2>*V**<NUM_LIT:3>*b + R**<NUM_LIT:2>*Tc**<NUM_LIT:2>*V**<NUM_LIT:2>*b**<NUM_LIT:2> - <NUM_LIT:2>*R*Tc*V**<NUM_LIT:3>*a*m**<NUM_LIT:2> + <NUM_LIT:2>*R*Tc*V*a*b**<NUM_LIT:2>*m**<NUM_LIT:2> + V**<NUM_LIT:2>*a**<NUM_LIT:2>*m**<NUM_LIT:4> - <NUM_LIT:2>*V*a**<NUM_LIT:2>*b*m**<NUM_LIT:4> + a**<NUM_LIT:2>*b**<NUM_LIT:2>*m**<NUM_LIT:4>))<EOL><DEDENT>

r'''Method to calculate `T` from a specified `P` and `V` for the SRK
        EOS. Uses `a`, `b`, and `Tc` obtained from the class's namespace.

        Parameters
        ----------
        P : float
            Pressure, [Pa]
        V : float
            Molar volume, [m^3/mol]
        quick : bool, optional
            Whether to use a SymPy cse-derived expression (3x faster) or
            individual formulas

        Returns
        -------
        T : float
            Temperature, [K]

        Notes
        -----
        The exact solution can be derived as follows; it is excluded for
        breviety.

        >>> from sympy import *
        >>> P, T, V, R, a, b, m = symbols('P, T, V, R, a, b, m')
        >>> Tc, Pc, omega = symbols('Tc, Pc, omega')
        >>> a_alpha = a*(1 + m*(1-sqrt(T/Tc)))**2
        >>> SRK = R*T/(V-b) - a_alpha/(V*(V+b)) - P
        >>> # solve(SRK, T)


alpha = self.a_alpha_and_derivatives(T, full=False)/self.a<EOL>Tr = T/self.Tc<EOL>x = alpha/Tr - <NUM_LIT:1.><EOL>c = self.Psat_coeffs_limiting if Tr < <NUM_LIT> else self.Psat_coeffs<EOL>y = horner(c, x)<EOL>try:<EOL><INDENT>Psat = exp(y)*Tr*self.Pc<EOL><DEDENT>except OverflowError:<EOL><INDENT>polish = False<EOL>Psat = <NUM_LIT:0><EOL><DEDENT>if polish:<EOL><INDENT>def to_solve(P):<EOL><INDENT>e = self.__class__(Tc=self.Tc, Pc=self.Pc, omega=self.omega, T=T, P=P)<EOL>err = e.fugacity_l - e.fugacity_g<EOL>return err<EOL><DEDENT>Psat = newton(to_solve, Psat)<EOL><DEDENT>return Psat<EOL>

r'''Generic method to calculate vapor pressure for a specified `T`.

        From Tc to 0.32Tc, uses a 10th order polynomial of the following form:

        .. math::
            \ln\frac{P_r}{T_r} = \sum_{k=0}^{10} C_k\left(\frac{\alpha}{T_r}
            -1\right)^{k}

        If `polish` is True, SciPy's `newton` solver is launched with the
        calculated vapor pressure as an initial guess in an attempt to get more
        accuracy. This may not converge however.

        Results above the critical temperature are meaningless. A first-order
        polynomial is used to extrapolate under 0.32 Tc; however, there is
        normally not a volume solution to the EOS which can produce that
        low of a pressure.

        Parameters
        ----------
        T : float
            Temperature, [K]
        polish : bool, optional
            Whether to attempt to use a numerical solver to make the solution
            more precise or not

        Returns
        -------
        Psat : float
            Vapor pressure, [Pa]

        Notes
        -----
        EOSs sharing the same `b`, `delta`, and `epsilon` have the same
        coefficient sets.

        All coefficients were derived with numpy's polyfit. The intersection
        between the polynomials is continuous, but there is a step change
        in its derivative.

        Form for the regression is inspired from [1]_.

        References
        ----------
        .. [1] Soave, G. "Direct Calculation of Pure-Compound Vapour Pressures
           through Cubic Equations of State." Fluid Phase Equilibria 31, no. 2
           (January 1, 1986): 203-7. doi:10.1016/0378-3812(86)90013-0.


@staticmethod<EOL><INDENT>def Soave_1984(self, T, full=True, quick=True):<DEDENT>

c1, c2 = self.alpha_function_coeffs<EOL>T, Tc, a = self.T, self.Tc, self.a<EOL>a_alpha = a*(c1*(-T/Tc + <NUM_LIT:1>) + c2*(-<NUM_LIT:1> + Tc/T) + <NUM_LIT:1>)<EOL>if not full:<EOL><INDENT>return a_alpha<EOL><DEDENT>else:<EOL><INDENT>da_alpha_dT = a*(-c1/Tc - Tc*c2/T**<NUM_LIT:2>)<EOL>d2a_alpha_dT2 = a*(<NUM_LIT:2>*Tc*c2/T**<NUM_LIT:3>)<EOL>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives according to Soave (1984) [1]_. Returns `a_alpha`, `da_alpha_dT`, and
        `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives` for more
        documentation. Two coefficients needed.

        .. math::
            \alpha = c_{1} \left(- \frac{T}{Tc} + 1\right) + c_{2} \left(-1
            + \frac{Tc}{T}\right) + 1

        References
        ----------
        .. [1] Soave, G. "Improvement of the Van Der Waals Equation of State."
           Chemical Engineering Science 39, no. 2 (January 1, 1984): 357-69.
           doi:10.1016/0009-2509(84)80034-2.


def TWU_a_alpha_common(T, Tc, omega, a, full=True, quick=True, method='<STR_LIT>'):

Tr = T/Tc<EOL>if method == '<STR_LIT>':<EOL><INDENT>if Tr < <NUM_LIT:1>:<EOL><INDENT>L0, M0, N0 = <NUM_LIT>, <NUM_LIT>, <NUM_LIT><EOL>L1, M1, N1 = <NUM_LIT>, <NUM_LIT>, <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>L0, M0, N0 = <NUM_LIT>, <NUM_LIT>, -<NUM_LIT><EOL>L1, M1, N1 = <NUM_LIT>, <NUM_LIT>, -<NUM_LIT>  <EOL><DEDENT><DEDENT>elif method == '<STR_LIT>':<EOL><INDENT>if Tr < <NUM_LIT:1>:<EOL><INDENT>L0, M0, N0 = <NUM_LIT>, <NUM_LIT>, <NUM_LIT><EOL>L1, M1, N1 = <NUM_LIT>, <NUM_LIT>, <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>L0, M0, N0 = <NUM_LIT>, <NUM_LIT>, -<NUM_LIT><EOL>L1, M1, N1 = <NUM_LIT>,  <NUM_LIT>, -<NUM_LIT><EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>if not full:<EOL><INDENT>alpha0 = Tr**(N0*(M0-<NUM_LIT:1.>))*exp(L0*(<NUM_LIT:1.>-Tr**(N0*M0)))<EOL>alpha1 = Tr**(N1*(M1-<NUM_LIT:1.>))*exp(L1*(<NUM_LIT:1.>-Tr**(N1*M1)))<EOL>alpha = alpha0 + omega*(alpha1 - alpha0)<EOL>return a*alpha<EOL><DEDENT>else:<EOL><INDENT>if quick:<EOL><INDENT>x0 = T/Tc<EOL>x1 = M0 - <NUM_LIT:1><EOL>x2 = N0*x1<EOL>x3 = x0**x2<EOL>x4 = M0*N0<EOL>x5 = x0**x4<EOL>x6 = exp(-L0*(x5 - <NUM_LIT:1.>))<EOL>x7 = x3*x6<EOL>x8 = M1 - <NUM_LIT:1.><EOL>x9 = N1*x8<EOL>x10 = x0**x9<EOL>x11 = M1*N1<EOL>x12 = x0**x11<EOL>x13 = x2*x7<EOL>x14 = L0*M0*N0*x3*x5*x6<EOL>x15 = x13 - x14<EOL>x16 = exp(-L1*(x12 - <NUM_LIT:1>))<EOL>x17 = -L1*M1*N1*x10*x12*x16 + x10*x16*x9 - x13 + x14<EOL>x18 = N0*N0<EOL>x19 = x18*x3*x6<EOL>x20 = x1**<NUM_LIT:2>*x19<EOL>x21 = M0**<NUM_LIT:2><EOL>x22 = L0*x18*x3*x5*x6<EOL>x23 = x21*x22<EOL>x24 = <NUM_LIT:2>*M0*x1*x22<EOL>x25 = L0**<NUM_LIT:2>*x0**(<NUM_LIT:2>*x4)*x19*x21<EOL>x26 = N1**<NUM_LIT:2><EOL>x27 = x10*x16*x26<EOL>x28 = M1**<NUM_LIT:2><EOL>x29 = L1*x10*x12*x16*x26<EOL>a_alpha = a*(-omega*(-x10*exp(L1*(-x12 + <NUM_LIT:1>)) + x3*exp(L0*(-x5 + <NUM_LIT:1>))) + x7)<EOL>da_alpha_dT = a*(omega*x17 + x15)/T<EOL>d2a_alpha_dT2 = a*(-(omega*(-L1**<NUM_LIT:2>*x0**(<NUM_LIT>*x11)*x27*x28 + <NUM_LIT>*M1*x29*x8 + x17 + x20 - x23 - x24 + x25 - x27*x8**<NUM_LIT:2> + x28*x29) + x15 - x20 + x23 + x24 - x25)/T**<NUM_LIT:2>)<EOL><DEDENT>else:<EOL><INDENT>a_alpha = TWU_a_alpha_common(T=T, Tc=Tc, omega=omega, a=a, full=False, quick=quick, method=method)<EOL>da_alpha_dT = a*(-L0*M0*N0*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(L0*(-(T/Tc)**(M0*N0) + <NUM_LIT:1>))/T + N0*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)*exp(L0*(-(T/Tc)**(M0*N0) + <NUM_LIT:1>))/T + omega*(L0*M0*N0*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(L0*(-(T/Tc)**(M0*N0) + <NUM_LIT:1>))/T - L1*M1*N1*(T/Tc)**(M1*N1)*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*exp(L1*(-(T/Tc)**(M1*N1) + <NUM_LIT:1>))/T - N0*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)*exp(L0*(-(T/Tc)**(M0*N0) + <NUM_LIT:1>))/T + N1*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*(M1 - <NUM_LIT:1>)*exp(L1*(-(T/Tc)**(M1*N1) + <NUM_LIT:1>))/T))<EOL>d2a_alpha_dT2 = a*((L0**<NUM_LIT:2>*M0**<NUM_LIT:2>*N0**<NUM_LIT:2>*(T/Tc)**(<NUM_LIT:2>*M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - L0*M0**<NUM_LIT:2>*N0**<NUM_LIT:2>*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - <NUM_LIT:2>*L0*M0*N0**<NUM_LIT:2>*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) + L0*M0*N0*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) + N0**<NUM_LIT:2>*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)**<NUM_LIT:2>*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - N0*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - omega*(L0**<NUM_LIT:2>*M0**<NUM_LIT:2>*N0**<NUM_LIT:2>*(T/Tc)**(<NUM_LIT:2>*M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - L0*M0**<NUM_LIT:2>*N0**<NUM_LIT:2>*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - <NUM_LIT:2>*L0*M0*N0**<NUM_LIT:2>*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) + L0*M0*N0*(T/Tc)**(M0*N0)*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - L1**<NUM_LIT:2>*M1**<NUM_LIT:2>*N1**<NUM_LIT:2>*(T/Tc)**(<NUM_LIT:2>*M1*N1)*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*exp(-L1*((T/Tc)**(M1*N1) - <NUM_LIT:1>)) + L1*M1**<NUM_LIT:2>*N1**<NUM_LIT:2>*(T/Tc)**(M1*N1)*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*exp(-L1*((T/Tc)**(M1*N1) - <NUM_LIT:1>)) + <NUM_LIT:2>*L1*M1*N1**<NUM_LIT:2>*(T/Tc)**(M1*N1)*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*(M1 - <NUM_LIT:1>)*exp(-L1*((T/Tc)**(M1*N1) - <NUM_LIT:1>)) - L1*M1*N1*(T/Tc)**(M1*N1)*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*exp(-L1*((T/Tc)**(M1*N1) - <NUM_LIT:1>)) + N0**<NUM_LIT:2>*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)**<NUM_LIT:2>*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - N0*(T/Tc)**(N0*(M0 - <NUM_LIT:1>))*(M0 - <NUM_LIT:1>)*exp(-L0*((T/Tc)**(M0*N0) - <NUM_LIT:1>)) - N1**<NUM_LIT:2>*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*(M1 - <NUM_LIT:1>)**<NUM_LIT:2>*exp(-L1*((T/Tc)**(M1*N1) - <NUM_LIT:1>)) + N1*(T/Tc)**(N1*(M1 - <NUM_LIT:1>))*(M1 - <NUM_LIT:1>)*exp(-L1*((T/Tc)**(M1*N1) - <NUM_LIT:1>))))/T**<NUM_LIT:2>)<EOL><DEDENT>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Function to calculate `a_alpha` and optionally its first and second
    derivatives for the TWUPR or TWUSRK EOS. Returns 'a_alpha', and
    optionally 'da_alpha_dT' and 'd2a_alpha_dT2'.
    Used by `TWUPR` and `TWUSRK`; has little purpose on its own.
    See either class for the correct reference, and examples of using the EOS.

    Parameters
    ----------
    T : float
        Temperature, [K]
    Tc : float
        Critical temperature, [K]
    omega : float
        Acentric factor, [-]
    a : float
        Coefficient calculated by EOS-specific method, [J^2/mol^2/Pa]
    full : float
        Whether or not to return its first and second derivatives
    quick : bool, optional
        Whether to use a SymPy cse-derived expression (3x faster) or
        individual formulas
    method : str
        Either 'PR' or 'SRK'

    Notes
    -----
    The derivatives are somewhat long and are not described here for
    brevity; they are obtainable from the following SymPy expression.

    >>> from sympy import *
    >>> T, Tc, omega, N1, N0, M1, M0, L1, L0 = symbols('T, Tc, omega, N1, N0, M1, M0, L1, L0')
    >>> Tr = T/Tc
    >>> alpha0 = Tr**(N0*(M0-1))*exp(L0*(1-Tr**(N0*M0)))
    >>> alpha1 = Tr**(N1*(M1-1))*exp(L1*(1-Tr**(N1*M1)))
    >>> alpha = alpha0 + omega*(alpha1-alpha0)
    >>> # diff(alpha, T)
    >>> # diff(alpha, T, T)


@staticmethod<EOL><INDENT>def Androulakis(self, T, full=True, quick=True):<DEDENT>

c1, c2, c3 = self.alpha_function_coeffs<EOL>T, Tc, a = self.T, self.Tc, self.a<EOL>a_alpha = a*(c1*(-(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) + <NUM_LIT:1>) + c2*(-(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) + <NUM_LIT:1>)**<NUM_LIT:2> + c3*(-(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) + <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)<EOL>if not full:<EOL><INDENT>return a_alpha<EOL><DEDENT>else:<EOL><INDENT>da_alpha_dT = a*(-<NUM_LIT:2>*c1*(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>)/(<NUM_LIT:3>*T) - <NUM_LIT:4>*c2*(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>)*(-(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) + <NUM_LIT:1>)/(<NUM_LIT:3>*T) - <NUM_LIT:2>*c3*(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>)*(-(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) + <NUM_LIT:1>)**<NUM_LIT:2>/T)<EOL>d2a_alpha_dT2 = a*(<NUM_LIT:2>*(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>)*(c1 + <NUM_LIT:4>*c2*(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) - <NUM_LIT:2>*c2*((T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) - <NUM_LIT:1>) - <NUM_LIT:12>*c3*(T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>)*((T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) - <NUM_LIT:1>) + <NUM_LIT:3>*c3*((T/Tc)**(<NUM_LIT:2>/<NUM_LIT:3>) - <NUM_LIT:1>)**<NUM_LIT:2>)/(<NUM_LIT:9>*T**<NUM_LIT:2>))<EOL>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives according to Androulakis et al. (1989) [1]_. Returns `a_alpha`,
        `da_alpha_dT`, and `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives`
        for more documentation. Three coefficients needed.

        .. math::
            \alpha = c_{1} \left(- \left(\frac{T}{Tc}\right)^{\frac{2}{3}}
            + 1\right) + c_{2} \left(- \left(\frac{T}{Tc}\right)^{\frac{2}{3}}
            + 1\right)^{2} + c_{3} \left(- \left(\frac{T}{Tc}\right)^{
            \frac{2}{3}} + 1\right)^{3} + 1

        References
        ----------
        .. [1] Androulakis, I. P., N. S. Kalospiros, and D. P. Tassios.
           "Thermophysical Properties of Pure Polar and Nonpolar Compounds with
           a Modified VdW-711 Equation of State." Fluid Phase Equilibria 45,
           no. 2 (April 1, 1989): 135-63. doi:10.1016/0378-3812(89)80254-7.


@staticmethod<EOL><INDENT>def Melhem(self, T, full=True, quick=True):<DEDENT>

c1, c2 = self.alpha_function_coeffs<EOL>T, Tc, a = self.T, self.Tc, self.a<EOL>a_alpha = a*exp(c1*(-T/Tc + <NUM_LIT:1>) + c2*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:2>)<EOL>if not full:<EOL><INDENT>return a_alpha<EOL><DEDENT>else:<EOL><INDENT>da_alpha_dT = a*((-c1/Tc - c2*sqrt(T/Tc)*(-sqrt(T/Tc) + <NUM_LIT:1>)/T)*exp(c1*(-T/Tc + <NUM_LIT:1>) + c2*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:2>))<EOL>d2a_alpha_dT2 = a*(((c1/Tc - c2*sqrt(T/Tc)*(sqrt(T/Tc) - <NUM_LIT:1>)/T)**<NUM_LIT:2> + c2*(<NUM_LIT:1>/Tc - sqrt(T/Tc)*(sqrt(T/Tc) - <NUM_LIT:1>)/T)/(<NUM_LIT:2>*T))*exp(-c1*(T/Tc - <NUM_LIT:1>) + c2*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2>))<EOL>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives according to Melhem et al. (1989) [1]_. Returns `a_alpha`,
        `da_alpha_dT`, and `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives`
        for more documentation. Two coefficients needed.

        .. math::
            \alpha = e^{c_{1} \left(- \frac{T}{Tc} + 1\right) + c_{2}
            \left(- \sqrt{\frac{T}{Tc}} + 1\right)^{2}}

        References
        ----------
        .. [1] Melhem, Georges A., Riju Saini, and Bernard M. Goodwin. "A
           Modified Peng-Robinson Equation of State." Fluid Phase Equilibria
           47, no. 2 (August 1, 1989): 189-237.
           doi:10.1016/0378-3812(89)80176-1.


def a_alpha_and_derivatives(self, T, full=True, quick=True):

Tc, a, kappa0, kappa1, kappa2, kappa3 = self.Tc, self.a, self.kappa0, self.kappa1, self.kappa2, self.kappa3<EOL>if not full:<EOL><INDENT>Tr = T/Tc<EOL>kappa = kappa0 + ((kappa1 + kappa2*(kappa3 - Tr)*(<NUM_LIT:1> - Tr**<NUM_LIT:0.5>))*(<NUM_LIT:1> + Tr**<NUM_LIT:0.5>)*(<NUM_LIT> - Tr))<EOL>return a*(<NUM_LIT:1> + kappa*(<NUM_LIT:1>-sqrt(T/Tc)))**<NUM_LIT:2><EOL><DEDENT>else:<EOL><INDENT>if quick:<EOL><INDENT>x1 = T/Tc<EOL>x2 = sqrt(x1)<EOL>x3 = x2 - <NUM_LIT:1.><EOL>x4 = x2 + <NUM_LIT:1.><EOL>x5 = <NUM_LIT>*x1 - <NUM_LIT><EOL>x6 = -kappa3 + x1<EOL>x7 = kappa1 + kappa2*x3*x6<EOL>x8 = x5*x7<EOL>x9 = <NUM_LIT>*kappa0 - x4*x8<EOL>x10 = x3*x9<EOL>x11 = x10*<NUM_LIT:0.1> - <NUM_LIT:1.><EOL>x13 = x2/T<EOL>x14 = x7/Tc<EOL>x15 = kappa2*x4*x5<EOL>x16 = <NUM_LIT>*(-x2 + <NUM_LIT:1.>)/Tc + x13*(kappa3 - x1)<EOL>x17 = -x13*x8 - x14*(<NUM_LIT>*x2 + <NUM_LIT>) + x15*x16<EOL>x18 = x13*x9 + x17*x3<EOL>x19 = x2/(T*T)<EOL>x20 = <NUM_LIT>*x2/T<EOL>a_alpha = a*x11*x11<EOL>da_alpha_dT = a*x11*x18*<NUM_LIT:0.1><EOL>d2a_alpha_dT2 = a*(x18*x18 + (x10 - <NUM_LIT>)*(x17*x20 - x19*x9 + x3*(<NUM_LIT>*kappa2/Tc*x16*x4 + kappa2*x16*x20*x5 - <NUM_LIT>/T*x14*x2 - x15/T*x2*(<NUM_LIT>/Tc - x6/T) + x19*x8)))/<NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>a_alpha = a*(<NUM_LIT:1> + self.kappa*(<NUM_LIT:1>-sqrt(T/Tc)))**<NUM_LIT:2><EOL>da_alpha_dT = a*((kappa0 + (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>))*(-sqrt(T/Tc) + <NUM_LIT:1>) + <NUM_LIT:1>)*(<NUM_LIT:2>*(-sqrt(T/Tc) + <NUM_LIT:1>)*((sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)*(-kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)/Tc - kappa2*sqrt(T/Tc)*(-T/Tc + kappa3)/(<NUM_LIT:2>*T)) - (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)/Tc + sqrt(T/Tc)*(kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)/(<NUM_LIT:2>*T)) - sqrt(T/Tc)*(kappa0 + (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>))/T)<EOL>d2a_alpha_dT2 = a*((kappa0 + (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>))*(-sqrt(T/Tc) + <NUM_LIT:1>) + <NUM_LIT:1>)*(<NUM_LIT:2>*(-sqrt(T/Tc) + <NUM_LIT:1>)*((sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)*(kappa2*sqrt(T/Tc)/(T*Tc) + kappa2*sqrt(T/Tc)*(-T/Tc + kappa3)/(<NUM_LIT:4>*T**<NUM_LIT:2>)) - <NUM_LIT:2>*(sqrt(T/Tc) + <NUM_LIT:1>)*(-kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)/Tc - kappa2*sqrt(T/Tc)*(-T/Tc + kappa3)/(<NUM_LIT:2>*T))/Tc + sqrt(T/Tc)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)*(-kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)/Tc - kappa2*sqrt(T/Tc)*(-T/Tc + kappa3)/(<NUM_LIT:2>*T))/T - sqrt(T/Tc)*(kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))/(T*Tc) - sqrt(T/Tc)*(kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)/(<NUM_LIT:4>*T**<NUM_LIT:2>)) - <NUM_LIT:2>*sqrt(T/Tc)*((sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)*(-kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)/Tc - kappa2*sqrt(T/Tc)*(-T/Tc + kappa3)/(<NUM_LIT:2>*T)) - (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)/Tc + sqrt(T/Tc)*(kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)/(<NUM_LIT:2>*T))/T + sqrt(T/Tc)*(kappa0 + (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>))/(<NUM_LIT:2>*T**<NUM_LIT:2>)) + a*((-sqrt(T/Tc) + <NUM_LIT:1>)*((sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)*(-kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)/Tc - kappa2*sqrt(T/Tc)*(-T/Tc + kappa3)/(<NUM_LIT:2>*T)) - (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)/Tc + sqrt(T/Tc)*(kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)/(<NUM_LIT:2>*T)) - sqrt(T/Tc)*(kappa0 + (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>))/(<NUM_LIT:2>*T))*(<NUM_LIT:2>*(-sqrt(T/Tc) + <NUM_LIT:1>)*((sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)*(-kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)/Tc - kappa2*sqrt(T/Tc)*(-T/Tc + kappa3)/(<NUM_LIT:2>*T)) - (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)/Tc + sqrt(T/Tc)*(kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>)/(<NUM_LIT:2>*T)) - sqrt(T/Tc)*(kappa0 + (kappa1 + kappa2*(-sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + kappa3))*(sqrt(T/Tc) + <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:7>/<NUM_LIT:10>))/T)<EOL><DEDENT>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives for this EOS. Returns `a_alpha`, `da_alpha_dT`, and
        `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives` for more
        documentation. Uses the set values of `Tc`, `kappa0`, `kappa1`,
        `kappa2`, `kappa3`, and `a`.

        For use in `solve_T`, returns only `a_alpha` if full is False.

        The first and second derivatives of `a_alpha` are available through the
        following SymPy expression.

        >>> from sympy import *
        >>> P, T, V = symbols('P, T, V')
        >>> Tc, Pc, omega = symbols('Tc, Pc, omega')
        >>> R, a, b, kappa0, kappa1, kappa2, kappa3 = symbols('R, a, b, kappa0, kappa1, kappa2, kappa3')
        >>> Tr = T/Tc
        >>> kappa = kappa0 + (kappa1 + kappa2*(kappa3-Tr)*(1-sqrt(Tr)))*(1+sqrt(Tr))*(Rational('0.7')-Tr)
        >>> a_alpha = a*(1 + kappa*(1-sqrt(T/Tc)))**2
        >>> # diff(a_alpha, T)
        >>> # diff(a_alpha, T, 2)


if not ((self.T and self.P) or (self.T and self.V) or (self.P and self.V)):<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>

Method to an exception if none of the pairs (T, P), (T, V), or
        (P, V) are given.


@staticmethod<EOL><INDENT>def Coquelet(self, T, full=True, quick=True):<DEDENT>

c1, c2, c3 = self.alpha_function_coeffs<EOL>T, Tc, a = self.T, self.Tc, self.a<EOL>a_alpha = a*(exp(c1*(-T/Tc + <NUM_LIT:1>)*(c2*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:2> + c3*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)**<NUM_LIT:2>))<EOL>if not full:<EOL><INDENT>return a_alpha<EOL><DEDENT>else:<EOL><INDENT>da_alpha_dT = a*((c1*(-T/Tc + <NUM_LIT:1>)*(-<NUM_LIT:2>*c2*sqrt(T/Tc)*(-sqrt(T/Tc) + <NUM_LIT:1>)/T - <NUM_LIT:3>*c3*sqrt(T/Tc)*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:2>/T)*(c2*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:2> + c3*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>) - c1*(c2*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:2> + c3*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)**<NUM_LIT:2>/Tc)*exp(c1*(-T/Tc + <NUM_LIT:1>)*(c2*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:2> + c3*(-sqrt(T/Tc) + <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)**<NUM_LIT:2>))<EOL>d2a_alpha_dT2 = a*(c1*(c1*(-(c2*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2> - c3*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)/Tc + sqrt(T/Tc)*(-<NUM_LIT:2>*c2 + <NUM_LIT:3>*c3*(sqrt(T/Tc) - <NUM_LIT:1>))*(sqrt(T/Tc) - <NUM_LIT:1>)*(T/Tc - <NUM_LIT:1>)/T)**<NUM_LIT:2>*(c2*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2> - c3*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)**<NUM_LIT:2> - ((T/Tc - <NUM_LIT:1>)*(c2*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2> - c3*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)*(<NUM_LIT:2>*c2/Tc - <NUM_LIT:6>*c3*(sqrt(T/Tc) - <NUM_LIT:1>)/Tc - <NUM_LIT:2>*c2*sqrt(T/Tc)*(sqrt(T/Tc) - <NUM_LIT:1>)/T + <NUM_LIT:3>*c3*sqrt(T/Tc)*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2>/T) + <NUM_LIT:4>*sqrt(T/Tc)*(<NUM_LIT:2>*c2 - <NUM_LIT:3>*c3*(sqrt(T/Tc) - <NUM_LIT:1>))*(sqrt(T/Tc) - <NUM_LIT:1>)*(c2*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2> - c3*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)/Tc + (<NUM_LIT:2>*c2 - <NUM_LIT:3>*c3*(sqrt(T/Tc) - <NUM_LIT:1>))**<NUM_LIT:2>*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2>*(T/Tc - <NUM_LIT:1>)/Tc)/(<NUM_LIT:2>*T))*exp(-c1*(T/Tc - <NUM_LIT:1>)*(c2*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:2> - c3*(sqrt(T/Tc) - <NUM_LIT:1>)**<NUM_LIT:3> + <NUM_LIT:1>)**<NUM_LIT:2>))<EOL>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives according to Coquelet et al. (2004) [1]_. Returns `a_alpha`, `da_alpha_dT`, and
        `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives` for more
        documentation. Three coefficients needed.

        .. math::
            \alpha = e^{c_{1} \left(- \frac{T}{Tc} + 1\right) \left(c_{2}
            \left(- \sqrt{\frac{T}{Tc}} + 1\right)^{2} + c_{3}
            \left(- \sqrt{\frac{T}{Tc}} + 1\right)^{3} + 1\right)^{2}}

        References
        ----------
        .. [1] Coquelet, C., A. Chapoy, and D. Richon. "Development of a New
           Alpha Function for the Peng–Robinson Equation of State: Comparative
           Study of Alpha Function Models for Pure Gases (Natural Gas
           Components) and Water-Gas Systems." International Journal of
           Thermophysics 25, no. 1 (January 1, 2004): 133-58.
           doi:10.1023/B:IJOT.0000022331.46865.2f.


@staticmethod<EOL><INDENT>def Twu(self, T, full=True, quick=True):<DEDENT>

c1, c2, c3 = self.alpha_function_coeffs<EOL>T, Tc, a = self.T, self.Tc, self.a<EOL>a_alpha = a*((T/Tc)**(c3*(c2 - <NUM_LIT:1>))*exp(c1*(-(T/Tc)**(c2*c3) + <NUM_LIT:1>)))<EOL>if not full:<EOL><INDENT>return a_alpha<EOL><DEDENT>else:<EOL><INDENT>da_alpha_dT = a*(-c1*c2*c3*(T/Tc)**(c2*c3)*(T/Tc)**(c3*(c2 - <NUM_LIT:1>))*exp(c1*(-(T/Tc)**(c2*c3) + <NUM_LIT:1>))/T + c3*(T/Tc)**(c3*(c2 - <NUM_LIT:1>))*(c2 - <NUM_LIT:1>)*exp(c1*(-(T/Tc)**(c2*c3) + <NUM_LIT:1>))/T)<EOL>d2a_alpha_dT2 = a*(c3*(T/Tc)**(c3*(c2 - <NUM_LIT:1>))*(c1**<NUM_LIT:2>*c2**<NUM_LIT:2>*c3*(T/Tc)**(<NUM_LIT:2>*c2*c3) - c1*c2**<NUM_LIT:2>*c3*(T/Tc)**(c2*c3) - <NUM_LIT:2>*c1*c2*c3*(T/Tc)**(c2*c3)*(c2 - <NUM_LIT:1>) + c1*c2*(T/Tc)**(c2*c3) - c2 + c3*(c2 - <NUM_LIT:1>)**<NUM_LIT:2> + <NUM_LIT:1>)*exp(-c1*((T/Tc)**(c2*c3) - <NUM_LIT:1>))/T**<NUM_LIT:2>)<EOL>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives according to Twu et al. (1991) [1]_. Returns `a_alpha`,
        `da_alpha_dT`, and `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives`
        for more documentation. Three coefficients needed.

        .. math::
            \alpha = \left(\frac{T}{Tc}\right)^{c_{3} \left(c_{2}
            - 1\right)} e^{c_{1} \left(- \left(\frac{T}{Tc}
            \right)^{c_{2} c_{3}} + 1\right)}

        References
        ----------
        .. [1] Twu, Chorng H., David Bluck, John R. Cunningham, and John E.
           Coon. "A Cubic Equation of State with a New Alpha Function and a
           New Mixing Rule." Fluid Phase Equilibria 69 (December 10, 1991):
           33-50. doi:10.1016/0378-3812(91)90024-2.


if self.S2 == <NUM_LIT:0>:<EOL><INDENT>self.m = self.S1<EOL>return SRK.solve_T(self, P, V, quick=quick)<EOL><DEDENT>else:<EOL><INDENT>return super(SRK, self).solve_T(P, V, quick=quick) <EOL>

r'''Method to calculate `T` from a specified `P` and `V` for the API
        SRK EOS. Uses `a`, `b`, and `Tc` obtained from the class's namespace.

        Parameters
        ----------
        P : float
            Pressure, [Pa]
        V : float
            Molar volume, [m^3/mol]
        quick : bool, optional
            Whether to use a SymPy cse-derived expression (3x faster) or
            individual formulas

        Returns
        -------
        T : float
            Temperature, [K]

        Notes
        -----
        If S2 is set to 0, the solution is the same as in the SRK EOS, and that
        is used. Otherwise, newton's method must be used to solve for `T`.
        There are 8 roots of T in that case, six of them real. No guarantee can
        be made regarding which root will be obtained.


@staticmethod<EOL><INDENT>def main_derivatives_and_departures(T, P, V, b, delta, epsilon, a_alpha,<EOL>da_alpha_dT, d2a_alpha_dT2, quick=True):<DEDENT>

dP_dT = R/(V - b)<EOL>dP_dV = -R*T/(V - b)**<NUM_LIT:2> + <NUM_LIT:2>*a_alpha/V**<NUM_LIT:3><EOL>d2P_dT2 = <NUM_LIT:0><EOL>d2P_dV2 = <NUM_LIT:2>*(R*T/(V - b)**<NUM_LIT:3> - <NUM_LIT:3>*a_alpha/V**<NUM_LIT:4>)<EOL>d2P_dTdV = -R/(V - b)**<NUM_LIT:2><EOL>H_dep = P*V - R*T - a_alpha/V<EOL>S_dep = R*(-log(V) + log(V - b)) + R*log(P*V/(R*T))<EOL>Cv_dep = <NUM_LIT:0><EOL>return [dP_dT, dP_dV, d2P_dT2, d2P_dV2, d2P_dTdV, H_dep, S_dep, Cv_dep]<EOL>

Re-implementation of derivatives and excess property calculations,
        as ZeroDivisionError errors occur with the general solution. The
        following derivation is the source of these formulas.

        >>> from sympy import *
        >>> P, T, V, R, b, a = symbols('P, T, V, R, b, a')
        >>> P_vdw = R*T/(V-b) - a/(V*V)
        >>> vdw = P_vdw - P
        >>>
        >>> dP_dT = diff(vdw, T)
        >>> dP_dV = diff(vdw, V)
        >>> d2P_dT2 = diff(vdw, T, 2)
        >>> d2P_dV2 = diff(vdw, V, 2)
        >>> d2P_dTdV = diff(vdw, T, V)
        >>> H_dep = integrate(T*dP_dT - P_vdw, (V, oo, V))
        >>> H_dep += P*V - R*T
        >>> S_dep = integrate(dP_dT - R/V, (V,oo,V))
        >>> S_dep += R*log(P*V/(R*T))
        >>> Cv_dep = T*integrate(d2P_dT2, (V,oo,V))
        >>>
        >>> dP_dT, dP_dV, d2P_dT2, d2P_dV2, d2P_dTdV, H_dep, S_dep, Cv_dep
        (R/(V - b), -R*T/(V - b)**2 + 2*a/V**3, 0, 2*(R*T/(V - b)**3 - 3*a/V**4), -R/(V - b)**2, P*V - R*T - a/V, R*(-log(V) + log(V - b)) + R*log(P*V/(R*T)), 0)


@staticmethod<EOL><INDENT>def Mathias(self, T, full=True, quick=True):<DEDENT>

c1, c2 = self.alpha_function_coeffs<EOL>T, Tc, a = self.T, self.Tc, self.a<EOL>a_alpha = a*(<NUM_LIT:1> + c1*(<NUM_LIT:1>-sqrt(Tr)) -c2*(<NUM_LIT:1>-Tr)*(<NUM_LIT>-Tr))**<NUM_LIT:2><EOL>if not full:<EOL><INDENT>return a_alpha<EOL><DEDENT>else:<EOL><INDENT>da_alpha_dT = a*(c1*(-sqrt(T/Tc) + <NUM_LIT:1>) - c2*(-T/Tc + <NUM_LIT>)*(-T/Tc + <NUM_LIT:1>) + <NUM_LIT:1>)*(<NUM_LIT:2>*c2*(-T/Tc + <NUM_LIT>)/Tc + <NUM_LIT:2>*c2*(-T/Tc + <NUM_LIT:1>)/Tc - c1*sqrt(T/Tc)/T)<EOL>d2a_alpha_dT2 = a*((<NUM_LIT:8>*c2/Tc**<NUM_LIT:2> - c1*sqrt(T/Tc)/T**<NUM_LIT:2>)*(c1*(sqrt(T/Tc) - <NUM_LIT:1>) + c2*(T/Tc - <NUM_LIT:1>)*(T/Tc - <NUM_LIT>) - <NUM_LIT:1>) + (<NUM_LIT:2>*c2*(T/Tc - <NUM_LIT:1>)/Tc + <NUM_LIT:2>*c2*(T/Tc - <NUM_LIT>)/Tc + c1*sqrt(T/Tc)/T)**<NUM_LIT:2>)/<NUM_LIT:2><EOL>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives according to Mathias (1983) [1]_. Returns `a_alpha`,
        `da_alpha_dT`, and `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives`
        for more documentation. Two coefficients needed.

        .. math::
            \alpha = \left(c_{1} \left(- \sqrt{\frac{T}{Tc}} + 1\right)
            - c_{2} \left(- \frac{T}{Tc} + 0.7\right) \left(- \frac{T}{Tc}
            + 1\right) + 1\right)^{2}

        References
        ----------
        .. [1] Mathias, Paul M. "A Versatile Phase Equilibrium Equation of
           State." Industrial & Engineering Chemistry Process Design and
           Development 22, no. 3 (July 1, 1983): 385-91.
           doi:10.1021/i200022a008.


@staticmethod<EOL><INDENT>def Almeida(self, T, full=True, quick=True):<DEDENT>

<EOL>c1, c2, c3 = self.alpha_function_coeffs<EOL>T, Tc, a = self.T, self.Tc, self.a<EOL>a_alpha = a*exp(c1*(-T/Tc + <NUM_LIT:1>)*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:1>) + c3*(-<NUM_LIT:1> + Tc/T))<EOL>if not full:<EOL><INDENT>return a_alpha<EOL><DEDENT>else:<EOL><INDENT>da_alpha_dT = a*((c1*(c2 - <NUM_LIT:1>)*(-T/Tc + <NUM_LIT:1>)*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:1>)*copysign(<NUM_LIT:1>, T/Tc - <NUM_LIT:1>)/(Tc*Abs(T/Tc - <NUM_LIT:1>)) - c1*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:1>)/Tc - Tc*c3/T**<NUM_LIT:2>)*exp(c1*(-T/Tc + <NUM_LIT:1>)*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:1>) + c3*(-<NUM_LIT:1> + Tc/T)))<EOL>d2a_alpha_dT2 = a*exp(c3*(Tc/T - <NUM_LIT:1>) - c1*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:1>)*(T/Tc - <NUM_LIT:1>))*((c1*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:1>))/Tc + (Tc*c3)/T**<NUM_LIT:2> + (c1*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:2>)*copysign(<NUM_LIT:1>, T/Tc - <NUM_LIT:1>)*(c2 - <NUM_LIT:1>)*(T/Tc - <NUM_LIT:1>))/Tc)**<NUM_LIT:2> - exp(c3*(Tc/T - <NUM_LIT:1>) - c1*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:1>)*(T/Tc - <NUM_LIT:1>))*((<NUM_LIT:2>*c1*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:2>)*copysign(<NUM_LIT:1>, T/Tc - <NUM_LIT:1>)*(c2 - <NUM_LIT:1>))/Tc**<NUM_LIT:2> - (<NUM_LIT:2>*Tc*c3)/T**<NUM_LIT:3> + (c1*abs(T/Tc - <NUM_LIT:1>)**(c2 - <NUM_LIT:3>)*copysign(<NUM_LIT:1>, T/Tc - <NUM_LIT:1>)**<NUM_LIT:2>*(c2 - <NUM_LIT:1>)*(c2 - <NUM_LIT:2>)*(T/Tc - <NUM_LIT:1>))/Tc**<NUM_LIT:2>)<EOL>return a_alpha, da_alpha_dT, d2a_alpha_dT2<EOL><DEDENT>

r'''Method to calculate `a_alpha` and its first and second
        derivatives according to Almeida et al. (1991) [1]_. Returns `a_alpha`,
        `da_alpha_dT`, and `d2a_alpha_dT2`. See `GCEOS.a_alpha_and_derivatives`
        for more documentation. Three coefficients needed.

        .. math::
            \alpha = e^{c_{1} \left(- \frac{T}{Tc} + 1\right) \left|{
            \frac{T}{Tc} - 1}\right|^{c_{2} - 1} + c_{3} \left(-1
            + \frac{Tc}{T}\right)}

        References
        ----------
        .. [1] Almeida, G. S., M. Aznar, and A. S. Telles. "Uma Nova Forma de
           Dependência Com a Temperatura Do Termo Atrativo de Equações de
           Estado Cúbicas." RBE, Rev. Bras. Eng., Cad. Eng. Quim 8 (1991): 95.


def Clapeyron(T, Tc, Pc, dZ=<NUM_LIT:1>, Psat=<NUM_LIT>):

Tr = T/Tc<EOL>return R*T*dZ*log(Pc/Psat)/(<NUM_LIT:1.> - Tr)<EOL>

r'''Calculates enthalpy of vaporization at arbitrary temperatures using the
    Clapeyron equation.

    The enthalpy of vaporization is given by:

    .. math::
        \Delta H_{vap} = RT \Delta Z \frac{\ln (P_c/Psat)}{(1-T_{r})}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    Pc : float
        Critical pressure of fluid [Pa]
    dZ : float
        Change in compressibility factor between liquid and gas, []
    Psat : float
        Saturation pressure of fluid [Pa], optional

    Returns
    -------
    Hvap : float
        Enthalpy of vaporization, [J/mol]

    Notes
    -----
    No original source is available for this equation.
    [1]_ claims this equation overpredicts enthalpy by several percent.
    Under Tr = 0.8, dZ = 1 is a reasonable assumption.
    This equation is most accurate at the normal boiling point.

    Internal units are bar.

    WARNING: I believe it possible that the adjustment for pressure may be incorrect

    Examples
    --------
    Problem from Perry's examples.

    >>> Clapeyron(T=294.0, Tc=466.0, Pc=5.55E6)
    26512.354585061985

    References
    ----------
    .. [1] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.


def Tliquidus(Tms=None, ws=None, xs=None, CASRNs=None, AvailableMethods=False,<EOL>Method=None):

def list_methods():<EOL><INDENT>methods = []<EOL>if none_and_length_check([Tms]):<EOL><INDENT>methods.append('<STR_LIT>')<EOL>methods.append('<STR_LIT>')<EOL><DEDENT>methods.append('<STR_LIT:None>')<EOL>return methods<EOL><DEDENT>if AvailableMethods:<EOL><INDENT>return list_methods()<EOL><DEDENT>if not Method:<EOL><INDENT>Method = list_methods()[<NUM_LIT:0>]<EOL><DEDENT>if Method == '<STR_LIT>':<EOL><INDENT>_Tliq = max(Tms)<EOL><DEDENT>elif Method == '<STR_LIT>':<EOL><INDENT>_Tliq = mixing_simple(xs, Tms)<EOL><DEDENT>elif Method == '<STR_LIT:None>':<EOL><INDENT>return None<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>return _Tliq<EOL>

This function handles the retrival of a mixtures's liquidus point.

    This API is considered experimental, and is expected to be removed in a
    future release in favor of a more complete object-oriented interface.

    >>> Tliquidus(Tms=[250.0, 350.0], xs=[0.5, 0.5])
    350.0
    >>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], Method='Simple')
    300.0
    >>> Tliquidus(Tms=[250, 350], xs=[0.5, 0.5], AvailableMethods=True)
    ['Maximum', 'Simple', 'None']


Pc = Pc/<NUM_LIT>  <EOL>Tbr = Tb/Tc<EOL>return <NUM_LIT>*Tb*R*(log(Pc) - <NUM_LIT>)/(<NUM_LIT> - Tbr)<EOL>

r'''Calculates enthalpy of vaporization at the boiling point, using the
    Ridel [1]_ CSP method. Required information are critical temperature
    and pressure, and boiling point. Equation taken from [2]_ and [3]_.

    The enthalpy of vaporization is given by:

    .. math::
        \Delta_{vap} H=1.093 T_b R\frac{\ln P_c-1.013}{0.930-T_{br}}

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

    Returns
    -------
    Hvap : float
        Enthalpy of vaporization at the normal boiling point, [J/mol]

    Notes
    -----
    This equation has no example calculation in any source. The source has not
    been verified. It is equation 4-144 in Perry's. Perry's also claims that
    errors seldom surpass 5%.

    [2]_ is the source of example work here, showing a calculation at 0.0%
    error.

    Internal units of pressure are bar.

    Examples
    --------
    Pyridine, 0.0% err vs. exp: 35090 J/mol; from Poling [2]_.

    >>> Riedel(388.4, 620.0, 56.3E5)
    35089.78989646058

    References
    ----------
    .. [1] Riedel, L. "Eine Neue Universelle Dampfdruckformel Untersuchungen
       Uber Eine Erweiterung Des Theorems Der Ubereinstimmenden Zustande. Teil
       I." Chemie Ingenieur Technik 26, no. 2 (February 1, 1954): 83-89.
       doi:10.1002/cite.330260206.
    .. [2] Poling, Bruce E. The Properties of Gases and Liquids. 5th edition.
       New York: McGraw-Hill Professional, 2000.
    .. [3] Green, Don, and Robert Perry. Perry's Chemical Engineers' Handbook,
       Eighth Edition. McGraw-Hill Professional, 2007.


def Hfus(T=<NUM_LIT>, P=<NUM_LIT>, MW=None, AvailableMethods=False, Method=None, CASRN='<STR_LIT>'):

def list_methods():<EOL><INDENT>methods = []<EOL>if CASRN in CRCHfus_data.index:<EOL><INDENT>methods.append('<STR_LIT>')<EOL><DEDENT>methods.append('<STR_LIT:None>')<EOL>return methods<EOL><DEDENT>if AvailableMethods:<EOL><INDENT>return list_methods()<EOL><DEDENT>if not Method:<EOL><INDENT>Method = list_methods()[<NUM_LIT:0>]<EOL><DEDENT>if Method == '<STR_LIT>':<EOL><INDENT>_Hfus = CRCHfus_data.at[CASRN, '<STR_LIT>']<EOL><DEDENT>elif Method == '<STR_LIT:None>' or not MW:<EOL><INDENT>_Hfus = None<EOL><DEDENT>else:<EOL><INDENT>raise Exception('<STR_LIT>')<EOL><DEDENT>_Hfus = property_molar_to_mass(_Hfus, MW)<EOL>return _Hfus<EOL>

This function handles the calculation of a chemical's enthalpy of fusion.
    Generally this, is used by the chemical class, as all parameters are passed.
    Calling the function directly works okay.

    Enthalpy of fusion is a weak function of pressure, and its effects are
    neglected.

    This API is considered experimental, and is expected to be removed in a
    future release in favor of a more complete object-oriented interface.


return (<NUM_LIT> + <NUM_LIT>*omega + <NUM_LIT>*omega**<NUM_LIT:2>)*(<NUM_LIT:1>-T/Tc)**<NUM_LIT>*R*Tc<EOL>

r'''Calculates enthalpy of vaporization at arbitrary temperatures using a
    the work of [1]_; requires a chemical's critical temperature and
    acentric factor.

    The enthalpy of vaporization is given by:

    .. math::
        \Delta_{vap} H = RT_c(7.2729 + 10.4962\omega + 0.6061\omega^2)(1-T_r)^{0.38}

    Parameters
    ----------
    T : float
        Temperature of fluid [K]
    Tc : float
        Critical temperature of fluid [K]
    omega : float
        Acentric factor [-]

    Returns
    -------
    Hvap : float
        Enthalpy of vaporization, [J/mol]

    Notes
    -----
    The original article has been reviewed. It is regressed from enthalpy of
    vaporization values at 0.7Tr, from 121 fluids in REFPROP 9.1.
    A value in the article was read to be similar, but slightly too low from
    that calculated here.

    Examples
    --------
    From graph, in [1]_ for perfluoro-n-heptane.

    >>> Velasco(333.2, 476.0, 0.5559)
    33299.41734936356

    References
    ----------
    .. [1] Velasco, S., M. J. Santos, and J. A. White. "Extended Corresponding
       States Expressions for the Changes in Enthalpy, Compressibility Factor
       and Constant-Volume Heat Capacity at Vaporization." The Journal of
       Chemical Thermodynamics 85 (June 2015): 68-76.
       doi:10.1016/j.jct.2015.01.011.