Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/neqsim-engine.sha256
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0f56e426a999dfc844fe647c0c6f710afd09be306dada2085778dbcc672bfba2 neqsim-3.28.0.jar
d75c8314a0ac14bebdd2be5c0a733be836cbc9752a19bb6c9185b8cbb32d40bb neqsim-3.29.0.jar
2 changes: 1 addition & 1 deletion conda/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% set name = "neqsim" %}
{% set version = "3.28.0" %}
{% set version = "3.29.0" %}

package:
name: {{ name|lower }}
Expand Down
96 changes: 96 additions & 0 deletions docs/release-notes/v3.29.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# NeqSim Python 3.29.0

NeqSim Python is the Python interface to the NeqSim engine for thermodynamic
calculations, physical properties, process simulation, and PVT analysis from
Python and Jupyter notebooks.

## Highlights

- Bundles the official NeqSim Java 3.29.0 release engine for Java 17 or newer.
- Thermodynamics and flash: speeds up CPA association solving and cubic phase
classification, recovers free water below the overall-water screen, corrects
LBC viscosity pseudo-critical mixing, and preserves phase state and
composition across zero stream flow.
- Reservoir and PVT: extends fixed-cell depletion with dry and wet-gas phase
transitions and conserved-inventory Gibbs comparisons, stabilizes aquifer
influence functions, and adds OLGA PVT table options (configurable grids,
produced water, salinity) and a forward PVT proxy surface process generator.
- Electrolytes and chemistry: adds an exact-source reactive carbonate mode for
Pitzer brines, solid-gas reaction equilibrium (FeS/FeCO3), and reservoir H2S
mineral-buffer screening.
- Process equipment and dynamics: adds compressor power-train integration with
turbine and electric drivers, conservative separator energy integration,
dynamic heat-exchanger control workflows, reference water and seawater
cooling properties, and gas-turbine installation pressure-loss corrections.
- Pipelines and networks: improves two-fluid restart, terrain low-point pool
reporting, pig position events and gas-inventory coupling, and atomic
algebraic-junction network solving.
- Engineering drawings and safety: connects ESD/HIPPS and PSV responses and
compressor automation to DEXPI P&IDs, links System Control Diagrams, and runs
safety scenarios across process models. Review drawings still require
engineering verification.
- Fixes: distillation columns are no longer reported solved while internal flows
are still changing, `.neqsim` files are stamped with the real NeqSim
version, DEXPI import handles standard Proteus XML, and the n-decane molar
mass in the ISO 6976 constants is corrected.- Refreshes the bundled Java API manifest, type stubs, and component-name
metadata for the 3.29.0 engine.
- Retains Python 3.10-3.14 support and the existing NeqSim Python API.

## Install

Use pip when you already have Java installed:

```bash
pip install --upgrade neqsim==3.29.0
```

The matching conda-forge package can be installed once it is published:

```bash
conda install -c conda-forge neqsim=3.29.0
```

Requirements:

