xref: /honee/qfunctions/differential_filter.h (revision 682a9695a063c66e8637ac585865627931707085)
1 // Copyright (c) 2017-2023, Lawrence Livermore National Security, LLC and other CEED contributors.
2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3 //
4 // SPDX-License-Identifier: BSD-2-Clause
5 //
6 // This file is part of CEED:  http://github.com/ceed
7 //
8 /// @file
9 /// Implementation of differential filtering
10 
11 #include <ceed.h>
12 
13 #include "newtonian_state.h"
14 #include "newtonian_types.h"
15 #include "utils.h"
16 
17 enum DifferentialFilterComponent {
18   DIFF_FILTER_PRESSURE,
19   DIFF_FILTER_VELOCITY_X,
20   DIFF_FILTER_VELOCITY_Y,
21   DIFF_FILTER_VELOCITY_Z,
22   DIFF_FILTER_TEMPERATURE,
23   DIFF_FILTER_VELOCITY_SQUARED_XX,
24   DIFF_FILTER_VELOCITY_SQUARED_YY,
25   DIFF_FILTER_VELOCITY_SQUARED_ZZ,
26   DIFF_FILTER_VELOCITY_SQUARED_YZ,
27   DIFF_FILTER_VELOCITY_SQUARED_XZ,
28   DIFF_FILTER_VELOCITY_SQUARED_XY,
29   DIFF_FILTER_NUM_COMPONENTS,
30 };
31 
32 enum DifferentialFilterDampingFunction { DIFF_FILTER_DAMP_NONE, DIFF_FILTER_DAMP_VAN_DRIEST };
33 static const char *const DifferentialFilterDampingFunctions[] = {"none", "van_driest", "DifferentialFilterDampingFunction", "DIFF_FILTER_DAMP_",
34                                                                  NULL};
35 
36 typedef struct DifferentialFilterContext_ *DifferentialFilterContext;
37 struct DifferentialFilterContext_ {
38   bool                                   grid_based_width;
39   CeedScalar                             width_scaling[3];
40   CeedScalar                             kernel_scaling;
41   CeedScalar                             friction_length;
42   enum DifferentialFilterDampingFunction damping_function;
43   CeedScalar                             damping_constant;
44   struct NewtonianIdealGasContext_       gas;
45 };
46 
47 CEED_QFUNCTION_HELPER int DifferentialFilter_RHS(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, StateVariable state_var) {
48   const CeedScalar(*q)[CEED_Q_VLA]      = (const CeedScalar(*)[CEED_Q_VLA])in[0];
49   const CeedScalar(*q_data)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[1];
50   const CeedScalar(*x)[CEED_Q_VLA]      = (const CeedScalar(*)[CEED_Q_VLA])in[2];
51   CeedScalar(*v)[CEED_Q_VLA]            = (CeedScalar(*)[CEED_Q_VLA])out[0];
52 
53   DifferentialFilterContext context = (DifferentialFilterContext)ctx;
54   NewtonianIdealGasContext  gas     = &context->gas;
55 
56   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
57     const CeedScalar qi[5]  = {q[0][i], q[1][i], q[2][i], q[3][i], q[4][i]};
58     const CeedScalar x_i[3] = {x[0][i], x[1][i], x[2][i]};
59     const CeedScalar wdetJ  = q_data[0][i];
60     const State      s      = StateFromQ(gas, qi, x_i, state_var);
61 
62     v[DIFF_FILTER_PRESSURE][i]            = wdetJ * s.Y.pressure;
63     v[DIFF_FILTER_VELOCITY_X][i]          = wdetJ * s.Y.velocity[0];
64     v[DIFF_FILTER_VELOCITY_Y][i]          = wdetJ * s.Y.velocity[1];
65     v[DIFF_FILTER_VELOCITY_Z][i]          = wdetJ * s.Y.velocity[2];
66     v[DIFF_FILTER_TEMPERATURE][i]         = wdetJ * s.Y.temperature;
67     v[DIFF_FILTER_VELOCITY_SQUARED_XX][i] = wdetJ * s.Y.velocity[0] * s.Y.velocity[0];
68     v[DIFF_FILTER_VELOCITY_SQUARED_YY][i] = wdetJ * s.Y.velocity[1] * s.Y.velocity[1];
69     v[DIFF_FILTER_VELOCITY_SQUARED_ZZ][i] = wdetJ * s.Y.velocity[2] * s.Y.velocity[2];
70     v[DIFF_FILTER_VELOCITY_SQUARED_YZ][i] = wdetJ * s.Y.velocity[1] * s.Y.velocity[2];
71     v[DIFF_FILTER_VELOCITY_SQUARED_XZ][i] = wdetJ * s.Y.velocity[0] * s.Y.velocity[2];
72     v[DIFF_FILTER_VELOCITY_SQUARED_XY][i] = wdetJ * s.Y.velocity[0] * s.Y.velocity[1];
73   }
74   return 0;
75 }
76 
77 CEED_QFUNCTION(DifferentialFilter_RHS_Conserv)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
78   return DifferentialFilter_RHS(ctx, Q, in, out, STATEVAR_CONSERVATIVE);
79 }
80 
81 CEED_QFUNCTION(DifferentialFilter_RHS_Prim)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
82   return DifferentialFilter_RHS(ctx, Q, in, out, STATEVAR_PRIMITIVE);
83 }
84 
85 CEED_QFUNCTION_HELPER CeedScalar VanDriestWallDamping(const CeedScalar wall_dist_plus, const CeedScalar A_plus) {
86   return -expm1(-wall_dist_plus / A_plus);
87 }
88 
89 CEED_QFUNCTION_HELPER int DifferentialFilter_LHS_N(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, const CeedInt N) {
90   const CeedScalar(*q)[CEED_Q_VLA]          = (const CeedScalar(*)[CEED_Q_VLA])in[0];
91   const CeedScalar(*Grad_q)[CEED_Q_VLA]     = (const CeedScalar(*)[CEED_Q_VLA])in[1];
92   const CeedScalar(*A_ij_delta)[CEED_Q_VLA] = (const CeedScalar(*)[CEED_Q_VLA])in[2];
93   const CeedScalar(*x)[CEED_Q_VLA]          = (const CeedScalar(*)[CEED_Q_VLA])in[3];
94   const CeedScalar(*q_data)[CEED_Q_VLA]     = (const CeedScalar(*)[CEED_Q_VLA])in[4];
95   CeedScalar(*v)[CEED_Q_VLA]                = (CeedScalar(*)[CEED_Q_VLA])out[0];
96   CeedScalar(*Grad_v)[CEED_Q_VLA]           = (CeedScalar(*)[CEED_Q_VLA])out[1];
97 
98   DifferentialFilterContext context = (DifferentialFilterContext)ctx;
99 
100   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
101     CeedPragmaSIMD for (CeedInt j = 0; j < N; j++) {
102       const CeedScalar x_i[3]     = {x[0][i], x[1][i], x[2][i]};
103       const CeedScalar wdetJ      = q_data[0][i];
104       const CeedScalar dXdx[3][3] = {
105           {q_data[1][i], q_data[2][i], q_data[3][i]},
106           {q_data[4][i], q_data[5][i], q_data[6][i]},
107           {q_data[7][i], q_data[8][i], q_data[9][i]}
108       };
109 
110       CeedScalar Delta_ij[3][3] = {{0.}};
111       if (context->grid_based_width) {
112         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]};
113         const CeedScalar delta      = A_ij_delta[6][i];
114         ScaleN(km_A_ij, delta, 6);  // Dimensionalize the normalized anisotropy tensor
115         KMUnpack(km_A_ij, Delta_ij);
116       } else {
117         Delta_ij[0][0] = Delta_ij[1][1] = Delta_ij[2][2] = 1;
118       }
119 
120       CeedScalar scaling_matrix[3][3] = {{0}};
121       if (context->damping_function == DIFF_FILTER_DAMP_VAN_DRIEST) {
122         const CeedScalar damping_coeff = VanDriestWallDamping(x_i[1] / context->friction_length, context->damping_constant);
123         scaling_matrix[0][0]           = Max(1, damping_coeff * context->width_scaling[0]);
124         scaling_matrix[1][1]           = damping_coeff * context->width_scaling[1];
125         scaling_matrix[2][2]           = Max(1, damping_coeff * context->width_scaling[2]);
126       } else if (context->damping_function == DIFF_FILTER_DAMP_NONE) {
127         scaling_matrix[0][0] = context->width_scaling[0];
128         scaling_matrix[1][1] = context->width_scaling[1];
129         scaling_matrix[2][2] = context->width_scaling[2];
130       }
131 
132       CeedScalar scaled_Delta_ij[3][3] = {{0.}};
133       MatMat3(scaling_matrix, Delta_ij, CEED_NOTRANSPOSE, CEED_NOTRANSPOSE, scaled_Delta_ij);
134       CopyMat3(scaled_Delta_ij, Delta_ij);
135 
136       CeedScalar alpha_ij[3][3] = {{0.}};
137       MatMat3(Delta_ij, Delta_ij, CEED_NOTRANSPOSE, CEED_NOTRANSPOSE, alpha_ij);
138       ScaleN((CeedScalar *)alpha_ij, context->kernel_scaling, 9);
139 
140       v[j][i] = wdetJ * q[j][i];
141       CeedScalar dq[3], dq_dXdx[3] = {0.}, dq_dXdx_a[3] = {0.};
142       for (int k = 0; k < 3; k++) {
143         dq[k] = Grad_q[0 * N + j][i] * dXdx[0][k] + Grad_q[1 * N + j][i] * dXdx[1][k] + Grad_q[2 * N + j][i] * dXdx[2][k];
144       }
145       MatVec3(dXdx, dq, CEED_NOTRANSPOSE, dq_dXdx);
146       MatVec3(alpha_ij, dq_dXdx, CEED_NOTRANSPOSE, dq_dXdx_a);
147       for (int k = 0; k < 3; k++) {
148         Grad_v[k * N + j][i] = wdetJ * dq_dXdx_a[k];
149       }
150     }
151   }
152   return 0;
153 }
154 
155 CEED_QFUNCTION(DifferentialFilter_LHS_1)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
156   return DifferentialFilter_LHS_N(ctx, Q, in, out, 1);
157 }
158 
159 CEED_QFUNCTION(DifferentialFilter_LHS_5)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
160   return DifferentialFilter_LHS_N(ctx, Q, in, out, 5);
161 }
162 
163 CEED_QFUNCTION(DifferentialFilter_LHS_11)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
164   return DifferentialFilter_LHS_N(ctx, Q, in, out, 11);
165 }
166