xref: /libCEED/rust/libceed-sys/c-src/backends/ref/ceed-ref-restriction.c (revision 94648b7d790ab3fd1a5eb5a8aed21d2faa625ce1)
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 //------------------------------------------------------------------------------
19*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyStridedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
20*94648b7dSSebastian Grimberg                                                                       CeedInt start, CeedInt stop, CeedInt num_elem, CeedInt elem_size,
21*94648b7dSSebastian Grimberg                                                                       CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
22*94648b7dSSebastian 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   }
53*94648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
54*94648b7dSSebastian Grimberg }
55*94648b7dSSebastian Grimberg 
56*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyDefaultNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
57*94648b7dSSebastian Grimberg                                                                       const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
58*94648b7dSSebastian Grimberg                                                                       CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
59fcbe8c06SSebastian Grimberg   // Default restriction with offsets
60*94648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
61*94648b7dSSebastian 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   }
69*94648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
70*94648b7dSSebastian Grimberg }
71*94648b7dSSebastian Grimberg 
72*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyOrientedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
73*94648b7dSSebastian Grimberg                                                                        const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
74*94648b7dSSebastian Grimberg                                                                        CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
75fcbe8c06SSebastian Grimberg   // Restriction with orientations
76*94648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
77*94648b7dSSebastian 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   }
86*94648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
87*94648b7dSSebastian Grimberg }
88*94648b7dSSebastian Grimberg 
89*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
90*94648b7dSSebastian Grimberg                                                                            const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
91*94648b7dSSebastian Grimberg                                                                            CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu,
92*94648b7dSSebastian Grimberg                                                                            CeedScalar *vv) {
9377d1c127SSebastian Grimberg   // Restriction with tridiagonal transformation
94*94648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
95*94648b7dSSebastian 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 
129*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedUnsignedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp,
130*94648b7dSSebastian Grimberg                                                                                    const CeedInt blk_size, const CeedInt comp_stride, CeedInt start,
131*94648b7dSSebastian Grimberg                                                                                    CeedInt stop, CeedInt num_elem, CeedInt elem_size,
132*94648b7dSSebastian Grimberg                                                                                    CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
133*94648b7dSSebastian 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 
169*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyStridedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
170*94648b7dSSebastian Grimberg                                                                     CeedInt start, CeedInt stop, CeedInt num_elem, CeedInt elem_size,
171*94648b7dSSebastian Grimberg                                                                     CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
172*94648b7dSSebastian 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++) {
182*94648b7dSSebastian 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   }
202*94648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
203*94648b7dSSebastian Grimberg }
204*94648b7dSSebastian Grimberg 
205*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyDefaultTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
206*94648b7dSSebastian Grimberg                                                                     const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
207*94648b7dSSebastian Grimberg                                                                     CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
208fcbe8c06SSebastian Grimberg   // Default restriction with offsets
209*94648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
210*94648b7dSSebastian 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   }
221*94648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
222*94648b7dSSebastian Grimberg }
223*94648b7dSSebastian Grimberg 
224*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyOrientedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
225*94648b7dSSebastian Grimberg                                                                      const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
226*94648b7dSSebastian Grimberg                                                                      CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
227fcbe8c06SSebastian Grimberg   // Restriction with orientations
228*94648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
229*94648b7dSSebastian 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   }
241*94648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
242*94648b7dSSebastian Grimberg }
243*94648b7dSSebastian Grimberg 
244*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size,
245*94648b7dSSebastian Grimberg                                                                          const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
246*94648b7dSSebastian Grimberg                                                                          CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
24777d1c127SSebastian Grimberg   // Restriction with tridiagonal transformation
248*94648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
249*94648b7dSSebastian 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 
284*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedUnsignedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp,
285*94648b7dSSebastian Grimberg                                                                                  const CeedInt blk_size, const CeedInt comp_stride, CeedInt start,
286*94648b7dSSebastian Grimberg                                                                                  CeedInt stop, CeedInt num_elem, CeedInt elem_size, CeedInt v_offset,
287*94648b7dSSebastian Grimberg                                                                                  const CeedScalar *uu, CeedScalar *vv) {
288*94648b7dSSebastian 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 
325*94648b7dSSebastian Grimberg static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
326*94648b7dSSebastian Grimberg                                                     CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients,
327*94648b7dSSebastian 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 
337*94648b7dSSebastian Grimberg   CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu));
338*94648b7dSSebastian Grimberg   if (t_mode == CEED_TRANSPOSE) {
339*94648b7dSSebastian Grimberg     // Sum into for transpose mode, E-vector to L-vector
340*94648b7dSSebastian Grimberg     CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_HOST, &vv));
341*94648b7dSSebastian Grimberg   } else {
342*94648b7dSSebastian Grimberg     // Overwrite for notranspose mode, L-vector to E-vector
343*94648b7dSSebastian Grimberg     CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_HOST, &vv));
344*94648b7dSSebastian Grimberg   }
345*94648b7dSSebastian 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:
353*94648b7dSSebastian Grimberg         CeedElemRestrictionApplyStridedTranspose_Ref_Core(r, num_comp, blk_size, start, stop, num_elem, elem_size, v_offset, uu, vv);
354*94648b7dSSebastian Grimberg         break;
3557c1dbaffSSebastian Grimberg       case CEED_RESTRICTION_DEFAULT:
356*94648b7dSSebastian Grimberg         CeedElemRestrictionApplyDefaultTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
357*94648b7dSSebastian Grimberg         break;
3587c1dbaffSSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
359*94648b7dSSebastian Grimberg         if (use_signs) {
360*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyOrientedTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
361*94648b7dSSebastian Grimberg         } else {
362*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyDefaultTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
363*94648b7dSSebastian Grimberg         }
364*94648b7dSSebastian Grimberg         break;
365*94648b7dSSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
366*94648b7dSSebastian Grimberg         if (use_signs && use_orients) {
367*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
368*94648b7dSSebastian Grimberg                                                                  vv);
369*94648b7dSSebastian Grimberg         } else if (use_orients) {
370*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedUnsignedTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size,
371*94648b7dSSebastian Grimberg                                                                          v_offset, uu, vv);
372*94648b7dSSebastian Grimberg         } else {
373*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyDefaultTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
374*94648b7dSSebastian Grimberg         }
375*94648b7dSSebastian Grimberg         break;
376*94648b7dSSebastian Grimberg     }
377*94648b7dSSebastian Grimberg   } else {
378*94648b7dSSebastian Grimberg     // Restriction from L-vector to E-vector
379*94648b7dSSebastian Grimberg     // Perform: v = r * u
380*94648b7dSSebastian Grimberg     // vv has shape [elem_size, num_comp, num_elem], row-major
381*94648b7dSSebastian Grimberg     // uu has shape [nnodes, num_comp]
382*94648b7dSSebastian Grimberg     // Overwrite for notranspose mode
383*94648b7dSSebastian Grimberg     switch (rstr_type) {
384*94648b7dSSebastian Grimberg       case CEED_RESTRICTION_STRIDED:
385*94648b7dSSebastian Grimberg         CeedElemRestrictionApplyStridedNoTranspose_Ref_Core(r, num_comp, blk_size, start, stop, num_elem, elem_size, v_offset, uu, vv);
386*94648b7dSSebastian Grimberg         break;
387*94648b7dSSebastian Grimberg       case CEED_RESTRICTION_DEFAULT:
388*94648b7dSSebastian Grimberg         CeedElemRestrictionApplyDefaultNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
389*94648b7dSSebastian Grimberg         break;
390*94648b7dSSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
391*94648b7dSSebastian Grimberg         if (use_signs) {
392*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyOrientedNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
393*94648b7dSSebastian Grimberg                                                                vv);
394*94648b7dSSebastian Grimberg         } else {
395*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyDefaultNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
396*94648b7dSSebastian Grimberg         }
397*94648b7dSSebastian Grimberg         break;
398*94648b7dSSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
399*94648b7dSSebastian Grimberg         if (use_signs && use_orients) {
400*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
401*94648b7dSSebastian Grimberg                                                                    vv);
402*94648b7dSSebastian Grimberg         } else if (use_orients) {
403*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyCurlOrientedUnsignedNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size,
404*94648b7dSSebastian Grimberg                                                                            v_offset, uu, vv);
405*94648b7dSSebastian Grimberg         } else {
406*94648b7dSSebastian Grimberg           CeedElemRestrictionApplyDefaultNoTranspose_Ref_Core(r, num_comp, blk_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
407*94648b7dSSebastian Grimberg         }
408*94648b7dSSebastian Grimberg         break;
409*94648b7dSSebastian Grimberg     }
4107c1dbaffSSebastian Grimberg   }
4117c1dbaffSSebastian Grimberg   CeedCallBackend(CeedVectorRestoreArrayRead(u, &uu));
4127c1dbaffSSebastian Grimberg   CeedCallBackend(CeedVectorRestoreArray(v, &vv));
4137c1dbaffSSebastian Grimberg   if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL;
4147c1dbaffSSebastian Grimberg   return CEED_ERROR_SUCCESS;
4157c1dbaffSSebastian Grimberg }
4167c1dbaffSSebastian Grimberg 
4177c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
418f10650afSjeremylt // ElemRestriction Apply - Common Sizes
419f10650afSjeremylt //------------------------------------------------------------------------------
4207c1dbaffSSebastian Grimberg static int CeedElemRestrictionApply_Ref_110(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4217c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4227c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4237c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
424d979a051Sjeremylt }
425d979a051Sjeremylt 
4262b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_111(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4277c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4287c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4297c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4304d2a38eeSjeremylt }
4314d2a38eeSjeremylt 
4322b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_180(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4337c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4347c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4357c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
4369c36149bSjeremylt }
4379c36149bSjeremylt 
4382b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_181(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4397c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4407c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4417c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4429c36149bSjeremylt }
4439c36149bSjeremylt 
4442b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_310(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4457c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4467c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4477c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
448d979a051Sjeremylt }
449d979a051Sjeremylt 
4502b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_311(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4517c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4527c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4537c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
454d979a051Sjeremylt }
455d979a051Sjeremylt 
4562b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_380(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4577c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4587c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4597c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
460d979a051Sjeremylt }
461d979a051Sjeremylt 
4622b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_381(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4637c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4647c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4657c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
466d979a051Sjeremylt }
467d979a051Sjeremylt 
468bf4d1581Sjeremylt // LCOV_EXCL_START
4692b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4707c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4717c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4727c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
473d979a051Sjeremylt }
474bf4d1581Sjeremylt // LCOV_EXCL_STOP
475d979a051Sjeremylt 
4762b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4777c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4787c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4797c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
480d979a051Sjeremylt }
481d979a051Sjeremylt 
482bf4d1581Sjeremylt // LCOV_EXCL_START
4832b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4847c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4857c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4867c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
487d979a051Sjeremylt }
488bf4d1581Sjeremylt // LCOV_EXCL_STOP
489d979a051Sjeremylt 
4902b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
4917c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4920c73c039SSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4937c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4944d2a38eeSjeremylt }
4954d2a38eeSjeremylt 
496f10650afSjeremylt //------------------------------------------------------------------------------
497f10650afSjeremylt // ElemRestriction Apply
498f10650afSjeremylt //------------------------------------------------------------------------------
4992b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
500d1d35e2fSjeremylt   CeedInt num_blk, blk_size, num_comp, comp_stride;
5012b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
5022b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
5032b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5042b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5057509a596Sjeremylt   CeedElemRestriction_Ref *impl;
5062b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
5074d2a38eeSjeremylt 
5087c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, t_mode, true, true, u, v, request);
509f30b1135SSebastian Grimberg }
510f30b1135SSebastian Grimberg 
511f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
512f30b1135SSebastian Grimberg // ElemRestriction Apply Unsigned
513f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
514f30b1135SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
515f30b1135SSebastian Grimberg   CeedInt num_blk, blk_size, num_comp, comp_stride;
516f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
517f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
518f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
519f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
520f30b1135SSebastian Grimberg   CeedElemRestriction_Ref *impl;
521f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
522f30b1135SSebastian Grimberg 
5237c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, t_mode, false, true, u, v, request);
5247c1dbaffSSebastian Grimberg }
5257c1dbaffSSebastian Grimberg 
5267c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
5277c1dbaffSSebastian Grimberg // ElemRestriction Apply Unoriented
5287c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
5297c1dbaffSSebastian Grimberg static int CeedElemRestrictionApplyUnoriented_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
5307c1dbaffSSebastian Grimberg   CeedInt num_blk, blk_size, num_comp, comp_stride;
5317c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
5327c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
5337c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5347c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5357c1dbaffSSebastian Grimberg   CeedElemRestriction_Ref *impl;
5367c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
5377c1dbaffSSebastian Grimberg 
5387c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, t_mode, false, false, u, v, request);
5399c36149bSjeremylt }
540be9261b7Sjeremylt 
541f10650afSjeremylt //------------------------------------------------------------------------------
542f10650afSjeremylt // ElemRestriction Apply Block
543f10650afSjeremylt //------------------------------------------------------------------------------
5442b730f8bSJeremy L Thompson static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
545074cb416Sjeremylt                                              CeedRequest *request) {
546d1d35e2fSjeremylt   CeedInt blk_size, num_comp, comp_stride;
5472b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
5482b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5492b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5507509a596Sjeremylt   CeedElemRestriction_Ref *impl;
5512b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
5524d2a38eeSjeremylt 
5537c1dbaffSSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, block, block + 1, t_mode, true, true, u, v, request);
5549c36149bSjeremylt }
555be9261b7Sjeremylt 
556f10650afSjeremylt //------------------------------------------------------------------------------
557bd33150aSjeremylt // ElemRestriction Get Offsets
558bd33150aSjeremylt //------------------------------------------------------------------------------
5592b730f8bSJeremy L Thompson static int CeedElemRestrictionGetOffsets_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) {
560bd33150aSjeremylt   CeedElemRestriction_Ref *impl;
5612b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
562bd33150aSjeremylt   Ceed ceed;
5632b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
564bd33150aSjeremylt 
5656574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
566bd33150aSjeremylt 
567bd33150aSjeremylt   *offsets = impl->offsets;
568e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
569bd33150aSjeremylt }
570bd33150aSjeremylt 
571bd33150aSjeremylt //------------------------------------------------------------------------------
57277d1c127SSebastian Grimberg // ElemRestriction Get Orientations
57377d1c127SSebastian Grimberg //------------------------------------------------------------------------------
57477d1c127SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) {
57577d1c127SSebastian Grimberg   CeedElemRestriction_Ref *impl;
57677d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
57777d1c127SSebastian Grimberg   Ceed ceed;
57877d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
57977d1c127SSebastian Grimberg 
580fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
58177d1c127SSebastian Grimberg 
58277d1c127SSebastian Grimberg   *orients = impl->orients;
58377d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
58477d1c127SSebastian Grimberg }
58577d1c127SSebastian Grimberg 
58677d1c127SSebastian Grimberg //------------------------------------------------------------------------------
58777d1c127SSebastian Grimberg // ElemRestriction Get Curl-Conforming Orientations
58877d1c127SSebastian Grimberg //------------------------------------------------------------------------------
5890c73c039SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) {
59077d1c127SSebastian Grimberg   CeedElemRestriction_Ref *impl;
59177d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
59277d1c127SSebastian Grimberg   Ceed ceed;
59377d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
59477d1c127SSebastian Grimberg 
595fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
59677d1c127SSebastian Grimberg 
59777d1c127SSebastian Grimberg   *curl_orients = impl->curl_orients;
59877d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
59977d1c127SSebastian Grimberg }
60077d1c127SSebastian Grimberg 
60177d1c127SSebastian Grimberg //------------------------------------------------------------------------------
602f10650afSjeremylt // ElemRestriction Destroy
603f10650afSjeremylt //------------------------------------------------------------------------------
60421617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) {
605fe2413ffSjeremylt   CeedElemRestriction_Ref *impl;
6062b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
60721617c04Sjeremylt 
6082b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->offsets_allocated));
60977d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->orients_allocated));
61077d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->curl_orients_allocated));
6112b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
612e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
61321617c04Sjeremylt }
61421617c04Sjeremylt 
615f10650afSjeremylt //------------------------------------------------------------------------------
616f10650afSjeremylt // ElemRestriction Create
617f10650afSjeremylt //------------------------------------------------------------------------------
618fcbe8c06SSebastian Grimberg int CeedElemRestrictionCreate_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients,
6190c73c039SSebastian Grimberg                                   const CeedInt8 *curl_orients, CeedElemRestriction r) {
62021617c04Sjeremylt   CeedElemRestriction_Ref *impl;
621d1d35e2fSjeremylt   CeedInt                  num_elem, elem_size, num_blk, blk_size, num_comp, comp_stride;
6222b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem));
6232b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size));
6242b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
6252b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
6262b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
6272b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
6284ce2993fSjeremylt   Ceed ceed;
6292b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(r, &ceed));
63021617c04Sjeremylt 
6316574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Only MemType = HOST supported");
6322b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
6333661185eSjeremylt 
63492fe105eSJeremy L Thompson   // Offsets data
635fcbe8c06SSebastian Grimberg   CeedRestrictionType rstr_type;
636fcbe8c06SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(r, &rstr_type));
637fcbe8c06SSebastian Grimberg   if (rstr_type != CEED_RESTRICTION_STRIDED) {
63892fe105eSJeremy L Thompson     // Check indices for ref or memcheck backends
639d1d35e2fSjeremylt     Ceed parent_ceed = ceed, curr_ceed = NULL;
640d1d35e2fSjeremylt     while (parent_ceed != curr_ceed) {
641d1d35e2fSjeremylt       curr_ceed = parent_ceed;
6422b730f8bSJeremy L Thompson       CeedCallBackend(CeedGetParent(curr_ceed, &parent_ceed));
6433661185eSjeremylt     }
6443661185eSjeremylt     const char *resource;
6452b730f8bSJeremy L Thompson     CeedCallBackend(CeedGetResource(parent_ceed, &resource));
6462b730f8bSJeremy L Thompson     if (!strcmp(resource, "/cpu/self/ref/serial") || !strcmp(resource, "/cpu/self/ref/blocked") || !strcmp(resource, "/cpu/self/memcheck/serial") ||
647d1d35e2fSjeremylt         !strcmp(resource, "/cpu/self/memcheck/blocked")) {
648e79b91d9SJeremy L Thompson       CeedSize l_size;
6492b730f8bSJeremy L Thompson       CeedCallBackend(CeedElemRestrictionGetLVectorSize(r, &l_size));
6503661185eSjeremylt 
6512b730f8bSJeremy L Thompson       for (CeedInt i = 0; i < num_elem * elem_size; i++) {
6526574a04fSJeremy L Thompson         CeedCheck(offsets[i] >= 0 && offsets[i] + (num_comp - 1) * comp_stride < l_size, ceed, CEED_ERROR_BACKEND,
6536574a04fSJeremy L Thompson                   "Restriction offset %" CeedInt_FMT " (%" CeedInt_FMT ") out of range [0, %" CeedInt_FMT "]", i, offsets[i], l_size);
6542b730f8bSJeremy L Thompson       }
6552b730f8bSJeremy L Thompson     }
6563661185eSjeremylt 
65792fe105eSJeremy L Thompson     // Copy data
658d1d35e2fSjeremylt     switch (copy_mode) {
65921617c04Sjeremylt       case CEED_COPY_VALUES:
6602b730f8bSJeremy L Thompson         CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->offsets_allocated));
6612b730f8bSJeremy L Thompson         memcpy(impl->offsets_allocated, offsets, num_elem * elem_size * sizeof(offsets[0]));
662d979a051Sjeremylt         impl->offsets = impl->offsets_allocated;
66321617c04Sjeremylt         break;
66421617c04Sjeremylt       case CEED_OWN_POINTER:
665d979a051Sjeremylt         impl->offsets_allocated = (CeedInt *)offsets;
666d979a051Sjeremylt         impl->offsets           = impl->offsets_allocated;
66721617c04Sjeremylt         break;
66821617c04Sjeremylt       case CEED_USE_POINTER:
669d979a051Sjeremylt         impl->offsets = offsets;
67021617c04Sjeremylt     }
671fcbe8c06SSebastian Grimberg 
672fcbe8c06SSebastian Grimberg     // Orientation data
673fcbe8c06SSebastian Grimberg     if (rstr_type == CEED_RESTRICTION_ORIENTED) {
6740305e208SSebastian Grimberg       CeedCheck(orients != NULL, ceed, CEED_ERROR_BACKEND, "No orients array provided for oriented restriction");
675fcbe8c06SSebastian Grimberg       switch (copy_mode) {
676fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
677fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->orients_allocated));
678fcbe8c06SSebastian Grimberg           memcpy(impl->orients_allocated, orients, num_elem * elem_size * sizeof(orients[0]));
679fcbe8c06SSebastian Grimberg           impl->orients = impl->orients_allocated;
680fcbe8c06SSebastian Grimberg           break;
681fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
682fcbe8c06SSebastian Grimberg           impl->orients_allocated = (bool *)orients;
683fcbe8c06SSebastian Grimberg           impl->orients           = impl->orients_allocated;
684fcbe8c06SSebastian Grimberg           break;
685fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
686fcbe8c06SSebastian Grimberg           impl->orients = orients;
687fcbe8c06SSebastian Grimberg       }
688fcbe8c06SSebastian Grimberg     } else if (rstr_type == CEED_RESTRICTION_CURL_ORIENTED) {
6890305e208SSebastian Grimberg       CeedCheck(curl_orients != NULL, ceed, CEED_ERROR_BACKEND, "No curl_orients array provided for oriented restriction");
690fcbe8c06SSebastian Grimberg       switch (copy_mode) {
691fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
692fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * 3 * elem_size, &impl->curl_orients_allocated));
693fcbe8c06SSebastian Grimberg           memcpy(impl->curl_orients_allocated, curl_orients, num_elem * 3 * elem_size * sizeof(curl_orients[0]));
694fcbe8c06SSebastian Grimberg           impl->curl_orients = impl->curl_orients_allocated;
695fcbe8c06SSebastian Grimberg           break;
696fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
6970c73c039SSebastian Grimberg           impl->curl_orients_allocated = (CeedInt8 *)curl_orients;
698fcbe8c06SSebastian Grimberg           impl->curl_orients           = impl->curl_orients_allocated;
699fcbe8c06SSebastian Grimberg           break;
700fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
701fcbe8c06SSebastian Grimberg           impl->curl_orients = curl_orients;
702fcbe8c06SSebastian Grimberg       }
703fcbe8c06SSebastian Grimberg     }
70492fe105eSJeremy L Thompson   }
705fe2413ffSjeremylt 
7062b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetData(r, impl));
707d1d35e2fSjeremylt   CeedInt layout[3] = {1, elem_size, elem_size * num_comp};
7082b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetELayout(r, layout));
7092b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", CeedElemRestrictionApply_Ref));
710f30b1135SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Ref));
7117c1dbaffSSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnoriented", CeedElemRestrictionApplyUnoriented_Ref));
7122b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", CeedElemRestrictionApplyBlock_Ref));
7132b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOffsets", CeedElemRestrictionGetOffsets_Ref));
71477d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOrientations", CeedElemRestrictionGetOrientations_Ref));
71577d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Ref));
7162b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", CeedElemRestrictionDestroy_Ref));
717d979a051Sjeremylt 
718d1d35e2fSjeremylt   // Set apply function based upon num_comp, blk_size, and comp_stride
719d979a051Sjeremylt   CeedInt idx = -1;
7202b730f8bSJeremy L Thompson   if (blk_size < 10) idx = 100 * num_comp + 10 * blk_size + (comp_stride == 1);
721d979a051Sjeremylt   switch (idx) {
722d979a051Sjeremylt     case 110:
723d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_110;
724d979a051Sjeremylt       break;
725d979a051Sjeremylt     case 111:
726d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_111;
727d979a051Sjeremylt       break;
728d979a051Sjeremylt     case 180:
729d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_180;
730d979a051Sjeremylt       break;
731d979a051Sjeremylt     case 181:
732d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_181;
733d979a051Sjeremylt       break;
734d979a051Sjeremylt     case 310:
735d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_310;
736d979a051Sjeremylt       break;
737d979a051Sjeremylt     case 311:
738d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_311;
739d979a051Sjeremylt       break;
740d979a051Sjeremylt     case 380:
741d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_380;
742d979a051Sjeremylt       break;
743d979a051Sjeremylt     case 381:
744d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_381;
745d979a051Sjeremylt       break;
746bf4d1581Sjeremylt     // LCOV_EXCL_START
747d979a051Sjeremylt     case 510:
748d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_510;
749d979a051Sjeremylt       break;
750bf4d1581Sjeremylt     // LCOV_EXCL_STOP
751d979a051Sjeremylt     case 511:
752d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_511;
753d979a051Sjeremylt       break;
754bf4d1581Sjeremylt     // LCOV_EXCL_START
755d979a051Sjeremylt     case 580:
756d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_580;
757d979a051Sjeremylt       break;
758bf4d1581Sjeremylt     // LCOV_EXCL_STOP
759d979a051Sjeremylt     case 581:
760d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_581;
761d979a051Sjeremylt       break;
762d979a051Sjeremylt     default:
763d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_Core;
764d979a051Sjeremylt       break;
765d979a051Sjeremylt   }
766d979a051Sjeremylt 
767e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
76821617c04Sjeremylt }
769fc0567d9Srezgarshakeri 
770fc0567d9Srezgarshakeri //------------------------------------------------------------------------------
771