Skip to content

Perfect Gas Pressure Example

This comprehensive example demonstrates a complete parametric study using the ideal gas law. We'll calculate pressure for various combinations of temperature, volume, and amount of gas.

The Ideal Gas Law

The ideal gas law relates pressure, volume, temperature, and amount of gas:

\[PV = nRT\]

Where:

  • P = Pressure (Pa)
  • V = Volume (m³)
  • n = Amount of substance (mol)
  • R = Gas constant = 8.314 J/(mol·K)
  • T = Temperature (K)

Project Structure

perfectgas/
├── input.txt           # Input template
├── calculate.sh        # Calculation script
└── run_study.py        # Python orchestration

Step 1: Input Template

Create input.txt with variables and formulas:

# input file for Perfect Gas Pressure, with variables n_mol, T_celsius, V_L
n_mol=$n_mol
T_kelvin=@($T_celsius + 273.15)

#@ def L_to_m3(L):
#@     return(L / 1000)
V_m3=@(L_to_m3($V_L))

Key features:

  • Variables: $n_mol, $T_celsius, $V_L
  • Formulas: Convert Celsius to Kelvin, Liters to m³
  • Functions: L_to_m3() for unit conversion

Step 2: Calculation Script

Create calculate.sh:

#!/bin/bash

# Read input file
source $1

# Simulate calculation time
sleep 1

# Calculate pressure using ideal gas law
# P = nRT/V where R = 8.314 J/(mol·K)
pressure=$(echo "scale=4; $n_mol * 8.314 * $T_kelvin / $V_m3" | bc)

# Write output
echo "pressure = $pressure" > output.txt
echo "Temperature: $T_celsius °C ($T_kelvin K)" >> output.txt
echo "Volume: $V_L L ($V_m3 m³)" >> output.txt
echo "Amount: $n_mol mol" >> output.txt

echo "Calculation complete"

Make executable:

chmod +x calculate.sh

Step 3: Run Parametric Study

Create run_study.py:

import fz
import pandas as pd
import matplotlib.pyplot as plt

# Define the model
model = {
    "varprefix": "$",
    "formulaprefix": "@",
    "delim": "()",
    "commentline": "#",
    "output": {
        "pressure": "grep 'pressure = ' output.txt | awk '{print $3}'"
    }
}

# Define parameter space
input_variables = {
    "n_mol": [1, 2, 3],              # 3 amounts
    "T_celsius": [0, 10, 20, 30, 40], # 5 temperatures
    "V_L": [1, 2, 5, 10]              # 4 volumes
}

# Total cases: 3 × 5 × 4 = 60

# Run parametric study
results = fz.fzr(
    "input.txt",
    input_variables,
    model,
    calculators="sh://bash calculate.sh",
    results_dir="results"
)

# Display summary
print(f"\nCompleted {len(results)} calculations")
print(f"\nResults summary:")
print(results.describe())

# Save results
results.to_csv("perfectgas_results.csv", index=False)
print(f"\nResults saved to perfectgas_results.csv")

Step 4: Execute

Run the study:

python run_study.py

Results Analysis

View Results

import pandas as pd

# Load results
results = pd.read_csv("perfectgas_results.csv")

# Show first few rows
print(results.head())

# Filter high pressure cases
high_pressure = results[results['pressure'] > 10000]
print(f"\nHigh pressure cases: {len(high_pressure)}")

Statistical Analysis

# Group by amount of gas
by_amount = results.groupby('n_mol').agg({
    'pressure': ['mean', 'std', 'min', 'max']
})
print("\nPressure statistics by amount:")
print(by_amount)

# Correlation analysis
print("\nCorrelation matrix:")
print(results[['n_mol', 'T_celsius', 'V_L', 'pressure']].corr())

Visualization

Pressure vs Temperature

import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(15, 5))

# Plot 1: Different volumes
ax = axes[0]
for volume in sorted(results['V_L'].unique()):
    for n in sorted(results['n_mol'].unique()):
        data = results[(results['V_L'] == volume) & (results['n_mol'] == n)]
        ax.plot(data['T_celsius'], data['pressure'],
                marker='o', label=f'n={n} mol, V={volume} L')

