// Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
// All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
//
// SPDX-License-Identifier: BSD-2-Clause
//
// This file is part of CEED:  http://github.com/ceed

#include <ceed.h>

// Interpolation matrices for cell-to-face of Q1 hexahedral element onto it's "5" face (in PETSc)
// Nodes are at Gauss-Lobatto points and quadrature points are Gauss, all over [-1,1] domain range
const CeedScalar Q1_interp_gauss[4][8] = {
    {0.62200846792814612,  0, 0.16666666666666669,  0, 0.16666666666666669,  0, 0.044658198738520463, 0},
    {0.16666666666666669,  0, 0.62200846792814612,  0, 0.044658198738520463, 0, 0.16666666666666669,  0},
    {0.16666666666666669,  0, 0.044658198738520463, 0, 0.62200846792814612,  0, 0.16666666666666669,  0},
    {0.044658198738520463, 0, 0.16666666666666669,  0, 0.16666666666666669,  0, 0.62200846792814612,  0}
};
const CeedScalar Q1_grad_gauss[3][4][8] = {
    {{-0.31100423396407312, 0.31100423396407312, -0.083333333333333343, 0.083333333333333343, -0.083333333333333343, 0.083333333333333343,
      -0.022329099369260232, 0.022329099369260232},
     {-0.083333333333333343, 0.083333333333333343, -0.31100423396407312, 0.31100423396407312, -0.022329099369260232, 0.022329099369260232,
      -0.083333333333333343, 0.083333333333333343},
     {-0.083333333333333343, 0.083333333333333343, -0.022329099369260232, 0.022329099369260232, -0.31100423396407312, 0.31100423396407312,
      -0.083333333333333343, 0.083333333333333343},
     {-0.022329099369260232, 0.022329099369260232, -0.083333333333333343, 0.083333333333333343, -0.083333333333333343, 0.083333333333333343,
      -0.31100423396407312, 0.31100423396407312}                                                       },
    {{-0.39433756729740643, 0, 0.39433756729740643, 0, -0.10566243270259357, 0, 0.10566243270259357, 0},
     {-0.39433756729740643, 0, 0.39433756729740643, 0, -0.10566243270259357, 0, 0.10566243270259357, 0},
     {-0.10566243270259357, 0, 0.10566243270259357, 0, -0.39433756729740643, 0, 0.39433756729740643, 0},
     {-0.10566243270259357, 0, 0.10566243270259357, 0, -0.39433756729740643, 0, 0.39433756729740643, 0}},
    {{-0.39433756729740643, 0, -0.10566243270259357, 0, 0.39433756729740643, 0, 0.10566243270259357, 0},
     {-0.10566243270259357, 0, -0.39433756729740643, 0, 0.10566243270259357, 0, 0.39433756729740643, 0},
     {-0.39433756729740643, 0, -0.10566243270259357, 0, 0.39433756729740643, 0, 0.10566243270259357, 0},
     {-0.10566243270259357, 0, -0.39433756729740643, 0, 0.10566243270259357, 0, 0.39433756729740643, 0}}
};

const CeedScalar Q1_interp_gauss_lobatto[4][8] = {
    {1, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 1, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 1, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 1, 0}
};
/* clang-format off */
const CeedScalar Q1_grad_gauss_lobatto[3][4][8] = {
    {{-0.5,  0.5, 0,    0,   0,    0,   0,    0},
      {0,    0,   -0.5, 0.5, 0,    0,   0,    0},
      {0,    0,   0,    0,   -0.5, 0.5, 0,    0},
      {0,    0,   0,    0,   0,    0,   -0.5, 0.5}},
    {{-0.5,  0,   0.5,  0,   0,    0,   0,    0},
      {-0.5, 0,   0.5,  0,   0,    0,   0,    0},
      {0,    0,   0,    0,   -0.5, 0,   0.5,  0},
      {0,    0,   0,    0,   -0.5, 0,   0.5,  0}},
    {{-0.5,  0,   0,    0,   0.5,  0,   0,    0},
      {0,    0,   -0.5, 0,   0,    0,   0.5,  0},
      {-0.5, 0,   0,    0,   0.5,  0,   0,    0},
      {0,    0,   -0.5, 0,   0,    0,   0.5,  0}}
};
/* clang-format on */

static void GetCellToFaceTabulation(CeedQuadMode quad_mode, CeedInt *P, CeedInt *Q, const CeedScalar **interp, const CeedScalar **grad) {
  if (P) *P = 8;
  if (Q) *Q = 4;

  if (quad_mode == CEED_GAUSS) {
    *interp = (const CeedScalar *)Q1_interp_gauss;
    *grad   = (const CeedScalar *)Q1_grad_gauss;
  }
  if (quad_mode == CEED_GAUSS_LOBATTO) {
    *interp = (const CeedScalar *)Q1_interp_gauss_lobatto;
    *grad   = (const CeedScalar *)Q1_grad_gauss_lobatto;
  }
}
