xref: /honee/qfunctions/diff_flux_projection.h (revision b78d7c7d152a2530c4ff7c4fb0143fe9be02cbec)
18c85b835SJames Wright // SPDX-FileCopyrightText: Copyright (c) 2017-2024, HONEE contributors.
28c85b835SJames Wright // SPDX-License-Identifier: Apache-2.0 OR BSD-2-Clause
38c85b835SJames Wright 
4*3e17a7a1SJames Wright #include <ceed/types.h>
58c85b835SJames Wright 
68c85b835SJames Wright #include "utils.h"
78c85b835SJames Wright 
88c85b835SJames Wright // @brief QFunction to calculate the divergence of the diffusive flux
ComputeDivDiffusiveFluxGeneric(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out,const CeedInt dim,const CeedInt num_comps)98c85b835SJames Wright CEED_QFUNCTION_HELPER int ComputeDivDiffusiveFluxGeneric(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out, const CeedInt dim,
108c85b835SJames Wright                                                          const CeedInt num_comps) {
118c85b835SJames Wright   const CeedScalar *grad_q   = in[0];
128c85b835SJames Wright   const CeedScalar(*q_data)  = in[1];
138c85b835SJames Wright   CeedScalar(*v)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
148c85b835SJames Wright 
158c85b835SJames Wright   CeedPragmaSIMD for (CeedInt i = 0; i < Q; i++) {
168c85b835SJames Wright     CeedScalar dXdx[9];
178c85b835SJames Wright 
188c85b835SJames Wright     QdataUnpack_ND(dim, Q, i, q_data, NULL, dXdx);
198c85b835SJames Wright     CeedPragmaSIMD for (CeedInt n = 0; n < num_comps; n++) {
208c85b835SJames Wright       CeedScalar grad_qn[9];
218c85b835SJames Wright 
228c85b835SJames Wright       // Get gradient into dim x dim matrix form, with orientation [flux_direction][gradient_direction]
238c85b835SJames Wright       // Equivalent of GradUnpackN
248c85b835SJames Wright       const CeedInt offset = Q * n * dim;  // offset to reach nth component flux gradients
258c85b835SJames Wright       for (CeedInt g = 0; g < dim; g++) {
268c85b835SJames Wright         for (CeedInt f = 0; f < dim; f++) {
278c85b835SJames Wright           grad_qn[f * dim + g] = grad_q[offset + (Q * num_comps * dim) * g + Q * f + i];
288c85b835SJames Wright         }
298c85b835SJames Wright       }
308c85b835SJames Wright       v[n][i] = 0;
318c85b835SJames Wright       DivergenceND(grad_qn, dXdx, dim, &v[n][i]);
328c85b835SJames Wright     }
338c85b835SJames Wright   }
348c85b835SJames Wright   return 0;
358c85b835SJames Wright }
368c85b835SJames Wright 
ComputeDivDiffusiveFlux3D_4(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)378c85b835SJames Wright CEED_QFUNCTION(ComputeDivDiffusiveFlux3D_4)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
388c85b835SJames Wright   return ComputeDivDiffusiveFluxGeneric(ctx, Q, in, out, 3, 4);
398c85b835SJames Wright }
4040b78511SJames Wright 
ComputeDivDiffusiveFlux3D_1(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)4140b78511SJames Wright CEED_QFUNCTION(ComputeDivDiffusiveFlux3D_1)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
4240b78511SJames Wright   return ComputeDivDiffusiveFluxGeneric(ctx, Q, in, out, 3, 1);
4340b78511SJames Wright }
4440b78511SJames Wright 
ComputeDivDiffusiveFlux2D_1(void * ctx,CeedInt Q,const CeedScalar * const * in,CeedScalar * const * out)4540b78511SJames Wright CEED_QFUNCTION(ComputeDivDiffusiveFlux2D_1)(void *ctx, CeedInt Q, const CeedScalar *const *in, CeedScalar *const *out) {
4640b78511SJames Wright   return ComputeDivDiffusiveFluxGeneric(ctx, Q, in, out, 2, 1);
4740b78511SJames Wright }
48