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 :doc:`09_local_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 :doc:`09_local_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 -------- - :doc:`09_local_simulation` - Detailed parameter documentation - :doc:`user_guide/physics` - Physical models and validation - :doc:`api/visualization` - Visualization module API reference