1*0fb1909eSJames Wright# Auxiliary Functionality 2*0fb1909eSJames WrightThis section documents functionality that is not apart of the core PDE solver, but is used for other miscellaneous tasks, such as statistics collection or in-situ machine learning. 3*0fb1909eSJames Wright 4*0fb1909eSJames Wright(aux-statistics)= 5*0fb1909eSJames Wright## Statistics Collection 6*0fb1909eSJames WrightFor scale-resolving simulations (such as LES and DNS), statistics for a simulation are more often useful than time-instantaneous snapshots of the simulation itself. 7*0fb1909eSJames WrightTo make this process more computationally efficient, averaging in the spanwise direction, if physically correct, can help reduce the amount of simulation time needed to get converged statistics. 8*0fb1909eSJames Wright 9*0fb1909eSJames WrightFirst, let's more precisely define what we mean by spanwise average. 10*0fb1909eSJames WrightDenote $\langle \phi \rangle$ as the Reynolds average of $\phi$, which in this case would be a average over the spanwise direction and time: 11*0fb1909eSJames Wright 12*0fb1909eSJames Wright$$ 13*0fb1909eSJames Wright\langle \phi \rangle(x,y) = \frac{1}{L_z + (T_f - T_0)}\int_0^{L_z} \int_{T_0}^{T_f} \phi(x, y, z, t) \mathrm{d}t \mathrm{d}z 14*0fb1909eSJames Wright$$ 15*0fb1909eSJames Wright 16*0fb1909eSJames Wrightwhere $z$ is the spanwise direction, the domain has size $[0, L_z]$ in the spanwise direction, and $[T_0, T_f]$ is the range of time being averaged over. 17*0fb1909eSJames WrightNote that here and in the code, **we assume the spanwise direction to be in the $z$ direction**. 18*0fb1909eSJames Wright 19*0fb1909eSJames WrightTo discuss the details of the implementation we'll first discuss the spanwise integral, then the temporal integral, and lastly the statistics themselves. 20*0fb1909eSJames Wright 21*0fb1909eSJames Wright### Spanwise Integral 22*0fb1909eSJames WrightThe function $\langle \phi \rangle (x,y)$ is represented on a 2-D finite element grid, taken from the full domain mesh itself. 23*0fb1909eSJames WrightIf isoperiodicity is set, the periodic face is extracted as the spanwise statistics mesh. 24*0fb1909eSJames WrightOtherwise the negative z face is used. 25*0fb1909eSJames WrightWe'll refer to this mesh as the *parent grid*, as for every "parent" point in the parent grid, there are many "child" points in the full domain. 26*0fb1909eSJames WrightDefine a function space on the parent grid as $\mathcal{V}_p^\mathrm{parent} = \{ \bm v(\bm x) \in H^{1}(\Omega_e^\mathrm{parent}) \,|\, \bm v(\bm x_e(\bm X)) \in P_p(\bm{I}), e=1,\ldots,N_e \}$. 27*0fb1909eSJames WrightWe enforce that the order of the parent FEM space is equal to the full domain's order. 28*0fb1909eSJames Wright 29*0fb1909eSJames WrightMany statistics are the product of 2 or more solution functions, which results in functions of degree higher than the parent FEM space, $\mathcal{V}_p^\mathrm{parent}$. 30*0fb1909eSJames WrightTo represent these higher-order functions on the parent FEM space, we perform an $L^2$ projection. 31*0fb1909eSJames WrightDefine the spanwise averaged function as: 32*0fb1909eSJames Wright 33*0fb1909eSJames Wright$$ 34*0fb1909eSJames Wright\langle \phi \rangle_z(x,y,t) = \frac{1}{L_z} \int_0^{L_z} \phi(x, y, z, t) \mathrm{d}z 35*0fb1909eSJames Wright$$ 36*0fb1909eSJames Wright 37*0fb1909eSJames Wrightwhere the function $\phi$ may be the product of multiple solution functions and $\langle \phi \rangle_z$ denotes the spanwise average. 38*0fb1909eSJames WrightThe projection of a function $u$ onto the parent FEM space would look like: 39*0fb1909eSJames Wright 40*0fb1909eSJames Wright$$ 41*0fb1909eSJames Wright\bm M u_N = \int_0^{L_x} \int_0^{L_y} u \psi^\mathrm{parent}_N \mathrm{d}y \mathrm{d}x 42*0fb1909eSJames Wright$$ 43*0fb1909eSJames Wrightwhere $\bm M$ is the mass matrix for $\mathcal{V}_p^\mathrm{parent}$, $u_N$ the coefficients of the projected function, and $\psi^\mathrm{parent}_N$ the basis functions of the parent FEM space. 44*0fb1909eSJames WrightSubstituting the spanwise average of $\phi$ for $u$, we get: 45*0fb1909eSJames Wright 46*0fb1909eSJames Wright$$ 47*0fb1909eSJames Wright\bm M [\langle \phi \rangle_z]_N = \int_0^{L_x} \int_0^{L_y} \left [\frac{1}{L_z} \int_0^{L_z} \phi(x,y,z,t) \mathrm{d}z \right ] \psi^\mathrm{parent}_N(x,y) \mathrm{d}y \mathrm{d}x 48*0fb1909eSJames Wright$$ 49*0fb1909eSJames Wright 50*0fb1909eSJames WrightThe triple integral in the right hand side is just an integral over the full domain 51*0fb1909eSJames Wright 52*0fb1909eSJames Wright$$ 53*0fb1909eSJames Wright\bm M [\langle \phi \rangle_z]_N = \frac{1}{L_z} \int_\Omega \phi(x,y,z,t) \psi^\mathrm{parent}_N(x,y) \mathrm{d}\Omega 54*0fb1909eSJames Wright$$ 55*0fb1909eSJames Wright 56*0fb1909eSJames WrightWe need to evaluate $\psi^\mathrm{parent}_N$ at quadrature points in the full domain. 57*0fb1909eSJames WrightTo do this efficiently, **we assume and exploit the full domain grid to be a tensor product in the spanwise direction**. 58*0fb1909eSJames WrightThis assumption means quadrature points in the full domain have the same $(x,y)$ coordinate location as quadrature points in the parent domain. 59*0fb1909eSJames WrightThis also allows the use of the full domain quadrature weights for the triple integral. 60*0fb1909eSJames Wright 61*0fb1909eSJames Wright### Temporal Integral/Averaging 62*0fb1909eSJames WrightTo calculate the temporal integral, we do a running average using left-rectangle rule. 63*0fb1909eSJames WrightAt the beginning of each simulation, the time integral of a statistic is set to 0, $\overline{\phi} = 0$. 64*0fb1909eSJames WrightPeriodically, the integral is updated using left-rectangle rule: 65*0fb1909eSJames Wright 66*0fb1909eSJames Wright$$\overline{\phi}_\mathrm{new} = \overline{\phi}_{\mathrm{old}} + \phi(t_\mathrm{new}) \Delta T$$ 67*0fb1909eSJames Wrightwhere $\phi(t_\mathrm{new})$ is the statistic at the current time and $\Delta T$ is the time since the last update. 68*0fb1909eSJames WrightWhen stats are written out to file, this running sum is then divided by $T_f - T_0$ to get the time average. 69*0fb1909eSJames Wright 70*0fb1909eSJames WrightWith this method of calculating the running time average, we can plug this into the $L^2$ projection of the spanwise integral: 71*0fb1909eSJames Wright 72*0fb1909eSJames Wright$$ 73*0fb1909eSJames Wright\bm M [\langle \phi \rangle]_N = \frac{1}{L_z + (T_f - T_0)} \int_\Omega \int_{T_0}^{T_f} \phi(x,y,z,t) \psi^\mathrm{parent}_N \mathrm{d}t \mathrm{d}\Omega 74*0fb1909eSJames Wright$$ 75*0fb1909eSJames Wrightwhere the integral $\int_{T_0}^{T_f} \phi(x,y,z,t) \mathrm{d}t$ is calculated on a running basis. 76*0fb1909eSJames Wright 77*0fb1909eSJames Wright 78*0fb1909eSJames Wright### Running 79*0fb1909eSJames WrightAs the simulation runs, it takes a running time average of the statistics at the full domain quadrature points. 80*0fb1909eSJames WrightThis running average is only updated at the interval specified by `-ts_monitor_turbulence_spanstats_collect_interval` as number of timesteps. 81*0fb1909eSJames WrightThe $L^2$ projection problem is only solved when statistics are written to file, which is controlled by `-ts_monitor_turbulence_spanstats_viewer_interval`. 82*0fb1909eSJames WrightNote that the averaging is not reset after each file write. 83*0fb1909eSJames WrightThe average is always over the bounds $[T_0, T_f]$, where $T_f$ in this case would be the time the file was written at and $T_0$ is the solution time at the beginning of the run. 84*0fb1909eSJames Wright 85*0fb1909eSJames Wright:::{list-table} Spanwise Turbulent Statistics Runtime Options 86*0fb1909eSJames Wright:header-rows: 1 87*0fb1909eSJames Wright 88*0fb1909eSJames Wright* - Option 89*0fb1909eSJames Wright - Description 90*0fb1909eSJames Wright - Default value 91*0fb1909eSJames Wright 92*0fb1909eSJames Wright* - `-ts_monitor_turbulence_spanstats_collect_interval` 93*0fb1909eSJames Wright - Number of timesteps between statistics collection 94*0fb1909eSJames Wright - `1` 95*0fb1909eSJames Wright 96*0fb1909eSJames Wright* - `-ts_monitor_turbulence_spanstats_viewer` 97*0fb1909eSJames Wright - Sets the PetscViewer for the statistics file writing, such as `cgns:output-%d.cgns` (requires PETSc `--download-cgns`). Also turns the statistics collection on. 98*0fb1909eSJames Wright - 99*0fb1909eSJames Wright 100*0fb1909eSJames Wright* - `-ts_monitor_turbulence_spanstats_viewer_interval` 101*0fb1909eSJames Wright - Number of timesteps between statistics file writing (`-1` means only at end of run) 102*0fb1909eSJames Wright - `-1` 103*0fb1909eSJames Wright 104*0fb1909eSJames Wright* - `-ts_monitor_turbulence_spanstats_viewer_cgns_batch_size` 105*0fb1909eSJames Wright - Number of frames written per CGNS file if the CGNS file name includes a format specifier (`%d`). 106*0fb1909eSJames Wright - `20` 107*0fb1909eSJames Wright::: 108*0fb1909eSJames Wright 109*0fb1909eSJames Wright### Turbulent Statistics 110*0fb1909eSJames Wright 111*0fb1909eSJames WrightThe focus here are those statistics that are relevant to turbulent flow. 112*0fb1909eSJames WrightThe terms collected are listed below, with the mathematical definition on the left and the label (present in CGNS output files) is on the right. 113*0fb1909eSJames Wright 114*0fb1909eSJames Wright| Math | Label | 115*0fb1909eSJames Wright| ----------------- | -------- | 116*0fb1909eSJames Wright| $\langle \rho \rangle$ | MeanDensity | 117*0fb1909eSJames Wright| $\langle p \rangle$ | MeanPressure | 118*0fb1909eSJames Wright| $\langle p^2 \rangle$ | MeanPressureSquared | 119*0fb1909eSJames Wright| $\langle p u_i \rangle$ | MeanPressureVelocity[$i$] | 120*0fb1909eSJames Wright| $\langle \rho T \rangle$ | MeanDensityTemperature | 121*0fb1909eSJames Wright| $\langle \rho T u_i \rangle$ | MeanDensityTemperatureFlux[$i$] | 122*0fb1909eSJames Wright| $\langle \rho u_i \rangle$ | MeanMomentum[$i$] | 123*0fb1909eSJames Wright| $\langle \rho u_i u_j \rangle$ | MeanMomentumFlux[$ij$] | 124*0fb1909eSJames Wright| $\langle u_i \rangle$ | MeanVelocity[$i$] | 125*0fb1909eSJames Wright 126*0fb1909eSJames Wrightwhere [$i$] are suffixes to the labels. So $\langle \rho u_x u_y \rangle$ would correspond to MeanMomentumFluxXY. 127*0fb1909eSJames WrightThis naming convention is chosen to align with the CGNS standard naming style. 128*0fb1909eSJames Wright 129*0fb1909eSJames WrightTo get second-order statistics from these terms, simply use the identity: 130*0fb1909eSJames Wright 131*0fb1909eSJames Wright$$ 132*0fb1909eSJames Wright\langle \phi' \theta' \rangle = \langle \phi \theta \rangle - \langle \phi \rangle \langle \theta \rangle 133*0fb1909eSJames Wright$$ 134*0fb1909eSJames Wright 135*0fb1909eSJames Wright(aux-differential-filtering)= 136*0fb1909eSJames Wright## Differential Filtering 137*0fb1909eSJames Wright 138*0fb1909eSJames WrightThere is the option to filter the solution field using differential filtering. 139*0fb1909eSJames WrightThis was first proposed in {cite}`germanoDiffFilterLES1986`, using an inverse Hemholtz operator. 140*0fb1909eSJames WrightThe strong form of the differential equation is 141*0fb1909eSJames Wright 142*0fb1909eSJames Wright$$ 143*0fb1909eSJames Wright\overline{\phi} - \nabla \cdot (\beta (\bm{D}\bm{\Delta})^2 \nabla \overline{\phi} ) = \phi 144*0fb1909eSJames Wright$$ 145*0fb1909eSJames Wright 146*0fb1909eSJames Wrightfor $\phi$ the scalar solution field we want to filter, $\overline \phi$ the filtered scalar solution field, $\bm{\Delta} \in \mathbb{R}^{3 \times 3}$ a symmetric positive-definite rank 2 tensor defining the width of the filter, $\bm{D}$ is the filter width scaling tensor (also a rank 2 SPD tensor), and $\beta$ is a kernel scaling factor on the filter tensor. 147*0fb1909eSJames WrightThis admits the weak form: 148*0fb1909eSJames Wright 149*0fb1909eSJames Wright$$ 150*0fb1909eSJames Wright\int_\Omega \left( v \overline \phi + \beta \nabla v \cdot (\bm{D}\bm{\Delta})^2 \nabla \overline \phi \right) \,d\Omega 151*0fb1909eSJames Wright- \cancel{\int_{\partial \Omega} \beta v \nabla \overline \phi \cdot (\bm{D}\bm{\Delta})^2 \bm{\hat{n}} \,d\partial\Omega} = 152*0fb1909eSJames Wright\int_\Omega v \phi \, , \; \forall v \in \mathcal{V}_p 153*0fb1909eSJames Wright$$ 154*0fb1909eSJames Wright 155*0fb1909eSJames WrightThe boundary integral resulting from integration-by-parts is crossed out, as we assume that $(\bm{D}\bm{\Delta})^2 = \bm{0} \Leftrightarrow \overline \phi = \phi$ at boundaries (this is reasonable at walls, but for convenience elsewhere). 156*0fb1909eSJames Wright 157*0fb1909eSJames Wright### Filter Width Tensor, Δ 158*0fb1909eSJames WrightFor homogenous filtering, $\bm{\Delta}$ is defined as the identity matrix. 159*0fb1909eSJames Wright 160*0fb1909eSJames Wright:::{note} 161*0fb1909eSJames WrightIt is common to denote a filter width dimensioned relative to the radial distance of the filter kernel. 162*0fb1909eSJames WrightNote here we use the filter *diameter* instead, as that feels more natural (albeit mathematically less convenient). 163*0fb1909eSJames WrightFor example, under this definition a box filter would be defined as: 164*0fb1909eSJames Wright 165*0fb1909eSJames Wright$$ 166*0fb1909eSJames WrightB(\Delta; \bm{r}) = 167*0fb1909eSJames Wright\begin{cases} 168*0fb1909eSJames Wright1 & \Vert \bm{r} \Vert \leq \Delta/2 \\ 169*0fb1909eSJames Wright0 & \Vert \bm{r} \Vert > \Delta/2 170*0fb1909eSJames Wright\end{cases} 171*0fb1909eSJames Wright$$ 172*0fb1909eSJames Wright::: 173*0fb1909eSJames Wright 174*0fb1909eSJames WrightFor inhomogeneous anisotropic filtering, we use the finite element grid itself to define $\bm{\Delta}$. 175*0fb1909eSJames WrightThis is set via `-diff_filter_grid_based_width`. 176*0fb1909eSJames WrightSpecifically, we use the filter width tensor defined in {cite}`prakashDDSGSAnisotropic2022`. 177*0fb1909eSJames WrightFor finite element grids, the filter width tensor is most conveniently defined by $\bm{\Delta} = \bm{g}^{-1/2}$ where $\bm g = \nabla_{\bm x} \bm{X} \cdot \nabla_{\bm x} \bm{X}$ is the metric tensor. 178*0fb1909eSJames Wright 179*0fb1909eSJames Wright### Filter Width Scaling Tensor, $\bm{D}$ 180*0fb1909eSJames WrightThe filter width tensor $\bm{\Delta}$, be it defined from grid based sources or just the homogenous filtering, can be scaled anisotropically. 181*0fb1909eSJames WrightThe coefficients for that anisotropic scaling are given by `-diff_filter_width_scaling`, denoted here by $c_1, c_2, c_3$. 182*0fb1909eSJames WrightThe definition for $\bm{D}$ then becomes 183*0fb1909eSJames Wright 184*0fb1909eSJames Wright$$ 185*0fb1909eSJames Wright\bm{D} = 186*0fb1909eSJames Wright\begin{bmatrix} 187*0fb1909eSJames Wright c_1 & 0 & 0 \\ 188*0fb1909eSJames Wright 0 & c_2 & 0 \\ 189*0fb1909eSJames Wright 0 & 0 & c_3 \\ 190*0fb1909eSJames Wright\end{bmatrix} 191*0fb1909eSJames Wright$$ 192*0fb1909eSJames Wright 193*0fb1909eSJames WrightIn the case of $\bm{\Delta}$ being defined as homogenous, $\bm{D}\bm{\Delta}$ means that $\bm{D}$ effectively sets the filter width. 194*0fb1909eSJames Wright 195*0fb1909eSJames WrightThe filtering at the wall may also be damped, to smoothly meet the $\overline \phi = \phi$ boundary condition at the wall. 196*0fb1909eSJames WrightThe selected damping function for this is the van Driest function {cite}`vandriestWallDamping1956`: 197*0fb1909eSJames Wright 198*0fb1909eSJames Wright$$ 199*0fb1909eSJames Wright\zeta = 1 - \exp\left(-\frac{y^+}{A^+}\right) 200*0fb1909eSJames Wright$$ 201*0fb1909eSJames Wright 202*0fb1909eSJames Wrightwhere $y^+$ is the wall-friction scaled wall-distance ($y^+ = y u_\tau / \nu = y/\delta_\nu$), $A^+$ is some wall-friction scaled scale factor, and $\zeta$ is the damping coefficient. 203*0fb1909eSJames WrightFor this implementation, we assume that $\delta_\nu$ is constant across the wall and is defined by `-diff_filter_friction_length`. 204*0fb1909eSJames Wright$A^+$ is defined by `-diff_filter_damping_constant`. 205*0fb1909eSJames Wright 206*0fb1909eSJames WrightTo apply this scalar damping coefficient to the filter width tensor, we construct the wall-damping tensor from it. 207*0fb1909eSJames WrightThe construction implemented currently limits damping in the wall parallel directions to be no less than the original filter width defined by $\bm{\Delta}$. 208*0fb1909eSJames WrightThe wall-normal filter width is allowed to be damped to a zero filter width. 209*0fb1909eSJames WrightIt is currently assumed that the second component of the filter width tensor is in the wall-normal direction. 210*0fb1909eSJames WrightUnder these assumptions, $\bm{D}$ then becomes: 211*0fb1909eSJames Wright 212*0fb1909eSJames Wright$$ 213*0fb1909eSJames Wright\bm{D} = 214*0fb1909eSJames Wright\begin{bmatrix} 215*0fb1909eSJames Wright \max(1, \zeta c_1) & 0 & 0 \\ 216*0fb1909eSJames Wright 0 & \zeta c_2 & 0 \\ 217*0fb1909eSJames Wright 0 & 0 & \max(1, \zeta c_3) \\ 218*0fb1909eSJames Wright\end{bmatrix} 219*0fb1909eSJames Wright$$ 220*0fb1909eSJames Wright 221*0fb1909eSJames Wright### Filter Kernel Scaling, β 222*0fb1909eSJames WrightWhile we define $\bm{D}\bm{\Delta}$ to be of a certain physical filter width, the actual width of the implied filter kernel is quite larger than "normal" kernels. 223*0fb1909eSJames WrightTo account for this, we use $\beta$ to scale the filter tensor to the appropriate size, as is done in {cite}`bullExplicitFilteringExact2016`. 224*0fb1909eSJames WrightTo match the "size" of a normal kernel to our differential kernel, we attempt to have them match second order moments with respect to the prescribed filter width. 225*0fb1909eSJames WrightTo match the box and Gaussian filters "sizes", we use $\beta = 1/10$ and $\beta = 1/6$, respectively. 226*0fb1909eSJames Wright$\beta$ can be set via `-diff_filter_kernel_scaling`. 227*0fb1909eSJames Wright 228*0fb1909eSJames Wright### Runtime Options 229*0fb1909eSJames Wright 230*0fb1909eSJames Wright:::{list-table} Differential Filtering Runtime Options 231*0fb1909eSJames Wright:header-rows: 1 232*0fb1909eSJames Wright 233*0fb1909eSJames Wright* - Option 234*0fb1909eSJames Wright - Description 235*0fb1909eSJames Wright - Default value 236*0fb1909eSJames Wright - Unit 237*0fb1909eSJames Wright 238*0fb1909eSJames Wright* - `-diff_filter_monitor` 239*0fb1909eSJames Wright - Enable differential filter TSMonitor 240*0fb1909eSJames Wright - `false` 241*0fb1909eSJames Wright - boolean 242*0fb1909eSJames Wright 243*0fb1909eSJames Wright* - `-diff_filter_grid_based_width` 244*0fb1909eSJames Wright - Use filter width based on the grid size 245*0fb1909eSJames Wright - `false` 246*0fb1909eSJames Wright - boolean 247*0fb1909eSJames Wright 248*0fb1909eSJames Wright* - `-diff_filter_width_scaling` 249*0fb1909eSJames Wright - Anisotropic scaling for filter width in wall-aligned coordinates (snz) 250*0fb1909eSJames Wright - `1,1,1` 251*0fb1909eSJames Wright - `m` 252*0fb1909eSJames Wright 253*0fb1909eSJames Wright* - `-diff_filter_kernel_scaling` 254*0fb1909eSJames Wright - Scaling to make differential kernel size equivalent to other filter kernels 255*0fb1909eSJames Wright - `0.1` 256*0fb1909eSJames Wright - `m^2` 257*0fb1909eSJames Wright 258*0fb1909eSJames Wright* - `-diff_filter_wall_damping_function` 259*0fb1909eSJames Wright - Damping function to use at the wall for anisotropic filtering (`none`, `van_driest`) 260*0fb1909eSJames Wright - `none` 261*0fb1909eSJames Wright - string 262*0fb1909eSJames Wright 263*0fb1909eSJames Wright* - `-diff_filter_wall_damping_constant` 264*0fb1909eSJames Wright - Constant for the wall-damping function. $A^+$ for `van_driest` damping function. 265*0fb1909eSJames Wright - 25 266*0fb1909eSJames Wright - 267*0fb1909eSJames Wright 268*0fb1909eSJames Wright* - `-diff_filter_friction_length` 269*0fb1909eSJames Wright - Friction length associated with the flow, $\delta_\nu$. Used in wall-damping functions 270*0fb1909eSJames Wright - 0 271*0fb1909eSJames Wright - `m` 272*0fb1909eSJames Wright::: 273*0fb1909eSJames Wright 274*0fb1909eSJames Wright(aux-in-situ-ml)= 275*0fb1909eSJames Wright## *In Situ* Machine-Learning Model Training 276*0fb1909eSJames WrightTraining machine-learning models normally uses *a priori* (already gathered) data stored on disk. 277*0fb1909eSJames WrightThis is computationally inefficient, particularly as the scale of the problem grows and the data that is saved to disk reduces to a small percentage of the total data generated by a simulation. 278*0fb1909eSJames WrightOne way of working around this to to train a model on data coming from an ongoing simulation, known as *in situ* (in place) learning. 279*0fb1909eSJames Wright 280*0fb1909eSJames WrightThis is implemented in the code using [SmartSim](https://www.craylabs.org/docs/overview.html). 281*0fb1909eSJames WrightBriefly, the fluid simulation will periodically place data for training purposes into a database that a separate process uses to train a model. 282*0fb1909eSJames WrightThe database used by SmartSim is [Redis](https://redis.com/modules/redis-ai/) and the library to connect to the database is called [SmartRedis](https://www.craylabs.org/docs/smartredis.html). 283*0fb1909eSJames WrightMore information about how to utilize this code in a SmartSim configuration can be found on [SmartSim's website](https://www.craylabs.org/docs/overview.html). 284*0fb1909eSJames Wright 285*0fb1909eSJames WrightTo use this code in a SmartSim *in situ* setup, first the code must be built with SmartRedis enabled. 286*0fb1909eSJames WrightThis is done by specifying the installation directory of SmartRedis using the `SMARTREDIS_DIR` environment variable when building: 287*0fb1909eSJames Wright 288*0fb1909eSJames Wright``` 289*0fb1909eSJames Wrightmake SMARTREDIS_DIR=~/software/smartredis/install 290*0fb1909eSJames Wright``` 291*0fb1909eSJames Wright 292*0fb1909eSJames Wright### SGS Data-Driven Model *In Situ* Training 293*0fb1909eSJames WrightCurrently the code is only setup to do *in situ* training for the SGS data-driven model. 294*0fb1909eSJames WrightTraining data is split into the model inputs and outputs. 295*0fb1909eSJames WrightThe model inputs are calculated as the same model inputs in the SGS Data-Driven model described {ref}`earlier<sgs-dd-model>`. 296*0fb1909eSJames WrightThe model outputs (or targets in the case of training) are the subgrid stresses. 297*0fb1909eSJames WrightBoth the inputs and outputs are computed from a filtered velocity field, which is calculated via {ref}`aux-differential-filtering`. 298*0fb1909eSJames WrightThe settings for the differential filtering used during training are described in {ref}`aux-differential-filtering`. 299*0fb1909eSJames WrightThe training will create multiple sets of data per each filter width defined in `-sgs_train_filter_widths`. 300*0fb1909eSJames WrightThose scalar filter widths correspond to the scaling correspond to $\bm{D} = c \bm{I}$, where $c$ is the scalar filter width. 301*0fb1909eSJames Wright 302*0fb1909eSJames WrightThe SGS *in situ* training can be enabled using the `-sgs_train_enable` flag. 303*0fb1909eSJames WrightData can be processed and placed into the database periodically. 304*0fb1909eSJames WrightThe interval between is controlled by `-sgs_train_write_data_interval`. 305*0fb1909eSJames WrightThere's also the choice of whether to add new training data on each database write or to overwrite the old data with new data. 306*0fb1909eSJames WrightThis is controlled by `-sgs_train_overwrite_data`. 307*0fb1909eSJames Wright 308*0fb1909eSJames WrightThe database may also be located on the same node as a MPI rank (collocated) or located on a separate node (distributed). 309*0fb1909eSJames WrightIt's necessary to know how many ranks are associated with each collocated database, which is set by `-smartsim_collocated_database_num_ranks`. 310*0fb1909eSJames Wright 311*0fb1909eSJames Wright### Runtime Options 312*0fb1909eSJames Wright:::{list-table} *In Situ* Machine-Learning Training Runtime Options 313*0fb1909eSJames Wright:header-rows: 1 314*0fb1909eSJames Wright 315*0fb1909eSJames Wright* - Option 316*0fb1909eSJames Wright - Description 317*0fb1909eSJames Wright - Default value 318*0fb1909eSJames Wright - Unit 319*0fb1909eSJames Wright 320*0fb1909eSJames Wright* - `-sgs_train_enable` 321*0fb1909eSJames Wright - Whether to enable *in situ* training of data-driven SGS model. Require building with SmartRedis. 322*0fb1909eSJames Wright - `false` 323*0fb1909eSJames Wright - boolean 324*0fb1909eSJames Wright 325*0fb1909eSJames Wright* - `-sgs_train_write_data_interval` 326*0fb1909eSJames Wright - Number of timesteps between writing training data into SmartRedis database 327*0fb1909eSJames Wright - `1` 328*0fb1909eSJames Wright - 329*0fb1909eSJames Wright 330*0fb1909eSJames Wright* - `-sgs_train_overwrite_data` 331*0fb1909eSJames Wright - Whether new training data should overwrite old data on database 332*0fb1909eSJames Wright - `true` 333*0fb1909eSJames Wright - boolean 334*0fb1909eSJames Wright 335*0fb1909eSJames Wright* - `-sgs_train_filter_widths` 336*0fb1909eSJames Wright - List of scalar values for different filter widths to calculate for training data 337*0fb1909eSJames Wright - 338*0fb1909eSJames Wright - `m` 339*0fb1909eSJames Wright 340*0fb1909eSJames Wright* - `-smartsim_collocated_num_ranks` 341*0fb1909eSJames Wright - Number of MPI ranks associated with each collocated database (i.e. ranks per node) 342*0fb1909eSJames Wright - `1` 343*0fb1909eSJames Wright - 344*0fb1909eSJames Wright::: 345