processforge 0.2.20__tar.gz → 0.2.24__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.
- {processforge-0.2.20/src/processforge.egg-info → processforge-0.2.24}/PKG-INFO +31 -82
- {processforge-0.2.20 → processforge-0.2.24}/README.md +24 -81
- {processforge-0.2.20 → processforge-0.2.24}/flowsheets/closed-loop-chain.json +4 -4
- processforge-0.2.24/flowsheets/festim/festim_2d.json +54 -0
- processforge-0.2.24/flowsheets/festim/festim_dynamic_loop.json +52 -0
- {processforge-0.2.20 → processforge-0.2.24}/flowsheets/hydraulic-chain.json +4 -4
- processforge-0.2.24/flowsheets/openmc/msre_eigenvalue.json +117 -0
- {processforge-0.2.20 → processforge-0.2.24}/pyproject.toml +9 -1
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/__init__.py +2 -2
- processforge-0.2.24/src/processforge/__main__.py +7 -0
- processforge-0.2.24/src/processforge/api/app.py +84 -0
- processforge-0.2.24/src/processforge/api/models.py +25 -0
- processforge-0.2.24/src/processforge/api/runner.py +148 -0
- processforge-0.2.24/src/processforge/api/serve.py +41 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/__init__.py +1 -1
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/backends/scipy_backend.py +5 -1
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/flowsheet.py +71 -35
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/solver.py +41 -3
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/flowsheet.py +95 -34
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/fmu/_fmi_vars.py +1 -1
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/fmu/builder.py +8 -22
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/modelica/__init__.py +1 -1
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/modelica/mo_writer.py +9 -24
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/modelica/transpiler.py +4 -4
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/provenance.py +22 -26
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/__init__.py +2 -2
- processforge-0.2.24/src/processforge/providers/base.py +156 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/cantera_jacobian.py +1 -1
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/cantera_provider.py +11 -4
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/coolprop_provider.py +9 -2
- processforge-0.2.24/src/processforge/providers/festim_provider.py +697 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/jacobian_contributor.py +1 -1
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/manager.py +14 -12
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/modelica_provider.py +11 -4
- processforge-0.2.24/src/processforge/providers/openmc_provider.py +773 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/result.py +59 -7
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/schemas/flowsheet_schema.json +112 -10
- processforge-0.2.24/src/processforge/schemas/openmc/openmc_model.py +714 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/simulate.py +136 -64
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/state.py +22 -15
- processforge-0.2.24/src/processforge/types.py +442 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/__init__.py +7 -1
- processforge-0.2.24/src/processforge/units/festim_membrane.py +243 -0
- processforge-0.2.24/src/processforge/units/solver.py +5 -0
- processforge-0.2.24/src/processforge/units/solver_unit.py +111 -0
- processforge-0.2.24/src/processforge/utils/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/utils/mermaid_diagram.py +7 -1
- processforge-0.2.24/src/processforge/utils/topology.py +24 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/utils/validate_flowsheet.py +241 -18
- {processforge-0.2.20 → processforge-0.2.24/src/processforge.egg-info}/PKG-INFO +31 -82
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge.egg-info/SOURCES.txt +16 -5
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge.egg-info/entry_points.txt +1 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge.egg-info/requires.txt +7 -0
- processforge-0.2.20/flowsheets/archive/example_dynamic_hybrid.json +0 -41
- processforge-0.2.20/flowsheets/archive/example_dynamic_tank.json +0 -50
- processforge-0.2.20/flowsheets/archive/example_flash.json +0 -25
- processforge-0.2.20/flowsheets/archive/hydraulic_chain.json +0 -93
- processforge-0.2.20/src/processforge/providers/base.py +0 -86
- processforge-0.2.20/src/processforge/units/solver.py +0 -26
- processforge-0.2.20/src/processforge/validate.py +0 -26
- {processforge-0.2.20 → processforge-0.2.24}/LICENSE +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/MANIFEST.in +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/setup.cfg +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/_schema.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/analysis/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/analysis/dof.py +0 -0
- {processforge-0.2.20/src/processforge/utils → processforge-0.2.24/src/processforge/api}/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/backends/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/backends/base.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/backends/casadi_backend.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/backends/pyomo_backend.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/jacobian.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/mixin.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/stream_var.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/units/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/units/flash_eo.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/units/heater_eo.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/units/pipes_eo.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/units/pump_eo.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/units/strainer_eo.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/eo/units/valve_eo.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/fmu/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/fmu/slave_template.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/modelica/omc_runner.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/modelica/unit_equations.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/pcl/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/pcl/compiler.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/pcl/namespace.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/base_jacobian_mixin.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/modelica_jacobian.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/reference_state_registry.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/providers/registry.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/schemas/__init__.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/solver.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/thermo.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/cstr.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/flash.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/heater.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/pfr.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/pipes.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/provider_mixin.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/pump.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/strainer.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/tank.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/units/valve.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/utils/flowsheet_diagram.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/utils/unit_consistency.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge/utils/validation.py +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge.egg-info/dependency_links.txt +0 -0
- {processforge-0.2.20 → processforge-0.2.24}/src/processforge.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: processforge
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.24
|
|
4
4
|
Summary: A Python-based process simulation framework for chemical engineering applications.
|
|
5
5
|
Author-email: Process Forge Team <team@processforge.dev>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -28,6 +28,12 @@ Requires-Dist: jsonschema>=4.20
|
|
|
28
28
|
Requires-Dist: graphviz>=0.20
|
|
29
29
|
Requires-Dist: pandas>=2.2
|
|
30
30
|
Requires-Dist: zarr>=3.0
|
|
31
|
+
Provides-Extra: api
|
|
32
|
+
Requires-Dist: fastapi>=0.110; extra == "api"
|
|
33
|
+
Requires-Dist: uvicorn[standard]>=0.29; extra == "api"
|
|
34
|
+
Requires-Dist: boto3>=1.34; extra == "api"
|
|
35
|
+
Requires-Dist: s3fs>=2024.3; extra == "api"
|
|
36
|
+
Requires-Dist: pydantic>=2.0; extra == "api"
|
|
31
37
|
Provides-Extra: eo
|
|
32
38
|
Requires-Dist: pyomo>=6.7; extra == "eo"
|
|
33
39
|
Provides-Extra: eo-casadi
|
|
@@ -58,7 +64,7 @@ Dynamic: license-file
|
|
|
58
64
|
|
|
59
65
|

