Production Ocean Wave Simulation

The run_production_simulation.py script is designed for large-scale, production-quality ray tracing simulations on ocean wave surfaces. It shares the same core features as the local simulation but is optimized for high ray counts and extended analysis.

Overview

This production script provides:

  • Scalable architecture - Handles millions of rays efficiently

  • Identical physics - Same wave models and ray tracing as local simulation

  • Complete output suite - All 8 visualization figures plus HDF5 data

  • Batch processing ready - Designed for automated parameter sweeps

  • Resource monitoring - Memory and timing information

Differences from Local Simulation

The production and local simulation scripts are nearly identical, with minor differences:

Similarities:
  • Same wave surface models (Gerstner waves)

  • Identical Fresnel reflection/refraction physics

  • Same recording sphere geometry

  • Identical visualization outputs

  • Same command-line interface

Key Differences:
  • Default: Still uses collimated beam (needs manual update for diverging option)

  • Optimized for large ray counts (100k - 10M rays)

  • May include additional logging/monitoring features

  • Designed for cluster/batch processing environments

Note

The production script does not yet include the --beam-type option. To use diverging beams, either modify the script or use run_local_simulation.py which has full beam type support.

Usage

High-resolution simulation with 1 million rays:

python run_production_simulation.py \
    --num-rays 1000000 \
    --grazing-angle 5 \
    --wave-amplitude 2.0 \
    --wave-wavelength 100

Parameter sweep example:

for angle in 5 10 15 20 30 45 60 75 85; do
    python run_production_simulation.py \
        --num-rays 500000 \
        --grazing-angle $angle \
        --wave-amplitude 2.0 \
        --tag "sweep_${angle}deg"
done

Command-Line Arguments

The production script accepts the same arguments as the local simulation. See Local Scale Ocean Wave Simulation for complete parameter documentation.

Key Parameters for Production:

--num-rays INT

Recommended: 100,000 - 10,000,000 for production runs

--tag STR

Essential for batch processing - tags output files for identification

Example:

python run_production_simulation.py \
    --num-rays 1000000 \
    --grazing-angle 10 \
    --wave-amplitude 1.5 \
    --wave-wavelength 75 \
    --tag "prod_run_001"

Output Files

Identical to local simulation, with filenames prefixed by local_simulation_. See Local Scale Ocean Wave Simulation for detailed output descriptions.

Performance Considerations

Memory Requirements

Approximate memory usage:

Ray Count

Memory (approx)

Recommended System

100,000

~100 MB

Any modern system

1,000,000

~1 GB

8 GB RAM minimum

10,000,000

~10 GB

32 GB RAM recommended

Runtime Scaling

Typical execution times on modern GPU (NVIDIA RTX/Tesla):

  • 100k rays: ~5-10 seconds

  • 1M rays: ~30-60 seconds

  • 10M rays: ~5-10 minutes

CPU-only execution is significantly slower (10-100x).

Optimization Tips

  1. Use GPU acceleration - Ensure CUDA-capable GPU and proper Numba installation

  2. Adjust recording altitude - Smaller spheres = less memory for storage

  3. Limit max bounces - Single bounce is usually sufficient for most analyses

  4. Profile first - Run small tests before large production batches

Batch Processing

Example PBS job script for cluster:

#!/bin/bash
#PBS -N ocean_raytrace
#PBS -l select=1:ncpus=4:ngpus=1:mem=16GB
#PBS -l walltime=01:00:00

cd $PBS_O_WORKDIR
module load cuda/11.8
module load python/3.10

source venv/bin/activate

python run_production_simulation.py \
    --num-rays 1000000 \
    --grazing-angle ${ANGLE} \
    --wave-amplitude ${AMP} \
    --tag "cluster_${PBS_JOBID}"

Example SLURM script:

#!/bin/bash
#SBATCH --job-name=ocean_raytrace
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --gres=gpu:1
#SBATCH --mem=16G
#SBATCH --time=01:00:00

module load cuda python
source venv/bin/activate

