# Powered Grounding and Allision

This chapter describes OMRAT’s calculations for powered grounding and allision – accidents involving ships that are under power but fail to navigate correctly. Two categories are modelled based on Hansen (2008).

## Overview

Powered accidents occur when a vessel has operational engines but the crew fails to take appropriate action. This can happen because of:

- Navigation errors

- Equipment malfunction

- Human factors (fatigue, distraction)

- Environmental conditions (poor visibility)

Unlike drifting accidents, powered accidents depend on the lateral traffic distribution relative to obstacles and the probability of course correction after an error.

Current implementation notes:

- Powered grounding uses effective depth bins (by depth contour)

    instead of recomputing geometry for every individual draught value.

- Progress is reported per obstacle-bin step, so long runs show

    meaningful status updates in the task manager.

Grounding pipeline: `compute/powered_model.py:28` – run_powered_grounding_model() | Allision pipeline: `compute/powered_model.py:178` – run_powered_allision_model() | Exponential decay: `compute/basic_equations.py:26` – powered_na()

## Category I: Direct Overlap

Category I covers ships whose natural course (based on their lateral position in the traffic distribution) takes them directly into an obstacle. These ships are sailing on a heading that overlaps with the obstacle, and will ground/collide unless they take evasive action.

### Equation (Hansen Eq. 4.15)

\[N_I = P_C \times Q \times \int_{z_{\min}}^{z_{\max}} f(z) \, dz\]

Where:

- \(P_C\) = causation factor (\(1.6 \times 10^{-4}\) for grounding)

- \(Q\) = traffic volume (ships/year)

- \(f(z)\) = lateral traffic distribution (PDF)

- \(z_{\min}, z_{\max}\) = lateral extent of the obstacle

- The integral represents the fraction of traffic whose course overlaps the obstacle

For a normal distribution, the integral evaluates to:

\[\int_{z_{\min}}^{z_{\max}} f(z) \, dz = \Phi\!\left(\frac{z_{\max} - \mu}{\sigma}\right) - \Phi\!\left(\frac{z_{\min} - \mu}{\sigma}\right)\]

Where \(\Phi\) is the standard normal CDF and \(\mu, \sigma\) are the mean and standard deviation of the lateral position distribution.

`compute/basic_equations.py:432` – get_powered_grounding_cat1()

Category I – direct overlap (compute/basic_equations.py)

        # Number of geometric collision candidates
        # N_G = (Q_fast/V_fast) × (Q_slow/V_slow) × V_ij × P_G × L_w

### Physical Interpretation

Category I accidents are “ships sailing into the obstacle”. Even though the ship has power, the crew may not be paying attention, may not see the obstacle (e.g., submerged reef), or may misjudge the ship’s position. The causation factor \(P_C = 1.6 \times 10^{-4}\) means that roughly 1 in 6,000 geometric encounter candidates results in an actual accident.

## Category II: Missed Turn at Bend

Category II covers ships that fail to change course at a waypoint/bend. The ship continues on its original heading instead of turning, and may collide with an obstacle that lies ahead on the original course.

The probability decreases exponentially with distance from the bend, because the crew has more opportunities to detect and correct the course error the further they travel.

### Equation (Hansen Eq. 4.16–4.17)

\[N_{II} = P_C \times Q \times f(z) \times \exp\!\left( -\frac{d}{a} \right)\]

Where:

- \(d\) = distance from the bend to the obstacle (metres)

- \(a = \lambda \times V\) = recovery distance (metres)

- \(\lambda\) = position check interval (minutes, converted to seconds)

- \(V\) = ship speed (m/s)

- \(f(z)\) = probability density at the lateral position where the original heading leads to the obstacle

`compute/basic_equations.py:470` – get_powered_grounding_cat2()

Category II – exponential decay (compute/basic_equations.py)

            Length ship type 2 (m)
        B1 : float
            Beam ship type 1 (m)
        B2 : float
            Beam ship type 2 (m)
        theta : float
            Crossing angle (radians)

        Returns
        -------
        float
            Geometric number of crossing collision candidates per year

