Pages

Saturday, August 26, 2023

Head's Up

Recently, I saw my father-in-law Scott pour a bottle of beer into a glass, and I was fascinated by the relationship between the rising beer at the bottom, and the foam moving on top. I was curious if I could model the dynamics involved, so I decided to check if anyone else has tackled the problem. I found an article from a brewer discussing some of the steps involved, and I decided to split the process into 4 parts:

  1. For each bubble in the foam, apply forces from neighboring bubbles, and gravity pulling down.
  2. Drain liquid from higher to lower bubbles, based on the content of each. Bubbles at the bottom drain into the liquid beer.
  3. If neighboring bubbles each have low liquid content, merge them into a single larger bubble.
  4. Bubbles with low liquid and/or large size pop, adding their liquid to the beer at the bottom.
To represent these bubbles, we need to use sphere-packing to figure out how they fit in the glass. I've talked about the concept before, but since we're making a simulation this time, I found the package spack for Python. This handles keeping track of where the bubbles are, and can draw them for us. It also calculates the forces between the bubbles, based on their separation and radii.

To apply these forces, we need the mass of the bubbles – They're made of gas and liquid, but the liquid mass will far outweigh the gas. We're already keeping track of liquid content for the other steps, so we can use that for the mass and then displace each bubble based on the total force divided by its mass.

The spack package keeps track of which bubbles are adjacent – For each pair, we can drain liquid from the upper to the lower. The proportion I settled on was that at each step the lower bubble would get 51% of the total moisture, and the top one would be left with 49%. For bubbles with nothing below them, they drain the full amount to the liquid at the bottom. Similarly, we can use the adjacent list to pick bubbles to merge – Based on the article I linked above, I decided their circumferences would add, rather than areas. We select which bubbles merge based on their liquid content – Dryer bubbles merge more easily. Big, dry bubbles can also pop, giving up their liquid to the beer at the bottom.

We start off the simulation by filling the glass with a bunch of small bubbles, then let the rules outlined take over. I ended up using 1000 bubbles to start with, which takes a bit of time to get through, but I'm impressed with the results:

We can also measure some averages over the course of the simulation. First, we can simply count the number of bubbles:

The rate is fairly constant, despite the various dynamics going into determining the merging/popping. We can also look at the average size of bubbles:

I was a bit surprised by the sudden rise in the average size at the end, but I think it may be related to the merging of the bubbles: They get larger and fewer, resulting in a compounded effect on the average, and near the end, we have far fewer bubbles, making the average more sensitive to change. The average liquid content has a similar knee at the later times:

I have no idea how accurate this model is, but it does seem to follow the events outlined in the article: Bubbles merge, dry out, and pop, resulting in a shrinking head of foam, and growing reservoir of liquid at the bottom. Clearly I need to gather more data – Cheers!

1 comment: