pathsim-chem 0.2.6__tar.gz → 0.2.7__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 (97) hide show
  1. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/PKG-INFO +1 -1
  2. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/_version.py +3 -3
  3. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/glc.py +18 -90
  4. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem.egg-info/PKG-INFO +1 -1
  5. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem.egg-info/scm_version.json +2 -2
  6. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/tritium/test_glc.py +12 -18
  7. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/.github/workflows/pypi_deployment.yml +0 -0
  8. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/.github/workflows/tests.yml +0 -0
  9. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/.gitignore +0 -0
  10. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/LICENSE +0 -0
  11. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/README.md +0 -0
  12. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/.readthedocs.yaml +0 -0
  13. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/Makefile +0 -0
  14. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/make.bat +0 -0
  15. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/requirements.txt +0 -0
  16. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/_autosummary/pathsim_chem.rst +0 -0
  17. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/_static/custom.css +0 -0
  18. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/api.rst +0 -0
  19. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/conf.py +0 -0
  20. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/cstr_reaction.ipynb +0 -0
  21. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/equation_of_state.ipynb +0 -0
  22. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/flash_distillation.ipynb +0 -0
  23. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/heat_exchanger.ipynb +0 -0
  24. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/multicomponent_flash.ipynb +0 -0
  25. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/point_kinetics.ipynb +0 -0
  26. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/process_flowsheet.ipynb +0 -0
  27. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/valve_characteristics.ipynb +0 -0
  28. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/vapor_pressure_curves.ipynb +0 -0
  29. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/examples/vle_calculation.ipynb +0 -0
  30. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/index.rst +0 -0
  31. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/logos/chem_logo.png +0 -0
  32. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/logos/pathsim_icon.png +0 -0
  33. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/logos/pathsim_logo.png +0 -0
  34. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/modules/tritium.rst +0 -0
  35. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/docs/source/pathsim_docs.mplstyle +0 -0
  36. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/pyproject.toml +0 -0
  37. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/setup.cfg +0 -0
  38. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/__init__.py +0 -0
  39. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/neutronics/__init__.py +0 -0
  40. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/neutronics/point_kinetics.py +0 -0
  41. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/__init__.py +0 -0
  42. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/cstr.py +0 -0
  43. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/distillation.py +0 -0
  44. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/flash_drum.py +0 -0
  45. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/heat_exchanger.py +0 -0
  46. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/heater.py +0 -0
  47. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/mixer.py +0 -0
  48. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/multicomponent_flash.py +0 -0
  49. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/pfr.py +0 -0
  50. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/process/valve.py +0 -0
  51. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/__init__.py +0 -0
  52. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/activity_coefficients.py +0 -0
  53. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/averages.py +0 -0
  54. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/corrections.py +0 -0
  55. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/correlations.py +0 -0
  56. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/enthalpy.py +0 -0
  57. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/equations_of_state.py +0 -0
  58. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/fugacity_coefficients.py +0 -0
  59. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/thermodynamics/reactions.py +0 -0
  60. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/README.md +0 -0
  61. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/__init__.py +0 -0
  62. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/bubbler.py +0 -0
  63. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/ionisation_chamber.py +0 -0
  64. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/residencetime.py +0 -0
  65. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/splitter.py +0 -0
  66. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem/tritium/tcap.py +0 -0
  67. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem.egg-info/SOURCES.txt +0 -0
  68. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem.egg-info/dependency_links.txt +0 -0
  69. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem.egg-info/requires.txt +0 -0
  70. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem.egg-info/scm_file_list.json +0 -0
  71. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/src/pathsim_chem.egg-info/top_level.txt +0 -0
  72. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/neutronics/__init__.py +0 -0
  73. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/neutronics/test_point_kinetics.py +0 -0
  74. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/__init__.py +0 -0
  75. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_cstr.py +0 -0
  76. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_distillation.py +0 -0
  77. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_flash_drum.py +0 -0
  78. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_heat_exchanger.py +0 -0
  79. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_heater.py +0 -0
  80. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_mixer.py +0 -0
  81. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_multicomponent_flash.py +0 -0
  82. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_pfr.py +0 -0
  83. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/process/test_valve.py +0 -0
  84. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/__init__.py +0 -0
  85. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_activity_coefficients.py +0 -0
  86. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_averages.py +0 -0
  87. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_corrections.py +0 -0
  88. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_correlations.py +0 -0
  89. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_enthalpy.py +0 -0
  90. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_equations_of_state.py +0 -0
  91. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_fugacity_coefficients.py +0 -0
  92. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/thermodynamics/test_reactions.py +0 -0
  93. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/tritium/__init__.py +0 -0
  94. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/tritium/test_bubbler.py +0 -0
  95. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/tritium/test_ionisation_chamber.py +0 -0
  96. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/tritium/test_residencetime.py +0 -0
  97. {pathsim_chem-0.2.6 → pathsim_chem-0.2.7}/tests/tritium/test_splitter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pathsim-chem
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Chemical Engineering Blocks for PathSim
5
5
  Author: PathSim Contributors
