pyrestoolbox 3.1.5__tar.gz → 3.3.0__tar.gz

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.
Files changed (122) hide show
  1. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/PKG-INFO +1 -1
  2. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyproject.toml +1 -1
  3. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/brine/_lib_vle_engine.py +6 -3
  4. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/brine/brine.py +6 -3
  5. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/dca/dca.py +11 -2
  6. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/changelist.rst +36 -0
  7. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/gas.rst +38 -24
  8. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/gas/gas.py +170 -85
  9. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/layer/layer.py +48 -63
  10. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/recommend/recommend.py +8 -2
  11. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/sensitivity/sensitivity.py +11 -0
  12. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/simtools/simtools.py +6 -80
  13. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/gas_viscosity/mod.rs +23 -7
  14. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/pseudopressure.rs +36 -20
  15. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/mod.rs +23 -14
  16. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/zfactor/mod.rs +33 -7
  17. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/.github/workflows/build-wheels.yml +0 -0
  18. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/.gitignore +0 -0
  19. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/Cargo.lock +0 -0
  20. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/Cargo.toml +0 -0
  21. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/LICENSE +0 -0
  22. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/MANIFEST.in +0 -0
  23. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/README.rst +0 -0
  24. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/ResToolbox/privacy_policy.md +0 -0
  25. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/benchmark_rust_vs_python.py +0 -0
  26. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/build_pure_python.py +0 -0
  27. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/__init__.py +0 -0
  28. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/_accelerator.py +0 -0
  29. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/brine/__init__.py +0 -0
  30. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/brine/_lib_salting_library.py +0 -0
  31. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/classes/__init__.py +0 -0
  32. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/classes/classes.py +0 -0
  33. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/constants/__init__.py +0 -0
  34. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/constants/constants.py +0 -0
  35. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/dca/__init__.py +0 -0
  36. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/brine.rst +0 -0
  37. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/dca.rst +0 -0
  38. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/examples.ipynb +0 -0
  39. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/bot.png +0 -0
  40. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/bot_PVTO.png +0 -0
  41. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/bot_img.png +0 -0
  42. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/dry_gas.png +0 -0
  43. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/grid_sat_df.png +0 -0
  44. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/influence.png +0 -0
  45. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/properties_df.png +0 -0
  46. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/sgof.png +0 -0
  47. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/img/swof.png +0 -0
  48. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/layer.rst +0 -0
  49. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/library.rst +0 -0
  50. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/matbal.rst +0 -0
  51. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/nodal.rst +0 -0
  52. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/nodal_examples.ipynb +0 -0
  53. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/nodal_hydrate_demo.ipynb +0 -0
  54. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/oil.rst +0 -0
  55. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/recommend.rst +0 -0
  56. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/sensitivity.rst +0 -0
  57. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/docs/simtools.rst +0 -0
  58. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/gas/__init__.py +0 -0
  59. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/layer/__init__.py +0 -0
  60. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/library/__init__.py +0 -0
  61. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/library/component_library.xlsx +0 -0
  62. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/library/library.py +0 -0
  63. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/matbal/__init__.py +0 -0
  64. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/matbal/matbal.py +0 -0
  65. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/nodal/__init__.py +0 -0
  66. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/nodal/nodal.py +0 -0
  67. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/__init__.py +0 -0
  68. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_compressibility.py +0 -0
  69. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_constants.py +0 -0
  70. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_correlations.py +0 -0
  71. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_density.py +0 -0
  72. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_harmonize.py +0 -0
  73. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_pvt_class.py +0 -0
  74. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_rate.py +0 -0
  75. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_separator.py +0 -0
  76. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_tables.py +0 -0
  77. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/oil/_utils.py +0 -0
  78. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/plyasunov/__init__.py +0 -0
  79. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/plyasunov/iapws_if97.py +0 -0
  80. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/plyasunov/plyasunov_model.py +0 -0
  81. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/plyasunov/water_properties.py +0 -0
  82. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/recommend/__init__.py +0 -0
  83. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/sensitivity/__init__.py +0 -0
  84. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/shared_fns/__init__.py +0 -0
  85. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/shared_fns/shared_fns.py +0 -0
  86. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/simtools/__init__.py +0 -0
  87. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/validate/__init__.py +0 -0
  88. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/pyrestoolbox/validate/validate.py +0 -0
  89. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/setup.cfg +0 -0
  90. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/setup.py +0 -0
  91. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/bessel.rs +0 -0
  92. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/critical_properties/mod.rs +0 -0
  93. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/dca/hyperbolic.rs +0 -0
  94. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/dca/mod.rs +0 -0
  95. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/dca/ransac.rs +0 -0
  96. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/gwr.rs +0 -0
  97. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/lib.rs +0 -0
  98. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/matbal/mod.rs +0 -0
  99. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/matbal/objective.rs +0 -0
  100. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/oil/density.rs +0 -0
  101. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/oil/mod.rs +0 -0
  102. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/spycher_pruess/mod.rs +0 -0
  103. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/spycher_pruess/solubility.rs +0 -0
  104. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/alpha.rs +0 -0
  105. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/bip.rs +0 -0
  106. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/components.rs +0 -0
  107. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/eos.rs +0 -0
  108. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/flash.rs +0 -0
  109. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/fugacity.rs +0 -0
  110. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/k_init.rs +0 -0
  111. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vle/rachford_rice.rs +0 -0
  112. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/friction.rs +0 -0
  113. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/holdup_bb.rs +0 -0
  114. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/holdup_gray.rs +0 -0
  115. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/holdup_hb.rs +0 -0
  116. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/holdup_wg.rs +0 -0
  117. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/ift.rs +0 -0
  118. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/mod.rs +0 -0
  119. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/pvt_helpers.rs +0 -0
  120. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/segment_gas.rs +0 -0
  121. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/segment_oil.rs +0 -0
  122. {pyrestoolbox-3.1.5 → pyrestoolbox-3.3.0}/src/vlp/static_column.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyrestoolbox
