libceed-sys 0.12.0

Low-level bindings for libCEED library.
Documentation
// Copyright (c) 2017-2022, 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 "../kernel-defines.hpp"

const char *occa_simplex_basis_cpu_function_source = STRINGIFY_SOURCE(

    @directive("#define SIMPLEX_FUNCTION(FUNCTION_NAME) simplex_ ## DIM ## d_ ## FUNCTION_NAME ## _Q ## Q ## _P ## P")

        inline void SIMPLEX_FUNCTION(interpElement)(const CeedScalar *B @dim(P, Q), const CeedScalar *Ue, CeedScalar *Ve) {
          for (int q = 0; q < Q; ++q) {
            CeedScalar v = 0;
            for (int p = 0; p < P; ++p) {
              v += B(p, q) * Ue[p];
            }
            Ve[q] = v;
          }
        }

    inline void SIMPLEX_FUNCTION(interpElementTranspose)(const CeedScalar *B @dim(P, Q), const CeedScalar *Ue, CeedScalar *Ve) {
      for (int p = 0; p < P; ++p) {
        CeedScalar v = 0;
        for (int q = 0; q < Q; ++q) {
          v += B(p, q) * Ue[q];
        }
        Ve[p] = v;
      }
    }

    inline void SIMPLEX_FUNCTION(gradElement)(const CeedScalar *Bx @dim(P, Q, DIM), const CeedScalar *Ue, CeedScalar *Ve, ) {
      for (int q = 0; q < Q; ++q) {
        CeedScalar v[DIM];
        for (int dim = 0; dim < DIM; ++dim) {
          v[dim] = 0;
        }

        for (int p = 0; p < P; ++p) {
          const CeedScalar u = Ue[p];
          for (int dim = 0; dim < DIM; ++dim) {
            v[dim] += Bx(p, q, dim) * u;
          }
        }

        for (int dim = 0; dim < DIM; ++dim) {
          Ve[dim * Q + q] = v[dim];
        }
      }
    }

    inline void SIMPLEX_FUNCTION(gradElementTranspose)(const CeedScalar *Bx @dim(P, Q, DIM), const CeedScalar *Ue, CeedScalar *Ve) {
      for (int p = 0; p < P; ++p) {
        CeedScalar v = 0;
        for (int dim = 0; dim < DIM; ++dim) {
          for (int q = 0; q < Q; ++q) {
            v += Bx(p, q, dim) * Ue[dim * Q + q];
          }
        }
        Ve[p] = v;
      }
    }

    inline void SIMPLEX_FUNCTION(weightElement)(const CeedScalar *qWeights, CeedScalar *We) {
      for (int q = 0; q < Q; ++q) {
        We[q] = qWeights[q];
      }
    }

);

const char *occa_simplex_basis_cpu_kernel_source = STRINGIFY_SOURCE(

    @kernel void interp(const CeedInt elementCount, const CeedScalar *B, const CeedScalar *U, CeedScalar *V) {
      for (int element = 0; element < elementCount; ++element; @outer) {
        for (int component = 0; component < BASIS_COMPONENT_COUNT; ++component; @inner) {
          if (!TRANSPOSE) {
            const CeedScalar *Ue @dim(P, BASIS_COMPONENT_COUNT, elementCount) = U;
            CeedScalar       *Ve @dim(Q, elementCount, BASIS_COMPONENT_COUNT) = V;

            SIMPLEX_FUNCTION(interpElement)(B, &Ue(0, component, element), &Ve(0, element, component));
          } else {
            const CeedScalar *Ue @dim(Q, elementCount, BASIS_COMPONENT_COUNT) = U;
            CeedScalar       *Ve @dim(P, BASIS_COMPONENT_COUNT, elementCount) = V;

            SIMPLEX_FUNCTION(interpElementTranspose)(B, &Ue(0, element, component), &Ve(0, component, element));
          }
        }
      }
    }

    @kernel void grad(const CeedInt elementCount, const CeedScalar *Bx, const CeedScalar *U, CeedScalar *V) {
      for (int element = 0; element < elementCount; ++element; @outer) {
        for (int component = 0; component < BASIS_COMPONENT_COUNT; ++component; @inner) {
          if (!TRANSPOSE) {
            const CeedScalar *Ue @dim(P, BASIS_COMPONENT_COUNT, elementCount)       = U;
            CeedScalar       *_Ve @dim(Q, elementCount, BASIS_COMPONENT_COUNT, DIM) = V;

            CeedScalar Ve[DIM][Q];
            for (int dim = 0; dim < DIM; ++dim) {
              for (int q = 0; q < Q; ++q) {
                Ve[dim][q] = _Ve(q, element, component, dim);
              }
            }

            SIMPLEX_FUNCTION(gradElement)(Bx, &Ue(0, component, element), (CeedScalar *)Ve);

            for (int dim = 0; dim < DIM; ++dim) {
              for (int q = 0; q < Q; ++q) {
                _Ve(q, element, component, dim) = Ve[dim][q];
              }
            }
          } else {
            const CeedScalar *_Ue @dim(Q, elementCount, BASIS_COMPONENT_COUNT, DIM) = U;
            CeedScalar       *Ve @dim(P, BASIS_COMPONENT_COUNT, elementCount)       = V;

            CeedScalar Ue[DIM][Q];
            for (int dim = 0; dim < DIM; ++dim) {
              for (int q = 0; q < Q; ++q) {
                Ue[dim][q] = _Ue(q, element, component, dim);
              }
            }

            SIMPLEX_FUNCTION(gradElementTranspose)(Bx, (CeedScalar *)Ue, &Ve(0, component, element));
          }
        }
      }
    }

    @kernel void weight(const CeedInt elementCount, const CeedScalar *qWeights, CeedScalar *W @dim(Q, elementCount)) {
      @tile(32, @outer, @inner) for (int element = 0; element < elementCount; ++element) {
        SIMPLEX_FUNCTION(weightElement)(qWeights, &W(0, element));
      }
    }

);