xref: /libCEED/rust/libceed-sys/c-src/backends/ref/ceed-ref-restriction.c (revision ad70ee2c7083010521460a681a248527200af770)
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*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyStridedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_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;
24*ad70ee2cSJeremy L Thompson 
252b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides));
26d1d35e2fSjeremylt   if (has_backend_strides) {
27d1d35e2fSjeremylt     // CPU backend strides are {1, elem_size, elem_size*num_comp}
287f90ec76Sjeremylt     // This if branch is left separate to allow better inlining
29*ad70ee2cSJeremy L Thompson     for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
302b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
312b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
32*ad70ee2cSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
33*ad70ee2cSJeremy L Thompson             vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
342b730f8bSJeremy L Thompson                 uu[n + k * elem_size + CeedIntMin(e + j, num_elem - 1) * elem_size * num_comp];
352b730f8bSJeremy L Thompson           }
362b730f8bSJeremy L Thompson         }
372b730f8bSJeremy L Thompson       }
382b730f8bSJeremy L Thompson     }
397f90ec76Sjeremylt   } else {
407f90ec76Sjeremylt     // User provided strides
417f90ec76Sjeremylt     CeedInt strides[3];
42*ad70ee2cSJeremy L Thompson 
432b730f8bSJeremy L Thompson     CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides));
44*ad70ee2cSJeremy L Thompson     for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
452b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
462b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
47*ad70ee2cSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
48*ad70ee2cSJeremy L Thompson             vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
492b730f8bSJeremy L Thompson                 uu[n * strides[0] + k * strides[1] + CeedIntMin(e + j, num_elem - 1) * strides[2]];
502b730f8bSJeremy L Thompson           }
512b730f8bSJeremy L Thompson         }
522b730f8bSJeremy L Thompson       }
532b730f8bSJeremy L Thompson     }
547509a596Sjeremylt   }
5594648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
5694648b7dSSebastian Grimberg }
5794648b7dSSebastian Grimberg 
58*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
5994648b7dSSebastian Grimberg                                                                        const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
6094648b7dSSebastian Grimberg                                                                        CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
61fcbe8c06SSebastian Grimberg   // Default restriction with offsets
6294648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
63*ad70ee2cSJeremy L Thompson 
6494648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
65*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
662b730f8bSJeremy L Thompson     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
67*ad70ee2cSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * block_size; i++) {
68*ad70ee2cSJeremy L Thompson         vv[elem_size * (k * block_size + e * num_comp) + i - v_offset] = uu[impl->offsets[i + e * elem_size] + k * comp_stride];
69fcbe8c06SSebastian Grimberg       }
70fcbe8c06SSebastian Grimberg     }
71fcbe8c06SSebastian Grimberg   }
7294648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
7394648b7dSSebastian Grimberg }
7494648b7dSSebastian Grimberg 
75*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyOrientedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
7694648b7dSSebastian Grimberg                                                                        const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
7794648b7dSSebastian Grimberg                                                                        CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
78fcbe8c06SSebastian Grimberg   // Restriction with orientations
7994648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
80*ad70ee2cSJeremy L Thompson 
8194648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
82*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
83fcbe8c06SSebastian Grimberg     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
84*ad70ee2cSJeremy L Thompson       CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * block_size; i++) {
85*ad70ee2cSJeremy L Thompson         vv[elem_size * (k * block_size + e * num_comp) + i - v_offset] =
867c1dbaffSSebastian Grimberg             uu[impl->offsets[i + e * elem_size] + k * comp_stride] * (impl->orients[i + e * elem_size] ? -1.0 : 1.0);
87fcbe8c06SSebastian Grimberg       }
88fcbe8c06SSebastian Grimberg     }
89fcbe8c06SSebastian Grimberg   }
9094648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
9194648b7dSSebastian Grimberg }
9294648b7dSSebastian Grimberg 
93*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyCurlOrientedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
9494648b7dSSebastian Grimberg                                                                            const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
9594648b7dSSebastian Grimberg                                                                            CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu,
9694648b7dSSebastian Grimberg                                                                            CeedScalar *vv) {
9777d1c127SSebastian Grimberg   // Restriction with tridiagonal transformation
9894648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
99*ad70ee2cSJeremy L Thompson 
10094648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
101*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
102fcbe8c06SSebastian Grimberg     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1030c73c039SSebastian Grimberg       CeedInt n = 0;
104*ad70ee2cSJeremy L Thompson       CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
105*ad70ee2cSJeremy L Thompson         vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
106*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] *
107*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size] +
108*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + (n + 1) * block_size + e * elem_size] + k * comp_stride] *
109*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n + 2) * block_size + e * 3 * elem_size];
1100c73c039SSebastian Grimberg       }
1110c73c039SSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
112*ad70ee2cSJeremy L Thompson         CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
113*ad70ee2cSJeremy L Thompson           vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
114*ad70ee2cSJeremy L Thompson               uu[impl->offsets[j + (n - 1) * block_size + e * elem_size] + k * comp_stride] *
115*ad70ee2cSJeremy L Thompson                   impl->curl_orients[j + (3 * n + 0) * block_size + e * 3 * elem_size] +
116*ad70ee2cSJeremy L Thompson               uu[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] *
117*ad70ee2cSJeremy L Thompson                   impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size] +
118*ad70ee2cSJeremy L Thompson               uu[impl->offsets[j + (n + 1) * block_size + e * elem_size] + k * comp_stride] *
119*ad70ee2cSJeremy L Thompson                   impl->curl_orients[j + (3 * n + 2) * block_size + e * 3 * elem_size];
1200c73c039SSebastian Grimberg         }
1210c73c039SSebastian Grimberg       }
122*ad70ee2cSJeremy L Thompson       CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
123*ad70ee2cSJeremy L Thompson         vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
124*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + (n - 1) * block_size + e * elem_size] + k * comp_stride] *
125*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n + 0) * block_size + e * 3 * elem_size] +
126*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] *
127*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size];
1282b730f8bSJeremy L Thompson       }
1292b730f8bSJeremy L Thompson     }
1302b730f8bSJeremy L Thompson   }
1310c73c039SSebastian Grimberg   return CEED_ERROR_SUCCESS;
132fcbe8c06SSebastian Grimberg }
1330c73c039SSebastian Grimberg 
13494648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedUnsignedNoTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp,
135*ad70ee2cSJeremy L Thompson                                                                                    const CeedInt block_size, const CeedInt comp_stride, CeedInt start,
13694648b7dSSebastian Grimberg                                                                                    CeedInt stop, CeedInt num_elem, CeedInt elem_size,
13794648b7dSSebastian Grimberg                                                                                    CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
13894648b7dSSebastian Grimberg   // Restriction with (unsigned) tridiagonal transformation
1390c73c039SSebastian Grimberg   CeedElemRestriction_Ref *impl;
140*ad70ee2cSJeremy L Thompson 
1410c73c039SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
142*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
1437c1dbaffSSebastian Grimberg     CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1447c1dbaffSSebastian Grimberg       CeedInt n = 0;
145*ad70ee2cSJeremy L Thompson 
146*ad70ee2cSJeremy L Thompson       CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
147*ad70ee2cSJeremy L Thompson         vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
148*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] *
149*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size]) +
150*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + (n + 1) * block_size + e * elem_size] + k * comp_stride] *
151*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n + 2) * block_size + e * 3 * elem_size]);
1527c1dbaffSSebastian Grimberg       }
1537c1dbaffSSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
154*ad70ee2cSJeremy L Thompson         CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
155*ad70ee2cSJeremy L Thompson           vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
156*ad70ee2cSJeremy L Thompson               uu[impl->offsets[j + (n - 1) * block_size + e * elem_size] + k * comp_stride] *
157*ad70ee2cSJeremy L Thompson                   abs(impl->curl_orients[j + (3 * n + 0) * block_size + e * 3 * elem_size]) +
158*ad70ee2cSJeremy L Thompson               uu[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] *
159*ad70ee2cSJeremy L Thompson                   abs(impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size]) +
160*ad70ee2cSJeremy L Thompson               uu[impl->offsets[j + (n + 1) * block_size + e * elem_size] + k * comp_stride] *
161*ad70ee2cSJeremy L Thompson                   abs(impl->curl_orients[j + (3 * n + 2) * block_size + e * 3 * elem_size]);
1627c1dbaffSSebastian Grimberg         }
1637c1dbaffSSebastian Grimberg       }
164*ad70ee2cSJeremy L Thompson       CeedPragmaSIMD for (CeedInt j = 0; j < block_size; j++) {
165*ad70ee2cSJeremy L Thompson         vv[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] =
166*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + (n - 1) * block_size + e * elem_size] + k * comp_stride] *
167*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n + 0) * block_size + e * 3 * elem_size]) +
168*ad70ee2cSJeremy L Thompson             uu[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] *
169*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size]);
1707c1dbaffSSebastian Grimberg       }
1717c1dbaffSSebastian Grimberg     }
1727c1dbaffSSebastian Grimberg   }
1737c1dbaffSSebastian Grimberg   return CEED_ERROR_SUCCESS;
1747c1dbaffSSebastian Grimberg }
1757c1dbaffSSebastian Grimberg 
176*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyStridedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
17794648b7dSSebastian Grimberg                                                                     CeedInt start, CeedInt stop, CeedInt num_elem, CeedInt elem_size,
17894648b7dSSebastian Grimberg                                                                     CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
17994648b7dSSebastian Grimberg   // No offsets provided, identity restriction
180d1d35e2fSjeremylt   bool has_backend_strides;
181*ad70ee2cSJeremy L Thompson 
1822b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides));
183d1d35e2fSjeremylt   if (has_backend_strides) {
184d1d35e2fSjeremylt     // CPU backend strides are {1, elem_size, elem_size*num_comp}
1857f90ec76Sjeremylt     // This if brach is left separate to allow better inlining
186*ad70ee2cSJeremy L Thompson     for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
1872b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1882b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
189*ad70ee2cSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(block_size, num_elem - e); j++) {
190*ad70ee2cSJeremy L Thompson             vv[n + k * elem_size + (e + j) * elem_size * num_comp] += uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset];
1912b730f8bSJeremy L Thompson           }
1922b730f8bSJeremy L Thompson         }
1932b730f8bSJeremy L Thompson       }
1942b730f8bSJeremy L Thompson     }
1957f90ec76Sjeremylt   } else {
1967f90ec76Sjeremylt     // User provided strides
1977f90ec76Sjeremylt     CeedInt strides[3];
198*ad70ee2cSJeremy L Thompson 
1992b730f8bSJeremy L Thompson     CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides));
200*ad70ee2cSJeremy L Thompson     for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
2012b730f8bSJeremy L Thompson       CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
2022b730f8bSJeremy L Thompson         CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
203*ad70ee2cSJeremy L Thompson           CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(block_size, num_elem - e); j++) {
2042b730f8bSJeremy L Thompson             vv[n * strides[0] + k * strides[1] + (e + j) * strides[2]] +=
205*ad70ee2cSJeremy L Thompson                 uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset];
2062b730f8bSJeremy L Thompson           }
2072b730f8bSJeremy L Thompson         }
2082b730f8bSJeremy L Thompson       }
2092b730f8bSJeremy L Thompson     }
210523b8ea0Sjeremylt   }
21194648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
21294648b7dSSebastian Grimberg }
21394648b7dSSebastian Grimberg 
214*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyStandardTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
21594648b7dSSebastian Grimberg                                                                      const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
21694648b7dSSebastian Grimberg                                                                      CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
217fcbe8c06SSebastian Grimberg   // Default restriction with offsets
21894648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
219*ad70ee2cSJeremy L Thompson 
22094648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
221*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
2222b730f8bSJeremy L Thompson     for (CeedInt k = 0; k < num_comp; k++) {
223*ad70ee2cSJeremy L Thompson       for (CeedInt i = 0; i < elem_size * block_size; i += block_size) {
2248d94b059Sjeremylt         // Iteration bound set to discard padding elements
225*ad70ee2cSJeremy L Thompson         for (CeedInt j = i; j < i + CeedIntMin(block_size, num_elem - e); j++) {
226*ad70ee2cSJeremy L Thompson           vv[impl->offsets[j + e * elem_size] + k * comp_stride] += uu[elem_size * (k * block_size + e * num_comp) + j - v_offset];
227fcbe8c06SSebastian Grimberg         }
228fcbe8c06SSebastian Grimberg       }
229fcbe8c06SSebastian Grimberg     }
230fcbe8c06SSebastian Grimberg   }
23194648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
23294648b7dSSebastian Grimberg }
23394648b7dSSebastian Grimberg 
234*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyOrientedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
23594648b7dSSebastian Grimberg                                                                      const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
23694648b7dSSebastian Grimberg                                                                      CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
237fcbe8c06SSebastian Grimberg   // Restriction with orientations
23894648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
239*ad70ee2cSJeremy L Thompson 
24094648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
241*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
242fcbe8c06SSebastian Grimberg     for (CeedInt k = 0; k < num_comp; k++) {
243*ad70ee2cSJeremy L Thompson       for (CeedInt i = 0; i < elem_size * block_size; i += block_size) {
244fcbe8c06SSebastian Grimberg         // Iteration bound set to discard padding elements
245*ad70ee2cSJeremy L Thompson         for (CeedInt j = i; j < i + CeedIntMin(block_size, num_elem - e); j++) {
246f30b1135SSebastian Grimberg           vv[impl->offsets[j + e * elem_size] + k * comp_stride] +=
247*ad70ee2cSJeremy L Thompson               uu[elem_size * (k * block_size + e * num_comp) + j - v_offset] * (impl->orients[j + e * elem_size] ? -1.0 : 1.0);
248fcbe8c06SSebastian Grimberg         }
249fcbe8c06SSebastian Grimberg       }
250fcbe8c06SSebastian Grimberg     }
251fcbe8c06SSebastian Grimberg   }
25294648b7dSSebastian Grimberg   return CEED_ERROR_SUCCESS;
25394648b7dSSebastian Grimberg }
25494648b7dSSebastian Grimberg 
255*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApplyCurlOrientedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
25694648b7dSSebastian Grimberg                                                                          const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedInt num_elem,
25794648b7dSSebastian Grimberg                                                                          CeedInt elem_size, CeedInt v_offset, const CeedScalar *uu, CeedScalar *vv) {
25877d1c127SSebastian Grimberg   // Restriction with tridiagonal transformation
25994648b7dSSebastian Grimberg   CeedElemRestriction_Ref *impl;
260*ad70ee2cSJeremy L Thompson 
26194648b7dSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
262*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
263fcbe8c06SSebastian Grimberg     for (CeedInt k = 0; k < num_comp; k++) {
264fcbe8c06SSebastian Grimberg       // Iteration bound set to discard padding elements
265*ad70ee2cSJeremy L Thompson       CeedInt block_end = CeedIntMin(block_size, num_elem - e), n = 0;
266*ad70ee2cSJeremy L Thompson       for (CeedInt j = 0; j < block_end; j++) {
267*ad70ee2cSJeremy L Thompson         vv[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] +=
268*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] *
269*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size] +
270*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n + 1) * block_size + j - v_offset] *
271*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n + 3) * block_size + e * 3 * elem_size];
2720c73c039SSebastian Grimberg       }
2730c73c039SSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
274*ad70ee2cSJeremy L Thompson         for (CeedInt j = 0; j < block_end; j++) {
275*ad70ee2cSJeremy L Thompson           vv[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] +=
276*ad70ee2cSJeremy L Thompson               uu[e * elem_size * num_comp + (k * elem_size + n - 1) * block_size + j - v_offset] *
277*ad70ee2cSJeremy L Thompson                   impl->curl_orients[j + (3 * n - 1) * block_size + e * 3 * elem_size] +
278*ad70ee2cSJeremy L Thompson               uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] *
279*ad70ee2cSJeremy L Thompson                   impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size] +
280*ad70ee2cSJeremy L Thompson               uu[e * elem_size * num_comp + (k * elem_size + n + 1) * block_size + j - v_offset] *
281*ad70ee2cSJeremy L Thompson                   impl->curl_orients[j + (3 * n + 3) * block_size + e * 3 * elem_size];
2820c73c039SSebastian Grimberg         }
2830c73c039SSebastian Grimberg       }
284*ad70ee2cSJeremy L Thompson       for (CeedInt j = 0; j < block_end; j++) {
285*ad70ee2cSJeremy L Thompson         vv[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] +=
286*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n - 1) * block_size + j - v_offset] *
287*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n - 1) * block_size + e * 3 * elem_size] +
288*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] *
289*ad70ee2cSJeremy L Thompson                 impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size];
29021617c04Sjeremylt       }
291b435c5a6Srezgarshakeri     }
2922b730f8bSJeremy L Thompson   }
293e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
29421617c04Sjeremylt }
29521617c04Sjeremylt 
29694648b7dSSebastian Grimberg static inline int CeedElemRestrictionApplyCurlOrientedUnsignedTranspose_Ref_Core(CeedElemRestriction r, const CeedInt num_comp,
297*ad70ee2cSJeremy L Thompson                                                                                  const CeedInt block_size, const CeedInt comp_stride, CeedInt start,
29894648b7dSSebastian Grimberg                                                                                  CeedInt stop, CeedInt num_elem, CeedInt elem_size, CeedInt v_offset,
29994648b7dSSebastian Grimberg                                                                                  const CeedScalar *uu, CeedScalar *vv) {
30094648b7dSSebastian Grimberg   // Restriction with (unsigned) tridiagonal transformation
3017c1dbaffSSebastian Grimberg   CeedElemRestriction_Ref *impl;
302*ad70ee2cSJeremy L Thompson 
3037c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
304*ad70ee2cSJeremy L Thompson   for (CeedInt e = start * block_size; e < stop * block_size; e += block_size) {
3057c1dbaffSSebastian Grimberg     for (CeedInt k = 0; k < num_comp; k++) {
3067c1dbaffSSebastian Grimberg       // Iteration bound set to discard padding elements
307*ad70ee2cSJeremy L Thompson       CeedInt       n         = 0;
308*ad70ee2cSJeremy L Thompson       const CeedInt block_end = CeedIntMin(block_size, num_elem - e);
309*ad70ee2cSJeremy L Thompson 
310*ad70ee2cSJeremy L Thompson       for (CeedInt j = 0; j < block_end; j++) {
311*ad70ee2cSJeremy L Thompson         vv[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] +=
312*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] *
313*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size]) +
314*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n + 1) * block_size + j - v_offset] *
315*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n + 3) * block_size + e * 3 * elem_size]);
3167c1dbaffSSebastian Grimberg       }
3177c1dbaffSSebastian Grimberg       for (n = 1; n < elem_size - 1; n++) {
318*ad70ee2cSJeremy L Thompson         for (CeedInt j = 0; j < block_end; j++) {
319*ad70ee2cSJeremy L Thompson           vv[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] +=
320*ad70ee2cSJeremy L Thompson               uu[e * elem_size * num_comp + (k * elem_size + n - 1) * block_size + j - v_offset] *
321*ad70ee2cSJeremy L Thompson                   abs(impl->curl_orients[j + (3 * n - 1) * block_size + e * 3 * elem_size]) +
322*ad70ee2cSJeremy L Thompson               uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] *
323*ad70ee2cSJeremy L Thompson                   abs(impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size]) +
324*ad70ee2cSJeremy L Thompson               uu[e * elem_size * num_comp + (k * elem_size + n + 1) * block_size + j - v_offset] *
325*ad70ee2cSJeremy L Thompson                   abs(impl->curl_orients[j + (3 * n + 3) * block_size + e * 3 * elem_size]);
3267c1dbaffSSebastian Grimberg         }
3277c1dbaffSSebastian Grimberg       }
328*ad70ee2cSJeremy L Thompson       for (CeedInt j = 0; j < block_end; j++) {
329*ad70ee2cSJeremy L Thompson         vv[impl->offsets[j + n * block_size + e * elem_size] + k * comp_stride] +=
330*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n - 1) * block_size + j - v_offset] *
331*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n - 1) * block_size + e * 3 * elem_size]) +
332*ad70ee2cSJeremy L Thompson             uu[e * elem_size * num_comp + (k * elem_size + n) * block_size + j - v_offset] *
333*ad70ee2cSJeremy L Thompson                 abs(impl->curl_orients[j + (3 * n + 1) * block_size + e * 3 * elem_size]);
3347c1dbaffSSebastian Grimberg       }
3357c1dbaffSSebastian Grimberg     }
3367c1dbaffSSebastian Grimberg   }
3377c1dbaffSSebastian Grimberg   return CEED_ERROR_SUCCESS;
3387c1dbaffSSebastian Grimberg }
3397c1dbaffSSebastian Grimberg 
340*ad70ee2cSJeremy L Thompson static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size,
341*ad70ee2cSJeremy L Thompson                                                     const CeedInt comp_stride, CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs,
342*ad70ee2cSJeremy L Thompson                                                     bool use_orients, CeedVector u, CeedVector v, CeedRequest *request) {
343*ad70ee2cSJeremy L Thompson   CeedInt             num_elem, elem_size, v_offset;
344*ad70ee2cSJeremy L Thompson   CeedRestrictionType rstr_type;
3457c1dbaffSSebastian Grimberg   const CeedScalar   *uu;
3467c1dbaffSSebastian Grimberg   CeedScalar         *vv;
347*ad70ee2cSJeremy L Thompson 
3487c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem));
3497c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size));
350*ad70ee2cSJeremy L Thompson   v_offset = start * block_size * elem_size * num_comp;
3517c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(r, &rstr_type));
35294648b7dSSebastian Grimberg   CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu));
353*ad70ee2cSJeremy L Thompson 
35494648b7dSSebastian Grimberg   if (t_mode == CEED_TRANSPOSE) {
35594648b7dSSebastian Grimberg     // Sum into for transpose mode, E-vector to L-vector
35694648b7dSSebastian Grimberg     CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_HOST, &vv));
35794648b7dSSebastian Grimberg   } else {
35894648b7dSSebastian Grimberg     // Overwrite for notranspose mode, L-vector to E-vector
35994648b7dSSebastian Grimberg     CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_HOST, &vv));
36094648b7dSSebastian Grimberg   }
36194648b7dSSebastian Grimberg   if (t_mode == CEED_TRANSPOSE) {
3627c1dbaffSSebastian Grimberg     // Restriction from E-vector to L-vector
3637c1dbaffSSebastian Grimberg     // Performing v += r^T * u
3647c1dbaffSSebastian Grimberg     // uu has shape [elem_size, num_comp, num_elem], row-major
3657c1dbaffSSebastian Grimberg     // vv has shape [nnodes, num_comp]
3667c1dbaffSSebastian Grimberg     // Sum into for transpose mode
3677c1dbaffSSebastian Grimberg     switch (rstr_type) {
3687c1dbaffSSebastian Grimberg       case CEED_RESTRICTION_STRIDED:
369*ad70ee2cSJeremy L Thompson         CeedElemRestrictionApplyStridedTranspose_Ref_Core(r, num_comp, block_size, start, stop, num_elem, elem_size, v_offset, uu, vv);
37094648b7dSSebastian Grimberg         break;
37161a27d74SSebastian Grimberg       case CEED_RESTRICTION_STANDARD:
372*ad70ee2cSJeremy L Thompson         CeedElemRestrictionApplyStandardTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu, vv);
37394648b7dSSebastian Grimberg         break;
3747c1dbaffSSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
37594648b7dSSebastian Grimberg         if (use_signs) {
376*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyOrientedTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
377*ad70ee2cSJeremy L Thompson                                                              vv);
37894648b7dSSebastian Grimberg         } else {
379*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyStandardTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
380*ad70ee2cSJeremy L Thompson                                                              vv);
38194648b7dSSebastian Grimberg         }
38294648b7dSSebastian Grimberg         break;
38394648b7dSSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
38494648b7dSSebastian Grimberg         if (use_signs && use_orients) {
385*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyCurlOrientedTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
38694648b7dSSebastian Grimberg                                                                  vv);
38794648b7dSSebastian Grimberg         } else if (use_orients) {
388*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyCurlOrientedUnsignedTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size,
38994648b7dSSebastian Grimberg                                                                          v_offset, uu, vv);
39094648b7dSSebastian Grimberg         } else {
391*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyStandardTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
392*ad70ee2cSJeremy L Thompson                                                              vv);
39394648b7dSSebastian Grimberg         }
39494648b7dSSebastian Grimberg         break;
39594648b7dSSebastian Grimberg     }
39694648b7dSSebastian Grimberg   } else {
39794648b7dSSebastian Grimberg     // Restriction from L-vector to E-vector
39894648b7dSSebastian Grimberg     // Perform: v = r * u
39994648b7dSSebastian Grimberg     // vv has shape [elem_size, num_comp, num_elem], row-major
40094648b7dSSebastian Grimberg     // uu has shape [nnodes, num_comp]
40194648b7dSSebastian Grimberg     // Overwrite for notranspose mode
40294648b7dSSebastian Grimberg     switch (rstr_type) {
40394648b7dSSebastian Grimberg       case CEED_RESTRICTION_STRIDED:
404*ad70ee2cSJeremy L Thompson         CeedElemRestrictionApplyStridedNoTranspose_Ref_Core(r, num_comp, block_size, start, stop, num_elem, elem_size, v_offset, uu, vv);
40594648b7dSSebastian Grimberg         break;
40661a27d74SSebastian Grimberg       case CEED_RESTRICTION_STANDARD:
407*ad70ee2cSJeremy L Thompson         CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
408*ad70ee2cSJeremy L Thompson                                                              vv);
40994648b7dSSebastian Grimberg         break;
41094648b7dSSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
41194648b7dSSebastian Grimberg         if (use_signs) {
412*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyOrientedNoTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
41394648b7dSSebastian Grimberg                                                                vv);
41494648b7dSSebastian Grimberg         } else {
415*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
41661a27d74SSebastian Grimberg                                                                vv);
41794648b7dSSebastian Grimberg         }
41894648b7dSSebastian Grimberg         break;
41994648b7dSSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
42094648b7dSSebastian Grimberg         if (use_signs && use_orients) {
421*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyCurlOrientedNoTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset,
422*ad70ee2cSJeremy L Thompson                                                                    uu, vv);
42394648b7dSSebastian Grimberg         } else if (use_orients) {
424*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyCurlOrientedUnsignedNoTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size,
42594648b7dSSebastian Grimberg                                                                            v_offset, uu, vv);
42694648b7dSSebastian Grimberg         } else {
427*ad70ee2cSJeremy L Thompson           CeedElemRestrictionApplyStandardNoTranspose_Ref_Core(r, num_comp, block_size, comp_stride, start, stop, num_elem, elem_size, v_offset, uu,
42861a27d74SSebastian Grimberg                                                                vv);
42994648b7dSSebastian Grimberg         }
43094648b7dSSebastian Grimberg         break;
43194648b7dSSebastian Grimberg     }
4327c1dbaffSSebastian Grimberg   }
4337c1dbaffSSebastian Grimberg   CeedCallBackend(CeedVectorRestoreArrayRead(u, &uu));
4347c1dbaffSSebastian Grimberg   CeedCallBackend(CeedVectorRestoreArray(v, &vv));
4357c1dbaffSSebastian Grimberg   if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL;
4367c1dbaffSSebastian Grimberg   return CEED_ERROR_SUCCESS;
4377c1dbaffSSebastian Grimberg }
4387c1dbaffSSebastian Grimberg 
4397c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
440f10650afSjeremylt // ElemRestriction Apply - Common Sizes
441f10650afSjeremylt //------------------------------------------------------------------------------
442*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_110(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4437c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4447c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4457c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
446d979a051Sjeremylt }
447d979a051Sjeremylt 
448*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_111(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4497c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4507c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4517c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4524d2a38eeSjeremylt }
4534d2a38eeSjeremylt 
454*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_180(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4557c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4567c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4577c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
4589c36149bSjeremylt }
4599c36149bSjeremylt 
460*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_181(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4617c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4627c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4637c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
4649c36149bSjeremylt }
4659c36149bSjeremylt 
466*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_310(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4677c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4687c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4697c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
470d979a051Sjeremylt }
471d979a051Sjeremylt 
472*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_311(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4737c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4747c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4757c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
476d979a051Sjeremylt }
477d979a051Sjeremylt 
478*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_380(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_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, 3, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
482d979a051Sjeremylt }
483d979a051Sjeremylt 
484*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_381(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4857c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4867c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4877c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
488d979a051Sjeremylt }
489d979a051Sjeremylt 
490bf4d1581Sjeremylt // LCOV_EXCL_START
491*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4927c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
4937c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
4947c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
495d979a051Sjeremylt }
496bf4d1581Sjeremylt // LCOV_EXCL_STOP
497d979a051Sjeremylt 
498*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
4997c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
5007c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
5017c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
502d979a051Sjeremylt }
503d979a051Sjeremylt 
504bf4d1581Sjeremylt // LCOV_EXCL_START
505*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
5067c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
5077c1dbaffSSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
5087c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, comp_stride, start, stop, t_mode, use_signs, use_orients, u, v, request);
509d979a051Sjeremylt }
510bf4d1581Sjeremylt // LCOV_EXCL_STOP
511d979a051Sjeremylt 
512*ad70ee2cSJeremy L Thompson static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, const CeedInt num_comp, const CeedInt block_size, const CeedInt comp_stride,
5137c1dbaffSSebastian Grimberg                                             CeedInt start, CeedInt stop, CeedTransposeMode t_mode, bool use_signs, bool use_orients, CeedVector u,
5140c73c039SSebastian Grimberg                                             CeedVector v, CeedRequest *request) {
5157c1dbaffSSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, t_mode, use_signs, use_orients, u, v, request);
5164d2a38eeSjeremylt }
5174d2a38eeSjeremylt 
518f10650afSjeremylt //------------------------------------------------------------------------------
519f10650afSjeremylt // ElemRestriction Apply
520f10650afSjeremylt //------------------------------------------------------------------------------
5212b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
522*ad70ee2cSJeremy L Thompson   CeedInt                  num_block, block_size, num_comp, comp_stride;
523*ad70ee2cSJeremy L Thompson   CeedElemRestriction_Ref *impl;
524*ad70ee2cSJeremy L Thompson 
525*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_block));
526*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &block_size));
5272b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5282b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5292b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
530*ad70ee2cSJeremy L Thompson   return impl->Apply(r, num_comp, block_size, comp_stride, 0, num_block, t_mode, true, true, u, v, request);
531f30b1135SSebastian Grimberg }
532f30b1135SSebastian Grimberg 
533f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
534f30b1135SSebastian Grimberg // ElemRestriction Apply Unsigned
535f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
536f30b1135SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
537*ad70ee2cSJeremy L Thompson   CeedInt                  num_block, block_size, num_comp, comp_stride;
538*ad70ee2cSJeremy L Thompson   CeedElemRestriction_Ref *impl;
539*ad70ee2cSJeremy L Thompson 
540*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_block));
541*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &block_size));
542f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
543f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
544f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
545*ad70ee2cSJeremy L Thompson   return impl->Apply(r, num_comp, block_size, comp_stride, 0, num_block, t_mode, false, true, u, v, request);
5467c1dbaffSSebastian Grimberg }
5477c1dbaffSSebastian Grimberg 
5487c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
5497c1dbaffSSebastian Grimberg // ElemRestriction Apply Unoriented
5507c1dbaffSSebastian Grimberg //------------------------------------------------------------------------------
5517c1dbaffSSebastian Grimberg static int CeedElemRestrictionApplyUnoriented_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
552*ad70ee2cSJeremy L Thompson   CeedInt                  num_block, block_size, num_comp, comp_stride;
553*ad70ee2cSJeremy L Thompson   CeedElemRestriction_Ref *impl;
554*ad70ee2cSJeremy L Thompson 
555*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_block));
556*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &block_size));
5577c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5587c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5597c1dbaffSSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
560*ad70ee2cSJeremy L Thompson   return impl->Apply(r, num_comp, block_size, comp_stride, 0, num_block, t_mode, false, false, u, v, request);
5619c36149bSjeremylt }
562be9261b7Sjeremylt 
563f10650afSjeremylt //------------------------------------------------------------------------------
564f10650afSjeremylt // ElemRestriction Apply Block
565f10650afSjeremylt //------------------------------------------------------------------------------
5662b730f8bSJeremy L Thompson static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
567074cb416Sjeremylt                                              CeedRequest *request) {
568*ad70ee2cSJeremy L Thompson   CeedInt                  block_size, num_comp, comp_stride;
569*ad70ee2cSJeremy L Thompson   CeedElemRestriction_Ref *impl;
570*ad70ee2cSJeremy L Thompson 
571*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &block_size));
5722b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
5732b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
5742b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
575*ad70ee2cSJeremy L Thompson   return impl->Apply(r, num_comp, block_size, comp_stride, block, block + 1, t_mode, true, true, u, v, request);
5769c36149bSjeremylt }
577be9261b7Sjeremylt 
578f10650afSjeremylt //------------------------------------------------------------------------------
579bd33150aSjeremylt // ElemRestriction Get Offsets
580bd33150aSjeremylt //------------------------------------------------------------------------------
5812b730f8bSJeremy L Thompson static int CeedElemRestrictionGetOffsets_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) {
582bd33150aSjeremylt   Ceed                     ceed;
583*ad70ee2cSJeremy L Thompson   CeedElemRestriction_Ref *impl;
584*ad70ee2cSJeremy L Thompson 
585*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
5862b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
587bd33150aSjeremylt 
5886574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
589bd33150aSjeremylt 
590bd33150aSjeremylt   *offsets = impl->offsets;
591e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
592bd33150aSjeremylt }
593bd33150aSjeremylt 
594bd33150aSjeremylt //------------------------------------------------------------------------------
59577d1c127SSebastian Grimberg // ElemRestriction Get Orientations
59677d1c127SSebastian Grimberg //------------------------------------------------------------------------------
59777d1c127SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) {
59877d1c127SSebastian Grimberg   Ceed                     ceed;
599*ad70ee2cSJeremy L Thompson   CeedElemRestriction_Ref *impl;
600*ad70ee2cSJeremy L Thompson 
601*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
60277d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
60377d1c127SSebastian Grimberg 
604fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
60577d1c127SSebastian Grimberg 
60677d1c127SSebastian Grimberg   *orients = impl->orients;
60777d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
60877d1c127SSebastian Grimberg }
60977d1c127SSebastian Grimberg 
61077d1c127SSebastian Grimberg //------------------------------------------------------------------------------
61177d1c127SSebastian Grimberg // ElemRestriction Get Curl-Conforming Orientations
61277d1c127SSebastian Grimberg //------------------------------------------------------------------------------
6130c73c039SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) {
61477d1c127SSebastian Grimberg   Ceed                     ceed;
615*ad70ee2cSJeremy L Thompson   CeedElemRestriction_Ref *impl;
616*ad70ee2cSJeremy L Thompson 
617*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
61877d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
61977d1c127SSebastian Grimberg 
620fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
62177d1c127SSebastian Grimberg 
62277d1c127SSebastian Grimberg   *curl_orients = impl->curl_orients;
62377d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
62477d1c127SSebastian Grimberg }
62577d1c127SSebastian Grimberg 
62677d1c127SSebastian Grimberg //------------------------------------------------------------------------------
627f10650afSjeremylt // ElemRestriction Destroy
628f10650afSjeremylt //------------------------------------------------------------------------------
62921617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) {
630fe2413ffSjeremylt   CeedElemRestriction_Ref *impl;
63121617c04Sjeremylt 
632*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
6332b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->offsets_allocated));
63477d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->orients_allocated));
63577d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->curl_orients_allocated));
6362b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
637e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
63821617c04Sjeremylt }
63921617c04Sjeremylt 
640f10650afSjeremylt //------------------------------------------------------------------------------
641f10650afSjeremylt // ElemRestriction Create
642f10650afSjeremylt //------------------------------------------------------------------------------
643fcbe8c06SSebastian Grimberg int CeedElemRestrictionCreate_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients,
6440c73c039SSebastian Grimberg                                   const CeedInt8 *curl_orients, CeedElemRestriction r) {
645*ad70ee2cSJeremy L Thompson   Ceed                     ceed;
646*ad70ee2cSJeremy L Thompson   CeedInt                  num_elem, elem_size, num_block, block_size, num_comp, comp_stride;
647*ad70ee2cSJeremy L Thompson   CeedRestrictionType      rstr_type;
64821617c04Sjeremylt   CeedElemRestriction_Ref *impl;
649*ad70ee2cSJeremy L Thompson 
650*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(r, &ceed));
6512b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem));
6522b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size));
653*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_block));
654*ad70ee2cSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &block_size));
6552b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
6562b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
657*ad70ee2cSJeremy L Thompson   CeedInt layout[3] = {1, elem_size, elem_size * num_comp};
65821617c04Sjeremylt 
6596574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Only MemType = HOST supported");
6602b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
6613661185eSjeremylt 
66292fe105eSJeremy L Thompson   // Offsets data
663fcbe8c06SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(r, &rstr_type));
664fcbe8c06SSebastian Grimberg   if (rstr_type != CEED_RESTRICTION_STRIDED) {
6653661185eSjeremylt     const char *resource;
666*ad70ee2cSJeremy L Thompson 
667*ad70ee2cSJeremy L Thompson     // Check indices for ref or memcheck backends
668*ad70ee2cSJeremy L Thompson     CeedCallBackend(CeedGetResource(ceed, &resource));
6692b730f8bSJeremy L Thompson     if (!strcmp(resource, "/cpu/self/ref/serial") || !strcmp(resource, "/cpu/self/ref/blocked") || !strcmp(resource, "/cpu/self/memcheck/serial") ||
670d1d35e2fSjeremylt         !strcmp(resource, "/cpu/self/memcheck/blocked")) {
671e79b91d9SJeremy L Thompson       CeedSize l_size;
6723661185eSjeremylt 
673*ad70ee2cSJeremy L Thompson       CeedCallBackend(CeedElemRestrictionGetLVectorSize(r, &l_size));
6742b730f8bSJeremy L Thompson       for (CeedInt i = 0; i < num_elem * elem_size; i++) {
6756574a04fSJeremy L Thompson         CeedCheck(offsets[i] >= 0 && offsets[i] + (num_comp - 1) * comp_stride < l_size, ceed, CEED_ERROR_BACKEND,
6766574a04fSJeremy L Thompson                   "Restriction offset %" CeedInt_FMT " (%" CeedInt_FMT ") out of range [0, %" CeedInt_FMT "]", i, offsets[i], l_size);
6772b730f8bSJeremy L Thompson       }
6782b730f8bSJeremy L Thompson     }
6793661185eSjeremylt 
68092fe105eSJeremy L Thompson     // Copy data
681d1d35e2fSjeremylt     switch (copy_mode) {
68221617c04Sjeremylt       case CEED_COPY_VALUES:
6832b730f8bSJeremy L Thompson         CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->offsets_allocated));
6842b730f8bSJeremy L Thompson         memcpy(impl->offsets_allocated, offsets, num_elem * elem_size * sizeof(offsets[0]));
685d979a051Sjeremylt         impl->offsets = impl->offsets_allocated;
68621617c04Sjeremylt         break;
68721617c04Sjeremylt       case CEED_OWN_POINTER:
688d979a051Sjeremylt         impl->offsets_allocated = (CeedInt *)offsets;
689d979a051Sjeremylt         impl->offsets           = impl->offsets_allocated;
69021617c04Sjeremylt         break;
69121617c04Sjeremylt       case CEED_USE_POINTER:
692d979a051Sjeremylt         impl->offsets = offsets;
69321617c04Sjeremylt     }
694fcbe8c06SSebastian Grimberg 
695fcbe8c06SSebastian Grimberg     // Orientation data
696fcbe8c06SSebastian Grimberg     if (rstr_type == CEED_RESTRICTION_ORIENTED) {
6970305e208SSebastian Grimberg       CeedCheck(orients != NULL, ceed, CEED_ERROR_BACKEND, "No orients array provided for oriented restriction");
698fcbe8c06SSebastian Grimberg       switch (copy_mode) {
699fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
700fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->orients_allocated));
701fcbe8c06SSebastian Grimberg           memcpy(impl->orients_allocated, orients, num_elem * elem_size * sizeof(orients[0]));
702fcbe8c06SSebastian Grimberg           impl->orients = impl->orients_allocated;
703fcbe8c06SSebastian Grimberg           break;
704fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
705fcbe8c06SSebastian Grimberg           impl->orients_allocated = (bool *)orients;
706fcbe8c06SSebastian Grimberg           impl->orients           = impl->orients_allocated;
707fcbe8c06SSebastian Grimberg           break;
708fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
709fcbe8c06SSebastian Grimberg           impl->orients = orients;
710fcbe8c06SSebastian Grimberg       }
711fcbe8c06SSebastian Grimberg     } else if (rstr_type == CEED_RESTRICTION_CURL_ORIENTED) {
7120305e208SSebastian Grimberg       CeedCheck(curl_orients != NULL, ceed, CEED_ERROR_BACKEND, "No curl_orients array provided for oriented restriction");
713fcbe8c06SSebastian Grimberg       switch (copy_mode) {
714fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
715fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * 3 * elem_size, &impl->curl_orients_allocated));
716fcbe8c06SSebastian Grimberg           memcpy(impl->curl_orients_allocated, curl_orients, num_elem * 3 * elem_size * sizeof(curl_orients[0]));
717fcbe8c06SSebastian Grimberg           impl->curl_orients = impl->curl_orients_allocated;
718fcbe8c06SSebastian Grimberg           break;
719fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
7200c73c039SSebastian Grimberg           impl->curl_orients_allocated = (CeedInt8 *)curl_orients;
721fcbe8c06SSebastian Grimberg           impl->curl_orients           = impl->curl_orients_allocated;
722fcbe8c06SSebastian Grimberg           break;
723fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
724fcbe8c06SSebastian Grimberg           impl->curl_orients = curl_orients;
725fcbe8c06SSebastian Grimberg       }
726fcbe8c06SSebastian Grimberg     }
72792fe105eSJeremy L Thompson   }
728fe2413ffSjeremylt 
7292b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetData(r, impl));
7302b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetELayout(r, layout));
7312b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", CeedElemRestrictionApply_Ref));
732f30b1135SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Ref));
7337c1dbaffSSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnoriented", CeedElemRestrictionApplyUnoriented_Ref));
7342b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", CeedElemRestrictionApplyBlock_Ref));
7352b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOffsets", CeedElemRestrictionGetOffsets_Ref));
73677d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOrientations", CeedElemRestrictionGetOrientations_Ref));
73777d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Ref));
7382b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", CeedElemRestrictionDestroy_Ref));
739d979a051Sjeremylt 
740*ad70ee2cSJeremy L Thompson   // Set apply function based upon num_comp, block_size, and comp_stride
741*ad70ee2cSJeremy L Thompson   CeedInt index = -1;
742*ad70ee2cSJeremy L Thompson 
743*ad70ee2cSJeremy L Thompson   if (block_size < 10) index = 100 * num_comp + 10 * block_size + (comp_stride == 1);
744*ad70ee2cSJeremy L Thompson   switch (index) {
745d979a051Sjeremylt     case 110:
746d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_110;
747d979a051Sjeremylt       break;
748d979a051Sjeremylt     case 111:
749d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_111;
750d979a051Sjeremylt       break;
751d979a051Sjeremylt     case 180:
752d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_180;
753d979a051Sjeremylt       break;
754d979a051Sjeremylt     case 181:
755d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_181;
756d979a051Sjeremylt       break;
757d979a051Sjeremylt     case 310:
758d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_310;
759d979a051Sjeremylt       break;
760d979a051Sjeremylt     case 311:
761d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_311;
762d979a051Sjeremylt       break;
763d979a051Sjeremylt     case 380:
764d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_380;
765d979a051Sjeremylt       break;
766d979a051Sjeremylt     case 381:
767d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_381;
768d979a051Sjeremylt       break;
769bf4d1581Sjeremylt     // LCOV_EXCL_START
770d979a051Sjeremylt     case 510:
771d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_510;
772d979a051Sjeremylt       break;
773bf4d1581Sjeremylt     // LCOV_EXCL_STOP
774d979a051Sjeremylt     case 511:
775d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_511;
776d979a051Sjeremylt       break;
777bf4d1581Sjeremylt     // LCOV_EXCL_START
778d979a051Sjeremylt     case 580:
779d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_580;
780d979a051Sjeremylt       break;
781bf4d1581Sjeremylt     // LCOV_EXCL_STOP
782d979a051Sjeremylt     case 581:
783d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_581;
784d979a051Sjeremylt       break;
785d979a051Sjeremylt     default:
786d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_Core;
787d979a051Sjeremylt       break;
788d979a051Sjeremylt   }
789e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
79021617c04Sjeremylt }
791fc0567d9Srezgarshakeri 
792fc0567d9Srezgarshakeri //------------------------------------------------------------------------------
793