3
- Version: 3.1.5
3
+ Version: 3.3.0
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "pyrestoolbox"
7
- version = "3.1.5"
7
+ version = "3.3.0"
8
8
  description = "pyResToolbox - A collection of Reservoir Engineering Utilities"
9
9
  license = {text = "GPL-3.0-or-later"}
10
10
  authors = [{name = "Mark W. Burgoyne", email = "mark.w.burgoyne@gmail.com"}]
@@ -2100,9 +2100,12 @@ class SWMultiComponentFlash:
2100
2100
  z = np.asarray(z, dtype=float)
2101
2101
  z = z / np.sum(z)
2102
2102
 
2103
- # Rust acceleration path — gamma is always passed explicitly
2104
- # to prevent Rust from using its built-in ks model (which lacks
2105
- # the specialised Dubessy/Akinfiev models for CO2/H2S).
2103
+ # Rust acceleration path — gamma is always passed explicitly.
2104
+ # The Rust entry point trusts the caller-supplied gamma and never
2105
+ # substitutes its own S&W Eq 8 ks fallback. framework='proposed'
2106
+ # specialised ks models (Dubessy CO2, Akinfiev H2S, Li HC,
2107
+ # Mao-Duan N2, Duan-Sun CO2) are applied in self.calc_gamma()
2108
+ # on the Python side.
2106
2109
  if _RUST_AVAILABLE:
2107
2110
  try:
2108
2111
  gamma_arr = np.asarray(gamma, dtype=float) if gamma is not None \
@@ -315,7 +315,7 @@ def brine_props(p: float = None, degf: float = None, wt: float = None, ch4_sat:
315
315
  / ((Mpa - vap_pressure) - 2 * dlambdadptm * m)
316
316
  ) # Eq 4.33
317
317
 