python run_production_simulation.py \
    --num-rays 1000000 \
    --grazing-angle $1 \
    --wave-amplitude $2 \
    --tag "slurm_${SLURM_JOB_ID}"

Data Analysis Workflow

Post-processing the HDF5 output files:

import h5py
import numpy as np
import matplotlib.pyplot as plt

# Load simulation results
with h5py.File('data/local_simulation_20260104_120000.h5', 'r') as f:
    recorded_rays = f['recorded_rays']
    positions = recorded_rays['positions'][:]
    directions = recorded_rays['directions'][:]
    times = recorded_rays['times'][:]
    intensities = recorded_rays['intensities'][:]

# Custom analysis
elevation = np.degrees(np.arcsin(directions[:, 2]))

# Plot custom histogram
plt.hist(elevation, bins=50, weights=intensities)
plt.xlabel('Elevation Angle (degrees)')
plt.ylabel('Intensity-weighted Count')
plt.savefig('custom_analysis.png')

Combining Multiple Runs

Merge results from parameter sweep:

import h5py
import numpy as np
import glob

results = {}
for filename in glob.glob('data/sweep_*.h5'):
    with h5py.File(filename, 'r') as f:
        # Extract grazing angle from metadata
        angle = f.attrs['grazing_angle']

        # Store key statistics
        recorded = f['recorded_rays']
        results[angle] = {
            'num_rays': len(recorded['intensities']),
            'total_intensity': np.sum(recorded['intensities'][:]),
            'time_range': (recorded['times'][:].min(),
                          recorded['times'][:].max()),
        }

# Analyze trends across parameters
angles = sorted(results.keys())
efficiencies = [results[a]['total_intensity'] for a in angles]

plt.plot(angles, efficiencies, 'o-')
plt.xlabel('Grazing Angle (degrees)')
plt.ylabel('Recording Efficiency')
plt.savefig('efficiency_vs_angle.png')

Common Production Scenarios

Scenario 1: Reflection Efficiency vs Grazing Angle

Study how reflection efficiency changes with incidence angle:

angles=(5 10 15 20 30 45 60 75 85)
for angle in "${angles[@]}"; do
    python run_production_simulation.py \
        --num-rays 500000 \
        --grazing-angle $angle \
        --wave-amplitude 1.0 \
        --wave-wavelength 50 \
        --tag "efficiency_${angle}deg"
done

Scenario 2: Wave Height Sensitivity

Examine impact of wave amplitude on scattering:

amplitudes=(0.5 1.0 1.5 2.0 2.5 3.0)
for amp in "${amplitudes[@]}"; do
    python run_production_simulation.py \
        --num-rays 500000 \
        --grazing-angle 10 \
        --wave-amplitude $amp \
        --wave-wavelength 50 \
        --tag "amplitude_${amp}m"
done

Scenario 3: Wavelength Dependence

Investigate ocean wavelength effects:

wavelengths=(20 50 100 200 500)
for wl in "${wavelengths[@]}"; do
    python run_production_simulation.py \
        --num-rays 500000 \
        --grazing-angle 10 \
        --wave-amplitude 2.0 \
        --wave-wavelength $wl \
        --tag "wavelength_${wl}m"
done

Troubleshooting

Out of Memory Errors

If simulation crashes with OOM:

  1. Reduce --num-rays

  2. Decrease --recording-altitude (smaller sphere)

  3. Set --max-bounces 1 (only single reflection)

  4. Close other GPU applications

Slow Performance

If simulation is unexpectedly slow:

  1. Verify GPU is being used: nvidia-smi during run

  2. Check CUDA installation: numba -s

  3. Update GPU drivers

  4. Ensure no thermal throttling

Missing Plots

If visualization fails but simulation completes:

  1. Check disk space for plot directory

  2. Verify matplotlib backend is available

  3. Review error messages in terminal

  4. Manually regenerate plots from HDF5 data

See Also

  • Local Scale Ocean Wave Simulation - Detailed parameter documentation

  • user_guide/physics - Physical models and validation

  • api/visualization - Visualization module API reference