Skip to content

Commit 7b7fb91

Browse files
efhuntThomas Howarth
andauthored
Add turbulent forcing functionality to generate and maintain homogeneous isotropic turbulence. (#588)
* add turbulent forcing functionality * add turbulent forcing documentation * add removed .png back in documentation * removing nprocs as suggested by CI * remove unused function * cleanup some clang warnings * fixed typo * fixed typo * some constexpr particulars * mersenne formatting * Remove unnecessary commentary and add DIO for papers (requested by baperry2). * constexpr * doi tidy * duplicate target * remove additional user specified rho for incompressible forcing (as requested by baperry2) * formatting * formatting * clang-format * why clang-format? --------- Co-authored-by: Thomas Howarth <tlhowarth@bernicia.local>
1 parent d5c4ae8 commit 7b7fb91

File tree

7 files changed

+1388
-0
lines changed

7 files changed

+1388
-0
lines changed

Docs/sphinx/Utility.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ In addition to routines for evaluating chemical reactions, transport properties,
1010

1111
* Premixed Flame (``PMF``) initialization from precomputed 1D flame profiles
1212
* Turbulent inflows (``TurbInflow``) on domain boundaries from saved turbulence data
13+
* Forced Turbulence (``TurbForce``) for maintained HIT
1314
* Plt file management (``PltFileManager``)
1415
* Output of runtime ``Diagnostics``
1516
* Basic ``Utilities``, including unit conversions
@@ -136,6 +137,42 @@ inflow plane data and interpolation approaches for periodic and nonperiodic tang
136137

137138
.. figure:: ./Visualization/TurbInflowData.png
138139

140+
.. _sec_turbforce:
141+
142+
Forced Turbulence
143+
=================
144+
145+
PelePhysics supports the capability for maintained homogeneous isotropic turbulence. A source term in the momentum equation injects energy at
146+
large scales, which naturally cascades to form (maintained) homogeneous isotropic turbulence.
147+
148+
Input file options
149+
~~~~~~~~~~~~~~~~~~
150+
151+
The input file options that drive this utility (and thus are inherited by PeleC and PeleLMeX) are
152+
provided below. ::
153+
154+
turbforce.v = 0 # Verbosity level
155+
turbforce.urms = [Must be User Defined] # Target urms
156+
turbforce.time_offset = 0.0 # Offset of the forcing function.
157+
turbforce.hack_lz = 0 # Allow periodic reproduction in z.
158+
turbforce.force_scale_fudge = 1.0 # Used for fine scale tuning of the forcing function.
159+
160+
turbforce.ff_factor = 4 # Fast force coarsening factor.
161+
turbforce.nmodes = 4 # Largest mode to force.
162+
turbforce.forcing_epsilon = 0.1 # Reduce amplitude of modes used for breaking symmetry.
163+
turbforce.spectrum_type = 2 # Shape of the spectrum of the forcing.
164+
turbforce.moderate_zero_modes = 1 # Reduce the impact of any zero mode.
165+
turbforce.mode_start = 0 # Starting mode
166+
167+
For ff_factor, nmodes, forcing_epsilon, spectrum_type and moderate_zero_modes, it is best to leave these as defaults unless you are confident on
168+
the consiquences.
169+
170+
Forced Turbulence Implementation Details
171+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
172+
173+
The strategy is to inject energy into the large scales using a source term in the momentum equation; the turbulence then develops naturally through the Richardson-Kolmogorov cascade. The original description is in `Aspden et al. <https://doi.org/10.2140/camcos.2008.3.103>`_; a few modifications (e.g. tweaking the amplitudes of the modes through the random seed, which reduced the temporal variation in u_rms) and explicitly using a divergence-free form (see `Almgren et al. <https://doi.org/10.1137/110829386>`_). We typically run in a cube, or 4:1 box; larger boxes can achieved using the hack_lz option, which uses a periodic reproduction of the forcing in the z direction. As the source term is a superposition of a substantial number of fourier modes, the direct evaluation is computationally expensive. The resulting field is smooth (as we're forcing the large scales), so for computational efficiency, the source term is evaluated on a coarser box (by ff_factor, usually 4), and interpolated onto the required resolution; this is substantially faster, and indistinguishable from the direct approach.
174+
175+
139176
Plt File Management
140177
===================
141178

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
CEXE_headers += TurbForcing.H MersenneTwister.H
2+
CEXE_sources += TurbForcing.cpp MersenneTwister.cpp
3+
4+
VPATH_LOCATIONS += $(PELE_PHYSICS_HOME)/Source/Utility/TurbForcing
5+
INCLUDE_LOCATIONS += $(PELE_PHYSICS_HOME)/Source/Utility/TurbForcing
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//
2+
// AMReX Interface to Mersenne Twistor
3+
//
4+
5+
/* A C-program for MT19937: Real number version (1999/10/28) */
6+
/* genrand() generates one pseudorandom real number (double) */
7+
/* which is uniformly distributed on [0,1]-interval, for each */
8+
/* call. sgenrand(seed) sets initial values to the working area */
9+
/* of 624 words. Before genrand(), sgenrand(seed) must be */
10+
/* called once. (seed is any 32-bit integer.) */
11+
/* Integer generator is obtained by modifying two lines. */
12+
/* Coded by Takuji Nishimura, considering the suggestions by */
13+
/* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
14+
15+
/* This library is free software under the Artistic license: */
16+
/* see the file COPYING distributed together with this code. */
17+
/* For the verification of the code, its output sequence file */
18+
/* mt19937-1.out is attached (2001/4/2) */
19+
20+
/* Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. */
21+
/* Any feedback is very welcome. For any question, comments, */
22+
/* see http://www.math.keio.ac.jp/matumoto/emt.html or email */
23+
/* matumoto@math.keio.ac.jp */
24+
25+
/* REFERENCE */
26+
/* M. Matsumoto and T. Nishimura, */
27+
/* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform */
28+
/* Pseudo-Random Number Generator", */
29+
/* ACM Transactions on Modeling and Computer Simulation, */
30+
/* Vol. 8, No. 1, January 1998, pp 3--30. */
31+
32+
#ifndef MERSENNETWISTER_H_
33+
#define MERSENNETWISTER_H_
34+
35+
#include <AMReX_Vector.H>
36+
37+
namespace pele::physics::turbforcing::mersenne_twister {
38+
class mt19937
39+
{
40+
public:
41+
using seed_type = unsigned long;
42+
explicit mt19937(seed_type seed = 4357UL);
43+
mt19937(seed_type array[], int array_len);
44+
void rewind();
45+
void reset(unsigned long seed);
46+
47+
double d_value(); // [0,1] random numbers
48+
double d1_value(); // [0,1) random numbers
49+
double d2_value(); // (0,1) random numbers
50+
51+
long l_value(); // [0,2^31-1] random numbers
52+
unsigned long u_value(); // [0,2^32-1] random numbers
53+
54+
void save(amrex::Vector<unsigned long>& state) const;
55+
int RNGstatesize() const;
56+
void restore(const amrex::Vector<unsigned long>& state);
57+
58+
private:
59+
enum { N = 624 };
60+
static unsigned long init_seed;
61+
static unsigned long mt[N]; // the array for the state vector
62+
static int mti; // mti==N+1 means mt[N] is not initialized
63+
#ifdef _OPENMP
64+
#pragma omp threadprivate(init_seed, mt, mti)
65+
#endif
66+
void sgenrand(unsigned long seed);
67+
unsigned long igenrand();
68+
void reload();
69+
};
70+
71+
/*
72+
Generates one pseudorandom real number (double) which is
73+
uniformly distributed on [0,1]-interval for each call.
74+
75+
Accepts any 32-bit integer as a seed -- uses 4357 as the default.
76+
77+
Has a period of 2**19937.
78+
79+
Mersenne Twister Home Page: http://www.math.keio.ac.jp/matumoto/emt.html
80+
81+
There is also an entry point for Fortran callable as:
82+
83+
REAL_T rn
84+
call blutilrand(rn)
85+
86+
Internally, blutilrand() calls a static Mersenne Twister object (the
87+
same one used by AMReX::Random()) to get a value in [0,1] and then
88+
sets "rn" to that value.
89+
*/
90+
double Random(); // [0,1]
91+
double Random1(); // [0,1)
92+
double Random2(); // (0,1)
93+
unsigned long Random_int(unsigned long n); // [0,n-1], where n<=2^32-1
94+
/* Set the seed of the random number generator.
95+
96+
There is also an entry point for Fortran callable as:
97+
98+
INTEGER seed
99+
call blutilinitrand(seed)
100+
101+
or
102+
103+
INTEGER seed
104+
call blinitrand(seed)
105+
*/
106+
void InitRandom(unsigned long seed);
107+
108+
void ResetRandomSeed(unsigned long seed);
109+
//
110+
// Save and restore random state.
111+
//
112+
// state.size() == 626 on return from Save & on entry to Restore.
113+
//
114+
void SaveRandomState(amrex::Vector<unsigned long>& state);
115+
116+
int sizeofRandomState();
117+
118+
void RestoreRandomState(const amrex::Vector<unsigned long>& state);
119+
//
120+
// Create a unique subset of random numbers from a pool
121+
// of integers in the range [0, poolSize - 1]
122+
// the set will be in the order they are found
123+
// setSize must be <= poolSize
124+
// uSet will be resized to setSize
125+
// if you want all processors to have the same set,
126+
// call this on one processor and broadcast the array
127+
//
128+
void UniqueRandomSubset(
129+
amrex::Vector<int>& uSet, int setSize, int poolSize, bool printSet = false);
130+
} // namespace pele::physics::turbforcing::mersenne_twister
131+
132+
#endif

0 commit comments

Comments
 (0)