yaeos 4.0.0__cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_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.
@@ -0,0 +1,449 @@
1
+ """Cubic EoS implementations module."""
2
+
3
+ from yaeos.core import ArModel
4
+ from yaeos.lib import yaeos_c
5
+ from yaeos.models.groups import groups_from_dicts
6
+ from yaeos.models.residual_helmholtz.cubic_eos.mixing_rules import CubicMixRule
7
+
8
+
9
+ class CubicEoS(ArModel):
10
+ """Cubic equation of state base class.
11
+
12
+ Parameters
13
+ ----------
14
+ critical_temperatures : array_like
15
+ Critical temperatures vector [K]
16
+ critical_pressures : array_like
17
+ Critical pressures vector [bar]
18
+ acentric_factors : array_like
19
+ Acentric factors vector
20
+
21
+ Attributes
22
+ ----------
23
+ nc : int
24
+ Number of components
25
+ tc : array_like
26
+ Critical temperatures vector [K]
27
+ pc : array_like
28
+ Critical pressures vector [bar]
29
+ w : array_like
30
+ Acentric factors vector
31
+ """
32
+
33
+ def __init__(
34
+ self,
35
+ critical_temperatures,
36
+ critical_pressures,
37
+ acentric_factors,
38
+ ) -> None:
39
+ nc = len(critical_temperatures)
40
+ self.nc = nc
41
+ self.tc = critical_temperatures
42
+ self.pc = critical_pressures
43
+ self.w = acentric_factors
44
+
45
+ def set_mixrule(self, mixrule: CubicMixRule) -> None:
46
+ """Set the mixing rule for the EoS.
47
+
48
+ Parameters
49
+ ----------
50
+ mixrule : CubicMixRule
51
+ Mixing rule object
52
+ """
53
+ self.mixrule = mixrule
54
+ self.mixrule.set_mixrule(self.id)
55
+
56
+
57
+ class PengRobinson76(CubicEoS):
58
+ """Peng-Robinson 1976 cubic equation of state.
59
+
60
+ Parameters
61
+ ----------
62
+ critical_temperatures : array_like
63
+ Critical temperatures vector [K]
64
+ critical_pressures : array_like
65
+ Critical pressures vector [bar]
66
+ acentric_factors : array_like
67
+ Acentric factors vector
68
+ mixrule : CubicMixRule, optional
69
+ Mixing rule object. If no provided the quadratric mixing rule (QMR)
70
+ with zero for kij and lij parameters is set, by default None
71
+
72
+ Attributes
73
+ ----------
74
+ nc : int
75
+ Number of components
76
+ critical_temperatures : array_like
77
+ Critical temperatures vector [K]
78
+ critical_pressures : array_like
79
+ Critical pressures vector [bar]
80
+ acentric_factors : array_like
81
+ Acentric factors vector
82
+ id : int
83
+ EoS identifier
84
+ mixrule : CubicMixRule
85
+ Mixing rule object
86
+
87
+ Example
88
+ -------
89
+ .. code-block:: python
90
+
91
+ from yaeos import PengRobinson76
92
+
93
+ tc = [190.56, 305.32] # Critical temperatures [K]
94
+ pc = [45.99, 48.72] # Critical pressures [bar]
95
+ w = [0.0115, 0.0985] # Acentric factors
96
+
97
+ pr76 = PengRobinson76(tc, pc, w)
98
+ """
99
+
100
+ name = "PengRobinson76"
101
+
102
+ def __init__(
103
+ self,
104
+ critical_temperatures,
105
+ critical_pressures,
106
+ acentric_factors,
107
+ mixrule: CubicMixRule = None,
108
+ ) -> None:
109
+
110
+ super(PengRobinson76, self).__init__(
111
+ critical_temperatures,
112
+ critical_pressures,
113
+ acentric_factors,
114
+ )
115
+ self.id = yaeos_c.pr76(self.tc, self.pc, self.w)
116
+ self.mixrule = mixrule
117
+ if mixrule:
118
+ mixrule.set_mixrule(self.id)
119
+
120
+
121
+ class PengRobinson78(CubicEoS):
122
+ """Peng-Robinson 1978 cubic equation of state.
123
+
124
+ Parameters
125
+ ----------
126
+ critical_temperatures : array_like
127
+ Critical temperatures vector [K]
128
+ critical_pressures : array_like
129
+ Critical pressures vector [bar]
130
+ acentric_factors : array_like
131
+ Acentric factors vector
132
+ mixrule : CubicMixRule, optional
133
+ Mixing rule object. If no provided the quadratric mixing rule (QMR)
134
+ with zero for kij and lij parameters is set, by default None
135
+
136
+ Attributes
137
+ ----------
138
+ nc : int
139
+ Number of components
140
+ critical_temperatures : array_like
141
+ Critical temperatures vector [K]
142
+ critical_pressures : array_like
143
+ Critical pressures vector [bar]
144
+ acentric_factors : array_like
145
+ Acentric factors vector
146
+ id : int
147
+ EoS identifier
148
+ mixrule : CubicMixRule
149
+ Mixing rule object
150
+
151
+ Example
152
+ -------
153
+ .. code-block:: python
154
+
155
+ from yaeos import PengRobinson78
156
+
157
+ tc = [190.56, 305.32] # Critical temperatures [K]
158
+ pc = [45.99, 48.72] # Critical pressures [bar]
159
+ w = [0.0115, 0.0985] # Acentric factors
160
+
161
+ pr78 = PengRobinson78(tc, pc, w)
162
+ """
163
+
164
+ name = "PengRobinson78"
165
+
166
+ def __init__(
167
+ self,
168
+ critical_temperatures,
169
+ critical_pressures,
170
+ acentric_factors,
171
+ mixrule: CubicMixRule = None,
172
+ ) -> None:
173
+
174
+ super(PengRobinson78, self).__init__(
175
+ critical_temperatures,
176
+ critical_pressures,
177
+ acentric_factors,
178
+ )
179
+ self.id = yaeos_c.pr78(self.tc, self.pc, self.w)
180
+ self.mixrule = mixrule
181
+ if mixrule:
182
+ mixrule.set_mixrule(self.id)
183
+
184
+
185
+ class SoaveRedlichKwong(CubicEoS):
186
+ """Soave-Redlich-Kwong cubic equation of state.
187
+
188
+ Parameters
189
+ ----------
190
+ critical_temperatures : array_like
191
+ Critical temperatures vector [K]
192
+ critical_pressures : array_like
193
+ Critical pressures vector [bar]
194
+ acentric_factors : array_like
195
+ Acentric factors vector
196
+ mixrule : CubicMixRule, optional
197
+ Mixing rule object. If no provided the quadratric mixing rule (QMR)
198
+ with zero for kij and lij parameters is set, by default None
199
+
200
+ Attributes
201
+ ----------
202
+ nc : int
203
+ Number of components
204
+ critical_temperatures : array_like
205
+ Critical temperatures vector [K]
206
+ critical_pressures : array_like
207
+ Critical pressures vector [bar]
208
+ acentric_factors : array_like
209
+ Acentric factors vector
210
+ id : int
211
+ EoS identifier
212
+ mixrule : CubicMixRule
213
+ Mixing rule object
214
+
215
+ Example
216
+ -------
217
+ .. code-block:: python
218
+
219
+ from yaeos import SoaveRedlichKwong
220
+
221
+ tc = [190.56, 305.32] # Critical temperatures [K]
222
+ pc = [45.99, 48.72] # Critical pressures [bar]
223
+ w = [0.0115, 0.0985] # Acentric factors
224
+
225
+ srk = SoaveRedlichKwong(tc, pc, w)
226
+ """
227
+
228
+ name = "SoaveReldichKwong"
229
+
230
+ def __init__(
231
+ self,
232
+ critical_temperatures,
233
+ critical_pressures,
234
+ acentric_factors,
235
+ mixrule: CubicMixRule = None,
236
+ ) -> None:
237
+
238
+ super(SoaveRedlichKwong, self).__init__(
239
+ critical_temperatures,
240
+ critical_pressures,
241
+ acentric_factors,
242
+ )
243
+ self.id = yaeos_c.srk(self.tc, self.pc, self.w)
244
+ self.mixrule = mixrule
245
+ if mixrule:
246
+ mixrule.set_mixrule(self.id)
247
+
248
+
249
+ class RKPR(CubicEoS):
250
+ """RKPR cubic equation of state.
251
+
252
+ Parameters
253
+ ----------
254
+ critical_temperatures : array_like
255
+ Critical temperatures vector [K]
256
+ critical_pressures : array_like
257
+ Critical pressures vector [bar]
258
+ acentric_factors : array_like
259
+ Acentric factors vector
260
+ critical_z : array_like
261
+ Critical compressibility factor vector
262
+ k : array_like, optional
263
+ k parameter, by default None
264
+ delta_1 : array_like, optional
265
+ delta_1 parameter, by default None
266
+ mixrule : CubicMixRule, optional
267
+ Mixing rule object. If no provided the quadratric mixing rule (QMR)
268
+ with zero for kij and lij parameters is set, by default None
269
+
270
+ Attributes
271
+ ----------
272
+ nc : int
273
+ Number of components
274
+ critical_temperatures : array_like
275
+ Critical temperatures vector [K]
276
+ critical_pressures : array_like
277
+ Critical pressures vector [bar]
278
+ acentric_factors : array_like
279
+ Acentric factors vector
280
+ zc : array_like
281
+ Critical compressibility factor vector
282
+ id : int
283
+ EoS identifier
284
+ mixrule : CubicMixRule
285
+ Mixing rule object
286
+
287
+ Example
288
+ -------
289
+ .. code-block:: python
290
+
291
+ from yaeos import RKPR
292
+
293
+ tc = [190.56, 305.32] # Critical temperatures [K]
294
+ pc = [45.99, 48.72] # Critical pressures [bar]
295
+ w = [0.0115, 0.0985] # Acentric factors
296
+ zc = [0.27, 0.28] # Critical compressibility factor
297
+
298
+ rkpr = RKPR(tc, pc, w, zc)
299
+ """
300
+
301
+ name = "RKPR"
302
+
303
+ def __init__(
304
+ self,
305
+ critical_temperatures,
306
+ critical_pressures,
307
+ acentric_factors,
308
+ critical_z,
309
+ k=None,
310
+ delta_1=None,
311
+ mixrule: CubicMixRule = None,
312
+ ) -> None:
313
+
314
+ super(RKPR, self).__init__(
315
+ critical_temperatures,
316
+ critical_pressures,
317
+ acentric_factors,
318
+ )
319
+ self.zc = critical_z
320
+
321
+ match (k is None, delta_1 is None):
322
+ case (True, True):
323
+ self.id = yaeos_c.rkpr(self.tc, self.pc, self.w, self.zc)
324
+ case (False, True):
325
+ self.id = yaeos_c.rkpr(self.tc, self.pc, self.w, self.zc, k=k)
326
+ case (True, False):
327
+ self.id = yaeos_c.rkpr(
328
+ self.tc, self.pc, self.w, self.zc, delta_1=delta_1
329
+ )
330
+ case (False, False):
331
+ self.id = yaeos_c.rkpr(
332
+ self.tc, self.pc, self.w, self.zc, k=k, delta_1=delta_1
333
+ )
334
+ self.mixrule = mixrule
335
+ if mixrule:
336
+ mixrule.set_mixrule(self.id)
337
+
338
+
339
+ class PSRK(CubicEoS):
340
+ """Predictive-Soave-Redlich-Kwong cubic equation of state.
341
+
342
+ Parameters
343
+ ----------
344
+ critical_temperatures : array_like
345
+ Critical temperatures vector [K]
346
+ critical_pressures : array_like
347
+ Critical pressures vector [bar]
348
+ acentric_factors : array_like
349
+ Acentric factors vector
350
+ molecules: list of dict
351
+ List of dicts with the groups and their amounts for each molecule
352
+ c1: array_like
353
+ Mathias-Copeman parameters c1
354
+ c2: array_like
355
+ Mathias-Copeman parameters c3
356
+ c3: array_like
357
+ Mathias-Copeman parameters c3
358
+
359
+ Attributes
360
+ ----------
361
+ nc : int
362
+ Number of components
363
+ critical_temperatures : array_like
364
+ Critical temperatures vector [K]
365
+ critical_pressures : array_like
366
+ Critical pressures vector [bar]
367
+ acentric_factors : array_like
368
+ Acentric factors vector
369
+ id : int
370
+ EoS identifier
371
+
372
+ Example
373
+ -------
374
+ .. code-block:: python
375
+
376
+ from yaeos import PSRK
377
+
378
+ # methanol/n-hexane mixture
379
+ tc = [512.5, 507.6] # Critical temperatures [K]
380
+ pc = [80.84, 30.25] # Critical pressures [bar]
381
+ w = [0.565831, 0.301261] # Acentric factors
382
+
383
+ # Methanol: 1 CH3OH subgroup
384
+ # n-hexane: 2 CH3, 4 CH2 subgroups
385
+ molecules = [{15:1}, {1:2, 2:4}]
386
+
387
+ # Mathias-copeman constants
388
+ c1 = [1.31458917, 0.93830213]
389
+ c2 = [0.0, 0.0]
390
+ c3 = [0.0, 0.0]
391
+
392
+ psrk = PSRK(tc, pc, w, molecules=molecules, c1=c1, c2=c2, c3=c3)
393
+
394
+ .. code-block:: python
395
+
396
+ # The dictionary of molecules can be created using the `ugropy` library
397
+
398
+ import ugropy as ug
399
+
400
+ molecules = ["methanol", "ethanol"]
401
+
402
+ groups = [ug.get_groups(ug.psrk, molecule) for molecule in molecules]
403
+ molecules = [
404
+ ug.writers.to_thermo(grp.subgroups, ug.psrk) for grp in groups
405
+ ]
406
+
407
+ print(molecules)
408
+
409
+ >>> [{15: 1}, {1: 1, 2: 1, 14: 1}]
410
+ """
411
+
412
+ def __init__(
413
+ self,
414
+ critical_temperatures,
415
+ critical_pressures,
416
+ acentric_factors,
417
+ molecules,
418
+ c1=None,
419
+ c2=None,
420
+ c3=None,
421
+ ) -> None:
422
+
423
+ super(PSRK, self).__init__(
424
+ critical_temperatures,
425
+ critical_pressures,
426
+ acentric_factors,
427
+ )
428
+ (number_of_groups, groups_ids, groups_ammounts) = groups_from_dicts(
429
+ molecules
430
+ )
431
+
432
+ if c1 is None:
433
+ c1 = 0.48 + 1.574 * self.w - 0.175 * self.w**2
434
+ if c2 is None:
435
+ c2 = [0 for i in range(len(self.w))]
436
+ if c3 is None:
437
+ c3 = [0 for i in range(len(self.w))]
438
+
439
+ self.id = yaeos_c.psrk(
440
+ tc=self.tc,
441
+ pc=self.pc,
442
+ w=self.w,
443
+ ngs=number_of_groups,
444
+ g_ids=groups_ids,
445
+ g_v=groups_ammounts,
446
+ c1=c1,
447
+ c2=c2,
448
+ c3=c3,
449
+ )
@@ -0,0 +1,253 @@
1
+ """Cubic EoS mixing rules implementations module."""
2
+
3
+ from abc import ABC, abstractmethod
4
+
5
+ import numpy as np
6
+
7
+ from yaeos.core import GeModel
8
+ from yaeos.lib import yaeos_c
9
+
10
+
11
+ class CubicMixRule(ABC):
12
+ """Cubic mix rule abstract class."""
13
+
14
+ @abstractmethod
15
+ def set_mixrule(self, ar_model_id: int) -> None:
16
+ """Set mix rule abstract method.
17
+
18
+ Changes the default mixing rule of the given cubic EoS model.
19
+
20
+ Parameters
21
+ ----------
22
+ ar_model_id : int
23
+ ID of the cubic EoS model
24
+
25
+ Raises
26
+ ------
27
+ NotImplementedError
28
+ Abstract error, this method must be implemented in the subclass
29
+ """
30
+ raise NotImplementedError
31
+
32
+
33
+ class QMR(CubicMixRule):
34
+ """Quadratic mixing rule.
35
+
36
+ Parameters
37
+ ----------
38
+ kij : array_like
39
+ kij binary interaction parameters matrix
40
+ lij : array_like
41
+ lij binary interaction parameters matrix
42
+
43
+ Attributes
44
+ ----------
45
+ kij : array_like
46
+ kij binary interaction parameters matrix
47
+ lij : array_like
48
+ lij binary interaction parameters matrix
49
+
50
+ Example
51
+ -------
52
+ .. code-block:: python
53
+
54
+ from yaeos import QMR, SoaveRedlichKwong
55
+
56
+ kij = [[0.0, 0.1], [0.1, 0.0]]
57
+ lij = [[0.0, 0.02], [0.02, 0.0]]
58
+
59
+ mixrule = QMR(kij, lij) # Quadratic mixing rule instance
60
+
61
+ tc = [305.32, 469.7] # critical temperature [K]
62
+ pc = [48.72, 33.7] # critical pressure [bar]
63
+ w = [0.0995, 0.152] # acentric factor
64
+
65
+ model = SoaveRedlichKwong(tc, pc, w, mixrule)
66
+ """
67
+
68
+ def __init__(self, kij, lij) -> None:
69
+ self.kij = np.array(kij, order="F")
70
+ self.lij = np.array(lij, order="F")
71
+
72
+ def set_mixrule(self, ar_model_id: int) -> None:
73
+ """Set quadratic mix rule method.
74
+
75
+ Parameters
76
+ ----------
77
+ ar_model_id : int
78
+ ID of the cubic EoS model
79
+ """
80
+ yaeos_c.set_qmr(ar_model_id, self.kij, self.lij)
81
+
82
+
83
+ class QMRTD(CubicMixRule):
84
+ r"""Quadratic mixing rule, with temperature dependence.
85
+
86
+ ..math::
87
+ k_{ij}(T) = k_{ij}^{\infty} + k_{ij}^0 \exp{\left(-T/T^{ref}\right)}
88
+
89
+ Parameters
90
+ ----------
91
+ kij_0 : array_like
92
+ kij_0 binary interaction parameters matrix
93
+ kij_inf : array_like
94
+ kij_inf binary interaction parameters matrix
95
+ t_ref: array_like
96
+ Reference temperature
97
+ lij : array_like
98
+ lij binary interaction parameters matrix
99
+
100
+ Attributes
101
+ ----------
102
+ kij_0 : array_like
103
+ kij_0 binary interaction parameters matrix
104
+ kij_inf : array_like
105
+ kij_inf binary interaction parameters matrix
106
+ t_ref: array_like
107
+ Reference temperature
108
+ lij : array_like
109
+ lij binary interaction parameters matrix
110
+
111
+ Example
112
+ -------
113
+ .. code-block:: python
114
+
115
+ from yaeos import QMRTD, SoaveRedlichKwong
116
+
117
+ kij_0 = [[0.0, 0.1], [0.1, 0.0]]
118
+ kij_inf = [[0.0, 0.1], [0.1, 0.0]]
119
+ Tref = [[0.0, 390], [390, 0.0]]
120
+ lij = [[0.0, 0.02], [0.02, 0.0]]
121
+
122
+ # Quadratic mixing rule instance
123
+ mixrule = QMRTD(kij_0, kij_inf, Tref, lij)
124
+
125
+ tc = [305.32, 469.7] # critical temperature [K]
126
+ pc = [48.72, 33.7] # critical pressure [bar]
127
+ w = [0.0995, 0.152] # acentric factor
128
+
129
+ model = SoaveRedlichKwong(tc, pc, w, mixrule)
130
+ """
131
+
132
+ def __init__(self, kij_0, kij_inf, t_ref, lij) -> None:
133
+ self.kij_0 = np.array(kij_0, order="F")
134
+ self.kij_inf = np.array(kij_inf, order="F")
135
+ self.t_ref = np.array(t_ref, order="F")
136
+ self.lij = np.array(lij, order="F")
137
+
138
+ def set_mixrule(self, ar_model_id: int) -> None:
139
+ """Set mix rule method."""
140
+ yaeos_c.set_qmrtd(
141
+ ar_model_id,
142
+ kij_0=self.kij_0,
143
+ kij_inf=self.kij_inf,
144
+ t_star=self.t_ref,
145
+ lij=self.lij,
146
+ )
147
+
148
+
149
+ class MHV(CubicMixRule):
150
+ """Modified Huron-Vidal mixing rule.
151
+
152
+ Parameters
153
+ ----------
154
+ ge : GeModel
155
+ Excess Gibbs energy model
156
+ q : float
157
+ q parameter. Use:
158
+ q = -0.594 for Soave-Redlich-Kwong
159
+ q = -0.53 for Peng-Robinson
160
+ q = -0.85 for Van der Waals
161
+ lij : array_like, optional
162
+ lij binary interaction parameters matrix, by default None
163
+
164
+ Attributes
165
+ ----------
166
+ ge : GeModel
167
+ Excess Gibbs energy model
168
+ q : float
169
+ q parameter
170
+ lij : array_like
171
+ lij binary interaction parameters matrix
172
+
173
+ Example
174
+ -------
175
+ .. code-block:: python
176
+
177
+ from yaeos import MHV, SoaveRedlichKwong, NRTL
178
+
179
+ tc = [647.14, 513.92] # critical temperature [K]
180
+ pc = [220.64, 61.48] # critical pressure [bar]
181
+ w = [0.344, 0.649] # acentric factor
182
+
183
+ a = [[0, 3.458], [-0.801, 0]] # NRTL aij parameters
184
+ b = [[0, -586.1], [246.2, 0]] # NRTL bij parameters
185
+ c = [[0, 0.3], [0.3, 0]] # NRTL cij parameters
186
+
187
+ ge_model = NRTL(a, b, c)
188
+ mixrule = MHV(ge_model, q=-0.53)
189
+
190
+ model_mhv = PengRobinson76(tc, pc, w, mixrule)
191
+ """
192
+
193
+ def __init__(self, ge: GeModel, q: float, lij=None) -> None:
194
+ self.ge = ge
195
+ self.q = q
196
+ self.lij = np.array(lij, order="F")
197
+
198
+ def set_mixrule(self, ar_model_id: int) -> None:
199
+ """Set modified Huron-Vidal mix rule method.
200
+
201
+ Parameters
202
+ ----------
203
+ ar_model_id : int
204
+ ID of the cubic EoS model
205
+ """
206
+ yaeos_c.set_mhv(ar_model_id, self.ge.id, self.q)
207
+
208
+
209
+ class HV(CubicMixRule):
210
+ """Huron-Vidal mixing rule.
211
+
212
+ Parameters
213
+ ----------
214
+ ge : GeModel
215
+ Excess Gibbs energy model
216
+
217
+ Attributes
218
+ ----------
219
+ ge : GeModel
220
+ Excess Gibbs energy model
221
+
222
+ Example
223
+ -------
224
+ .. code-block:: python
225
+
226
+ from yaeos import HV, SoaveRedlichKwong, NRTL
227
+
228
+ tc = [647.14, 513.92] # critical temperature [K]
229
+ pc = [220.64, 61.48] # critical pressure [bar]
230
+ w = [0.344, 0.649] # acentric factor
231
+
232
+ a = [[0, 3.458], [-0.801, 0]] # NRTL aij parameters
233
+ b = [[0, -586.1], [246.2, 0]] # NRTL bij parameters
234
+ c = [[0, 0.3], [0.3, 0]] # NRTL cij parameters
235
+
236
+ ge_model = NRTL(a, b, c)
237
+ mixrule = HV(ge_model)
238
+
239
+ model_hv = PengRobinson76(tc, pc, w, mixrule)
240
+ """
241
+
242
+ def __init__(self, ge: GeModel) -> None:
243
+ self.ge = ge
244
+
245
+ def set_mixrule(self, ar_model_id: int) -> None:
246
+ """Set modified Huron-Vidal mix rule method.
247
+
248
+ Parameters
249
+ ----------
250
+ ar_model_id : int
251
+ ID of the cubic EoS model
252
+ """
253
+ yaeos_c.set_hv(ar_model_id, self.ge.id)
@@ -0,0 +1,12 @@
1
+ """
2
+ Multifluid equations module.
3
+
4
+ Implemented models:
5
+
6
+ - GERG2008
7
+ """
8
+
9
+ from .gerg2008 import GERG2008
10
+
11
+
12
+ __all__ = ["GERG2008"]