- Python 3.10 or newer.
- Java 17 or newer for pip installs. Download Java from
[Adoptium](https://adoptium.net/).
- Conda installs include OpenJDK through conda-forge.

Verify the installed package version without starting the JVM:

```bash
python -c "from importlib.metadata import version; print(version('neqsim'))"
```

## Quick Start

```python
from neqsim.thermo import TPflash, fluid, printFrame

natural_gas = fluid("srk")
natural_gas.addComponent("methane", 0.85)
natural_gas.addComponent("ethane", 0.10)
natural_gas.addComponent("propane", 0.05)
natural_gas.setTemperature(25.0, "C")
natural_gas.setPressure(60.0, "bara")
natural_gas.setMixingRule("classic")

TPflash(natural_gas)
printFrame(natural_gas)
```

## Engine Provenance

The bundled `neqsim-3.29.0.jar` is downloaded from the
[official NeqSim 3.29.0 release](https://github.com/equinor/neqsim/releases/tag/v3.29.0).

SHA-256: `d75c8314a0ac14bebdd2be5c0a733be836cbc9752a19bb6c9185b8cbb32d40bb`

## Useful Links

- Full changelog: https://github.com/equinor/neqsim-python/compare/v3.28.0...v3.29.0
- NeqSim Java 3.29.0 release: https://github.com/equinor/neqsim/releases/tag/v3.29.0
- Documentation: https://equinor.github.io/neqsimhome/
- Python examples: https://github.com/equinor/neqsim-python/tree/master/examples
- Discussions: https://github.com/equinor/neqsim/discussions
2 changes: 1 addition & 1 deletion environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ dependencies:
# Install neqsim from PyPI until conda-forge package is available
- pip
- pip:
- neqsim==3.28.0
- neqsim==3.29.0
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "neqsim"
version = "3.28.0"
version = "3.29.0"
description = "NeqSim is a tool for thermodynamic and process calculations"
authors = [{ name = "Even Solbraa", email = "esolbraa@gmail.com" }]
requires-python = ">=3.10,<4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import jneqsim.physicalproperties.methods.liquidphysicalproperties.conductivity
import jneqsim.physicalproperties.methods.liquidphysicalproperties.density
import jneqsim.physicalproperties.methods.liquidphysicalproperties.diffusivity
import jneqsim.physicalproperties.methods.liquidphysicalproperties.viscosity
import jneqsim.physicalproperties.methods.methodinterface
import jneqsim.physicalproperties.system
import typing

Expand All @@ -19,11 +20,20 @@ class LiquidPhysicalPropertyMethod(jneqsim.physicalproperties.methods.PhysicalPr
def __init__(self, physicalProperties: jneqsim.physicalproperties.system.PhysicalProperties): ...
def setPhase(self, physicalProperties: jneqsim.physicalproperties.system.PhysicalProperties) -> None: ...

class ReferenceWaterTransportProperties(LiquidPhysicalPropertyMethod, jneqsim.physicalproperties.methods.methodinterface.DensityInterface, jneqsim.physicalproperties.methods.methodinterface.ViscosityInterface, jneqsim.physicalproperties.methods.methodinterface.ConductivityInterface):
def __init__(self, physicalProperties: jneqsim.physicalproperties.system.PhysicalProperties): ...
def calcConductivity(self) -> float: ...
def calcDensity(self) -> float: ...
def calcViscosity(self) -> float: ...
def clone(self) -> 'ReferenceWaterTransportProperties': ...
def getPureComponentViscosity(self, int: int) -> float: ...


class __module_protocol__(Protocol):
# A module protocol which reflects the result of ``jp.JPackage("jneqsim.physicalproperties.methods.liquidphysicalproperties")``.

LiquidPhysicalPropertyMethod: typing.Type[LiquidPhysicalPropertyMethod]
ReferenceWaterTransportProperties: typing.Type[ReferenceWaterTransportProperties]
conductivity: jneqsim.physicalproperties.methods.liquidphysicalproperties.conductivity.__module_protocol__
density: jneqsim.physicalproperties.methods.liquidphysicalproperties.density.__module_protocol__
diffusivity: jneqsim.physicalproperties.methods.liquidphysicalproperties.diffusivity.__module_protocol__
Expand Down
6 changes: 6 additions & 0 deletions src/jneqsim-stubs/process/controllerdevice/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ class ControllerDeviceBaseClass(jneqsim.util.NamedBaseClass, ControllerDeviceInt
@typing.overload
def __init__(self, string: typing.Union[java.lang.String, str]): ...
def addGainSchedulePoint(self, double: float, double2: float, double3: float, double4: float) -> None: ...
def applyControlConfiguration(self, map: typing.Union[java.util.Map[typing.Union[java.lang.String, str], typing.Any], typing.Mapping[typing.Union[java.lang.String, str], typing.Any]]) -> None: ...
@typing.overload
def autoTune(self, double: float, double2: float) -> None: ...
@typing.overload
Expand All @@ -232,6 +233,7 @@ class ControllerDeviceBaseClass(jneqsim.util.NamedBaseClass, ControllerDeviceInt
@typing.overload
def autoTuneStepResponse(self, double: float, double2: float, double3: float, boolean: bool) -> None: ...
def captureTransientState(self) -> 'ControllerDeviceBaseClass.ControllerTransientState': ...
def getControlConfiguration(self) -> java.util.Map[java.lang.String, typing.Any]: ...
def getControllerSetPoint(self) -> float: ...
def getDeadBand(self) -> float: ...
def getEventLog(self) -> java.util.List[ControllerEvent]: ...
Expand Down Expand Up @@ -609,7 +611,9 @@ class AntiSurgeController(ControllerDeviceBaseClass):
def __init__(self, string: typing.Union[java.lang.String, str]): ...
@typing.overload
def __init__(self, string: typing.Union[java.lang.String, str], compressor: jneqsim.process.equipment.compressor.Compressor, throttlingValve: jneqsim.process.equipment.valve.ThrottlingValve): ...
def applyControlConfiguration(self, map: typing.Union[java.util.Map[typing.Union[java.lang.String, str], typing.Any], typing.Mapping[typing.Union[java.lang.String, str], typing.Any]]) -> None: ...
def getCompressor(self) -> jneqsim.process.equipment.compressor.Compressor: ...
def getControlConfiguration(self) -> java.util.Map[java.lang.String, typing.Any]: ...
def getFilteredMarginRate(self) -> float: ...
def getIntegralTime(self) -> float: ...
@typing.overload
Expand All @@ -621,6 +625,7 @@ class AntiSurgeController(ControllerDeviceBaseClass):
def getProportionalGain(self) -> float: ...
def getRecycleValve(self) -> jneqsim.process.equipment.valve.ThrottlingValve: ...
def getResponse(self) -> float: ...
def getSurgeMarginMeasurement(self) -> jneqsim.process.measurementdevice.MeasurementDeviceInterface: ...
def getSurgeMarginSetPoint(self) -> float: ...
def getTargetValveOpening(self) -> float: ...
def getValveOpening(self) -> float: ...
Expand All @@ -640,6 +645,7 @@ class AntiSurgeController(ControllerDeviceBaseClass):
def setPredictiveActionEnabled(self, boolean: bool) -> None: ...
def setProportionalGain(self, double: float) -> None: ...
def setRecycleValve(self, throttlingValve: jneqsim.process.equipment.valve.ThrottlingValve) -> None: ...
def setSurgeMarginMeasurement(self, measurementDeviceInterface: jneqsim.process.measurementdevice.MeasurementDeviceInterface) -> None: ...
def setSurgeMarginSetPoint(self, double: float) -> None: ...


Expand Down
1 change: 1 addition & 0 deletions src/jneqsim-stubs/process/diagnostics/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ class RelationshipGraph(java.io.Serializable):

class RootCauseAnalyzer(java.io.Serializable):
def __init__(self, processSystem: jneqsim.process.processmodel.ProcessSystem, string: typing.Union[java.lang.String, str]): ...
def addIncidentHistoryPrior(self, string: typing.Union[java.lang.String, str], int: int, string2: typing.Union[java.lang.String, str]) -> None: ...
def analyze(self) -> 'RootCauseReport': ...
@typing.overload
def analyzeAutonomous(self) -> 'RootCauseReport': ...
Expand Down
37 changes: 37 additions & 0 deletions src/jneqsim-stubs/process/engineering/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ else:
import com.google.gson
import java.io
import java.lang
import java.nio.file
import java.util
import jpype
import jpype.protocol
import jneqsim.process.engineering.automation
import jneqsim.process.engineering.calculation
import jneqsim.process.engineering.deliverables
Expand All @@ -27,19 +30,36 @@ import jneqsim.process.engineering.piping
import jneqsim.process.engineering.production
import jneqsim.process.engineering.rotating
import jneqsim.process.engineering.safety
import jneqsim.process.engineering.scd
import jneqsim.process.engineering.validation
import jneqsim.process.engineering.verticalslice
import jneqsim.process.equipment
import jneqsim.process.materials
import jneqsim.process.processmodel
import jneqsim.process.processmodel.dexpi
import jneqsim.process.safety.depressurization
import jneqsim.process.safety.esd
import jneqsim.process.safety.overpressure
import jneqsim.process.safety.scenario
import jneqsim.process.util.scenario
import typing



class CompressorAutomationWorkflow:
@staticmethod
def defaultCases() -> java.util.List[jneqsim.process.util.scenario.CompressorAutomationStudy.CaseDefinition]: ...
@staticmethod
def designFromJson(string: typing.Union[java.lang.String, str]) -> jneqsim.process.util.scenario.CompressorAutomationStudy.Design: ...
@staticmethod
def main(stringArray: typing.Union[typing.List[java.lang.String], jpype.JArray]) -> None: ...
@typing.overload
@staticmethod
def run(design: jneqsim.process.util.scenario.CompressorAutomationStudy.Design, path: typing.Union[java.nio.file.Path, jpype.protocol.SupportsPath]) -> java.util.Map[java.lang.String, typing.Any]: ...
@typing.overload
@staticmethod
def run(design: jneqsim.process.util.scenario.CompressorAutomationStudy.Design, pidDesignModel: jneqsim.process.engineering.pid.PidDesignModel, list: java.util.List[jneqsim.process.util.scenario.CompressorAutomationStudy.CaseDefinition], path: typing.Union[java.nio.file.Path, jpype.protocol.SupportsPath]) -> java.util.Map[java.lang.String, typing.Any]: ...

class EngineeringApprovalRecord(java.io.Serializable):
def __init__(self, string: typing.Union[java.lang.String, str], string2: typing.Union[java.lang.String, str], string3: typing.Union[java.lang.String, str], status: 'EngineeringApprovalRecord.Status', string4: typing.Union[java.lang.String, str], string5: typing.Union[java.lang.String, str], string6: typing.Union[java.lang.String, str]): ...
def getDiscipline(self) -> java.lang.String: ...
Expand Down Expand Up @@ -272,6 +292,12 @@ class EngineeringSimulationRunner:
def buildCaseSet(engineeringProject: EngineeringProject) -> jneqsim.process.engineering.designcase.EngineeringCaseSet: ...
@staticmethod
def run(engineeringProject: EngineeringProject, engineeringCaseRunOptions: jneqsim.process.engineering.designcase.EngineeringCaseRunOptions) -> EngineeringSimulationResult: ...
@typing.overload
@staticmethod
def runStrict(engineeringProject: EngineeringProject) -> EngineeringSimulationResult: ...
@typing.overload
@staticmethod
def runStrict(engineeringProject: EngineeringProject, engineeringCaseRunOptions: jneqsim.process.engineering.designcase.EngineeringCaseRunOptions) -> EngineeringSimulationResult: ...

class EngineeringStandard(java.io.Serializable):
def __init__(self, string: typing.Union[java.lang.String, str], string2: typing.Union[java.lang.String, str], string3: typing.Union[java.lang.String, str], string4: typing.Union[java.lang.String, str]): ...
Expand Down Expand Up @@ -307,6 +333,14 @@ class EngineeringValidationReport(java.io.Serializable):
@staticmethod
def values() -> typing.MutableSequence['EngineeringValidationReport.Severity']: ...

class HeatExchangerAutomationWorkflow:
@staticmethod
def export(engineeringProject: EngineeringProject, dexpi20PlantExportMetadata: jneqsim.process.processmodel.dexpi.Dexpi20PlantExportMetadata, path: typing.Union[java.nio.file.Path, jpype.protocol.SupportsPath], result: jneqsim.process.engineering.pid.HeatExchangerControllerTuning.Result) -> java.nio.file.Path: ...
@staticmethod
def instrument(processSystem: jneqsim.process.processmodel.ProcessSystem, string: typing.Union[java.lang.String, str], string2: typing.Union[java.lang.String, str], string3: typing.Union[java.lang.String, str], settings: 'HeatExchangerAutomationWorkflow.Settings') -> EngineeringProject: ...
class Settings:
def __init__(self, int: int, int2: int, double: float, double2: float, double3: float, double4: float): ...

class LineDesignInput(java.io.Serializable):
def __init__(self, string: typing.Union[java.lang.String, str], string2: typing.Union[java.lang.String, str]): ...
def addEvidenceReference(self, string: typing.Union[java.lang.String, str]) -> 'LineDesignInput': ...
Expand Down Expand Up @@ -544,6 +578,7 @@ class SimulationEngineeringDesignRunner:
class __module_protocol__(Protocol):
# A module protocol which reflects the result of ``jp.JPackage("jneqsim.process.engineering")``.

CompressorAutomationWorkflow: typing.Type[CompressorAutomationWorkflow]
EngineeringApprovalRecord: typing.Type[EngineeringApprovalRecord]
EngineeringApprovalStatus: typing.Type[EngineeringApprovalStatus]
EngineeringBoundary: typing.Type[EngineeringBoundary]
Expand All @@ -558,6 +593,7 @@ class __module_protocol__(Protocol):
EngineeringSimulationRunner: typing.Type[EngineeringSimulationRunner]
EngineeringStandard: typing.Type[EngineeringStandard]
EngineeringValidationReport: typing.Type[EngineeringValidationReport]
HeatExchangerAutomationWorkflow: typing.Type[HeatExchangerAutomationWorkflow]
LineDesignInput: typing.Type[LineDesignInput]
NorsokOffshoreEngineeringBuilder: typing.Type[NorsokOffshoreEngineeringBuilder]
ProcessToEngineeringDesignBuilder: typing.Type[ProcessToEngineeringDesignBuilder]
Expand Down Expand Up @@ -585,5 +621,6 @@ class __module_protocol__(Protocol):
production: jneqsim.process.engineering.production.__module_protocol__
rotating: jneqsim.process.engineering.rotating.__module_protocol__
safety: jneqsim.process.engineering.safety.__module_protocol__
scd: jneqsim.process.engineering.scd.__module_protocol__
validation: jneqsim.process.engineering.validation.__module_protocol__
verticalslice: jneqsim.process.engineering.verticalslice.__module_protocol__
4 changes: 4 additions & 0 deletions src/jneqsim-stubs/process/engineering/dexpi/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ class Dexpi201PidMaterializer:
class DexpiEngineeringExporter:
@staticmethod
def export(engineeringProject: jneqsim.process.engineering.EngineeringProject, path: typing.Union[java.nio.file.Path, jpype.protocol.SupportsPath]) -> 'DexpiEngineeringExporter.ExportResult': ...
@typing.overload
@staticmethod
def exportDexpi201(engineeringProject: jneqsim.process.engineering.EngineeringProject, path: typing.Union[java.nio.file.Path, jpype.protocol.SupportsPath], dexpi20PlantExportMetadata: jneqsim.process.processmodel.dexpi.Dexpi20PlantExportMetadata) -> jneqsim.process.processmodel.dexpi.Dexpi20ConformanceAssessment.Report: ...
@typing.overload
@staticmethod
def exportDexpi201(engineeringProject: jneqsim.process.engineering.EngineeringProject, path: typing.Union[java.nio.file.Path, jpype.protocol.SupportsPath], dexpi20PlantExportMetadata: jneqsim.process.processmodel.dexpi.Dexpi20PlantExportMetadata, boolean: bool) -> jneqsim.process.processmodel.dexpi.Dexpi20ConformanceAssessment.Report: ...
@staticmethod
def refreshPackageManifest(path: typing.Union[java.nio.file.Path, jpype.protocol.SupportsPath]) -> java.nio.file.Path: ...
class ExportResult:
Expand Down
Loading
Loading