processforge 0.2.30__tar.gz → 0.2.34__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.

Potentially problematic release.


This version of processforge might be problematic. Click here for more details.

Files changed (113) hide show
  1. processforge-0.2.34/PKG-INFO +122 -0
  2. processforge-0.2.34/README.md +62 -0
  3. {processforge-0.2.30 → processforge-0.2.34}/flowsheets/closed-loop-chain.json +1 -1
  4. processforge-0.2.34/flowsheets/custom/simple_hyrdaulic_scheme.json +202 -0
  5. processforge-0.2.34/flowsheets/festim/hydrogen_transport_1d.json +70 -0
  6. {processforge-0.2.30 → processforge-0.2.34}/flowsheets/hydraulic-chain.json +1 -1
  7. {processforge-0.2.30 → processforge-0.2.34}/flowsheets/openmc/msre_eigenvalue.json +2 -1
  8. {processforge-0.2.30 → processforge-0.2.34}/pyproject.toml +6 -10
  9. processforge-0.2.34/src/processforge/compose.py +47 -0
  10. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/flowsheet.py +11 -47
  11. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/jacobian.py +7 -4
  12. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/solver.py +0 -1
  13. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/flowsheet.py +149 -162
  14. processforge-0.2.34/src/processforge/lock.py +41 -0
  15. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/__init__.py +2 -1
  16. processforge-0.2.34/src/processforge/providers/festim_provider.py +411 -0
  17. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/manager.py +95 -50
  18. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/openmc_provider.py +8 -1
  19. processforge-0.2.34/src/processforge/providers/registry.py +185 -0
  20. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/result.py +3 -5
  21. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/schemas/flowsheet_schema.json +18 -6
  22. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/schemas/openmc/openmc_model.py +2 -2
  23. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/simulate.py +283 -20
  24. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/state.py +19 -6
  25. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/types.py +121 -1
  26. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/__init__.py +3 -0
  27. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/cstr.py +5 -0
  28. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/flash.py +9 -6
  29. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/heater.py +9 -5
  30. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/pfr.py +4 -0
  31. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/pipes.py +4 -0
  32. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/pump.py +4 -0
  33. processforge-0.2.34/src/processforge/units/registry.py +24 -0
  34. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/solver_unit.py +4 -0
  35. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/strainer.py +4 -0
  36. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/tank.py +4 -0
  37. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/valve.py +4 -0
  38. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/utils/validate_flowsheet.py +158 -11
  39. processforge-0.2.34/src/processforge.egg-info/PKG-INFO +122 -0
  40. {processforge-0.2.30 → processforge-0.2.34}/src/processforge.egg-info/SOURCES.txt +11 -6
  41. {processforge-0.2.30 → processforge-0.2.34}/src/processforge.egg-info/entry_points.txt +0 -1
  42. {processforge-0.2.30 → processforge-0.2.34}/src/processforge.egg-info/requires.txt +4 -7
  43. processforge-0.2.34/tests/test_festim_provider.py +596 -0
  44. processforge-0.2.34/tests/test_init.py +256 -0
  45. processforge-0.2.34/tests/test_providers.py +318 -0
  46. processforge-0.2.34/tests/test_state.py +125 -0
  47. processforge-0.2.30/PKG-INFO +0 -615
  48. processforge-0.2.30/README.md +0 -553
  49. processforge-0.2.30/src/processforge/api/app.py +0 -87
  50. processforge-0.2.30/src/processforge/api/models.py +0 -83
  51. processforge-0.2.30/src/processforge/api/runner.py +0 -164
  52. processforge-0.2.30/src/processforge/api/serve.py +0 -41
  53. processforge-0.2.30/src/processforge/providers/registry.py +0 -52
  54. processforge-0.2.30/src/processforge/utils/__init__.py +0 -0
  55. processforge-0.2.30/src/processforge.egg-info/PKG-INFO +0 -615
  56. {processforge-0.2.30 → processforge-0.2.34}/LICENSE +0 -0
  57. {processforge-0.2.30 → processforge-0.2.34}/MANIFEST.in +0 -0
  58. {processforge-0.2.30 → processforge-0.2.34}/setup.cfg +0 -0
  59. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/__init__.py +0 -0
  60. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/__main__.py +0 -0
  61. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/_schema.py +0 -0
  62. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/analysis/__init__.py +0 -0
  63. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/analysis/dof.py +0 -0
  64. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/__init__.py +0 -0
  65. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/backends/__init__.py +0 -0
  66. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/backends/base.py +0 -0
  67. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/backends/casadi_backend.py +0 -0
  68. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/backends/pyomo_backend.py +0 -0
  69. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/backends/scipy_backend.py +0 -0
  70. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/mixin.py +0 -0
  71. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/stream_var.py +0 -0
  72. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/units/__init__.py +0 -0
  73. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/units/flash_eo.py +0 -0
  74. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/units/heater_eo.py +0 -0
  75. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/units/pipes_eo.py +0 -0
  76. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/units/pump_eo.py +0 -0
  77. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/units/strainer_eo.py +0 -0
  78. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/eo/units/valve_eo.py +0 -0
  79. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/fmu/__init__.py +0 -0
  80. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/fmu/_fmi_vars.py +0 -0
  81. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/fmu/builder.py +0 -0
  82. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/fmu/slave_template.py +0 -0
  83. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/modelica/__init__.py +0 -0
  84. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/modelica/mo_writer.py +0 -0
  85. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/modelica/omc_runner.py +0 -0
  86. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/modelica/transpiler.py +0 -0
  87. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/modelica/unit_equations.py +0 -0
  88. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/pcl/__init__.py +0 -0
  89. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/pcl/compiler.py +0 -0
  90. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/pcl/namespace.py +0 -0
  91. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/provenance.py +0 -0
  92. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/base.py +0 -0
  93. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/base_jacobian_mixin.py +0 -0
  94. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/cantera_jacobian.py +0 -0
  95. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/cantera_provider.py +0 -0
  96. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/coolprop_provider.py +0 -0
  97. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/jacobian_contributor.py +0 -0
  98. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/modelica_jacobian.py +0 -0
  99. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/modelica_provider.py +0 -0
  100. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/providers/reference_state_registry.py +0 -0
  101. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/schemas/__init__.py +0 -0
  102. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/solver.py +0 -0
  103. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/thermo.py +0 -0
  104. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/provider_mixin.py +0 -0
  105. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/units/solver.py +0 -0
  106. {processforge-0.2.30/src/processforge/api → processforge-0.2.34/src/processforge/utils}/__init__.py +0 -0
  107. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/utils/flowsheet_diagram.py +0 -0
  108. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/utils/mermaid_diagram.py +0 -0
  109. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/utils/topology.py +0 -0
  110. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/utils/unit_consistency.py +0 -0
  111. {processforge-0.2.30 → processforge-0.2.34}/src/processforge/utils/validation.py +0 -0
  112. {processforge-0.2.30 → processforge-0.2.34}/src/processforge.egg-info/dependency_links.txt +0 -0
  113. {processforge-0.2.30 → processforge-0.2.34}/src/processforge.egg-info/top_level.txt +0 -0
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: processforge
3
+ Version: 0.2.34
4
+ Summary: A Python-based process simulation framework for chemical engineering applications.
5
+ Author-email: Processforge Team <team@processforge.dev>
6
+ License-Expression: BSD-3-Clause
7
+ Project-URL: Homepage, https://github.com/urjanova/processforge
8
+ Project-URL: Repository, https://github.com/urjanova/processforge
9
+ Project-URL: Issues, https://github.com/urjanova/processforge/issues
10
+ Keywords: process,simulation,chemical,engineering,flowsheet
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
18
+ Classifier: Topic :: Scientific/Engineering
19
+ Requires-Python: >=3.12
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: numpy>=2.0
23
+ Requires-Dist: pydantic>=2.0
24
+ Requires-Dist: scipy>=1.14
25
+ Requires-Dist: matplotlib>=3.9
26
+ Requires-Dist: loguru>=0.7
27
+ Requires-Dist: jsonschema>=4.20
28
+ Requires-Dist: graphviz>=0.20
29
+ Requires-Dist: pandas>=2.2
30
+ Requires-Dist: zarr>=3.0
31
+ Requires-Dist: coolprop>=7.2.0
32
+ Requires-Dist: pi>=0.1.2
33
+ Requires-Dist: pip>=26.1.2
34
+ Provides-Extra: eo
35
+ Requires-Dist: pyomo>=6.7; extra == "eo"
36
+ Provides-Extra: eo-casadi
37
+ Requires-Dist: pyomo>=6.7; extra == "eo-casadi"
38
+ Requires-Dist: casadi>=3.6; extra == "eo-casadi"
39
+ Provides-Extra: fmu
40
+ Requires-Dist: pythonfmu>=0.6; extra == "fmu"
41
+ Provides-Extra: modelica
42
+ Requires-Dist: OMPython>=4.0.0; extra == "modelica"
43
+ Requires-Dist: fmpy>=0.3; extra == "modelica"
44
+ Provides-Extra: cantera
45
+ Requires-Dist: cantera>=3.0; extra == "cantera"
46
+ Provides-Extra: coolprop
47
+ Requires-Dist: coolprop>=6.6; extra == "coolprop"
48
+ Provides-Extra: pcl
49
+ Requires-Dist: pint>=0.24; extra == "pcl"
50
+ Provides-Extra: dev
51
+ Requires-Dist: pytest>=7.0; extra == "dev"
52
+ Requires-Dist: black; extra == "dev"
53
+ Requires-Dist: flake8; extra == "dev"
54
+ Requires-Dist: build; extra == "dev"
55
+ Requires-Dist: twine; extra == "dev"
56
+ Provides-Extra: docs
57
+ Requires-Dist: sphinx; extra == "docs"
58
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
59
+ Dynamic: license-file
60
+
61
+ # Processforge
62
+
63
+ ![processforge-logo](images/processforge-logo.svg)
64
+
65
+ A lightweight Python framework for process simulation, coupling hydraulic, thermal, and reactor workflows.
66
+
67
+ ## Install
68
+
69
+ ```bash
70
+ uv add processforge
71
+ ```
72
+
73
+ For CoolProp-backed units:
74
+
75
+ ```bash
76
+ uv add "processforge[coolprop]"
77
+ ```
78
+
79
+ Optional solver backends:
80
+
81
+ ```bash
82
+ uv add "processforge[eo]"
83
+ uv add "processforge[eo-casadi]"
84
+ uv add "processforge[modelica]"
85
+ ```
86
+
87
+ ## Quick start
88
+
89
+ Use `plan` to validate and preview changes, then `apply` to solve and store a snapshot. For flowsheets without Tank units, use `apply` to solve with the EO solver.
90
+
91
+ ```bash
92
+ pf init
93
+ pf plan flowsheets/hydraulic-chain.json
94
+ pf apply flowsheets/hydraulic-chain.json
95
+ ```
96
+ For flowsheets with Tank units, use `run` to solve with the SM solver. For direct run mode (for dynamic flowsheets with Tank units), use `run`:
97
+
98
+ ```bash
99
+ pf run flowsheets/hydraulic-chain.json
100
+ ```
101
+
102
+ ## Python API
103
+
104
+ ```python
105
+ from processforge import EOFlowsheet, validate_flowsheet
106
+ config = validate_flowsheet("flowsheets/hydraulic-chain.json")
107
+ fs = EOFlowsheet(config, backend="scipy")
108
+ results = fs.run()
109
+ ```
110
+
111
+ ## Usage and Docker
112
+ Processforge is also available as Docker images, and can be run in the cloud. See the [usage guide](docs/usage.md) for CLI commands, workflows, Docker, and cloud notes.
113
+
114
+ ## Flowsheets
115
+ The core of Processforge is the flowsheet JSON format, which defines materials, units, and recycle rules. See below for more information on the formats and example flowsheets.
116
+ - [docs/flowsheets.md](docs/flowsheets.md) : flowsheet JSON format, materials, units, and recycle rules
117
+ - [flowsheets/](flowsheets/) : example flowsheets shipped with the repo
118
+
119
+
120
+ ## License
121
+
122
+ BSD 3-Clause License
@@ -0,0 +1,62 @@
1
+ # Processforge
2
+
3
+ ![processforge-logo](images/processforge-logo.svg)
4
+
5
+ A lightweight Python framework for process simulation, coupling hydraulic, thermal, and reactor workflows.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ uv add processforge
11
+ ```
12
+
13
+ For CoolProp-backed units:
14
+
15
+ ```bash
16
+ uv add "processforge[coolprop]"
17
+ ```
18
+
19
+ Optional solver backends:
20
+
21
+ ```bash
22
+ uv add "processforge[eo]"
23
+ uv add "processforge[eo-casadi]"
24
+ uv add "processforge[modelica]"
25
+ ```
26
+
27
+ ## Quick start
28
+
29
+ Use `plan` to validate and preview changes, then `apply` to solve and store a snapshot. For flowsheets without Tank units, use `apply` to solve with the EO solver.
30
+
31
+ ```bash
32
+ pf init
33
+ pf plan flowsheets/hydraulic-chain.json
34
+ pf apply flowsheets/hydraulic-chain.json
35
+ ```
36
+ For flowsheets with Tank units, use `run` to solve with the SM solver. For direct run mode (for dynamic flowsheets with Tank units), use `run`:
37
+
38
+ ```bash
39
+ pf run flowsheets/hydraulic-chain.json
40
+ ```
41
+
42
+ ## Python API
43
+
44
+ ```python
45
+ from processforge import EOFlowsheet, validate_flowsheet
46
+ config = validate_flowsheet("flowsheets/hydraulic-chain.json")
47
+ fs = EOFlowsheet(config, backend="scipy")
48
+ results = fs.run()
49
+ ```
50
+
51
+ ## Usage and Docker
52
+ Processforge is also available as Docker images, and can be run in the cloud. See the [usage guide](docs/usage.md) for CLI commands, workflows, Docker, and cloud notes.
53
+
54
+ ## Flowsheets
55
+ The core of Processforge is the flowsheet JSON format, which defines materials, units, and recycle rules. See below for more information on the formats and example flowsheets.
56
+ - [docs/flowsheets.md](docs/flowsheets.md) : flowsheet JSON format, materials, units, and recycle rules
57
+ - [flowsheets/](flowsheets/) : example flowsheets shipped with the repo
58
+
59
+
60
+ ## License
61
+
62
+ BSD 3-Clause License
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "material_mixes": {
47
47
  "Benzene_Toluene_Mix": {
48
- "friendly_material_mix_id": 1,
48
+ "id": 1,
49
49
  "percent_type": "ao",
50
50
  "components": [
51
51
  {"name": "Benzene", "fraction": 0.5},
@@ -0,0 +1,202 @@
1
+ {
2
+ "metadata": {
3
+ "name": "Hydraulic Chain Example",
4
+ "description": "A two-pump, one-valve, one-strainer steady-state hydraulic system.",
5
+ "version": "2.0"
6
+ },
7
+ "providers": {
8
+ "coolprop": {
9
+ "type": "coolprop"
10
+ }
11
+ },
12
+ "materials": {
13
+ "Benzene": {
14
+ "id": 1
15
+ },
16
+ "Toluene": {
17
+ "id": 2
18
+ },
19
+ "Steel": {
20
+ "id": 3
21
+ }
22
+ },
23
+ "material_mixes": {
24
+ "Benzene_Toluene_Mix": {
25
+ "friendly_material_mix_id": 1,
26
+ "percent_type": "ao",
27
+ "components": [
28
+ {"name": "Benzene", "fraction": 0.8},
29
+ {"name": "Toluene", "fraction": 0.2}
30
+ ]
31
+ }
32
+ },
33
+ "streams": {
34
+ "feed": {
35
+ "T": 298.15,
36
+ "P": 101325,
37
+ "flowrate": 38,
38
+ "material_mix": 1
39
+ }
40
+ },
41
+ "units": {
42
+ "pipe_1": {
43
+ "type": "Pipes",
44
+ "in": "feed",
45
+ "out": "after_pipe_1",
46
+ "delta_p": 1000.0,
47
+ "diameter": 0.040,
48
+ "material": 3
49
+ },
50
+ "valve_1": {
51
+ "type": "Valve",
52
+ "in": "after_pipe_1",
53
+ "out": "after_valve_1",
54
+ "pressure_ratio": 0.5,
55
+ "material": 3
56
+ },
57
+ "pipe_2": {
58
+ "type": "Pipes",
59
+ "in": "after_valve_1",
60
+ "out": "after_pipe_2",
61
+ "delta_p": 1000.0,
62
+ "diameter": 0.08,
63
+ "material": 3
64
+ },
65
+ "pump_1": {
66
+ "type": "Pump",
67
+ "in": "after_pipe_2",
68
+ "out": "after_pump_1",
69
+ "deltaP": 600000.0,
70
+ "efficiency": 0.75,
71
+ "material": 3
72
+ },
73
+ "pipe_3": {
74
+ "type": "Pipes",
75
+ "in": "after_pump_1",
76
+ "out": "after_pipe_3",
77
+ "delta_p": 1000.0,
78
+ "diameter": 0.08,
79
+ "material": 3
80
+ },
81
+ "strainer_1": {
82
+ "type": "Strainer",
83
+ "in": "after_pipe_3",
84
+ "out": "after_strainer_1",
85
+ "deltaP": 5000.0,
86
+ "material": 3
87
+ },
88
+ "pipe_4": {
89
+ "type": "Pipes",
90
+ "in": "after_strainer_1",
91
+ "out": "after_pipe_4",
92
+ "delta_p": 1000.0,
93
+ "diameter": 0.08,
94
+ "material": 3
95
+ },
96
+ "pipe_1a": {
97
+ "type": "Pipes",
98
+ "in": "after_strainer_1",
99
+ "out": "after_pipe_1a",
100
+ "delta_p": 1000.0,
101
+ "diameter": 0.08,
102
+ "material": 3
103
+ },
104
+ "valve_1a": {
105
+ "type": "Valve",
106
+ "in": "after_pipe_1a",
107
+ "out": "after_valve_1a",
108
+ "pressure_ratio": 0.5,
109
+ "material": 3
110
+ },
111
+ "pipe_2a": {
112
+ "type": "Pipes",
113
+ "in": "after_valve_1a",
114
+ "out": "after_pipe_2a",
115
+ "delta_p": 1000.0,
116
+ "diameter": 0.08,
117
+ "material": 3
118
+ },
119
+ "valve_2": {
120
+ "type": "Valve",
121
+ "in": "after_pipe_4",
122
+ "out": "after_valve_2",
123
+ "pressure_ratio": 0.5,
124
+ "material": 3
125
+ },
126
+ "pipe_5": {
127
+ "type": "Pipes",
128
+ "in": "after_valve_2",
129
+ "out": "after_pipe_5",
130
+ "delta_p": 1000.0,
131
+ "diameter": 0.08,
132
+ "material": 3
133
+ },
134
+ "pump_2": {
135
+ "type": "Pump",
136
+ "in": "after_pipe_5",
137
+ "out": "after_pump_2",
138
+ "deltaP": 600000.0,
139
+ "efficiency": 0.75,
140
+ "material": 3
141
+ },
142
+ "pipe_6": {
143
+ "type": "Pipes",
144
+ "in": "after_pump_2",
145
+ "out": "after_pipe_6",
146
+ "delta_p": 1000.0,
147
+ "diameter": 0.08,
148
+ "material": 3
149
+ },
150
+ "valve_3": {
151
+ "type": "Valve",
152
+ "in": "after_pipe_6",
153
+ "out": "after_valve_3",
154
+ "pressure_ratio": 0.5,
155
+ "material": 3
156
+ },
157
+ "pipe_7": {
158
+ "type": "Pipes",
159
+ "in": "after_valve_3",
160
+ "out": "after_pipe_7",
161
+ "delta_p": 1000.0,
162
+ "diameter": 0.08,
163
+ "material": 3
164
+ },
165
+ "valve_4": {
166
+ "type": "Valve",
167
+ "in": "after_pipe_7",
168
+ "out": "after_valve_4",
169
+ "pressure_ratio": 0.5,
170
+ "material": 3
171
+ },
172
+ "pipe_8": {
173
+ "type": "Pipes",
174
+ "in": "after_valve_4",
175
+ "out": "after_pipe_8",
176
+ "delta_p": 1000.0,
177
+ "diameter": 0.08,
178
+ "material": 3
179
+ },
180
+ "valve_5": {
181
+ "type": "Valve",
182
+ "in": ["after_pipe_8","after_pipe_2a"],
183
+ "out": "after_valve_5",
184
+ "pressure_ratio": 0.5,
185
+ "material": 3
186
+ },
187
+ "pipe_9": {
188
+ "type": "Pipes",
189
+ "in": "after_valve_5",
190
+ "out": "after_pipe_9",
191
+ "delta_p": 1000.0,
192
+ "diameter": 0.025,
193
+ "material": 3
194
+ }
195
+
196
+ },
197
+ "simulation": {
198
+ "mode":"dynamic",
199
+ "t_final": 20,
200
+ "t_step": 1
201
+ }
202
+ }
@@ -0,0 +1,70 @@
1
+ {
2
+ "metadata": {
3
+ "name": "FESTIM Hydrogen Transport — 1D Diffusion",
4
+ "description": "Simple 1D hydrogen diffusion through a slab. Fixed concentration BCs: c=1 on left, c=0 on right. D_0=1 m²/s, E_D=0 eV, T=300 K.",
5
+ "version": "1.0"
6
+ },
7
+ "providers": {
8
+ "festim": {
9
+ "type": "festim",
10
+ "url": "http://localhost:9002",
11
+ "output_dir": "festim"
12
+ }
13
+ },
14
+ "materials": {
15
+ "default": {
16
+ "id": 1,
17
+ "extra": {
18
+ "D_0": 1,
19
+ "E_D": 0.0
20
+ }
21
+ }
22
+ },
23
+ "streams": {},
24
+ "units": {
25
+ "festim_solver": {
26
+ "type": "SolverUnit",
27
+ "provider": "festim",
28
+ "sim_type": "hydrogen_transport",
29
+ "mesh": {
30
+ "vertices": [0.0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, 0.01]
31
+ },
32
+ "species": [
33
+ { "name": "H" }
34
+ ],
35
+ "subdomains": {
36
+ "volume": [
37
+ { "id": 1, "borders": [0.0, 0.01], "material": "default" }
38
+ ],
39
+ "surface": [
40
+ { "id": 2, "x": 0.0 },
41
+ { "id": 3, "x": 0.01 }
42
+ ]
43
+ },
44
+ "boundary_conditions": [
45
+ { "type": "fixed_concentration", "subdomain_id": 2, "species": "H", "value": 1 },
46
+ { "type": "fixed_concentration", "subdomain_id": 3, "species": "H", "value": 0 }
47
+ ],
48
+ "exports": [
49
+ { "type": "vtx_species", "field": "H", "filename": "hydrogen_concentration.bp", "times": "milestones" },
50
+ { "type": "profile_1d", "field": "H", "volume_id": 1, "times": "milestones" }
51
+ ],
52
+ "solver_config": {
53
+ "atol": 1e-10,
54
+ "rtol": 1e-10,
55
+ "final_time": 2,
56
+ "temperature": 300,
57
+ "stepsize": {
58
+ "initial_value": 0.05,
59
+ "growth_factor": 1.1,
60
+ "cutback_factor": 0.9,
61
+ "target_nb_iterations": 4,
62
+ "milestones": [0.05, 0.1, 0.2, 0.5, 1]
63
+ }
64
+ }
65
+ }
66
+ },
67
+ "simulation": {
68
+ "mode": "steady"
69
+ }
70
+ }
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "material_mixes": {
24
24
  "Water_Toluene_Mix": {
25
- "friendly_material_mix_id": 1,
25
+ "id": 1,
26
26
  "percent_type": "ao",
27
27
  "components": [
28
28
  {"name": "Water", "fraction": 0.8},
@@ -7,7 +7,8 @@
7
7
  "providers": {
8
8
  "openmc": {
9
9
  "type": "openmc",
10
- "output_dir": "outputs/openmc/msre_run",
10
+ "url": "http://localhost:9001",
11
+ "output_dir": "openmc/msre_run",
11
12
  "cross_sections": "${OPENMC_DATA_ROOT}/cross_sections/cross_sections.xml"
12
13
  }
13
14
  },
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "processforge"
7
- version = "0.2.30"
7
+ version = "0.2.34"
8
8
  description = "A Python-based process simulation framework for chemical engineering applications."
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
11
11
  license-files = ["LICENSE"]
12
12
  requires-python = ">=3.12"
13
13
  authors = [
14
- {name = "Process Forge Team", email = "team@processforge.dev"},
14
+ {name = "Processforge Team", email = "team@processforge.dev"},
15
15
  ]
16
16
  classifiers = [
17
17
  "Development Status :: 3 - Alpha",
@@ -26,6 +26,7 @@ classifiers = [
26
26
  keywords = ["process", "simulation", "chemical", "engineering", "flowsheet"]
27
27
  dependencies = [
28
28
  "numpy>=2.0",
29
+ "pydantic>=2.0",
29
30
  "scipy>=1.14",
30
31
  "matplotlib>=3.9",
31
32
  "loguru>=0.7",
@@ -33,16 +34,12 @@ dependencies = [
33
34
  "graphviz>=0.20",
34
35
  "pandas>=2.2",
35
36
  "zarr>=3.0",
37
+ "coolprop>=7.2.0",
38
+ "pi>=0.1.2",
39
+ "pip>=26.1.2",
36
40
  ]
37
41
 
38
42
  [project.optional-dependencies]
39
- api = [
40
- "fastapi>=0.110",
41
- "uvicorn[standard]>=0.29",
42
- "boto3>=1.34",
43
- "s3fs>=2024.3",
44
- "pydantic>=2.0",
45
- ]
46
43
  eo = [
47
44
  "pyomo>=6.7",
48
45
  ]
@@ -86,7 +83,6 @@ Issues = "https://github.com/urjanova/processforge/issues"
86
83
  [project.scripts]
87
84
  processforge = "processforge.simulate:main"
88
85
  pf = "processforge.simulate:main"
89
- pf-serve = "processforge.api.serve:main"
90
86
 
91
87
  [tool.setuptools.packages.find]
92
88
  where = ["src"]
@@ -0,0 +1,47 @@
1
+ """Generate docker-compose.yml for containerized providers."""
2
+ from __future__ import annotations
3
+
4
+ import os
5
+
6
+ COMPOSE_FILENAME = "docker-compose.yml"
7
+ COMPOSE_HEADER = (
8
+ "# Auto-generated by pf init — do not edit manually.\n"
9
+ "# Re-generate: pf init <flowsheet.json>\n"
10
+ )
11
+
12
+
13
+ def _compose_path(pf_dir: str) -> str:
14
+ return os.path.join(pf_dir, COMPOSE_FILENAME)
15
+
16
+
17
+ def generate_compose(
18
+ pf_dir: str,
19
+ containerized_providers: dict[str, dict],
20
+ outputs_dir: str = "outputs",
21
+ ) -> None:
22
+ """Generate docker-compose.yml for providers that need Docker.
23
+
24
+ Args:
25
+ pf_dir: Path to .processforge/ directory.
26
+ containerized_providers: Dict of provider_name -> {"url": ..., "docker_image": ..., "port": ...}.
27
+ outputs_dir: Host directory to mount as /data in containers.
28
+ """
29
+ if not containerized_providers:
30
+ return
31
+
32
+ lines = [COMPOSE_HEADER, "services:"]
33
+ for name, info in containerized_providers.items():
34
+ image = info["docker_image"]
35
+ port = info.get("port") or 9000
36
+ lines.append(f" {name}:")
37
+ lines.append(f" image: {image}")
38
+ lines.append(f" ports:")
39
+ lines.append(f' - "{port}:{port}"')
40
+ lines.append(f" volumes:")
41
+ lines.append(f' - "${{PROCESSFORGE_OUTPUT_DIR:-{outputs_dir}}}:/data"')
42
+ lines.append("")
43
+
44
+ os.makedirs(pf_dir, exist_ok=True)
45
+ path = _compose_path(pf_dir)
46
+ with open(path, "w", encoding="utf-8") as f:
47
+ f.write("\n".join(lines))
@@ -2,10 +2,14 @@
2
2
  from __future__ import annotations
3
3
 
4
4
  from copy import deepcopy
5
+ from typing import TYPE_CHECKING
5
6
 
6
7
  import numpy as np
7
8
  from loguru import logger
8
9
 
10
+ if TYPE_CHECKING:
11
+ from ..providers.manager import ProviderMap
12
+
9
13
  from .jacobian import GlobalJacobianManager
10
14
  from .solver import EOSolver
11
15
  from ..types import SnapshotState
@@ -43,7 +47,7 @@ class EOFlowsheet:
43
47
  or sim_cfg.get("default_backend", "scipy")
44
48
  )
45
49
  self._unit_objects: dict = {}
46
- self._provider_map: dict = {}
50
+ self._provider_map: ProviderMap | None = None
47
51
  self.solver_tol: float = 1e-6
48
52
  self.solver_max_iter: int = 50
49
53
 
@@ -141,55 +145,15 @@ class EOFlowsheet:
141
145
 
142
146
  return manager
143
147
 
144
- def _build_units(self, provider_map: dict | None = None) -> dict:
145
- """Instantiate unit objects using the same factory logic as Flowsheet."""
146
- from processforge.units.pump import Pump
147
- from processforge.units.valve import Valve
148
- from processforge.units.strainer import Strainer
149
- from processforge.units.pipes import Pipes
150
- from processforge.units.heater import Heater
151
- from processforge.units.flash import Flash
152
- from processforge.units.solver_unit import SolverUnit
153
-
154
- unit_types = {
155
- "Pump": (Pump, "kwargs"),
156
- "Valve": (Valve, "kwargs"),
157
- "Strainer": (Strainer, "kwargs"),
158
- "Pipes": (Pipes, "kwargs"),
159
- "Heater": (Heater, "params"),
160
- "Flash": (Flash, "params"),
161
- "SolverUnit": (SolverUnit, "kwargs"),
162
- }
163
-
164
- from processforge.providers.manager import get_unit_provider
165
- _pm = provider_map or {}
148
+ def _build_units(self, provider_map: ProviderMap | None = None) -> dict:
149
+ """Instantiate unit objects using the shared registry."""
150
+ from ..flowsheet import _build_unit, _merge_provider_types
151
+ _merge_provider_types(provider_map)
166
152
 
167
153
  units = {}
168
154
  for unit_name, unit_cfg in self.config["units"].items():
169
- unit_type = unit_cfg["type"]
170
- if unit_type not in unit_types:
171
- raise ValueError(f"Unknown unit type '{unit_type}'.")
172
- cls, style = unit_types[unit_type]
173
-
174
- exclude = {"type", "in", "out", "provider"}
175
- if unit_type == "Flash":
176
- # Flash uses out_vap / out_liq — exclude both from kwargs
177
- exclude |= {"out_vap", "out_liq"}
178
-
179
- params = {k: v for k, v in unit_cfg.items() if k not in exclude}
180
- if style == "params":
181
- # Heater / Flash use __init__(name, params_dict)
182
- unit = cls(unit_name, params)
183
- else:
184
- unit = cls(unit_name, **params)
185
-
186
- # Attach provider so EO residuals can route thermo calls.
187
- if _pm:
188
- unit._provider = get_unit_provider(_pm, unit_cfg)
189
-
190
- units[unit_name] = unit
191
- logger.info(f"Built unit '{unit_name}' ({unit_type})")
192
-
155
+ units[unit_name] = _build_unit(unit_name, unit_cfg, provider_map)
156
+ logger.info(f"Built unit '{unit_name}' ({unit_cfg['type']})")
193
157
  return units
194
158
 
195
159
  def _check_provider_backend_compat(self) -> None: