diff --git a/.github/RELEASE_TEMPLATE.md b/.github/RELEASE_TEMPLATE.md index b83c9b3..866e2c0 100644 --- a/.github/RELEASE_TEMPLATE.md +++ b/.github/RELEASE_TEMPLATE.md @@ -25,7 +25,7 @@ conda install -c conda-forge neqsim= Requirements: - Python 3.9 or newer. -- Java 8 or newer for pip installs. +- Java 11 or newer for pip installs. - Conda installs include OpenJDK through conda-forge. Verify the installed package version without starting the JVM: diff --git a/.github/workflows/generate-stubs.yml b/.github/workflows/generate-stubs.yml index d3e6131..a62515f 100644 --- a/.github/workflows/generate-stubs.yml +++ b/.github/workflows/generate-stubs.yml @@ -4,7 +4,7 @@ on: # Run when JAR files are updated push: paths: - - 'src/neqsim/lib/**/*.jar' + - 'src/neqsim/lib/*.jar' # Run on release release: types: [published] @@ -16,18 +16,18 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: '3.11' + python-version: '3.13' - name: Set up Java - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: 'temurin' - java-version: '17' + java-version: '21' - name: Install dependencies run: | @@ -39,7 +39,7 @@ jobs: poetry run python scripts/generate_stubs.py - name: Commit updated stubs - uses: stefanzweifel/git-auto-commit-action@v5 + uses: stefanzweifel/git-auto-commit-action@v7 with: commit_message: "chore: regenerate Java stubs" file_pattern: "src/jneqsim-stubs/**" diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 5b3843a..afaf36d 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -10,10 +10,10 @@ jobs: main: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v6 with: - python-version: "3.12" + python-version: "3.13" - uses: pre-commit/action@v3.0.1 - uses: pre-commit-ci/lite-action@v1.1.0 if: always() diff --git a/.github/workflows/publish-to-test-pypi.yml b/.github/workflows/publish-to-test-pypi.yml index fd0c21b..cfdc3ae 100644 --- a/.github/workflows/publish-to-test-pypi.yml +++ b/.github/workflows/publish-to-test-pypi.yml @@ -14,15 +14,15 @@ jobs: id-token: write contents: read steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Install poetry run: pipx install poetry - name: Setup python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: - python-version: 3.11 + python-version: 3.13 - name: Install dependencies run: poetry install --no-interaction diff --git a/.github/workflows/runtests.yml b/.github/workflows/runtests.yml index 3f113c2..3001454 100644 --- a/.github/workflows/runtests.yml +++ b/.github/workflows/runtests.yml @@ -14,13 +14,13 @@ jobs: version: [3.9, 3.12, 3.13] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v7 - name: Install poetry run: pipx install poetry - name: Setup Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.version }} diff --git a/README.md b/README.md index 823a75d..c08f089 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ It provides Python toolboxes such as [thermoTools](https://github.com/equinor/ne ### Install - +
pip (requires Java 8+)conda (Java included)
pip (requires Java 11+)conda (Java included)
@@ -65,7 +65,7 @@ conda install -c conda-forge neqsim
-> **Prerequisites:** Python 3.9+ and Java 8+. The conda package automatically installs OpenJDK — no separate Java setup needed. For pip, install Java from [Adoptium](https://adoptium.net/). +> **Prerequisites:** Python 3.9+ and Java 11+. The conda package automatically installs OpenJDK — no separate Java setup needed. For pip, install Java from [Adoptium](https://adoptium.net/). ### Try it now diff --git a/docs/release-notes/v3.10.0.md b/docs/release-notes/v3.10.0.md index 4b69c70..9c8d252 100644 --- a/docs/release-notes/v3.10.0.md +++ b/docs/release-notes/v3.10.0.md @@ -57,4 +57,4 @@ printFrame(natural_gas) - Documentation: https://equinor.github.io/neqsimhome/ - Python examples: https://github.com/equinor/neqsim-python/tree/master/examples - Java engine: https://github.com/equinor/neqsim -- Discussions: https://github.com/equinor/neqsim/discussions \ No newline at end of file +- Discussions: https://github.com/equinor/neqsim/discussions diff --git a/docs/release-notes/v3.11.0.md b/docs/release-notes/v3.11.0.md index 24f36e8..fd6d8ed 100644 --- a/docs/release-notes/v3.11.0.md +++ b/docs/release-notes/v3.11.0.md @@ -57,4 +57,4 @@ printFrame(natural_gas) - Documentation: https://equinor.github.io/neqsimhome/ - Python examples: https://github.com/equinor/neqsim-python/tree/master/examples - Java engine: https://github.com/equinor/neqsim -- Discussions: https://github.com/equinor/neqsim/discussions \ No newline at end of file +- Discussions: https://github.com/equinor/neqsim/discussions diff --git a/examples/equationOfState.py b/examples/equationOfState.py index b814dfe..6518632 100644 --- a/examples/equationOfState.py +++ b/examples/equationOfState.py @@ -212,7 +212,8 @@ def create_wet_gas(eos_name): # ============================================================================= print("\n6. EOS-CG FOR CO2 AND COMBUSTION GASES") print("-" * 40) -print(""" +print( + """ EOS-CG (Equation of State for Combustion Gases) is based on GERG-2008 but optimized for CO2-rich mixtures and combustion product gases. @@ -224,7 +225,8 @@ def create_wet_gas(eos_name): - Blue/green hydrogen with CO2 Components: CO2, N2, O2, Ar, H2O, CO, H2, H2S, SO2, CH4 -""") +""" +) # Create a typical flue gas / CCS mixture print("Example: CO2-rich CCS mixture") @@ -261,7 +263,8 @@ def create_wet_gas(eos_name): # ============================================================================= print("\n7. GUIDELINES FOR EoS SELECTION") print("-" * 40) -print(""" +print( + """ Application | Recommended EoS -------------------------------------|---------------------- Natural gas properties | GERG-2008 (most accurate) @@ -286,5 +289,6 @@ def create_wet_gas(eos_name): Gas hydrates | CPA with hydrate model | Electrolyte solutions (brine) | Electrolyte-CPA -""") +""" +) print("=" * 70) diff --git a/examples/flashCalculations.py b/examples/flashCalculations.py index 8295ed3..02f9b80 100644 --- a/examples/flashCalculations.py +++ b/examples/flashCalculations.py @@ -189,7 +189,8 @@ print("\n" + "=" * 70) print("FLASH CALCULATION SUMMARY") print("=" * 70) -print(""" +print( + """ Flash Type | Given | Find | Application -----------|----------------|----------------|--------------------------- TPflash | T, P | Phases, comp. | General equilibrium @@ -198,5 +199,6 @@ TVflash | T, V | P, phases | Closed vessels VHflash | V, H | T, P, phases | Adiabatic closed systems VUflash | V, U | T, P, phases | Isolated systems -""") +""" +) print("=" * 70) diff --git a/examples/fluidCreation.py b/examples/fluidCreation.py index e42f7f7..0b786a1 100644 --- a/examples/fluidCreation.py +++ b/examples/fluidCreation.py @@ -272,7 +272,8 @@ # ============================================================================= print("\n9. COMMONLY USED COMPONENTS") print("-" * 40) -print(""" +print( + """ Category | Component Names -------------------|------------------------------------------------ Light gases | nitrogen, oxygen, argon, helium, hydrogen, H2S @@ -287,7 +288,8 @@ Note: For components not in database, use addTBPfraction() or addPlusFraction() with MW and density. -""") +""" +) # ============================================================================= # 10. ELECTROLYTE FLUIDS diff --git a/examples/hydrateCalculations.py b/examples/hydrateCalculations.py index 35e5097..8b05cac 100644 --- a/examples/hydrateCalculations.py +++ b/examples/hydrateCalculations.py @@ -31,7 +31,8 @@ # ============================================================================= print("\n1. INTRODUCTION TO GAS HYDRATES") print("-" * 40) -print(""" +print( + """ Gas hydrates form when water and light gases (C1, C2, C3, CO2, H2S) combine under high pressure and low temperature conditions. @@ -43,7 +44,8 @@ - Temperature: Typically < 25°C - Pressure: Typically > 10-20 bara - Presence of free water -""") +""" +) # ============================================================================= # 2. HYDRATE FORMATION TEMPERATURE @@ -114,14 +116,16 @@ # ============================================================================= print("\n4. SUBCOOLING - HYDRATE RISK ASSESSMENT") print("-" * 40) -print(""" +print( + """ Subcooling (ΔT) = Hydrate formation T - Operating T Interpretation: ΔT > 0: Operating BELOW hydrate T → HIGH RISK ΔT = 0: At hydrate equilibrium → BORDERLINE ΔT < 0: Operating ABOVE hydrate T → SAFE -""") +""" +) # Example calculation gas.setPressure(100.0, "bara") @@ -224,7 +228,8 @@ # ============================================================================= print("\n7. INHIBITOR SELECTION GUIDELINES") print("-" * 40) -print(""" +print( + """ ┌─────────────────────────────────────────────────────────────────┐ │ Inhibitor Comparison │ ├────────────┬──────────────────────────────────────────────────┐ @@ -251,14 +256,16 @@ │ │ ✗ Cannot be regenerated │ │ │ → Best for: Drilling fluids, completion ops │ └────────────┴──────────────────────────────────────────────────┘ -""") +""" +) # ============================================================================= # 8. KINETIC HYDRATE INHIBITORS (KHI) # ============================================================================= print("\n8. KINETIC HYDRATE INHIBITORS (KHI)") print("-" * 40) -print(""" +print( + """ Unlike thermodynamic inhibitors (MEG, MeOH) that shift equilibrium, KHIs work by slowing hydrate formation kinetics. @@ -273,7 +280,8 @@ Note: NeqSim primarily calculates thermodynamic equilibrium. KHI effects require separate kinetic models. -""") +""" +) # ============================================================================= # 9. PRACTICAL EXAMPLE: PIPELINE HYDRATE ASSESSMENT @@ -281,14 +289,16 @@ print("\n9. PRACTICAL EXAMPLE: PIPELINE HYDRATE ASSESSMENT") print("-" * 40) -print(""" +print( + """ Scenario: Subsea pipeline from wellhead to platform - Wellhead: 150 bara, 80°C - Pipeline arrival: 80 bara, 5°C - Gas is water-saturated Question: Will hydrates form? How much MEG is needed? -""") +""" +) # Check hydrate risk pipeline_gas = fluid("cpa") diff --git a/examples/mineralScalePrediction.py b/examples/mineralScalePrediction.py index b4b29bc..52a511a 100644 --- a/examples/mineralScalePrediction.py +++ b/examples/mineralScalePrediction.py @@ -32,7 +32,8 @@ # ============================================================================= print("\n1. INTRODUCTION TO MINERAL SCALE") print("-" * 40) -print(""" +print( + """ Mineral scale forms when dissolved ions precipitate as solid deposits: Type | Formula | Common Causes @@ -48,14 +49,16 @@ - Equipment damage - Increased operating costs - Production loss -""") +""" +) # ============================================================================= # 2. SATURATION INDEX CONCEPT # ============================================================================= print("\n2. SATURATION INDEX (SI)") print("-" * 40) -print(""" +print( + """ SI = log(IAP / Ksp) Where: @@ -66,7 +69,8 @@ SI > 0: Supersaturated → Scale WILL form SI = 0: At equilibrium → Borderline SI < 0: Undersaturated → Scale will NOT form -""") +""" +) # ============================================================================= # 3. CREATING FORMATION WATER @@ -120,10 +124,12 @@ print(" SO4--: 0.028 mol (2.7 g/L) ← HIGH!") print(" HCO3-: 0.002 mol (122 mg/L)") -print(""" +print( + """ ⚠️ WARNING: Mixing formation water (high Ba++) with seawater (high SO4--) causes severe BaSO4 scale! -""") +""" +) # ============================================================================= # 5. SCALE POTENTIAL CALCULATION @@ -162,7 +168,8 @@ # ============================================================================= print("\n6. EFFECT OF PRESSURE DROP ON CaCO3 SCALE") print("-" * 40) -print(""" +print( + """ CaCO3 (calcite) precipitation is driven by CO2 loss: Ca++ + 2HCO3- ⇌ CaCO3↓ + H2O + CO2↑ @@ -177,7 +184,8 @@ - Wellhead chokes - First stage separator - ESPs (Electrical Submersible Pumps) -""") +""" +) print("\nPressure | Expected CaCO3 Scaling Tendency") print("---------|----------------------------------") @@ -191,7 +199,8 @@ # ============================================================================= print("\n7. BaSO4 SCALE FROM WATER MIXING") print("-" * 40) -print(""" +print( + """ Barite (BaSO4) is one of the hardest scales to remove: Ba++ (formation water) + SO4-- (seawater) → BaSO4↓ @@ -206,7 +215,8 @@ - Low-sulfate seawater injection - Scale inhibitor squeeze treatments - Careful mixing ratio control -""") +""" +) # Simulate mixing at different ratios print("\nMixing formation water with seawater:") @@ -228,7 +238,8 @@ # ============================================================================= print("\n8. SCALE INHIBITORS") print("-" * 40) -print(""" +print( + """ Scale inhibitors prevent crystal growth even when supersaturated: Type | Target Scales @@ -244,14 +255,16 @@ 3. Batch treatment (periodic) Typical dosages: 5-50 ppm based on water volume -""") +""" +) # ============================================================================= # 9. PRACTICAL SCALE ASSESSMENT WORKFLOW # ============================================================================= print("\n9. PRACTICAL SCALE ASSESSMENT WORKFLOW") print("-" * 40) -print(""" +print( + """ Step 1: Water Analysis └─ Measure: Na, K, Ca, Mg, Ba, Sr, Fe, Cl, SO4, HCO3, CO2 @@ -275,14 +288,16 @@ └─ Inhibitor selection and dosage └─ Operating condition optimization └─ Monitoring and intervention plan -""") +""" +) # ============================================================================= # 10. TEMPERATURE EFFECTS SUMMARY # ============================================================================= print("\n10. TEMPERATURE EFFECTS ON SCALE") print("-" * 40) -print(""" +print( + """ Scale Type | Solubility vs Temperature --------------|-------------------------------- CaCO3 | Decreases with increasing T @@ -301,6 +316,7 @@ | SiO2 | Increases significantly with T (Silica) | (Normal solubility) -""") +""" +) print("=" * 70) diff --git a/examples/phaseEquilibrium.py b/examples/phaseEquilibrium.py index 93abc09..18a77e6 100644 --- a/examples/phaseEquilibrium.py +++ b/examples/phaseEquilibrium.py @@ -144,13 +144,15 @@ # ============================================================================= print("\n4. RETROGRADE CONDENSATION") print("-" * 40) -print(""" +print( + """ Retrograde condensation is a unique phenomenon in gas condensate systems where REDUCING pressure causes MORE liquid to form (counterintuitive!). This occurs between the cricondentherm and critical point at pressures below the cricondenbar. It's important for gas condensate reservoirs. -""") +""" +) # Demonstrate retrograde behavior print("Demonstrating retrograde behavior with the rich gas:") @@ -218,7 +220,8 @@ # ============================================================================= print("\n6. CRICONDENBAR & CRICONDENTHERM SIGNIFICANCE") print("-" * 40) -print(""" +print( + """ ┌─────────────────────────────────────────────────────────────────┐ │ PHASE ENVELOPE │ │ │ @@ -240,6 +243,7 @@ │ ● Above cricondentherm: Heating cannot cause condensation │ │ ● Critical point: Liquid and gas become indistinguishable │ └─────────────────────────────────────────────────────────────────┘ -""") +""" +) print("=" * 70) diff --git a/examples/processApproaches.py b/examples/processApproaches.py index c16f5cc..5261a55 100644 --- a/examples/processApproaches.py +++ b/examples/processApproaches.py @@ -215,7 +215,8 @@ print("\n" + "=" * 70) print("CHOOSING AN APPROACH") print("=" * 70) -print(""" +print( + """ | Use Case | Recommended Approach | |---------------------------------|-------------------------------| | Learning / tutorials | Wrappers (global process) | @@ -227,4 +228,5 @@ | Clean declarative style | ProcessBuilder | | Mixing wrapper convenience | Hybrid (process= parameter) | with explicit control | | -""") +""" +) diff --git a/examples/processBuilderGUI.py b/examples/processBuilderGUI.py index 5117822..c261e0e 100644 --- a/examples/processBuilderGUI.py +++ b/examples/processBuilderGUI.py @@ -451,7 +451,8 @@ def run_process(): with st.sidebar: st.header("ℹ️ About") - st.markdown(""" + st.markdown( + """ **NeqSim Process Builder GUI** A visual tool for building and simulating @@ -472,7 +473,8 @@ def run_process(): - Valves - Heaters/Coolers - Pipes - """) + """ + ) st.divider() diff --git a/examples/pvtExperimentsAdvanced.py b/examples/pvtExperimentsAdvanced.py index e358b99..7e99aca 100644 --- a/examples/pvtExperimentsAdvanced.py +++ b/examples/pvtExperimentsAdvanced.py @@ -318,7 +318,8 @@ # ============================================================================= print("\n8. PVT EXPERIMENTS SUMMARY") print("-" * 40) -print(""" +print( + """ Experiment | Purpose --------------------|---------------------------------------------- CME | Oil compressibility, relative volume, GOR @@ -327,6 +328,7 @@ Separator Test | Optimize surface separation, stock tank oil Swelling Test | EOR potential with gas injection (CO2, HC gas) Viscosity Study | Flow assurance, production optimization -""") +""" +) print("=" * 70) diff --git a/examples/viscosityModels.py b/examples/viscosityModels.py index ff75eeb..8115c78 100644 --- a/examples/viscosityModels.py +++ b/examples/viscosityModels.py @@ -33,7 +33,8 @@ # ============================================================================= print("\n1. AVAILABLE VISCOSITY MODELS") print("-" * 40) -print(""" +print( + """ Model | Keyword | Best For -------------------|--------------------|--------------------------------- LBC | "LBC" | General oil, reservoir fluids @@ -44,7 +45,8 @@ The LBC model is based on corresponding states principle using critical properties. Friction Theory links viscosity to EoS pressure terms, providing thermodynamic consistency. -""") +""" +) # ============================================================================= # 2. BASIC VISCOSITY CALCULATION @@ -90,7 +92,8 @@ # ============================================================================= print("\n3. LBC MODEL (LOHRENZ-BRAY-CLARK)") print("-" * 40) -print(""" +print( + """ The LBC model calculates viscosity as: η = η* + η_dense / ξ_m @@ -112,7 +115,8 @@ a4 = 0.0093324 These parameters can be tuned to match laboratory viscosity data. -""") +""" +) # ============================================================================= # 4. TUNING LBC MODEL PARAMETERS @@ -167,7 +171,8 @@ print(f"Further adjusted (a2=0.10): {tuned_visc_2:.4f} cP") -print(""" +print( + """ LBC Tuning Guidelines: ---------------------- • a0 (index 0): Baseline offset - increase for higher overall viscosity @@ -175,14 +180,16 @@ • a2 (index 2): Quadratic term - significant for liquid viscosity • a3 (index 3): Cubic term - fine-tuning at high density • a4 (index 4): Quartic term - extreme density behavior -""") +""" +) # ============================================================================= # 5. FRICTION THEORY MODEL # ============================================================================= print("\n5. FRICTION THEORY MODEL") print("-" * 40) -print(""" +print( + """ Friction Theory (f-theory) links viscosity to EoS pressure terms: η = η0 + ηf @@ -198,7 +205,8 @@ ✓ Consistent with phase equilibrium calculations ✓ Better extrapolation behavior ✓ Works well for wide T/P ranges -""") +""" +) # ============================================================================= # 6. TUNING FRICTION THEORY - TBP CORRECTION FACTOR @@ -254,7 +262,8 @@ # Reset to default visc_model.setTBPviscosityCorrection(1.0) -print(""" +print( + """ Friction Theory Tuning Guidelines: ---------------------------------- • TBP Correction Factor: @@ -265,7 +274,8 @@ • Use when TBP fractions give incorrect viscosity predictions • Tune to match laboratory viscosity at one T/P condition • Model will extrapolate to other conditions -""") +""" +) # ============================================================================= # 7. ADVANCED: TUNING WITH EXPERIMENTAL DATA @@ -287,7 +297,8 @@ for pt in exp_data: print(f"{pt['T_C']:6} | {pt['P_bara']:8} | {pt['visc_cP']:.2f}") -print(""" +print( + """ Tuning Workflow: ---------------- 1. Create fluid with accurate composition @@ -302,7 +313,8 @@ For automatic optimization, use NeqSim's parameter fitting capabilities with the ViscosityFunction class in PVT simulation. -""") +""" +) # ============================================================================= # 8. MODEL COMPARISON AT DIFFERENT CONDITIONS @@ -357,7 +369,8 @@ # ============================================================================= print("\n9. HEAVY OIL CONSIDERATIONS") print("-" * 40) -print(""" +print( + """ For heavy oils (API < 20°, viscosity > 100 cP), consider: 1. Use PFCT-Heavy-Oil model: @@ -370,14 +383,16 @@ 4. Temperature sensitivity is critical - ensure accurate measurements 5. Consider using Pedersen corresponding states for very heavy systems -""") +""" +) # ============================================================================= # 10. SUMMARY # ============================================================================= print("\n10. SUMMARY: MODEL SELECTION GUIDELINES") print("-" * 40) -print(""" +print( + """ ┌────────────────────┬──────────────────────────────────────────┐ │ Oil Type │ Recommended Model & Notes │ ├────────────────────┼──────────────────────────────────────────┤ @@ -393,6 +408,7 @@ │ Extra-heavy │ Specialized correlations │ │ (API < 10°) │ May require custom viscosity data │ └────────────────────┴──────────────────────────────────────────┘ -""") +""" +) print("=" * 70) diff --git a/src/neqsim/lib/java8/neqsim-3.14.0-Java8.jar b/src/neqsim/lib/java8/neqsim-3.14.0-Java8.jar deleted file mode 100644 index f7d077a..0000000 Binary files a/src/neqsim/lib/java8/neqsim-3.14.0-Java8.jar and /dev/null differ diff --git a/src/neqsim/lib/java11/neqsim-3.14.0.jar b/src/neqsim/lib/neqsim-3.14.0.jar similarity index 100% rename from src/neqsim/lib/java11/neqsim-3.14.0.jar rename to src/neqsim/lib/neqsim-3.14.0.jar diff --git a/src/neqsim/neqsimpython.py b/src/neqsim/neqsimpython.py index b0a6600..632f1d5 100644 --- a/src/neqsim/neqsimpython.py +++ b/src/neqsim/neqsimpython.py @@ -45,15 +45,11 @@ def _get_jvm_error_message() -> str: except TypeError: jpype.startJVM("-Xrs", **start_kwargs) jvm_version = jpype.getJVMVersion()[0] - if jvm_version == 1 and jpype.getJVMVersion()[1] >= 8: - jpype.addClassPath("./lib/java8/*") - # elif jvm_version >= 21: - # jpype.addClassPath("./lib/java21/*") - elif jvm_version >= 11: - jpype.addClassPath("./lib/java11/*") + if jvm_version >= 11: + jpype.addClassPath("./lib/*") else: print( - "Your version of Java is not supported. Please upgrade to Java version 8 or higher." + "Your version of Java is not supported. Please upgrade to Java version 11 or higher." ) print("See: https://github.com/equinor/neqsim-python#prerequisites") except Exception as e: