I built a tiny wind tunnel in Go

go dev.to

I built Kutta, a small 2D wind tunnel for aeromodelers, game developers, and anyone who enjoys watching air misbehave.

It is written in Go, uses Ebitengine for rendering, and runs as a single desktop application.

The project is open source:

https://github.com/crgimenes/kutta

The idea

Kutta started as a simple visual experiment: stream air past an airfoil and make the flow visible.

Not as a replacement for real CFD software. Not as an engineering tool for designing aircraft. The goal is more modest and, in my opinion, more useful for experimentation:

Give immediate visual intuition about what happens around an airfoil.

You can change the angle of attack and watch the flow field react. You can see the wake. You can toggle different visualization modes. You can draw your own shapes. You can split a wing into a wing and a flap, animate the control surface, and see the wake become unstable when the geometry or angle gets too aggressive.

It is a toy in the best possible sense: simple enough to play with, but grounded enough to teach something.

What it shows

Kutta visualizes several aspects of the flow:

  • speed field;
  • vorticity;
  • pressure-like scalar field;
  • smoke streaklines;
  • lift and drag vectors;
  • wake behavior;
  • separation when the angle of attack becomes too high.

It also includes NACA 4-digit and 5-digit airfoil generation, so you can type a profile such as 2412, 0012, or 23012 and get the corresponding shape without loading anything from disk.

And yes, there is also a neko airfoil.

It is terrible.

That is the point.

Qualitative, not validated CFD

This part is important.

Kutta is not a validated CFD tool.

It uses lattice units instead of physical units. It can show useful flow behavior such as stagnation, wake formation, suction over the upper side of the airfoil, and separation as the angle grows, but the numeric values should not be treated as engineering data.

Use it for:

  • intuition;
  • teaching;
  • visual experiments;
  • aeromodeling curiosity;
  • game/tool inspiration;
  • pretty projector demos.

Do not use it to size a real aircraft wing.

That boundary is intentional. I prefer tools that are honest about what they are.

How it works internally

The solver uses a 2D Lattice-Boltzmann method: D2Q9 with BGK collision.

The channel has a free stream coming from the left. The body is represented as a no-slip wall using half-way bounce-back. Forces are estimated from pressure integration over the body faces.

That means Kutta can capture form drag and lift behavior, but it does not model everything. For example, skin friction is ignored, so drag is understated. That is a known limitation, not a hidden bug.

The project is split into a few internal packages:

  • lbm: the flow solver;
  • foil: NACA airfoil generation;
  • scene and sceneio: editable multi-object scenes;
  • viz: color maps and smoke tracer particles;
  • the app layer: Ebitengine loop, editor, input, menus, and rendering.

The lower-level packages do not depend on rendering and can be tested headlessly. There is also a snapshot tool that renders fields to PNG, which is useful for sanity-checking behavior without opening a window.

The editor

Kutta includes a simple shape editor.

You can draw a closed shape, move vertices, and use Bézier handles to curve edges. You can also cut and rejoin shapes, which makes it possible to split an airfoil into separate parts.

That is how a wing can become a wing plus flap.

There is also a basic animation mode. You can scrub a timeline, add keyframes, and animate the pose of each part while the flow keeps running.

Scenes are saved as .afoil files. The format is small, textual, and based on s-expressions.

I like this kind of format because it is easy to inspect, diff, and keep in Git.

Why Go?

Go is not the first language people usually associate with simulations or visual creative tools.

That is one reason I like using it for this type of project.

For Kutta, Go gives me:

  • fast compilation;
  • simple cross-platform builds;
  • good standard tooling;
  • readable code;
  • easy packaging;
  • enough performance for this kind of real-time qualitative simulation.

Ebitengine handles the rendering and application loop. The result is a normal desktop app, not a large runtime environment or a complex toolchain.

For users, that means: download one executable and run it.

Why make it visual?

The original motivation was not only technical.

I wanted something that felt alive.

A static chart can explain lift. A formula can describe the idea. A textbook diagram can show separation. But watching a wake form behind a wing while you change the angle of attack gives a different kind of understanding.

It is less precise, but more immediate.

That matters for learning.

It also matters for open source visibility. A short video of Kutta running reached far more people than a traditional technical post would have. That reinforced something I already suspected:

Visual projects are much easier to explain at a glance.

People may not care about the solver at first. They care because it looks interesting. Then some of them become curious about how it works.

That is a good entry point.

Running it

There are prebuilt binaries for macOS, Windows, and Linux in the GitHub releases.

On macOS, it can also be installed with Homebrew:

brew install --cask crgimenes/tap/kutta
Enter fullscreen mode Exit fullscreen mode

To run from source:

go run .
Enter fullscreen mode Exit fullscreen mode

On Linux, Ebitengine needs the usual Cgo/OpenGL/audio development dependencies.

Controls

Some useful controls:

  • Up / Down: change angle of attack;
  • Tab: cycle NACA profile;
  • V: change visualization mode;
  • S: toggle streamlines;
  • G: toggle glow/bloom;
  • Space: pause/resume;
  • N: single step while paused;
  • R: reset the flow;
  • E: open the editor;
  • O: open an .afoil scene;
  • Cmd+S / Ctrl+S: save.

You can also type a NACA code directly in the field at the top.

What I learned

The main lesson was that a small, constrained simulation can still be valuable.

It does not need to solve the full real-world problem. It only needs to make one layer of the problem visible.

For Kutta, that layer is aerodynamic intuition.

It also reminded me that open source projects benefit from being demonstrable. A project that produces an interesting image, sound, animation, or interaction is much easier to share than a library that only makes sense after reading the API.

That does not make visual projects better, but it makes them easier to communicate.

Possible next steps

Some ideas I may explore:

  • better scene examples;
  • more airfoil presets;
  • improved editor workflow;
  • better force visualization;
  • exportable screenshots or short clips;

I want to keep the project small. The goal is not to turn it into a professional CFD package. The goal is to keep it useful, understandable, and fun.

Repository

Kutta is open source under the MIT license:

https://github.com/crgimenes/kutta

If you like small visual tools written in Go, take a look at the repository. A star helps me understand which experiments are worth maintaining.

Source: dev.to

arrow_back Back to Tutorials