ax.set_xlabel('Temperature (°C)')
ax.set_ylabel('Pressure (Pa)')
ax.set_title('Ideal Gas: Pressure vs Temperature')
ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
ax.grid(True)

# Plot 2: 3D surface for fixed n=1
ax = axes[1]
from mpl_toolkits.mplot3d import Axes3D
ax = plt.subplot(122, projection='3d')

data_n1 = results[results['n_mol'] == 1]
ax.scatter(data_n1['T_celsius'], data_n1['V_L'], data_n1['pressure'],
           c=data_n1['pressure'], cmap='viridis')
ax.set_xlabel('Temperature (°C)')
ax.set_ylabel('Volume (L)')
ax.set_zlabel('Pressure (Pa)')
ax.set_title('Pressure Surface (n=1 mol)')

plt.tight_layout()
plt.savefig('perfectgas_analysis.png', dpi=150, bbox_inches='tight')
print("Visualization saved to perfectgas_analysis.png")

Heatmap

import seaborn as sns

# Create pivot table for n=1 mol
pivot_data = results[results['n_mol'] == 1].pivot(
    index='V_L', columns='T_celsius', values='pressure'
)

plt.figure(figsize=(10, 6))
sns.heatmap(pivot_data, annot=True, fmt='.0f', cmap='RdYlBu_r')
plt.title('Pressure Heatmap (n=1 mol)')
plt.xlabel('Temperature (°C)')
plt.ylabel('Volume (L)')
plt.savefig('perfectgas_heatmap.png', dpi=150, bbox_inches='tight')

Advanced: Parallel Execution

Run with 4 parallel workers:

results = fz.fzr(
    "input.txt",
    input_variables,
    model,
    calculators=[
        "sh://bash calculate.sh",
        "sh://bash calculate.sh",
        "sh://bash calculate.sh",
        "sh://bash calculate.sh"
    ],
    results_dir="results_parallel"
)

Advanced: Remote Execution

Run on an HPC cluster:

results = fz.fzr(
    "input.txt",
    input_variables,
    model,
    calculators="ssh://user@cluster.edu/bash /path/to/calculate.sh",
    results_dir="results_remote"
)

Advanced: Caching

Resume or extend a previous study:

# Extend to more cases
extended_variables = {
    "n_mol": [1, 2, 3, 4, 5],        # Added 4 and 5
    "T_celsius": [0, 10, 20, 30, 40],
    "V_L": [1, 2, 5, 10]
}

# Reuse previous results, only calculate new cases
results = fz.fzr(
    "input.txt",
    extended_variables,
    model,
    calculators=[
        "cache://results",           # Check cache first
        "sh://bash calculate.sh"     # Only run new cases
    ],
    results_dir="results_extended"
)

Google Colab Version

Try this example in Google Colab without any local installation:

Open In Colab

The notebook includes:

  • Automatic FZ installation
  • Complete working example
  • Interactive visualization
  • Downloadable results

Validation

Verify results against theoretical values:

import numpy as np

def ideal_gas_pressure(n, T_celsius, V_L):
    """Calculate pressure using ideal gas law"""
    R = 8.314  # J/(mol·K)
    T_kelvin = T_celsius + 273.15
    V_m3 = V_L / 1000
    return n * R * T_kelvin / V_m3

# Compare with simulation
for _, row in results.head().iterrows():
    expected = ideal_gas_pressure(row['n_mol'], row['T_celsius'], row['V_L'])
    actual = row['pressure']
    error = abs(expected - actual) / expected * 100
    print(f"n={row['n_mol']}, T={row['T_celsius']}, V={row['V_L']}: "
          f"Expected={expected:.2f}, Actual={actual:.2f}, Error={error:.3f}%")

Complete Working Example

Download all files:

Or clone the examples:

git clone https://github.com/Funz/fz.git
cd fz/examples/perfectgas
python run_study.py

Next Steps