processforge 0.3.19__tar.gz → 0.3.20__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 (139) hide show
  1. {processforge-0.3.19/src/processforge.egg-info → processforge-0.3.20}/PKG-INFO +1 -1
  2. {processforge-0.3.19 → processforge-0.3.20}/pyproject.toml +1 -1
  3. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/run.py +19 -0
  4. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/state.py +35 -15
  5. {processforge-0.3.19 → processforge-0.3.20/src/processforge.egg-info}/PKG-INFO +1 -1
  6. {processforge-0.3.19 → processforge-0.3.20}/LICENSE +0 -0
  7. {processforge-0.3.19 → processforge-0.3.20}/MANIFEST.in +0 -0
  8. {processforge-0.3.19 → processforge-0.3.20}/README.md +0 -0
  9. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/closed-loop-chain.json +0 -0
  10. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/coupled/msre_coupled.json +0 -0
  11. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/custom/crimson/MUWS_HB.json +0 -0
  12. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/custom/simple_hyrdaulic_scheme.json +0 -0
  13. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/festim/hydrogen_transport_1d.json +0 -0
  14. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/festim/tds_tungsten.json +0 -0
  15. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/hydraulic-chain.json +0 -0
  16. {processforge-0.3.19 → processforge-0.3.20}/flowsheets/openmc/msre_eigenvalue.json +0 -0
  17. {processforge-0.3.19 → processforge-0.3.20}/setup.cfg +0 -0
  18. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/__init__.py +0 -0
  19. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/__main__.py +0 -0
  20. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/_schema.py +0 -0
  21. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/analysis/__init__.py +0 -0
  22. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/analysis/dof.py +0 -0
  23. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/api/__init__.py +0 -0
  24. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/api/serve.py +0 -0
  25. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/__init__.py +0 -0
  26. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/apply.py +0 -0
  27. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/common.py +0 -0
  28. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/diagram.py +0 -0
  29. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/display.py +0 -0
  30. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/export_fmu.py +0 -0
  31. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/export_modelica.py +0 -0
  32. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/init.py +0 -0
  33. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/plan.py +0 -0
  34. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/cli/validate.py +0 -0
  35. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/compose.py +0 -0
  36. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/coupling.py +0 -0
  37. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/__init__.py +0 -0
  38. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/backends/__init__.py +0 -0
  39. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/backends/base.py +0 -0
  40. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/backends/casadi_backend.py +0 -0
  41. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/backends/pyomo_backend.py +0 -0
  42. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/backends/scipy_backend.py +0 -0
  43. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/flowsheet.py +0 -0
  44. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/jacobian.py +0 -0
  45. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/mixin.py +0 -0
  46. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/solver.py +0 -0
  47. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/stream_var.py +0 -0
  48. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/units/__init__.py +0 -0
  49. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/units/flash_eo.py +0 -0
  50. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/units/heater_eo.py +0 -0
  51. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/units/pipes_eo.py +0 -0
  52. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/units/pump_eo.py +0 -0
  53. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/units/strainer_eo.py +0 -0
  54. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/eo/units/valve_eo.py +0 -0
  55. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/flowsheet.py +0 -0
  56. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/fmu/__init__.py +0 -0
  57. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/fmu/_fmi_vars.py +0 -0
  58. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/fmu/builder.py +0 -0
  59. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/fmu/slave_template.py +0 -0
  60. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/lock.py +0 -0
  61. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/modelica/__init__.py +0 -0
  62. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/modelica/mo_writer.py +0 -0
  63. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/modelica/omc_runner.py +0 -0
  64. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/modelica/transpiler.py +0 -0
  65. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/modelica/unit_equations.py +0 -0
  66. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/output_collector.py +0 -0
  67. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/pcl/__init__.py +0 -0
  68. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/pcl/compiler.py +0 -0
  69. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/pcl/namespace.py +0 -0
  70. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/persistence/__init__.py +0 -0
  71. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/persistence/archive.py +0 -0
  72. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/persistence/artifact_store.py +0 -0
  73. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/provenance.py +0 -0
  74. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/__init__.py +0 -0
  75. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/base.py +0 -0
  76. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/base_jacobian_mixin.py +0 -0
  77. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/cantera_jacobian.py +0 -0
  78. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/cantera_provider.py +0 -0
  79. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/container_client.py +0 -0
  80. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/coolprop_provider.py +0 -0
  81. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/errors.py +0 -0
  82. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/festim_provider.py +0 -0
  83. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/jacobian_contributor.py +0 -0
  84. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/manager.py +0 -0
  85. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/modelica_jacobian.py +0 -0
  86. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/modelica_provider.py +0 -0
  87. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/openmc_provider.py +0 -0
  88. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/reference_state_registry.py +0 -0
  89. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/providers/registry.py +0 -0
  90. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/quantity.py +0 -0
  91. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/result.py +0 -0
  92. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/result_schema.py +0 -0
  93. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/schemas/__init__.py +0 -0
  94. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/schemas/festim/festim_model.py +0 -0
  95. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/schemas/flowsheet_schema.json +0 -0
  96. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/schemas/openmc/openmc_model.py +0 -0
  97. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/simulate.py +0 -0
  98. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/solver.py +0 -0
  99. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/thermo.py +0 -0
  100. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/types.py +0 -0
  101. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/__init__.py +0 -0
  102. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/base.py +0 -0
  103. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/cstr.py +0 -0
  104. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/flash.py +0 -0
  105. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/heater.py +0 -0
  106. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/pfr.py +0 -0
  107. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/pipes.py +0 -0
  108. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/pump.py +0 -0
  109. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/registry.py +0 -0
  110. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/solver_unit.py +0 -0
  111. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/strainer.py +0 -0
  112. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/tank.py +0 -0
  113. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/units/valve.py +0 -0
  114. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/__init__.py +0 -0
  115. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/flowsheet_diagram.py +0 -0
  116. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/mermaid_diagram.py +0 -0
  117. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/s3_upload.py +0 -0
  118. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/topology.py +0 -0
  119. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/unit_consistency.py +0 -0
  120. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/validate_flowsheet.py +0 -0
  121. {processforge-0.3.19 → processforge-0.3.20}/src/processforge/utils/validation.py +0 -0
  122. {processforge-0.3.19 → processforge-0.3.20}/src/processforge.egg-info/SOURCES.txt +0 -0
  123. {processforge-0.3.19 → processforge-0.3.20}/src/processforge.egg-info/dependency_links.txt +0 -0
  124. {processforge-0.3.19 → processforge-0.3.20}/src/processforge.egg-info/entry_points.txt +0 -0
  125. {processforge-0.3.19 → processforge-0.3.20}/src/processforge.egg-info/requires.txt +0 -0
  126. {processforge-0.3.19 → processforge-0.3.20}/src/processforge.egg-info/top_level.txt +0 -0
  127. {processforge-0.3.19 → processforge-0.3.20}/tests/test_cli.py +0 -0
  128. {processforge-0.3.19 → processforge-0.3.20}/tests/test_container_client.py +0 -0
  129. {processforge-0.3.19 → processforge-0.3.20}/tests/test_coupling.py +0 -0
  130. {processforge-0.3.19 → processforge-0.3.20}/tests/test_festim_provider.py +0 -0
  131. {processforge-0.3.19 → processforge-0.3.20}/tests/test_festim_schema.py +0 -0
  132. {processforge-0.3.19 → processforge-0.3.20}/tests/test_init.py +0 -0
  133. {processforge-0.3.19 → processforge-0.3.20}/tests/test_openmc_provider.py +0 -0
  134. {processforge-0.3.19 → processforge-0.3.20}/tests/test_provider_errors.py +0 -0
  135. {processforge-0.3.19 → processforge-0.3.20}/tests/test_providers.py +0 -0
  136. {processforge-0.3.19 → processforge-0.3.20}/tests/test_result_zarr.py +0 -0
  137. {processforge-0.3.19 → processforge-0.3.20}/tests/test_s3_upload.py +0 -0
  138. {processforge-0.3.19 → processforge-0.3.20}/tests/test_state.py +0 -0
  139. {processforge-0.3.19 → processforge-0.3.20}/tests/test_types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: processforge
