Skip to content

Commit ac2c1be

Browse files
committed
update docs
1 parent b084f57 commit ac2c1be

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1307
-506
lines changed

.github/copilot-instructions.md

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,3 +691,201 @@ String jsonReport = design.toJson();
691691

692692
---
693693

694+
## Jupyter Notebook Creation Guidelines (MANDATORY)
695+
696+
When creating Jupyter notebooks for NeqSim examples, follow these critical patterns:
697+
698+
### Import Pattern (USE THIS EXACT PATTERN)
699+
700+
**CORRECT** - Use the `jneqsim` gateway for direct Java access:
701+
```python
702+
# Import NeqSim - Direct Java Access via jneqsim
703+
from neqsim import jneqsim
704+
705+
# Import commonly used Java classes through the jneqsim gateway
706+
SystemSrkEos = jneqsim.thermo.system.SystemSrkEos
707+
ProcessSystem = jneqsim.process.processmodel.ProcessSystem
708+
Stream = jneqsim.process.equipment.stream.Stream
709+
Separator = jneqsim.process.equipment.separator.Separator
710+
Compressor = jneqsim.process.equipment.compressor.Compressor
711+
Cooler = jneqsim.process.equipment.heatexchanger.Cooler
712+
Heater = jneqsim.process.equipment.heatexchanger.Heater
713+
```
714+
715+
**WRONG** - Do NOT use jpype imports directly for new notebooks:
716+
```python
717+
# WRONG - This pattern may not work reliably
718+
import jpype
719+
import jpype.imports
720+
from jpype.types import *
721+
if not jpype.isJVMStarted():
722+
jpype.startJVM(classpath=['../target/classes'])
723+
from neqsim.thermo.system import SystemSrkEos # Direct jpype import
724+
```
725+
726+
### Common Problems and Solutions
727+
728+
| Problem | Cause | Solution |
729+
|---------|-------|----------|
730+
| `ModuleNotFoundError: No module named 'neqsim'` | neqsim-python not installed | Run `pip install neqsim` |
731+
| `AttributeError: 'NoneType' object has no attribute...` | JVM not started | Use `from neqsim import jneqsim` which auto-starts JVM |
732+
| `TypeError: No matching overloads found` | Wrong parameter types | Cast Python types explicitly: `float(value)`, `str(name)` |
733+
| Import fails for nested classes | Wrong import path | Use `jneqsim.package.subpackage.ClassName` pattern |
734+
| `RuntimeError: JVM cannot be restarted` | JVM already started/stopped | Restart the kernel |
735+
736+
### Temperature and Pressure Units
737+
738+
**CRITICAL**: NeqSim Java API uses **Kelvin** for temperatures and **bara** for pressures by default!
739+
740+
```python
741+
# Creating fluid - temperature in KELVIN, pressure in bara
742+
fluid = SystemSrkEos(273.15 + 25.0, 60.0) # 25°C, 60 bara
743+
744+
# Setting stream conditions - can use unit strings
745+
stream.setTemperature(30.0, "C") # Celsius
746+
stream.setPressure(60.0, "bara") # bara
747+
748+
# Getting values - returns KELVIN
749+
temp_kelvin = stream.getTemperature()
750+
temp_celsius = stream.getTemperature() - 273.15 # Convert to Celsius
751+
752+
# WRONG - forgetting Kelvin conversion
753+
temp = fluid.getTemperature() # This is in Kelvin!
754+
print(f"Temperature: {temp}°C") # WRONG - will show ~298°C instead of 25°C
755+
```
756+
757+
### Required Steps for Fluid Creation
758+
759+
Always follow this sequence:
760+
```python
761+
# 1. Create fluid with (T_Kelvin, P_bara)
762+
fluid = SystemSrkEos(273.15 + 25.0, 60.0)
763+
764+
# 2. Add components (name, mole_fraction)
765+
fluid.addComponent("methane", 0.85)
766+
fluid.addComponent("ethane", 0.10)
767+
fluid.addComponent("propane", 0.05)
768+
769+
# 3. MANDATORY: Set mixing rule
770+
fluid.setMixingRule("classic")
771+
772+
# 4. Optional but recommended for custom components
773+
# fluid.createDatabase(True)
774+
```
775+
776+
**NEVER skip the mixing rule** - simulations will fail or give wrong results without it.
777+
778+
### Process Equipment Connections
779+
780+
```python
781+
# Create process system
782+
process = ProcessSystem("My Process")
783+
784+
# Feed stream
785+
feed = Stream("Feed", fluid)
786+
feed.setFlowRate(50000.0, "kg/hr")
787+
process.add(feed)
788+
789+
# Equipment takes inlet stream in constructor
790+
separator = Separator("HP Sep", feed) # Stream object, not name
791+
process.add(separator)
792+
793+
# Get outlet streams from equipment
794+
gas_out = separator.getGasOutStream() # Gas phase
795+
liquid_out = separator.getLiquidOutStream() # Liquid phase
796+
797+
# Connect to next equipment
798+
compressor = Compressor("Comp", gas_out)
799+
process.add(compressor)
800+
801+
# For equipment outlet
802+
next_stream = compressor.getOutletStream()
803+
```
804+
805+
### Common Class Import Paths
806+
807+
```python
808+
# Thermo systems
809+
SystemSrkEos = jneqsim.thermo.system.SystemSrkEos
810+
SystemPrEos = jneqsim.thermo.system.SystemPrEos
811+
SystemSrkCPAstatoil = jneqsim.thermo.system.SystemSrkCPAstatoil
812+
813+
# Process equipment
814+
ProcessSystem = jneqsim.process.processmodel.ProcessSystem
815+
Stream = jneqsim.process.equipment.stream.Stream
816+
Separator = jneqsim.process.equipment.separator.Separator
817+
ThreePhaseSeparator = jneqsim.process.equipment.separator.ThreePhaseSeparator
818+
Compressor = jneqsim.process.equipment.compressor.Compressor
819+
Expander = jneqsim.process.equipment.expander.Expander
820+
Heater = jneqsim.process.equipment.heatexchanger.Heater
821+
Cooler = jneqsim.process.equipment.heatexchanger.Cooler
822+
HeatExchanger = jneqsim.process.equipment.heatexchanger.HeatExchanger
823+
Mixer = jneqsim.process.equipment.mixer.Mixer
824+
Splitter = jneqsim.process.equipment.splitter.Splitter
825+
ThrottlingValve = jneqsim.process.equipment.valve.ThrottlingValve
826+
Recycle = jneqsim.process.equipment.util.Recycle
827+
Adjuster = jneqsim.process.equipment.util.Adjuster
828+
829+
# Pipes
830+
AdiabaticPipe = jneqsim.process.equipment.pipeline.AdiabaticPipe
831+
PipeBeggsAndBrills = jneqsim.process.equipment.pipeline.PipeBeggsAndBrills
832+
833+
# Distillation
834+
DistillationColumn = jneqsim.process.equipment.distillation.DistillationColumn
835+
```
836+
837+
### Getting Results
838+
839+
```python
840+
# After running process
841+
process.run()
842+
843+
# Stream properties
844+
stream.getTemperature() # Kelvin
845+
stream.getPressure() # bara
846+
stream.getFlowRate("kg/hr") # Mass flow with unit
847+
848+
# Fluid properties
849+
fluid = stream.getFluid()
850+
fluid.getDensity("kg/m3") # Density
851+
fluid.getMolarMass("kg/mol") # Molar mass
852+
fluid.getZ() # Compressibility factor
853+
fluid.getNumberOfPhases() # Phase count
854+
fluid.hasPhaseType("gas") # Check phase presence
855+
856+
# Compressor
857+
comp.getPower("kW") # Power consumption
858+
comp.getOutletStream() # Outlet stream
859+
860+
# Heat exchangers
861+
heater.getDuty() # Heat duty in Watts
862+
cooler.getDuty() # Cooling duty (positive = heat removed)
863+
```
864+
865+
### Notebook Structure Best Practice
866+
867+
1. **Introduction cell** - Describe what the notebook demonstrates
868+
2. **Setup cell** - All imports in one cell
869+
3. **Fluid creation** - Separate cell for creating thermodynamic system
870+
4. **Process building** - Build process step by step
871+
5. **Run simulation** - Single `process.run()` call
872+
6. **Results** - Extract and display results
873+
7. **Visualization** - Plots using matplotlib
874+
8. **Tips/Next steps** - Summary and links to related examples
875+
876+
### Type Conversion for Java
877+
878+
When passing values to Java methods, ensure correct types:
879+
```python
880+
# Explicitly convert to float for numeric parameters
881+
pressure = 60.0 # Already float
882+
comp.setOutletPressure(float(pressure)) # Explicit conversion if unsure
883+
884+
# String parameters
885+
stream.setFlowRate(50000.0, str("kg/hr")) # Usually not needed but safe
886+
887+
# Boolean
888+
fluid.setMultiPhaseCheck(True) # Python bool works
889+
```
890+
891+
---

