xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision aefd83785c2df88dfccc51fc4901501fa3238add)
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;
58*aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
59*aefd8378Sjeremylt     CeedChk(ierr);
605fe0d4faSjeremylt 
615fe0d4faSjeremylt     if (!delegate)
62d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
635fe0d4faSjeremylt 
645fe0d4faSjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize,
655fe0d4faSjeremylt                                      ndof, ncomp, mtype, cmode,
664ce2993fSjeremylt                                      indices, rstr); CeedChk(ierr);
675fe0d4faSjeremylt     return 0;
685fe0d4faSjeremylt   }
695fe0d4faSjeremylt 
704ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
714ce2993fSjeremylt   (*rstr)->ceed = ceed;
72d7b241e6Sjeremylt   ceed->refcount++;
734ce2993fSjeremylt   (*rstr)->refcount = 1;
744ce2993fSjeremylt   (*rstr)->nelem = nelem;
754ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
764ce2993fSjeremylt   (*rstr)->ndof = ndof;
774ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
784ce2993fSjeremylt   (*rstr)->nblk = nelem;
794ce2993fSjeremylt   (*rstr)->blksize = 1;
804ce2993fSjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr);
81d7b241e6Sjeremylt   return 0;
82d7b241e6Sjeremylt }
83d7b241e6Sjeremylt 
84d7b241e6Sjeremylt /**
85b11c1e72Sjeremylt   @brief Create an identity CeedElemRestriction
86d7b241e6Sjeremylt 
87b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
88b11c1e72Sjeremylt   @param nelem      Number of elements described in the @a indices array
89b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
90d7b241e6Sjeremylt   @param ndof       The total size of the input CeedVector to which the
91d7b241e6Sjeremylt                       restriction will be applied. This size may include data
92d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
93b11c1e72Sjeremylt                       different types of elements
94b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
954ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
96b11c1e72Sjeremylt                       CeedElemRestriction will be stored
97d7b241e6Sjeremylt 
98b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
99dfdf5a53Sjeremylt 
100dfdf5a53Sjeremylt   @ref Basic
101b11c1e72Sjeremylt **/
1024b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem,
1034b8bea3bSJed Brown                                       CeedInt elemsize,
1044ce2993fSjeremylt                                       CeedInt ndof, CeedInt ncomp, CeedElemRestriction *rstr) {
105d7b241e6Sjeremylt   int ierr;
106d7b241e6Sjeremylt 
1075fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
1085fe0d4faSjeremylt     Ceed delegate;
109*aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
110*aefd8378Sjeremylt     CeedChk(ierr);
1115fe0d4faSjeremylt 
1125fe0d4faSjeremylt     if (!delegate)
1134b8bea3bSJed Brown       return CeedError(ceed, 1,
1145fe0d4faSjeremylt                        "Backend does not support ElemRestrictionCreate");
1155fe0d4faSjeremylt 
1165fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize,
1174ce2993fSjeremylt            ndof, ncomp, rstr); CeedChk(ierr);
1185fe0d4faSjeremylt     return 0;
1195fe0d4faSjeremylt   }
1205fe0d4faSjeremylt 
1214ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
1224ce2993fSjeremylt   (*rstr)->ceed = ceed;
123d7b241e6Sjeremylt   ceed->refcount++;
1244ce2993fSjeremylt   (*rstr)->refcount = 1;
1254ce2993fSjeremylt   (*rstr)->nelem = nelem;
1264ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
1274ce2993fSjeremylt   (*rstr)->ndof = ndof;
1284ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
1294ce2993fSjeremylt   (*rstr)->nblk = nelem;
1304ce2993fSjeremylt   (*rstr)->blksize = 1;
1311dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
1321dfeef1dSjeremylt                                      *rstr);
1334b8bea3bSJed Brown   CeedChk(ierr);
134d7b241e6Sjeremylt   return 0;
135d7b241e6Sjeremylt }
136d7b241e6Sjeremylt 
137d7b241e6Sjeremylt /**
138b11c1e72Sjeremylt   @brief Permute and pad indices for a blocked restriction
139d7b241e6Sjeremylt 
140ecf6354eSJed Brown   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list
141d7b241e6Sjeremylt                       of the indices (into the input CeedVector) for the unknowns
142d7b241e6Sjeremylt                       corresponding to element i, where 0 <= i < @a nelements.
143d7b241e6Sjeremylt                       All indices must be in the range [0, @a ndof).
144ecf6354eSJed Brown   @param blkindices Array of permuted and padded indices of
145ecf6354eSJed Brown                       shape [@a nblk, @a elemsize, @a blksize].
146d7b241e6Sjeremylt   @param nblk       Number of blocks
147d7b241e6Sjeremylt   @param nelem      Number of elements
148d7b241e6Sjeremylt   @param blksize    Number of elements in a block
149d7b241e6Sjeremylt   @param elemsize   Size of each element
150d7b241e6Sjeremylt 
151b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
152b11c1e72Sjeremylt 
153dfdf5a53Sjeremylt   @ref Utility
154b11c1e72Sjeremylt **/
155dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices,
156d7b241e6Sjeremylt                           CeedInt nblk, CeedInt nelem,
157d7b241e6Sjeremylt                           CeedInt blksize, CeedInt elemsize) {
158d7b241e6Sjeremylt   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
159d7b241e6Sjeremylt     for (int j = 0; j < blksize; j++)
160d7b241e6Sjeremylt       for (int k = 0; k < elemsize; k++)
161d7b241e6Sjeremylt         blkindices[e*elemsize + k*blksize + j]
162d7b241e6Sjeremylt           = indices[CeedIntMin(e+j,nelem-1)*elemsize + k];
163dfdf5a53Sjeremylt   return 0;
164d7b241e6Sjeremylt }
165d7b241e6Sjeremylt 
166d7b241e6Sjeremylt /**
167b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
168d7b241e6Sjeremylt 
169d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
170d7b241e6Sjeremylt   @param nelem      Number of elements described in the @a indices array.
171b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
172b11c1e72Sjeremylt   @param blksize    Number of elements in a block
173d7b241e6Sjeremylt   @param ndof       The total size of the input CeedVector to which the
174d7b241e6Sjeremylt                       restriction will be applied. This size may include data
175d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
176d7b241e6Sjeremylt                       different types of elements.
177b11c1e72Sjeremylt   @param ncomp      Number of components stored at each node
178b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
179b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
180ecf6354eSJed Brown   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list
181d7b241e6Sjeremylt                       of the indices (into the input CeedVector) for the unknowns
182d7b241e6Sjeremylt                       corresponding to element i, where 0 <= i < @a nelements.
183d7b241e6Sjeremylt                       All indices must be in the range [0, @a ndof). The
184d7b241e6Sjeremylt                       backend will permute and pad this array to the desired
185d7b241e6Sjeremylt                       ordering for the blocksize, which is typically given by the
186d7b241e6Sjeremylt                       backend. The default reordering is to interlace elements.
1874ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
188b11c1e72Sjeremylt                       CeedElemRestriction will be stored
189d7b241e6Sjeremylt 
190b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
191dfdf5a53Sjeremylt 
192dfdf5a53Sjeremylt   @ref Advanced
193b11c1e72Sjeremylt  **/
194d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
195d7b241e6Sjeremylt                                      CeedInt blksize, CeedInt ndof, CeedInt ncomp,
196d7b241e6Sjeremylt                                      CeedMemType mtype, CeedCopyMode cmode,
1974ce2993fSjeremylt                                      const CeedInt *indices,
1984ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
199d7b241e6Sjeremylt   int ierr;
200d7b241e6Sjeremylt   CeedInt *blkindices;
201d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
202d7b241e6Sjeremylt 
2035fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
2045fe0d4faSjeremylt     Ceed delegate;
205*aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
206*aefd8378Sjeremylt     CeedChk(ierr);
2075fe0d4faSjeremylt 
2085fe0d4faSjeremylt     if (!delegate)
209d7b241e6Sjeremylt       return CeedError(ceed, 1,
210d7b241e6Sjeremylt                        "Backend does not support ElemRestrictionCreateBlocked");
2115fe0d4faSjeremylt 
2125fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize,
2135fe0d4faSjeremylt                                             blksize, ndof, ncomp, mtype, cmode,
2144ce2993fSjeremylt                                             indices, rstr); CeedChk(ierr);
2155fe0d4faSjeremylt     return 0;
2165fe0d4faSjeremylt   }
217d7b241e6Sjeremylt 
2184ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
219d7b241e6Sjeremylt 
220d7b241e6Sjeremylt   if (indices) {
221de686571SJeremy L Thompson     ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr);
2224b8bea3bSJed Brown     ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize,
2234b8bea3bSJed Brown                                  elemsize);
224dfdf5a53Sjeremylt     CeedChk(ierr);
225d7b241e6Sjeremylt   } else {
226d7b241e6Sjeremylt     blkindices = NULL;
227d7b241e6Sjeremylt   }
228d7b241e6Sjeremylt 
2294ce2993fSjeremylt   (*rstr)->ceed = ceed;
230d7b241e6Sjeremylt   ceed->refcount++;
2314ce2993fSjeremylt   (*rstr)->refcount = 1;
2324ce2993fSjeremylt   (*rstr)->nelem = nelem;
2334ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2344ce2993fSjeremylt   (*rstr)->ndof = ndof;
2354ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
2364ce2993fSjeremylt   (*rstr)->nblk = nblk;
2374ce2993fSjeremylt   (*rstr)->blksize = blksize;
238667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
2394ce2993fSjeremylt          (const CeedInt *) blkindices, *rstr);
240d7b241e6Sjeremylt   CeedChk(ierr);
241d7b241e6Sjeremylt 
242d7b241e6Sjeremylt   if (cmode == CEED_OWN_POINTER)
243d7b241e6Sjeremylt     ierr = CeedFree(&indices); CeedChk(ierr);
244d7b241e6Sjeremylt 
245d7b241e6Sjeremylt   return 0;
246d7b241e6Sjeremylt }
247d7b241e6Sjeremylt 
248b11c1e72Sjeremylt /**
249b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
250b11c1e72Sjeremylt 
2514ce2993fSjeremylt   @param rstr  CeedElemRestriction
252b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
253b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
254b11c1e72Sjeremylt 
255b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
256dfdf5a53Sjeremylt 
257dfdf5a53Sjeremylt   @ref Advanced
258b11c1e72Sjeremylt **/
2594ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
260d7b241e6Sjeremylt                                     CeedVector *evec) {
261d7b241e6Sjeremylt   int ierr;
262d7b241e6Sjeremylt   CeedInt n, m;
2634ce2993fSjeremylt   m = rstr->ndof * rstr->ncomp;
2644ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
265d7b241e6Sjeremylt   if (lvec) {
2664ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
267d7b241e6Sjeremylt   }
268d7b241e6Sjeremylt   if (evec) {
2694ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
270d7b241e6Sjeremylt   }
271d7b241e6Sjeremylt   return 0;
272d7b241e6Sjeremylt }
273d7b241e6Sjeremylt 
274d7b241e6Sjeremylt /**
275b11c1e72Sjeremylt   @brief Restrict an L-vector to an E-vector or apply transpose
276d7b241e6Sjeremylt 
2774ce2993fSjeremylt   @param rstr    CeedElemRestriction
278d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
279d7b241e6Sjeremylt   @param lmode   Ordering of the ncomp components
280d7b241e6Sjeremylt   @param u       Input vector (of size @a ndof when tmode=CEED_NOTRANSPOSE)
281d7b241e6Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when tmode=CEED_NOTRANSPOSE)
282d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
283b11c1e72Sjeremylt 
284b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
285dfdf5a53Sjeremylt 
286dfdf5a53Sjeremylt   @ref Advanced
287b11c1e72Sjeremylt **/
2884ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
289d7b241e6Sjeremylt                              CeedTransposeMode lmode,
290d7b241e6Sjeremylt                              CeedVector u, CeedVector v, CeedRequest *request) {
291d7b241e6Sjeremylt   CeedInt m,n;
292d7b241e6Sjeremylt   int ierr;
293d7b241e6Sjeremylt 
294d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
2954ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
2964ce2993fSjeremylt     n = rstr->ndof * rstr->ncomp;
297d7b241e6Sjeremylt   } else {
2984ce2993fSjeremylt     m = rstr->ndof * rstr->ncomp;
2994ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
300d7b241e6Sjeremylt   }
301d7b241e6Sjeremylt   if (n != u->length)
3024ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
303d7b241e6Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
304d7b241e6Sjeremylt                      u->length, m, n);
305d7b241e6Sjeremylt   if (m != v->length)
3064ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
307d7b241e6Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
308d7b241e6Sjeremylt                      v->length, m, n);
3094ce2993fSjeremylt   ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr);
310d7b241e6Sjeremylt 
311d7b241e6Sjeremylt   return 0;
312d7b241e6Sjeremylt }
313d7b241e6Sjeremylt 
314d7b241e6Sjeremylt /**
315be9261b7Sjeremylt   @brief Restrict an L-vector to a block of an E-vector or apply transpose
316be9261b7Sjeremylt 
317be9261b7Sjeremylt   @param rstr    CeedElemRestriction
3181f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
3191f37b403Sjeremylt                  elements [0 : blksize] and block=3 will handle elements
3201f37b403Sjeremylt                  [3*blksize : 4*blksize]
321be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
322be9261b7Sjeremylt   @param lmode   Ordering of the ncomp components
323be9261b7Sjeremylt   @param u       Input vector (of size @a ndof when tmode=CEED_NOTRANSPOSE)
324be9261b7Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when tmode=CEED_NOTRANSPOSE)
325be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
326be9261b7Sjeremylt 
327be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
328be9261b7Sjeremylt 
329be9261b7Sjeremylt   @ref Advanced
330be9261b7Sjeremylt **/
331be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
332be9261b7Sjeremylt                                   CeedTransposeMode tmode,
333be9261b7Sjeremylt                                   CeedTransposeMode lmode,
334be9261b7Sjeremylt                                   CeedVector u, CeedVector v,
335be9261b7Sjeremylt                                   CeedRequest *request) {
336be9261b7Sjeremylt   CeedInt m,n;
337be9261b7Sjeremylt   int ierr;
338be9261b7Sjeremylt 
339be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
340be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
341be9261b7Sjeremylt     n = rstr->ndof * rstr->ncomp;
342be9261b7Sjeremylt   } else {
343be9261b7Sjeremylt     m = rstr->ndof * rstr->ncomp;
344be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
345be9261b7Sjeremylt   }
346be9261b7Sjeremylt   if (n != u->length)
347be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
348be9261b7Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
349be9261b7Sjeremylt                      u->length, m, n);
350be9261b7Sjeremylt   if (m != v->length)
351be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
352be9261b7Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
353be9261b7Sjeremylt                      v->length, m, n);
354be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
355be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
356be9261b7Sjeremylt                      "Cannot retrieve block %d, element %d > total elements %d",
357be9261b7Sjeremylt                      block, rstr->blksize*block, rstr->nelem);
358be9261b7Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request);
359be9261b7Sjeremylt   CeedChk(ierr);
360be9261b7Sjeremylt 
361be9261b7Sjeremylt   return 0;
362be9261b7Sjeremylt }
363be9261b7Sjeremylt 
364be9261b7Sjeremylt /**
3654ce2993fSjeremylt   @brief Get the Ceed associated with a CeedElemRestriction
3664ce2993fSjeremylt 
3674ce2993fSjeremylt   @param rstr             CeedElemRestriction
3684ce2993fSjeremylt   @param[out] ceed        Variable to store Ceed
3694ce2993fSjeremylt 
3704ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3714ce2993fSjeremylt 
37223617272Sjeremylt   @ref Advanced
3734ce2993fSjeremylt **/
3744ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
3754ce2993fSjeremylt   *ceed = rstr->ceed;
3764ce2993fSjeremylt   return 0;
3774ce2993fSjeremylt }
3784ce2993fSjeremylt 
3794ce2993fSjeremylt /**
380b11c1e72Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
381d7b241e6Sjeremylt 
3824ce2993fSjeremylt   @param rstr             CeedElemRestriction
3834ce2993fSjeremylt   @param[out] numelements Variable to store number of elements
384b11c1e72Sjeremylt 
385b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
386dfdf5a53Sjeremylt 
38723617272Sjeremylt   @ref Advanced
388b11c1e72Sjeremylt **/
3894ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
3904ce2993fSjeremylt                                       CeedInt *numelem) {
3914ce2993fSjeremylt   *numelem = rstr->nelem;
3924ce2993fSjeremylt   return 0;
3934ce2993fSjeremylt }
3944ce2993fSjeremylt 
3954ce2993fSjeremylt /**
3964ce2993fSjeremylt   @brief Get the size of elements in the CeedElemRestriction
3974ce2993fSjeremylt 
3984ce2993fSjeremylt   @param rstr             CeedElemRestriction
3994ce2993fSjeremylt   @param[out] elemsize    Variable to store size of elements
4004ce2993fSjeremylt 
4014ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4024ce2993fSjeremylt 
40323617272Sjeremylt   @ref Advanced
4044ce2993fSjeremylt **/
4054ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
4064ce2993fSjeremylt                                       CeedInt *elemsize) {
4074ce2993fSjeremylt   *elemsize = rstr->elemsize;
4084ce2993fSjeremylt   return 0;
4094ce2993fSjeremylt }
4104ce2993fSjeremylt 
4114ce2993fSjeremylt /**
4124ce2993fSjeremylt   @brief Get the number of degrees of freedom in the range of a
4134ce2993fSjeremylt          CeedElemRestriction
4144ce2993fSjeremylt 
4154ce2993fSjeremylt   @param rstr             CeedElemRestriction
4164ce2993fSjeremylt   @param[out] numdof      Variable to store number of DoFs
4174ce2993fSjeremylt 
4184ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4194ce2993fSjeremylt 
42023617272Sjeremylt   @ref Advanced
4214ce2993fSjeremylt **/
4224ce2993fSjeremylt int CeedElemRestrictionGetNumDoF(CeedElemRestriction rstr,
4234ce2993fSjeremylt                                  CeedInt *numdof) {
4244ce2993fSjeremylt   *numdof = rstr->ndof;
4254ce2993fSjeremylt   return 0;
4264ce2993fSjeremylt }
4274ce2993fSjeremylt 
4284ce2993fSjeremylt /**
4294ce2993fSjeremylt   @brief Get the number of components in the elements of a
4304ce2993fSjeremylt          CeedElemRestriction
4314ce2993fSjeremylt 
4324ce2993fSjeremylt   @param rstr             CeedElemRestriction
4334ce2993fSjeremylt   @param[out] numcomp     Variable to store number of components
4344ce2993fSjeremylt 
4354ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4364ce2993fSjeremylt 
43723617272Sjeremylt   @ref Advanced
4384ce2993fSjeremylt **/
4394ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
4404ce2993fSjeremylt                                         CeedInt *numcomp) {
4414ce2993fSjeremylt   *numcomp = rstr->ncomp;
4424ce2993fSjeremylt   return 0;
4434ce2993fSjeremylt }
4444ce2993fSjeremylt 
4454ce2993fSjeremylt /**
4464ce2993fSjeremylt   @brief Get the number of blocks in a CeedElemRestriction
4474ce2993fSjeremylt 
4484ce2993fSjeremylt   @param rstr             CeedElemRestriction
4494ce2993fSjeremylt   @param[out] numblock    Variable to store number of blocks
4504ce2993fSjeremylt 
4514ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4524ce2993fSjeremylt 
45323617272Sjeremylt   @ref Advanced
4544ce2993fSjeremylt **/
4554ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
4564ce2993fSjeremylt                                     CeedInt *numblock) {
4574ce2993fSjeremylt   *numblock = rstr->nblk;
4584ce2993fSjeremylt   return 0;
4594ce2993fSjeremylt }
4604ce2993fSjeremylt 
4614ce2993fSjeremylt /**
4624ce2993fSjeremylt   @brief Get the size of blocks in the CeedElemRestriction
4634ce2993fSjeremylt 
4644ce2993fSjeremylt   @param r                CeedElemRestriction
4654ce2993fSjeremylt   @param[out] blksize     Variable to store size of blocks
4664ce2993fSjeremylt 
4674ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4684ce2993fSjeremylt 
46923617272Sjeremylt   @ref Advanced
4704ce2993fSjeremylt **/
4714ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
4724ce2993fSjeremylt                                     CeedInt *blksize) {
4734ce2993fSjeremylt   *blksize = rstr->blksize;
4744ce2993fSjeremylt   return 0;
4754ce2993fSjeremylt }
4764ce2993fSjeremylt 
4774ce2993fSjeremylt /**
4784ce2993fSjeremylt   @brief Get the backend data of a CeedElemRestriction
4794ce2993fSjeremylt 
4804ce2993fSjeremylt   @param r                CeedElemRestriction
4814ce2993fSjeremylt   @param[out] data        Variable to store data
4824ce2993fSjeremylt 
4834ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4844ce2993fSjeremylt 
48523617272Sjeremylt   @ref Advanced
4864ce2993fSjeremylt **/
4874ce2993fSjeremylt int CeedElemRestrictionGetData(CeedElemRestriction rstr,
4884ce2993fSjeremylt                                void* *data) {
4894ce2993fSjeremylt   *data = rstr->data;
490d7b241e6Sjeremylt   return 0;
491d7b241e6Sjeremylt }
492d7b241e6Sjeremylt 
493d7b241e6Sjeremylt /**
494fe2413ffSjeremylt   @brief Set the backend data of a CeedElemRestriction
495fe2413ffSjeremylt 
496fe2413ffSjeremylt   @param[out] r           CeedElemRestriction
497fe2413ffSjeremylt   @param data             Data to set
498fe2413ffSjeremylt 
499fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
500fe2413ffSjeremylt 
501fe2413ffSjeremylt   @ref Advanced
502fe2413ffSjeremylt **/
503fe2413ffSjeremylt int CeedElemRestrictionSetData(CeedElemRestriction rstr,
504fe2413ffSjeremylt                                void* *data) {
505fe2413ffSjeremylt   rstr->data = *data;
506fe2413ffSjeremylt   return 0;
507fe2413ffSjeremylt }
508fe2413ffSjeremylt 
509fe2413ffSjeremylt /**
510b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
511b11c1e72Sjeremylt 
5124ce2993fSjeremylt   @param rstr CeedElemRestriction to destroy
513b11c1e72Sjeremylt 
514b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
515dfdf5a53Sjeremylt 
516dfdf5a53Sjeremylt   @ref Basic
517b11c1e72Sjeremylt **/
5184ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
519d7b241e6Sjeremylt   int ierr;
520d7b241e6Sjeremylt 
5214ce2993fSjeremylt   if (!*rstr || --(*rstr)->refcount > 0) return 0;
5224ce2993fSjeremylt   if ((*rstr)->Destroy) {
5234ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
524d7b241e6Sjeremylt   }
5254ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
5264ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
527d7b241e6Sjeremylt   return 0;
528d7b241e6Sjeremylt }
529d7b241e6Sjeremylt 
530d7b241e6Sjeremylt /// @}
531