Multifluid+Association

Version 0.22 of teqp adds a new sort of hybrid model – a combination of multifluid model plus an association model. Conceptually the pure fluid EOS consider the self-association implicitly, so you may want to consider the association model to only allow cross-assocation, which be enforced by supplying the “self_assocation_mask” logical mask in the “options” of the model. See below

[1]:
import teqp, json, numpy as np
import matplotlib.pyplot as plt
import pandas

BIP = [{
    "Name1": "Water",
    "Name2": "Ammonia",
    "betaT": 1.0,
    "gammaT": 1.0,
    "betaV": 1.0,
    "gammaV": 1.0,
    "F": 0.0
}]
jmf = {
    "components": ["Water", "Ammonia"],
    "root": teqp.get_datapath(),
    "BIP": BIP,
}

jassoc = {
    "kind": "Dufal",
    "model": {
        "sigma / m": [3.0555e-10, 3.3309e-10],
        "epsilon / J/mol": [3475.445374388054, 323.70*8.3124462618],
        "lambda_r": [35.823, 36.832],

        # Note the scaling factors of 0.2 on the bonding energy to yield more reasonable behavior
        "epsilon_HB / J/mol": [0.2*13303.140189045183, 0.2*1105.0*8.314462618],

        "K_HB / m^3": [496.66e-30, 560.73e-30],
        "kmat": [[0.0,0.0],[0.0, 0.0]],
        "Delta_rule": "Dufal",
        "molecule_sites": [["e","e","H","H"],["e","H","H","H"]],
        "options": {"self_association_mask": [False, False]}
    }
}

j = {
    'kind': 'multifluid-association',
    'model': {
        'multifluid': jmf,
        'association': jassoc
    }
}

model = teqp.make_model(j)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[1], line 46
     20 jassoc = {
     21     "kind": "Dufal",
     22     "model": {
   (...)
     35     }
     36 }
     38 j = {
     39     'kind': 'multifluid-association',
     40     'model': {
   (...)
     43     }
     44 }
---> 46 model = teqp.make_model(j)

File ~/checkouts/readthedocs.org/user_builds/teqp/conda/stable/lib/python3.11/site-packages/teqp/__init__.py:47, in make_model(*args, **kwargs)
     42 def make_model(*args, **kwargs):
     43     """
     44     This function is in two parts; first the make_model function (renamed to _make_model in the Python interface)
     45     is used to make the model and then the model-specific methods are attached to the instance
     46     """
---> 47     AS = _make_model(*args, **kwargs)
     48     attach_model_specific_methods(AS)
     49     return AS

ValueError: Don't understand "kind" of: multifluid-association
[2]:
# model.get_assoc_calcs(300, 300, np.array([0.5, 0.5]))
[3]:
T = 293.15 # K
pure = teqp.build_multifluid_model(["Ammonia"], teqp.get_datapath())
anc = pure.build_ancillaries()
j = model.trace_VLE_isotherm_binary(T, np.array([0, anc.rhoL(T)]), np.array([0, anc.rhoV(T)]))
df = pandas.DataFrame(j)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[3], line 4
      2 pure = teqp.build_multifluid_model(["Ammonia"], teqp.get_datapath())
      3 anc = pure.build_ancillaries()
----> 4 j = model.trace_VLE_isotherm_binary(T, np.array([0, anc.rhoL(T)]), np.array([0, anc.rhoV(T)]))
      5 df = pandas.DataFrame(j)

NameError: name 'model' is not defined
[4]:
plt.plot(df['xL_0 / mole frac.'], df['pL / Pa']/1e3)
plt.plot(df['xV_0 / mole frac.'], df['pL / Pa']/1e3)
plt.yscale('log')
plt.gca().set(xlabel='$x_1,y_1$ / mole frac.', ylabel='p / kPa')
plt.title(f'Water(1) + Ammonia(2) @ {T} K')
plt.show()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 plt.plot(df['xL_0 / mole frac.'], df['pL / Pa']/1e3)
      2 plt.plot(df['xV_0 / mole frac.'], df['pL / Pa']/1e3)
      3 plt.yscale('log')

NameError: name 'df' is not defined