### Recovery Distance

The recovery distance \(a\) represents the average distance a ship travels between position checks:

\[a = \lambda \times V = (\lambda_{\text{min}} \times 60) \times V\]

Where \(\lambda_{\text{min}}\) is the position check interval in minutes. A typical value is \(\lambda = 3\) minutes, meaning the navigator checks the ship’s position approximately every 3 minutes.

For a ship travelling at 10 knots (~5.1 m/s):

\[a = 3 \times 60 \times 5.1 \approx 920 \text{ m}\]

`compute/basic_equations.py:408` – get_recovery_distance()

### Exponential Decay

The term \(\exp(-d/a)\) represents the probability that the ship has not detected its course error before reaching the obstacle.

- At \(d = 0\) (obstacle at bend): \(\exp(0) = 1\) (no time to detect)

- At \(d = a\) (one check interval away): \(\exp(-1) \approx 0.37\)

- At \(d = 3a\) (three check intervals): \(\exp(-3) \approx 0.05\)

- At \(d = 5a\) (five check intervals): \(\exp(-5) \approx 0.007\)

This means obstacles close to bends are much more dangerous than obstacles far from bends, because the crew has less time to detect and correct the error.

### Physical Interpretation

Category II models the “missed turn” scenario. A ship approaching a waypoint should change course, but some fraction of ships (weighted by \(P_C\)) continue straight. The exponential decay represents the crew’s progressive awareness: at each position check interval, they have a chance to notice they are off course and correct.

## Shadow-Aware Ray Casting

The Category II equations above describe the probability for a single ray from the turning point to a single obstacle. In practice, the lateral traffic distribution means ships may be at any lateral offset when they miss the turn. OMRAT evaluates this by casting 500 rays across the full lateral distribution.

### The Algorithm

For each leg and direction (turning point + extension direction):

1. Sample the lateral distribution: Generate `N_RAYS = 500` equally spaced offsets from \(\mu - 4\sigma\) to \(\mu + 4\sigma\), where \(\mu\) and \(\sigma\) are the lateral distribution parameters.

2. Compute PDF weights: For each offset \(z_i\), evaluate the normal PDF and multiply by the spacing:

   \[m_i = f(z_i) \times \Delta z\]

   This gives the probability mass carried by each ray.

3. Cast each ray: From the turning point offset laterally by \(z_i\), cast a ray in the extension direction (the heading the ship would continue on after missing the turn). The ray extends up to 50 km.

4. First-hit logic: For each ray, find the closest obstacle it intersects. This is the key step – a ray can only hit one obstacle. If obstacle A is closer than obstacle B on a given ray, only A receives that ray’s mass.

5. Accumulate per obstacle: For each obstacle, collect:

   - mass = sum of \(m_i\) for all rays that hit it (first)

   - weighted distance = \(\sum m_i \times d_i\)

   - mean distance = weighted distance / mass

   - probability integral = \(\sum m_i \times \exp(-d_i / a)\)

6. Compute final probability: For each obstacle:

   \[P_{\text{obs}} = P_C \times Q \times \text{mass} \times \exp\!\left(-\frac{d_{\text{mean}}}{a}\right)\]

   Where \(a = \lambda \times V\) is the recovery distance.

### Performance Optimization (Depth-Bin Caching)

Powered grounding now groups ships by an effective depth bin:

1. Extract unique depth contour values from `depths`.

2. Map each ship draught to the deepest contour that is still shallower than or equal to that draught.

3. Run expensive shadow/ray computations once per bin, then reuse results for all ship classes mapped to that bin.

This avoids repeated ray-casting with identical obstacle sets and significantly reduces runtime on projects with many draught entries.

`compute/powered_model.py:85` – depth-bin grouping and caching in run_powered_grounding_model() | `compute/powered_model.py:114` – per-bin progress updates | `compute/powered_model.py:178` – ship draught -> cached bin mapping