docs/blackoil/README.md

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -78,34 +78,43 @@ $$B_o = 1 + C_1 R_s + C_2 (T - 60) \left( \frac{API}{\gamma_{g,100}} \right) + C
7878

7979
### BlackOilPVTTable
8080

81+
The `BlackOilPVTTable` class stores PVT properties at multiple pressure points with linear interpolation.
82+
8183
```java
8284
import neqsim.blackoil.BlackOilPVTTable;
85+
import neqsim.blackoil.BlackOilPVTTable.Record;
86+
import java.util.Arrays;
87+
import java.util.List;
88+
89+
// Create PVT records at each pressure point
90+
// Record(p, Rs, Bo, mu_o, Bg, mu_g, Rv, Bw, mu_w)
91+
List<Record> records = Arrays.asList(
92+
new Record(50.0, 80.0, 1.25, 0.0015, 0.010, 0.000015, 0.0, 1.01, 0.001),
93+
new Record(100.0, 100.0, 1.30, 0.0012, 0.008, 0.000016, 0.0, 1.01, 0.001),
94+
new Record(150.0, 120.0, 1.35, 0.0010, 0.006, 0.000017, 0.0, 1.02, 0.001),
95+
new Record(200.0, 140.0, 1.40, 0.0009, 0.005, 0.000018, 0.0, 1.02, 0.001),
96+
new Record(250.0, 160.0, 1.45, 0.0008, 0.004, 0.000019, 0.0, 1.03, 0.001),
97+
new Record(300.0, 180.0, 1.50, 0.0007, 0.003, 0.000020, 0.0, 1.03, 0.001)
98+
);
8399

84-
// Create PVT table
85-
BlackOilPVTTable pvtTable = new BlackOilPVTTable();
86-
87-
// Set pressure points
88-
double[] pressures = {50, 100, 150, 200, 250, 300};
89-
pvtTable.setPressures(pressures);
90-
91-
// Set properties at each pressure
92-
pvtTable.setRs(new double[]{80, 100, 120, 140, 160, 180});
93-
pvtTable.setBo(new double[]{1.25, 1.30, 1.35, 1.40, 1.45, 1.50});
94-
pvtTable.setBg(new double[]{0.010, 0.008, 0.006, 0.005, 0.004, 0.003});
95-
pvtTable.setMuO(new double[]{1.5, 1.2, 1.0, 0.9, 0.8, 0.7});
96-
pvtTable.setMuG(new double[]{0.015, 0.016, 0.017, 0.018, 0.019, 0.020});
100+
// Create PVT table with bubble point pressure
101+
double bubblePointPressure = 250.0; // bar
102+
BlackOilPVTTable pvtTable = new BlackOilPVTTable(records, bubblePointPressure);
97103
```
98104

