Vector Field Aerodynamics: Simulating Wind Without CFD
CFD is the right tool for designing aircraft. For testing whether a robot arm disturbs a nearby sensor in a wind tunnel, it's 10,000x more compute than needed.
The Core Abstraction
Air velocity in
laminar flow approximates as the gradient of a scalar potential function. Precompute potential flow
solutions offline for canonical shapes (cylinder, flat plate, sphere) and store as lookup tables. At
runtime, superpose these fields. Superposition is exact for potential flow — it's linear.
Vector
Field Sampling
@dataclass
class VectorField:
origin: np.ndarray
spacing:
float
data: np.ndarray # (nx, ny, nz, 3)
def sample(self, point: np.ndarray) ->
np.ndarray:
local = (point - self.origin) / self.spacing
i, j, k =
np.floor(local).astype(int)
# trilinear interpolation over 8 surrounding cells
...
Wake Model
Velocity deficit decays as 1/r from obstacle
centerline:
deficit = speed * (radius / max(r, radius)) * exp(-axial / (8 *
radius))
result[i,j,k] -= deficit * flow_dir
ROS 2 Integration
Node subscribes to TF, superimposes wake fields at sensor query points, publishes perturbation vectors at 20Hz.
Results
vs Physical Tunnel
- Velocity magnitude: within 12% RMS
- Turbulence intensity: within 20% RMS
- Wake location: within 0.5 diameters
Runs at 20Hz on a Raspberry Pi 4. CFD for the same geometry: 45 minutes on a 16-core workstation.