`geometries/get_powered_overlap.py:205` – _compute_cat2_with_shadows()

### Shadow Effect

The first-hit logic naturally creates shadows. When a closer obstacle intercepts a set of rays, those rays never reach any obstacle behind it. The farther obstacle only receives rays that pass around the closer one.

    Lateral offset (z)
    |
    |  miss  miss  miss                 miss  miss
    |   .     .     .                     .     .
    |    .    .    .          SHADOW        .    .
    |     .   .   .    +---------+------+   .   .
    |   hit-A hit-A    | Obs A   | (blocked)|   .
    |     .   .   .    +---------+------+   .   .
    |    .    .    .          SHADOW        .    .
    |   .     .     .                     .     .
    |  hit-B hit-B hit-B               hit-B hit-B
    +---------------------------------------------------> distance

This approach differs from drifting risk, where shadows are created by geometric subtraction of corridor polygons. In the powered model, shadows emerge from the ray-casting itself – no explicit shadow geometry is needed.

Mass conservation: The sum of masses across all obstacles plus the “miss” mass (rays that hit nothing) equals 1.0 (within numerical precision). Each ray’s mass is assigned to exactly one obstacle or none, so there is no double-counting.

The waterfall visualisation (see Visualization below) shows how the lateral distribution loses mass at each obstacle in distance order.

## Draft Filtering for Grounding

For powered grounding, not all depth areas are hazardous. A depth area is only a grounding risk if the water is shallower than the ship’s draught:

\[\text{Hazard if:} \quad \text{depth} \leq T_{\text{ship}}\]

Where \(T_{\text{ship}}\) is the ship’s draught in metres.

Since different ship types have different draughts, the set of obstacles varies per ship type. A large tanker with \(T = 15\) m faces more grounding hazards than a small ferry with \(T = 4\) m.

To avoid running the expensive ray-casting computation once per ship type, OMRAT groups ships by unique draught values:

1. Collect all unique draughts from the traffic data

2. For each unique draught, filter depth areas to those \(\leq T\) and build the obstacle list

3. Run the shadow-aware ray casting once per draught bracket

4. When summing per-ship-type contributions, look up the pre-computed results for the closest matching draught bracket

For powered allision (hitting structures above water), draft filtering does not apply – all objects are obstacles regardless of ship draught.

`compute/powered_model.py:66` – draught grouping

## Computation Pipeline

The full powered risk computation is orchestrated by `powered_model.py`, which provides two methods: `run_powered_grounding_model()` and `run_powered_allision_model()`.

### Grounding Pipeline

    1. Build equirectangular projector from first segment
    2. Collect all unique draughts from traffic data
    3. For each unique draught:
       a. Filter depth areas to those <= draught
       b. Build projected obstacle list
       c. Run _run_all_computations():
          For each (leg, direction):
            - Determine turning point and extension direction
            - Cast 500 rays across lateral distribution
            - First-hit logic assigns each ray to nearest obstacle
            - Accumulate mass and mean distance per obstacle
    4. For each (leg, direction, LOA class, ship type):
       a. Get ship frequency Q, speed V, draught T, check interval ai
       b. Look up shadow results for closest draught bracket
       c. For each obstacle hit:
          total += Pc * Q * mass * exp(-d_mean / (ai * V))

### Allision Pipeline

The allision pipeline is simpler because no draft filtering is needed:

    1. Build equirectangular projector from first segment
    2. Build projected obstacle list (all objects, ignore depths)
    3. Run _run_all_computations() once for all obstacles
    4. For each (leg, direction, LOA class, ship type):
       a. Get ship frequency Q, speed V, check interval ai
       b. For each obstacle hit:
          total += Pc * Q * mass * exp(-d_mean / (ai * V))

### Per-Ship-Type Parameters

The final summation loops over every ship type in the traffic data. Key parameters that vary per ship type:

