config.yaml

# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (C) 2025 SWGY, Inc
#
# Default configuration for the blast-pressure simulation. Every parameter can
# be overridden on the command line with repeatable dotted flags, e.g.:
#
#   uv run simulate_blasts.py --config config.yaml \
#       --set blast.cube_segments=12 --set rays.resolution_arcmin=10

blast:
  cube_center_m: [0.0, -4.0, 0.0]   # centre of the sampled blast cube (x, y, z), metres
  cube_extents_m: 8.0               # side length of the cube, metres
  cube_segments: 10                 # samples per axis -> cube_segments**3 blast points
  min_dist_m: 0.7                   # blasts closer than this to the sensor are skipped

rays:
  resolution_arcmin: 20             # angular ray spacing (ray density), arc-minutes
  max_bounces: 4                    # max specular reflections to follow per ray
  max_length_m: 35.0                # max distance to trace a ray, metres
  fan_mode: sensor_cone             # sensor_cone (rays span the sensor disc only)
                                    # | geometry (widen the fan to the armor extents)

physics:
  initial_peak_pressure_kpa: 50000.0  # p0, peak overpressure at the blast, kPa
  positive_phase_duration_s: 0.01     # t_d, Friedlander positive phase duration
  decay_alpha: 1.0                    # Friedlander decay parameter
  reflection_loss: 0.8                # energy retained per specular bounce

sensor:
  diameter_m: 0.111                 # sensor sphere diameter; radius = diameter / 2

geometry:
  helmet: assets/MICH.obj
  vest: assets/SAPI.obj             # SAPI plate mesh; posed twice (front + back plates)

compute:
  device: cuda                      # cuda (GPU) | cpu (Warp CPU backend, for testing)
                                    # Warp mesh queries run float32; impulse sums float64.

output:
  file: null                        # null -> ./blast-results-<timestamp>.csv

diffraction:
  enabled: false                    # add first-order BTM edge diffraction
  edge_mode: rim_plane              # rim_plane | feature_edges | polyline
  rim_plane_normal: [0.0, 0.0, 1.0] # helmet is Z-up, so the rim is a constant-Z cut
  rim_plane_offset_m: -0.09         # plane offset along the normal, metres
  feature_angle_deg: 30.0           # dihedral threshold for feature_edges mode
  segment_length_m: 0.01            # edge discretisation, metres
  wedge_model: screen               # screen (nu=1/2) | dihedral (nu from faces)
  polyline_file: null               # authored rim polyline (edge_mode: polyline)