xref: /libCEED/interface/ceed-elemrestriction.c (revision fa9eac48825b2c0339cddc576d44c186940d4520)
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
328795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
338795c945Sjeremylt                       to which the restriction will be applied is of size
348795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
35d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
36d7b241e6Sjeremylt                       different types of elements.
37b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
38b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
39b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
408795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
418795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
428795c945Sjeremylt                       for the unknowns corresponding to element i, where
4334138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
4423e8ed12Sjeremylt                       [0, @a nnodes - 1].
454ce2993fSjeremylt   @param[out] rstr  Address of the variable where the newly created
46b11c1e72Sjeremylt                       CeedElemRestriction will be stored
47d7b241e6Sjeremylt 
48b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
49dfdf5a53Sjeremylt 
50dfdf5a53Sjeremylt   @ref Basic
51b11c1e72Sjeremylt **/
52d7b241e6Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize,
538795c945Sjeremylt                               CeedInt nnodes, CeedInt ncomp, CeedMemType mtype,
54d7b241e6Sjeremylt                               CeedCopyMode cmode, const CeedInt *indices,
554ce2993fSjeremylt                               CeedElemRestriction *rstr) {
56d7b241e6Sjeremylt   int ierr;
57d7b241e6Sjeremylt 
585fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
595fe0d4faSjeremylt     Ceed delegate;
60aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
61aefd8378Sjeremylt     CeedChk(ierr);
625fe0d4faSjeremylt 
635fe0d4faSjeremylt     if (!delegate)
64c042f62fSJeremy L Thompson       // LCOV_EXCL_START
65d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
66c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
675fe0d4faSjeremylt 
685fe0d4faSjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize,
698795c945Sjeremylt                                      nnodes, ncomp, mtype, cmode,
704ce2993fSjeremylt                                      indices, rstr); CeedChk(ierr);
715fe0d4faSjeremylt     return 0;
725fe0d4faSjeremylt   }
735fe0d4faSjeremylt 
744ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
754ce2993fSjeremylt   (*rstr)->ceed = ceed;
76d7b241e6Sjeremylt   ceed->refcount++;
774ce2993fSjeremylt   (*rstr)->refcount = 1;
784ce2993fSjeremylt   (*rstr)->nelem = nelem;
794ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
808795c945Sjeremylt   (*rstr)->nnodes = nnodes;
814ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
824ce2993fSjeremylt   (*rstr)->nblk = nelem;
834ce2993fSjeremylt   (*rstr)->blksize = 1;
844ce2993fSjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr);
85d7b241e6Sjeremylt   return 0;
86d7b241e6Sjeremylt }
87d7b241e6Sjeremylt 
88d7b241e6Sjeremylt /**
89b11c1e72Sjeremylt   @brief Create an identity CeedElemRestriction
90d7b241e6Sjeremylt 
91b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
92b11c1e72Sjeremylt   @param nelem      Number of elements described in the @a indices array
93b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
948795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
958795c945Sjeremylt                       to which the restriction will be applied is of size
968795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
97d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
988795c945Sjeremylt                       different types of elements.
99b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
1004ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
101b11c1e72Sjeremylt                       CeedElemRestriction will be stored
102d7b241e6Sjeremylt 
103b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
104dfdf5a53Sjeremylt 
105dfdf5a53Sjeremylt   @ref Basic
106b11c1e72Sjeremylt **/
1074b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem,
108f90c8643Sjeremylt                                       CeedInt elemsize, CeedInt nnodes,
109f90c8643Sjeremylt                                       CeedInt ncomp,
110f90c8643Sjeremylt                                       CeedElemRestriction *rstr) {
111d7b241e6Sjeremylt   int ierr;
112d7b241e6Sjeremylt 
1135fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
1145fe0d4faSjeremylt     Ceed delegate;
115aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
116aefd8378Sjeremylt     CeedChk(ierr);
1175fe0d4faSjeremylt 
1185fe0d4faSjeremylt     if (!delegate)
119c042f62fSJeremy L Thompson       // LCOV_EXCL_START
1201d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
121c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
1225fe0d4faSjeremylt 
1235fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize,
1248795c945Sjeremylt            nnodes, ncomp, rstr); CeedChk(ierr);
1255fe0d4faSjeremylt     return 0;
1265fe0d4faSjeremylt   }
1275fe0d4faSjeremylt 
1284ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
1294ce2993fSjeremylt   (*rstr)->ceed = ceed;
130d7b241e6Sjeremylt   ceed->refcount++;
1314ce2993fSjeremylt   (*rstr)->refcount = 1;
1324ce2993fSjeremylt   (*rstr)->nelem = nelem;
1334ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
1348795c945Sjeremylt   (*rstr)->nnodes = nnodes;
1354ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
1364ce2993fSjeremylt   (*rstr)->nblk = nelem;
1374ce2993fSjeremylt   (*rstr)->blksize = 1;
1381dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
1391dfeef1dSjeremylt                                      *rstr);
1404b8bea3bSJed Brown   CeedChk(ierr);
141d7b241e6Sjeremylt   return 0;
142d7b241e6Sjeremylt }
143d7b241e6Sjeremylt 
144d7b241e6Sjeremylt /**
145b11c1e72Sjeremylt   @brief Permute and pad indices for a blocked restriction
146d7b241e6Sjeremylt 
1478795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
1488795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
1498795c945Sjeremylt                       for the unknowns corresponding to element i, where
15034138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
1518795c945Sjeremylt                       [0, @a nnodes).
152ecf6354eSJed Brown   @param blkindices Array of permuted and padded indices of
153ecf6354eSJed Brown                       shape [@a nblk, @a elemsize, @a blksize].
154d7b241e6Sjeremylt   @param nblk       Number of blocks
155d7b241e6Sjeremylt   @param nelem      Number of elements
156d7b241e6Sjeremylt   @param blksize    Number of elements in a block
157d7b241e6Sjeremylt   @param elemsize   Size of each element
158d7b241e6Sjeremylt 
159b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
160b11c1e72Sjeremylt 
161dfdf5a53Sjeremylt   @ref Utility
162b11c1e72Sjeremylt **/
163dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices,
164692c2638Sjeremylt                           CeedInt nblk, CeedInt nelem, CeedInt blksize,
165692c2638Sjeremylt                           CeedInt elemsize) {
166d7b241e6Sjeremylt   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
167d7b241e6Sjeremylt     for (int j = 0; j < blksize; j++)
168d7b241e6Sjeremylt       for (int k = 0; k < elemsize; k++)
169d7b241e6Sjeremylt         blkindices[e*elemsize + k*blksize + j]
170d7b241e6Sjeremylt           = indices[CeedIntMin(e+j,nelem-1)*elemsize + k];
171dfdf5a53Sjeremylt   return 0;
172d7b241e6Sjeremylt }
173d7b241e6Sjeremylt 
174d7b241e6Sjeremylt /**
175b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
176d7b241e6Sjeremylt 
177d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
178d7b241e6Sjeremylt   @param nelem      Number of elements described in the @a indices array.
179b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
180b11c1e72Sjeremylt   @param blksize    Number of elements in a block
1818795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
1828795c945Sjeremylt                       to which the restriction will be applied is of size
1838795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
184d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
185d7b241e6Sjeremylt                       different types of elements.
186b11c1e72Sjeremylt   @param ncomp      Number of components stored at each node
187b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
188b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
1898795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
1908795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
1918795c945Sjeremylt                       for the unknowns corresponding to element i, where
19234138859Sjeremylt                       0 <= i < @a nelem. All indices must be in the range
1938795c945Sjeremylt                       [0, @a nnodes). The backend will permute and pad this
1948795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
1958795c945Sjeremylt                       typically given by the backend. The default reordering is
1968795c945Sjeremylt                       to interlace elements.
1974ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
198b11c1e72Sjeremylt                       CeedElemRestriction will be stored
199d7b241e6Sjeremylt 
200b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
201dfdf5a53Sjeremylt 
202dfdf5a53Sjeremylt   @ref Advanced
203b11c1e72Sjeremylt  **/
204d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
2058795c945Sjeremylt                                      CeedInt blksize, CeedInt nnodes,
2068795c945Sjeremylt                                      CeedInt ncomp, CeedMemType mtype,
2078795c945Sjeremylt                                      CeedCopyMode cmode, const CeedInt *indices,
2084ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
209d7b241e6Sjeremylt   int ierr;
210d7b241e6Sjeremylt   CeedInt *blkindices;
211d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
212d7b241e6Sjeremylt 
2135fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
2145fe0d4faSjeremylt     Ceed delegate;
215aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
216aefd8378Sjeremylt     CeedChk(ierr);
2175fe0d4faSjeremylt 
2185fe0d4faSjeremylt     if (!delegate)
219c042f62fSJeremy L Thompson       // LCOV_EXCL_START
2201d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
2211d102b48SJeremy L Thompson                        "ElemRestrictionCreateBlocked");
222c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
2235fe0d4faSjeremylt 
2245fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize,
2258795c945Sjeremylt                                             blksize, nnodes, ncomp, mtype, cmode,
2264ce2993fSjeremylt                                             indices, rstr); CeedChk(ierr);
2275fe0d4faSjeremylt     return 0;
2285fe0d4faSjeremylt   }
229d7b241e6Sjeremylt 
2304ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
231d7b241e6Sjeremylt 
232d7b241e6Sjeremylt   if (indices) {
233de686571SJeremy L Thompson     ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr);
2344b8bea3bSJed Brown     ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize,
2354b8bea3bSJed Brown                                  elemsize);
236dfdf5a53Sjeremylt     CeedChk(ierr);
237d7b241e6Sjeremylt   } else {
238d7b241e6Sjeremylt     blkindices = NULL;
239d7b241e6Sjeremylt   }
240d7b241e6Sjeremylt 
2414ce2993fSjeremylt   (*rstr)->ceed = ceed;
242d7b241e6Sjeremylt   ceed->refcount++;
2434ce2993fSjeremylt   (*rstr)->refcount = 1;
2444ce2993fSjeremylt   (*rstr)->nelem = nelem;
2454ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2468795c945Sjeremylt   (*rstr)->nnodes = nnodes;
2474ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
2484ce2993fSjeremylt   (*rstr)->nblk = nblk;
2494ce2993fSjeremylt   (*rstr)->blksize = blksize;
250667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
2517f823360Sjeremylt          (const CeedInt *) blkindices, *rstr); CeedChk(ierr);
252d7b241e6Sjeremylt 
2531d102b48SJeremy L Thompson   if (cmode == CEED_OWN_POINTER) {
254d7b241e6Sjeremylt     ierr = CeedFree(&indices); CeedChk(ierr);
2551d102b48SJeremy L Thompson   }
256d7b241e6Sjeremylt 
257d7b241e6Sjeremylt   return 0;
258d7b241e6Sjeremylt }
259d7b241e6Sjeremylt 
260b11c1e72Sjeremylt /**
261b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
262b11c1e72Sjeremylt 
2634ce2993fSjeremylt   @param rstr  CeedElemRestriction
264b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
265b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
266b11c1e72Sjeremylt 
267b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
268dfdf5a53Sjeremylt 
269dfdf5a53Sjeremylt   @ref Advanced
270b11c1e72Sjeremylt **/
2714ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
272d7b241e6Sjeremylt                                     CeedVector *evec) {
273d7b241e6Sjeremylt   int ierr;
274d7b241e6Sjeremylt   CeedInt n, m;
2758795c945Sjeremylt   m = rstr->nnodes * rstr->ncomp;
2764ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
277d7b241e6Sjeremylt   if (lvec) {
2784ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
279d7b241e6Sjeremylt   }
280d7b241e6Sjeremylt   if (evec) {
2814ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
282d7b241e6Sjeremylt   }
283d7b241e6Sjeremylt   return 0;
284d7b241e6Sjeremylt }
285d7b241e6Sjeremylt 
286d7b241e6Sjeremylt /**
287d9e1f99aSValeria Barra   @brief Restrict an L-vector to an E-vector or apply its transpose
288d7b241e6Sjeremylt 
2894ce2993fSjeremylt   @param rstr    CeedElemRestriction
290d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
291d9e1f99aSValeria Barra   @param lmode   Ordering of the ncomp components, i.e. it specifies
292d9e1f99aSValeria Barra                    the ordering of the components of the l-vector used
293d9e1f99aSValeria Barra                    by this CeedElemRestriction. CEED_NOTRANSPOSE indicates
294d9e1f99aSValeria Barra                    the component is the outermost index and CEED_TRANSPOSE
295d9e1f99aSValeria Barra                    indicates the component is the innermost index in
296d9e1f99aSValeria Barra                    ordering of the l-vector
2977aaeacdcSjeremylt   @param u       Input vector (of shape [@a nnodes, @a ncomp] when
2987aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE, lmode=CEED_TRANSPOSE)
2997aaeacdcSjeremylt   @param v       Output vector (of shape [@a nelem * @a elemsize] when
3007aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
3017aaeacdcSjeremylt                    by the backend.
302d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
303b11c1e72Sjeremylt 
304b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
305dfdf5a53Sjeremylt 
306dfdf5a53Sjeremylt   @ref Advanced
307b11c1e72Sjeremylt **/
3084ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
309692c2638Sjeremylt                              CeedTransposeMode lmode, CeedVector u,
310692c2638Sjeremylt                              CeedVector v, CeedRequest *request) {
311d7b241e6Sjeremylt   CeedInt m,n;
312d7b241e6Sjeremylt   int ierr;
313d7b241e6Sjeremylt 
314d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
3154ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
3168795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
317d7b241e6Sjeremylt   } else {
3188795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
3194ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
320d7b241e6Sjeremylt   }
321d7b241e6Sjeremylt   if (n != u->length)
322c042f62fSJeremy L Thompson     // LCOV_EXCL_START
3231d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
3241d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
325c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
326d7b241e6Sjeremylt   if (m != v->length)
327c042f62fSJeremy L Thompson     // LCOV_EXCL_START
3281d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
3291d102b48SJeremy L Thompson                      "element restriction (%d, %d)", v->length, m, n);
330c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
3314ce2993fSjeremylt   ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr);
332d7b241e6Sjeremylt 
333d7b241e6Sjeremylt   return 0;
334d7b241e6Sjeremylt }
335d7b241e6Sjeremylt 
336d7b241e6Sjeremylt /**
337d9e1f99aSValeria Barra   @brief Restrict an L-vector to a block of an E-vector or apply its transpose
338be9261b7Sjeremylt 
339be9261b7Sjeremylt   @param rstr    CeedElemRestriction
3401f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
3411f37b403Sjeremylt                    elements [0 : blksize] and block=3 will handle elements
3421f37b403Sjeremylt                    [3*blksize : 4*blksize]
343be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
344d9e1f99aSValeria Barra   @param lmode   Ordering of the ncomp components, i.e. it specifies
345d9e1f99aSValeria Barra                    the ordering of the components of the l-vector used
346d9e1f99aSValeria Barra                    by this CeedElemRestriction. CEED_NOTRANSPOSE indicates
347d9e1f99aSValeria Barra                    the component is the outermost index and CEED_TRANSPOSE
348d9e1f99aSValeria Barra                    indicates the component is the innermost index in
349d9e1f99aSValeria Barra                    ordering of the l-vector
3508795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
3517aaeacdcSjeremylt   @param u       Input vector (of shape [@a nnodes, @a ncomp] when
3527aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE, lmode=CEED_TRANSPOSE)
3537aaeacdcSjeremylt   @param v       Output vector (of shape [@a blksize * @a elemsize] when
3547aaeacdcSjeremylt                    tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided
3557aaeacdcSjeremylt                    by the backend.
356be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
357be9261b7Sjeremylt 
358be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
359be9261b7Sjeremylt 
360be9261b7Sjeremylt   @ref Advanced
361be9261b7Sjeremylt **/
362be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
363be9261b7Sjeremylt                                   CeedTransposeMode tmode,
364692c2638Sjeremylt                                   CeedTransposeMode lmode, CeedVector u,
365692c2638Sjeremylt                                   CeedVector v, CeedRequest *request) {
366be9261b7Sjeremylt   CeedInt m,n;
367be9261b7Sjeremylt   int ierr;
368be9261b7Sjeremylt 
369be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
370be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
3718795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
372be9261b7Sjeremylt   } else {
3738795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
374be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
375be9261b7Sjeremylt   }
376be9261b7Sjeremylt   if (n != u->length)
377c042f62fSJeremy L Thompson     // LCOV_EXCL_START
3781d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with "
3791d102b48SJeremy L Thompson                      "element restriction (%d, %d)", u->length, m, n);
380c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
381be9261b7Sjeremylt   if (m != v->length)
382c042f62fSJeremy L Thompson     // LCOV_EXCL_START
3831d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with "
3841d102b48SJeremy L Thompson                      "element restriction (%d, %d)", v->length, m, n);
385c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
386be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
387c042f62fSJeremy L Thompson     // LCOV_EXCL_START
3881d102b48SJeremy L Thompson     return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > "
3891d102b48SJeremy L Thompson                      "total elements %d", block, rstr->blksize*block,
3901d102b48SJeremy L Thompson                      rstr->nelem);
391c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
392be9261b7Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request);
393be9261b7Sjeremylt   CeedChk(ierr);
394be9261b7Sjeremylt 
395be9261b7Sjeremylt   return 0;
396be9261b7Sjeremylt }
397be9261b7Sjeremylt 
398be9261b7Sjeremylt /**
399d9e1f99aSValeria Barra   @brief Get the multiplicity of nodes in a CeedElemRestriction
4001469ee4dSjeremylt 
4011469ee4dSjeremylt   @param rstr      CeedElemRestriction
402*fa9eac48SJed Brown   @param[in] tmode Order the components of the output vector as interlaced (CEED_TRANSPOSE)
403*fa9eac48SJed Brown                    or blocked (CEED_NOTRANSPOSE)
404*fa9eac48SJed Brown   @param[out] mult Vector to store multiplicity (of size ndof)
4051469ee4dSjeremylt 
4061469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
4071469ee4dSjeremylt 
4081469ee4dSjeremylt   @ref Advanced
4091469ee4dSjeremylt **/
4101469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
411*fa9eac48SJed Brown                                        CeedTransposeMode tmode,
4121469ee4dSjeremylt                                        CeedVector mult) {
4131469ee4dSjeremylt   int ierr;
4141469ee4dSjeremylt   CeedVector evec;
4151469ee4dSjeremylt 
4161469ee4dSjeremylt   // Create and set evec
4171469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
4181469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
419*fa9eac48SJed Brown   ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr);
4201469ee4dSjeremylt 
4211469ee4dSjeremylt   // Apply to get multiplicity
422*fa9eac48SJed Brown   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, tmode, evec,
4231469ee4dSjeremylt                                   mult, CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
4241469ee4dSjeremylt 
4251469ee4dSjeremylt   // Cleanup
4261469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
4271469ee4dSjeremylt 
4281469ee4dSjeremylt   return 0;
4291469ee4dSjeremylt }
4301469ee4dSjeremylt 
4311469ee4dSjeremylt /**
4324ce2993fSjeremylt   @brief Get the Ceed associated with a CeedElemRestriction
4334ce2993fSjeremylt 
4344ce2993fSjeremylt   @param rstr             CeedElemRestriction
4354ce2993fSjeremylt   @param[out] ceed        Variable to store Ceed
4364ce2993fSjeremylt 
4374ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4384ce2993fSjeremylt 
43923617272Sjeremylt   @ref Advanced
4404ce2993fSjeremylt **/
4414ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
4424ce2993fSjeremylt   *ceed = rstr->ceed;
4434ce2993fSjeremylt   return 0;
4444ce2993fSjeremylt }
4454ce2993fSjeremylt 
4464ce2993fSjeremylt /**
447b11c1e72Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
448d7b241e6Sjeremylt 
4494ce2993fSjeremylt   @param rstr             CeedElemRestriction
450288c0443SJeremy L Thompson   @param[out] numelem     Variable to store number of elements
451b11c1e72Sjeremylt 
452b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
453dfdf5a53Sjeremylt 
45423617272Sjeremylt   @ref Advanced
455b11c1e72Sjeremylt **/
4564ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
4574ce2993fSjeremylt                                       CeedInt *numelem) {
4584ce2993fSjeremylt   *numelem = rstr->nelem;
4594ce2993fSjeremylt   return 0;
4604ce2993fSjeremylt }
4614ce2993fSjeremylt 
4624ce2993fSjeremylt /**
4634ce2993fSjeremylt   @brief Get the size of elements in the CeedElemRestriction
4644ce2993fSjeremylt 
4654ce2993fSjeremylt   @param rstr             CeedElemRestriction
4664ce2993fSjeremylt   @param[out] elemsize    Variable to store size of elements
4674ce2993fSjeremylt 
4684ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4694ce2993fSjeremylt 
47023617272Sjeremylt   @ref Advanced
4714ce2993fSjeremylt **/
4724ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
4734ce2993fSjeremylt                                       CeedInt *elemsize) {
4744ce2993fSjeremylt   *elemsize = rstr->elemsize;
4754ce2993fSjeremylt   return 0;
4764ce2993fSjeremylt }
4774ce2993fSjeremylt 
4784ce2993fSjeremylt /**
4794ce2993fSjeremylt   @brief Get the number of degrees of freedom in the range of a
4804ce2993fSjeremylt          CeedElemRestriction
4814ce2993fSjeremylt 
4824ce2993fSjeremylt   @param rstr             CeedElemRestriction
4838795c945Sjeremylt   @param[out] numnodes    Variable to store number of nodes
4844ce2993fSjeremylt 
4854ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4864ce2993fSjeremylt 
48723617272Sjeremylt   @ref Advanced
4884ce2993fSjeremylt **/
4898795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr,
4908795c945Sjeremylt                                    CeedInt *numnodes) {
4918795c945Sjeremylt   *numnodes = rstr->nnodes;
4924ce2993fSjeremylt   return 0;
4934ce2993fSjeremylt }
4944ce2993fSjeremylt 
4954ce2993fSjeremylt /**
4964ce2993fSjeremylt   @brief Get the number of components in the elements of a
4974ce2993fSjeremylt          CeedElemRestriction
4984ce2993fSjeremylt 
4994ce2993fSjeremylt   @param rstr             CeedElemRestriction
5004ce2993fSjeremylt   @param[out] numcomp     Variable to store number of components
5014ce2993fSjeremylt 
5024ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5034ce2993fSjeremylt 
50423617272Sjeremylt   @ref Advanced
5054ce2993fSjeremylt **/
5064ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
5074ce2993fSjeremylt                                         CeedInt *numcomp) {
5084ce2993fSjeremylt   *numcomp = rstr->ncomp;
5094ce2993fSjeremylt   return 0;
5104ce2993fSjeremylt }
5114ce2993fSjeremylt 
5124ce2993fSjeremylt /**
5134ce2993fSjeremylt   @brief Get the number of blocks in a CeedElemRestriction
5144ce2993fSjeremylt 
5154ce2993fSjeremylt   @param rstr             CeedElemRestriction
5164ce2993fSjeremylt   @param[out] numblock    Variable to store number of blocks
5174ce2993fSjeremylt 
5184ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5194ce2993fSjeremylt 
52023617272Sjeremylt   @ref Advanced
5214ce2993fSjeremylt **/
5224ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
5234ce2993fSjeremylt                                     CeedInt *numblock) {
5244ce2993fSjeremylt   *numblock = rstr->nblk;
5254ce2993fSjeremylt   return 0;
5264ce2993fSjeremylt }
5274ce2993fSjeremylt 
5284ce2993fSjeremylt /**
5294ce2993fSjeremylt   @brief Get the size of blocks in the CeedElemRestriction
5304ce2993fSjeremylt 
531288c0443SJeremy L Thompson   @param rstr             CeedElemRestriction
5324ce2993fSjeremylt   @param[out] blksize     Variable to store size of blocks
5334ce2993fSjeremylt 
5344ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5354ce2993fSjeremylt 
53623617272Sjeremylt   @ref Advanced
5374ce2993fSjeremylt **/
5384ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
5394ce2993fSjeremylt                                     CeedInt *blksize) {
5404ce2993fSjeremylt   *blksize = rstr->blksize;
5414ce2993fSjeremylt   return 0;
5424ce2993fSjeremylt }
5434ce2993fSjeremylt 
5444ce2993fSjeremylt /**
5454ce2993fSjeremylt   @brief Get the backend data of a CeedElemRestriction
5464ce2993fSjeremylt 
547288c0443SJeremy L Thompson   @param rstr             CeedElemRestriction
5484ce2993fSjeremylt   @param[out] data        Variable to store data
5494ce2993fSjeremylt 
5504ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5514ce2993fSjeremylt 
55223617272Sjeremylt   @ref Advanced
5534ce2993fSjeremylt **/
5541d102b48SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) {
5554ce2993fSjeremylt   *data = rstr->data;
556d7b241e6Sjeremylt   return 0;
557d7b241e6Sjeremylt }
558d7b241e6Sjeremylt 
559d7b241e6Sjeremylt /**
560fe2413ffSjeremylt   @brief Set the backend data of a CeedElemRestriction
561fe2413ffSjeremylt 
562288c0443SJeremy L Thompson   @param[out] rstr        CeedElemRestriction
563fe2413ffSjeremylt   @param data             Data to set
564fe2413ffSjeremylt 
565fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
566fe2413ffSjeremylt 
567fe2413ffSjeremylt   @ref Advanced
568fe2413ffSjeremylt **/
5691d102b48SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) {
570fe2413ffSjeremylt   rstr->data = *data;
571fe2413ffSjeremylt   return 0;
572fe2413ffSjeremylt }
573fe2413ffSjeremylt 
574fe2413ffSjeremylt /**
575f02ca4a2SJed Brown   @brief View a CeedElemRestriction
576f02ca4a2SJed Brown 
577f02ca4a2SJed Brown   @param[in] rstr CeedElemRestriction to view
578f02ca4a2SJed Brown   @param[in] stream Stream to write; typically stdout/stderr or a file
579f02ca4a2SJed Brown 
580f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
581f02ca4a2SJed Brown 
582f02ca4a2SJed Brown   @ref Utility
583f02ca4a2SJed Brown **/
584f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
5851d102b48SJeremy L Thompson   fprintf(stream, "CeedElemRestriction from (%d, %d) to %d elements with %d "
5861d102b48SJeremy L Thompson           "nodes each\n", rstr->nnodes, rstr->ncomp, rstr->nelem,
5871d102b48SJeremy L Thompson           rstr->elemsize);
588f02ca4a2SJed Brown   return 0;
589f02ca4a2SJed Brown }
590f02ca4a2SJed Brown 
591f02ca4a2SJed Brown /**
592b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
593b11c1e72Sjeremylt 
5944ce2993fSjeremylt   @param rstr CeedElemRestriction to destroy
595b11c1e72Sjeremylt 
596b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
597dfdf5a53Sjeremylt 
598dfdf5a53Sjeremylt   @ref Basic
599b11c1e72Sjeremylt **/
6004ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
601d7b241e6Sjeremylt   int ierr;
602d7b241e6Sjeremylt 
6031d102b48SJeremy L Thompson   if (!*rstr || --(*rstr)->refcount > 0)
6041d102b48SJeremy L Thompson     return 0;
6054ce2993fSjeremylt   if ((*rstr)->Destroy) {
6064ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
607d7b241e6Sjeremylt   }
6084ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
6094ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
610d7b241e6Sjeremylt   return 0;
611d7b241e6Sjeremylt }
612d7b241e6Sjeremylt 
613d7b241e6Sjeremylt /// @}
614