processforge 0.2.30__tar.gz → 0.2.38__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.
- processforge-0.2.38/PKG-INFO +140 -0
- processforge-0.2.38/README.md +82 -0
- {processforge-0.2.30 → processforge-0.2.38}/flowsheets/closed-loop-chain.json +1 -1
- processforge-0.2.38/flowsheets/festim/hydrogen_transport_1d.json +70 -0
- {processforge-0.2.30 → processforge-0.2.38}/flowsheets/hydraulic-chain.json +1 -1
- {processforge-0.2.30 → processforge-0.2.38}/flowsheets/openmc/msre_eigenvalue.json +2 -1
- {processforge-0.2.30 → processforge-0.2.38}/pyproject.toml +4 -10
- processforge-0.2.38/src/processforge/compose.py +47 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/flowsheet.py +11 -47
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/jacobian.py +7 -4
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/solver.py +0 -1
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/flowsheet.py +149 -162
- processforge-0.2.38/src/processforge/lock.py +41 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/__init__.py +2 -1
- processforge-0.2.38/src/processforge/providers/festim_provider.py +411 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/manager.py +95 -50
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/openmc_provider.py +8 -1
- processforge-0.2.38/src/processforge/providers/registry.py +185 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/result.py +3 -5
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/schemas/flowsheet_schema.json +18 -6
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/schemas/openmc/openmc_model.py +2 -2
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/simulate.py +283 -20
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/state.py +19 -6
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/types.py +121 -1
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/__init__.py +3 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/cstr.py +5 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/flash.py +9 -6
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/heater.py +9 -5
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/pfr.py +4 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/pipes.py +4 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/pump.py +4 -0
- processforge-0.2.38/src/processforge/units/registry.py +24 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/solver_unit.py +4 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/strainer.py +4 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/tank.py +4 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/valve.py +4 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/utils/validate_flowsheet.py +158 -11
- processforge-0.2.38/src/processforge.egg-info/PKG-INFO +140 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge.egg-info/SOURCES.txt +10 -6
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge.egg-info/entry_points.txt +0 -1
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge.egg-info/requires.txt +2 -7
- processforge-0.2.38/tests/test_festim_provider.py +596 -0
- processforge-0.2.38/tests/test_init.py +256 -0
- processforge-0.2.38/tests/test_providers.py +318 -0
- processforge-0.2.38/tests/test_state.py +125 -0
- processforge-0.2.30/PKG-INFO +0 -615
- processforge-0.2.30/README.md +0 -553
- processforge-0.2.30/src/processforge/api/app.py +0 -87
- processforge-0.2.30/src/processforge/api/models.py +0 -83
- processforge-0.2.30/src/processforge/api/runner.py +0 -164
- processforge-0.2.30/src/processforge/api/serve.py +0 -41
- processforge-0.2.30/src/processforge/providers/registry.py +0 -52
- processforge-0.2.30/src/processforge/utils/__init__.py +0 -0
- processforge-0.2.30/src/processforge.egg-info/PKG-INFO +0 -615
- {processforge-0.2.30 → processforge-0.2.38}/LICENSE +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/MANIFEST.in +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/setup.cfg +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/__main__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/_schema.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/analysis/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/analysis/dof.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/backends/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/backends/base.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/backends/casadi_backend.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/backends/pyomo_backend.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/backends/scipy_backend.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/mixin.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/stream_var.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/units/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/units/flash_eo.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/units/heater_eo.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/units/pipes_eo.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/units/pump_eo.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/units/strainer_eo.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/eo/units/valve_eo.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/fmu/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/fmu/_fmi_vars.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/fmu/builder.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/fmu/slave_template.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/modelica/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/modelica/mo_writer.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/modelica/omc_runner.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/modelica/transpiler.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/modelica/unit_equations.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/pcl/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/pcl/compiler.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/pcl/namespace.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/provenance.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/base.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/base_jacobian_mixin.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/cantera_jacobian.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/cantera_provider.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/coolprop_provider.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/jacobian_contributor.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/modelica_jacobian.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/modelica_provider.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/providers/reference_state_registry.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/schemas/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/solver.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/thermo.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/provider_mixin.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/units/solver.py +0 -0
- {processforge-0.2.30/src/processforge/api → processforge-0.2.38/src/processforge/utils}/__init__.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/utils/flowsheet_diagram.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/utils/mermaid_diagram.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/utils/topology.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/utils/unit_consistency.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge/utils/validation.py +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge.egg-info/dependency_links.txt +0 -0
- {processforge-0.2.30 → processforge-0.2.38}/src/processforge.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: processforge
|
|
3
|
+
Version: 0.2.38
|
|
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
|
+
Provides-Extra: eo
|
|
33
|
+
Requires-Dist: pyomo>=6.7; extra == "eo"
|
|
34
|
+
Provides-Extra: eo-casadi
|
|
35
|
+
Requires-Dist: pyomo>=6.7; extra == "eo-casadi"
|
|
36
|
+
Requires-Dist: casadi>=3.6; extra == "eo-casadi"
|
|
37
|
+
Provides-Extra: fmu
|
|
38
|
+
Requires-Dist: pythonfmu>=0.6; extra == "fmu"
|
|
39
|
+
Provides-Extra: modelica
|
|
40
|
+
Requires-Dist: OMPython>=4.0.0; extra == "modelica"
|
|
41
|
+
Requires-Dist: fmpy>=0.3; extra == "modelica"
|
|
42
|
+
Provides-Extra: cantera
|
|
43
|
+
Requires-Dist: cantera>=3.0; extra == "cantera"
|
|
44
|
+
Provides-Extra: coolprop
|
|
45
|
+
Requires-Dist: coolprop>=6.6; extra == "coolprop"
|
|
46
|
+
Provides-Extra: pcl
|
|
47
|
+
Requires-Dist: pint>=0.24; extra == "pcl"
|
|
48
|
+
Provides-Extra: dev
|
|
49
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
50
|
+
Requires-Dist: black; extra == "dev"
|
|
51
|
+
Requires-Dist: flake8; extra == "dev"
|
|
52
|
+
Requires-Dist: build; extra == "dev"
|
|
53
|
+
Requires-Dist: twine; extra == "dev"
|
|
54
|
+
Provides-Extra: docs
|
|
55
|
+
Requires-Dist: sphinx; extra == "docs"
|
|
56
|
+
Requires-Dist: sphinx-rtd-theme; extra == "docs"
|
|
57
|
+
Dynamic: license-file
|
|
58
|
+
|
|
59
|
+
# Processforge
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
A lightweight Python framework for process simulation, coupling hydraulic, thermal, and reactor workflows.
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
Install the `pf` command-line tool with [uv](https://docs.astral.sh/uv/):
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
uv tool install processforge
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
For CoolProp-backed units:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv tool install "processforge[coolprop]"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Optional solver backends:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
uv tool install "processforge[eo]"
|
|
83
|
+
uv tool install "processforge[eo-casadi]"
|
|
84
|
+
uv tool install "processforge[modelica]"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Quick start
|
|
88
|
+
|
|
89
|
+
1. **Install the tool**
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
uv tool install processforge
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
2. **Download an example flowsheet**
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
curl -O https://raw.githubusercontent.com/urjanova/processforge/master/flowsheets/hydraulic-chain.json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
3. **Initialize, plan, and apply**
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
pf init
|
|
105
|
+
pf plan hydraulic-chain.json
|
|
106
|
+
pf apply hydraulic-chain.json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`plan` validates the flowsheet (schema, DOF, units) without running the solver; `apply` solves it and stores a snapshot.
|
|
110
|
+
|
|
111
|
+
4. **Look at the output**
|
|
112
|
+
|
|
113
|
+
`pf apply` writes results under `outputs/`:
|
|
114
|
+
- `*_results.zarr` — simulation results store
|
|
115
|
+
- `*_validation.xlsx` — validation report
|
|
116
|
+
- `*.pfstate/` — versioned snapshot store with a `latest` pointer
|
|
117
|
+
|
|
118
|
+
For flowsheets with Tank units (dynamic), use `pf run` instead of `pf apply` to solve with the SM solver.
|
|
119
|
+
|
|
120
|
+
## Python API
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from processforge import EOFlowsheet, validate_flowsheet
|
|
124
|
+
config = validate_flowsheet("flowsheets/hydraulic-chain.json")
|
|
125
|
+
fs = EOFlowsheet(config, backend="scipy")
|
|
126
|
+
results = fs.run()
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Usage and Docker
|
|
130
|
+
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.
|
|
131
|
+
|
|
132
|
+
## Flowsheets
|
|
133
|
+
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.
|
|
134
|
+
- [docs/flowsheets.md](docs/flowsheets.md) : flowsheet JSON format, materials, units, and recycle rules
|
|
135
|
+
- [flowsheets/](flowsheets/) : example flowsheets shipped with the repo
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
BSD 3-Clause License
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Processforge
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
A lightweight Python framework for process simulation, coupling hydraulic, thermal, and reactor workflows.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
Install the `pf` command-line tool with [uv](https://docs.astral.sh/uv/):
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
uv tool install processforge
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
For CoolProp-backed units:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv tool install "processforge[coolprop]"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Optional solver backends:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uv tool install "processforge[eo]"
|
|
25
|
+
uv tool install "processforge[eo-casadi]"
|
|
26
|
+
uv tool install "processforge[modelica]"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
1. **Install the tool**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv tool install processforge
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
2. **Download an example flowsheet**
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
curl -O https://raw.githubusercontent.com/urjanova/processforge/master/flowsheets/hydraulic-chain.json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. **Initialize, plan, and apply**
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pf init
|
|
47
|
+
pf plan hydraulic-chain.json
|
|
48
|
+
pf apply hydraulic-chain.json
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`plan` validates the flowsheet (schema, DOF, units) without running the solver; `apply` solves it and stores a snapshot.
|
|
52
|
+
|
|
53
|
+
4. **Look at the output**
|
|
54
|
+
|
|
55
|
+
`pf apply` writes results under `outputs/`:
|
|
56
|
+
- `*_results.zarr` — simulation results store
|
|
57
|
+
- `*_validation.xlsx` — validation report
|
|
58
|
+
- `*.pfstate/` — versioned snapshot store with a `latest` pointer
|
|
59
|
+
|
|
60
|
+
For flowsheets with Tank units (dynamic), use `pf run` instead of `pf apply` to solve with the SM solver.
|
|
61
|
+
|
|
62
|
+
## Python API
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from processforge import EOFlowsheet, validate_flowsheet
|
|
66
|
+
config = validate_flowsheet("flowsheets/hydraulic-chain.json")
|
|
67
|
+
fs = EOFlowsheet(config, backend="scipy")
|
|
68
|
+
results = fs.run()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Usage and Docker
|
|
72
|
+
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.
|
|
73
|
+
|
|
74
|
+
## Flowsheets
|
|
75
|
+
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.
|
|
76
|
+
- [docs/flowsheets.md](docs/flowsheets.md) : flowsheet JSON format, materials, units, and recycle rules
|
|
77
|
+
- [flowsheets/](flowsheets/) : example flowsheets shipped with the repo
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
BSD 3-Clause License
|
|
@@ -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
|
+
}
|
|
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "processforge"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.38"
|
|
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 = "
|
|
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,10 @@ dependencies = [
|
|
|
33
34
|
"graphviz>=0.20",
|
|
34
35
|
"pandas>=2.2",
|
|
35
36
|
"zarr>=3.0",
|
|
37
|
+
"coolprop>=7.2.0",
|
|
36
38
|
]
|
|
37
39
|
|
|
38
40
|
[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
41
|
eo = [
|
|
47
42
|
"pyomo>=6.7",
|
|
48
43
|
]
|
|
@@ -86,7 +81,6 @@ Issues = "https://github.com/urjanova/processforge/issues"
|
|
|
86
81
|
[project.scripts]
|
|
87
82
|
processforge = "processforge.simulate:main"
|
|
88
83
|
pf = "processforge.simulate:main"
|
|
89
|
-
pf-serve = "processforge.api.serve:main"
|
|
90
84
|
|
|
91
85
|
[tool.setuptools.packages.find]
|
|
92
86
|
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:
|
|
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:
|
|
145
|
-
"""Instantiate unit objects using the
|
|
146
|
-
from
|
|
147
|
-
|
|
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
|
-
|
|
170
|
-
|
|
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:
|
|
@@ -376,14 +376,17 @@ class GlobalJacobianManager:
|
|
|
376
376
|
"""
|
|
377
377
|
Return column groups that can be perturbed simultaneously.
|
|
378
378
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
379
|
+
Each group contains a single column so that the finite-difference
|
|
380
|
+
Jacobian correctly captures the derivative of each variable
|
|
381
|
+
independently. Perturbing multiple variables in a stream block
|
|
382
|
+
simultaneously produces identical dF vectors for every column in
|
|
383
|
+
the group, which yields a rank-deficient Jacobian.
|
|
382
384
|
"""
|
|
383
385
|
groups: list[list[int]] = []
|
|
384
386
|
for sv in self._streams.values():
|
|
385
387
|
o = sv.global_offset
|
|
386
|
-
|
|
388
|
+
for i in range(sv.n_vars):
|
|
389
|
+
groups.append([o + i])
|
|
387
390
|
return groups
|
|
388
391
|
|
|
389
392
|
@property
|