Skip to content

Commit b75b5c5

Browse files
committed
docs: update documentation with ProcessContext and ProcessBuilder
Updated module docstring and README to document all four approaches: 1. Python Wrappers (global process) - for beginners/notebooks 2. ProcessContext - for production/multiple processes 3. ProcessBuilder - fluent API for configuration-driven design 4. Direct Java access - for advanced features Added code examples for each approach and updated comparison table.
1 parent cb822bb commit b75b5c5

File tree

2 files changed

+137
-74
lines changed

2 files changed

+137
-74
lines changed

README.md

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ See the [NeqSim Python Wiki](https://github.com/equinor/neqsim-python/wiki) for
2222

2323
## Process Simulation
2424

25-
NeqSim Python provides two ways to build process simulations:
25+
NeqSim Python provides multiple ways to build process simulations:
2626

2727
### 1. Python Wrappers (Recommended for beginners)
2828

@@ -48,9 +48,54 @@ runProcess()
4848
print(f"Compressor power: {comp.getPower()/1e6:.2f} MW")
4949
```
5050

51-
### 2. Direct Java Access (Full control)
51+
### 2. ProcessContext (Recommended for production)
5252

53-
Explicit process management using jneqsim - best for production code:
53+
Context manager with explicit process control - supports multiple independent processes:
54+
55+
```python
56+
from neqsim.thermo import fluid
57+
from neqsim.process import ProcessContext
58+
59+
feed = fluid('srk')
60+
feed.addComponent('methane', 0.9)
61+
feed.addComponent('ethane', 0.1)
62+
feed.setTemperature(30.0, 'C')
63+
feed.setPressure(50.0, 'bara')
64+
65+
with ProcessContext("Compression Train") as ctx:
66+
inlet = ctx.stream('inlet', feed)
67+
sep = ctx.separator('separator', inlet)
68+
comp = ctx.compressor('compressor', sep.getGasOutStream(), pres=100.0)
69+
ctx.run()
70+
print(f"Compressor power: {comp.getPower()/1e6:.2f} MW")
71+
```
72+
73+
### 3. ProcessBuilder (Fluent API)
74+
75+
Chainable builder pattern - ideal for configuration-driven design:
76+
77+
```python
78+
from neqsim.thermo import fluid
79+
from neqsim.process import ProcessBuilder
80+
81+
feed = fluid('srk')
82+
feed.addComponent('methane', 0.9)
83+
feed.addComponent('ethane', 0.1)
84+
feed.setTemperature(30.0, 'C')
85+
feed.setPressure(50.0, 'bara')
86+
87+
process = (ProcessBuilder("Compression Train")
88+
.add_stream('inlet', feed)
89+
.add_separator('separator', 'inlet')
90+
.add_compressor('compressor', 'separator', pressure=100.0)
91+
.run())
92+
93+
print(f"Compressor power: {process.get('compressor').getPower()/1e6:.2f} MW")
94+
```
95+
96+
### 4. Direct Java Access (Full control)
97+
98+
Explicit process management using jneqsim - for advanced features:
5499

55100
```python
56101
from neqsim import jneqsim
@@ -84,11 +129,12 @@ print(f"Compressor power: {comp.getPower()/1e6:.2f} MW")
84129
|----------|---------------------|
85130
| Learning & prototyping | Python wrappers |
86131
| Jupyter notebooks | Python wrappers |
87-
| Production applications | Direct Java access |
88-
| Multiple parallel processes | Direct Java access |
132+
| Production applications | ProcessContext |
133+
| Multiple parallel processes | ProcessContext |
134+
| Configuration-driven design | ProcessBuilder |
89135
| Advanced Java features | Direct Java access |
90136

91-
See the [examples folder](https://github.com/equinor/neqsim-python/tree/master/examples) for more process simulation examples.
137+
See the [examples folder](https://github.com/equinor/neqsim-python/tree/master/examples) for more process simulation examples, including [processApproaches.py](https://github.com/equinor/neqsim-python/blob/master/examples/processApproaches.py) which demonstrates all four approaches.
92138

93139
### Prerequisites
94140

src/neqsim/process/processTools.py

Lines changed: 85 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,22 @@
44
process simulations using the NeqSim Java library. It includes equipment
55
like compressors, pumps, heat exchangers, separators, and more.
66
7-
Two Approaches for Process Simulation
8-
=====================================
7+
Four Approaches for Process Simulation
8+
======================================
99
10-
NeqSim Python offers two ways to build process simulations:
10+
NeqSim Python offers four ways to build process simulations:
1111
12-
1. **Python Wrappers (Recommended for beginners)**
13-
Uses simple Python functions with a global process. Best for quick
14-
prototyping, Jupyter notebooks, and learning.
12+
1. **Python Wrappers with Global Process** (Recommended for beginners)
13+
Simple functions that auto-add equipment to a global process.
1514
16-
2. **Direct Java Access (Full control)**
17-
Uses the jneqsim module to access NeqSim Java classes directly.
18-
Best for production code, multiple processes, and advanced features.
15+
2. **ProcessContext** (Recommended for production)
16+
Context manager with its own process - supports multiple processes.
17+
18+
3. **ProcessBuilder** (Fluent API)
19+
Chainable builder pattern - great for configuration-driven design.
20+
21+
4. **Direct Java Access** (Full control)
22+
Direct jneqsim access for advanced features.
1923
2024
Approach 1: Python Wrappers (Global Process)
2125
--------------------------------------------
@@ -30,95 +34,106 @@
3034
>>> my_fluid.addComponent('methane', 1.0)
3135
>>> my_fluid.setTemperature(30.0, 'C')
3236
>>> my_fluid.setPressure(10.0, 'bara')
33-
>>> my_fluid.setTotalFlowRate(1.0, 'MSm3/day')
3437
>>>
3538
>>> inlet = stream('inlet', my_fluid)
3639
>>> comp = compressor('compressor1', inlet, pres=50.0)
3740
>>> runProcess()
3841
>>> print(f"Power: {comp.getPower()/1e6:.2f} MW")
3942
40-
Pros:
41-
- Concise, readable code
42-
- Tab completion and docstrings in IDE
43-
- No Java knowledge required
44-
- Great for learning and prototyping
43+
Pros: Concise, readable, great for learning and prototyping
44+
Cons: Global state limits to one process at a time
4545
46-
Cons:
47-
- Global state limits to one process at a time
48-
- Not all Java features may be exposed
49-
- Less control over process execution
46+
Approach 2: ProcessContext (Explicit Process Management)
47+
---------------------------------------------------------
48+
Context manager that creates its own ProcessSystem. Supports multiple
49+
independent processes running simultaneously.
5050
51-
Approach 2: Direct Java Access (Explicit Process)
51+
>>> from neqsim.thermo import fluid
52+
>>> from neqsim.process import ProcessContext
53+
>>>
54+
>>> with ProcessContext("Compression") as ctx:
55+
... my_fluid = fluid('srk')
56+
... my_fluid.addComponent('methane', 1.0)
57+
... my_fluid.setPressure(10.0, 'bara')
58+
...
59+
... inlet = ctx.stream('inlet', my_fluid)
60+
... comp = ctx.compressor('comp1', inlet, pres=50.0)
61+
... ctx.run()
62+
... print(f"Power: {comp.getPower()/1e6:.2f} MW")
63+
64+
Pros: Multiple processes, explicit control, clean resource management
65+
Cons: Slightly more verbose than global wrappers
66+
67+
Approach 3: ProcessBuilder (Fluent/Chainable API)
5268
--------------------------------------------------
69+
Builder pattern with method chaining. Equipment referenced by name.
70+
Ideal for configuration-driven process construction.
71+
72+
>>> from neqsim.thermo import fluid
73+
>>> from neqsim.process import ProcessBuilder
74+
>>>
75+
>>> my_fluid = fluid('srk')
76+
>>> my_fluid.addComponent('methane', 1.0)
77+
>>> my_fluid.setPressure(10.0, 'bara')
78+
>>>
79+
>>> process = (ProcessBuilder("Compression")
80+
... .add_stream('inlet', my_fluid)
81+
... .add_compressor('comp1', 'inlet', pressure=50.0)
82+
... .run())
83+
>>>
84+
>>> print(f"Power: {process.get('comp1').getPower()/1e6:.2f} MW")
85+
86+
Pros: Very readable, chainable, equipment by name, declarative style
87+
Cons: Less direct access during construction
88+
89+
Approach 4: Direct Java Access
90+
-------------------------------
5391
Create and manage ProcessSystem objects explicitly using jneqsim.
5492
5593
>>> from neqsim import jneqsim
5694
>>> from neqsim.thermo import fluid
5795
>>>
58-
>>> # Create fluid
5996
>>> my_fluid = fluid('srk')
6097
>>> my_fluid.addComponent('methane', 1.0)
61-
>>> my_fluid.setTemperature(30.0, 'C')
6298
>>> my_fluid.setPressure(10.0, 'bara')
63-
>>> my_fluid.setTotalFlowRate(1.0, 'MSm3/day')
6499
>>>
65-
>>> # Create equipment using Java classes
66100
>>> inlet = jneqsim.process.equipment.stream.Stream('inlet', my_fluid)
67-
>>> comp = jneqsim.process.equipment.compressor.Compressor('compressor1', inlet)
101+
>>> comp = jneqsim.process.equipment.compressor.Compressor('comp1', inlet)
68102
>>> comp.setOutletPressure(50.0)
69103
>>>
70-
>>> # Create and run process explicitly
71104
>>> process = jneqsim.process.processmodel.ProcessSystem()
72105
>>> process.add(inlet)
73106
>>> process.add(comp)
74107
>>> process.run()
75-
>>> print(f"Power: {comp.getPower()/1e6:.2f} MW")
76108
77-
Pros:
78-
- Full access to all NeqSim Java features
79-
- Multiple independent processes possible
80-
- Explicit control over process construction
81-
- Better for production code and testing
109+
Pros: Full access to all Java features, maximum flexibility
110+
Cons: Verbose, requires Java knowledge
82111
83-
Cons:
84-
- More verbose code
85-
- Requires understanding of Java class structure
86-
- Less IDE support (though stubs help)
112+
Hybrid Approach: Wrappers with process= Parameter
113+
--------------------------------------------------
114+
Wrapper functions accept an optional process= parameter for explicit
115+
process control while keeping concise syntax:
116+
117+
>>> from neqsim.process import stream, compressor, newProcess
118+
>>>
119+
>>> my_process = newProcess('MyProcess')
120+
>>> inlet = stream('inlet', my_fluid, process=my_process)
121+
>>> comp = compressor('comp1', inlet, pres=50.0, process=my_process)
122+
>>> my_process.run()
87123
88124
Choosing an Approach
89125
--------------------
90-
Use **Python wrappers** when:
91-
- Learning NeqSim or thermodynamics
92-
- Quick calculations in Jupyter notebooks
93-
- Single process simulations
94-
- Prototyping process designs
95-
96-
Use **direct Java access** when:
97-
- Building production applications
98-
- Running multiple processes in parallel
99-
- Need features not exposed by wrappers
100-
- Writing automated tests
101-
- Configuration-driven process construction
102-
103-
Hybrid Approach
104-
---------------
105-
You can mix both approaches. Create equipment with wrappers, then access
106-
Java methods directly:
107-
108-
>>> from neqsim.process import stream, compressor, runProcess, clearProcess
109-
>>> from neqsim.thermo import fluid
110-
>>>
111-
>>> clearProcess()
112-
>>> my_fluid = fluid('srk')
113-
>>> my_fluid.addComponent('methane', 1.0)
114-
>>> inlet = stream('inlet', my_fluid)
115-
>>> comp = compressor('comp1', inlet, pres=50.0)
116-
>>>
117-
>>> # Access Java methods not exposed by wrapper
118-
>>> comp.setPolytropicEfficiency(0.78)
119-
>>> comp.setUsePolytropicCalc(True)
120-
>>>
121-
>>> runProcess()
126+
+----------------------------------+--------------------------------+
127+
| Use Case | Recommended Approach |
128+
+==================================+================================+
129+
| Learning / tutorials | Wrappers (global process) |
130+
| Jupyter notebooks | Wrappers (global process) |
131+
| Quick prototyping | Wrappers (global process) |
132+
| Production applications | ProcessContext |
133+
| Multiple parallel processes | ProcessContext |
134+
| Configuration-driven design | ProcessBuilder |
135+
| Full Java API access | Direct jneqsim |
136+
+----------------------------------+--------------------------------+
122137
123138
Available Equipment
124139
-------------------
@@ -135,6 +150,8 @@
135150
Storage: tank, simplereservoir, manifold
136151
Measurement: waterDewPointAnalyser, hydrateEquilibriumTemperatureAnalyser
137152
Power: windturbine, solarpanel, batterystorage, fuelcell, electrolyzer, co2electrolyzer
153+
154+
Classes: ProcessContext, ProcessBuilder
138155
"""
139156
from __future__ import annotations
140157

0 commit comments

Comments
 (0)