xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision 1469ee4db5408bea386be07ffe83911249daf977)
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;
58aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
59aefd8378Sjeremylt     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;
109aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
110aefd8378Sjeremylt     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;
205aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
206aefd8378Sjeremylt     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 /**
365*1469ee4dSjeremylt   @brief Get the multiplicity of DoFs in a CeedElemRestriction
366*1469ee4dSjeremylt 
367*1469ee4dSjeremylt   @param rstr      CeedElemRestriction
368*1469ee4dSjeremylt   @param[out] mult Vector to store multiplicity (of size ndof)
369*1469ee4dSjeremylt 
370*1469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
371*1469ee4dSjeremylt 
372*1469ee4dSjeremylt   @ref Advanced
373*1469ee4dSjeremylt **/
374*1469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
375*1469ee4dSjeremylt                              CeedVector mult) {
376*1469ee4dSjeremylt   int ierr;
377*1469ee4dSjeremylt   CeedVector evec;
378*1469ee4dSjeremylt 
379*1469ee4dSjeremylt   // Create and set evec
380*1469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
381*1469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
382*1469ee4dSjeremylt 
383*1469ee4dSjeremylt   // Apply to get multiplicity
384*1469ee4dSjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, CEED_NOTRANSPOSE, evec,
385*1469ee4dSjeremylt                                   mult, CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
386*1469ee4dSjeremylt 
387*1469ee4dSjeremylt   // Cleanup
388*1469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
389*1469ee4dSjeremylt 
390*1469ee4dSjeremylt   return 0;
391*1469ee4dSjeremylt }
392*1469ee4dSjeremylt 
393*1469ee4dSjeremylt /**
3944ce2993fSjeremylt   @brief Get the Ceed associated with a CeedElemRestriction
3954ce2993fSjeremylt 
3964ce2993fSjeremylt   @param rstr             CeedElemRestriction
3974ce2993fSjeremylt   @param[out] ceed        Variable to store Ceed
3984ce2993fSjeremylt 
3994ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4004ce2993fSjeremylt 
40123617272Sjeremylt   @ref Advanced
4024ce2993fSjeremylt **/
4034ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
4044ce2993fSjeremylt   *ceed = rstr->ceed;
4054ce2993fSjeremylt   return 0;
4064ce2993fSjeremylt }
4074ce2993fSjeremylt 
4084ce2993fSjeremylt /**
409b11c1e72Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
410d7b241e6Sjeremylt 
4114ce2993fSjeremylt   @param rstr             CeedElemRestriction
4124ce2993fSjeremylt   @param[out] numelements Variable to store number of elements
413b11c1e72Sjeremylt 
414b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
415dfdf5a53Sjeremylt 
41623617272Sjeremylt   @ref Advanced
417b11c1e72Sjeremylt **/
4184ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
4194ce2993fSjeremylt                                       CeedInt *numelem) {
4204ce2993fSjeremylt   *numelem = rstr->nelem;
4214ce2993fSjeremylt   return 0;
4224ce2993fSjeremylt }
4234ce2993fSjeremylt 
4244ce2993fSjeremylt /**
4254ce2993fSjeremylt   @brief Get the size of elements in the CeedElemRestriction
4264ce2993fSjeremylt 
4274ce2993fSjeremylt   @param rstr             CeedElemRestriction
4284ce2993fSjeremylt   @param[out] elemsize    Variable to store size of elements
4294ce2993fSjeremylt 
4304ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4314ce2993fSjeremylt 
43223617272Sjeremylt   @ref Advanced
4334ce2993fSjeremylt **/
4344ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
4354ce2993fSjeremylt                                       CeedInt *elemsize) {
4364ce2993fSjeremylt   *elemsize = rstr->elemsize;
4374ce2993fSjeremylt   return 0;
4384ce2993fSjeremylt }
4394ce2993fSjeremylt 
4404ce2993fSjeremylt /**
4414ce2993fSjeremylt   @brief Get the number of degrees of freedom in the range of a
4424ce2993fSjeremylt          CeedElemRestriction
4434ce2993fSjeremylt 
4444ce2993fSjeremylt   @param rstr             CeedElemRestriction
4454ce2993fSjeremylt   @param[out] numdof      Variable to store number of DoFs
4464ce2993fSjeremylt 
4474ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4484ce2993fSjeremylt 
44923617272Sjeremylt   @ref Advanced
4504ce2993fSjeremylt **/
4514ce2993fSjeremylt int CeedElemRestrictionGetNumDoF(CeedElemRestriction rstr,
4524ce2993fSjeremylt                                  CeedInt *numdof) {
4534ce2993fSjeremylt   *numdof = rstr->ndof;
4544ce2993fSjeremylt   return 0;
4554ce2993fSjeremylt }
4564ce2993fSjeremylt 
4574ce2993fSjeremylt /**
4584ce2993fSjeremylt   @brief Get the number of components in the elements of a
4594ce2993fSjeremylt          CeedElemRestriction
4604ce2993fSjeremylt 
4614ce2993fSjeremylt   @param rstr             CeedElemRestriction
4624ce2993fSjeremylt   @param[out] numcomp     Variable to store number of components
4634ce2993fSjeremylt 
4644ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4654ce2993fSjeremylt 
46623617272Sjeremylt   @ref Advanced
4674ce2993fSjeremylt **/
4684ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
4694ce2993fSjeremylt                                         CeedInt *numcomp) {
4704ce2993fSjeremylt   *numcomp = rstr->ncomp;
4714ce2993fSjeremylt   return 0;
4724ce2993fSjeremylt }
4734ce2993fSjeremylt 
4744ce2993fSjeremylt /**
4754ce2993fSjeremylt   @brief Get the number of blocks in a CeedElemRestriction
4764ce2993fSjeremylt 
4774ce2993fSjeremylt   @param rstr             CeedElemRestriction
4784ce2993fSjeremylt   @param[out] numblock    Variable to store number of blocks
4794ce2993fSjeremylt 
4804ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4814ce2993fSjeremylt 
48223617272Sjeremylt   @ref Advanced
4834ce2993fSjeremylt **/
4844ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
4854ce2993fSjeremylt                                     CeedInt *numblock) {
4864ce2993fSjeremylt   *numblock = rstr->nblk;
4874ce2993fSjeremylt   return 0;
4884ce2993fSjeremylt }
4894ce2993fSjeremylt 
4904ce2993fSjeremylt /**
4914ce2993fSjeremylt   @brief Get the size of blocks in the CeedElemRestriction
4924ce2993fSjeremylt 
4934ce2993fSjeremylt   @param r                CeedElemRestriction
4944ce2993fSjeremylt   @param[out] blksize     Variable to store size of blocks
4954ce2993fSjeremylt 
4964ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4974ce2993fSjeremylt 
49823617272Sjeremylt   @ref Advanced
4994ce2993fSjeremylt **/
5004ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
5014ce2993fSjeremylt                                     CeedInt *blksize) {
5024ce2993fSjeremylt   *blksize = rstr->blksize;
5034ce2993fSjeremylt   return 0;
5044ce2993fSjeremylt }
5054ce2993fSjeremylt 
5064ce2993fSjeremylt /**
5074ce2993fSjeremylt   @brief Get the backend data of a CeedElemRestriction
5084ce2993fSjeremylt 
5094ce2993fSjeremylt   @param r                CeedElemRestriction
5104ce2993fSjeremylt   @param[out] data        Variable to store data
5114ce2993fSjeremylt 
5124ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5134ce2993fSjeremylt 
51423617272Sjeremylt   @ref Advanced
5154ce2993fSjeremylt **/
5164ce2993fSjeremylt int CeedElemRestrictionGetData(CeedElemRestriction rstr,
5174ce2993fSjeremylt                                void* *data) {
5184ce2993fSjeremylt   *data = rstr->data;
519d7b241e6Sjeremylt   return 0;
520d7b241e6Sjeremylt }
521d7b241e6Sjeremylt 
522d7b241e6Sjeremylt /**
523fe2413ffSjeremylt   @brief Set the backend data of a CeedElemRestriction
524fe2413ffSjeremylt 
525fe2413ffSjeremylt   @param[out] r           CeedElemRestriction
526fe2413ffSjeremylt   @param data             Data to set
527fe2413ffSjeremylt 
528fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
529fe2413ffSjeremylt 
530fe2413ffSjeremylt   @ref Advanced
531fe2413ffSjeremylt **/
532fe2413ffSjeremylt int CeedElemRestrictionSetData(CeedElemRestriction rstr,
533fe2413ffSjeremylt                                void* *data) {
534fe2413ffSjeremylt   rstr->data = *data;
535fe2413ffSjeremylt   return 0;
536fe2413ffSjeremylt }
537fe2413ffSjeremylt 
538fe2413ffSjeremylt /**
539b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
540b11c1e72Sjeremylt 
5414ce2993fSjeremylt   @param rstr CeedElemRestriction to destroy
542b11c1e72Sjeremylt 
543b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
544dfdf5a53Sjeremylt 
545dfdf5a53Sjeremylt   @ref Basic
546b11c1e72Sjeremylt **/
5474ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
548d7b241e6Sjeremylt   int ierr;
549d7b241e6Sjeremylt 
5504ce2993fSjeremylt   if (!*rstr || --(*rstr)->refcount > 0) return 0;
5514ce2993fSjeremylt   if ((*rstr)->Destroy) {
5524ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
553d7b241e6Sjeremylt   }
5544ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
5554ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
556d7b241e6Sjeremylt   return 0;
557d7b241e6Sjeremylt }
558d7b241e6Sjeremylt 
559d7b241e6Sjeremylt /// @}
560