3
- Version: 0.3.19
3
+ Version: 0.3.20
4
4
  Summary: A Python-based process simulation framework for chemical engineering applications.
5
5
  Author-email: Processforge Team <team@processforge.dev>
6
6
  License-Expression: BSD-3-Clause
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "processforge"
7
- version = "0.3.19"
7
+ version = "0.3.20"
8
8
  description = "A Python-based process simulation framework for chemical engineering applications."
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
@@ -102,6 +102,7 @@ def run(
102
102
  raise SystemExit(1)
103
103
 
104
104
  run_info = build_run_info(config, x0=x0, var_names=var_names)
105
+ snap_x, snap_vn, snap_backend, snap_ok = x0, var_names, "dynamic", True
105
106
  else:
106
107
  # Pass None so EOFlowsheet resolves backend from config (with scipy default).
107
108
  fs = EOFlowsheet(config, backend=None)
@@ -117,6 +118,9 @@ def run(
117
118
  logger.warning("Steady-state simulation did NOT converge. Results may be unreliable.")
118
119
 
119
120
  run_info = build_run_info(config, x0=fs.x0, var_names=fs.var_names)
121
+ snap_x, snap_vn = fs.x_converged, fs.var_names
122
+ snap_backend = getattr(fs, "backend", "scipy")
123
+ snap_ok = bool(getattr(fs, "converged", False))
120
124
 
121
125
  # Propagate run context to any containerized providers so their S3 uploads
122
126
  # are keyed by the same run_id/flowsheet_hash as this archive run.
@@ -134,6 +138,21 @@ def run(
134
138
  }
135
139
  archive.save_run(manifest, stream_results=stream_results)
136
140
 
141
+ # Persist a StateManager snapshot so `pf plan` (and `pf apply`) can diff
142
+ # against this run as a baseline. Without it, `pf plan` always reports
143
+ # "No prior state found" and never surfaces flowsheet edits.
144
+ if (is_dynamic or snap_ok) and snap_x is not None:
145
+ try:
146
+ from .common import build_run_metadata, save_snapshot
147
+
148
+ meta = build_run_metadata(config, 1e-6, 50, snap_backend)
149
+ save_snapshot(
150
+ archive, config, snap_x, snap_vn,
151
+ metadata=meta, parent_snapshot_id=None, label="run state",
152
+ )
153
+ except Exception as e:
154
+ logger.warning(f"Failed to save state snapshot: {type(e).__name__}: {e}")
155
+
137
156
  # Always persist a Zarr copy of the standardized outputs (fields + artifacts)
138
157
  # inside the archive. Works for every provider (OpenMC, CoolProp, FESTIM,
139
158
  # Cantera) and for both local and remote docker runs — remote artifacts
@@ -302,27 +302,47 @@ class StateManager:
302
302
  if ov != nv:
303
303
  changes.append(f"{key}: {ov!r} → {nv!r}")
304
304
 
305
- # Parameter changes (scalar unit params, not nested "parameters" dict)
306
- all_keys = set(old_cfg) | set(new_cfg)
307
- skip = {"type", "in", "out", "out_vap", "out_liq", "provider", "parameters"}
308
- for k in all_keys - skip:
309
- ov, nv = old_cfg.get(k), new_cfg.get(k)
310
- if ov != nv:
311
- changes.append(f"{k}: {ov} → {nv}")
312
-
313
- # Nested "parameters" dict
314
- old_params = old_cfg.get("parameters", {})
315
- new_params = new_cfg.get("parameters", {})
316
- for pk in set(old_params) | set(new_params):
317
- ov, nv = old_params.get(pk), new_params.get(pk)
318
- if ov != nv:
319
- changes.append(f"parameters.{pk}: {ov} → {nv}")
305
+ # Parameter changes recurse into nested dicts so leaf values
306
+ # (e.g. solver_config.batches) are reported individually rather
307
+ # than dumping the whole dict.
308
+ changes.extend(
309
+ StateManager._diff_params(old_cfg, new_cfg)
310
+ )
320
311
 
321
312
  if changes:
322
313
  modified[name] = {"type": new_cfg.get("type", "?"), "changes": changes}
323
314
 
324
315
  return {"added": added, "removed": removed, "modified": modified}
325
316
 
317
+ # ------------------------------------------------------------------
318
+ # Structural-diff helpers
319
+ # ------------------------------------------------------------------
320
+ @staticmethod
321
+ def _diff_params(
322
+ old_cfg: dict, new_cfg: dict, prefix: str = "", skip: set | None = None
323
+ ) -> list[str]:
324
+ """Recursively collect changed scalar/leaf params between two dicts.
325
+
326
+ Nested dicts are descended (``solver_config.batches: 25 → 999``) so the
327
+ structural diff reports leaf-level changes instead of whole-dict blobs.
328
+ """
329
+ if skip is None:
330
+ skip = {"type", "in", "out", "out_vap", "out_liq", "provider"}
331
+ all_keys = set(old_cfg) | set(new_cfg)
332
+ if not prefix:
333
+ all_keys -= skip
334
+ changes: list[str] = []
335
+ for k in all_keys:
336
+ ov, nv = old_cfg.get(k), new_cfg.get(k)
337
+ label = f"{prefix}{k}"
338
+ if isinstance(ov, dict) and isinstance(nv, dict):
339
+ changes.extend(
340
+ StateManager._diff_params(ov, nv, prefix=f"{label}.", skip=set())
341
+ )
342
+ elif ov != nv:
343
+ changes.append(f"{label}: {ov} → {nv}")
344
+ return changes
345
+
326
346
  # ------------------------------------------------------------------
327
347
  # State → stream dict conversion (for dynamic t=0 initialisation)
328
348
  # ------------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: processforge
3
- Version: 0.3.19
3
+ Version: 0.3.20
4
4
  Summary: A Python-based process simulation framework for chemical engineering applications.
5
5
  Author-email: Processforge Team <team@processforge.dev>
6
6
  License-Expression: BSD-3-Clause
File without changes
File without changes
File without changes
File without changes