yaeos 0.1.1__cp310-cp310-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 +30 -0
- yaeos/core.py +557 -0
- yaeos/lib/__init__.py +9 -0
- yaeos/lib/yaeos_python.cpython-310-x86_64-linux-gnu.so +0 -0
- yaeos/models/__init__.py +22 -0
- yaeos/models/excess_gibbs/__init__.py +12 -0
- yaeos/models/excess_gibbs/nrtl.py +49 -0
- yaeos/models/residual_helmholtz/__init__.py +19 -0
- yaeos/models/residual_helmholtz/cubic_eos/__init__.py +34 -0
- yaeos/models/residual_helmholtz/cubic_eos/cubic_eos.py +335 -0
- yaeos/models/residual_helmholtz/cubic_eos/mixing_rules.py +138 -0
- yaeos-0.1.1.dist-info/METADATA +42 -0
- yaeos-0.1.1.dist-info/RECORD +19 -0
- yaeos-0.1.1.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/liblapack-1ad85175.so.3.4.2 +0 -0
- yaeos.libs/libquadmath-96973f99.so.0.0.0 +0 -0
yaeos/__init__.py
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
"""Yet Another Equation-Of-State (library).
|
2
|
+
|
3
|
+
Library to use EoS-based calculations. This main module imports all the
|
4
|
+
relevant constants, procedures and objects to have better access to them.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from yaeos.lib import yaeos_c
|
8
|
+
from yaeos.models.excess_gibbs.nrtl import (
|
9
|
+
NRTL,
|
10
|
+
)
|
11
|
+
from yaeos.models.residual_helmholtz.cubic_eos import (
|
12
|
+
MHV,
|
13
|
+
PengRobinson76,
|
14
|
+
PengRobinson78,
|
15
|
+
QMR,
|
16
|
+
RKPR,
|
17
|
+
SoaveRedlichKwong,
|
18
|
+
)
|
19
|
+
|
20
|
+
|
21
|
+
__all__ = [
|
22
|
+
"yaeos_c",
|
23
|
+
"SoaveRedlichKwong",
|
24
|
+
"PengRobinson76",
|
25
|
+
"PengRobinson78",
|
26
|
+
"RKPR",
|
27
|
+
"QMR",
|
28
|
+
"NRTL",
|
29
|
+
"MHV",
|
30
|
+
]
|
yaeos/core.py
ADDED
@@ -0,0 +1,557 @@
|
|
1
|
+
"""yaeos Python API core module.
|
2
|
+
|
3
|
+
ArModel and GeModel abstract classes definition. Also, the implementation of
|
4
|
+
the models' thermoprops methods.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from abc import ABC
|
8
|
+
from typing import Union
|
9
|
+
|
10
|
+
import numpy as np
|
11
|
+
|
12
|
+
from yaeos.lib import yaeos_c
|
13
|
+
|
14
|
+
|
15
|
+
class GeModel(ABC):
|
16
|
+
"""Excess Gibbs (Ge) model abstract class."""
|
17
|
+
|
18
|
+
def __del__(self) -> None:
|
19
|
+
"""Delete the model from the available models list (Fortran side)."""
|
20
|
+
yaeos_c.make_available_ge_models_list(self.id)
|
21
|
+
|
22
|
+
|
23
|
+
class ArModel(ABC):
|
24
|
+
"""Residual Helmholtz (Ar) model abstract class."""
|
25
|
+
|
26
|
+
def lnphi_vt(
|
27
|
+
self,
|
28
|
+
moles,
|
29
|
+
volume: float,
|
30
|
+
temperature: float,
|
31
|
+
dt: bool = False,
|
32
|
+
dp: bool = False,
|
33
|
+
dn: bool = False,
|
34
|
+
) -> Union[np.ndarray, tuple[np.ndarray, dict]]:
|
35
|
+
r"""Calculate fugacity coefficent given volume and temperature.
|
36
|
+
|
37
|
+
Calculate :math:`ln \phi_i(n,V,T)` and its derivatives with respect to
|
38
|
+
temperature, pressure and moles number.
|
39
|
+
|
40
|
+
Parameters
|
41
|
+
----------
|
42
|
+
moles : array_like
|
43
|
+
Moles number vector [mol]
|
44
|
+
volume : float
|
45
|
+
Volume [L]
|
46
|
+
temperature : float
|
47
|
+
Temperature [K]
|
48
|
+
dt : bool, optional
|
49
|
+
Calculate temperature derivative, by default False
|
50
|
+
dp : bool, optional
|
51
|
+
Calculate pressure derivative, by default False
|
52
|
+
dn : bool, optional
|
53
|
+
Calculate moles derivative, by default False
|
54
|
+
|
55
|
+
Returns
|
56
|
+
-------
|
57
|
+
Union[np.ndarray, tuple[np.ndarray, dict]]
|
58
|
+
:math:`ln \phi_i(n,V,T)` vector or tuple with
|
59
|
+
:math:`ln \phi_i(n,V,T)` vector and derivatives dictionary if any
|
60
|
+
derivative is asked
|
61
|
+
|
62
|
+
Example
|
63
|
+
-------
|
64
|
+
.. code-block:: python
|
65
|
+
|
66
|
+
import numpy as np
|
67
|
+
|
68
|
+
from yaeos import PengRobinson76
|
69
|
+
|
70
|
+
|
71
|
+
tc = np.array([320.0, 375.0]) # critical temperatures [K]
|
72
|
+
pc = np.array([45.0, 60.0]) # critical pressures [bar]
|
73
|
+
w = np.array([0.0123, 0.045]) # acentric factors
|
74
|
+
|
75
|
+
model = PengRobinson76(tc, pc, w)
|
76
|
+
|
77
|
+
# Evaluating ln_phi only
|
78
|
+
# will print: [-1.45216274 -2.01044828]
|
79
|
+
|
80
|
+
print(model.lnphi_vt([5.0, 5.6], 1.0, 300.0))
|
81
|
+
|
82
|
+
# Asking for derivatives
|
83
|
+
# will print:
|
84
|
+
# (
|
85
|
+
# array([-1.45216274, -2.01044828]),
|
86
|
+
# {'dt': array([0.01400063, 0.01923493]), 'dp': None, 'dn': None}
|
87
|
+
# )
|
88
|
+
|
89
|
+
print(model.lnphi_vt([5.0, 5.6], 1.0, 300.0, dt=True)
|
90
|
+
"""
|
91
|
+
nc = len(moles)
|
92
|
+
|
93
|
+
dt = np.empty(nc, order="F") if dt else None
|
94
|
+
dp = np.empty(nc, order="F") if dp else None
|
95
|
+
dn = np.empty((nc, nc), order="F") if dn else None
|
96
|
+
|
97
|
+
res = yaeos_c.lnphi_vt(
|
98
|
+
self.id,
|
99
|
+
moles,
|
100
|
+
volume,
|
101
|
+
temperature,
|
102
|
+
dlnphidt=dt,
|
103
|
+
dlnphidp=dp,
|
104
|
+
dlnphidn=dn,
|
105
|
+
)
|
106
|
+
|
107
|
+
if dt is None and dp is None and dn is None:
|
108
|
+
...
|
109
|
+
else:
|
110
|
+
res = (res, {"dt": dt, "dp": dp, "dn": dn})
|
111
|
+
return res
|
112
|
+
|
113
|
+
def lnphi_pt(
|
114
|
+
self,
|
115
|
+
moles,
|
116
|
+
pressure: float,
|
117
|
+
temperature: float,
|
118
|
+
root: str = "stable",
|
119
|
+
dt: bool = False,
|
120
|
+
dp: bool = False,
|
121
|
+
dn: bool = False,
|
122
|
+
) -> Union[np.ndarray, tuple[np.ndarray, dict]]:
|
123
|
+
r"""Calculate fugacity coefficent given pressure and temperature.
|
124
|
+
|
125
|
+
Calculate :math:`ln \phi_i(n,P,T)` and its derivatives with respect to
|
126
|
+
temperature, pressure and moles number.
|
127
|
+
|
128
|
+
Parameters
|
129
|
+
----------
|
130
|
+
moles : array_like
|
131
|
+
Moles number vector [mol]
|
132
|
+
pressure : float
|
133
|
+
Pressure [bar]
|
134
|
+
temperature : float
|
135
|
+
Temperature [K]
|
136
|
+
root : str, optional
|
137
|
+
Volume root, use: "liquid", "vapor" or "stable", by default
|
138
|
+
"stable"
|
139
|
+
dt : bool, optional
|
140
|
+
Calculate temperature derivative, by default False
|
141
|
+
dp : bool, optional
|
142
|
+
Calculate pressure derivative, by default False
|
143
|
+
dn : bool, optional
|
144
|
+
Calculate moles derivative, by default False
|
145
|
+
|
146
|
+
Returns
|
147
|
+
-------
|
148
|
+
Union[np.ndarray, tuple[np.ndarray, dict]]
|
149
|
+
:math:`ln \phi_i(n,P,T)` vector or tuple with
|
150
|
+
:math:`ln \phi_i(n,P,T)` vector and derivatives dictionary if any
|
151
|
+
derivative is asked
|
152
|
+
|
153
|
+
Example
|
154
|
+
-------
|
155
|
+
.. code-block:: python
|
156
|
+
|
157
|
+
import numpy as np
|
158
|
+
|
159
|
+
from yaeos import PengRobinson76
|
160
|
+
|
161
|
+
|
162
|
+
tc = np.array([320.0, 375.0]) # critical temperatures [K]
|
163
|
+
pc = np.array([45.0, 60.0]) # critical pressures [bar]
|
164
|
+
w = np.array([0.0123, 0.045]) # acentric factors
|
165
|
+
|
166
|
+
model = PengRobinson76(tc, pc, w)
|
167
|
+
|
168
|
+
# Evaluating ln_phi only
|
169
|
+
# will print: [-0.10288733 -0.11909807]
|
170
|
+
|
171
|
+
print(model.lnphi_pt([5.0, 5.6], 10.0, 300.0))
|
172
|
+
|
173
|
+
# Asking for derivatives
|
174
|
+
# will print:
|
175
|
+
# (
|
176
|
+
# array([-0.10288733, -0.11909807]),
|
177
|
+
# {'dt': array([0.00094892, 0.00108809]), 'dp': None, 'dn': None}
|
178
|
+
# )
|
179
|
+
|
180
|
+
print(model.lnphi_pt([5.0, 5.6], 10.0, 300.0, dt=True)
|
181
|
+
"""
|
182
|
+
nc = len(moles)
|
183
|
+
|
184
|
+
dt = np.empty(nc, order="F") if dt else None
|
185
|
+
dp = np.empty(nc, order="F") if dp else None
|
186
|
+
dn = np.empty((nc, nc), order="F") if dn else None
|
187
|
+
|
188
|
+
res = yaeos_c.lnphi_pt(
|
189
|
+
self.id,
|
190
|
+
moles,
|
191
|
+
pressure,
|
192
|
+
temperature,
|
193
|
+
root,
|
194
|
+
dlnphidt=dt,
|
195
|
+
dlnphidp=dp,
|
196
|
+
dlnphidn=dn,
|
197
|
+
)
|
198
|
+
|
199
|
+
if dt is None and dp is None and dn is None:
|
200
|
+
...
|
201
|
+
else:
|
202
|
+
res = (res, {"dt": dt, "dp": dp, "dn": dn})
|
203
|
+
return res
|
204
|
+
|
205
|
+
def pressure(
|
206
|
+
self,
|
207
|
+
moles,
|
208
|
+
volume: float,
|
209
|
+
temperature: float,
|
210
|
+
dv: bool = False,
|
211
|
+
dt: bool = False,
|
212
|
+
dn: bool = False,
|
213
|
+
) -> Union[float, tuple[float, dict]]:
|
214
|
+
"""Calculate pressure given volume and temperature [bar].
|
215
|
+
|
216
|
+
Calculate :math:`P(n,V,T)` and its derivatives with respect to
|
217
|
+
volume, temperature and moles number.
|
218
|
+
|
219
|
+
Parameters
|
220
|
+
----------
|
221
|
+
moles : array_like
|
222
|
+
Moles number vector [mol]
|
223
|
+
volume : float
|
224
|
+
Volume [L]
|
225
|
+
temperature : float
|
226
|
+
Temperature [K]
|
227
|
+
dv : bool, optional
|
228
|
+
Calculate volume derivative, by default False
|
229
|
+
dt : bool, optional
|
230
|
+
Calculate temperature derivative, by default False
|
231
|
+
dn : bool, optional
|
232
|
+
Calculate moles derivative, by default False
|
233
|
+
|
234
|
+
Returns
|
235
|
+
-------
|
236
|
+
Union[float, tuple[float, dict]]
|
237
|
+
Pressure or tuple with Presure and derivatives dictionary if any
|
238
|
+
derivative is asked [bar]
|
239
|
+
|
240
|
+
Example
|
241
|
+
-------
|
242
|
+
.. code-block:: python
|
243
|
+
|
244
|
+
import numpy as np
|
245
|
+
|
246
|
+
from yaeos import PengRobinson76
|
247
|
+
|
248
|
+
|
249
|
+
tc = np.array([320.0, 375.0]) # critical temperatures [K]
|
250
|
+
pc = np.array([45.0, 60.0]) # critical pressures [bar]
|
251
|
+
w = np.array([0.0123, 0.045]) # acentric factors
|
252
|
+
|
253
|
+
model = PengRobinson76(tc, pc, w)
|
254
|
+
|
255
|
+
# Evaluating pressure only
|
256
|
+
# will print: 16.011985733846956
|
257
|
+
|
258
|
+
print(model.pressure(np.array([5.0, 5.6]), 2.0, 300.0))
|
259
|
+
|
260
|
+
# Asking for derivatives
|
261
|
+
# will print:
|
262
|
+
# (
|
263
|
+
# 16.011985733846956,
|
264
|
+
# {'dv': None, 'dt': np.float64(0.7664672352866752), 'dn': None}
|
265
|
+
# )
|
266
|
+
|
267
|
+
print(model.pressure(np.array([5.0, 5.6]), 2.0, 300.0, dt=True))
|
268
|
+
"""
|
269
|
+
nc = len(moles)
|
270
|
+
|
271
|
+
dv = np.empty(1, order="F") if dv else None
|
272
|
+
dt = np.empty(1, order="F") if dt else None
|
273
|
+
dn = np.empty(nc, order="F") if dn else None
|
274
|
+
|
275
|
+
res = yaeos_c.pressure(
|
276
|
+
self.id, moles, volume, temperature, dpdv=dv, dpdt=dt, dpdn=dn
|
277
|
+
)
|
278
|
+
|
279
|
+
if dt is None and dv is None and dn is None:
|
280
|
+
...
|
281
|
+
else:
|
282
|
+
res = (
|
283
|
+
res,
|
284
|
+
{
|
285
|
+
"dv": dv if dv is None else dv[0],
|
286
|
+
"dt": dt if dt is None else dt[0],
|
287
|
+
"dn": dn,
|
288
|
+
},
|
289
|
+
)
|
290
|
+
return res
|
291
|
+
|
292
|
+
def volume(
|
293
|
+
self, moles, pressure: float, temperature: float, root: str = "stable"
|
294
|
+
) -> float:
|
295
|
+
"""Calculate volume given pressure and temperature [L].
|
296
|
+
|
297
|
+
Parameters
|
298
|
+
----------
|
299
|
+
moles : array_like
|
300
|
+
Moles number vector [mol]
|
301
|
+
pressure : float
|
302
|
+
Pressure [bar]
|
303
|
+
temperature : float
|
304
|
+
Temperature [K]
|
305
|
+
root : str, optional
|
306
|
+
Volume root, use: "liquid", "vapor" or "stable", by default
|
307
|
+
"stable"
|
308
|
+
|
309
|
+
Returns
|
310
|
+
-------
|
311
|
+
float
|
312
|
+
Volume [L]
|
313
|
+
|
314
|
+
Example
|
315
|
+
-------
|
316
|
+
.. code-block:: python
|
317
|
+
|
318
|
+
import numpy as np
|
319
|
+
|
320
|
+
from yaeos import PengRobinson76
|
321
|
+
|
322
|
+
|
323
|
+
tc = np.array([320.0, 375.0]) # critical temperatures [K]
|
324
|
+
pc = np.array([45.0, 60.0]) # critical pressures [bar]
|
325
|
+
w = np.array([0.0123, 0.045]) # acentric factors
|
326
|
+
|
327
|
+
model = PengRobinson76(tc, pc, w)
|
328
|
+
|
329
|
+
# Evaluating stable root volume
|
330
|
+
# will print: 23.373902973572587
|
331
|
+
|
332
|
+
print(model.volume(np.array([5.0, 5.6]), 10.0, 300.0))
|
333
|
+
|
334
|
+
# Liquid root volume (not stable)
|
335
|
+
# will print: 0.8156388756398074
|
336
|
+
|
337
|
+
print(model.volume(np.array([5.0, 5.6]), 10.0, 300.0, "liquid"))
|
338
|
+
"""
|
339
|
+
res = yaeos_c.volume(self.id, moles, pressure, temperature, root)
|
340
|
+
return res
|
341
|
+
|
342
|
+
def flash_pt(self, z, pressure: float, temperature: float) -> dict:
|
343
|
+
"""Two-phase split with specification of temperature and pressure.
|
344
|
+
|
345
|
+
Parameters
|
346
|
+
----------
|
347
|
+
z : array_like
|
348
|
+
Global mole fractions
|
349
|
+
pressure : float
|
350
|
+
Pressure [bar]
|
351
|
+
temperature : float
|
352
|
+
Temperature [K]
|
353
|
+
|
354
|
+
Returns
|
355
|
+
-------
|
356
|
+
dict
|
357
|
+
Flash result dictionary with keys:
|
358
|
+
- x: heavy phase mole fractions
|
359
|
+
- y: light phase mole fractions
|
360
|
+
- Vx: heavy phase volume [L]
|
361
|
+
- Vy: light phase volume [L]
|
362
|
+
- P: pressure [bar]
|
363
|
+
- T: temperature [K]
|
364
|
+
- beta: light phase fraction
|
365
|
+
|
366
|
+
Example
|
367
|
+
-------
|
368
|
+
.. code-block:: python
|
369
|
+
|
370
|
+
import numpy as np
|
371
|
+
|
372
|
+
from yaeos import PengRobinson76
|
373
|
+
|
374
|
+
|
375
|
+
tc = np.array([369.83, 507.6]) # critical temperatures [K]
|
376
|
+
pc = np.array([42.48, 30.25]) # critical pressures [bar]
|
377
|
+
w = np.array([0.152291, 0.301261]) # acentric factors
|
378
|
+
|
379
|
+
model = PengRobinson76(tc, pc, w)
|
380
|
+
|
381
|
+
# Flash calculation
|
382
|
+
# will print:
|
383
|
+
# {
|
384
|
+
# 'x': array([0.3008742, 0.6991258]),
|
385
|
+
# 'y': array([0.85437317, 0.14562683]),
|
386
|
+
# 'Vx': 0.12742569165483714,
|
387
|
+
# 'Vy': 3.218831515959867,
|
388
|
+
# 'P': 8.0,
|
389
|
+
# 'T': 350.0,
|
390
|
+
# 'beta': 0.35975821044266726
|
391
|
+
# }
|
392
|
+
|
393
|
+
print(model.flash_pt([0.5, 0.5], 8.0, 350.0))
|
394
|
+
"""
|
395
|
+
x, y, pressure, temperature, volume_x, volume_y, beta = yaeos_c.flash(
|
396
|
+
self.id, z, p=pressure, t=temperature
|
397
|
+
)
|
398
|
+
|
399
|
+
flash_result = {
|
400
|
+
"x": x,
|
401
|
+
"y": y,
|
402
|
+
"Vx": volume_x,
|
403
|
+
"Vy": volume_y,
|
404
|
+
"P": pressure,
|
405
|
+
"T": temperature,
|
406
|
+
"beta": beta,
|
407
|
+
}
|
408
|
+
|
409
|
+
return flash_result
|
410
|
+
|
411
|
+
def saturation_pressure(
|
412
|
+
self, z, temperature: float, kind: str = "bubble"
|
413
|
+
) -> dict:
|
414
|
+
"""Saturation pressure at specified temperature.
|
415
|
+
|
416
|
+
Arguments
|
417
|
+
---------
|
418
|
+
z: array_like
|
419
|
+
Global molar fractions
|
420
|
+
temperature: float
|
421
|
+
Temperature [K]
|
422
|
+
kind: str, optional
|
423
|
+
Kind of saturation point, defaults to "bubble". Options are
|
424
|
+
- "bubble"
|
425
|
+
- "dew"
|
426
|
+
- "liquid-liquid"
|
427
|
+
|
428
|
+
Returns
|
429
|
+
-------
|
430
|
+
dict
|
431
|
+
Saturation pressure calculation result dictionary with keys:
|
432
|
+
- x: heavy phase mole fractions
|
433
|
+
- y: light phase mole fractions
|
434
|
+
- Vx: heavy phase volume [L]
|
435
|
+
- Vy: light phase volume [L]
|
436
|
+
- P: pressure [bar]
|
437
|
+
- T: temperature [K]
|
438
|
+
- beta: light phase fraction
|
439
|
+
|
440
|
+
Example
|
441
|
+
-------
|
442
|
+
.. code-block:: python
|
443
|
+
|
444
|
+
import numpy as np
|
445
|
+
|
446
|
+
from yaeos import PengRobinson76
|
447
|
+
|
448
|
+
|
449
|
+
tc = np.array([369.83, 507.6]) # critical temperatures [K]
|
450
|
+
pc = np.array([42.48, 30.25]) # critical pressures [bar]
|
451
|
+
w = np.array([0.152291, 0.301261]) # acentric factors
|
452
|
+
|
453
|
+
model = PengRobinson76(tc, pc, w)
|
454
|
+
|
455
|
+
# Saturation pressure calculation
|
456
|
+
# will print:
|
457
|
+
# {
|
458
|
+
# 'x': array([0.5, 0.5]),
|
459
|
+
# 'y': array([0.9210035 , 0.07899651]),
|
460
|
+
# 'Vx': 0.11974125553488875,
|
461
|
+
# 'Vy': 1.849650524323853,
|
462
|
+
# 'T': 350.0,
|
463
|
+
# 'P': 12.990142036059941,
|
464
|
+
# 'beta': 0.0
|
465
|
+
# }
|
466
|
+
|
467
|
+
print(model.saturation_pressure(np.array([0.5, 0.5]), 350.0))
|
468
|
+
"""
|
469
|
+
p, x, y, volume_x, volume_y, beta = yaeos_c.saturation_pressure(
|
470
|
+
self.id, z, temperature, kind
|
471
|
+
)
|
472
|
+
|
473
|
+
return {
|
474
|
+
"x": x,
|
475
|
+
"y": y,
|
476
|
+
"Vx": volume_x,
|
477
|
+
"Vy": volume_y,
|
478
|
+
"T": temperature,
|
479
|
+
"P": p,
|
480
|
+
"beta": beta,
|
481
|
+
}
|
482
|
+
|
483
|
+
def phase_envelope_pt(
|
484
|
+
self,
|
485
|
+
z,
|
486
|
+
kind: str = "bubble",
|
487
|
+
max_points: int = 300,
|
488
|
+
t0: float = 150.0,
|
489
|
+
p0: float = 1.0,
|
490
|
+
) -> dict:
|
491
|
+
"""Two phase envelope calculation (PT).
|
492
|
+
|
493
|
+
Parameters
|
494
|
+
----------
|
495
|
+
z : array_like
|
496
|
+
Global mole fractions
|
497
|
+
kind : str, optional
|
498
|
+
Kind of saturation point to start the envelope calculation,
|
499
|
+
defaults to "bubble". Options are
|
500
|
+
- "bubble"
|
501
|
+
- "dew"
|
502
|
+
max_points : int, optional
|
503
|
+
Envelope's maximum points to calculate (T, P), by default 300
|
504
|
+
t0 : float, optional
|
505
|
+
Initial guess for temperature [K] for the saturation point of kind:
|
506
|
+
`kind`, by default 150.0
|
507
|
+
p0 : float, optional
|
508
|
+
Initial guess for pressure [bar] for the saturation point of kind:
|
509
|
+
`kind`, by default 1.0
|
510
|
+
|
511
|
+
Returns
|
512
|
+
-------
|
513
|
+
dict
|
514
|
+
Envelope calculation result dictionary with keys:
|
515
|
+
- Ts: temperatures [K]
|
516
|
+
- Ps: pressures [bar]
|
517
|
+
- Tcs: critical temperatures [K]
|
518
|
+
- Pcs: critical pressures [bar]
|
519
|
+
|
520
|
+
Example
|
521
|
+
-------
|
522
|
+
.. code-block:: python
|
523
|
+
|
524
|
+
import numpy as np
|
525
|
+
|
526
|
+
import matplotlib.pyplot as plt
|
527
|
+
|
528
|
+
from yaeos import PengRobinson76
|
529
|
+
|
530
|
+
|
531
|
+
tc = np.array([369.83, 507.6]) # critical temperatures [K]
|
532
|
+
pc = np.array([42.48, 30.25]) # critical pressures [bar]
|
533
|
+
w = np.array([0.152291, 0.301261]) # acentric factors
|
534
|
+
|
535
|
+
model = PengRobinson76(tc, pc, w)
|
536
|
+
|
537
|
+
# Two phase envelope calculation and plot
|
538
|
+
env = model.phase_envelope_pt(
|
539
|
+
np.array([0.5, 0.5]),
|
540
|
+
t0=150.0,
|
541
|
+
p0=1.0
|
542
|
+
)
|
543
|
+
|
544
|
+
plt.plot(env["Ts"], env["Ps"])
|
545
|
+
plt.scatter(env["Tcs"], env["Pcs"])
|
546
|
+
"""
|
547
|
+
ts, ps, tcs, pcs = yaeos_c.pt2_phase_envelope(
|
548
|
+
self.id, z, kind=kind, t0=t0, p0=p0, max_points=max_points
|
549
|
+
)
|
550
|
+
|
551
|
+
res = {"Ts": ts, "Ps": ps, "Tcs": tcs, "Pcs": pcs}
|
552
|
+
|
553
|
+
return res
|
554
|
+
|
555
|
+
def __del__(self) -> None:
|
556
|
+
"""Delete the model from the available models list (Fortran side)."""
|
557
|
+
yaeos_c.make_available_ar_models_list(self.id)
|
yaeos/lib/__init__.py
ADDED
Binary file
|
yaeos/models/__init__.py
ADDED
@@ -0,0 +1,22 @@
|
|
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
|
+
|
8
|
+
- residual_helmholtz: Residual Helmholtz energy models
|
9
|
+
- Cubic EoS:
|
10
|
+
- PengRobinson76: Peng-Robinson model (1976)
|
11
|
+
- PengRobinson78: Peng-Robinson model (1978)
|
12
|
+
- SoaveRedlichKwong: Soave-Redlich-Kwong model
|
13
|
+
- RKPR: RKPR model
|
14
|
+
- Mixing rules: mixing rules for cubic EoS
|
15
|
+
- QMR: cuadratic mixing rule
|
16
|
+
- MHV: modified Huron-Vidal mixing rule
|
17
|
+
"""
|
18
|
+
|
19
|
+
from . import excess_gibbs, residual_helmholtz
|
20
|
+
|
21
|
+
|
22
|
+
__all__ = ["excess_gibbs", "residual_helmholtz"]
|
@@ -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,19 @@
|
|
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
|
+
- Mixing rules: mixing rules for cubic EoS
|
12
|
+
- QMR: cuadratic mixing rule
|
13
|
+
- MHV: modified Huron-Vidal mixing rule
|
14
|
+
"""
|
15
|
+
|
16
|
+
from . import cubic_eos
|
17
|
+
|
18
|
+
|
19
|
+
__all__ = ["cubic_eos"]
|
@@ -0,0 +1,34 @@
|
|
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
|
+
PengRobinson76,
|
18
|
+
PengRobinson78,
|
19
|
+
RKPR,
|
20
|
+
SoaveRedlichKwong,
|
21
|
+
)
|
22
|
+
from .mixing_rules import CubicMixRule, MHV, QMR
|
23
|
+
|
24
|
+
|
25
|
+
__all__ = [
|
26
|
+
"CubicEoS",
|
27
|
+
"PengRobinson76",
|
28
|
+
"PengRobinson78",
|
29
|
+
"SoaveRedlichKwong",
|
30
|
+
"RKPR",
|
31
|
+
"CubicMixRule",
|
32
|
+
"QMR",
|
33
|
+
"MHV",
|
34
|
+
]
|
@@ -0,0 +1,335 @@
|
|
1
|
+
"""Cubic EoS implementations module."""
|
2
|
+
|
3
|
+
from yaeos.core import ArModel
|
4
|
+
from yaeos.lib import yaeos_c
|
5
|
+
from yaeos.models.residual_helmholtz.cubic_eos.mixing_rules import CubicMixRule
|
6
|
+
|
7
|
+
|
8
|
+
class CubicEoS(ArModel):
|
9
|
+
"""Cubic equation of state base class.
|
10
|
+
|
11
|
+
Parameters
|
12
|
+
----------
|
13
|
+
critical_temperatures : array_like
|
14
|
+
Critical temperatures vector [K]
|
15
|
+
critical_pressures : array_like
|
16
|
+
Critical pressures vector [bar]
|
17
|
+
acentric_factors : array_like
|
18
|
+
Acentric factors vector
|
19
|
+
|
20
|
+
Attributes
|
21
|
+
----------
|
22
|
+
nc : int
|
23
|
+
Number of components
|
24
|
+
tc : array_like
|
25
|
+
Critical temperatures vector [K]
|
26
|
+
pc : array_like
|
27
|
+
Critical pressures vector [bar]
|
28
|
+
w : array_like
|
29
|
+
Acentric factors vector
|
30
|
+
"""
|
31
|
+
|
32
|
+
def __init__(
|
33
|
+
self,
|
34
|
+
critical_temperatures,
|
35
|
+
critical_pressures,
|
36
|
+
acentric_factors,
|
37
|
+
) -> None:
|
38
|
+
nc = len(critical_temperatures)
|
39
|
+
self.nc = nc
|
40
|
+
self.tc = critical_temperatures
|
41
|
+
self.pc = critical_pressures
|
42
|
+
self.w = acentric_factors
|
43
|
+
|
44
|
+
def set_mixrule(self, mixrule: CubicMixRule) -> None:
|
45
|
+
"""Set the mixing rule for the EoS.
|
46
|
+
|
47
|
+
Parameters
|
48
|
+
----------
|
49
|
+
mixrule : CubicMixRule
|
50
|
+
Mixing rule object
|
51
|
+
"""
|
52
|
+
self.mixrule = mixrule
|
53
|
+
self.mixrule.set_mixrule(self.id)
|
54
|
+
|
55
|
+
|
56
|
+
class PengRobinson76(CubicEoS):
|
57
|
+
"""Peng-Robinson 1976 cubic equation of state.
|
58
|
+
|
59
|
+
Parameters
|
60
|
+
----------
|
61
|
+
critical_temperatures : array_like
|
62
|
+
Critical temperatures vector [K]
|
63
|
+
critical_pressures : array_like
|
64
|
+
Critical pressures vector [bar]
|
65
|
+
acentric_factors : array_like
|
66
|
+
Acentric factors vector
|
67
|
+
mixrule : CubicMixRule, optional
|
68
|
+
Mixing rule object. If no provided the quadratric mixing rule (QMR)
|
69
|
+
with zero for kij and lij parameters is set, by default None
|
70
|
+
|
71
|
+
Attributes
|
72
|
+
----------
|
73
|
+
nc : int
|
74
|
+
Number of components
|
75
|
+
critical_temperatures : array_like
|
76
|
+
Critical temperatures vector [K]
|
77
|
+
critical_pressures : array_like
|
78
|
+
Critical pressures vector [bar]
|
79
|
+
acentric_factors : array_like
|
80
|
+
Acentric factors vector
|
81
|
+
id : int
|
82
|
+
EoS identifier
|
83
|
+
mixrule : CubicMixRule
|
84
|
+
Mixing rule object
|
85
|
+
|
86
|
+
Example
|
87
|
+
-------
|
88
|
+
.. code-block:: python
|
89
|
+
|
90
|
+
from yaeos import PengRobinson76
|
91
|
+
|
92
|
+
tc = [190.56, 305.32] # Critical temperatures [K]
|
93
|
+
pc = [45.99, 48.72] # Critical pressures [bar]
|
94
|
+
w = [0.0115, 0.0985] # Acentric factors
|
95
|
+
|
96
|
+
pr76 = PengRobinson76(tc, pc, w)
|
97
|
+
"""
|
98
|
+
|
99
|
+
name = "PengRobinson76"
|
100
|
+
|
101
|
+
def __init__(
|
102
|
+
self,
|
103
|
+
critical_temperatures,
|
104
|
+
critical_pressures,
|
105
|
+
acentric_factors,
|
106
|
+
mixrule: CubicMixRule = None,
|
107
|
+
) -> None:
|
108
|
+
|
109
|
+
super(PengRobinson76, self).__init__(
|
110
|
+
critical_temperatures,
|
111
|
+
critical_pressures,
|
112
|
+
acentric_factors,
|
113
|
+
)
|
114
|
+
self.id = yaeos_c.pr76(self.tc, self.pc, self.w)
|
115
|
+
self.mixrule = mixrule
|
116
|
+
if mixrule:
|
117
|
+
mixrule.set_mixrule(self.id)
|
118
|
+
|
119
|
+
|
120
|
+
class PengRobinson78(CubicEoS):
|
121
|
+
"""Peng-Robinson 1978 cubic equation of state.
|
122
|
+
|
123
|
+
Parameters
|
124
|
+
----------
|
125
|
+
critical_temperatures : array_like
|
126
|
+
Critical temperatures vector [K]
|
127
|
+
critical_pressures : array_like
|
128
|
+
Critical pressures vector [bar]
|
129
|
+
acentric_factors : array_like
|
130
|
+
Acentric factors vector
|
131
|
+
mixrule : CubicMixRule, optional
|
132
|
+
Mixing rule object. If no provided the quadratric mixing rule (QMR)
|
133
|
+
with zero for kij and lij parameters is set, by default None
|
134
|
+
|
135
|
+
Attributes
|
136
|
+
----------
|
137
|
+
nc : int
|
138
|
+
Number of components
|
139
|
+
critical_temperatures : array_like
|
140
|
+
Critical temperatures vector [K]
|
141
|
+
critical_pressures : array_like
|
142
|
+
Critical pressures vector [bar]
|
143
|
+
acentric_factors : array_like
|
144
|
+
Acentric factors vector
|
145
|
+
id : int
|
146
|
+
EoS identifier
|
147
|
+
mixrule : CubicMixRule
|
148
|
+
Mixing rule object
|
149
|
+
|
150
|
+
Example
|
151
|
+
-------
|
152
|
+
.. code-block:: python
|
153
|
+
|
154
|
+
from yaeos import PengRobinson78
|
155
|
+
|
156
|
+
tc = [190.56, 305.32] # Critical temperatures [K]
|
157
|
+
pc = [45.99, 48.72] # Critical pressures [bar]
|
158
|
+
w = [0.0115, 0.0985] # Acentric factors
|
159
|
+
|
160
|
+
pr78 = PengRobinson78(tc, pc, w)
|
161
|
+
"""
|
162
|
+
|
163
|
+
name = "PengRobinson78"
|
164
|
+
|
165
|
+
def __init__(
|
166
|
+
self,
|
167
|
+
critical_temperatures,
|
168
|
+
critical_pressures,
|
169
|
+
acentric_factors,
|
170
|
+
mixrule: CubicMixRule = None,
|
171
|
+
) -> None:
|
172
|
+
|
173
|
+
super(PengRobinson78, self).__init__(
|
174
|
+
critical_temperatures,
|
175
|
+
critical_pressures,
|
176
|
+
acentric_factors,
|
177
|
+
)
|
178
|
+
self.id = yaeos_c.pr78(self.tc, self.pc, self.w)
|
179
|
+
self.mixrule = mixrule
|
180
|
+
if mixrule:
|
181
|
+
mixrule.set_mixrule(self.id)
|
182
|
+
|
183
|
+
|
184
|
+
class SoaveRedlichKwong(CubicEoS):
|
185
|
+
"""Soave-Redlich-Kwong cubic equation of state.
|
186
|
+
|
187
|
+
Parameters
|
188
|
+
----------
|
189
|
+
critical_temperatures : array_like
|
190
|
+
Critical temperatures vector [K]
|
191
|
+
critical_pressures : array_like
|
192
|
+
Critical pressures vector [bar]
|
193
|
+
acentric_factors : array_like
|
194
|
+
Acentric factors vector
|
195
|
+
mixrule : CubicMixRule, optional
|
196
|
+
Mixing rule object. If no provided the quadratric mixing rule (QMR)
|
197
|
+
with zero for kij and lij parameters is set, by default None
|
198
|
+
|
199
|
+
Attributes
|
200
|
+
----------
|
201
|
+
nc : int
|
202
|
+
Number of components
|
203
|
+
critical_temperatures : array_like
|
204
|
+
Critical temperatures vector [K]
|
205
|
+
critical_pressures : array_like
|
206
|
+
Critical pressures vector [bar]
|
207
|
+
acentric_factors : array_like
|
208
|
+
Acentric factors vector
|
209
|
+
id : int
|
210
|
+
EoS identifier
|
211
|
+
mixrule : CubicMixRule
|
212
|
+
Mixing rule object
|
213
|
+
|
214
|
+
Example
|
215
|
+
-------
|
216
|
+
.. code-block:: python
|
217
|
+
|
218
|
+
from yaeos import SoaveRedlichKwong
|
219
|
+
|
220
|
+
tc = [190.56, 305.32] # Critical temperatures [K]
|
221
|
+
pc = [45.99, 48.72] # Critical pressures [bar]
|
222
|
+
w = [0.0115, 0.0985] # Acentric factors
|
223
|
+
|
224
|
+
srk = SoaveRedlichKwong(tc, pc, w)
|
225
|
+
"""
|
226
|
+
|
227
|
+
name = "SoaveReldichKwong"
|
228
|
+
|
229
|
+
def __init__(
|
230
|
+
self,
|
231
|
+
critical_temperatures,
|
232
|
+
critical_pressures,
|
233
|
+
acentric_factors,
|
234
|
+
mixrule: CubicMixRule = None,
|
235
|
+
) -> None:
|
236
|
+
|
237
|
+
super(SoaveRedlichKwong, self).__init__(
|
238
|
+
critical_temperatures,
|
239
|
+
critical_pressures,
|
240
|
+
acentric_factors,
|
241
|
+
)
|
242
|
+
self.id = yaeos_c.srk(self.tc, self.pc, self.w)
|
243
|
+
self.mixrule = mixrule
|
244
|
+
if mixrule:
|
245
|
+
mixrule.set_mixrule(self.id)
|
246
|
+
|
247
|
+
|
248
|
+
class RKPR(CubicEoS):
|
249
|
+
"""RKPR cubic equation of state.
|
250
|
+
|
251
|
+
Parameters
|
252
|
+
----------
|
253
|
+
critical_temperatures : array_like
|
254
|
+
Critical temperatures vector [K]
|
255
|
+
critical_pressures : array_like
|
256
|
+
Critical pressures vector [bar]
|
257
|
+
acentric_factors : array_like
|
258
|
+
Acentric factors vector
|
259
|
+
critical_z : array_like
|
260
|
+
Critical compressibility factor vector
|
261
|
+
k : array_like, optional
|
262
|
+
k parameter, by default None
|
263
|
+
delta_1 : array_like, optional
|
264
|
+
delta_1 parameter, by default None
|
265
|
+
mixrule : CubicMixRule, optional
|
266
|
+
Mixing rule object. If no provided the quadratric mixing rule (QMR)
|
267
|
+
with zero for kij and lij parameters is set, by default None
|
268
|
+
|
269
|
+
Attributes
|
270
|
+
----------
|
271
|
+
nc : int
|
272
|
+
Number of components
|
273
|
+
critical_temperatures : array_like
|
274
|
+
Critical temperatures vector [K]
|
275
|
+
critical_pressures : array_like
|
276
|
+
Critical pressures vector [bar]
|
277
|
+
acentric_factors : array_like
|
278
|
+
Acentric factors vector
|
279
|
+
zc : array_like
|
280
|
+
Critical compressibility factor vector
|
281
|
+
id : int
|
282
|
+
EoS identifier
|
283
|
+
mixrule : CubicMixRule
|
284
|
+
Mixing rule object
|
285
|
+
|
286
|
+
Example
|
287
|
+
-------
|
288
|
+
.. code-block:: python
|
289
|
+
|
290
|
+
from yaeos import RKPR
|
291
|
+
|
292
|
+
tc = [190.56, 305.32] # Critical temperatures [K]
|
293
|
+
pc = [45.99, 48.72] # Critical pressures [bar]
|
294
|
+
w = [0.0115, 0.0985] # Acentric factors
|
295
|
+
zc = [0.27, 0.28] # Critical compressibility factor
|
296
|
+
|
297
|
+
rkpr = RKPR(tc, pc, w, zc)
|
298
|
+
"""
|
299
|
+
|
300
|
+
name = "RKPR"
|
301
|
+
|
302
|
+
def __init__(
|
303
|
+
self,
|
304
|
+
critical_temperatures,
|
305
|
+
critical_pressures,
|
306
|
+
acentric_factors,
|
307
|
+
critical_z,
|
308
|
+
k=None,
|
309
|
+
delta_1=None,
|
310
|
+
mixrule: CubicMixRule = None,
|
311
|
+
) -> None:
|
312
|
+
|
313
|
+
super(RKPR, self).__init__(
|
314
|
+
critical_temperatures,
|
315
|
+
critical_pressures,
|
316
|
+
acentric_factors,
|
317
|
+
)
|
318
|
+
self.zc = critical_z
|
319
|
+
|
320
|
+
match (k is None, delta_1 is None):
|
321
|
+
case (True, True):
|
322
|
+
self.id = yaeos_c.rkpr(self.tc, self.pc, self.w, self.zc)
|
323
|
+
case (False, True):
|
324
|
+
self.id = yaeos_c.rkpr(self.tc, self.pc, self.w, self.zc, k=k)
|
325
|
+
case (True, False):
|
326
|
+
self.id = yaeos_c.rkpr(
|
327
|
+
self.tc, self.pc, self.w, self.zc, delta_1=delta_1
|
328
|
+
)
|
329
|
+
case (False, False):
|
330
|
+
self.id = yaeos_c.rkpr(
|
331
|
+
self.tc, self.pc, self.w, self.zc, k=k, delta_1=delta_1
|
332
|
+
)
|
333
|
+
self.mixrule = mixrule
|
334
|
+
if mixrule:
|
335
|
+
mixrule.set_mixrule(self.id)
|
@@ -0,0 +1,138 @@
|
|
1
|
+
"""Cubic EoS mixing rules implementations module."""
|
2
|
+
|
3
|
+
from abc import ABC, abstractmethod
|
4
|
+
|
5
|
+
from yaeos.core import GeModel
|
6
|
+
from yaeos.lib import yaeos_c
|
7
|
+
|
8
|
+
|
9
|
+
class CubicMixRule(ABC):
|
10
|
+
"""Cubic mix rule abstract class."""
|
11
|
+
|
12
|
+
@abstractmethod
|
13
|
+
def set_mixrule(self, ar_model_id: int) -> None:
|
14
|
+
"""Set mix rule abstract method.
|
15
|
+
|
16
|
+
Changes the default mixing rule of the given cubic EoS model.
|
17
|
+
|
18
|
+
Parameters
|
19
|
+
----------
|
20
|
+
ar_model_id : int
|
21
|
+
ID of the cubic EoS model
|
22
|
+
|
23
|
+
Raises
|
24
|
+
------
|
25
|
+
NotImplementedError
|
26
|
+
Abstract error, this method must be implemented in the subclass
|
27
|
+
"""
|
28
|
+
raise NotImplementedError
|
29
|
+
|
30
|
+
|
31
|
+
class QMR(CubicMixRule):
|
32
|
+
"""Quadratic mixing rule.
|
33
|
+
|
34
|
+
Parameters
|
35
|
+
----------
|
36
|
+
kij : array_like
|
37
|
+
kij binary interaction parameters matrix
|
38
|
+
lij : array_like
|
39
|
+
lij binary interaction parameters matrix
|
40
|
+
|
41
|
+
Attributes
|
42
|
+
----------
|
43
|
+
kij : array_like
|
44
|
+
kij binary interaction parameters matrix
|
45
|
+
lij : array_like
|
46
|
+
lij binary interaction parameters matrix
|
47
|
+
|
48
|
+
Example
|
49
|
+
-------
|
50
|
+
.. code-block:: python
|
51
|
+
|
52
|
+
from yaeos import QMR, SoaveRedlichKwong
|
53
|
+
|
54
|
+
kij = [[0.0, 0.1], [0.1, 0.0]]
|
55
|
+
lij = [[0.0, 0.02], [0.02, 0.0]]
|
56
|
+
|
57
|
+
mixrule = QMR(kij, lij) # Quadratic mixing rule instance
|
58
|
+
|
59
|
+
tc = [305.32, 469.7] # critical temperature [K]
|
60
|
+
pc = [48.72, 33.7] # critical pressure [bar]
|
61
|
+
w = [0.0995, 0.152] # acentric factor
|
62
|
+
|
63
|
+
model = SoaveRedlichKwong(tc, pc, w, mixrule)
|
64
|
+
"""
|
65
|
+
|
66
|
+
def __init__(self, kij, lij) -> None:
|
67
|
+
self.kij = kij
|
68
|
+
self.lij = lij
|
69
|
+
|
70
|
+
def set_mixrule(self, ar_model_id: int) -> None:
|
71
|
+
"""Set quadratic mix rule method.
|
72
|
+
|
73
|
+
Parameters
|
74
|
+
----------
|
75
|
+
ar_model_id : int
|
76
|
+
ID of the cubic EoS model
|
77
|
+
"""
|
78
|
+
yaeos_c.set_qmr(ar_model_id, self.kij, self.lij)
|
79
|
+
|
80
|
+
|
81
|
+
class MHV(CubicMixRule):
|
82
|
+
"""Modified Huron-Vidal mixing rule.
|
83
|
+
|
84
|
+
Parameters
|
85
|
+
----------
|
86
|
+
ge : GeModel
|
87
|
+
Excess Gibbs energy model
|
88
|
+
q : float
|
89
|
+
q parameter. Use:
|
90
|
+
q = -0.594 for Soave-Redlich-Kwong
|
91
|
+
q = -0.53 for Peng-Robinson
|
92
|
+
q = -0.85 for Van der Waals
|
93
|
+
lij : array_like, optional
|
94
|
+
lij binary interaction parameters matrix, by default None
|
95
|
+
|
96
|
+
Attributes
|
97
|
+
----------
|
98
|
+
ge : GeModel
|
99
|
+
Excess Gibbs energy model
|
100
|
+
q : float
|
101
|
+
q parameter
|
102
|
+
lij : array_like
|
103
|
+
lij binary interaction parameters matrix
|
104
|
+
|
105
|
+
Example
|
106
|
+
-------
|
107
|
+
.. code-block:: python
|
108
|
+
|
109
|
+
from yaeos import MHV, SoaveRedlichKwong, NRTL
|
110
|
+
|
111
|
+
tc = [647.14, 513.92] # critical temperature [K]
|
112
|
+
pc = [220.64, 61.48] # critical pressure [bar]
|
113
|
+
w = [0.344, 0.649] # acentric factor
|
114
|
+
|
115
|
+
a = [[0, 3.458], [-0.801, 0]] # NRTL aij parameters
|
116
|
+
b = [[0, -586.1], [246.2, 0]] # NRTL bij parameters
|
117
|
+
c = [[0, 0.3], [0.3, 0]] # NRTL cij parameters
|
118
|
+
|
119
|
+
ge_model = NRTL(a, b, c)
|
120
|
+
mixrule = MHV(ge_model, q=-0.53)
|
121
|
+
|
122
|
+
model_mhv = PengRobinson76(tc, pc, w, mixrule)
|
123
|
+
"""
|
124
|
+
|
125
|
+
def __init__(self, ge: GeModel, q: float, lij=None) -> None:
|
126
|
+
self.ge = ge
|
127
|
+
self.q = q
|
128
|
+
self.lij = lij
|
129
|
+
|
130
|
+
def set_mixrule(self, ar_model_id: int) -> None:
|
131
|
+
"""Set modified Huron-Vidal mix rule method.
|
132
|
+
|
133
|
+
Parameters
|
134
|
+
----------
|
135
|
+
ar_model_id : int
|
136
|
+
ID of the cubic EoS model
|
137
|
+
"""
|
138
|
+
yaeos_c.set_mhv(ar_model_id, self.ge.id, self.q)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: yaeos
|
3
|
+
Version: 0.1.1
|
4
|
+
Summary: Thermodynamic modelling with Equation of State
|
5
|
+
Requires-Python: >=3.10
|
6
|
+
Requires-Dist: numpy
|
7
|
+
Description-Content-Type: text/markdown
|
8
|
+
|
9
|
+
# yaeos Python bindings
|
10
|
+
THIS IS A WIP SO THE API WILL DRASTICALLY CHANGE WITH TIME
|
11
|
+
|
12
|
+
Set of Python bindings to call `yaeos` functions and models.
|
13
|
+
|
14
|
+
Editable installation
|
15
|
+
|
16
|
+
```
|
17
|
+
cd python
|
18
|
+
pip install -r requirements-build.txt
|
19
|
+
pip install -e . --no-build-isolation
|
20
|
+
```
|
21
|
+
|
22
|
+
If you want to install on your environment instead
|
23
|
+
|
24
|
+
```shell
|
25
|
+
pip install .
|
26
|
+
```
|
27
|
+
|
28
|
+
To check if the installation worked correctly:
|
29
|
+
|
30
|
+
```python
|
31
|
+
from yaeos import PengRobinson76
|
32
|
+
|
33
|
+
import numpy as np
|
34
|
+
|
35
|
+
model = PengRobinson76(np.array([320, 375]), np.array([30, 45]), np.array([0.0123, 0.045]), mr)
|
36
|
+
|
37
|
+
model.lnphi_vt(np.array([5.0, 4.0]), 2.0, 303.15)
|
38
|
+
```
|
39
|
+
|
40
|
+
```
|
41
|
+
{'ln_phi': array([0.47647471, 0.35338115]), 'dt': None, 'dp': None, 'dn': None}
|
42
|
+
```
|
@@ -0,0 +1,19 @@
|
|
1
|
+
yaeos.libs/liblapack-1ad85175.so.3.4.2,sha256=wrfEW65bG_XaXB2gB_JZR24uf8UxvWTrvVe6nIqfwu4,5682809
|
2
|
+
yaeos.libs/libquadmath-96973f99.so.0.0.0,sha256=k0wi3tDn0WnE1GeIdslgUa3z2UVF2pYvYLQWWbB12js,247609
|
3
|
+
yaeos.libs/libgfortran-91cc3cb1.so.3.0.0,sha256=VePrZzBsL_F-b4oIEOqg3LJulM2DkkxQZdUEDoeBRgg,1259665
|
4
|
+
yaeos.libs/libgfortran-040039e1.so.5.0.0,sha256=FK-zEpsai1C8QKOwggx_EVLqm8EBIaqxUpQ_cFdHKIY,2686065
|
5
|
+
yaeos.libs/libblas-357956a1.so.3.4.2,sha256=eLqolYX0nkk2PP64pkqa0Nif8hllaovrJMGbx8jU5W0,374265
|
6
|
+
yaeos-0.1.1.dist-info/RECORD,,
|
7
|
+
yaeos-0.1.1.dist-info/WHEEL,sha256=sZM_NeUMz2G4fDenMf11eikcCxcLaQWiYRmjwQBavQs,137
|
8
|
+
yaeos-0.1.1.dist-info/METADATA,sha256=YVZPquTLIAItFG_32wy3SWcr_A7jsaq9OAJPLf9-esw,886
|
9
|
+
yaeos/__init__.py,sha256=ZTMBNOaRmrcBEv6YLWyJdTKs0hX0VaMHP6_KGE4JI5I,578
|
10
|
+
yaeos/core.py,sha256=Bp4Y9LBt8EAk6S8QaZJo0pRD7WAomfBygn0YxrxQBgg,16239
|
11
|
+
yaeos/lib/__init__.py,sha256=JoG2sgKPrqe_TbvRI9bYXU0U_SF-GplchencGp9nNT0,199
|
12
|
+
yaeos/lib/yaeos_python.cpython-310-x86_64-linux-gnu.so,sha256=mQ7z8vGGGh4AlbCC4JVb6Z8Mkd0CeX12s5iTubVMtdY,10195929
|
13
|
+
yaeos/models/__init__.py,sha256=oH8vxuM-mMai2qeeaza0RK9KC3q-icGofg_I2t9ELaM,667
|
14
|
+
yaeos/models/residual_helmholtz/__init__.py,sha256=OWgvPQlbfyF83UVxQih_9FeAJFBrhsDSc_BWfiYpqIA,573
|
15
|
+
yaeos/models/residual_helmholtz/cubic_eos/mixing_rules.py,sha256=E8NFikKT8TxXDTUCSaKrX_IPFevUhVc4WXdMlGLQ5As,3600
|
16
|
+
yaeos/models/residual_helmholtz/cubic_eos/cubic_eos.py,sha256=r0z48oIeBFGRN_E8f9Jt6-u100epzb_Y-UeTN_i1c-Y,9169
|
17
|
+
yaeos/models/residual_helmholtz/cubic_eos/__init__.py,sha256=GM0qMwru74eSBXqVSuwxfFgK_NB3HWx9RM6ndlKRWpU,671
|
18
|
+
yaeos/models/excess_gibbs/nrtl.py,sha256=U7uLp-SLdjO-By3FSiljO5apyk4AAhbbWKK7a0kKuLg,1023
|
19
|
+
yaeos/models/excess_gibbs/__init__.py,sha256=sq1wetoEjgZB5iBZdECz-OB1bH9g0j9Ru7NuF_PaW8U,239
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|