OpenFOAM “automation” with bash

As always, I am currently hunting for application data for my recent visualization. As it is not easy to get data that can be used in a publication, plus my requirements were a bit special (2D, rather small resolution, many ensemble members), I decided to generate the data on my own using OpenFOAM. I haven’t worked with simulation tools before, thus stumbling through two or more tutorials at a time, I finally got my simulation set up. The OpenFOAM tutorials are very nice by the way, I mainly followed this one.

Now I wanted the results for not less than 140 different Reynolds numbers. That means:

  • Calculate & change the kinematic viscosity in the appropriate OpenFOAM file
  • Run the simulation
  • Store the results

I started doing this by hand the first 3 runs, then started googeling about OpenFOAM automation, found job vacancies for freelancers to do this. Seems like nobody wants to do this on his own. So get your regular expressions ready – we do it via bash file.

I put my complete files here since I would have been _very_ happy to find them on the internet, so maybe I can make someones day 🙂

The described tasks add up to the following:

#!/bin/bash

source ~/OpenFOAM/OpenFOAM-v1812/etc/bashrc 

for re in {10..150}
do
	nu=`echo "0.1/$re" | bc -l`
	sed -i -e "s/\(nu[[:space:]]*\)[[:digit:]]*.[[:digit:]]*;/\10$nu;/" "constant/transportProperties"
	
	icoFoam
	mv 0.7/U 0.7/Ensemble/Re$re

done

This file expects to be executed in the main OpenFOAM folder of the simulation (the one containing constant and system folder). After sourcing OpenFOAM, everything is executed for Reynolds numbers from 10 to 150. The kinematic viscosity is calculated. Actually that is nu = d|U|/Re where d and U are the characteristic length and velocity respectively and Re is the Reynolds number, but in my case d and |U| was given as 0.1 and 1. So having differing values there: change the 0.1 in “0.1/$re” accordingly.

Then, sed is used to find the right place in the transportProperties file to put nu, and the file is changed. At first, none of my regular expressions would work since I used \d for digits. Be aware that these shorthand characters don’t exist using sed.

After executing the simulation with the current Reynolds number, the file I am interested in (U) is moved to an extra directory and renamed as Re10 – Re150 (Re#). My time step for storing the data was 0.7, so the path in mv might change for you. I did not test if the extra directory is necessary (especially since we take the files out of there in the next step) but it felt better do have them out of OpenFOAMs eyes while running the simulations.

Now a sanity check of the results would be nice. Using the ParaView interface of OpenFoam this should not be a problem. But after putting all Re# files one level up in the 0.7 directory, I realized the name of the contained field is stored in the file itself. Thus ParaView seems to overwrite the same field again and again when reading the files in, and just the last ensemble member is accessible. Thank god we already know what to do in such a case. We write an other bash file changing the stored name of the field from “U” to “Re#”:

#!/bin/bash
for re in {10..150}
do
	sed -i -e "s/\(object[[:space:]]*\)U;/\1Re$re;/" 0.7/Re$re
done

This one is like a smaller version of the previous one, just the regular expression changed. Now when entering ParaView by paraFoam, all fields are available to have a look at them.

I was quite happy how a night of repetitive and boring work became some minutes of fiddling with regular expressions. Probably I should use more bash scripts.

Dynamic Time Warp

I was playing around with the DTW implementation in Python by Pierre Rouanet to match two signals. While the reference signal is fix, a given measurement should be changed to nicely match the reference. BUT measurement features should be kept.

For everybody not familiar with DTW, the explanation in the paper “Derivative dynamic time warping” by Keogh and Pazzani was very helpfull to me: https://doi.org/10.1137/1.9781611972719.1.

My first try using DTW resulted in a fairly close matching, with huge plateaus, not resembling the original matching sequence at all 🙁

I visualized the matching between “raw” (the given measurement) and “ref” (the reference). When multiple points of the measurement are matched to one point in the reference, the resulting curve (“match type 0”) at this point is the mean value of all matched values. If one point of the measurement is matched to multiple points in the reference, the value is repeated forming plateaus.

This is uncool!

So what can I do about DTW completely changing the shape of the measurement curve? Two nice possibilities I found are

  • Slope weighting: Leaving the diagonal with the matching path is punished with a constant factor.
  • Windowing: The difference between indices that are allowed to be matched is restricted.

Both options seemed to be interesting, so I implemented both in the dtw package https://pypi.org/project/dtw/ and indeed! I got better results.

While the plateaus are effectively avoided/down scaled using these additions, it currently seems like I get best results using structure analysis instead of DTW. Anyway, playing around was nice 🙂