|
|
60
66
|
|
|
61
|
-
A Python-based process simulation framework for
|
|
67
|
+
A Python-based process simulation framework for coupling different simulation engines.
|
|
62
68
|
|
|
63
69
|
## Table of Contents
|
|
64
70
|
|
|
@@ -178,7 +184,7 @@ uv add "processforge[modelica]"
|
|
|
178
184
|
|
|
179
185
|
### Command Line Interface
|
|
180
186
|
|
|
181
|
-
|
|
187
|
+
Processforge provides a CLI with the following subcommands. Both `processforge` and the shorter alias `pf` are interchangeable.
|
|
182
188
|
|
|
183
189
|
#### Recommended workflow: init → plan → apply
|
|
184
190
|
|
|
@@ -260,9 +266,9 @@ Flowsheets are defined as JSON files. The `simulation.mode` field controls which
|
|
|
260
266
|
{
|
|
261
267
|
"metadata": { "name": "My Flowsheet", "version": "2.0" },
|
|
262
268
|
"materials": {
|
|
263
|
-
"Water": { "
|
|
264
|
-
"Toluene": { "
|
|
265
|
-
"Steel": { "
|
|
269
|
+
"Water": { "id": 1 },
|
|
270
|
+
"Toluene": { "id": 2 },
|
|
271
|
+
"Steel": { "id": 3 }
|
|
266
272
|
},
|
|
267
273
|
"material_mixes": {
|
|
268
274
|
"Water_Toluene_Mix": {
|
|
@@ -322,7 +328,7 @@ Rules:
|
|
|
322
328
|
- Each component `name` in a mix must match a key in the top-level `materials` section.
|
|
323
329
|
- When all component fractions are provided they must sum to 1.0.
|
|
324
330
|
|
|
325
|
-
Every unit also requires a `material` integer field pointing to
|
|
331
|
+
Every unit also requires a `material` integer field pointing to an `id` in the `materials` section (this identifies the structural material the unit is made of, separate from the fluid composition).
|
|
326
332
|
|
|
327
333
|
### Recycle streams
|
|
328
334
|
|
|
@@ -397,84 +403,27 @@ If both the direct Newton solve and the homotopy fallback fail to converge:
|
|
|
397
403
|
1. `latest` is automatically reverted to the previous good snapshot.
|
|
398
404
|
2. A `*_divergence.json` report is written with the drifted parameters, final `||F||`, homotopy step history, and the last `x` vector for debugging.
|
|
399
405
|
|
|
400
|
-
## Project Structure
|
|
401
406
|
|
|
407
|
+
## Running on the cloud
|
|
408
|
+
To run a simulation on any cloud provider (AWS EC2, Google Cloud, etc.) with Docker installed:
|
|
409
|
+
|
|
410
|
+
Pull the image:
|
|
402
411
|
```
|
|
403
|
-
processforge
|
|
404
|
-
├── src/processforge/ # Core package
|
|
405
|
-
│ ├── __init__.py # Public API
|
|
406
|
-
│ ├── flowsheet.py # Sequential-modular solver (dynamic mode)
|
|
407
|
-
│ ├── thermo.py # Thermodynamic calculations via CoolProp
|
|
408
|
-
│ ├── result.py # Results export (Zarr, Excel, plotting)
|
|
409
|
-
│ ├── simulate.py # CLI entry point (init, plan, apply, run, diagram, export-*)
|
|
410
|
-
│ ├── state.py # StateManager — versioned .pfstate snapshots, drift detection
|
|
411
|
-
│ ├── solver.py # ODE solver interface (dynamic)
|
|
412
|
-
│ ├── validate.py # Simple schema validation
|
|
413
|
-
│ ├── _schema.py # Schema loader (importlib.resources)
|
|
414
|
-
│ ├── eo/ # Equation-oriented (EO) steady-state solver
|
|
415
|
-
│ │ ├── flowsheet.py # EOFlowsheet — build, warm-start, solve; exposes fs.converged
|
|
416
|
-
│ │ ├── solver.py # EOSolver — backend selector; solve_with_homotopy() continuation
|
|
417
|
-
│ │ ├── jacobian.py # GlobalJacobianManager — F(x), J(x)
|
|
418
|
-
│ │ ├── stream_var.py # StreamVar — per-stream variable container
|
|
419
|
-
│ │ ├── mixin.py # EOUnitModelMixin — unit residual interface
|
|
420
|
-
│ │ ├── backends/ # Pluggable solver backends
|
|
421
|
-
│ │ │ ├── scipy_backend.py # Newton-Raphson + Armijo (built-in)
|
|
422
|
-
│ │ │ ├── pyomo_backend.py # Pyomo ConcreteModel + IPOPT (optional)
|
|
423
|
-
│ │ │ └── casadi_backend.py # CasADi SX + rootfinder (optional)
|
|
424
|
-
│ │ └── units/ # EO residual equations per unit type
|
|
425
|
-
│ │ ├── pump_eo.py
|
|
426
|
-
│ │ ├── valve_eo.py
|
|
427
|
-
│ │ ├── strainer_eo.py
|
|
428
|
-
│ │ ├── pipes_eo.py
|
|
429
|
-
│ │ ├── heater_eo.py
|
|
430
|
-
│ │ └── flash_eo.py
|
|
431
|
-
│ ├── units/ # Unit operation implementations
|
|
432
|
-
│ │ ├── pump.py # Pump with efficiency
|
|
433
|
-
│ │ ├── valve.py # Pressure-reducing valve
|
|
434
|
-
│ │ ├── strainer.py # Pressure drop element
|
|
435
|
-
│ │ ├── pipes.py # Pipe with friction losses
|
|
436
|
-
│ │ ├── tank.py # Well-mixed tank (dynamic ODE)
|
|
437
|
-
│ │ ├── flash.py # Isothermal flash separator
|
|
438
|
-
│ │ └── heater.py # Temperature control heater
|
|
439
|
-
│ ├── modelica/ # OMPython bridge: .mo transpiler + omc runner
|
|
440
|
-
│ │ ├── transpiler.py # transpile() — config → Modelica source
|
|
441
|
-
│ │ ├── mo_writer.py # build_model_source() — string builder
|
|
442
|
-
│ │ ├── unit_equations.py # Per-unit equation generators
|
|
443
|
-
│ │ └── omc_runner.py # compile_modelica() — OMPython validate + FMU
|
|
444
|
-
│ ├── utils/ # Utilities
|
|
445
|
-
│ │ ├── validate_flowsheet.py # Schema + connectivity validation
|
|
446
|
-
│ │ └── flowsheet_diagram.py # Graphviz visualization
|
|
447
|
-
│ └── schemas/ # Bundled JSON schemas
|
|
448
|
-
│ └── flowsheet_schema.json
|
|
449
|
-
├── flowsheets/ # Example flowsheet configurations
|
|
450
|
-
│ ├── closed-loop-chain.json # Dynamic recycle example
|
|
451
|
-
│ └── archive/ # Additional examples
|
|
452
|
-
├── pyproject.toml # Project configuration
|
|
453
|
-
└── MANIFEST.in # Source distribution manifest
|
|
412
|
+
docker pull ghcr.io/urjanova/processforge:latest
|
|
454
413
|
```
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
-
|
|
461
|
-
-
|
|
462
|
-
-
|
|
463
|
-
-
|
|
464
|
-
|
|
465
|
-
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
- **openpyxl** - Excel report generation
|
|
469
|
-
- **zarr** - Chunked storage for simulation outputs
|
|
470
|
-
|
|
471
|
-
Optional EO solver backends:
|
|
472
|
-
|
|
473
|
-
- **pyomo** ≥ 6.7 — Pyomo + IPOPT backend (`pip install "processforge[eo]"`)
|
|
474
|
-
- **casadi** ≥ 3.6 — CasADi AD-based backend (`pip install "processforge[eo-casadi]"`)
|
|
475
|
-
- **OMPython** ≥ 1.4 — Python API to OpenModelica compiler (`pip install "processforge[modelica]"`). Requires [OpenModelica](https://openmodelica.org) installed on the system.
|
|
476
|
-
|
|
477
|
-
|
|
414
|
+
Run a simulation and map an output folder:
|
|
415
|
+
|
|
416
|
+
```Bash
|
|
417
|
+
docker run -p 8080:8080 \
|
|
418
|
+
-e S3_ACCESS_KEY='XXXXXX' \
|
|
419
|
+
-e S3_SECRET_KEY='YYYYYYYYY' \
|
|
420
|
+
-e S3_ENDPOINT_URL='https://processforge-files.ams3.s3.com' \
|
|
421
|
+
-e S3_REGION_NAME='ams3' \
|
|
422
|
+
-e S3_BUCKET_NAME='Dev' \
|
|
423
|
+
ghcr.io/urjanova/processforge:latest \
|
|
424
|
+
pf-serve
|
|
425
|
+
```
|
|
426
|
+
(Ensure you provide your S3-compatible credentials and endpoint URL; output and results will be synced directly to the specified bucket.)
|
|
478
427
|
## Logo credit
|
|
479
428
|
Google Gemini / Nano Banana
|
|
480
429
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
A Python-based process simulation framework for
|
|
6
|
+
A Python-based process simulation framework for coupling different simulation engines.
|
|
7
7
|
|
|
8
8
|
## Table of Contents
|
|
9
9
|
|
|
@@ -123,7 +123,7 @@ uv add "processforge[modelica]"
|
|
|
123
123
|
|
|
124
124
|
### Command Line Interface
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
Processforge provides a CLI with the following subcommands. Both `processforge` and the shorter alias `pf` are interchangeable.
|
|
127
127
|
|
|
128
128
|
#### Recommended workflow: init → plan → apply
|
|
129
129
|
|
|
@@ -205,9 +205,9 @@ Flowsheets are defined as JSON files. The `simulation.mode` field controls which
|
|
|
205
205
|
{
|
|
206
206
|
"metadata": { "name": "My Flowsheet", "version": "2.0" },
|
|
207
207
|
"materials": {
|
|
208
|
-
"Water": { "
|
|
209
|
-
"Toluene": { "
|
|
210
|
-
"Steel": { "
|
|
208
|
+
"Water": { "id": 1 },
|
|
209
|
+
"Toluene": { "id": 2 },
|
|
210
|
+
"Steel": { "id": 3 }
|
|
211
211
|
},
|
|
212
212
|
"material_mixes": {
|
|
213
213
|
"Water_Toluene_Mix": {
|
|
@@ -267,7 +267,7 @@ Rules:
|
|
|
267
267
|
- Each component `name` in a mix must match a key in the top-level `materials` section.
|
|
268
268
|
- When all component fractions are provided they must sum to 1.0.
|
|
269
269
|
|
|
270
|
-
Every unit also requires a `material` integer field pointing to
|
|
270
|
+
Every unit also requires a `material` integer field pointing to an `id` in the `materials` section (this identifies the structural material the unit is made of, separate from the fluid composition).
|
|
271
271
|
|
|
272
272
|
### Recycle streams
|
|
273
273
|
|
|
@@ -342,84 +342,27 @@ If both the direct Newton solve and the homotopy fallback fail to converge:
|
|
|
342
342
|
1. `latest` is automatically reverted to the previous good snapshot.
|
|
343
343
|
2. A `*_divergence.json` report is written with the drifted parameters, final `||F||`, homotopy step history, and the last `x` vector for debugging.
|
|
344
344
|
|
|
345
|
-
## Project Structure
|
|
346
345
|
|
|
346
|
+
## Running on the cloud
|
|
347
|
+
To run a simulation on any cloud provider (AWS EC2, Google Cloud, etc.) with Docker installed:
|
|
348
|
+
|
|
349
|
+
Pull the image:
|
|
347
350
|
```
|
|
348
|
-
processforge
|
|
349
|
-
├── src/processforge/ # Core package
|
|
350
|
-
│ ├── __init__.py # Public API
|
|
351
|
-
│ ├── flowsheet.py # Sequential-modular solver (dynamic mode)
|
|
352
|
-
│ ├── thermo.py # Thermodynamic calculations via CoolProp
|
|
353
|
-
│ ├── result.py # Results export (Zarr, Excel, plotting)
|
|
354
|
-
│ ├── simulate.py # CLI entry point (init, plan, apply, run, diagram, export-*)
|
|
355
|
-
│ ├── state.py # StateManager — versioned .pfstate snapshots, drift detection
|
|
356
|
-
│ ├── solver.py # ODE solver interface (dynamic)
|
|
357
|
-
│ ├── validate.py # Simple schema validation
|
|
358
|
-
│ ├── _schema.py # Schema loader (importlib.resources)
|
|
359
|
-
│ ├── eo/ # Equation-oriented (EO) steady-state solver
|
|
360
|
-
│ │ ├── flowsheet.py # EOFlowsheet — build, warm-start, solve; exposes fs.converged
|
|
361
|
-
│ │ ├── solver.py # EOSolver — backend selector; solve_with_homotopy() continuation
|
|
362
|
-
│ │ ├── jacobian.py # GlobalJacobianManager — F(x), J(x)
|
|
363
|
-
│ │ ├── stream_var.py # StreamVar — per-stream variable container
|
|
364
|
-
│ │ ├── mixin.py # EOUnitModelMixin — unit residual interface
|
|
365
|
-
│ │ ├── backends/ # Pluggable solver backends
|
|
366
|
-
│ │ │ ├── scipy_backend.py # Newton-Raphson + Armijo (built-in)
|
|
367
|
-
│ │ │ ├── pyomo_backend.py # Pyomo ConcreteModel + IPOPT (optional)
|
|
368
|
-
│ │ │ └── casadi_backend.py # CasADi SX + rootfinder (optional)
|
|
369
|
-
│ │ └── units/ # EO residual equations per unit type
|
|
370
|
-
│ │ ├── pump_eo.py
|
|
371
|
-
│ │ ├── valve_eo.py
|
|
372
|
-
│ │ ├── strainer_eo.py
|
|
373
|
-
│ │ ├── pipes_eo.py
|
|
374
|
-
│ │ ├── heater_eo.py
|
|
375
|
-
│ │ └── flash_eo.py
|
|
376
|
-
│ ├── units/ # Unit operation implementations
|
|
377
|
-
│ │ ├── pump.py # Pump with efficiency
|
|
378
|
-
│ │ ├── valve.py # Pressure-reducing valve
|
|
379
|
-
│ │ ├── strainer.py # Pressure drop element
|
|
380
|
-
│ │ ├── pipes.py # Pipe with friction losses
|
|
381
|
-
│ │ ├── tank.py # Well-mixed tank (dynamic ODE)
|
|
382
|
-
│ │ ├── flash.py # Isothermal flash separator
|
|
383
|
-
│ │ └── heater.py # Temperature control heater
|
|
384
|
-
│ ├── modelica/ # OMPython bridge: .mo transpiler + omc runner
|
|
385
|
-
│ │ ├── transpiler.py # transpile() — config → Modelica source
|
|
386
|
-
│ │ ├── mo_writer.py # build_model_source() — string builder
|
|
387
|
-
│ │ ├── unit_equations.py # Per-unit equation generators
|
|
388
|
-
│ │ └── omc_runner.py # compile_modelica() — OMPython validate + FMU
|
|
389
|
-
│ ├── utils/ # Utilities
|
|
390
|
-
│ │ ├── validate_flowsheet.py # Schema + connectivity validation
|
|
391
|
-
│ │ └── flowsheet_diagram.py # Graphviz visualization
|
|
392
|
-
│ └── schemas/ # Bundled JSON schemas
|
|
393
|
-
│ └── flowsheet_schema.json
|
|
394
|
-
├── flowsheets/ # Example flowsheet configurations
|
|
395
|
-
│ ├── closed-loop-chain.json # Dynamic recycle example
|
|
396
|
-
│ └── archive/ # Additional examples
|
|
397
|
-
├── pyproject.toml # Project configuration
|
|
398
|
-
└── MANIFEST.in # Source distribution manifest
|
|
351
|
+
docker pull ghcr.io/urjanova/processforge:latest
|
|
399
352
|
```
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
407
|
-
-
|
|
408
|
-
-
|
|
409
|
-
|
|
410
|
-
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
- **openpyxl** - Excel report generation
|
|
414
|
-
- **zarr** - Chunked storage for simulation outputs
|
|
415
|
-
|
|
416
|
-
Optional EO solver backends:
|
|
417
|
-
|
|
418
|
-
- **pyomo** ≥ 6.7 — Pyomo + IPOPT backend (`pip install "processforge[eo]"`)
|
|
419
|
-
- **casadi** ≥ 3.6 — CasADi AD-based backend (`pip install "processforge[eo-casadi]"`)
|
|
420
|
-
- **OMPython** ≥ 1.4 — Python API to OpenModelica compiler (`pip install "processforge[modelica]"`). Requires [OpenModelica](https://openmodelica.org) installed on the system.
|
|
421
|
-
|
|
422
|
-
|
|
353
|
+
Run a simulation and map an output folder:
|
|
354
|
+
|
|
355
|
+
```Bash
|
|
356
|
+
docker run -p 8080:8080 \
|
|
357
|
+
-e S3_ACCESS_KEY='XXXXXX' \
|
|
358
|
+
-e S3_SECRET_KEY='YYYYYYYYY' \
|
|
359
|
+
-e S3_ENDPOINT_URL='https://processforge-files.ams3.s3.com' \
|
|
360
|
+
-e S3_REGION_NAME='ams3' \
|
|
361
|
+
-e S3_BUCKET_NAME='Dev' \
|
|
362
|
+
ghcr.io/urjanova/processforge:latest \
|
|
363
|
+
pf-serve
|
|
364
|
+
```
|
|
365
|
+
(Ensure you provide your S3-compatible credentials and endpoint URL; output and results will be synced directly to the specified bucket.)
|
|
423
366
|
## Logo credit
|
|
424
367
|
Google Gemini / Nano Banana
|
|
425
368
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"materials": {
|
|
13
13
|
"Benzene": {
|
|
14
|
-
"
|
|
14
|
+
"id": 1,
|
|
15
15
|
"density": 0.8765,
|
|
16
16
|
"density_units": "g/cm3",
|
|
17
17
|
"temperature": 298.15,
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
]
|
|
23
23
|
},
|
|
24
24
|
"Toluene": {
|
|
25
|
-
"
|
|
25
|
+
"id": 2,
|
|
26
26
|
"density": 0.867,
|
|
27
27
|
"density_units": "g/cm3",
|
|
28
28
|
"temperature": 298.15,
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
]
|
|
34
34
|
},
|
|
35
35
|
"Steel": {
|
|
36
|
-
"
|
|
36
|
+
"id": 3,
|
|
37
37
|
"density": 7.85,
|
|
38
38
|
"density_units": "g/cm3",
|
|
39
39
|
"depletable": false,
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
}
|
|
163
163
|
},
|
|
164
164
|
"simulation": {
|
|
165
|
-
"mode": "
|
|
165
|
+
"mode": "dynamic",
|
|
166
166
|
"t0": 0.0,
|
|
167
167
|
"tf": 20.0,
|
|
168
168
|
"dt": 1.0
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"metadata": {
|
|
3
|
+
"name": "Festim 2D Heat and Hydrogen Transport",
|
|
4
|
+
"description": "2D unit square — coupled heat transfer + H transport with a trap, matching simple_2D.py",
|
|
5
|
+
"version": "1.0"
|
|
6
|
+
},
|
|
7
|
+
"providers": {
|
|
8
|
+
"festim": {
|
|
9
|
+
"type": "festim",
|
|
10
|
+
"output_dir": "outputs/festim_2d"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"materials": {
|
|
14
|
+
"tungsten_2d": {
|
|
15
|
+
"id": 10,
|
|
16
|
+
"D_0": 4.1e-7,
|
|
17
|
+
"E_D": 0.39,
|
|
18
|
+
"thermal_cond": "3 + 0.1 * T"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"streams": {},
|
|
22
|
+
"units": {
|
|
23
|
+
"festim_solver": {
|
|
24
|
+
"type": "SolverUnit",
|
|
25
|
+
"provider": "festim",
|
|
26
|
+
"sim_type": "heat_2d",
|
|
27
|
+
"material": 10,
|
|
28
|
+
"solver_config": {
|
|
29
|
+
"mesh": { "nx": 20, "ny": 20 },
|
|
30
|
+
"transient": false,
|
|
31
|
+
"boundary_conditions": [
|
|
32
|
+
{ "type": "DirichletBC", "field": "T", "value": 300, "surfaces": 1 },
|
|
33
|
+
{ "type": "ConvectiveFlux", "h_coeff": 10, "T_ext": 650, "surfaces": 2 },
|
|
34
|
+
{ "type": "FluxBC", "field": "T", "value": 0, "surfaces": 3 },
|
|
35
|
+
{ "type": "DirichletBC", "field": 0, "value": 1e19, "surfaces": 1 }
|
|
36
|
+
],
|
|
37
|
+
"sources": [
|
|
38
|
+
{ "value": 1000, "volume": 1, "field": "T" }
|
|
39
|
+
],
|
|
40
|
+
"traps": [
|
|
41
|
+
{ "k_0": 3.8e-17, "E_k": 0.39, "p_0": 8.4e12, "E_p": 0.9, "density": 1e25 }
|
|
42
|
+
],
|
|
43
|
+
"exports": [
|
|
44
|
+
{ "field": "solute" },
|
|
45
|
+
{ "field": "retention" },
|
|
46
|
+
{ "field": "T" }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"simulation": {
|
|
52
|
+
"mode": "steady"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"metadata": {
|
|
3
|
+
"name": "Festim Dynamic Loop",
|
|
4
|
+
"description": "A closed loop to test dynamic H2 depletion via a Festim membrane.",
|
|
5
|
+
"version": "1.0"
|
|
6
|
+
},
|
|
7
|
+
"providers": {
|
|
8
|
+
"festim": {
|
|
9
|
+
"type": "festim"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"materials": {
|
|
13
|
+
"H2": {
|
|
14
|
+
"id": 1
|
|
15
|
+
},
|
|
16
|
+
"tungsten": {
|
|
17
|
+
"id": 3,
|
|
18
|
+
"D_0": 4.1e-7,
|
|
19
|
+
"E_D": 0.39,
|
|
20
|
+
"S_0": 4.28e-5,
|
|
21
|
+
"E_S": 0.26
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
"streams": {
|
|
26
|
+
"feed": {
|
|
27
|
+
"T": 300.0,
|
|
28
|
+
"P": 1000000,
|
|
29
|
+
"flowrate": 0.1,
|
|
30
|
+
"z": { "H2": 1.0 }
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"units": {
|
|
34
|
+
"membrane": {
|
|
35
|
+
"type": "FestimMembrane",
|
|
36
|
+
"provider": "festim",
|
|
37
|
+
"in": "feed",
|
|
38
|
+
"retentate_out": "recycle",
|
|
39
|
+
"permeate_out": "waste",
|
|
40
|
+
"thickness": 0.005,
|
|
41
|
+
"mesh_cells": 50,
|
|
42
|
+
"area": 10.0,
|
|
43
|
+
"material": 3
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"simulation": {
|
|
47
|
+
"mode": "dynamic",
|
|
48
|
+
"t0": 0.0,
|
|
49
|
+
"tf": 10.0,
|
|
50
|
+
"dt": 1.0
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
},
|
|
12
12
|
"materials": {
|
|
13
13
|
"Water": {
|
|
14
|
-
"
|
|
14
|
+
"id": 1
|
|
15
15
|
},
|
|
16
16
|
"Toluene": {
|
|
17
|
-
"
|
|
17
|
+
"id": 2
|
|
18
18
|
},
|
|
19
19
|
"Steel": {
|
|
20
|
-
"
|
|
20
|
+
"id": 3
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"material_mixes": {
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"type": "Pump",
|
|
90
90
|
"in": "after_pipe_3",
|
|
91
91
|
"out": "after_pump_2",
|
|
92
|
-
"deltaP":
|
|
92
|
+
"deltaP": 200000.0,
|
|
93
93
|
"efficiency": 0.8,
|
|
94
94
|
"material": 3
|
|
95
95
|
},
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
{
|
|
2
|
+
"metadata": {
|
|
3
|
+
"name": "MSRE Eigenvalue — DAGMC geometry",
|
|
4
|
+
"description": "Molten Salt Reactor Experiment eigenvalue simulation. Replicates openmc.py reference script. DAGMC geometry loaded from .h5m file. 7 materials matching h5m volume tags: graphite, inor, salt, inconel, helium, Graveyard, helium_comp.",
|
|
5
|
+
"version": "1.1"
|
|
6
|
+
},
|
|
7
|
+
"providers": {
|
|
8
|
+
"openmc": {
|
|
9
|
+
"type": "openmc",
|
|
10
|
+
"output_dir": "outputs/openmc/msre_run",
|
|
11
|
+
"cross_sections": "tmp_files/cross_sections/cross_sections.xml"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"materials": {
|
|
15
|
+
"graphite": {
|
|
16
|
+
"id": 1,
|
|
17
|
+
"density": 2.26,
|
|
18
|
+
"density_units": "g/cm3",
|
|
19
|
+
"temperature": 0.0,
|
|
20
|
+
"elements": [
|
|
21
|
+
{ "element": "C", "percent": 1.0, "percent_type": "ao" }
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"inor": {
|
|
25
|
+
"id": 2,
|
|
26
|
+
"density": 9.0,
|
|
27
|
+
"density_units": "g/cm3",
|
|
28
|
+
"temperature": 0.0,
|
|
29
|
+
"elements": [
|
|
30
|
+
{ "element": "Ni", "percent": 0.72, "percent_type": "wo" },
|
|
31
|
+
{ "element": "Mo", "percent": 0.16, "percent_type": "wo" },
|
|
32
|
+
{ "element": "Cr", "percent": 0.07, "percent_type": "wo" },
|
|
33
|
+
{ "element": "Fe", "percent": 0.05, "percent_type": "wo" }
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
"salt": {
|
|
37
|
+
"id": 3,
|
|
38
|
+
"density": 2.2,
|
|
39
|
+
"density_units": "g/cm3",
|
|
40
|
+
"temperature": 0.0,
|
|
41
|
+
"depletable": true,
|
|
42
|
+
"nuclides": [
|
|
43
|
+
{ "name": "Li7", "percent": 0.335000, "percent_type": "ao" },
|
|
44
|
+
{ "name": "U235", "percent": 0.000527, "percent_type": "ao" },
|
|
45
|
+
{ "name": "U238", "percent": 0.001053, "percent_type": "ao" }
|
|
46
|
+
],
|
|
47
|
+
"elements": [
|
|
48
|
+
{ "element": "F", "percent": 0.534653, "percent_type": "ao" },
|
|
49
|
+
{ "element": "Be", "percent": 0.076667, "percent_type": "ao" },
|
|
50
|
+
{ "element": "Zr", "percent": 0.010000, "percent_type": "ao" }
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"inconel": {
|
|
54
|
+
"id": 4,
|
|
55
|
+
"density": 8.9,
|
|
56
|
+
"density_units": "g/cm3",
|
|
57
|
+
"temperature": 0.0,
|
|
58
|
+
"elements": [
|
|
59
|
+
{ "element": "Ni", "percent": 0.72, "percent_type": "ao" },
|
|
60
|
+
{ "element": "Cr", "percent": 0.20, "percent_type": "ao" },
|
|
61
|
+
{ "element": "Fe", "percent": 0.08, "percent_type": "ao" }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"helium": {
|
|
65
|
+
"id": 5,
|
|
66
|
+
"density": 1.0e-4,
|
|
67
|
+
"density_units": "g/cm3",
|
|
68
|
+
"temperature": 0.0,
|
|
69
|
+
"nuclides": [
|
|
70
|
+
{ "name": "He4", "percent": 1.0, "percent_type": "ao" }
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
},
|
|
75
|
+
"streams": {},
|
|
76
|
+
"units": {
|
|
77
|
+
"openmc_solver": {
|
|
78
|
+
"type": "SolverUnit",
|
|
79
|
+
"provider": "openmc",
|
|
80
|
+
"material":3,
|
|
81
|
+
"sim_type": "eigenvalue_dagmc",
|
|
82
|
+
"solver_config": {
|
|
83
|
+
"dagmc_path": "/home/hrishiballal/Documents/Github/urjanova/processforge/tmp_files/geometry/msre_simple.h5m",
|
|
84
|
+
"batches": 20,
|
|
85
|
+
"inactive": 5,
|
|
86
|
+
"particles": 20000,
|
|
87
|
+
"run_mode": "eigenvalue",
|
|
88
|
+
"source_box": {
|
|
89
|
+
"lower_left": [-125, -125, 0],
|
|
90
|
+
"upper_right": [ 125, 125, 500],
|
|
91
|
+
"only_fissionable": true
|
|
92
|
+
},
|
|
93
|
+
"mesh_tallies": [
|
|
94
|
+
{
|
|
95
|
+
"tally_id": 1,
|
|
96
|
+
"name": "flux1",
|
|
97
|
+
"lower_left": [-125, -125, 90],
|
|
98
|
+
"upper_right": [ 125, 125, 110],
|
|
99
|
+
"dimension": [400, 400, 1],
|
|
100
|
+
"scores": ["flux", "fission"]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"tally_id": 2,
|
|
104
|
+
"name": "flux2",
|
|
105
|
+
"lower_left": [-175, -10, -50],
|
|
106
|
+
"upper_right": [ 175, 10, 400],
|
|
107
|
+
"dimension": [400, 1, 400],
|
|
108
|
+
"scores": ["flux", "fission"]
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"simulation": {
|
|
115
|
+
"mode": "steady"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "processforge"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.24"
|
|
8
8
|
description = "A Python-based process simulation framework for chemical engineering applications."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "BSD-3-Clause"
|
|
@@ -37,6 +37,13 @@ dependencies = [
|
|
|
37
37
|
]
|
|
38
38
|
|
|
39
39
|
[project.optional-dependencies]
|
|
40
|
+
api = [
|
|
41
|
+
"fastapi>=0.110",
|
|
42
|
+
"uvicorn[standard]>=0.29",
|
|
43
|
+
"boto3>=1.34",
|
|
44
|
+
"s3fs>=2024.3",
|
|
45
|
+
"pydantic>=2.0",
|
|
46
|
+
]
|
|
40
47
|
eo = [
|
|
41
48
|
"pyomo>=6.7",
|
|
42
49
|
]
|
|
@@ -77,6 +84,7 @@ Issues = "https://github.com/urjanova/processforge/issues"
|
|
|
77
84
|
[project.scripts]
|
|
78
85
|
processforge = "processforge.simulate:main"
|
|
79
86
|
pf = "processforge.simulate:main"
|
|
87
|
+
pf-serve = "processforge.api.serve:main"
|
|
80
88
|
|
|
81
89
|
[tool.setuptools.packages.find]
|
|
82
90
|
where = ["src"]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
Processforge - A Python process simulation framework for chemical engineering.
|
|
3
3
|
|
|
4
4
|
Provides steady-state and dynamic process simulation capabilities including:
|
|
5
5
|
- Flowsheet modeling with recycle loop support
|
|
@@ -14,7 +14,7 @@ from .flowsheet import Flowsheet
|
|
|
14
14
|
from .provenance import build_run_info
|
|
15
15
|
from .solver import Solver
|
|
16
16
|
from .thermo import get_enthalpy_molar, get_Cp_molar, get_K_values, rachford_rice
|
|
17
|
-
from .
|
|
17
|
+
from .utils.validate_flowsheet import validate_flowsheet
|
|
18
18
|
from .result import (
|
|
19
19
|
plot_results,
|
|
20
20
|
plot_timeseries,
|