xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision 1f37b403ef08d286079519fbc830f486b0f4359b)
1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details.
4d7b241e6Sjeremylt //
5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral
7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and
8d7b241e6Sjeremylt // source code availability see http://github.com/ceed.
9d7b241e6Sjeremylt //
10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for
13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including
14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early
15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
16d7b241e6Sjeremylt 
17d7b241e6Sjeremylt #include <ceed-impl.h>
18d863ab9bSjeremylt #include <ceed-backend.h>
19d7b241e6Sjeremylt 
20d7b241e6Sjeremylt /// @file
21d7b241e6Sjeremylt /// Implementation of public CeedElemRestriction interfaces
22d7b241e6Sjeremylt ///
23dfdf5a53Sjeremylt /// @addtogroup CeedElemRestriction
24d7b241e6Sjeremylt /// @{
25d7b241e6Sjeremylt 
26d7b241e6Sjeremylt /**
27b11c1e72Sjeremylt   @brief Create a CeedElemRestriction
28d7b241e6Sjeremylt 
29b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
30b11c1e72Sjeremylt   @param nelem      Number of elements described in the @a indices array
31b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
32d7b241e6Sjeremylt   @param ndof       The total size of the input CeedVector to which the
33d7b241e6Sjeremylt                       restriction will be applied. This size may include data
34d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
35d7b241e6Sjeremylt                       different types of elements.
36b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
37b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
38b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
39ecf6354eSJed Brown   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list
40d7b241e6Sjeremylt                       of the indices (into the input CeedVector) for the unknowns
41d7b241e6Sjeremylt                       corresponding to element i, where 0 <= i < @a nelements.
42d7b241e6Sjeremylt                       All indices must be in the range [0, @a ndof).
434ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
44b11c1e72Sjeremylt                       CeedElemRestriction will be stored
45d7b241e6Sjeremylt 
46b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
47dfdf5a53Sjeremylt 
48dfdf5a53Sjeremylt   @ref Basic
49b11c1e72Sjeremylt **/
50d7b241e6Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
51d7b241e6Sjeremylt                               CeedInt ndof, CeedInt ncomp, CeedMemType mtype,
52d7b241e6Sjeremylt                               CeedCopyMode cmode, const CeedInt *indices,
534ce2993fSjeremylt                               CeedElemRestriction *rstr) {
54d7b241e6Sjeremylt   int ierr;
55d7b241e6Sjeremylt 
565fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
575fe0d4faSjeremylt     Ceed delegate;
585fe0d4faSjeremylt     ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr);
595fe0d4faSjeremylt 
605fe0d4faSjeremylt     if (!delegate)
61d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
625fe0d4faSjeremylt 
635fe0d4faSjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize,
645fe0d4faSjeremylt                                      ndof, ncomp, mtype, cmode,
654ce2993fSjeremylt                                      indices, rstr); CeedChk(ierr);
665fe0d4faSjeremylt     return 0;
675fe0d4faSjeremylt   }
685fe0d4faSjeremylt 
694ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
704ce2993fSjeremylt   (*rstr)->ceed = ceed;
71d7b241e6Sjeremylt   ceed->refcount++;
724ce2993fSjeremylt   (*rstr)->refcount = 1;
734ce2993fSjeremylt   (*rstr)->nelem = nelem;
744ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
754ce2993fSjeremylt   (*rstr)->ndof = ndof;
764ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
774ce2993fSjeremylt   (*rstr)->nblk = nelem;
784ce2993fSjeremylt   (*rstr)->blksize = 1;
794ce2993fSjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr);
80d7b241e6Sjeremylt   return 0;
81d7b241e6Sjeremylt }
82d7b241e6Sjeremylt 
83d7b241e6Sjeremylt /**
84b11c1e72Sjeremylt   @brief Create an identity CeedElemRestriction
85d7b241e6Sjeremylt 
86b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
87b11c1e72Sjeremylt   @param nelem      Number of elements described in the @a indices array
88b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
89d7b241e6Sjeremylt   @param ndof       The total size of the input CeedVector to which the
90d7b241e6Sjeremylt                       restriction will be applied. This size may include data
91d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
92b11c1e72Sjeremylt                       different types of elements
93b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
944ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
95b11c1e72Sjeremylt                       CeedElemRestriction will be stored
96d7b241e6Sjeremylt 
97b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
98dfdf5a53Sjeremylt 
99dfdf5a53Sjeremylt   @ref Basic
100b11c1e72Sjeremylt **/
1014b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem,
1024b8bea3bSJed Brown                                       CeedInt elemsize,
1034ce2993fSjeremylt                                       CeedInt ndof, CeedInt ncomp, CeedElemRestriction *rstr) {
104d7b241e6Sjeremylt   int ierr;
105d7b241e6Sjeremylt 
1065fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
1075fe0d4faSjeremylt     Ceed delegate;
1085fe0d4faSjeremylt     ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr);
1095fe0d4faSjeremylt 
1105fe0d4faSjeremylt     if (!delegate)
1114b8bea3bSJed Brown       return CeedError(ceed, 1,
1125fe0d4faSjeremylt                        "Backend does not support ElemRestrictionCreate");
1135fe0d4faSjeremylt 
1145fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize,
1154ce2993fSjeremylt            ndof, ncomp, rstr); CeedChk(ierr);
1165fe0d4faSjeremylt     return 0;
1175fe0d4faSjeremylt   }
1185fe0d4faSjeremylt 
1194ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
1204ce2993fSjeremylt   (*rstr)->ceed = ceed;
121d7b241e6Sjeremylt   ceed->refcount++;
1224ce2993fSjeremylt   (*rstr)->refcount = 1;
1234ce2993fSjeremylt   (*rstr)->nelem = nelem;
1244ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
1254ce2993fSjeremylt   (*rstr)->ndof = ndof;
1264ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
1274ce2993fSjeremylt   (*rstr)->nblk = nelem;
1284ce2993fSjeremylt   (*rstr)->blksize = 1;
1291dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
1301dfeef1dSjeremylt                                      *rstr);
1314b8bea3bSJed Brown   CeedChk(ierr);
132d7b241e6Sjeremylt   return 0;
133d7b241e6Sjeremylt }
134d7b241e6Sjeremylt 
135d7b241e6Sjeremylt /**
136b11c1e72Sjeremylt   @brief Permute and pad indices for a blocked restriction
137d7b241e6Sjeremylt 
138ecf6354eSJed Brown   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list
139d7b241e6Sjeremylt                       of the indices (into the input CeedVector) for the unknowns
140d7b241e6Sjeremylt                       corresponding to element i, where 0 <= i < @a nelements.
141d7b241e6Sjeremylt                       All indices must be in the range [0, @a ndof).
142ecf6354eSJed Brown   @param blkindices Array of permuted and padded indices of
143ecf6354eSJed Brown                       shape [@a nblk, @a elemsize, @a blksize].
144d7b241e6Sjeremylt   @param nblk       Number of blocks
145d7b241e6Sjeremylt   @param nelem      Number of elements
146d7b241e6Sjeremylt   @param blksize    Number of elements in a block
147d7b241e6Sjeremylt   @param elemsize   Size of each element
148d7b241e6Sjeremylt 
149b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
150b11c1e72Sjeremylt 
151dfdf5a53Sjeremylt   @ref Utility
152b11c1e72Sjeremylt **/
153dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices,
154d7b241e6Sjeremylt                           CeedInt nblk, CeedInt nelem,
155d7b241e6Sjeremylt                           CeedInt blksize, CeedInt elemsize) {
156d7b241e6Sjeremylt   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
157d7b241e6Sjeremylt     for (int j = 0; j < blksize; j++)
158d7b241e6Sjeremylt       for (int k = 0; k < elemsize; k++)
159d7b241e6Sjeremylt         blkindices[e*elemsize + k*blksize + j]
160d7b241e6Sjeremylt           = indices[CeedIntMin(e+j,nelem-1)*elemsize + k];
161dfdf5a53Sjeremylt   return 0;
162d7b241e6Sjeremylt }
163d7b241e6Sjeremylt 
164d7b241e6Sjeremylt /**
165b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
166d7b241e6Sjeremylt 
167d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
168d7b241e6Sjeremylt   @param nelem      Number of elements described in the @a indices array.
169b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
170b11c1e72Sjeremylt   @param blksize    Number of elements in a block
171d7b241e6Sjeremylt   @param ndof       The total size of the input CeedVector to which the
172d7b241e6Sjeremylt                       restriction will be applied. This size may include data
173d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
174d7b241e6Sjeremylt                       different types of elements.
175b11c1e72Sjeremylt   @param ncomp      Number of components stored at each node
176b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
177b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
178ecf6354eSJed Brown   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list
179d7b241e6Sjeremylt                       of the indices (into the input CeedVector) for the unknowns
180d7b241e6Sjeremylt                       corresponding to element i, where 0 <= i < @a nelements.
181d7b241e6Sjeremylt                       All indices must be in the range [0, @a ndof). The
182d7b241e6Sjeremylt                       backend will permute and pad this array to the desired
183d7b241e6Sjeremylt                       ordering for the blocksize, which is typically given by the
184d7b241e6Sjeremylt                       backend. The default reordering is to interlace elements.
1854ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
186b11c1e72Sjeremylt                       CeedElemRestriction will be stored
187d7b241e6Sjeremylt 
188b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
189dfdf5a53Sjeremylt 
190dfdf5a53Sjeremylt   @ref Advanced
191b11c1e72Sjeremylt  **/
192d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
193d7b241e6Sjeremylt                                      CeedInt blksize, CeedInt ndof, CeedInt ncomp,
194d7b241e6Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
1954ce2993fSjeremylt                                      const CeedInt *indices,
1964ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
197d7b241e6Sjeremylt   int ierr;
198d7b241e6Sjeremylt   CeedInt *blkindices;
199d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
200d7b241e6Sjeremylt 
2015fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
2025fe0d4faSjeremylt     Ceed delegate;
2035fe0d4faSjeremylt     ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr);
2045fe0d4faSjeremylt 
2055fe0d4faSjeremylt     if (!delegate)
206d7b241e6Sjeremylt       return CeedError(ceed, 1,
207d7b241e6Sjeremylt                        "Backend does not support ElemRestrictionCreateBlocked");
2085fe0d4faSjeremylt 
2095fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize,
2105fe0d4faSjeremylt                                             blksize, ndof, ncomp, mtype, cmode,
2114ce2993fSjeremylt                                             indices, rstr); CeedChk(ierr);
2125fe0d4faSjeremylt     return 0;
2135fe0d4faSjeremylt   }
214d7b241e6Sjeremylt 
2154ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
216d7b241e6Sjeremylt 
217d7b241e6Sjeremylt   if (indices) {
218de686571SJeremy L Thompson     ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr);
2194b8bea3bSJed Brown     ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize,
2204b8bea3bSJed Brown                                  elemsize);
221dfdf5a53Sjeremylt     CeedChk(ierr);
222d7b241e6Sjeremylt   } else {
223d7b241e6Sjeremylt     blkindices = NULL;
224d7b241e6Sjeremylt   }
225d7b241e6Sjeremylt 
2264ce2993fSjeremylt   (*rstr)->ceed = ceed;
227d7b241e6Sjeremylt   ceed->refcount++;
2284ce2993fSjeremylt   (*rstr)->refcount = 1;
2294ce2993fSjeremylt   (*rstr)->nelem = nelem;
2304ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2314ce2993fSjeremylt   (*rstr)->ndof = ndof;
2324ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
2334ce2993fSjeremylt   (*rstr)->nblk = nblk;
2344ce2993fSjeremylt   (*rstr)->blksize = blksize;
235667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
2364ce2993fSjeremylt          (const CeedInt *) blkindices, *rstr);
237d7b241e6Sjeremylt   CeedChk(ierr);
238d7b241e6Sjeremylt 
239d7b241e6Sjeremylt   if (cmode == CEED_OWN_POINTER)
240d7b241e6Sjeremylt     ierr = CeedFree(&indices); CeedChk(ierr);
241d7b241e6Sjeremylt 
242d7b241e6Sjeremylt   return 0;
243d7b241e6Sjeremylt }
244d7b241e6Sjeremylt 
245b11c1e72Sjeremylt /**
246b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
247b11c1e72Sjeremylt 
2484ce2993fSjeremylt   @param rstr  CeedElemRestriction
249b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
250b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
251b11c1e72Sjeremylt 
252b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
253dfdf5a53Sjeremylt 
254dfdf5a53Sjeremylt   @ref Advanced
255b11c1e72Sjeremylt **/
2564ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
257d7b241e6Sjeremylt                                     CeedVector *evec) {
258d7b241e6Sjeremylt   int ierr;
259d7b241e6Sjeremylt   CeedInt n, m;
2604ce2993fSjeremylt   m = rstr->ndof * rstr->ncomp;
2614ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
262d7b241e6Sjeremylt   if (lvec) {
2634ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
264d7b241e6Sjeremylt   }
265d7b241e6Sjeremylt   if (evec) {
2664ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
267d7b241e6Sjeremylt   }
268d7b241e6Sjeremylt   return 0;
269d7b241e6Sjeremylt }
270d7b241e6Sjeremylt 
271d7b241e6Sjeremylt /**
272b11c1e72Sjeremylt   @brief Restrict an L-vector to an E-vector or apply transpose
273d7b241e6Sjeremylt 
2744ce2993fSjeremylt   @param rstr    CeedElemRestriction
275d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
276d7b241e6Sjeremylt   @param lmode   Ordering of the ncomp components
277d7b241e6Sjeremylt   @param u       Input vector (of size @a ndof when tmode=CEED_NOTRANSPOSE)
278d7b241e6Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when tmode=CEED_NOTRANSPOSE)
279d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
280b11c1e72Sjeremylt 
281b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
282dfdf5a53Sjeremylt 
283dfdf5a53Sjeremylt   @ref Advanced
284b11c1e72Sjeremylt **/
2854ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
286d7b241e6Sjeremylt                              CeedTransposeMode lmode,
287d7b241e6Sjeremylt                              CeedVector u, CeedVector v, CeedRequest *request) {
288d7b241e6Sjeremylt   CeedInt m,n;
289d7b241e6Sjeremylt   int ierr;
290d7b241e6Sjeremylt 
291d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
2924ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
2934ce2993fSjeremylt     n = rstr->ndof * rstr->ncomp;
294d7b241e6Sjeremylt   } else {
2954ce2993fSjeremylt     m = rstr->ndof * rstr->ncomp;
2964ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
297d7b241e6Sjeremylt   }
298d7b241e6Sjeremylt   if (n != u->length)
2994ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
300d7b241e6Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
301d7b241e6Sjeremylt                      u->length, m, n);
302d7b241e6Sjeremylt   if (m != v->length)
3034ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
304d7b241e6Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
305d7b241e6Sjeremylt                      v->length, m, n);
3064ce2993fSjeremylt   ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr);
307d7b241e6Sjeremylt 
308d7b241e6Sjeremylt   return 0;
309d7b241e6Sjeremylt }
310d7b241e6Sjeremylt 
311d7b241e6Sjeremylt /**
312be9261b7Sjeremylt   @brief Restrict an L-vector to a block of an E-vector or apply transpose
313be9261b7Sjeremylt 
314be9261b7Sjeremylt   @param rstr    CeedElemRestriction
315*1f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
316*1f37b403Sjeremylt                  elements [0 : blksize] and block=3 will handle elements
317*1f37b403Sjeremylt                  [3*blksize : 4*blksize]
318be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
319be9261b7Sjeremylt   @param lmode   Ordering of the ncomp components
320be9261b7Sjeremylt   @param u       Input vector (of size @a ndof when tmode=CEED_NOTRANSPOSE)
321be9261b7Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when tmode=CEED_NOTRANSPOSE)
322be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
323be9261b7Sjeremylt 
324be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
325be9261b7Sjeremylt 
326be9261b7Sjeremylt   @ref Advanced
327be9261b7Sjeremylt **/
328be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
329be9261b7Sjeremylt                                   CeedTransposeMode tmode,
330be9261b7Sjeremylt                                   CeedTransposeMode lmode,
331be9261b7Sjeremylt                                   CeedVector u, CeedVector v,
332be9261b7Sjeremylt                                   CeedRequest *request) {
333be9261b7Sjeremylt   CeedInt m,n;
334be9261b7Sjeremylt   int ierr;
335be9261b7Sjeremylt 
336be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
337be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
338be9261b7Sjeremylt     n = rstr->ndof * rstr->ncomp;
339be9261b7Sjeremylt   } else {
340be9261b7Sjeremylt     m = rstr->ndof * rstr->ncomp;
341be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
342be9261b7Sjeremylt   }
343be9261b7Sjeremylt   if (n != u->length)
344be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
345be9261b7Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
346be9261b7Sjeremylt                      u->length, m, n);
347be9261b7Sjeremylt   if (m != v->length)
348be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
349be9261b7Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
350be9261b7Sjeremylt                      v->length, m, n);
351be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
352be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
353be9261b7Sjeremylt                      "Cannot retrieve block %d, element %d > total elements %d",
354be9261b7Sjeremylt                      block, rstr->blksize*block, rstr->nelem);
355be9261b7Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request);
356be9261b7Sjeremylt   CeedChk(ierr);
357be9261b7Sjeremylt 
358be9261b7Sjeremylt   return 0;
359be9261b7Sjeremylt }
360be9261b7Sjeremylt 
361be9261b7Sjeremylt /**
3624ce2993fSjeremylt   @brief Get the Ceed associated with a CeedElemRestriction
3634ce2993fSjeremylt 
3644ce2993fSjeremylt   @param rstr             CeedElemRestriction
3654ce2993fSjeremylt   @param[out] ceed        Variable to store Ceed
3664ce2993fSjeremylt 
3674ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3684ce2993fSjeremylt 
36923617272Sjeremylt   @ref Advanced
3704ce2993fSjeremylt **/
3714ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
3724ce2993fSjeremylt   *ceed = rstr->ceed;
3734ce2993fSjeremylt   return 0;
3744ce2993fSjeremylt }
3754ce2993fSjeremylt 
3764ce2993fSjeremylt /**
377b11c1e72Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
378d7b241e6Sjeremylt 
3794ce2993fSjeremylt   @param rstr             CeedElemRestriction
3804ce2993fSjeremylt   @param[out] numelements Variable to store number of elements
381b11c1e72Sjeremylt 
382b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
383dfdf5a53Sjeremylt 
38423617272Sjeremylt   @ref Advanced
385b11c1e72Sjeremylt **/
3864ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
3874ce2993fSjeremylt                                       CeedInt *numelem) {
3884ce2993fSjeremylt   *numelem = rstr->nelem;
3894ce2993fSjeremylt   return 0;
3904ce2993fSjeremylt }
3914ce2993fSjeremylt 
3924ce2993fSjeremylt /**
3934ce2993fSjeremylt   @brief Get the size of elements in the CeedElemRestriction
3944ce2993fSjeremylt 
3954ce2993fSjeremylt   @param rstr             CeedElemRestriction
3964ce2993fSjeremylt   @param[out] elemsize    Variable to store size of elements
3974ce2993fSjeremylt 
3984ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3994ce2993fSjeremylt 
40023617272Sjeremylt   @ref Advanced
4014ce2993fSjeremylt **/
4024ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
4034ce2993fSjeremylt                                       CeedInt *elemsize) {
4044ce2993fSjeremylt   *elemsize = rstr->elemsize;
4054ce2993fSjeremylt   return 0;
4064ce2993fSjeremylt }
4074ce2993fSjeremylt 
4084ce2993fSjeremylt /**
4094ce2993fSjeremylt   @brief Get the number of degrees of freedom in the range of a
4104ce2993fSjeremylt          CeedElemRestriction
4114ce2993fSjeremylt 
4124ce2993fSjeremylt   @param rstr             CeedElemRestriction
4134ce2993fSjeremylt   @param[out] numdof      Variable to store number of DoFs
4144ce2993fSjeremylt 
4154ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4164ce2993fSjeremylt 
41723617272Sjeremylt   @ref Advanced
4184ce2993fSjeremylt **/
4194ce2993fSjeremylt int CeedElemRestrictionGetNumDoF(CeedElemRestriction rstr,
4204ce2993fSjeremylt                                  CeedInt *numdof) {
4214ce2993fSjeremylt   *numdof = rstr->ndof;
4224ce2993fSjeremylt   return 0;
4234ce2993fSjeremylt }
4244ce2993fSjeremylt 
4254ce2993fSjeremylt /**
4264ce2993fSjeremylt   @brief Get the number of components in the elements of a
4274ce2993fSjeremylt          CeedElemRestriction
4284ce2993fSjeremylt 
4294ce2993fSjeremylt   @param rstr             CeedElemRestriction
4304ce2993fSjeremylt   @param[out] numcomp     Variable to store number of components
4314ce2993fSjeremylt 
4324ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4334ce2993fSjeremylt 
43423617272Sjeremylt   @ref Advanced
4354ce2993fSjeremylt **/
4364ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
4374ce2993fSjeremylt                                         CeedInt *numcomp) {
4384ce2993fSjeremylt   *numcomp = rstr->ncomp;
4394ce2993fSjeremylt   return 0;
4404ce2993fSjeremylt }
4414ce2993fSjeremylt 
4424ce2993fSjeremylt /**
4434ce2993fSjeremylt   @brief Get the number of blocks in a CeedElemRestriction
4444ce2993fSjeremylt 
4454ce2993fSjeremylt   @param rstr             CeedElemRestriction
4464ce2993fSjeremylt   @param[out] numblock    Variable to store number of blocks
4474ce2993fSjeremylt 
4484ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4494ce2993fSjeremylt 
45023617272Sjeremylt   @ref Advanced
4514ce2993fSjeremylt **/
4524ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
4534ce2993fSjeremylt                                     CeedInt *numblock) {
4544ce2993fSjeremylt   *numblock = rstr->nblk;
4554ce2993fSjeremylt   return 0;
4564ce2993fSjeremylt }
4574ce2993fSjeremylt 
4584ce2993fSjeremylt /**
4594ce2993fSjeremylt   @brief Get the size of blocks in the CeedElemRestriction
4604ce2993fSjeremylt 
4614ce2993fSjeremylt   @param r                CeedElemRestriction
4624ce2993fSjeremylt   @param[out] blksize     Variable to store size of blocks
4634ce2993fSjeremylt 
4644ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4654ce2993fSjeremylt 
46623617272Sjeremylt   @ref Advanced
4674ce2993fSjeremylt **/
4684ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
4694ce2993fSjeremylt                                     CeedInt *blksize) {
4704ce2993fSjeremylt   *blksize = rstr->blksize;
4714ce2993fSjeremylt   return 0;
4724ce2993fSjeremylt }
4734ce2993fSjeremylt 
4744ce2993fSjeremylt /**
4754ce2993fSjeremylt   @brief Get the backend data of a CeedElemRestriction
4764ce2993fSjeremylt 
4774ce2993fSjeremylt   @param r                CeedElemRestriction
4784ce2993fSjeremylt   @param[out] data        Variable to store data
4794ce2993fSjeremylt 
4804ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4814ce2993fSjeremylt 
48223617272Sjeremylt   @ref Advanced
4834ce2993fSjeremylt **/
4844ce2993fSjeremylt int CeedElemRestrictionGetData(CeedElemRestriction rstr,
4854ce2993fSjeremylt                                void* *data) {
4864ce2993fSjeremylt   *data = rstr->data;
487d7b241e6Sjeremylt   return 0;
488d7b241e6Sjeremylt }
489d7b241e6Sjeremylt 
490d7b241e6Sjeremylt /**
491fe2413ffSjeremylt   @brief Set the backend data of a CeedElemRestriction
492fe2413ffSjeremylt 
493fe2413ffSjeremylt   @param[out] r           CeedElemRestriction
494fe2413ffSjeremylt   @param data             Data to set
495fe2413ffSjeremylt 
496fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
497fe2413ffSjeremylt 
498fe2413ffSjeremylt   @ref Advanced
499fe2413ffSjeremylt **/
500fe2413ffSjeremylt int CeedElemRestrictionSetData(CeedElemRestriction rstr,
501fe2413ffSjeremylt                                void* *data) {
502fe2413ffSjeremylt   rstr->data = *data;
503fe2413ffSjeremylt   return 0;
504fe2413ffSjeremylt }
505fe2413ffSjeremylt 
506fe2413ffSjeremylt /**
507b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
508b11c1e72Sjeremylt 
5094ce2993fSjeremylt   @param rstr CeedElemRestriction to destroy
510b11c1e72Sjeremylt 
511b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
512dfdf5a53Sjeremylt 
513dfdf5a53Sjeremylt   @ref Basic
514b11c1e72Sjeremylt **/
5154ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
516d7b241e6Sjeremylt   int ierr;
517d7b241e6Sjeremylt 
5184ce2993fSjeremylt   if (!*rstr || --(*rstr)->refcount > 0) return 0;
5194ce2993fSjeremylt   if ((*rstr)->Destroy) {
5204ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
521d7b241e6Sjeremylt   }
5224ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
5234ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
524d7b241e6Sjeremylt   return 0;
525d7b241e6Sjeremylt }
526d7b241e6Sjeremylt 
527d7b241e6Sjeremylt /// @}
528