Source code for pytherm.activity.sit

"""Module contain SIT class for activity calculations

.. contents:: :local:

SIT Class
------------
.. autoclass:: SIT
    :members: get_y
    :undoc-members:
    :show-inheritance:
    :member-order: bysource
"""
import math
from .electrolytes import get_I, get_A
from pytherm.stoichiometry import extract_charges
import numpy as np
from .db.sit.sit import sit_parameters


[docs] class SIT: r""" Class for activity calculations using Specific ion interaction theory .. math:: \log_{10}(\gamma_{i}) = - z_i^2 * \frac{0.51 * \sqrt{I}}{1 + 1.5\sqrt{I}} + \sum_k\epsilon_{ik}m_k Parameters ---------- ph: dict Phase dict for parameters initialization parameters: list SIT parameters list ex.: [['Na_+1', 'Cl_-1', 0.03]] dict_mode: bool Dict or array mode, defaults to False """ substances = None charges = None cations = None anions = None epsilon_matrix = None dict_mode: bool def __init__(self, ph: dict, parameters=sit_parameters, dict_mode=False): self.substances = np.array(ph) self.charges = np.array(extract_charges(ph)) self.cations = self.substances[self.charges > 0] self.anions = self.substances[self.charges < 0] self.epsilon_matrix = np.zeros((len(self.cations), len(self.anions))) self.dict_mode = dict_mode for i in range(len(self.cations)): for j in range(len(self.anions)): for k in parameters: if k[0] == self.cations[i] and k[1] == self.anions[j]: self.epsilon_matrix[i, j] = k[2] if .0 in self.epsilon_matrix: print("SIT model: zero values in epsilon_matrix")
[docs] def get_y(self, ph, T=298): """Calculate activity coefficients Parameters ---------- ph: dict[str, float] Input dictionary T: float Temperature, [K], defaults to 298 Returns ------- dict[str, float] activity coefficients """ if self.dict_mode: molalities = np.array(list(ph.values())) else: molalities = np.array(ph) I = get_I(molalities, charges=self.charges) sqrt_I = math.sqrt(I) D = 0.509 * sqrt_I / (1 + 1.5 * sqrt_I) lny = np.zeros((len(self.substances))) for i in range(len(self.substances)): if self.charges[i] > 0: j = np.where(self.cations == self.substances[i])[0][0] lny[i] = - self.charges[i] ** 2 * D + self.epsilon_matrix[j, :] @ molalities[self.charges < 0] elif self.charges[i] < 0: j = np.where(self.anions == self.substances[i])[0][0] lny[i] = - self.charges[i] ** 2 * D + self.epsilon_matrix[:, j] @ molalities[self.charges > 0] else: lny[i] = 0 if self.dict_mode: y = {} for i in range(len(self.substances)): y[self.substances[i]] = 10 ** lny[i] return y else: y = [] for i in range(len(self.substances)): y.append(10 ** lny[i]) return np.array(y)
def get_a(self, ph, T=298): y = self.get_y(ph, T) if self.dict_mode: a = {} for i in y: a[i] = ph[i] * y[i] return a else: a = [] for i in range(len(self.substances)): a.append(ph[i] * y[i]) return np.array(a)