|
| 1 | +--- |
| 2 | +title: Unsteady von Karman vortex shedding |
| 3 | +permalink: /tutorials/Inc_Von_Karman/ |
| 4 | +written_by: Nijso Beishuizen |
| 5 | +for_version: 8.0.1 |
| 6 | +revised_by: |
| 7 | +revision_date: |
| 8 | +revised_version: |
| 9 | +solver: INC_NAVIER_STOKES |
| 10 | +requires: SU2_CFD |
| 11 | +complexity: intermediate |
| 12 | +--- |
| 13 | + |
| 14 | + |
| 15 | + |
| 16 | +Figure (1): impression of the von Karman vortex shedding. A high quality mp4 video can be found [here](../../../tutorials_files/incompressible_flow/Inc_Von_Karman/images/unsteady_cylinder.mp4) |
| 17 | + |
| 18 | +## Goals |
| 19 | + |
| 20 | +In this tutorial we will simulate the laminar but unsteady vortex shedding behind a 2D circular cylinder, also known as von Karman vortex shedding. The unsteady pattern behind the cylinder is known as a von Karman sheet. In this tutorial we will touch upon the following aspects: |
| 21 | +- Setting up an unsteady simulation in SU2 |
| 22 | +- Choosing appropriate settings for the unsteady simulation |
| 23 | +- Inspecting the effects of our choices for the numerical setup |
| 24 | +- Creating movies with paraview |
| 25 | +- Extracting the shedding frequency with paraview |
| 26 | +- visualize the forces on the cylinder with paraview |
| 27 | + |
| 28 | + |
| 29 | +## Resources |
| 30 | + |
| 31 | +The resources for this tutorial can be found in the [incompressible_flow/Inc_Von_Karman](https://github.com/su2code/Tutorials/tree/master/incompressible_flow/Inc_Von_Karman_Cylinder) directory in the [tutorial repository](https://github.com/su2code/Tutorials). You will need the configuration file ([unsteady_incomp_cylinder.cfg](https://github.com/su2code/Tutorials/tree/master/incompressible_flow/Inc_Von_Karman_Cylinder/unsteady_incomp_cylinder.cfg)) and the mesh file ([cylinder_wake.su2](https://github.com/su2code/Tutorials/tree/master/incompressible_flow/Inc_Von_Karman_cylinder/cylinder_wake.su2)). Additionally, the Gmsh geometry is also provided so you can recreate the mesh yourself: [cylinder_wake.geo](https://github.com/su2code/Tutorials/tree/master/incompressible_flow/Inc_Von_Karman_Cylinder/cylinder_wake.geo). |
| 32 | + |
| 33 | + |
| 34 | +### Background |
| 35 | + |
| 36 | +When the Reynolds number $$Re=\rho \cdot V \cdot D / \mu$$ is low (Re < 40), the flow around a circular cylinder is laminar and steady. At around Re=49, the flow becomes unsteady and a periodic shedding of vortices forms in the wake of the cylinder, known as vortex shedding. The frequency of this vortex shedding is usually expressed in terms of the Strouhal number $$St= f \ cdot D / U_{\infty}$$, with f the shedding frequency, D the diameter of the cylinder and U the far-field velocity. Important experimental work can be found in the paper of Williamson, *Vortex Dynamics in the Cylinder Wake*, Annual Review of Fluid Mechanics (1996) [doi](https://doi.org/10.1146/annurev.fl.28.010196.002401). After around Re=180, a second frequency is observed experimentally, in the longitudinal direction. This frequency can only be observed in a 3D simulation. The increase in number of frequencies continues until after around Re=1000 the flow is considered fully turbulent. |
| 37 | + |
| 38 | +### Problem Setup |
| 39 | + |
| 40 | +The configuration is a circular cylinder of 5 mm surrounded by a far field at $$L = 30 D$$ and a rectangular wake region of $$X = 150 D$$. The far-field velocity is $$U_{\infty} = 0.12 m/s$$. With a viscosity of $$\mu=1.0 \cdot 10^{-5}$$ and a density of $$\rho = 1 kg/m3$$, the Reynolds number is $$Re=120$$. |
| 41 | + |
| 42 | + |
| 43 | +Figure 2: Computational domain for the von Karman vortex shedding. |
| 44 | + |
| 45 | +The solution is initialized with uniform flow conditions. After an initial phase of around 4 seconds, the flow becomes periodic with a specific frequency depending on the Reynolds number. |
| 46 | + |
| 47 | + |
| 48 | +### Mesh Description |
| 49 | + |
| 50 | +The mesh consists of a structured mesh with 70k cells and 75k points. The mesh was created using Gmsh and the configuration file to create the mesh can be found here: [cylinder_wake.geo](https://github.com/su2code/Tutorials/tree/master/incompressible_flow/Inc_Von_Karman/cylinder_wake.geo). The only thing you need to do to create a mesh from the geometry is start Gmsh, and then load the .geo file. You will then see the geometry in the Gmsh visualization window. If you click on *Mesh->2D* the 2D mesh will be generated. You can then export the mesh as a .su2 file by choosing *File->Export*. The mesh will automatically be saved in su2 format when the filename has the extension .su2. In general, you should not choose *save all elements* because this will also save additional points that were used to construct the geometry but are not part of the final mesh, like for example the center of a circle. |
| 51 | + |
| 52 | + |
| 53 | +### Configuration File Options |
| 54 | + |
| 55 | +Several of the key configuration file options for this simulation are highlighted here. First, we activate the turbulence model: |
| 56 | + |
| 57 | +``` |
| 58 | +SOLVER= INC_NAVIER_STOKES |
| 59 | +INC_NONDIM= DIMENSIONAL |
| 60 | +KIND_TURB_MODEL= NONE |
| 61 | +``` |
| 62 | + |
| 63 | +We use the incompressible NAVIER-STOKES without turbulence model, since the flow is unsteady but laminar. |
| 64 | + |
| 65 | +``` |
| 66 | +TIME_DOMAIN = YES |
| 67 | +TIME_MARCHING= DUAL_TIME_STEPPING-2ND_ORDER |
| 68 | +TIME_STEP= 0.005 |
| 69 | +MAX_TIME=25.00 |
| 70 | +TIME_ITER=2500 |
| 71 | +INNER_ITER= 20 |
| 72 | +``` |
| 73 | + |
| 74 | +The **TIME_DOMAIN** keyword activates transient simulations. We use a second order timestep, with a step size of $$\Delta t = 0.01 s$$. The maximum time is set to $$t_{max} = 25 s$$ or 2500 iterations, whichever is reached first. We use 20 inner iterations per timestep, which sufficiently converges the residuals. This is important to check, insufficient convergence per time step quickly leads to large errors. |
| 75 | + |
| 76 | +``` |
| 77 | +INC_VELOCITY_INIT= ( 0.12, 0.0, 0.0 ) |
| 78 | +MARKER_HEATFLUX= ( cylinder, 0.0 ) |
| 79 | +MARKER_FAR= ( farfield_in,farfield_side,farfield_out ) |
| 80 | +MARKER_MONITORING= ( cylinder ) |
| 81 | +``` |
| 82 | + |
| 83 | +There is no heat transfer, so we set zero heatflux boundary conditions on the walls and we impose a far-field velocity of 0.12 m/s. The **MARKER_MONITORING** keyword is used to monitor forces at the cylinder surface. We are interested in the lift and drag coefficient. |
| 84 | + |
| 85 | +``` |
| 86 | +% monitoring points in the cylinder wake |
| 87 | +CUSTOM_OUTPUTS= 'velocity : Macro{sqrt(pow(VELOCITY_X, 2) + pow(VELOCITY_Y, 2) )};\ |
| 88 | + probe1 : Probe{$velocity}[0.15, 0.0]' |
| 89 | +HISTORY_OUTPUT= (TIME_ITER, CUR_TIME, RMS_RES, LIST, DRAG, LIFT, SURFACE_STATIC_PRESSURE, CUSTOM) |
| 90 | +``` |
| 91 | + |
| 92 | +We define a monitoring point called *probe1* at location $$(x,y)=(0.15, 0.0)$$ downstream of the cylinder and at the centerline. In this probe, we monitor the velocity magnitude $velocity$, that we compute from the existing velocity components. We write the probe information to the history output using the keyword **CUSTOM**. |
| 93 | + |
| 94 | + |
| 95 | +### Running SU2 |
| 96 | + |
| 97 | +If possible, always use a parallel setup to reduce computational time (wall clock time). Run the SU2_CFD executable in parallel using MPI and 4 nodes by entering: |
| 98 | + |
| 99 | + $ mpirun -n 4 SU2_CFD unsteady_incomp_cylinder.cfg |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +### Results |
| 104 | + |
| 105 | + |
| 106 | +Figure (3): Developed von Karman street with injected particles. |
| 107 | + |
| 108 | +The figure above shows the von Karman vortices. A movie of the von Karman Vortex shedding as shown in this tutorial can be made using the paraview statefile here: [statefile_with_particles.pvsm](https://github.com/su2code/Tutorials/tree/master/incompressible_flow/Inc_Von_Karman_Cylinder/statefile_with_particles.pvsm). The colored vorticity gradients are created in the wake immediately behind the cylinder, and transported downstream. In paraview, we inject particles and let them be transported downstream over streamlines. We can clearly see that the particles are not mixed homogeneously but are being transported in batches of red and green particles moving with their corresponding vortices. |
| 109 | + |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | +A link to a high quality video can be found [here](https://github.com/su2code/su2code.github.io/tree/master/tutorials_files/incompressible_flow/Inc_Von_Karman/images/unsteady_cylinder_arrow.mp4). |
| 114 | + |
| 115 | +The forces on the cylinder can also be visualized, see the above movie. We see the unsteady velocity magnitude, and on the cylinder surface we visualize the local force as the local pressure normal to the surface. For this we need to extract the surface data only and then compute the surface normal using a programmable filter. We can then visualize the glyph distribution. The total lift force is the integrated vertical component, whose size can be visualize as a colored arrow of a size proportional to the lift force using another programmable filter. Below the image we visualize the lift force in time using the PlotSelectionOverTime feature. |
| 116 | + |
| 117 | + |
| 118 | + |
| 119 | +Figure (4): Strouhal number, comparison with experimental data from Williamson (2006). |
| 120 | + |
| 121 | +The Strouhal number can be computed from the lift coefficient that was stored in the history.csv file. A simple python file gives us the frequency from the FFT: |
| 122 | + |
| 123 | +```python |
| 124 | +#%matplotlib inline |
| 125 | +#import matplotlib.pyplot as plt |
| 126 | +import pandas as pd |
| 127 | +import numpy as np |
| 128 | +import scipy.fftpack |
| 129 | +import csv |
| 130 | + |
| 131 | +# Return value belonging to key in config.cfg |
| 132 | +# (splits key= value for you) |
| 133 | +def find_config_key_value(filename,config_key): |
| 134 | + with open(filename, "r") as file: |
| 135 | + for line in file: |
| 136 | + line = line.split('=') |
| 137 | + if line[0] == config_key: |
| 138 | + print(line[-1].strip() ) |
| 139 | + return(line[-1].strip()) |
| 140 | + raise ValueError('key not found:',config_key) |
| 141 | + |
| 142 | +# diameter of cylinder |
| 143 | +D = 0.01 |
| 144 | + |
| 145 | +# read history, use comma as separator, with zero or more spaces before or after |
| 146 | +df = pd.read_csv('history.csv', sep='\s*,\s*') |
| 147 | + |
| 148 | +T = float(find_config_key_value('unsteady_incomp_cylinder.cfg','TIME_STEP')) |
| 149 | +U = find_config_key_value('unsteady_incomp_cylinder.cfg','INC_VELOCITY_INIT') |
| 150 | +N = len(df.index) |
| 151 | +print('timestep=',T) |
| 152 | +print('samplepoints=',N) |
| 153 | +print('velocity=',U) |
| 154 | +U = float(U.replace('(','').replace(')','').split(',')[0].strip()) |
| 155 | +print('velocity=',U) |
| 156 | + |
| 157 | +# assign data |
| 158 | +x = df['"Cur_Time"'] |
| 159 | +y = df['"CL"'] |
| 160 | + |
| 161 | +# compute DFT with optimized FFT |
| 162 | +xf = np.linspace(0.0, 1.0/(2.0*T), N//2) |
| 163 | +yf = np.fft.fft(y) |
| 164 | +yf2 = 2.0/N * np.abs(yf[:N//2]) |
| 165 | + |
| 166 | +#fig, ax = plt.subplots() |
| 167 | +#plt.xlim(0,5.0) |
| 168 | +#ax.plot(xf, yf2 ) |
| 169 | +#plt.show() |
| 170 | + |
| 171 | +print("index of max = ",np.argmax(yf2)) |
| 172 | +freq = xf[np.argmax(yf2)] |
| 173 | +print("frequency of max = ",freq) |
| 174 | +St = freq * D / U |
| 175 | +print("strouhal number = ",St) |
| 176 | +``` |
| 177 | + |
| 178 | + |
| 179 | +When we compare the Strouhal number with the experimental data from Williamson, we see in Figure 4 that the frequency is underpredicted. We will vary some numerical settings to investigate if we can improve the prediction of the Strouhal number. |
| 180 | + |
| 181 | + |
| 182 | + |
| 183 | +### Numerical variations |
| 184 | + |
| 185 | + |
| 186 | + |
| 187 | +Figure (5): Comparison of different numerical settings |
| 188 | + |
| 189 | +In Figure 5, we see the effect of different numerical settings on the prediction of the Strouhal number. The second order scheme predicts a Strouhal number of $$St = 0.1734$$, slightly over predicting the experimental value of $$St_{exp} = 0.170$$. Note that our predictions of the Strouhal frequency depends on the number of samples and sampling rate that we provide to the FFT. We took 2500 timesteps of 0.01 s which contains enough cycles for an accurate frequency prediction using an fft. |
| 190 | +When switching from second order in time to first order, the Strouhal number is under predicted by 6 \% compared to the experimental value. Also, when increasing the time step from 0.01 s to 0.02 seconds, the St decreases by 2 \%. When increasing the time step even further to $$ \Delta t = 0.04 s%%, St is under predicted by 8 \%. The period of the dimensional frequency is $$f \approx 0.5 s$$, so with a timestep of 0.01 s we have 50 time steps per period, we have 25 time steps when $$\Delta t = 0.02 s$$, and only 12 time steps when $$\Delta t = 0.04 s$$. It is clear that 12 time steps per period is not sufficient. |
| 191 | + |
| 192 | +It is also known that the size of the computational domain influences the results, so we reduce the domain by half, $$L = 15 D$$ and $$X = 75 D$$. The Strouhal then increases to $$St = 0.1768$$, an increase of 2 \%. It seems that a far-field that is 15D away from the cylinder is sufficient. |
| 193 | + |
| 194 | +As a final test, the testcase can be executed for varying Reynolds numbers, ranging from Re=60 to Re=180, giving the result in Figure (6). |
| 195 | + |
| 196 | + |
| 197 | + |
| 198 | +Figure (6): Comparison of numerical Strouhal numbers with experiments for varying Reynolds numbers. |
| 199 | + |
| 200 | +We get a pretty good agreement compared to the experimentally measured values. |
| 201 | + |
| 202 | +### Final notes |
| 203 | + |
| 204 | +The paraview statefile to create the movie can be found here: [statefile_with_particles.pvsm](https://github.com/su2code/Tutorials/blob/master/incompressible_flow/Inc_Von_Karman/statefile_with_particles.pvsm) |
| 205 | +and here: |
| 206 | +[statefile_movablearrow_timeseries.pvsm](https://github.com/su2code/Tutorials/blob/master/incompressible_flow/Inc_Von_Karman/statefile_movablearrow_timeseries.pvsm) |
| 207 | +Note that you have to select your own, local files when you load the statefile. |
0 commit comments