how the homepage video was made
After deciding to use a fullscreen video as the landing for my homepage I had several design goals for the video in mind:
- it should be created from scratch and representative of science I work on
- it should be simple with strong visuals so the viewer is not distracted by trying to understand what is going on
- things should be changing at a fast enough rate to be interesting but slow enough to be relaxing (to me this feels like a timescale of 5-10 seconds)
- though it doesn’t have to perfectly loop, it should be in some sort of steady state so that it can loop and not be jarringly obvious
- it should be at least 30 seconds long
I settled on running a simulation of driven turbulence using the Athena++ code. Running the simulation is as easy as installing Athena++ and fftw, compiling with python configure.py --problem=turb --eos=isothermal -fftw
, and then running the binary with input file athinput.turb.
I used the following parameters to get the kind of turbulence that would meet my design goals:
<turbulence>
dedt = 1.0 # Energy injection rate (for driven) or Total energy (for decaying)
nlow = 2 # cut-off wavenumber at low-k
nhigh = 512 # cut-off wavenumber at high-k
expo = 2.0 # power-law exponent
tcorr = 0.1 # correlation time for OU process (both impulsive and continuous)
dtdrive = 0.1 # time interval between perturbation (impulsive)
f_shear = 0.5 # the ratio of the shear component
rseed = -1 # if non-negative, seed will be set by hand (slow PS generation)
<problem>
turb_flag = 3 # 1 for decaying, 2 (impulsive) or 3 (continuous) for driven turbulence
But most notably I set nlow = 2
and nhigh=512
to seed intermediate scale modes and turb_flag = 3
to drive the turbulence to a steady state. After putting the Athena++ outputs into the directory data/
, converting them to .png
was done with a simple python script:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import athena_read
from PIL import Image
for i in range(0,2000):
j = 800 + 3*i
# choose colormap
cmap = mpl.cm.get_cmap('OrRd')
# choose normalization
norm = mpl.colors.Normalize(0.3,2.0)
x,y,z,data = athena_read.vtk('data/Turb.block0.out2.'+str(j).zfill(5)+'.vtk')
# normalize data to interval [0,1]
normed_data = norm(data['dens'][0])[::-1,:]
# get rgb colors from normed, cmapped data
rgb = cmap(normed_data,bytes=True)[:,:,:3]
# create image
im = Image.fromarray(rgb)
im.save('pngs/turb.'+str(i)+'.png')
I wanted to start with simulation already in steady-state and save on webpage loading times by making the video 20 fps, hence starting at file 800 only reading every third file (j = 800 + 3*i
). With the .png
frames in hand, I converted them to a video with an ffmpeg command:
ffmpeg -f image2 -r 20 -i turb.%d.png -vcodec libx264 -crf 18 -pix_fmt yuv420p homepage-turbulence.mp4