xref: /honee/qfunctions/sgs_dd_training.h (revision 8ecc9db92962ddef4644386812e66677d724f589)
1*8ecc9db9SJames Wright // Copyright (c) 2017-2023, Lawrence Livermore National Security, LLC and other CEED contributors.
2*8ecc9db9SJames Wright // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3*8ecc9db9SJames Wright //
4*8ecc9db9SJames Wright // SPDX-License-Identifier: BSD-2-Clause
5*8ecc9db9SJames Wright //
6*8ecc9db9SJames Wright // This file is part of CEED:  http://github.com/ceed
7*8ecc9db9SJames Wright 
8*8ecc9db9SJames Wright /// @file
9*8ecc9db9SJames Wright /// Structs and helper functions for training data-driven subgrid-stress models
10*8ecc9db9SJames Wright /// See 'Invariant data-driven subgrid stress modeling in the strain-rate eigenframe for large eddy simulation' 2022 and 'S-frame discrepancy
11*8ecc9db9SJames Wright /// correction models for data-informed Reynolds stress closure' 2022
12*8ecc9db9SJames Wright 
13*8ecc9db9SJames Wright #ifndef sgs_dd_training_h
14*8ecc9db9SJames Wright #define sgs_dd_training_h
15*8ecc9db9SJames Wright 
16*8ecc9db9SJames Wright #include <ceed.h>
17*8ecc9db9SJames Wright 
18*8ecc9db9SJames Wright #include "differential_filter_enums.h"
19*8ecc9db9SJames Wright #include "newtonian_state.h"
20*8ecc9db9SJames Wright #include "newtonian_types.h"
21*8ecc9db9SJames Wright #include "sgs_dd_utils.h"
22*8ecc9db9SJames Wright #include "utils.h"
23*8ecc9db9SJames Wright #include "utils_eigensolver_jacobi.h"
24*8ecc9db9SJames Wright 
25*8ecc9db9SJames Wright typedef struct SGS_DD_TrainingContext_ *SGS_DDTrainingContext;
26*8ecc9db9SJames Wright struct SGS_DD_TrainingContext_ {
27*8ecc9db9SJames Wright   struct NewtonianIdealGasContext_ gas;
28*8ecc9db9SJames Wright };
29*8ecc9db9SJames Wright 
30*8ecc9db9SJames Wright // @brief Calculate Data-Driven SGS model training data at nodes
31*8ecc9db9SJames Wright CEED_QFUNCTION_HELPER int ComputeSGS_DDAnisotropicTrainingDataNodal(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out,
32*8ecc9db9SJames Wright                                                                     StateVariable state_var) {
33*8ecc9db9SJames Wright   const CeedScalar(*q)[CEED_Q_VLA]            = (const CeedScalar(*)[CEED_Q_VLA])in[0];
34*8ecc9db9SJames Wright   const CeedScalar(*velo_prod)[CEED_Q_VLA]    = (const CeedScalar(*)[CEED_Q_VLA])in[1];
35*8ecc9db9SJames Wright   const CeedScalar(*grad_velo)[3][CEED_Q_VLA] = (const CeedScalar(*)[3][CEED_Q_VLA])in[2];
36*8ecc9db9SJames Wright   const CeedScalar(*A_ij_delta)[CEED_Q_VLA]   = (const CeedScalar(*)[CEED_Q_VLA])in[3];
37*8ecc9db9SJames Wright   const CeedScalar(*inv_multiplicity)         = (const CeedScalar(*))in[4];
38*8ecc9db9SJames Wright   CeedScalar(*v)[CEED_Q_VLA]                  = (CeedScalar(*)[CEED_Q_VLA])out[0];
39*8ecc9db9SJames Wright 
40*8ecc9db9SJames Wright   const SGS_DDTrainingContext    sgsdd_ctx = (SGS_DDTrainingContext)ctx;
41*8ecc9db9SJames Wright   const NewtonianIdealGasContext gas       = &sgsdd_ctx->gas;
42*8ecc9db9SJames Wright 
43*8ecc9db9SJames Wright   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
44*8ecc9db9SJames Wright     const CeedScalar qi[5]                 = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
45*8ecc9db9SJames Wright     const CeedScalar grad_velo_aniso[3][3] = {
46*8ecc9db9SJames Wright         {grad_velo[0][0][i], grad_velo[0][1][i], grad_velo[0][2][i]},
47*8ecc9db9SJames Wright         {grad_velo[1][0][i], grad_velo[1][1][i], grad_velo[1][2][i]},
48*8ecc9db9SJames Wright         {grad_velo[2][0][i], grad_velo[2][1][i], grad_velo[2][2][i]}
49*8ecc9db9SJames Wright     };
50*8ecc9db9SJames Wright     const CeedScalar km_A_ij[6] = {A_ij_delta[0][i], A_ij_delta[1][i], A_ij_delta[2][i], A_ij_delta[3][i], A_ij_delta[4][i], A_ij_delta[5][i]};
51*8ecc9db9SJames Wright     const CeedScalar delta      = A_ij_delta[6][i];
52*8ecc9db9SJames Wright     const State      s          = StateFromQ(gas, qi, state_var);
53*8ecc9db9SJames Wright     CeedScalar       inputs[6];
54*8ecc9db9SJames Wright     CeedScalar       eigenvectors[3][3], grad_velo_magnitude;  // dummy variables, don't actually use them
55*8ecc9db9SJames Wright 
56*8ecc9db9SJames Wright     ComputeSGS_DDAnisotropicInputs(grad_velo_aniso, km_A_ij, delta, gas->mu / s.U.density, eigenvectors, inputs, &grad_velo_magnitude);
57*8ecc9db9SJames Wright 
58*8ecc9db9SJames Wright     for (int j = 0; j < 6; j++) v[j][i] = inv_multiplicity[i] * inputs[j];
59*8ecc9db9SJames Wright 
60*8ecc9db9SJames Wright     v[0 + 6][i] = (velo_prod[DIFF_FILTER_VELOCITY_SQUARED_XX][i] - Square(s.Y.velocity[0])) * inv_multiplicity[i];
61*8ecc9db9SJames Wright     v[1 + 6][i] = (velo_prod[DIFF_FILTER_VELOCITY_SQUARED_YY][i] - Square(s.Y.velocity[1])) * inv_multiplicity[i];
62*8ecc9db9SJames Wright     v[2 + 6][i] = (velo_prod[DIFF_FILTER_VELOCITY_SQUARED_ZZ][i] - Square(s.Y.velocity[2])) * inv_multiplicity[i];
63*8ecc9db9SJames Wright     v[3 + 6][i] = (velo_prod[DIFF_FILTER_VELOCITY_SQUARED_YZ][i] - s.Y.velocity[1] * s.Y.velocity[2]) * inv_multiplicity[i];
64*8ecc9db9SJames Wright     v[4 + 6][i] = (velo_prod[DIFF_FILTER_VELOCITY_SQUARED_XZ][i] - s.Y.velocity[0] * s.Y.velocity[2]) * inv_multiplicity[i];
65*8ecc9db9SJames Wright     v[5 + 6][i] = (velo_prod[DIFF_FILTER_VELOCITY_SQUARED_XY][i] - s.Y.velocity[0] * s.Y.velocity[1]) * inv_multiplicity[i];
66*8ecc9db9SJames Wright   }
67*8ecc9db9SJames Wright   return 0;
68*8ecc9db9SJames Wright }
69*8ecc9db9SJames Wright 
70*8ecc9db9SJames Wright CEED_QFUNCTION(ComputeSGS_DDAnisotropicTrainingDataNodal_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
71*8ecc9db9SJames Wright   return ComputeSGS_DDAnisotropicTrainingDataNodal(ctx, Q, in, out, STATEVAR_PRIMITIVE);
72*8ecc9db9SJames Wright }
73*8ecc9db9SJames Wright 
74*8ecc9db9SJames Wright #endif  // sgs_dd_training_h
75