Examples

This page provides practical examples of using sandlercubics for common thermodynamic calculations.

Basic Property Calculations

Example 1: Single State Point

Calculate properties of propane at 350 K and 2.0 MPa using Peng-Robinson:

from sandlercubics import PengRobinsonEOS

# Initialize EOS and set state
eos = PengRobinsonEOS(T=350, P=2.0).set_compound('propane')

# Display results
print(f"State conditions:")
print(f"  T = {eos.T} K")
print(f"  P = {eos.P} MPa")
print(f"\nCalculated properties:")
print(f"  Z    = {eos.Z:.4f}")
print(f"  v    = {eos.v.item():.6f} m³/mol")
print(f"  Hdep = {eos.Hdep:.2f} J/mol")
print(f"  Sdep = {eos.Sdep:.4f} J/(mol·K)")

Example 2: Comparing Equations of State

Compare different equations for the same state:

from sandlercubics.eos import VanDerWaalsEOS, PengRobinsonEOS, SoaveRedlichKwongEOS
from sandlerprops.properties import PropertiesDatabase

db = PropertiesDatabase()
ethane = db.get_compound('ethane')

# Same critical properties for all equations
T, P = 300, 5.0  # K, MPa
Tc, Pc, omega = ethane.Tc, ethane.Pc / 10, ethane.Omega

# Create EOS objects
equations = {
    'van der Waals': VanDerWaalsEOS(Tc, Pc, omega),
    'Peng-Robinson': PengRobinsonEOS(Tc, Pc, omega),
    'Soave-RK': SoaveRedlichKwongEOS(Tc, Pc, omega)
}

# Compare results
print(f"Ethane at T = {T} K, P = {P} MPa\n")
print(f"{'Equation':<20} {'Z':>10} {'v (m³/mol)':>15} {'Hdep (J/mol)':>15}")
print("-" * 65)

for name, eos in equations.items():
    eos.T = T
    eos.P = P
    print(f"{name:<20} {eos.Z:>10.4f} {eos.v.item():>15.6f} {eos.Hdep:>15.2f}")

Phase Behavior

Example 3: Vapor-Liquid Equilibrium

Identify phases in a two-phase region:

from sandlercubics.eos import PengRobinsonEOS
from sandlerprops.properties import PropertiesDatabase

db = PropertiesDatabase()
propane = db.get_compound('propane')

eos = PengRobinsonEOS(
    Tc=propane.Tc,
    Pc=propane.Pc / 10,
    omega=propane.Omega
)

# Subcritical conditions (two-phase possible)
eos.T = 300  # K (Tc of propane is ~370 K)
eos.P = 1.0  # MPa

# Check if we're in two-phase region
# You may need to implement phase checking based on your API
if hasattr(eos, 'phases'):
    for phase in eos.phases:
        print(f"{phase.name} phase:")
        print(f"  Z = {phase.Z:.4f}")
        print(f"  v = {phase.v:.6f} m³/mol")
        print(f"  Hdep = {phase.Hdep:.2f} J/mol")
        print()

Property Changes

Example 5: Isothermal Compression

Calculate work and property changes during isothermal compression:

import numpy as np
from sandlercubics.eos import PengRobinsonEOS
from sandlerprops.properties import PropertiesDatabase

db = PropertiesDatabase()
nitrogen = db.get_compound('nitrogen')

eos = PengRobinsonEOS(
    Tc=nitrogen.Tc,
    Pc=nitrogen.Pc / 10,
    omega=nitrogen.Omega
)

# Isothermal process
T = 300  # K (constant)
P_initial = 1.0  # MPa
P_final = 10.0  # MPa

# Initial state
eos.T = T
eos.P = P_initial
Z1, v1 = eos.Z, eos.v.item()
H1, S1 = eos.Hdep, eos.Sdep

# Final state
eos.P = P_final
Z2, v2 = eos.Z, eos.v.item()
H2, S2 = eos.Hdep, eos.Sdep

# Property changes (ideal gas contribution + departure function changes)
R = 8.314  # J/(mol·K)
Delta_H_dep = H2 - H1
Delta_S_dep = S2 - S1
Delta_S_ig = -R * np.log(P_final / P_initial)

print(f"Isothermal Compression of Nitrogen")
print(f"T = {T} K (constant)")
print(f"P: {P_initial}{P_final} MPa\n")
print(f"State Changes:")
print(f"  Z: {Z1:.4f}{Z2:.4f}")
print(f"  v: {v1:.6f}{v2:.6f} m³/mol\n")
print(f"Property Changes:")
print(f"  ΔH_dep = {Delta_H_dep:.2f} J/mol")
print(f"  ΔS_dep = {Delta_S_dep:.4f} J/(mol·K)")
print(f"  ΔS_ig  = {Delta_S_ig:.4f} J/(mol·K)")
print(f"  ΔS_total = {Delta_S_dep + Delta_S_ig:.4f} J/(mol·K)")

Example 6: Isobaric Heating

Calculate enthalpy change during constant pressure heating:

from sandlercubics.eos import PengRobinsonEOS
from sandlerprops.properties import PropertiesDatabase
import numpy as np

db = PropertiesDatabase()
methane = db.get_compound('methane')

eos = PengRobinsonEOS(
    Tc=methane.Tc,
    Pc=methane.Pc / 10,
    omega=methane.Omega
)

# Process conditions
P = 5.0  # MPa (constant)
T1, T2 = 300, 400  # K

# Heat capacity coefficients (from database or literature)
# Cp_ig = A + B*T + C*T^2 + D*T^3
CpA = 19.25  # J/(mol·K)
CpB = 5.213e-2  # J/(mol·K²)
CpC = 1.197e-5  # J/(mol·K³)
CpD = -1.132e-8  # J/(mol·K⁴)

# State 1
eos.T = T1
eos.P = P
Hdep1 = eos.Hdep

# State 2
eos.T = T2
eos.P = P
Hdep2 = eos.Hdep

# Ideal gas enthalpy change (integrate Cp)
def cp_integral(T):
    return CpA * T + CpB * T**2 / 2 + CpC * T**3 / 3 + CpD * T**4 / 4

Delta_H_ig = cp_integral(T2) - cp_integral(T1)
Delta_H_dep = Hdep2 - Hdep1
Delta_H_total = Delta_H_ig + Delta_H_dep

print(f"Isobaric Heating of Methane")
print(f"P = {P} MPa (constant)")
print(f"T: {T1}{T2} K\n")
print(f"Enthalpy Changes:")
print(f"  ΔH_ig  = {Delta_H_ig:.2f} J/mol")
print(f"  ΔH_dep = {Delta_H_dep:.2f} J/mol")
print(f"  ΔH_total = {Delta_H_total:.2f} J/mol")