99105
### Interpolation
100106

101107
```java
102-
// Get properties at any pressure
108+
// Get properties at any pressure (linear interpolation)
103109
double P = 175.0; // bar
104-
double Rs = pvtTable.Rs(P);
105-
double Bo = pvtTable.Bo(P);
106-
double Bg = pvtTable.Bg(P);
107-
double muO = pvtTable.mu_o(P);
108-
double muG = pvtTable.mu_g(P);
110+
double Rs = pvtTable.Rs(P); // Solution GOR
111+
double Bo = pvtTable.Bo(P); // Oil FVF
112+
double Bg = pvtTable.Bg(P); // Gas FVF
113+
double muO = pvtTable.mu_o(P); // Oil viscosity (Pa·s)
114+
double muG = pvtTable.mu_g(P); // Gas viscosity (Pa·s)
115+
116+
// Above bubble point, Rs stays constant
117+
double RsEffective = pvtTable.RsEffective(P);
109118
```
110119

111120
---

docs/examples/AdvancedRiskFramework_Tutorial.ipynb

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,35 +29,33 @@
2929
"metadata": {},
3030
"outputs": [],
3131
"source": [
32-
"# Import NeqSim via JPype\n",
33-
"import jpype\n",
34-
"import jpype.imports\n",
35-
"from jpype.types import *\n",
36-
"\n",
37-
"# Start JVM if not already running\n",
38-
"if not jpype.isJVMStarted():\n",
39-
" jpype.startJVM(classpath=['neqsim-*.jar'])\n",
40-
"\n",
41-
"# Import Java classes\n",
42-
"from java.util import HashMap, ArrayList\n",
43-
"\n",
44-
"# Import NeqSim core\n",
45-
"from neqsim.thermo.system import SystemSrkEos\n",
46-
"from neqsim.process import ProcessSystem\n",
47-
"from neqsim.process.equipment.stream import Stream\n",
48-
"from neqsim.process.equipment.separator import Separator\n",
49-
"from neqsim.process.equipment.compressor import Compressor\n",
50-
"from neqsim.process.equipment.pump import Pump\n",
51-
"\n",
52-
"# Import Risk Framework\n",
53-
"from neqsim.process.safety.risk import OperationalRiskSimulator, RiskModel, RiskMatrix\n",
54-
"from neqsim.process.safety.risk.dynamic import DynamicRiskSimulator, ProductionProfile\n",
55-
"from neqsim.process.safety.risk.sis import SafetyInstrumentedFunction, SISIntegratedRiskModel\n",
56-
"from neqsim.process.safety.risk.realtime import RealTimeRiskMonitor, RealTimeRiskAssessment\n",
57-
"from neqsim.process.safety.risk.bowtie import BowTieAnalyzer, BowTieModel\n",
58-
"from neqsim.process.safety.risk.portfolio import PortfolioRiskAnalyzer, PortfolioRiskResult\n",
59-
"from neqsim.process.safety.risk.condition import ConditionBasedReliability\n",
60-
"from neqsim.process.safety.risk.ml import RiskMLInterface\n",
32+
"# Import NeqSim - Direct Java Access via jneqsim\n",
33+
"from neqsim import jneqsim\n",
34+
"\n",
35+
"# Import Java classes through the jneqsim gateway\n",
36+
"SystemSrkEos = jneqsim.thermo.system.SystemSrkEos\n",
37+
"ProcessSystem = jneqsim.process.processmodel.ProcessSystem\n",
38+
"Stream = jneqsim.process.equipment.stream.Stream\n",
39+
"Separator = jneqsim.process.equipment.separator.Separator\n",
40+
"Compressor = jneqsim.process.equipment.compressor.Compressor\n",
41+
"Pump = jneqsim.process.equipment.pump.Pump\n",
42+
"\n",
43+
"# Import Risk Framework classes\n",
44+
"OperationalRiskSimulator = jneqsim.process.safety.risk.OperationalRiskSimulator\n",
45+
"RiskModel = jneqsim.process.safety.risk.RiskModel\n",
46+
"RiskMatrix = jneqsim.process.safety.risk.RiskMatrix\n",
47+
"DynamicRiskSimulator = jneqsim.process.safety.risk.dynamic.DynamicRiskSimulator\n",
48+
"ProductionProfile = jneqsim.process.safety.risk.dynamic.ProductionProfile\n",
49+
"SafetyInstrumentedFunction = jneqsim.process.safety.risk.sis.SafetyInstrumentedFunction\n",
50+
"SISIntegratedRiskModel = jneqsim.process.safety.risk.sis.SISIntegratedRiskModel\n",
51+
"RealTimeRiskMonitor = jneqsim.process.safety.risk.realtime.RealTimeRiskMonitor\n",
52+
"RealTimeRiskAssessment = jneqsim.process.safety.risk.realtime.RealTimeRiskAssessment\n",
53+
"BowTieAnalyzer = jneqsim.process.safety.risk.bowtie.BowTieAnalyzer\n",
54+
"BowTieModel = jneqsim.process.safety.risk.bowtie.BowTieModel\n",
55+
"PortfolioRiskAnalyzer = jneqsim.process.safety.risk.portfolio.PortfolioRiskAnalyzer\n",
56+
"PortfolioRiskResult = jneqsim.process.safety.risk.portfolio.PortfolioRiskResult\n",
57+
"ConditionBasedReliability = jneqsim.process.safety.risk.condition.ConditionBasedReliability\n",
58+
"RiskMLInterface = jneqsim.process.safety.risk.ml.RiskMLInterface\n",
6159
"\n",
6260
"print(\"NeqSim Risk Framework loaded successfully!\")"
6361
]

docs/examples/FieldDevelopmentWorkflow.ipynb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,21 +28,21 @@
2828
"metadata": {},
2929
"outputs": [],
3030
"source": [
31-
"import jpype\n",
32-
"import jpype.imports\n",
33-
"from jpype.types import *\n",
31+
"# Import NeqSim - Direct Java Access via jneqsim\n",
32+
"from neqsim import jneqsim\n",
3433
"\n",
35-
"# Start JVM with NeqSim\n",
36-
"if not jpype.isJVMStarted():\n",
37-
" jpype.startJVM(classpath=['path/to/neqsim.jar'])\n",
34+
"# Import Java classes through the jneqsim gateway\n",
35+
"SystemSrkEos = jneqsim.thermo.system.SystemSrkEos\n",
36+
"SystemSrkCPAstatoil = jneqsim.thermo.system.SystemSrkCPAstatoil\n",
37+
"Stream = jneqsim.process.equipment.stream.Stream\n",
38+
"WellSystem = jneqsim.process.equipment.reservoir.WellSystem\n",
39+
"SimpleReservoir = jneqsim.process.equipment.reservoir.SimpleReservoir\n",
40+
"FieldDevelopmentWorkflow = jneqsim.process.fielddevelopment.workflow.FieldDevelopmentWorkflow\n",
41+
"CashFlowEngine = jneqsim.process.fielddevelopment.economics.CashFlowEngine\n",
42+
"NorwegianTaxModel = jneqsim.process.fielddevelopment.economics.NorwegianTaxModel\n",
43+
"FlowAssuranceResult = jneqsim.process.fielddevelopment.screening.FlowAssuranceResult\n",
3844
"\n",
39-
"# Import NeqSim classes\n",
40-
"from neqsim.thermo.system import SystemSrkEos, SystemSrkCPAstatoil\n",
41-
"from neqsim.process.equipment.stream import Stream\n",
42-
"from neqsim.process.equipment.reservoir import WellSystem, SimpleReservoir\n",
43-
"from neqsim.process.fielddevelopment.workflow import FieldDevelopmentWorkflow\n",
44-
"from neqsim.process.fielddevelopment.economics import CashFlowEngine, NorwegianTaxModel\n",
45-
"from neqsim.process.fielddevelopment.screening import FlowAssuranceResult"
45+
"print(\"NeqSim Field Development Framework loaded successfully!\")"
4646
]
4747
},
4848
{

0 commit comments

Comments
 (0)