318
- zee = gas.gas_z(p=p, sg=_SG_METHANE, degf=degf, zmethod='BNS',
318
+ zee = gas.gas_z(p=p, sg=_SG_METHANE, degf=degf, zmethod='BNS', cmethod='BNS',
319
319
  co2=0, h2s=0, n2=0, h2=0) # Z-Factor of pure methane
320
320
 
321
321
  vmch4g = zee * _R_CM3_MPA * degk / Mpa # Eq 4.34
@@ -342,7 +342,7 @@ def brine_props(p: float = None, degf: float = None, wt: float = None, ch4_sat:
342
342
 
343
343
 
344
344
 
345
- zee_sc = gas.gas_z(p=psc, sg=_SG_METHANE, degf=tsc, zmethod='BNS',
345
+ zee_sc = gas.gas_z(p=psc, sg=_SG_METHANE, degf=tsc, zmethod='BNS', cmethod='BNS',
346
346
  co2=0, h2s=0, n2=0, h2=0)
347
347
  vmch4g_sc = zee_sc * _R_CM3_MPA * (273 + 15) / 0.1013 # Eq 4.34
348
348
  rsw_new = mch4 * vmch4g_sc / ((1000 + m * 58.4428) * vb0_sc)
@@ -456,6 +456,7 @@ class CO2_Brine_Mixture():
456
456
  .Rs : CO2 Saturated Brine solution gas ratio (sm3/sm3 or scf/stb), relative to standard conditions
457
457
  .Cf_usat : Brine undersaturated compressibility (1/Bar or 1/psi). The compressibility with constant Rs
458
458
  .Cf_sat : Brine saturated compressibility (1/Bar or 1/psi). The compressibility with reducing Rs under depletion
459
+ .converged: True if the Spycher-Pruess fugacity iteration reached tolerance, False otherwise
459
460
 
460
461
  Usage example for 5000 psia x 275 deg F and 3% NaCl brine:
461
462
  mix = brine.CO2_Brine_Mixture(pres = 5000, temp = 275, ppm = 30000, metric = False)
@@ -523,6 +524,7 @@ class CO2_Brine_Mixture():
523
524
  self.Cf_sat = None # Saturated brine compressibility (1/Bar or 1/psi). Compressibility with changing Rs
524
525
  self.CO2_sat = False # Flag to determine if in P-T range for saturated liquid CO2 K values
525
526
  self.repeat = False # Flag to trigger repeat of calculations depending on whether CO2 is saturated liquid phase
527
+ self.converged = True # Spycher-Pruess fugacity iteration convergence flag
526
528
  #self.EzrokhiDenA = None # Ezrokhi coefficient array for density (to be calculated with ezrokhi() function)
527
529
  #self.EzrokhiVisB = None # Ezrokhi coefficient array for viscosity (to be calculated with ezrokhi() function)
528
530
  self.Rs_STD = None # Dissolved CO2 remaining at standard conditions (sm3/sm3)
@@ -1125,6 +1127,7 @@ class CO2_Brine_Mixture():
1125
1127
  iternum += 1
1126
1128
 
1127
1129
  if err > EPS:
1130
+ self.converged = False
1128
1131
  import warnings
1129
1132
  warnings.warn(
1130
1133
  f"Spycher CO2-brine iteration did not converge in {iternum} iterations "
@@ -1549,7 +1552,7 @@ class SoreideWhitson:
1549
1552
  self.gas_comp.get(g, 0) * _SW_GAS_MW.get(g, 28.97)
1550
1553
  for g in self.gas_comp
1551
1554
  ) / MW_AIR
1552
- zee = gas.gas_z(p=self.psia, sg=gas_sg, degf=self.degF, zmethod='BNS',
1555
+ zee = gas.gas_z(p=self.psia, sg=gas_sg, degf=self.degF, zmethod='BNS', cmethod='BNS',
1553
1556
  co2=self.gas_comp.get('CO2', 0),
1554
1557
  h2s=self.gas_comp.get('H2S', 0),
1555
1558
  n2=self.gas_comp.get('N2', 0),
@@ -323,10 +323,13 @@ def duong_cum(qi, a, m, t):
323
323
  if np.any(t <= 0):
324
324
  raise ValueError("Time must be positive for Duong model")
325
325
 
326
- # Generate fine time grid for integration
326
+ # Generate fine time grid for integration. Lower bound must be strictly
327
+ # less than ti to give np.linspace an ascending range, otherwise trapezoid
328
+ # integrates over a descending axis and returns negative cumulative.
327
329
  results = np.zeros_like(t, dtype=float)
328
330
  for i, ti in enumerate(t):
329
- t_fine = np.linspace(0.001, ti, max(500, int(ti * 10)))
331
+ lower = min(0.001, ti * 0.001)
332
+ t_fine = np.linspace(lower, ti, max(500, int(ti * 10)))
330
333
  q_fine = qi * t_fine ** (-m) * np.exp(a / (1.0 - m) * (t_fine ** (1.0 - m) - 1.0))
331
334
  results[i] = np.trapezoid(q_fine, t_fine)
332
335
 
@@ -958,6 +961,12 @@ def forecast(result, t_end, dt=1.0, q_min=0.0, uptime=1.0, ratios=None):
958
961
  -------
959
962
  ForecastResult
960
963
  """
964
+ if dt <= 0:
965
+ raise ValueError(f"dt must be positive, got {dt}")
966
+ if t_end <= 0:
967
+ raise ValueError(f"t_end must be positive, got {t_end}")
968
+ if not (0.0 < uptime <= 1.0):
969
+ raise ValueError(f"uptime must be in (0, 1], got {uptime}")
961
970
  t = np.arange(dt, t_end + dt / 2, dt)
962
971
 
963
972
  if result.method == 'duong':
@@ -1,3 +1,39 @@
1
+ Changelist in 3.3.0:
2
+
3
+ - **BNS Z-factor / critical-property coupling**: When either ``zmethod`` or ``cmethod`` is ``BNS``, both are now forced to ``BNS`` for thermodynamic consistency with a ``UserWarning`` naming the overruled counterpart. ``h2 > 0`` continues to auto-select BNS silently. Non-BNS methods (e.g. ``DAK`` + ``SUT``) remain freely mixable. Implemented via a single ``_resolve_methods`` helper applied at all gas public entry points plus ``GasPVT.__init__``.
4
+
5
+ - **User-supplied ``tc`` / ``pc`` honored across every method** (including BNS). Semantics:
6
+
7
+ - ``SUT`` / ``PMC``: supplied values replace the *mixture* pseudo-critical Tc/Pc.
8
+ - ``BNS``: supplied values replace only the *inert-free hydrocarbon* pseudo-component Tc/Pc. Inert Tc/Pc (CO2, H2S, N2, H2) remain at BNS internal constants, and the BNS 5-component PR-EOS mixes them with the user-supplied HC Tc/Pc.
9
+
10
+ This is reflected in ``gas_tc_pc``, ``gas_z``, ``gas_ug``, ``gas_cg``, ``gas_bg``, ``gas_den``, ``gas_dmp``, ``gas_ponz2p``, ``gas_grad2sg``, and ``GasPVT`` (new ``tc=0, pc=0`` kwargs on the class constructor).
11
+
12
+ - **Rust parity for user Tc/Pc**: The Rust batch paths (``dak_zfactor_batch``, ``hy_zfactor_batch``, ``bns_zfactor_batch``, ``gas_ug_lbc``/``gas_ug_lbc_batch``, ``gas_dmp_rust``, ``gas_ponz2p_rust``) now accept optional ``tc_user`` / ``pc_user`` parameters and apply the same override semantics as Python. Removes the previous Python fallback for BNS+user-Tc/Pc; Rust path is now always exercised.
13
+
14
+ - 716 validation tests (up from 701 in 3.2.0). New coverage for BNS coupling warnings, ``GasPVT`` user Tc/Pc, and Rust-vs-Python parity for user Tc/Pc.
15
+
16
+ Changelist in 3.2.0:
17
+
18
+ - **DCA bug fixes**:
19
+
20
+ - ``dca.duong_cum`` — fixed linspace-inversion bug where cumulative volume integrated over a descending axis for ``t < 0.001`` (small-t inputs) and returned a negative value. Lower bound of the integration is now ``min(0.001, t * 0.001)`` so the grid is always ascending.
21
+ - ``dca.forecast`` — now validates ``dt > 0``, ``t_end > 0`` and ``uptime`` in ``(0, 1]`` at entry with clear ``ValueError`` messages. Previously ``dt = 0`` raised an opaque ``ZeroDivisionError`` and out-of-range ``uptime`` was silently accepted.
22
+
23
+ - **Rachford-Rice solver consolidation**: ``simtools.rr_solver`` is now a thin wrapper that delegates to the canonical ``pyrestoolbox.brine._lib_vle_engine.rr_solver`` (Nielsen & Lia 2022). Removes ~100 lines of duplicated iterative code plus the dead ``ensure_numpy_array`` helper. Inputs validated for length/sum before delegation; behaviour is preserved (``EPS_T=1e-15``, ``max_iter=100``).
24
+
25
+ - **Rust Sechenov fallback guard**: ``src/vle/mod.rs::flash_tp_rust`` no longer silently substitutes its S&W Eq 8 ``ks`` fallback when a caller passes all-ones ``gamma`` with ``salinity > 0``. The caller-supplied ``gamma`` is now always trusted, eliminating any risk that Python ``framework='proposed'`` calls bypass the specialised Dubessy/Akinfiev/Li/Mao-Duan/Duan-Sun ``ks`` models. ``calc_equilibrium_rust`` retains the S&W Eq 8 path but now carries a prominent doc warning. Python path unchanged (Python always passes the correct ``gamma``).
26
+
27
+ - **Convergence flag on ``CO2_Brine_Mixture``**: New ``.converged`` attribute on the class. ``True`` after a successful Spycher-Pruess fugacity iteration, ``False`` when the 100-iteration limit is hit (matching the existing ``RuntimeWarning``). Lets downstream callers detect non-convergence programmatically.
28
+
29
+ - **``sensitivity.tornado`` robustness**: Raises ``ValueError`` if ``base_result`` is not finite (NaN/Inf), and if any ``ranges[param]`` has ``lo > hi``. Previously returned ``nan`` or ``inf`` sensitivities that silently corrupted tornado plots.
30
+
31
+ - **``layer`` module dedup**: Five copies of the EXP/LANG dispatch (B-clamp, flow-fraction evaluation) consolidated into three private helpers (``_clamp_b``, ``_b_max``, ``_flow_fraction_at_x``). No behaviour change.
32
+
33
+ - **``recommend`` module docstrings**: ``sg`` on ``recommend_gas_methods`` and ``well_type`` on ``recommend_vlp_method`` are currently unused by the decision logic. Docstrings now flag them as reserved for future rules. Signatures preserved for backward compatibility.
34
+
35
+ - 701 validation tests (up from 696 in 3.1.5).
36
+
1
37
  Changelist in 3.1.5:
2
38
 
3
39
  - **Agent-friendly UX**:
@@ -64,6 +64,16 @@ Calculating gas Z-Factor of pure methane using DAK and PMC for critical properti
64
64
  **BNS method strongly recommended for high-inert or hydrogen-bearing gases.**
65
65
  When modelling gases with significant CO2 (>10%), H2S, N2, or any H2 content, the ``'BNS'`` Z-factor and critical property methods (tuned 5-component Peng-Robinson EOS) should be used. Standard correlations (DAK/HY/WYW with PMC/SUT) were developed for sweet natural gas and become unreliable at high impurity concentrations. The BNS method handles the full range from pure hydrocarbon to 100% inerts. When ``h2 > 0``, BNS is auto-selected. For pure or high-concentration CO2/H2S/N2 gases, explicitly set ``zmethod='BNS', cmethod='BNS'``.
66
66
 
67
+ .. note::
68
+
69
+ **BNS coupling and user-supplied Tc/Pc.**
70
+ ``zmethod`` and ``cmethod`` are coupled for the BNS framework: if either is BNS, both are forced to BNS (a ``UserWarning`` is emitted if this overrules a user-chosen non-BNS method). Non-BNS methods are not coupled.
71
+
72
+ User-supplied ``tc`` and ``pc`` are always respected, but their meaning depends on the critical-property method:
73
+
74
+ - **SUT / PMC**: ``tc`` and ``pc`` are the *mixture* pseudo-critical values. They replace the correlation output entirely.
75
+ - **BNS**: ``tc`` and ``pc`` are the *inert-free hydrocarbon* pseudo-critical values. They replace only the hydrocarbon pseudo-component in the 5-component EOS; inert Tc/Pc (CO2, H2S, N2, H2) remain the BNS internal per-component constants.
76
+
67
77
  Calculating gas Z-Factor of pure CO2
68
78
 
69
79
  .. code-block:: python
@@ -139,7 +149,11 @@ pyrestoolbox.gas.gas_tc_pc
139
149
 
140
150
  gas_tc_pc(sg, co2 = 0, h2s = 0, n2 = 0, h2 = 0, cmethod = 'PMC', tc = 0, pc = 0, metric = False) -> tuple
141
151
 
142
- Returns a tuple of critical temperature (deg R, or K if metric=True) and critical pressure (psia, or barsa if metric=True) for hydrocarbon gas. If one or both of the tc and pc parameters are set to be non-zero, then this function will return that unchanged value for the corresponding critical parameter.
152
+ Returns a tuple of critical temperature (deg R, or K if metric=True) and critical pressure (psia, or barsa if metric=True). If one or both of the ``tc`` and ``pc`` parameters are set to be non-zero, then this function will return that unchanged value for the corresponding critical parameter.
153
+
154
+ For ``cmethod='SUT'`` and ``cmethod='PMC'``, the returned values describe *mixture* pseudo-critical properties (full gas, inerts included).
155
+
156
+ For ``cmethod='BNS'``, the returned values describe the *inert-free hydrocarbon* pseudo-critical properties only. The supplied inert fractions (``co2``, ``h2s``, ``n2``, ``h2``) are used solely to back out the inert-free hydrocarbon specific gravity from the overall mixture SG; the BNS pseudo-critical correlation is then applied to that hydrocarbon SG. Inert species (CO2, H2S, N2, H2) carry their own per-component Tc/Pc internally within the BNS 5-component PR-EOS, and are *not* included in the value returned here.
143
157
 
144
158
  .. list-table:: Inputs
145
159
  :widths: 10 15 40
@@ -168,10 +182,10 @@ Returns a tuple of critical temperature (deg R, or K if metric=True) and critica
168
182
  - Method for calculating gas critical parameters. `Calculation Methods and Class Objects`_.
169
183
  * - tc
170
184
  - float
171
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
185
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
172
186
  * - pc
173
187
  - float
174
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
188
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
175
189
  * - metric
176
190
  - bool
177
191
  - If True, inputs/outputs use Eclipse METRIC units. Defaults to False
@@ -254,10 +268,10 @@ A float or list / array can be used for p, returning corresponding 1-D array of
254
268
  - Molar fraction of Hydrogen. Defaults to zero if undefined. zmethod and cmethod get overriden to 'BUR' if positive fraction.
255
269
  * - tc
256
270
  - float
257
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
271
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
258
272
  * - pc
259
273
  - float
260
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
274
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
261
275
  * - metric
262
276
  - bool
263
277
  - If True, inputs/outputs use Eclipse METRIC units. Defaults to False
@@ -334,10 +348,10 @@ Furnishing a positive value for zee means it will be used instead of calculating
334
348
  - Molar fraction of Hydrogen. Defaults to zero if undefined. Overrides methods to 'BUR' if positive fraction.
335
349
  * - tc
336
350
  - float
337
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
351
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
338
352
  * - pc
339
353
  - float
340
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
354
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
341
355
  * - zee
342
356
  - float, list or np.array
343
357
  - Z-Factor value, or list of values of same length as P, in case recalculation of Z-Factors is not needed. If undefined, will trigger Z-Factor calculation.
@@ -414,10 +428,10 @@ A float or list / array can be used for p, returning corresponding 1-D array of
414
428
  - Molar fraction of Hydrogen. Defaults to zero if undefined. If positive fraction, cmethod will override to 'BUR'
415
429
  * - tc
416
430
  - float
417
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
431
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
418
432
  * - pc
419
433
  - float
420
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
434
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
421
435
  * - metric
422
436
  - bool
423
437
  - If True, inputs/outputs use Eclipse METRIC units. Defaults to False
@@ -491,10 +505,10 @@ A float or list / array can be used for p, returning corresponding 1-D array of
491
505
  - Molar fraction of Hydrogen. Defaults to zero if undefined. If positive fraction, cmethod will override to 'BUR'
492
506
  * - tc
493
507
  - float
494
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
508
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
495
509
  * - pc
496
510
  - float
497
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
511
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
498
512
  * - metric
499
513
  - bool
500
514
  - If True, inputs/outputs use Eclipse METRIC units. Defaults to False
@@ -567,10 +581,10 @@ A float or list / array can be used for p, returning corresponding 1-D array of
567
581
  - Molar fraction of Hydrogen. Defaults to zero if undefined. If positive fraction, cmethod will override to 'BUR'
568
582
  * - tc
569
583
  - float
570
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
584
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
571
585
  * - pc
572
586
  - float
573
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
587
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
574
588
  * - metric
575
589
  - bool
576
590
  - If True, inputs/outputs use Eclipse METRIC units. Defaults to False
@@ -691,10 +705,10 @@ A float or list / array can be used for poverz, returning corresponding 1-D arra
691
705
  - Molar fraction of Hydrogen. Defaults to zero if undefined. If positive fraction, cmethod will override to 'BUR'
692
706
  * - tc
693
707
  - float
694
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
708
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
695
709
  * - pc
696
710
  - float
697
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
711
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
698
712
  * - rtol
699
713
  - float
700
714
  - relative solution tolerance as compared with abs([User P/Z - Calculated P/Z] / [User P/Z])
@@ -730,7 +744,7 @@ pyrestoolbox.gas.gas_grad2sg
730
744
 
731
745
  gas_grad2sg( grad, p, degf, zmethod='DAK', cmethod='PMC', co2 = 0, h2s = 0, n2 = 0, h2 = 0, tc = 0, pc = 0, rtol = 1E-7, metric = False) -> float
732
746
 
733
- Returns gas specific gravity consistent with observed gas gradient. Calculated through iterative solution method. Will fail if gas SG is below 0.55, or greater than 1.75
747
+ Returns gas specific gravity consistent with observed gas gradient. Calculated through iterative solution method. Bisection bounds span pure H2 (SG ~0.070) to 3.0 to accommodate H2-blend and CO2-rich compositions; solutions outside this range will fail.
734
748
 
735
749
  .. list-table:: Inputs
736
750
  :widths: 10 15 40
@@ -768,10 +782,10 @@ Returns gas specific gravity consistent with observed gas gradient. Calculated t
768
782
  - Molar fraction of Hydrogen. Defaults to zero if undefined. If positive fraction, cmethod will override to 'BUR'
769
783
  * - tc
770
784
  - float
771
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
785
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
772
786
  * - pc
773
787
  - float
774
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
788
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
775
789
  * - rtol
776
790
  - float
777
791
  - relative solution tolerance as compared with abs([User grad - Calculated grad] / [User grad])
@@ -847,10 +861,10 @@ Integrates the equation: m(p) = 2 * p / (ug * z)
847
861
  - Molar fraction of Hydrogen. Defaults to zero if undefined. If positive fraction, cmethod will override to 'BUR'
848
862
  * - tc
849
863
  - float
850
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
864
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
851
865
  * - pc
852
866
  - float
853
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
867
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
854
868
  * - metric
855
869
  - bool
856
870
  - If True, inputs/outputs use Eclipse METRIC units. Defaults to False
@@ -973,10 +987,10 @@ A ``gas_pvt`` object can be provided instead of individual gas composition param
973
987
  - Method for calculating gas critical parameters. `Calculation Methods and Class Objects`_.
974
988
  * - tc
975
989
  - float
976
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
990
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
977
991
  * - pc
978
992
  - float
979
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
993
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
980
994
  * - n2
981
995
  - float
982
996
  - Molar fraction of Nitrogen. Defaults to zero if undefined
@@ -1131,10 +1145,10 @@ A ``gas_pvt`` object can be provided instead of individual gas composition param
1131
1145
  - Method for calculating gas critical parameters. `Calculation Methods and Class Objects`_.
1132
1146
  * - tc
1133
1147
  - float
1134
- - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified
1148
+ - Critical gas temperature (deg R, or K if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Tc (inert Tc stay at BNS internal constants)
1135
1149
  * - pc
1136
1150
  - float
1137
- - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified
1151
+ - Critical gas pressure (psia, or barsa if metric=True). Uses cmethod correlation if not specified. For BNS, overrides only the hydrocarbon pseudo-component Pc (inert Pc stay at BNS internal constants)
1138
1152
  * - n2
1139
1153
  - float
1140
1154
  - Molar fraction of Nitrogen. Defaults to zero if undefined