6
6
  License: MIT
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.2.6'
22
- __version_tuple__ = version_tuple = (0, 2, 6)
21
+ __version__ = version = '0.2.7'
22
+ __version_tuple__ = version_tuple = (0, 2, 7)
23
23
 
24
- __commit_id__ = commit_id = 'g27b677c30'
24
+ __commit_id__ = commit_id = 'g4d89f265b'
@@ -272,106 +272,34 @@ def _process_results(S_ends, params, phys_props, dim_params):
272
272
  P_T2_out = y_T2_out * P_out
273
273
  P_T2_in = y_T2_in * P_in
274
274
 
275
- # Mass balance check
276
- n_T_in_liquid = c_T_in * Q_l # mol/s
277
- n_T_out_liquid = c_T_out * Q_l # mol/s
278
- n_T2_in_gas = P_T2_in * Q_g / (R * T) # mol/s
279
- n_T_in_gas = n_T2_in_gas * 2 # mol/s
275
+ # Tritium molar flows from the converged solution (mol/s). Each T2 molecule
276
+ # carries two tritium atoms.
277
+ n_T_in_liquid = c_T_in * Q_l
278
+ n_T_in_gas = 2 * P_T2_in * Q_g / (R * T)
279
+ n_T_out_liquid = c_T_out * Q_l
280
280
  Q_g_out = Q_g * (P_in / P_out) # m3/s
281
- n_T2_out_gas = P_T2_out * Q_g_out / (R * T) # mol/s
282
- n_T_out_gas = n_T2_out_gas * 2 # mol/s
281
+ n_T_out_gas = 2 * P_T2_out * Q_g_out / (R * T)
283
282
 
284
- # Adjust for any mass balance error
285
- mass_balance_error = (n_T_in_liquid + n_T_in_gas) - (n_T_out_liquid + n_T_out_gas)
286
- n_T_out_gas += mass_balance_error * efficiency
287
- n_T_out_liquid += mass_balance_error * (1 - efficiency)
283
+ n_T_in = n_T_in_liquid + n_T_in_gas
284
+ n_T_out = n_T_out_liquid + n_T_out_gas
288
285
 