Parameter | Symbol | Effect
--- | --- | ---
Traffic frequency | \(Q\) (ships/year) | Linear scaling of risk
Ship speed | \(V\) (m/s) | Affects recovery distance \(a = \lambda \times V\)
Ship draught | \(T\) (m) | Determines which depths are hazards (grounding only)
Position check interval | \(\lambda\) (seconds) | Affects recovery distance; set per segment direction

Faster ships have a longer recovery distance, which means the exponential decay is gentler – obstacles far from the bend are relatively more dangerous for fast ships. Conversely, slow ships have a short recovery distance, so the exponential drops off quickly.

`compute/powered_model.py:28` – run_powered_grounding_model() | `compute/powered_model.py:178` – run_powered_allision_model()

## Visualization

OMRAT provides a three-panel interactive visualization for powered risk, implemented by `PoweredOverlapVisualizer`. The visualizer is embedded in the QGIS dialog and shows the shadow-aware ray-casting results.

### Overview Panel

The top panel shows the full geographic context:

- Route legs as coloured lines with start/end markers

- Distribution bands (semi-transparent) showing \(\pm 3\sigma\) around each direction’s lateral mean

- Depth areas in light blue (shallow, hazardous) and grey (deep, ignored)

- Objects (structures) in salmon

- Ray fans from each turning point, coloured by which obstacle the rays hit

- Clickable turning points – click to select a computation for the detail panels

### Detail Panel

The bottom-left panel shows a local-coordinate view for the selected turning point:

- X-axis: along-track distance from turning point

- Y-axis: lateral offset from centreline

- Lateral distribution drawn as a curve at \(x = 0\), coloured by which obstacle each ray hits

- Sample rays drawn from the turning point to each obstacle

- Shadow regions shown as hatched areas behind each obstacle

- Annotation boxes for each obstacle showing mass, mean distance, and probability

### Waterfall Panel

The bottom-right panel shows how the lateral distribution evolves as obstacles consume mass:

- Obstacles are shown left-to-right in distance order

- At each obstacle, the remaining distribution is drawn

- The consumed portion (rays hitting that obstacle) is highlighted

- After the last obstacle, the remaining (unconsumed) mass is shown

This visualization makes the shadow effect directly visible: when a nearby obstacle is wide, it consumes a large fraction of the distribution, leaving little mass for obstacles further away.

`geometries/get_powered_overlap.py:447` – PoweredOverlapVisualizer

## Combined Powered Risk

The total powered accident frequency for an obstacle is the sum of Category I and Category II contributions from all legs and ship types:

\[F_{\text{powered}} = \sum_{\text{legs}} \sum_{\text{dirs}} \sum_{\text{types}} (N_{I} + N_{II,k})\]

Where \(N_{II,k}\) includes the shadow-aware mass and exponential decay computed by the ray-casting algorithm. The summation runs over:

- All route legs (segments)

- Both travel directions per leg

- All ship types (LOA class x type category)

The `powered_model.py` module orchestrates this computation. The shadow-aware geometry (mass and mean distance per obstacle) is computed once per unique draught bracket, then reused across all ship types with that draught.

## Comparison with Drifting Risk

Aspect | Drifting Risk | Powered Risk
--- | --- | ---
Ship status | Engine failure (blackout) | Under power
Causation factor | 1.0 (no avoidance possible) | \(1.6 \times 10^{-4}\) (avoidance likely)
Direction | Wind/current driven (8 dirs) | Along ship’s heading
Key parameter | Repair time, wind rose | Lateral distribution, bend distance
Spatial model | Drift corridors | Distribution overlap / exp decay
Typical magnitude | Higher per-event | Lower per-event, but more frequent

In practice, powered risks often dominate for obstacles near route centrelines, while drifting risks dominate for obstacles that are off to the side of routes.

## Causation Factor Summary

Accident Type | Default \(P_C\) | Source
--- | --- | ---
Powered grounding | \(1.6 \times 10^{-4}\) | IALA / Fujii
Powered allision | \(1.9 \times 10^{-4}\) | Fujii et al. 1974
Drifting (all types) | \(1.0\) | N/A (powerless)