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 @@
2afff2377963e47565b8c473f3f9bbd69fae6fd383b7c0f53399ab2956e3974a neqsim-3.23.0.jar
ba8ab3749355fb9983d09a14892e6a23e7bac929f60547ce9db7b5bf4e18b139 neqsim-3.24.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.23.0" %}
{% set version = "3.24.0" %}

package:
name: {{ name|lower }}
Expand Down
62 changes: 62 additions & 0 deletions docs/release-notes/v3.24.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# NeqSim Python 3.24.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 NeqSim Java 3.24.0 engine for Java 17 or newer.
- Thermodynamic fixes: flash calculations recover conservative condensate
splits after an endpoint collapse, exact-zero mole fractions are preserved
through dependent property calculations, and the unused legacy TP flash
solver is deprecated in favor of the maintained solver path.
- Process fixes: `ProcessSystem` recycle diagnostics and minimum-flow spill
handling are corrected against the separator limit basis, and
`MultiStreamHeatExchanger2` reports solver status and flags an infeasible
approach temperature instead of returning a silently wrong result.
- Distillation fixes: shortcut columns reject invalid reflux ratios and stage
counts, and direct terminal specifications report physically consistent
residuals.
- Pipeline and network: multiphase chokes follow a new
`TabulatedValveCharacteristic`, Beggs and Brill pipe-flow solves fail closed
instead of returning an unconverged result, and field-scale pipeline
networks gain per-edge Beggs-Brill/two-fluid steady hydraulics alongside new
inflow-control-device, inflow-control-completion, and subsea
separation-station screening models.
- New capability: `SealGasSupplyConditioning` screens seal-gas supply dew
point margin for compressor dry-gas seal systems.
- Internal: the Jama linear-algebra dependency is replaced with EJML.
- 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.24.0
```

Use conda when you want OpenJDK installed with the package:

```bash
conda install -c conda-forge neqsim=3.24.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'))"
```

## Useful Links

- Full changelog: https://github.com/equinor/neqsim-python/compare/v3.23.0...v3.24.0
- NeqSim Java 3.24.0 release: https://github.com/equinor/neqsim/releases/tag/v3.24.0
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.23.0
- neqsim==3.24.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.23.0"
version = "3.24.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
2 changes: 2 additions & 0 deletions src/jneqsim-stubs/mathlib/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ else:
from typing_extensions import Protocol

import jneqsim.mathlib.generalmath
import jneqsim.mathlib.linearalgebra
import jneqsim.mathlib.nonlinearsolver
import typing

Expand All @@ -14,4 +15,5 @@ class __module_protocol__(Protocol):
# A module protocol which reflects the result of ``jp.JPackage("jneqsim.mathlib")``.

generalmath: jneqsim.mathlib.generalmath.__module_protocol__
linearalgebra: jneqsim.mathlib.linearalgebra.__module_protocol__
nonlinearsolver: jneqsim.mathlib.nonlinearsolver.__module_protocol__
127 changes: 127 additions & 0 deletions src/jneqsim-stubs/mathlib/linearalgebra/__init__.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@

import sys
if sys.version_info >= (3, 8):
from typing import Protocol
else:
from typing_extensions import Protocol

import java.lang
import jpype
import typing



class LinearAlgebraException(java.lang.RuntimeException):
@typing.overload
def __init__(self, string: typing.Union[java.lang.String, str]): ...
@typing.overload
def __init__(self, string: typing.Union[java.lang.String, str], throwable: java.lang.Throwable): ...

class LinearAlgebraOperations:
@typing.overload
def add(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def add(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def conditionNumber(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def determinant(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def euclideanNorm(self, doubleArray: typing.Union[typing.List[float], jpype.JArray]) -> float: ...
def getName(self) -> java.lang.String: ...
def identity(self, int: int) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def invert(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
@typing.overload
def multiply(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def multiply(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def oneNorm(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def rank(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> int: ...
@typing.overload
def scale(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], double2: float) -> typing.MutableSequence[float]: ...
@typing.overload
def scale(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], double2: float) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def solve(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
def solveLeastSquares(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
def spectralNorm(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def submatrix(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], int: int, int2: int, int3: int, int4: int) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
@typing.overload
def subtract(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def subtract(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def transpose(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def withSubmatrix(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], int: int, int2: int, doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...

class EjmlLinearAlgebra(LinearAlgebraOperations):
NAME: typing.ClassVar[java.lang.String] = ...
def __init__(self): ...
@typing.overload
def add(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def add(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def conditionNumber(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def determinant(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def euclideanNorm(self, doubleArray: typing.Union[typing.List[float], jpype.JArray]) -> float: ...
def getName(self) -> java.lang.String: ...
def identity(self, int: int) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def invert(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
@typing.overload
def multiply(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def multiply(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def oneNorm(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def rank(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> int: ...
@typing.overload
def scale(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], double2: float) -> typing.MutableSequence[float]: ...
@typing.overload
def scale(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], double2: float) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def solve(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
def solveLeastSquares(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
def spectralNorm(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def submatrix(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], int: int, int2: int, int3: int, int4: int) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
@typing.overload
def subtract(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def subtract(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def transpose(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def withSubmatrix(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], int: int, int2: int, doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...

class JamaLinearAlgebra(LinearAlgebraOperations):
NAME: typing.ClassVar[java.lang.String] = ...
def __init__(self): ...
@typing.overload
def add(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def add(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def conditionNumber(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def determinant(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def euclideanNorm(self, doubleArray: typing.Union[typing.List[float], jpype.JArray]) -> float: ...
def getName(self) -> java.lang.String: ...
def identity(self, int: int) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def invert(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
@typing.overload
def multiply(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def multiply(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def oneNorm(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def rank(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> int: ...
@typing.overload
def scale(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], double2: float) -> typing.MutableSequence[float]: ...
@typing.overload
def scale(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], double2: float) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def solve(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
def solveLeastSquares(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
def spectralNorm(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> float: ...
def submatrix(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], int: int, int2: int, int3: int, int4: int) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
@typing.overload
def subtract(self, doubleArray: typing.Union[typing.List[float], jpype.JArray], doubleArray2: typing.Union[typing.List[float], jpype.JArray]) -> typing.MutableSequence[float]: ...
@typing.overload
def subtract(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def transpose(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...
def withSubmatrix(self, doubleArray: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray], int: int, int2: int, doubleArray2: typing.Union[typing.List[typing.MutableSequence[float]], jpype.JArray]) -> typing.MutableSequence[typing.MutableSequence[float]]: ...


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

EjmlLinearAlgebra: typing.Type[EjmlLinearAlgebra]
JamaLinearAlgebra: typing.Type[JamaLinearAlgebra]
LinearAlgebraException: typing.Type[LinearAlgebraException]
LinearAlgebraOperations: typing.Type[LinearAlgebraOperations]
16 changes: 16 additions & 0 deletions src/jneqsim-stubs/mcp/runners/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ class BioprocessRunner:
@staticmethod
def run(string: typing.Union[java.lang.String, str]) -> java.lang.String: ...

class CapabilitiesRunner:
@staticmethod
def getCapabilities() -> java.lang.String: ...
@staticmethod
def getSetupTemplate(string: typing.Union[java.lang.String, str]) -> java.lang.String: ...
@staticmethod
def getSetupTemplates() -> java.lang.String: ...

class ChemistryRunner:
@staticmethod
def getSupportedAnalyses() -> java.util.List[java.lang.String]: ...
Expand Down Expand Up @@ -126,6 +134,12 @@ class DynamicRunner:
@staticmethod
def run(string: typing.Union[java.lang.String, str]) -> java.lang.String: ...

class EngineeringCoverageCatalog:
@staticmethod
def query(jsonObject: com.google.gson.JsonObject) -> com.google.gson.JsonObject: ...
@staticmethod
def summary() -> com.google.gson.JsonObject: ...

class EngineeringValidator:
@staticmethod
def validate(string: typing.Union[java.lang.String, str], string2: typing.Union[java.lang.String, str]) -> java.lang.String: ...
Expand Down Expand Up @@ -548,12 +562,14 @@ class __module_protocol__(Protocol):
BatchRunner: typing.Type[BatchRunner]
BenchmarkTrust: typing.Type[BenchmarkTrust]
BioprocessRunner: typing.Type[BioprocessRunner]
CapabilitiesRunner: typing.Type[CapabilitiesRunner]
ChemistryRunner: typing.Type[ChemistryRunner]
ComponentQuery: typing.Type[ComponentQuery]
CompositionRunner: typing.Type[CompositionRunner]
CrossValidationRunner: typing.Type[CrossValidationRunner]
DataCatalogRunner: typing.Type[DataCatalogRunner]
DynamicRunner: typing.Type[DynamicRunner]
EngineeringCoverageCatalog: typing.Type[EngineeringCoverageCatalog]
EngineeringValidator: typing.Type[EngineeringValidator]
EquipmentSizingRunner: typing.Type[EquipmentSizingRunner]
FieldDevelopmentRunner: typing.Type[FieldDevelopmentRunner]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ if sys.version_info >= (3, 8):
else:
from typing_extensions import Protocol

import java.io
import java.lang
import jneqsim.thermo
import jneqsim.thermo.system
import typing



class AdsorptionInterface(jneqsim.thermo.ThermodynamicConstantsInterface, java.io.Serializable):
class AdsorptionInterface(jneqsim.thermo.ThermodynamicConstantsInterface):
def calcAdsorption(self, int: int) -> None: ...
def getIsothermType(self) -> 'IsothermType': ...
@typing.overload
Expand All @@ -24,7 +23,7 @@ class AdsorptionInterface(jneqsim.thermo.ThermodynamicConstantsInterface, java.i
def isCalculated(self) -> bool: ...
def setSolidMaterial(self, string: typing.Union[java.lang.String, str]) -> None: ...

class CapillaryCondensationModel(java.io.Serializable, jneqsim.thermo.ThermodynamicConstantsInterface):
class CapillaryCondensationModel(jneqsim.thermo.ThermodynamicConstantsInterface):
KELVIN_VALIDITY_RADIUS_NM: typing.ClassVar[float] = ...
@typing.overload
def __init__(self): ...
Expand Down Expand Up @@ -152,7 +151,7 @@ class IsothermType(java.lang.Enum['IsothermType']):
@staticmethod
def values() -> typing.MutableSequence['IsothermType']: ...

class AbstractAdsorptionModel(AdsorptionInterface, java.io.Serializable):
class AbstractAdsorptionModel(AdsorptionInterface):
@typing.overload
def __init__(self): ...
@typing.overload
Expand Down
Loading
Loading