289
- results = {
290
- "Total tritium in [mol/s]": n_T_in_liquid + n_T_in_gas,
291
- "Total tritium out [mol/s]": n_T_out_liquid + n_T_out_gas,
292
- "tritium_out_liquid [mol/s]": n_T_out_liquid,
293
- "tritium_out_gas [mol/s]": n_T_out_gas,
294
- "extraction_efficiency [fraction]": efficiency,
286
+ # Mass-balance residual reported as a diagnostic. For closed-closed (C-C)
287
+ # boundary conditions it is at numerical-noise level; for open-closed (O-C)
288
+ # it reflects the dispersive flux neglected by the open inlet condition.
289
+ return {
295
290
  "c_T_outlet [mol/m^3]": c_T_out,
296
- "P_T2_inlet_gas [Pa]": P_T2_in,
297
- "P_T2_outlet_gas [Pa]": P_T2_out,
298
291
  "y_T2_outlet_gas": y_T2_out,
299
- "total_gas_P_inlet [Pa]": P_in,
292
+ "extraction_efficiency [fraction]": efficiency,
300
293
  "total_gas_P_outlet [Pa]": P_out,
301
294
  "liquid_vol_flow [m^3/s]": Q_l,
302
295
  "gas_vol_flow_outlet [m^3/s]": Q_g_out,
296
+ "tritium_out_liquid [mol/s]": n_T_out_liquid,
297
+ "tritium_out_gas [mol/s]": n_T_out_gas,
298
+ "Total tritium in [mol/s]": n_T_in,
299
+ "Total tritium out [mol/s]": n_T_out,
300
+ "mass_balance_residual [mol/s]": n_T_in - n_T_out,
303
301
  }
304
302
 
305
- # Add all calculated parameters to the results dictionary
306
- results.update(phys_props)
307
- results.update(dim_params)
308
-
309
- return results
310
-
311
-
312
- def solve(params):
313
- """
314
- Main solver function for the bubble column model.
315
-
316
- Builds the physical properties and dimensionless groups, then solves the
317
- boundary value problem with the native :class:`~pathsim.blocks.BVP1D` block.
318
-
319
- Args:
320
- params (dict): A dictionary of all input parameters for the model,
321
- including operational conditions and geometry.
322
-
323
- Returns:
324
- list: A list containing:
325
- - dict: A dictionary containing the simulation results.
326
- - pathsim.blocks.BVP1D: The BVP block, exposing the refined mesh
327
- (``.x``) and the sampled solution (``.solution()``).
328
-
329
- Raises:
330
- ValueError: If the calculated gas outlet pressure is non-positive.
331
- RuntimeError: If the BVP solver fails to converge.
332
- """
333
- # Adjust inlet gas concentration to avoid numerical instability at zero
334
- y_T2_in = max(params["y_T2_in"], 1e-20)
335
-
336
- # 1. Calculate physical, hydrodynamic, and mass transfer properties
337
- phys_props = _calculate_properties(params)
338
-
339
- # Pre-solver check for non-physical outlet pressure
340
- P_out = params["P_in"] - (
341
- phys_props["rho_l"] * (1 - phys_props["epsilon_g"]) * g * params["L"]
342
- )
343
- if P_out <= 0:
344
- raise ValueError(
345
- f"Calculated gas outlet pressure is non-positive ({P_out:.2e} Pa). "
346
- "Check input parameters P_in, L, etc."
347
- )
348
-
349
- # 2. Calculate dimensionless groups for the ODE system
350
- dim_params = _calculate_dimensionless_groups(params, phys_props)
351
-
352
- # 3. Solve the boundary value problem with the native BVP1D block, sampling
353
- # the two domain endpoints (xi=0 and xi=1)
354
- bvp = BVP1D(
355
- fun=lambda x, y, p, u: _ode_system(x, y, dim_params),
356
- bc=lambda ya, yb, p, u: _boundary_conditions(
357
- ya, yb, dim_params, y_T2_in, params["BCs"]
358
- ),
359
- n=4,
360
- domain=(0.0, 1.0),
361
- n_nodes=params["elements"] + 1,
362
- x_eval=np.array([0.0, 1.0]),
363
- tol=1e-5,
364
- max_nodes=10000,
365
- )
366
- bvp.update(0.0)
367
- if not bvp.success:
368
- raise RuntimeError("BVP solver failed to converge.")
369
-
370
- # 4. Process and return the results in a dimensional format
371
- results = _process_results(bvp.solution(), params, phys_props, dim_params)
372
-
373
- return [results, bvp]
374
-
375
303
 
376
304
  class GLC(BVP1D):
377
305
  r"""Counter-current bubble column gas-liquid contactor (GLC) for tritium extraction.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pathsim-chem
3
- Version: 0.2.6
3
+ Version: 0.2.7
4
4
  Summary: Chemical Engineering Blocks for PathSim
5
5
  Author: PathSim Contributors
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "0.2.6",
2
+ "tag": "0.2.7",
3
3
  "distance": 0,
4
- "node": "g27b677c3026ba13de35f6534a5a64797a23e046b",
4
+ "node": "g4d89f265b9597ffbb31e325b1e3bb1045a51bf87",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-06-25"
@@ -122,9 +122,16 @@ class TestGLC(unittest.TestCase):
122
122
  x_T_ref * _INPUT[0], places=12)
123
123
  self.assertAlmostEqual(res["y_T2_outlet_gas"], y_T2_ref, places=12)
124
124
 
125
+ #the open inlet condition neglects the dispersive flux, so O-C does not
126
+ #close the mass balance exactly; the residual is small but non-trivial
127
+ #(a few per mille) and is reported honestly rather than hidden
128
+ rel = abs(res["mass_balance_residual [mol/s]"]) / res["Total tritium in [mol/s]"]
129
+ self.assertGreater(rel, 1e-6)
130
+ self.assertLess(rel, 1e-2)
131
+
125
132
 
126
133
  def test_results_physical(self):
127
- """The dimensional results are physically sensible and mass conserving."""
134
+ """The dimensional results are physically sensible."""
128
135
  blk = GLC(BCs="C-C", **_BASE)
129
136
  blk.inputs.update_from_array(np.array(_INPUT))
130
137
  blk.update(0.0)
@@ -138,9 +145,10 @@ class TestGLC(unittest.TestCase):
138
145
  #hydrostatic head drops the gas pressure below the inlet pressure
139
146
  self.assertLess(res["total_gas_P_outlet [Pa]"], _BASE["P_in"])
140
147
 
141
- #closed tritium mass balance
142
- self.assertAlmostEqual(res["Total tritium in [mol/s]"],
143
- res["Total tritium out [mol/s]"], places=12)
148
+ #closed-closed boundary conditions conserve tritium to numerical noise;
149
+ #the residual is reported, not redistributed back into the outputs
150
+ rel = abs(res["mass_balance_residual [mol/s]"]) / res["Total tritium in [mol/s]"]
151
+ self.assertLess(rel, 1e-6)
144
152
 
145
153
 
146
154
  def test_output_ports(self):
@@ -197,20 +205,6 @@ class TestGLC(unittest.TestCase):
197
205
  bvpmod.solve_bvp = orig
198
206
 
199
207
 
200
- def test_solve_function(self):
201
- """The standalone solve() helper returns results and the BVP block."""
202
- p = dict(_BASE)
203
- p.update(elements=20, BCs="C-C", c_T_in=_INPUT[0], flow_l=_INPUT[1],
204
- y_T2_in=_INPUT[2], flow_g=_INPUT[3])
205
- results, bvp = glc.solve(p)
206
-
207
- self.assertIsInstance(bvp, BVP1D)
208
- self.assertTrue(bvp.success)
209
- x_T_ref, _ = _reference("C-C")
210
- self.assertAlmostEqual(results["c_T_outlet [mol/m^3]"],
211
- x_T_ref * _INPUT[0], places=12)
212
-
213
-
214
208
  def test_non_physical_pressure_raises(self):
215
209
  """A column tall enough to drive the outlet pressure non-positive fails."""
216
210
  #very tall column at low inlet pressure -> hydrostatic head exceeds P_in
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes