Hi there! My name is Adrian Kummerländer and I am a software developer currently studying mathematics in Karlsruhe. On these pages you will find blog articles covering amongst other topics some of my experiences in software development, open source and related tinkerings as well as repositories and information on some of my personal projects. If you have any comments or questions feel free to reach out. I hope you will find something here worth your time.

### » Working with tuples using swallowing and generic lambdas

May 26, 2020 | Adrian KummerländerSuppose you have some kind of list of types. Such a list can by itself be used to perform any compile time computation one might come up with. So let us suppose that you additionally want to construct a tuple from something that is based on this list. i.e. you want to connect the compile time only type list to a run time object. In such a case you might run into new question such as: How do I call constructors for each of my tuple values? How do I offer access to the tuple values using only the type as a reference? How do I call a function for each value in the tuple while preserving the connection to the compile time list? If such questions are of interest to you, this article might possibly also be. ↪

### » A Year of Lattice Boltzmann

December 31, 2019 | Adrian KummerländerTo both not leave the 2010s behind with just one measly article in their last year and to showcase some of the stuff I am currently working on this article covers a bouquet of topics – spanning both math-heavy theory and practical software development as well as travels to new continents. As to retroactively befit the title this past year of mine was dominated by various topics in the field of Lattice Boltzmann Methods. CFD in general and LBM in particular have shaped to become the common denominator of my studies, my work and even my leisure time. ↪

### » Expressive meta templates for flexible handling of compile-time constants

May 25, 2019 | Adrian KummerländerSo we recently released a new version of OpenLB which includes a major refactoring of the central datastructure used to handle various kinds of compile-time constants required by the simulation. This article will summarize the motivation and design of this new concept as well as highlight a couple of tricks and pitfalls in the context of template metaprogramming. ↪

### » Just-in-time volumetric CFD visualization

July 24, 2020 at 14:15 | Adrian KummerländerFor my seminar talk I wrote another LBM solver as a literate Org-document using CUDA and SymPy. The main focus was on just-in-time volumetric visualizations of the simulations performed by this code. While this is not ready to publish yet, check out the following impressions:

Further videos are available on my YouTube channel. e.g. a Taylor-Couette flow:

### » Visualizing the velocity distribution of a hard sphere gas

March 24, 2020 at 21:42 | Adrian KummerländerThe velocity distribution of a system of colliding hard sphere particles quickly evolves into the Maxwell-Boltzmann distribution. One example of this surprisingly quick process can be seen in the following video:

### » Visualize the sky for arbitrary time and space coordinates on earth

January 11, 2020 at 21:12 | firmament | 071bc3 | Adrian KummerländerThe primary color of the sky is caused by Rayleigh and Mie scattering of light in the atmosphere. While attending the lecture on Mathematical Modelling and Simulation at KIT I implemented a ray marcher to visualize this. Together with a model for calculating the sun direction for given coordinates and times this allows for generating interesting plots:

For more details check out Firmament.

### » Started working on a framework for generating LBM kernels

October 27, 2019 at 22:35 | Adrian KummerländerDuring the past exam season I now and then continued to play around with my GPU LBM code symlbm_playground. While I mostly focused on generating various real-time visualizations using e.g. volumetric ray marching, the underlying principle of generating OpenCL kernels from a symbolic description has not lost its promise.

This is why I have now started to extract the generator part of this past project into a more general framework. Currently boltzgen targets C++ and OpenCL using a shared symbolic description while providing various configuration options:

λ ~/p/d/boltzgen (boltzgen-env) ● ./boltzgen.py --help usage: boltzgen.py [-h] --lattice LATTICE --layout LAYOUT --precision PRECISION --geometry GEOMETRY --tau TAU [--disable-cse] [--functions FUNCTIONS [FUNCTIONS ...]] [--extras EXTRAS [EXTRAS ...]] language Generate LBM kernels in various languages using a symbolic description. positional arguments: language Target language (currently either "cl" or "cpp") optional arguments: -h, --help show this help message and exit --lattice LATTICE Lattice type (D2Q9, D3Q7, D3Q19, D3Q27) --layout LAYOUT Memory layout ("AOS" or "SOA") --precision PRECISION Floating precision ("single" or "double") --geometry GEOMETRY Size of the block geometry ("x:y(:z)") --tau TAU BGK relaxation time --disable-cse Disable common subexpression elimination --functions FUNCTIONS [FUNCTIONS ...] Function templates to be generated --extras EXTRAS [EXTRAS ...] Additional generator parameters

The goal is to build upon this foundation to provide an easy way to generate efficient code using a high level description of various collision models and boundary conditions. This should allow for easy comparision between various streaming patterns and memory layouts.

### » Symbolically generate D3Q19 OpenCL kernel using SymPy

June 15, 2019 at 20:45 | symlbm_playground | d71fae | Adrian KummerländerMy recent experiments in using the SymPy CAS library for automatically deriving optimized LBM codes have now evolved to the point where a single generator produces both D2Q9 and D3Q19 OpenCL kernels.

Automatically deriving kernel implementations from the symbolic formulation of e.g. the BGK relaxation operator presents itself as a very powerful concept. This could potentially be developed to the point where a LBM specific code generator could produce highly optimized GPU programs tailored to arbitrary simulation problems.

### » Experimental visualization of the velocity curl

April 28, 2019 at 12:53 | compustream | ecaf66 | Adrian KummerländerCalculating the curl of our simulated velocity field requires an additional compute shader step. Handling of buffer and shader switching depending on the display mode is implemented rudimentarily for now. Most of this commit is scaffolding, the actual computation is more or less trivial:

const float dxvy = (getFluidVelocity(x+1,y).y - getFluidVelocity(x-1,y).y) / (2*convLength); const float dyvx = (getFluidVelocity(x,y+1).x - getFluidVelocity(x,y-1).x) / (2*convLength); setFluidExtra(x, y, dxvy - dyvx);

This implements the following discretization of the 2d curl operator:

Let $V : \mathbb{N}^2 \to \mathbb{R}^2$ be the simulated velocity field at discrete lattice points spaced by $\Delta x \in \mathbb{R}_{\gt 0}$. We want to approximate the $z$-component of the curl for visualization:

$\omega := \partial_x V_y - \partial_y V_x$

As we do not possess the actual function $V$ but only its values at a set of discrete points we approximate the two partial derivatives using a second order central difference scheme:

$\overline{\omega}(i,j) := \frac{V_y(i+1,j) - V_y(i-1,j)}{2 \Delta x} - \frac{V_x(i,j+1) - V_x(i,j-1)}{2 \Delta x}$

Note that the scene shader does some further rescaling of the curl to better fit the color palette. One issue that irks me is the emergence of some artefacts near boundaries as well as isolated “single-cell-vortices”. This might be caused by running the simulation too close to divergence but as I am currently mostly interested in building an interactive fluid playground it could be worth it to try running an additional smoothening shader pass to straighten things out.