xref: /libCEED/rust/libceed-sys/c-src/backends/ref/ceed-ref-restriction.c (revision 61a27d74d4dddda1a6f7c53fa8f97daed16bb150)
13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
321617c04Sjeremylt //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
521617c04Sjeremylt //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
721617c04Sjeremylt 
849aac155SJeremy L Thompson #include <ceed.h>
9ec3da8bcSJed Brown #include <ceed/backend.h>
103d576824SJeremy L Thompson #include <stdbool.h>
11fcbe8c06SSebastian Grimberg #include <stdlib.h>
123d576824SJeremy L Thompson #include <string.h>
132b730f8bSJeremy L Thompson 
1421617c04Sjeremylt #include "ceed-ref.h"
1521617c04Sjeremylt 
16f10650afSjeremylt //------------------------------------------------------------------------------
17f10650afSjeremylt // Core ElemRestriction Apply Code
18f10650afSjeremylt //------------------------------------------------------------------------------
1994648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyStridedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
2094648b7dSSebastian Grimberg                                                                       CeedInt start, CeedInt stop, CeedInt num_elem, CeedInt elem_size,
2194648b7dSSebastian Grimberg                                                                       CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
2294648b7dSSebastian Grimberg   // No offsets provided, identity restriction
23d1d35e2fSjeremylt   bool has_backend_strides;
242b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides));
25d1d35e2fSjeremylt   if (has_backend_strides) {
26d1d35e2fSjeremylt     // CPU backend strides are {1, elem_size, elem_size*num_comp}
277f90ec76Sjeremylt     // This if branch is left separate to allow better inlining
282b730f8bSJeremy L Thompson     for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
292b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
302b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
312b730f8bSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
322b730f8bSJeremy L Thompson             vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
332b730f8bSJeremy L Thompson                 uu[n + k * elem_size + CeedIntMin(e + j, num_elem - 1) * elem_size * num_comp];
342b730f8bSJeremy L Thompson           }
352b730f8bSJeremy L Thompson         }
362b730f8bSJeremy L Thompson       }
372b730f8bSJeremy L Thompson     }
387f90ec76Sjeremylt   } else {
397f90ec76Sjeremylt     // User provided strides
407f90ec76Sjeremylt     CeedInt strides[3];
412b730f8bSJeremy L Thompson     CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides));
422b730f8bSJeremy L Thompson     for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
432b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
442b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
452b730f8bSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
462b730f8bSJeremy L Thompson             vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
472b730f8bSJeremy L Thompson                 uu[n * strides[0] + k * strides[1] + CeedIntMin(e + j, num_elem - 1) * strides[2]];
482b730f8bSJeremy L Thompson           }
492b730f8bSJeremy L Thompson         }
502b730f8bSJeremy L Thompson       }
512b730f8bSJeremy L Thompson     }
527509a596Sjeremylt   }
5394648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
5494648b7dSSebastian Grimberg }
5594648b7dSSebastian Grimberg 
56*61a27d74SSebastian Grimberg static inline int CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
5794648b7dSSebastian Grimberg                                                                        const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
5894648b7dSSebastian Grimberg                                                                        CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
59fcbe8c06SSebastian Grimberg   // Default restriction with offsets
6094648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
6194648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
622b730f8bSJeremy L Thompson   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
632b730f8bSJeremy L Thompson     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
642b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * blk_size; i++) {
650c73c039SSebastian Grimberg         vv[elem_size * (k * blk_size + e * num_comp) + i - v_offset] = uu[impl->offsets[i + e * elem_size] + k * comp_stride];
66fcbe8c06SSebastian Grimberg       }
67fcbe8c06SSebastian Grimberg     }
68fcbe8c06SSebastian Grimberg   }
6994648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
7094648b7dSSebastian Grimberg }
7194648b7dSSebastian Grimberg 
7294648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyOrientedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
7394648b7dSSebastian Grimberg                                                                        const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
7494648b7dSSebastian Grimberg                                                                        CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
75fcbe8c06SSebastian Grimberg   // Restriction with orientations
7694648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
7794648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
78fcbe8c06SSebastian Grimberg   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
79fcbe8c06SSebastian Grimberg     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
80fcbe8c06SSebastian Grimberg       CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * blk_size; i++) {
810c73c039SSebastian Grimberg         vv[elem_size * (k * blk_size + e * num_comp) + i - v_offset] =
827c1dbaffSSebastian Grimberg             uu[impl->offsets[i + e * elem_size] + k * comp_stride] * (impl->orients[i + e * elem_size] ? -1.0 : 1.0);
83fcbe8c06SSebastian Grimberg       }
84fcbe8c06SSebastian Grimberg     }
85fcbe8c06SSebastian Grimberg   }
8694648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
8794648b7dSSebastian Grimberg }
8894648b7dSSebastian Grimberg 
8994648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
9094648b7dSSebastian Grimberg                                                                            const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
9194648b7dSSebastian Grimberg                                                                            CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu,
9294648b7dSSebastian Grimberg                                                                            CeedScalar *vv) {
9377d1c127SSebastian Grimberg   // Restriction with tridiagonal transformation
9494648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
9594648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
96fcbe8c06SSebastian Grimberg   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
97fcbe8c06SSebastian Grimberg     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
980c73c039SSebastian Grimberg       CeedInt n = 0;
990c73c039SSebastian Grimberg       CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
1000c73c039SSebastian Grimberg         vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
1010c73c039SSebastian Grimberg             uu[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] *
1027c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size] +
1030c73c039SSebastian Grimberg             uu[impl->offsets[j + (n + 1) * blk_size + e * elem_size] + k * comp_stride] *
1047c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n + 2) * blk_size + e * 3 * elem_size];
1050c73c039SSebastian Grimberg       }
1060c73c039SSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
1070c73c039SSebastian Grimberg         CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
1080c73c039SSebastian Grimberg           vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
1090c73c039SSebastian Grimberg               uu[impl->offsets[j + (n - 1) * blk_size + e * elem_size] + k * comp_stride] *
1107c1dbaffSSebastian Grimberg                   impl->curl_orients[j + (3 * n + 0) * blk_size + e * 3 * elem_size] +
1110c73c039SSebastian Grimberg               uu[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] *
1127c1dbaffSSebastian Grimberg                   impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size] +
1130c73c039SSebastian Grimberg               uu[impl->offsets[j + (n + 1) * blk_size + e * elem_size] + k * comp_stride] *
1147c1dbaffSSebastian Grimberg                   impl->curl_orients[j + (3 * n + 2) * blk_size + e * 3 * elem_size];
1150c73c039SSebastian Grimberg         }
1160c73c039SSebastian Grimberg       }
1170c73c039SSebastian Grimberg       CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
1180c73c039SSebastian Grimberg         vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
1190c73c039SSebastian Grimberg             uu[impl->offsets[j + (n - 1) * blk_size + e * elem_size] + k * comp_stride] *
1207c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n + 0) * blk_size + e * 3 * elem_size] +
1210c73c039SSebastian Grimberg             uu[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] *
1227c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size];
1232b730f8bSJeremy L Thompson       }
1242b730f8bSJeremy L Thompson     }
1252b730f8bSJeremy L Thompson   }
1260c73c039SSebastian Grimberg   return CEED_ERROR_SUCCESS;
127fcbe8c06SSebastian Grimberg }
1280c73c039SSebastian Grimberg 
12994648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedUnsignedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp,
13094648b7dSSebastian Grimberg                                                                                    const CeedInt blk_size, const CeedInt comp_stride, CeedInt start,
13194648b7dSSebastian Grimberg                                                                                    CeedInt stop, CeedInt num_elem, CeedInt elem_size,
13294648b7dSSebastian Grimberg                                                                                    CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
13394648b7dSSebastian Grimberg   // Restriction with (unsigned) tridiagonal transformation
1340c73c039SSebastian Grimberg   CeedElemRestriction_Ref *impl;
1350c73c039SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
1367c1dbaffSSebastian Grimberg   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
1377c1dbaffSSebastian Grimberg     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1387c1dbaffSSebastian Grimberg       CeedInt n = 0;
1397c1dbaffSSebastian Grimberg       CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
1407c1dbaffSSebastian Grimberg         vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
1417c1dbaffSSebastian Grimberg             uu[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] *
1427c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size]) +
1437c1dbaffSSebastian Grimberg             uu[impl->offsets[j + (n + 1) * blk_size + e * elem_size] + k * comp_stride] *
1447c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n + 2) * blk_size + e * 3 * elem_size]);
1457c1dbaffSSebastian Grimberg       }
1467c1dbaffSSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
1477c1dbaffSSebastian Grimberg         CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
1487c1dbaffSSebastian Grimberg           vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
1497c1dbaffSSebastian Grimberg               uu[impl->offsets[j + (n - 1) * blk_size + e * elem_size] + k * comp_stride] *
1507c1dbaffSSebastian Grimberg                   abs(impl->curl_orients[j + (3 * n + 0) * blk_size + e * 3 * elem_size]) +
1517c1dbaffSSebastian Grimberg               uu[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] *
1527c1dbaffSSebastian Grimberg                   abs(impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size]) +
1537c1dbaffSSebastian Grimberg               uu[impl->offsets[j + (n + 1) * blk_size + e * elem_size] + k * comp_stride] *
1547c1dbaffSSebastian Grimberg                   abs(impl->curl_orients[j + (3 * n + 2) * blk_size + e * 3 * elem_size]);
1557c1dbaffSSebastian Grimberg         }
1567c1dbaffSSebastian Grimberg       }
1577c1dbaffSSebastian Grimberg       CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
1587c1dbaffSSebastian Grimberg         vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
1597c1dbaffSSebastian Grimberg             uu[impl->offsets[j + (n - 1) * blk_size + e * elem_size] + k * comp_stride] *
1607c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n + 0) * blk_size + e * 3 * elem_size]) +
1617c1dbaffSSebastian Grimberg             uu[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] *
1627c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size]);
1637c1dbaffSSebastian Grimberg       }
1647c1dbaffSSebastian Grimberg     }
1657c1dbaffSSebastian Grimberg   }
1667c1dbaffSSebastian Grimberg   return CEED_ERROR_SUCCESS;
1677c1dbaffSSebastian Grimberg }
1687c1dbaffSSebastian Grimberg 
16994648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyStridedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
17094648b7dSSebastian Grimberg                                                                     CeedInt start, CeedInt stop, CeedInt num_elem, CeedInt elem_size,
17194648b7dSSebastian Grimberg                                                                     CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
17294648b7dSSebastian Grimberg   // No offsets provided, identity restriction
173d1d35e2fSjeremylt   bool has_backend_strides;
1742b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides));
175d1d35e2fSjeremylt   if (has_backend_strides) {
176d1d35e2fSjeremylt     // CPU backend strides are {1, elem_size, elem_size*num_comp}
1777f90ec76Sjeremylt     // This if brach is left separate to allow better inlining
1782b730f8bSJeremy L Thompson     for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
1792b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1802b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
1812b730f8bSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) {
18294648b7dSSebastian Grimberg             vv[n + k * elem_size + (e + j) * elem_size * num_comp] += uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset];
1832b730f8bSJeremy L Thompson           }
1842b730f8bSJeremy L Thompson         }
1852b730f8bSJeremy L Thompson       }
1862b730f8bSJeremy L Thompson     }
1877f90ec76Sjeremylt   } else {
1887f90ec76Sjeremylt     // User provided strides
1897f90ec76Sjeremylt     CeedInt strides[3];
1902b730f8bSJeremy L Thompson     CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides));
1912b730f8bSJeremy L Thompson     for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
1922b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1932b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
1942b730f8bSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) {
1952b730f8bSJeremy L Thompson             vv[n * strides[0] + k * strides[1] + (e + j) * strides[2]] +=
1962b730f8bSJeremy L Thompson                 uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset];
1972b730f8bSJeremy L Thompson           }
1982b730f8bSJeremy L Thompson         }
1992b730f8bSJeremy L Thompson       }
2002b730f8bSJeremy L Thompson     }
201523b8ea0Sjeremylt   }
20294648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
20394648b7dSSebastian Grimberg }
20494648b7dSSebastian Grimberg 
205*61a27d74SSebastian Grimberg static inline int CeedElemRestrictionApplyStandardTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
20694648b7dSSebastian Grimberg                                                                      const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
20794648b7dSSebastian Grimberg                                                                      CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
208fcbe8c06SSebastian Grimberg   // Default restriction with offsets
20994648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
21094648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
2112b730f8bSJeremy L Thompson   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
2122b730f8bSJeremy L Thompson     for (CeedInt k = 0; k < num_comp; k++) {
2132b730f8bSJeremy L Thompson       for (CeedInt i = 0; i < elem_size * blk_size; i += blk_size) {
2148d94b059Sjeremylt         // Iteration bound set to discard padding elements
2152b730f8bSJeremy L Thompson         for (CeedInt j = i; j < i + CeedIntMin(blk_size, num_elem - e); j++) {
2160c73c039SSebastian Grimberg           vv[impl->offsets[j + e * elem_size] + k * comp_stride] += uu[elem_size * (k * blk_size + e * num_comp) + j - v_offset];
217fcbe8c06SSebastian Grimberg         }
218fcbe8c06SSebastian Grimberg       }
219fcbe8c06SSebastian Grimberg     }
220fcbe8c06SSebastian Grimberg   }
22194648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
22294648b7dSSebastian Grimberg }
22394648b7dSSebastian Grimberg 
22494648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyOrientedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
22594648b7dSSebastian Grimberg                                                                      const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
22694648b7dSSebastian Grimberg                                                                      CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
227fcbe8c06SSebastian Grimberg   // Restriction with orientations
22894648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
22994648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
230fcbe8c06SSebastian Grimberg   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
231fcbe8c06SSebastian Grimberg     for (CeedInt k = 0; k < num_comp; k++) {
232fcbe8c06SSebastian Grimberg       for (CeedInt i = 0; i < elem_size * blk_size; i += blk_size) {
233fcbe8c06SSebastian Grimberg         // Iteration bound set to discard padding elements
234fcbe8c06SSebastian Grimberg         for (CeedInt j = i; j < i + CeedIntMin(blk_size, num_elem - e); j++) {
235f30b1135SSebastian Grimberg           vv[impl->offsets[j + e * elem_size] + k * comp_stride] +=
2367c1dbaffSSebastian Grimberg               uu[elem_size * (k * blk_size + e * num_comp) + j - v_offset] * (impl->orients[j + e * elem_size] ? -1.0 : 1.0);
237fcbe8c06SSebastian Grimberg         }
238fcbe8c06SSebastian Grimberg       }
239fcbe8c06SSebastian Grimberg     }
240fcbe8c06SSebastian Grimberg   }
24194648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
24294648b7dSSebastian Grimberg }
24394648b7dSSebastian Grimberg 
24494648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
24594648b7dSSebastian Grimberg                                                                          const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
24694648b7dSSebastian Grimberg                                                                          CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
24777d1c127SSebastian Grimberg   // Restriction with tridiagonal transformation
24894648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
24994648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
250fcbe8c06SSebastian Grimberg   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
251fcbe8c06SSebastian Grimberg     for (CeedInt k = 0; k < num_comp; k++) {
252fcbe8c06SSebastian Grimberg       // Iteration bound set to discard padding elements
2530c73c039SSebastian Grimberg       CeedInt blk_end = CeedIntMin(blk_size, num_elem - e), n = 0;
2540c73c039SSebastian Grimberg       for (CeedInt j = 0; j < blk_end; j++) {
2550c73c039SSebastian Grimberg         vv[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] +=
2560c73c039SSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] *
2577c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size] +
2580c73c039SSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n + 1) * blk_size + j - v_offset] *
2597c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n + 3) * blk_size + e * 3 * elem_size];
2600c73c039SSebastian Grimberg       }
2610c73c039SSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
2620c73c039SSebastian Grimberg         for (CeedInt j = 0; j < blk_end; j++) {
2630c73c039SSebastian Grimberg           vv[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] +=
2640c73c039SSebastian Grimberg               uu[e * elem_size * num_comp + (k * elem_size + n - 1) * blk_size + j - v_offset] *
2657c1dbaffSSebastian Grimberg                   impl->curl_orients[j + (3 * n - 1) * blk_size + e * 3 * elem_size] +
2660c73c039SSebastian Grimberg               uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] *
2677c1dbaffSSebastian Grimberg                   impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size] +
2680c73c039SSebastian Grimberg               uu[e * elem_size * num_comp + (k * elem_size + n + 1) * blk_size + j - v_offset] *
2697c1dbaffSSebastian Grimberg                   impl->curl_orients[j + (3 * n + 3) * blk_size + e * 3 * elem_size];
2700c73c039SSebastian Grimberg         }
2710c73c039SSebastian Grimberg       }
2720c73c039SSebastian Grimberg       for (CeedInt j = 0; j < blk_end; j++) {
2730c73c039SSebastian Grimberg         vv[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] +=
2740c73c039SSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n - 1) * blk_size + j - v_offset] *
2757c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n - 1) * blk_size + e * 3 * elem_size] +
2760c73c039SSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] *
2777c1dbaffSSebastian Grimberg                 impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size];
27821617c04Sjeremylt       }
279b435c5a6Srezgarshakeri     }
2802b730f8bSJeremy L Thompson   }
281e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
28221617c04Sjeremylt }
28321617c04Sjeremylt 
28494648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedUnsignedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp,
28594648b7dSSebastian Grimberg                                                                                  const CeedInt blk_size, const CeedInt comp_stride, CeedInt start,
28694648b7dSSebastian Grimberg                                                                                  CeedInt stop, CeedInt num_elem, CeedInt elem_size, CeedInt v_offset,
28794648b7dSSebastian Grimberg                                                                                  const CeedScalar *uu, CeedScalar *vv) {
28894648b7dSSebastian Grimberg   // Restriction with (unsigned) tridiagonal transformation
2897c1dbaffSSebastian Grimberg   CeedElemRestriction_Ref *impl;
2907c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
2917c1dbaffSSebastian Grimberg   for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
2927c1dbaffSSebastian Grimberg     for (CeedInt k = 0; k < num_comp; k++) {
2937c1dbaffSSebastian Grimberg       // Iteration bound set to discard padding elements
2947c1dbaffSSebastian Grimberg       CeedInt blk_end = CeedIntMin(blk_size, num_elem - e), n = 0;
2957c1dbaffSSebastian Grimberg       for (CeedInt j = 0; j < blk_end; j++) {
2967c1dbaffSSebastian Grimberg         vv[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] +=
2977c1dbaffSSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] *
2987c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size]) +
2997c1dbaffSSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n + 1) * blk_size + j - v_offset] *
3007c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n + 3) * blk_size + e * 3 * elem_size]);
3017c1dbaffSSebastian Grimberg       }
3027c1dbaffSSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
3037c1dbaffSSebastian Grimberg         for (CeedInt j = 0; j < blk_end; j++) {
3047c1dbaffSSebastian Grimberg           vv[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] +=
3057c1dbaffSSebastian Grimberg               uu[e * elem_size * num_comp + (k * elem_size + n - 1) * blk_size + j - v_offset] *
3067c1dbaffSSebastian Grimberg                   abs(impl->curl_orients[j + (3 * n - 1) * blk_size + e * 3 * elem_size]) +
3077c1dbaffSSebastian Grimberg               uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] *
3087c1dbaffSSebastian Grimberg                   abs(impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size]) +
3097c1dbaffSSebastian Grimberg               uu[e * elem_size * num_comp + (k * elem_size + n + 1) * blk_size + j - v_offset] *
3107c1dbaffSSebastian Grimberg                   abs(impl->curl_orients[j + (3 * n + 3) * blk_size + e * 3 * elem_size]);
3117c1dbaffSSebastian Grimberg         }
3127c1dbaffSSebastian Grimberg       }
3137c1dbaffSSebastian Grimberg       for (CeedInt j = 0; j < blk_end; j++) {
3147c1dbaffSSebastian Grimberg         vv[impl->offsets[j + n * blk_size + e * elem_size] + k * comp_stride] +=
3157c1dbaffSSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n - 1) * blk_size + j - v_offset] *
3167c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n - 1) * blk_size + e * 3 * elem_size]) +
3177c1dbaffSSebastian Grimberg             uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] *
3187c1dbaffSSebastian Grimberg                 abs(impl->curl_orients[j + (3 * n + 1) * blk_size + e * 3 * elem_size]);
3197c1dbaffSSebastian Grimberg       }
3207c1dbaffSSebastian Grimberg     }
3217c1dbaffSSebastian Grimberg   }
3227c1dbaffSSebastian Grimberg   return CEED_ERROR_SUCCESS;
3237c1dbaffSSebastian Grimberg }
3247c1dbaffSSebastian Grimberg 
32594648b7dSSebastian Grimberg static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
32694648b7dSSebastian Grimberg                                                     CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients,
32794648b7dSSebastian Grimberg                                                     CeedVector u, CeedVector v, CeedRequest *request) {
3287c1dbaffSSebastian Grimberg   const CeedScalar *uu;
3297c1dbaffSSebastian Grimberg   CeedScalar       *vv;
3307c1dbaffSSebastian Grimberg   CeedInt           num_elem, elem_size, v_offset;
3317c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem));
3327c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size));
3337c1dbaffSSebastian Grimberg   v_offset = start * blk_size * elem_size * num_comp;
3347c1dbaffSSebastian Grimberg   CeedRestrictionType rstr_type;
3357c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(r, &rstr_type));
3367c1dbaffSSebastian Grimberg 
33794648b7dSSebastian Grimberg   CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu));
33894648b7dSSebastian Grimberg   if (t_mode == CEED_TRANSPOSE) {
33994648b7dSSebastian Grimberg     // Sum into for transpose mode, E-vector to L-vector
34094648b7dSSebastian Grimberg     CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_HOST, &vv));
34194648b7dSSebastian Grimberg   } else {
34294648b7dSSebastian Grimberg     // Overwrite for notranspose mode, L-vector to E-vector
34394648b7dSSebastian Grimberg     CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_HOST, &vv));
34494648b7dSSebastian Grimberg   }
34594648b7dSSebastian Grimberg   if (t_mode == CEED_TRANSPOSE) {
3467c1dbaffSSebastian Grimberg     // Restriction from E-vector to L-vector
3477c1dbaffSSebastian Grimberg     // Performing v += r^T * u
3487c1dbaffSSebastian Grimberg     // uu has shape [elem_size, num_comp, num_elem], row-major
3497c1dbaffSSebastian Grimberg     // vv has shape [nnodes, num_comp]
3507c1dbaffSSebastian Grimberg     // Sum into for transpose mode
3517c1dbaffSSebastian Grimberg     switch (rstr_type) {
3527c1dbaffSSebastian Grimberg       case CEED_RESTRICTION_STRIDED:
35394648b7dSSebastian Grimberg         CeedElemRestrictionApplyStridedTranspose_Ref_Core(r, num_comp, blk_size, start, stop, num_elem, elem_size, v_offset, uu, vv);
35494648b7dSSebastian Grimberg         break;
355*61a27d74SSebastian Grimberg       case CEED_RESTRICTION_STANDARD:
356*61a27d74SSebastian Grimberg         CeedElemRestrictionApplyStandardTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
35794648b7dSSebastian Grimberg         break;
3587c1dbaffSSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
35994648b7dSSebastian Grimberg         if (use_signs) {
36094648b7dSSebastian Grimberg           CeedElemRestrictionApplyOrientedTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
36194648b7dSSebastian Grimberg         } else {
362*61a27d74SSebastian Grimberg           CeedElemRestrictionApplyStandardTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
36394648b7dSSebastian Grimberg         }
36494648b7dSSebastian Grimberg         break;
36594648b7dSSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
36694648b7dSSebastian Grimberg         if (use_signs && use_orients) {
36794648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
36894648b7dSSebastian Grimberg                                                                  vv);
36994648b7dSSebastian Grimberg         } else if (use_orients) {
37094648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedUnsignedTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size,
37194648b7dSSebastian Grimberg                                                                          v_offset, uu, vv);
37294648b7dSSebastian Grimberg         } else {
373*61a27d74SSebastian Grimberg           CeedElemRestrictionApplyStandardTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
37494648b7dSSebastian Grimberg         }
37594648b7dSSebastian Grimberg         break;
37694648b7dSSebastian Grimberg     }
37794648b7dSSebastian Grimberg   } else {
37894648b7dSSebastian Grimberg     // Restriction from L-vector to E-vector
37994648b7dSSebastian Grimberg     // Perform: v = r * u
38094648b7dSSebastian Grimberg     // vv has shape [elem_size, num_comp, num_elem], row-major
38194648b7dSSebastian Grimberg     // uu has shape [nnodes, num_comp]
38294648b7dSSebastian Grimberg     // Overwrite for notranspose mode
38394648b7dSSebastian Grimberg     switch (rstr_type) {
38494648b7dSSebastian Grimberg       case CEED_RESTRICTION_STRIDED:
38594648b7dSSebastian Grimberg         CeedElemRestrictionApplyStridedNoTranspose_Ref_Core(r, num_comp, blk_size, start, stop, num_elem, elem_size, v_offset, uu, vv);
38694648b7dSSebastian Grimberg         break;
387*61a27d74SSebastian Grimberg       case CEED_RESTRICTION_STANDARD:
388*61a27d74SSebastian Grimberg         CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
38994648b7dSSebastian Grimberg         break;
39094648b7dSSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
39194648b7dSSebastian Grimberg         if (use_signs) {
39294648b7dSSebastian Grimberg           CeedElemRestrictionApplyOrientedNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
39394648b7dSSebastian Grimberg                                                                vv);
39494648b7dSSebastian Grimberg         } else {
395*61a27d74SSebastian Grimberg           CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
396*61a27d74SSebastian Grimberg                                                                vv);
39794648b7dSSebastian Grimberg         }
39894648b7dSSebastian Grimberg         break;
39994648b7dSSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
40094648b7dSSebastian Grimberg         if (use_signs && use_orients) {
40194648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
40294648b7dSSebastian Grimberg                                                                    vv);
40394648b7dSSebastian Grimberg         } else if (use_orients) {
40494648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedUnsignedNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size,
40594648b7dSSebastian Grimberg                                                                            v_offset, uu, vv);
40694648b7dSSebastian Grimberg         } else {
407*61a27d74SSebastian Grimberg           CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
408*61a27d74SSebastian Grimberg                                                                vv);
40994648b7dSSebastian Grimberg         }
41094648b7dSSebastian Grimberg         break;
41194648b7dSSebastian Grimberg     }
4127c1dbaffSSebastian Grimberg   }
4137c1dbaffSSebastian Grimberg   CeedCallBackend(CeedVectorRestoreArrayRead(u, &uu));
4147c1dbaffSSebastian Grimberg   CeedCallBackend(CeedVectorRestoreArray(v, &vv));
4157c1dbaffSSebastian Grimberg   if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL;
4167c1dbaffSSebastian Grimberg   return CEED_ERROR_SUCCESS;
4177c1dbaffSSebastian Grimberg }
4187c1dbaffSSebastian Grimberg 
4197c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
420f10650afSjeremylt // ElemRestriction Apply - Common Sizes
421f10650afSjeremylt //------------------------------------------------------------------------------
4227c1dbaffSSebastian Grimberg static int CeedElemRestrictionApply_Ref_110(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4237c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4247c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4257c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
426d979a051Sjeremylt }
427d979a051Sjeremylt 
4282b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_111(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4297c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4307c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4317c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4324d2a38eeSjeremylt }
4334d2a38eeSjeremylt 
4342b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_180(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4357c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4367c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4377c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
4389c36149bSjeremylt }
4399c36149bSjeremylt 
4402b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_181(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4417c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4427c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4437c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4449c36149bSjeremylt }
4459c36149bSjeremylt 
4462b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_310(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4477c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4487c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4497c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
450d979a051Sjeremylt }
451d979a051Sjeremylt 
4522b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_311(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4537c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4547c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4557c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
456d979a051Sjeremylt }
457d979a051Sjeremylt 
4582b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_380(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4597c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4607c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4617c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
462d979a051Sjeremylt }
463d979a051Sjeremylt 
4642b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_381(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4657c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4667c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4677c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
468d979a051Sjeremylt }
469d979a051Sjeremylt 
470bf4d1581Sjeremylt // LCOV_EXCL_START
4712b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4727c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4737c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4747c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
475d979a051Sjeremylt }
476bf4d1581Sjeremylt // LCOV_EXCL_STOP
477d979a051Sjeremylt 
4782b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4797c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4807c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4817c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
482d979a051Sjeremylt }
483d979a051Sjeremylt 
484bf4d1581Sjeremylt // LCOV_EXCL_START
4852b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4867c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4877c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4887c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
489d979a051Sjeremylt }
490bf4d1581Sjeremylt // LCOV_EXCL_STOP
491d979a051Sjeremylt 
4922b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4937c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4940c73c039SSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4957c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4964d2a38eeSjeremylt }
4974d2a38eeSjeremylt 
498f10650afSjeremylt //------------------------------------------------------------------------------
499f10650afSjeremylt // ElemRestriction Apply
500f10650afSjeremylt //------------------------------------------------------------------------------
5012b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
502d1d35e2fSjeremylt   CeedInt num_blk, blk_size, num_comp, comp_stride;
5032b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
5042b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
5052b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5062b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5077509a596Sjeremylt   CeedElemRestriction_Ref *impl;
5082b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
5094d2a38eeSjeremylt 
5107c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, t_mode, true, true, u, v, request);
511f30b1135SSebastian Grimberg }
512f30b1135SSebastian Grimberg 
513f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
514f30b1135SSebastian Grimberg // ElemRestriction Apply Unsigned
515f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
516f30b1135SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
517f30b1135SSebastian Grimberg   CeedInt num_blk, blk_size, num_comp, comp_stride;
518f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
519f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
520f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
521f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
522f30b1135SSebastian Grimberg   CeedElemRestriction_Ref *impl;
523f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
524f30b1135SSebastian Grimberg 
5257c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, t_mode, false, true, u, v, request);
5267c1dbaffSSebastian Grimberg }
5277c1dbaffSSebastian Grimberg 
5287c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
5297c1dbaffSSebastian Grimberg // ElemRestriction Apply Unoriented
5307c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
5317c1dbaffSSebastian Grimberg static int CeedElemRestrictionApplyUnoriented_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
5327c1dbaffSSebastian Grimberg   CeedInt num_blk, blk_size, num_comp, comp_stride;
5337c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
5347c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
5357c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5367c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5377c1dbaffSSebastian Grimberg   CeedElemRestriction_Ref *impl;
5387c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
5397c1dbaffSSebastian Grimberg 
5407c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, t_mode, false, false, u, v, request);
5419c36149bSjeremylt }
542be9261b7Sjeremylt 
543f10650afSjeremylt //------------------------------------------------------------------------------
544f10650afSjeremylt // ElemRestriction Apply Block
545f10650afSjeremylt //------------------------------------------------------------------------------
5462b730f8bSJeremy L Thompson static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
547074cb416Sjeremylt                                              CeedRequest *request) {
548d1d35e2fSjeremylt   CeedInt blk_size, num_comp, comp_stride;
5492b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
5502b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5512b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5527509a596Sjeremylt   CeedElemRestriction_Ref *impl;
5532b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
5544d2a38eeSjeremylt 
5557c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, block, block + 1, t_mode, true, true, u, v, request);
5569c36149bSjeremylt }
557be9261b7Sjeremylt 
558f10650afSjeremylt //------------------------------------------------------------------------------
559bd33150aSjeremylt // ElemRestriction Get Offsets
560bd33150aSjeremylt //------------------------------------------------------------------------------
5612b730f8bSJeremy L Thompson static int CeedElemRestrictionGetOffsets_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) {
562bd33150aSjeremylt   CeedElemRestriction_Ref *impl;
5632b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
564bd33150aSjeremylt   Ceed ceed;
5652b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
566bd33150aSjeremylt 
5676574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
568bd33150aSjeremylt 
569bd33150aSjeremylt   *offsets = impl->offsets;
570e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
571bd33150aSjeremylt }
572bd33150aSjeremylt 
573bd33150aSjeremylt //------------------------------------------------------------------------------
57477d1c127SSebastian Grimberg // ElemRestriction Get Orientations
57577d1c127SSebastian Grimberg //------------------------------------------------------------------------------
57677d1c127SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) {
57777d1c127SSebastian Grimberg   CeedElemRestriction_Ref *impl;
57877d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
57977d1c127SSebastian Grimberg   Ceed ceed;
58077d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
58177d1c127SSebastian Grimberg 
582fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
58377d1c127SSebastian Grimberg 
58477d1c127SSebastian Grimberg   *orients = impl->orients;
58577d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
58677d1c127SSebastian Grimberg }
58777d1c127SSebastian Grimberg 
58877d1c127SSebastian Grimberg //------------------------------------------------------------------------------
58977d1c127SSebastian Grimberg // ElemRestriction Get Curl-Conforming Orientations
59077d1c127SSebastian Grimberg //------------------------------------------------------------------------------
5910c73c039SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) {
59277d1c127SSebastian Grimberg   CeedElemRestriction_Ref *impl;
59377d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
59477d1c127SSebastian Grimberg   Ceed ceed;
59577d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
59677d1c127SSebastian Grimberg 
597fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
59877d1c127SSebastian Grimberg 
59977d1c127SSebastian Grimberg   *curl_orients = impl->curl_orients;
60077d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
60177d1c127SSebastian Grimberg }
60277d1c127SSebastian Grimberg 
60377d1c127SSebastian Grimberg //------------------------------------------------------------------------------
604f10650afSjeremylt // ElemRestriction Destroy
605f10650afSjeremylt //------------------------------------------------------------------------------
60621617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) {
607fe2413ffSjeremylt   CeedElemRestriction_Ref *impl;
6082b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
60921617c04Sjeremylt 
6102b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->offsets_allocated));
61177d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->orients_allocated));
61277d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->curl_orients_allocated));
6132b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
614e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
61521617c04Sjeremylt }
61621617c04Sjeremylt 
617f10650afSjeremylt //------------------------------------------------------------------------------
618f10650afSjeremylt // ElemRestriction Create
619f10650afSjeremylt //------------------------------------------------------------------------------
620fcbe8c06SSebastian Grimberg int CeedElemRestrictionCreate_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients,
6210c73c039SSebastian Grimberg                                   const CeedInt8 *curl_orients, CeedElemRestriction r) {
62221617c04Sjeremylt   CeedElemRestriction_Ref *impl;
623d1d35e2fSjeremylt   CeedInt                  num_elem, elem_size, num_blk, blk_size, num_comp, comp_stride;
6242b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem));
6252b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size));
6262b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
6272b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
6282b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
6292b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
6304ce2993fSjeremylt   Ceed ceed;
6312b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(r, &ceed));
63221617c04Sjeremylt 
6336574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Only MemType = HOST supported");
6342b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
6353661185eSjeremylt 
63692fe105eSJeremy L Thompson   // Offsets data
637fcbe8c06SSebastian Grimberg   CeedRestrictionType rstr_type;
638fcbe8c06SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(r, &rstr_type));
639fcbe8c06SSebastian Grimberg   if (rstr_type != CEED_RESTRICTION_STRIDED) {
64092fe105eSJeremy L Thompson     // Check indices for ref or memcheck backends
641d1d35e2fSjeremylt     Ceed parent_ceed = ceed, curr_ceed = NULL;
642d1d35e2fSjeremylt     while (parent_ceed != curr_ceed) {
643d1d35e2fSjeremylt       curr_ceed = parent_ceed;
6442b730f8bSJeremy L Thompson       CeedCallBackend(CeedGetParent(curr_ceed, &parent_ceed));
6453661185eSjeremylt     }
6463661185eSjeremylt     const char *resource;
6472b730f8bSJeremy L Thompson     CeedCallBackend(CeedGetResource(parent_ceed, &resource));
6482b730f8bSJeremy L Thompson     if (!strcmp(resource, "/cpu/self/ref/serial") || !strcmp(resource, "/cpu/self/ref/blocked") || !strcmp(resource, "/cpu/self/memcheck/serial") ||
649d1d35e2fSjeremylt         !strcmp(resource, "/cpu/self/memcheck/blocked")) {
650e79b91d9SJeremy L Thompson       CeedSize l_size;
6512b730f8bSJeremy L Thompson       CeedCallBackend(CeedElemRestrictionGetLVectorSize(r, &l_size));
6523661185eSjeremylt 
6532b730f8bSJeremy L Thompson       for (CeedInt i = 0; i < num_elem * elem_size; i++) {
6546574a04fSJeremy L Thompson         CeedCheck(offsets[i] >= 0 && offsets[i] + (num_comp - 1) * comp_stride < l_size, ceed, CEED_ERROR_BACKEND,
6556574a04fSJeremy L Thompson                   "Restriction offset %" CeedInt_FMT " (%" CeedInt_FMT ") out of range [0, %" CeedInt_FMT "]", i, offsets[i], l_size);
6562b730f8bSJeremy L Thompson       }
6572b730f8bSJeremy L Thompson     }
6583661185eSjeremylt 
65992fe105eSJeremy L Thompson     // Copy data
660d1d35e2fSjeremylt     switch (copy_mode) {
66121617c04Sjeremylt       case CEED_COPY_VALUES:
6622b730f8bSJeremy L Thompson         CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->offsets_allocated));
6632b730f8bSJeremy L Thompson         memcpy(impl->offsets_allocated, offsets, num_elem * elem_size * sizeof(offsets[0]));
664d979a051Sjeremylt         impl->offsets = impl->offsets_allocated;
66521617c04Sjeremylt         break;
66621617c04Sjeremylt       case CEED_OWN_POINTER:
667d979a051Sjeremylt         impl->offsets_allocated = (CeedInt *)offsets;
668d979a051Sjeremylt         impl->offsets           = impl->offsets_allocated;
66921617c04Sjeremylt         break;
67021617c04Sjeremylt       case CEED_USE_POINTER:
671d979a051Sjeremylt         impl->offsets = offsets;
67221617c04Sjeremylt     }
673fcbe8c06SSebastian Grimberg 
674fcbe8c06SSebastian Grimberg     // Orientation data
675fcbe8c06SSebastian Grimberg     if (rstr_type == CEED_RESTRICTION_ORIENTED) {
6760305e208SSebastian Grimberg       CeedCheck(orients != NULL, ceed, CEED_ERROR_BACKEND, "No orients array provided for oriented restriction");
677fcbe8c06SSebastian Grimberg       switch (copy_mode) {
678fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
679fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->orients_allocated));
680fcbe8c06SSebastian Grimberg           memcpy(impl->orients_allocated, orients, num_elem * elem_size * sizeof(orients[0]));
681fcbe8c06SSebastian Grimberg           impl->orients = impl->orients_allocated;
682fcbe8c06SSebastian Grimberg           break;
683fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
684fcbe8c06SSebastian Grimberg           impl->orients_allocated = (bool *)orients;
685fcbe8c06SSebastian Grimberg           impl->orients           = impl->orients_allocated;
686fcbe8c06SSebastian Grimberg           break;
687fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
688fcbe8c06SSebastian Grimberg           impl->orients = orients;
689fcbe8c06SSebastian Grimberg       }
690fcbe8c06SSebastian Grimberg     } else if (rstr_type == CEED_RESTRICTION_CURL_ORIENTED) {
6910305e208SSebastian Grimberg       CeedCheck(curl_orients != NULL, ceed, CEED_ERROR_BACKEND, "No curl_orients array provided for oriented restriction");
692fcbe8c06SSebastian Grimberg       switch (copy_mode) {
693fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
694fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * 3 * elem_size, &impl->curl_orients_allocated));
695fcbe8c06SSebastian Grimberg           memcpy(impl->curl_orients_allocated, curl_orients, num_elem * 3 * elem_size * sizeof(curl_orients[0]));
696fcbe8c06SSebastian Grimberg           impl->curl_orients = impl->curl_orients_allocated;
697fcbe8c06SSebastian Grimberg           break;
698fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
6990c73c039SSebastian Grimberg           impl->curl_orients_allocated = (CeedInt8 *)curl_orients;
700fcbe8c06SSebastian Grimberg           impl->curl_orients           = impl->curl_orients_allocated;
701fcbe8c06SSebastian Grimberg           break;
702fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
703fcbe8c06SSebastian Grimberg           impl->curl_orients = curl_orients;
704fcbe8c06SSebastian Grimberg       }
705fcbe8c06SSebastian Grimberg     }
70692fe105eSJeremy L Thompson   }
707fe2413ffSjeremylt 
7082b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetData(r, impl));
709d1d35e2fSjeremylt   CeedInt layout[3] = {1, elem_size, elem_size * num_comp};
7102b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetELayout(r, layout));
7112b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", CeedElemRestrictionApply_Ref));
712f30b1135SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Ref));
7137c1dbaffSSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnoriented", CeedElemRestrictionApplyUnoriented_Ref));
7142b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", CeedElemRestrictionApplyBlock_Ref));
7152b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOffsets", CeedElemRestrictionGetOffsets_Ref));
71677d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOrientations", CeedElemRestrictionGetOrientations_Ref));
71777d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Ref));
7182b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", CeedElemRestrictionDestroy_Ref));
719d979a051Sjeremylt 
720d1d35e2fSjeremylt   // Set apply function based upon num_comp, blk_size, and comp_stride
721d979a051Sjeremylt   CeedInt idx = -1;
7222b730f8bSJeremy L Thompson   if (blk_size < 10) idx = 100 * num_comp + 10 * blk_size + (comp_stride == 1);
723d979a051Sjeremylt   switch (idx) {
724d979a051Sjeremylt     case 110:
725d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_110;
726d979a051Sjeremylt       break;
727d979a051Sjeremylt     case 111:
728d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_111;
729d979a051Sjeremylt       break;
730d979a051Sjeremylt     case 180:
731d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_180;
732d979a051Sjeremylt       break;
733d979a051Sjeremylt     case 181:
734d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_181;
735d979a051Sjeremylt       break;
736d979a051Sjeremylt     case 310:
737d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_310;
738d979a051Sjeremylt       break;
739d979a051Sjeremylt     case 311:
740d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_311;
741d979a051Sjeremylt       break;
742d979a051Sjeremylt     case 380:
743d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_380;
744d979a051Sjeremylt       break;
745d979a051Sjeremylt     case 381:
746d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_381;
747d979a051Sjeremylt       break;
748bf4d1581Sjeremylt     // LCOV_EXCL_START
749d979a051Sjeremylt     case 510:
750d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_510;
751d979a051Sjeremylt       break;
752bf4d1581Sjeremylt     // LCOV_EXCL_STOP
753d979a051Sjeremylt     case 511:
754d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_511;
755d979a051Sjeremylt       break;
756bf4d1581Sjeremylt     // LCOV_EXCL_START
757d979a051Sjeremylt     case 580:
758d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_580;
759d979a051Sjeremylt       break;
760bf4d1581Sjeremylt     // LCOV_EXCL_STOP
761d979a051Sjeremylt     case 581:
762d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_581;
763d979a051Sjeremylt       break;
764d979a051Sjeremylt     default:
765d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_Core;
766d979a051Sjeremylt       break;
767d979a051Sjeremylt   }
768d979a051Sjeremylt 
769e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
77021617c04Sjeremylt }
771fc0567d9Srezgarshakeri 
772fc0567d9Srezgarshakeri //------------------------------------------------------------------------------
773