yaeos 3.1.0__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- yaeos/__init__.py +54 -0
- yaeos/constants.py +4 -0
- yaeos/core.py +2473 -0
- yaeos/envelopes.py +407 -0
- yaeos/fitting/__init__.py +12 -0
- yaeos/fitting/core.py +193 -0
- yaeos/fitting/model_setters.py +76 -0
- yaeos/fitting/solvers.py +87 -0
- yaeos/gpec.py +104 -0
- yaeos/lib/__init__.py +9 -0
- yaeos/lib/yaeos_python.cpython-313-x86_64-linux-gnu.so +0 -0
- yaeos/models/__init__.py +24 -0
- yaeos/models/excess_gibbs/__init__.py +20 -0
- yaeos/models/excess_gibbs/dortmund.py +45 -0
- yaeos/models/excess_gibbs/nrtl.py +49 -0
- yaeos/models/excess_gibbs/psrk_unifac.py +45 -0
- yaeos/models/excess_gibbs/unifac.py +45 -0
- yaeos/models/excess_gibbs/uniquac.py +117 -0
- yaeos/models/groups.py +49 -0
- yaeos/models/residual_helmholtz/__init__.py +21 -0
- yaeos/models/residual_helmholtz/cubic_eos/__init__.py +38 -0
- yaeos/models/residual_helmholtz/cubic_eos/cubic_eos.py +449 -0
- yaeos/models/residual_helmholtz/cubic_eos/mixing_rules.py +253 -0
- yaeos-3.1.0.dist-info/METADATA +87 -0
- yaeos-3.1.0.dist-info/RECORD +32 -0
- yaeos-3.1.0.dist-info/WHEEL +6 -0
- yaeos.libs/libblas-357956a1.so.3.4.2 +0 -0
- yaeos.libs/libgfortran-040039e1.so.5.0.0 +0 -0
- yaeos.libs/libgfortran-91cc3cb1.so.3.0.0 +0 -0
- yaeos.libs/libgomp-a34b3233.so.1.0.0 +0 -0
- yaeos.libs/liblapack-1ad85175.so.3.4.2 +0 -0
- yaeos.libs/libquadmath-96973f99.so.0.0.0 +0 -0
yaeos/fitting/solvers.py
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
"""Solvers.
|
2
|
+
|
3
|
+
Module that contains different solvers for specific porpouses.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import numpy as np
|
7
|
+
|
8
|
+
|
9
|
+
def binary_isofugacity_x1y1pt(x, p, t, model):
|
10
|
+
"""Isofugacity evaluation at a given P and T."""
|
11
|
+
y1, x1 = x
|
12
|
+
|
13
|
+
x = np.array([x1, 1 - x1])
|
14
|
+
y = np.array([y1, 1 - y1])
|
15
|
+
|
16
|
+
lnphi_x = model.lnphi_pt(x, pressure=p, temperature=t, root="stable")
|
17
|
+
lnphi_y = model.lnphi_pt(y, pressure=p, temperature=t, root="stable")
|
18
|
+
|
19
|
+
isofug = np.log(x) + lnphi_x - (np.log(y) + lnphi_y)
|
20
|
+
|
21
|
+
return isofug**2
|
22
|
+
|
23
|
+
|
24
|
+
def solve_pt(model, p, t, kind):
|
25
|
+
"""Solve a point at a given P and T."""
|
26
|
+
try:
|
27
|
+
x10, y10 = find_init_binary_ll(model, p, t, kind)
|
28
|
+
except ValueError:
|
29
|
+
x10, y10 = 0.1, 0.9
|
30
|
+
|
31
|
+
mean = (x10 + y10) / 2
|
32
|
+
|
33
|
+
z = [mean, 1 - mean]
|
34
|
+
y0 = np.array([y10, 1 - y10])
|
35
|
+
x0 = np.array([x10, 1 - x10])
|
36
|
+
|
37
|
+
flash = model.flash_pt(z, pressure=p, temperature=t, k0=y0 / x0)
|
38
|
+
|
39
|
+
x1 = flash["x"][0]
|
40
|
+
y1 = flash["y"][0]
|
41
|
+
|
42
|
+
return x1, y1
|
43
|
+
|
44
|
+
|
45
|
+
def find_init_binary_ll(model, pressure, temperature, kind):
|
46
|
+
"""Find initial guess for a binary liquid-liquid system."""
|
47
|
+
from scipy.signal import argrelmin, argrelmax
|
48
|
+
|
49
|
+
(
|
50
|
+
p,
|
51
|
+
t,
|
52
|
+
) = (
|
53
|
+
pressure,
|
54
|
+
temperature,
|
55
|
+
)
|
56
|
+
|
57
|
+
if kind == "liquid-liquid":
|
58
|
+
root = "liquid"
|
59
|
+
else:
|
60
|
+
root = "stable"
|
61
|
+
|
62
|
+
zs = np.linspace(1e-15, 1 - 1e-15, 100)
|
63
|
+
|
64
|
+
phis = np.array(
|
65
|
+
[
|
66
|
+
model.lnphi_pt([z, 1 - z], temperature=t, pressure=p, root=root)
|
67
|
+
for z in zs
|
68
|
+
]
|
69
|
+
)
|
70
|
+
phis = np.exp(phis)
|
71
|
+
fug_1 = zs * phis[:, 0] * p
|
72
|
+
|
73
|
+
argmin = argrelmin(zs * phis[:, 0] * p)[-1] + 1
|
74
|
+
argmax = argrelmax(zs * phis[:, 0] * p)[0] - 1
|
75
|
+
|
76
|
+
fug = np.mean([fug_1[argmin], fug_1[argmax]])
|
77
|
+
|
78
|
+
if fug > fug_1[-1]:
|
79
|
+
fug = np.mean([fug_1[argmin[0]], fug_1[-1]])
|
80
|
+
|
81
|
+
msk = zs < zs[argmax]
|
82
|
+
x1 = zs[msk][np.argmin(np.abs(fug - fug_1[msk]))]
|
83
|
+
|
84
|
+
msk = zs > zs[argmin]
|
85
|
+
y1 = zs[msk][np.argmin(np.abs(fug - fug_1[msk]))]
|
86
|
+
|
87
|
+
return x1, y1
|
yaeos/gpec.py
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
"""Global Phase Equilibria Calculations.
|
2
|
+
|
3
|
+
Module that implements the GPEC algorithm for calculation of GPEDs and its
|
4
|
+
derivatives to obtain isopleths, isotherms and isobars.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import matplotlib.pyplot as plt
|
8
|
+
|
9
|
+
import numpy as np
|
10
|
+
|
11
|
+
from yaeos.core import ArModel
|
12
|
+
|
13
|
+
|
14
|
+
class GPEC:
|
15
|
+
|
16
|
+
def __init__(
|
17
|
+
self,
|
18
|
+
model: ArModel,
|
19
|
+
max_pressure=2500,
|
20
|
+
max_points=10000,
|
21
|
+
stability_analysis=True,
|
22
|
+
step_21=1e-2,
|
23
|
+
step_12=1e-5,
|
24
|
+
):
|
25
|
+
self._z0 = [0, 1]
|
26
|
+
self._zi = [1, 0]
|
27
|
+
self._model = model
|
28
|
+
|
29
|
+
psats = [model.pure_saturation_pressures(i) for i in [1, 2]]
|
30
|
+
|
31
|
+
self._pures = psats
|
32
|
+
|
33
|
+
diff = 1e-3
|
34
|
+
cl, cep = model.critical_line(
|
35
|
+
z0=self._z0,
|
36
|
+
zi=self._zi,
|
37
|
+
ns=1,
|
38
|
+
s=diff,
|
39
|
+
a0=diff,
|
40
|
+
ds0=step_21,
|
41
|
+
stop_pressure=max_pressure,
|
42
|
+
max_points=max_points,
|
43
|
+
stability_analysis=stability_analysis,
|
44
|
+
)
|
45
|
+
|
46
|
+
self._cl21 = cl
|
47
|
+
self._cep21 = cep
|
48
|
+
|
49
|
+
if (
|
50
|
+
not np.isnan(cep["T"])
|
51
|
+
or (
|
52
|
+
abs(cl["T"][-1] - psats[0]["T"][-1]) > 10
|
53
|
+
and abs(cl["P"][-1] - psats[0]["P"][-1] > 10)
|
54
|
+
)
|
55
|
+
):
|
56
|
+
cl, cep = model.critical_line(
|
57
|
+
z0=self._z0,
|
58
|
+
zi=self._zi,
|
59
|
+
ns=1,
|
60
|
+
s=1 - diff / 10,
|
61
|
+
a0=1 - diff / 10,
|
62
|
+
ds0=-step_12,
|
63
|
+
stop_pressure=max_pressure,
|
64
|
+
max_points=max_points,
|
65
|
+
stability_analysis=stability_analysis,
|
66
|
+
)
|
67
|
+
|
68
|
+
self._cl12 = cl
|
69
|
+
self._cep12 = cep
|
70
|
+
else:
|
71
|
+
self._cl12 = None
|
72
|
+
self._cep12 = None
|
73
|
+
|
74
|
+
a, T, V = model.critical_line_liquid_liquid(
|
75
|
+
z0=self._z0, zi=self._zi, pressure=max_pressure, t0=500
|
76
|
+
)
|
77
|
+
|
78
|
+
cl, cep = model.critical_line(
|
79
|
+
z0=self._z0,
|
80
|
+
zi=self._zi,
|
81
|
+
ns=4,
|
82
|
+
s=np.log(max_pressure),
|
83
|
+
a0=a,
|
84
|
+
v0=V,
|
85
|
+
t0=T,
|
86
|
+
p0=max_pressure,
|
87
|
+
ds0=-1e-1,
|
88
|
+
stop_pressure=max_pressure * 1.1,
|
89
|
+
max_points=max_points,
|
90
|
+
stability_analysis=stability_analysis,
|
91
|
+
)
|
92
|
+
|
93
|
+
self._cl_ll = cl
|
94
|
+
self._cep_ll = cep
|
95
|
+
|
96
|
+
def plot_gped(self):
|
97
|
+
for pure in self._pures:
|
98
|
+
plt.plot(pure["T"], pure["P"], color="green")
|
99
|
+
|
100
|
+
plt.plot(self._cl21["T"], self._cl21["P"], color="black")
|
101
|
+
if self._cl12:
|
102
|
+
plt.plot(self._cl12["T"], self.cl12["P"], color="black")
|
103
|
+
if self._cl_ll:
|
104
|
+
plt.plot(self._cl_ll["T"], self._cl_ll["P"], color="black")
|
yaeos/lib/__init__.py
ADDED
Binary file
|
yaeos/models/__init__.py
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
"""Models module.
|
2
|
+
|
3
|
+
Yaeos models module. This module provides the following submodules:
|
4
|
+
|
5
|
+
- excess_gibbs: Excess Gibbs energy models
|
6
|
+
- NRTL: non-random two-liquid model
|
7
|
+
- UNIFACVLE: Original UNIFAC VLE model
|
8
|
+
- UNIQUAC: UNIversal QUAsiChemical Excess Gibbs free energy model
|
9
|
+
|
10
|
+
- residual_helmholtz: Residual Helmholtz energy models
|
11
|
+
- Cubic EoS:
|
12
|
+
- PengRobinson76: Peng-Robinson model (1976)
|
13
|
+
- PengRobinson78: Peng-Robinson model (1978)
|
14
|
+
- SoaveRedlichKwong: Soave-Redlich-Kwong model
|
15
|
+
- RKPR: RKPR model
|
16
|
+
- Mixing rules: mixing rules for cubic EoS
|
17
|
+
- QMR: cuadratic mixing rule
|
18
|
+
- MHV: modified Huron-Vidal mixing rule
|
19
|
+
"""
|
20
|
+
|
21
|
+
from . import excess_gibbs, residual_helmholtz
|
22
|
+
|
23
|
+
|
24
|
+
__all__ = ["excess_gibbs", "residual_helmholtz"]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
"""Gibbs Excess Models module.
|
2
|
+
|
3
|
+
Yaeos Gibbs excess module. This module provides the following submodules:
|
4
|
+
|
5
|
+
- excess_gibbs: Excess Gibbs energy models
|
6
|
+
- NRTL: non-random two-liquid model
|
7
|
+
- UNIFACVLE: Original UNIFAC VLE model
|
8
|
+
- UNIFACPSRK: UNIFAC-PSRK model (Predictive Soave-Redlich-Kwong)
|
9
|
+
- UNIFACDortmund: UNIFAC Dortmund model
|
10
|
+
- UNIQUAC: UNIversal QUAsiChemical Excess Gibbs free energy model
|
11
|
+
"""
|
12
|
+
|
13
|
+
from .dortmund import UNIFACDortmund
|
14
|
+
from .nrtl import NRTL
|
15
|
+
from .psrk_unifac import UNIFACPSRK
|
16
|
+
from .unifac import UNIFACVLE
|
17
|
+
from .uniquac import UNIQUAC
|
18
|
+
|
19
|
+
|
20
|
+
__all__ = ["NRTL", "UNIFACVLE", "UNIFACPSRK", "UNIFACDortmund", "UNIQUAC"]
|
@@ -0,0 +1,45 @@
|
|
1
|
+
"""UNIFAC Dortmund Module."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from yaeos.core import GeModel
|
6
|
+
from yaeos.lib import yaeos_c
|
7
|
+
from yaeos.models.groups import groups_from_dicts
|
8
|
+
|
9
|
+
|
10
|
+
class UNIFACDortmund(GeModel):
|
11
|
+
"""UNIFAC Dortmund model.
|
12
|
+
|
13
|
+
Please refer to the `yaeos` user documentation for an in-depth look at the
|
14
|
+
model's information: https://ipqa-research.github.io/yaeos/page/index.html
|
15
|
+
|
16
|
+
Parameters
|
17
|
+
----------
|
18
|
+
molecules : list of dict
|
19
|
+
List of dicts with the groups and their amounts for each molecule.
|
20
|
+
|
21
|
+
Example
|
22
|
+
-------
|
23
|
+
.. code-block:: python
|
24
|
+
|
25
|
+
from yaeos import UNIFACDortmund
|
26
|
+
|
27
|
+
# Groups for water and ethanol
|
28
|
+
water = {16: 1}
|
29
|
+
ethanol = {1: 1, 2: 1, 14: 1}
|
30
|
+
|
31
|
+
groups = [water, ethanol]
|
32
|
+
|
33
|
+
model = UNIFACDortmund(groups)
|
34
|
+
|
35
|
+
model.ln_gamma([0.5, 0.5], 298.15)
|
36
|
+
"""
|
37
|
+
|
38
|
+
def __init__(self, molecules: List[dict]) -> None:
|
39
|
+
|
40
|
+
(number_of_groups, groups_ids, groups_ammounts) = groups_from_dicts(
|
41
|
+
molecules
|
42
|
+
)
|
43
|
+
self.id = yaeos_c.unifac_dortmund(
|
44
|
+
ngs=number_of_groups, g_ids=groups_ids, g_v=groups_ammounts
|
45
|
+
)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
"""Non-random two-liquid model (NRTL) module."""
|
2
|
+
|
3
|
+
from yaeos.core import GeModel
|
4
|
+
from yaeos.lib import yaeos_c
|
5
|
+
|
6
|
+
|
7
|
+
class NRTL(GeModel):
|
8
|
+
"""Non-random two-liquid model (NRTL) class.
|
9
|
+
|
10
|
+
Parameters
|
11
|
+
----------
|
12
|
+
a : array_like
|
13
|
+
NRTL aij parameters matrix
|
14
|
+
b : array_like
|
15
|
+
NRTL bij parameters matrix
|
16
|
+
c : array_like
|
17
|
+
NRTL cij parameters matrix
|
18
|
+
|
19
|
+
Attributes
|
20
|
+
----------
|
21
|
+
a : array_like
|
22
|
+
NRTL aij parameters matrix
|
23
|
+
b : array_like
|
24
|
+
NRTL bij parameters matrix
|
25
|
+
c : array_like
|
26
|
+
NRTL cij parameters matrix
|
27
|
+
id : int
|
28
|
+
NRTL model ID
|
29
|
+
|
30
|
+
Example
|
31
|
+
-------
|
32
|
+
.. code-block:: python
|
33
|
+
|
34
|
+
import numpy as np
|
35
|
+
|
36
|
+
from yaeos import NRTL
|
37
|
+
|
38
|
+
a = np.array([[0, 0.3], [0.3, 0]])
|
39
|
+
b = np.array([[0, 0.4], [0.4, 0]])
|
40
|
+
c = np.array([[0, 0.5], [0.5, 0]])
|
41
|
+
|
42
|
+
nrtl = NRTL(a, b, c)
|
43
|
+
"""
|
44
|
+
|
45
|
+
def __init__(self, a, b, c) -> None:
|
46
|
+
self.a = a
|
47
|
+
self.b = b
|
48
|
+
self.c = c
|
49
|
+
self.id = yaeos_c.nrtl(a, b, c)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
"""PSRK-UNIFAC Module."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from yaeos.core import GeModel
|
6
|
+
from yaeos.lib import yaeos_c
|
7
|
+
from yaeos.models.groups import groups_from_dicts
|
8
|
+
|
9
|
+
|
10
|
+
class UNIFACPSRK(GeModel):
|
11
|
+
"""PSRK-UNIFAC model.
|
12
|
+
|
13
|
+
Please refer to the `yaeos` user documentation for an in-depth look at the
|
14
|
+
model's information: https://ipqa-research.github.io/yaeos/page/index.html
|
15
|
+
|
16
|
+
Parameters
|
17
|
+
----------
|
18
|
+
molecules : list of dict
|
19
|
+
List of dicts with the groups and their amounts for each molecule.
|
20
|
+
|
21
|
+
Example
|
22
|
+
-------
|
23
|
+
.. code-block:: python
|
24
|
+
|
25
|
+
from yaeos import UNIFACPSRK
|
26
|
+
|
27
|
+
# Groups for water and ethanol
|
28
|
+
water = {16: 1}
|
29
|
+
ethanol = {1: 1, 2: 1, 14: 1}
|
30
|
+
|
31
|
+
groups = [water, ethanol]
|
32
|
+
|
33
|
+
model = UNIFACPSRK(groups)
|
34
|
+
|
35
|
+
model.ln_gamma([0.5, 0.5], 298.15)
|
36
|
+
"""
|
37
|
+
|
38
|
+
def __init__(self, molecules: List[dict]) -> None:
|
39
|
+
|
40
|
+
(number_of_groups, groups_ids, groups_ammounts) = groups_from_dicts(
|
41
|
+
molecules
|
42
|
+
)
|
43
|
+
self.id = yaeos_c.unifac_psrk(
|
44
|
+
ngs=number_of_groups, g_ids=groups_ids, g_v=groups_ammounts
|
45
|
+
)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
"""UNIFAC Module."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
from yaeos.core import GeModel
|
6
|
+
from yaeos.lib import yaeos_c
|
7
|
+
from yaeos.models.groups import groups_from_dicts
|
8
|
+
|
9
|
+
|
10
|
+
class UNIFACVLE(GeModel):
|
11
|
+
"""UNIFAC VLE model.
|
12
|
+
|
13
|
+
Please refer to the `yaeos` user documentation for an in-depth look at the
|
14
|
+
model's information: https://ipqa-research.github.io/yaeos/page/index.html
|
15
|
+
|
16
|
+
Parameters
|
17
|
+
----------
|
18
|
+
molecules : list of dict
|
19
|
+
List of dicts with the groups and their amounts for each molecule.
|
20
|
+
|
21
|
+
Example
|
22
|
+
-------
|
23
|
+
.. code-block:: python
|
24
|
+
|
25
|
+
from yaeos import UNIFACVLE
|
26
|
+
|
27
|
+
# Groups for water and ethanol
|
28
|
+
water = {16: 1}
|
29
|
+
ethanol = {1: 1, 2: 1, 14: 1}
|
30
|
+
|
31
|
+
groups = [water, ethanol]
|
32
|
+
|
33
|
+
model = UNIFAVLE(groups)
|
34
|
+
|
35
|
+
model.ln_gamma([0.5, 0.5], 298.15)
|
36
|
+
"""
|
37
|
+
|
38
|
+
def __init__(self, molecules: List[dict]) -> None:
|
39
|
+
|
40
|
+
(number_of_groups, groups_ids, groups_ammounts) = groups_from_dicts(
|
41
|
+
molecules
|
42
|
+
)
|
43
|
+
self.id = yaeos_c.unifac_vle(
|
44
|
+
ngs=number_of_groups, g_ids=groups_ids, g_v=groups_ammounts
|
45
|
+
)
|
@@ -0,0 +1,117 @@
|
|
1
|
+
"""UNIQUAC (UNIversal QUAsiChemical) Excess Gibbs free energy model."""
|
2
|
+
|
3
|
+
import numpy as np
|
4
|
+
|
5
|
+
from yaeos.core import GeModel
|
6
|
+
from yaeos.lib import yaeos_c
|
7
|
+
|
8
|
+
|
9
|
+
class UNIQUAC(GeModel):
|
10
|
+
"""UNIQUAC (UNIversal QUAsiChemical) Excess Gibbs free energy model.
|
11
|
+
|
12
|
+
Please refer to the `yaeos` user documentation for an in-depth look at the
|
13
|
+
model's information: https://ipqa-research.github.io/yaeos/page/index.html
|
14
|
+
|
15
|
+
Parameters
|
16
|
+
----------
|
17
|
+
qs : array_like
|
18
|
+
Molecule's relative areas :math:`Q_i`
|
19
|
+
rs : array_like
|
20
|
+
Molecule's relative volumes :math:`R_i`
|
21
|
+
aij : array_like
|
22
|
+
Interaction parameters matrix :math:`a_{ij}` zero matrix if no
|
23
|
+
provided, by default None
|
24
|
+
bij : array_like
|
25
|
+
Interaction parameters matrix :math:`b_{ij}` zero matrix if no
|
26
|
+
provided, by default None
|
27
|
+
cij : array_like
|
28
|
+
Interaction parameters matrix :math:`c_{ij}` zero matrix if no
|
29
|
+
provided, by default None
|
30
|
+
dij : array_like
|
31
|
+
Interaction parameters matrix :math:`d_{ij}` zero matrix if no
|
32
|
+
provided, by default None
|
33
|
+
eij : array_like
|
34
|
+
Interaction parameters matrix :math:`e_{ij}` zero matrix if no
|
35
|
+
provided, by default None
|
36
|
+
|
37
|
+
Attributes
|
38
|
+
----------
|
39
|
+
qs : array_like
|
40
|
+
Molecule's relative areas :math:`Q_i`
|
41
|
+
rs : array_like
|
42
|
+
Molecule's relative volumes :math:`R_i`
|
43
|
+
aij : array_like
|
44
|
+
Interaction parameters matrix :math:`a_{ij}`
|
45
|
+
bij : array_like
|
46
|
+
Interaction parameters matrix :math:`b_{ij}`
|
47
|
+
cij : array_like
|
48
|
+
Interaction parameters matrix :math:`c_{ij}`
|
49
|
+
dij : array_like
|
50
|
+
Interaction parameters matrix :math:`d_{ij}`
|
51
|
+
eij : array_like
|
52
|
+
Interaction parameters matrix :math:`e_{ij}`
|
53
|
+
|
54
|
+
Example
|
55
|
+
-------
|
56
|
+
.. code-block:: python
|
57
|
+
|
58
|
+
import numpy as np
|
59
|
+
|
60
|
+
from yaeos import UNIQUAC
|
61
|
+
|
62
|
+
b = np.array(
|
63
|
+
[
|
64
|
+
[0.0, -526.02, -309.64],
|
65
|
+
[318.06, 0.0, 91.532],
|
66
|
+
[-1325.1, -302.57, 0.0],
|
67
|
+
]
|
68
|
+
)
|
69
|
+
|
70
|
+
rs = np.array([0.92, 2.1055, 3.1878])
|
71
|
+
qs = np.array([1.4, 1.972, 2.4])
|
72
|
+
|
73
|
+
t = 298.15
|
74
|
+
|
75
|
+
model = UNIQUAC(qs, rs, bij=b)
|
76
|
+
|
77
|
+
n = np.array([2.0, 2.0, 8.0])
|
78
|
+
|
79
|
+
gammas = np.exp(model.ln_gamma(n, t)) # [8.856, 0.860, 1.425]
|
80
|
+
"""
|
81
|
+
|
82
|
+
def __init__(
|
83
|
+
self, qs, rs, aij=None, bij=None, cij=None, dij=None, eij=None
|
84
|
+
) -> None:
|
85
|
+
self.qs = qs
|
86
|
+
self.rs = rs
|
87
|
+
|
88
|
+
nc = len(qs)
|
89
|
+
|
90
|
+
if aij is not None:
|
91
|
+
self.aij = np.array(aij, order="F")
|
92
|
+
else:
|
93
|
+
self.aij = np.zeros((nc, nc), order="F")
|
94
|
+
|
95
|
+
if bij is not None:
|
96
|
+
self.bij = np.array(bij, order="F")
|
97
|
+
else:
|
98
|
+
self.bij = np.zeros((nc, nc), order="F")
|
99
|
+
|
100
|
+
if cij is not None:
|
101
|
+
self.cij = np.array(cij, order="F")
|
102
|
+
else:
|
103
|
+
self.cij = np.zeros((nc, nc), order="F")
|
104
|
+
|
105
|
+
if dij is not None:
|
106
|
+
self.dij = np.array(dij, order="F")
|
107
|
+
else:
|
108
|
+
self.dij = np.zeros((nc, nc), order="F")
|
109
|
+
|
110
|
+
if eij is not None:
|
111
|
+
self.eij = np.array(eij, order="F")
|
112
|
+
else:
|
113
|
+
self.eij = np.zeros((nc, nc), order="F")
|
114
|
+
|
115
|
+
self.id = yaeos_c.uniquac(
|
116
|
+
qs, rs, self.aij, self.bij, self.cij, self.dij, self.eij
|
117
|
+
)
|
yaeos/models/groups.py
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
"""Handling groups for Group Contribution Models."""
|
2
|
+
|
3
|
+
from typing import List
|
4
|
+
|
5
|
+
import numpy as np
|
6
|
+
|
7
|
+
|
8
|
+
def groups_from_dicts(molecules: List[dict]):
|
9
|
+
"""Convert list of dicts with groups and their to C-API format.
|
10
|
+
|
11
|
+
Convert list of dicts with groups and their amounts to the format required
|
12
|
+
by the C-API.
|
13
|
+
|
14
|
+
Parameters
|
15
|
+
----------
|
16
|
+
molecules : list of dict
|
17
|
+
|
18
|
+
Returns
|
19
|
+
-------
|
20
|
+
number_of_groups : list of int
|
21
|
+
Number of groups for each molecule.
|
22
|
+
groups_ids : np.ndarray
|
23
|
+
Groups ids for each molecule.
|
24
|
+
groups_ammounts : np.ndarray
|
25
|
+
Groups amounts for each molecule.
|
26
|
+
"""
|
27
|
+
nc = len(molecules)
|
28
|
+
max_ng = max([len(groups) for groups in molecules])
|
29
|
+
|
30
|
+
# The C-API expects two 2D arrays with the groups and their amounts
|
31
|
+
# for each molecule. Each row in the arrays corresponds to a molecule
|
32
|
+
# and the columns to the groups. The arrays are padded with zeros.
|
33
|
+
groups_ids = np.zeros((nc, max_ng), dtype=np.int32, order="F")
|
34
|
+
groups_ammounts = np.zeros((nc, max_ng), dtype=np.int32, order="F")
|
35
|
+
|
36
|
+
# Construction of the arrays from the input dictionary
|
37
|
+
number_of_groups = []
|
38
|
+
for i, molecule_groups in enumerate(molecules):
|
39
|
+
ids = []
|
40
|
+
ammount = []
|
41
|
+
for group_id, group_count in molecule_groups.items():
|
42
|
+
ids.append(int(group_id))
|
43
|
+
ammount.append(int(group_count))
|
44
|
+
|
45
|
+
number_of_groups.append(len(ids))
|
46
|
+
groups_ids[i, : len(ids)] = ids
|
47
|
+
groups_ammounts[i, : len(ids)] = ammount
|
48
|
+
|
49
|
+
return number_of_groups, groups_ids, groups_ammounts
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"""Residual Helmholtz energy models module.
|
2
|
+
|
3
|
+
Yaeos Residual Helmholtz module. This module provides the following submodules:
|
4
|
+
|
5
|
+
- residual_helmholtz: Residual Helmholtz energy models
|
6
|
+
- Cubic EoS:
|
7
|
+
- PengRobinson76: Peng-Robinson model (1976)
|
8
|
+
- PengRobinson78: Peng-Robinson model (1978)
|
9
|
+
- SoaveRedlichKwong: Soave-Redlich-Kwong model
|
10
|
+
- RKPR: RKPR model
|
11
|
+
- PSRK: Predictive-Soave-Redlich-Kwong model
|
12
|
+
- Mixing rules: mixing rules for cubic EoS
|
13
|
+
- QMR: cuadratic mixing rule
|
14
|
+
- HV: Huron-Vidal mixing rule
|
15
|
+
- MHV: Michelsen's modified Huron-Vidal mixing rule
|
16
|
+
"""
|
17
|
+
|
18
|
+
from . import cubic_eos
|
19
|
+
|
20
|
+
|
21
|
+
__all__ = ["cubic_eos"]
|
@@ -0,0 +1,38 @@
|
|
1
|
+
"""Cubic EoS module.
|
2
|
+
|
3
|
+
Implemented models:
|
4
|
+
|
5
|
+
- Cubic EoS:
|
6
|
+
- PengRobinson76: Peng-Robinson model (1976)
|
7
|
+
- PengRobinson78: Peng-Robinson model (1978)
|
8
|
+
- SoaveRedlichKwong: Soave-Redlich-Kwong model
|
9
|
+
- RKPR: RKPR model
|
10
|
+
- Mixing rules: mixing rules for cubic EoS
|
11
|
+
- QMR: cuadratic mixing rule
|
12
|
+
- MHV: modified Huron-Vidal mixing rule
|
13
|
+
"""
|
14
|
+
|
15
|
+
from .cubic_eos import (
|
16
|
+
CubicEoS,
|
17
|
+
PSRK,
|
18
|
+
PengRobinson76,
|
19
|
+
PengRobinson78,
|
20
|
+
RKPR,
|
21
|
+
SoaveRedlichKwong,
|
22
|
+
)
|
23
|
+
from .mixing_rules import CubicMixRule, HV, MHV, QMR, QMRTD
|
24
|
+
|
25
|
+
|
26
|
+
__all__ = [
|
27
|
+
"CubicEoS",
|
28
|
+
"PengRobinson76",
|
29
|
+
"PengRobinson78",
|
30
|
+
"SoaveRedlichKwong",
|
31
|
+
"RKPR",
|
32
|
+
"PSRK",
|
33
|
+
"CubicMixRule",
|
34
|
+
"QMR",
|
35
|
+
"QMRTD",
|
36
|
+
"MHV",
|
37
|
+
"HV",
|
38
|
+
]
|