xref: /libCEED/interface/ceed-elemrestriction.c (revision f90c8643381e2b179b157b8e37de2782c57cb07e)
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
438795c945Sjeremylt                       0 <= i < @a nelements. All indices must be in the range
448795c945Sjeremylt                       [0, @a nnodes].
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)
64d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate");
655fe0d4faSjeremylt 
665fe0d4faSjeremylt     ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize,
678795c945Sjeremylt                                      nnodes, ncomp, mtype, cmode,
684ce2993fSjeremylt                                      indices, rstr); CeedChk(ierr);
695fe0d4faSjeremylt     return 0;
705fe0d4faSjeremylt   }
715fe0d4faSjeremylt 
724ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
734ce2993fSjeremylt   (*rstr)->ceed = ceed;
74d7b241e6Sjeremylt   ceed->refcount++;
754ce2993fSjeremylt   (*rstr)->refcount = 1;
764ce2993fSjeremylt   (*rstr)->nelem = nelem;
774ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
788795c945Sjeremylt   (*rstr)->nnodes = nnodes;
794ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
804ce2993fSjeremylt   (*rstr)->nblk = nelem;
814ce2993fSjeremylt   (*rstr)->blksize = 1;
824ce2993fSjeremylt   ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr);
83d7b241e6Sjeremylt   return 0;
84d7b241e6Sjeremylt }
85d7b241e6Sjeremylt 
86d7b241e6Sjeremylt /**
87b11c1e72Sjeremylt   @brief Create an identity CeedElemRestriction
88d7b241e6Sjeremylt 
89b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created
90b11c1e72Sjeremylt   @param nelem      Number of elements described in the @a indices array
91b11c1e72Sjeremylt   @param elemsize   Size (number of "nodes") per element
928795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
938795c945Sjeremylt                       to which the restriction will be applied is of size
948795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
95d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
968795c945Sjeremylt                       different types of elements.
97b11c1e72Sjeremylt   @param ncomp      Number of field components per interpolation node
984ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
99b11c1e72Sjeremylt                       CeedElemRestriction will be stored
100d7b241e6Sjeremylt 
101b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
102dfdf5a53Sjeremylt 
103dfdf5a53Sjeremylt   @ref Basic
104b11c1e72Sjeremylt **/
1054b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem,
106*f90c8643Sjeremylt                                       CeedInt elemsize, CeedInt nnodes,
107*f90c8643Sjeremylt                                       CeedInt ncomp,
108*f90c8643Sjeremylt                                       CeedElemRestriction *rstr) {
109d7b241e6Sjeremylt   int ierr;
110d7b241e6Sjeremylt 
1115fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
1125fe0d4faSjeremylt     Ceed delegate;
113aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
114aefd8378Sjeremylt     CeedChk(ierr);
1155fe0d4faSjeremylt 
1165fe0d4faSjeremylt     if (!delegate)
1174b8bea3bSJed Brown       return CeedError(ceed, 1,
1185fe0d4faSjeremylt                        "Backend does not support ElemRestrictionCreate");
1195fe0d4faSjeremylt 
1205fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize,
1218795c945Sjeremylt            nnodes, ncomp, rstr); CeedChk(ierr);
1225fe0d4faSjeremylt     return 0;
1235fe0d4faSjeremylt   }
1245fe0d4faSjeremylt 
1254ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
1264ce2993fSjeremylt   (*rstr)->ceed = ceed;
127d7b241e6Sjeremylt   ceed->refcount++;
1284ce2993fSjeremylt   (*rstr)->refcount = 1;
1294ce2993fSjeremylt   (*rstr)->nelem = nelem;
1304ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
1318795c945Sjeremylt   (*rstr)->nnodes = nnodes;
1324ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
1334ce2993fSjeremylt   (*rstr)->nblk = nelem;
1344ce2993fSjeremylt   (*rstr)->blksize = 1;
1351dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
1361dfeef1dSjeremylt                                      *rstr);
1374b8bea3bSJed Brown   CeedChk(ierr);
138d7b241e6Sjeremylt   return 0;
139d7b241e6Sjeremylt }
140d7b241e6Sjeremylt 
141d7b241e6Sjeremylt /**
142b11c1e72Sjeremylt   @brief Permute and pad indices for a blocked restriction
143d7b241e6Sjeremylt 
1448795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
1458795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
1468795c945Sjeremylt                       for the unknowns corresponding to element i, where
1478795c945Sjeremylt                       0 <= i < @a nelements. All indices must be in the range
1488795c945Sjeremylt                       [0, @a nnodes).
149ecf6354eSJed Brown   @param blkindices Array of permuted and padded indices of
150ecf6354eSJed Brown                       shape [@a nblk, @a elemsize, @a blksize].
151d7b241e6Sjeremylt   @param nblk       Number of blocks
152d7b241e6Sjeremylt   @param nelem      Number of elements
153d7b241e6Sjeremylt   @param blksize    Number of elements in a block
154d7b241e6Sjeremylt   @param elemsize   Size of each element
155d7b241e6Sjeremylt 
156b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
157b11c1e72Sjeremylt 
158dfdf5a53Sjeremylt   @ref Utility
159b11c1e72Sjeremylt **/
160dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices,
161d7b241e6Sjeremylt                           CeedInt nblk, CeedInt nelem,
162d7b241e6Sjeremylt                           CeedInt blksize, CeedInt elemsize) {
163d7b241e6Sjeremylt   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
164d7b241e6Sjeremylt     for (int j = 0; j < blksize; j++)
165d7b241e6Sjeremylt       for (int k = 0; k < elemsize; k++)
166d7b241e6Sjeremylt         blkindices[e*elemsize + k*blksize + j]
167d7b241e6Sjeremylt           = indices[CeedIntMin(e+j,nelem-1)*elemsize + k];
168dfdf5a53Sjeremylt   return 0;
169d7b241e6Sjeremylt }
170d7b241e6Sjeremylt 
171d7b241e6Sjeremylt /**
172b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
173d7b241e6Sjeremylt 
174d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
175d7b241e6Sjeremylt   @param nelem      Number of elements described in the @a indices array.
176b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
177b11c1e72Sjeremylt   @param blksize    Number of elements in a block
1788795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
1798795c945Sjeremylt                       to which the restriction will be applied is of size
1808795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
181d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
182d7b241e6Sjeremylt                       different types of elements.
183b11c1e72Sjeremylt   @param ncomp      Number of components stored at each node
184b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
185b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
1868795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
1878795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
1888795c945Sjeremylt                       for the unknowns corresponding to element i, where
1898795c945Sjeremylt                       0 <= i < @a nelements. All indices must be in the range
1908795c945Sjeremylt                       [0, @a nnodes). The backend will permute and pad this
1918795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
1928795c945Sjeremylt                       typically given by the backend. The default reordering is
1938795c945Sjeremylt                       to interlace elements.
1944ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
195b11c1e72Sjeremylt                       CeedElemRestriction will be stored
196d7b241e6Sjeremylt 
197b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
198dfdf5a53Sjeremylt 
199dfdf5a53Sjeremylt   @ref Advanced
200b11c1e72Sjeremylt  **/
201d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
2028795c945Sjeremylt                                      CeedInt blksize, CeedInt nnodes,
2038795c945Sjeremylt                                      CeedInt ncomp, CeedMemType mtype,
2048795c945Sjeremylt                                      CeedCopyMode cmode, const CeedInt *indices,
2054ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
206d7b241e6Sjeremylt   int ierr;
207d7b241e6Sjeremylt   CeedInt *blkindices;
208d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
209d7b241e6Sjeremylt 
2105fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
2115fe0d4faSjeremylt     Ceed delegate;
212aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
213aefd8378Sjeremylt     CeedChk(ierr);
2145fe0d4faSjeremylt 
2155fe0d4faSjeremylt     if (!delegate)
216d7b241e6Sjeremylt       return CeedError(ceed, 1,
217d7b241e6Sjeremylt                        "Backend does not support ElemRestrictionCreateBlocked");
2185fe0d4faSjeremylt 
2195fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize,
2208795c945Sjeremylt                                             blksize, nnodes, ncomp, mtype, cmode,
2214ce2993fSjeremylt                                             indices, rstr); CeedChk(ierr);
2225fe0d4faSjeremylt     return 0;
2235fe0d4faSjeremylt   }
224d7b241e6Sjeremylt 
2254ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
226d7b241e6Sjeremylt 
227d7b241e6Sjeremylt   if (indices) {
228de686571SJeremy L Thompson     ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr);
2294b8bea3bSJed Brown     ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize,
2304b8bea3bSJed Brown                                  elemsize);
231dfdf5a53Sjeremylt     CeedChk(ierr);
232d7b241e6Sjeremylt   } else {
233d7b241e6Sjeremylt     blkindices = NULL;
234d7b241e6Sjeremylt   }
235d7b241e6Sjeremylt 
2364ce2993fSjeremylt   (*rstr)->ceed = ceed;
237d7b241e6Sjeremylt   ceed->refcount++;
2384ce2993fSjeremylt   (*rstr)->refcount = 1;
2394ce2993fSjeremylt   (*rstr)->nelem = nelem;
2404ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
2418795c945Sjeremylt   (*rstr)->nnodes = nnodes;
2424ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
2434ce2993fSjeremylt   (*rstr)->nblk = nblk;
2444ce2993fSjeremylt   (*rstr)->blksize = blksize;
245667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
2464ce2993fSjeremylt          (const CeedInt *) blkindices, *rstr);
247d7b241e6Sjeremylt   CeedChk(ierr);
248d7b241e6Sjeremylt 
249d7b241e6Sjeremylt   if (cmode == CEED_OWN_POINTER)
250d7b241e6Sjeremylt     ierr = CeedFree(&indices); CeedChk(ierr);
251d7b241e6Sjeremylt 
252d7b241e6Sjeremylt   return 0;
253d7b241e6Sjeremylt }
254d7b241e6Sjeremylt 
255b11c1e72Sjeremylt /**
256b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
257b11c1e72Sjeremylt 
2584ce2993fSjeremylt   @param rstr  CeedElemRestriction
259b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
260b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
261b11c1e72Sjeremylt 
262b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
263dfdf5a53Sjeremylt 
264dfdf5a53Sjeremylt   @ref Advanced
265b11c1e72Sjeremylt **/
2664ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
267d7b241e6Sjeremylt                                     CeedVector *evec) {
268d7b241e6Sjeremylt   int ierr;
269d7b241e6Sjeremylt   CeedInt n, m;
2708795c945Sjeremylt   m = rstr->nnodes * rstr->ncomp;
2714ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
272d7b241e6Sjeremylt   if (lvec) {
2734ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
274d7b241e6Sjeremylt   }
275d7b241e6Sjeremylt   if (evec) {
2764ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
277d7b241e6Sjeremylt   }
278d7b241e6Sjeremylt   return 0;
279d7b241e6Sjeremylt }
280d7b241e6Sjeremylt 
281d7b241e6Sjeremylt /**
282b11c1e72Sjeremylt   @brief Restrict an L-vector to an E-vector or apply transpose
283d7b241e6Sjeremylt 
2844ce2993fSjeremylt   @param rstr    CeedElemRestriction
285d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
286d7b241e6Sjeremylt   @param lmode   Ordering of the ncomp components
2878795c945Sjeremylt   @param u       Input vector (of size @a nnodes * @a ncomp when
2888795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
2898795c945Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when
2908795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
291d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
292b11c1e72Sjeremylt 
293b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
294dfdf5a53Sjeremylt 
295dfdf5a53Sjeremylt   @ref Advanced
296b11c1e72Sjeremylt **/
2974ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
298d7b241e6Sjeremylt                              CeedTransposeMode lmode,
299d7b241e6Sjeremylt                              CeedVector u, CeedVector v, CeedRequest *request) {
300d7b241e6Sjeremylt   CeedInt m,n;
301d7b241e6Sjeremylt   int ierr;
302d7b241e6Sjeremylt 
303d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
3044ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
3058795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
306d7b241e6Sjeremylt   } else {
3078795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
3084ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
309d7b241e6Sjeremylt   }
310d7b241e6Sjeremylt   if (n != u->length)
3114ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
312d7b241e6Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
313d7b241e6Sjeremylt                      u->length, m, n);
314d7b241e6Sjeremylt   if (m != v->length)
3154ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
316d7b241e6Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
317d7b241e6Sjeremylt                      v->length, m, n);
3184ce2993fSjeremylt   ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr);
319d7b241e6Sjeremylt 
320d7b241e6Sjeremylt   return 0;
321d7b241e6Sjeremylt }
322d7b241e6Sjeremylt 
323d7b241e6Sjeremylt /**
324be9261b7Sjeremylt   @brief Restrict an L-vector to a block of an E-vector or apply transpose
325be9261b7Sjeremylt 
326be9261b7Sjeremylt   @param rstr    CeedElemRestriction
3271f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
3281f37b403Sjeremylt                  elements [0 : blksize] and block=3 will handle elements
3291f37b403Sjeremylt                  [3*blksize : 4*blksize]
330be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
331be9261b7Sjeremylt   @param lmode   Ordering of the ncomp components
3328795c945Sjeremylt   @param u       Input vector (of size @a nnodes * @a ncomp when
3338795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
3348795c945Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when
3358795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
336be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
337be9261b7Sjeremylt 
338be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
339be9261b7Sjeremylt 
340be9261b7Sjeremylt   @ref Advanced
341be9261b7Sjeremylt **/
342be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
343be9261b7Sjeremylt                                   CeedTransposeMode tmode,
344be9261b7Sjeremylt                                   CeedTransposeMode lmode,
345be9261b7Sjeremylt                                   CeedVector u, CeedVector v,
346be9261b7Sjeremylt                                   CeedRequest *request) {
347be9261b7Sjeremylt   CeedInt m,n;
348be9261b7Sjeremylt   int ierr;
349be9261b7Sjeremylt 
350be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
351be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
3528795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
353be9261b7Sjeremylt   } else {
3548795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
355be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
356be9261b7Sjeremylt   }
357be9261b7Sjeremylt   if (n != u->length)
358be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
359be9261b7Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
360be9261b7Sjeremylt                      u->length, m, n);
361be9261b7Sjeremylt   if (m != v->length)
362be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
363be9261b7Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
364be9261b7Sjeremylt                      v->length, m, n);
365be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
366be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
367be9261b7Sjeremylt                      "Cannot retrieve block %d, element %d > total elements %d",
368be9261b7Sjeremylt                      block, rstr->blksize*block, rstr->nelem);
369be9261b7Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request);
370be9261b7Sjeremylt   CeedChk(ierr);
371be9261b7Sjeremylt 
372be9261b7Sjeremylt   return 0;
373be9261b7Sjeremylt }
374be9261b7Sjeremylt 
375be9261b7Sjeremylt /**
3761469ee4dSjeremylt   @brief Get the multiplicity of DoFs in a CeedElemRestriction
3771469ee4dSjeremylt 
3781469ee4dSjeremylt   @param rstr      CeedElemRestriction
3791469ee4dSjeremylt   @param[out] mult Vector to store multiplicity (of size ndof)
3801469ee4dSjeremylt 
3811469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
3821469ee4dSjeremylt 
3831469ee4dSjeremylt   @ref Advanced
3841469ee4dSjeremylt **/
3851469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
3861469ee4dSjeremylt                                        CeedVector mult) {
3871469ee4dSjeremylt   int ierr;
3881469ee4dSjeremylt   CeedVector evec;
3891469ee4dSjeremylt 
3901469ee4dSjeremylt   // Create and set evec
3911469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
3921469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
3931469ee4dSjeremylt 
3941469ee4dSjeremylt   // Apply to get multiplicity
3951469ee4dSjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, CEED_NOTRANSPOSE, evec,
3961469ee4dSjeremylt                                   mult, CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
3971469ee4dSjeremylt 
3981469ee4dSjeremylt   // Cleanup
3991469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
4001469ee4dSjeremylt 
4011469ee4dSjeremylt   return 0;
4021469ee4dSjeremylt }
4031469ee4dSjeremylt 
4041469ee4dSjeremylt /**
4054ce2993fSjeremylt   @brief Get the Ceed associated with a CeedElemRestriction
4064ce2993fSjeremylt 
4074ce2993fSjeremylt   @param rstr             CeedElemRestriction
4084ce2993fSjeremylt   @param[out] ceed        Variable to store Ceed
4094ce2993fSjeremylt 
4104ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4114ce2993fSjeremylt 
41223617272Sjeremylt   @ref Advanced
4134ce2993fSjeremylt **/
4144ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
4154ce2993fSjeremylt   *ceed = rstr->ceed;
4164ce2993fSjeremylt   return 0;
4174ce2993fSjeremylt }
4184ce2993fSjeremylt 
4194ce2993fSjeremylt /**
420b11c1e72Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
421d7b241e6Sjeremylt 
4224ce2993fSjeremylt   @param rstr             CeedElemRestriction
4234ce2993fSjeremylt   @param[out] numelements Variable to store number of elements
424b11c1e72Sjeremylt 
425b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
426dfdf5a53Sjeremylt 
42723617272Sjeremylt   @ref Advanced
428b11c1e72Sjeremylt **/
4294ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
4304ce2993fSjeremylt                                       CeedInt *numelem) {
4314ce2993fSjeremylt   *numelem = rstr->nelem;
4324ce2993fSjeremylt   return 0;
4334ce2993fSjeremylt }
4344ce2993fSjeremylt 
4354ce2993fSjeremylt /**
4364ce2993fSjeremylt   @brief Get the size of elements in the CeedElemRestriction
4374ce2993fSjeremylt 
4384ce2993fSjeremylt   @param rstr             CeedElemRestriction
4394ce2993fSjeremylt   @param[out] elemsize    Variable to store size of elements
4404ce2993fSjeremylt 
4414ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4424ce2993fSjeremylt 
44323617272Sjeremylt   @ref Advanced
4444ce2993fSjeremylt **/
4454ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
4464ce2993fSjeremylt                                       CeedInt *elemsize) {
4474ce2993fSjeremylt   *elemsize = rstr->elemsize;
4484ce2993fSjeremylt   return 0;
4494ce2993fSjeremylt }
4504ce2993fSjeremylt 
4514ce2993fSjeremylt /**
4524ce2993fSjeremylt   @brief Get the number of degrees of freedom in the range of a
4534ce2993fSjeremylt          CeedElemRestriction
4544ce2993fSjeremylt 
4554ce2993fSjeremylt   @param rstr             CeedElemRestriction
4568795c945Sjeremylt   @param[out] numnodes    Variable to store number of nodes
4574ce2993fSjeremylt 
4584ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4594ce2993fSjeremylt 
46023617272Sjeremylt   @ref Advanced
4614ce2993fSjeremylt **/
4628795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr,
4638795c945Sjeremylt                                    CeedInt *numnodes) {
4648795c945Sjeremylt   *numnodes = rstr->nnodes;
4654ce2993fSjeremylt   return 0;
4664ce2993fSjeremylt }
4674ce2993fSjeremylt 
4684ce2993fSjeremylt /**
4694ce2993fSjeremylt   @brief Get the number of components in the elements of a
4704ce2993fSjeremylt          CeedElemRestriction
4714ce2993fSjeremylt 
4724ce2993fSjeremylt   @param rstr             CeedElemRestriction
4734ce2993fSjeremylt   @param[out] numcomp     Variable to store number of components
4744ce2993fSjeremylt 
4754ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4764ce2993fSjeremylt 
47723617272Sjeremylt   @ref Advanced
4784ce2993fSjeremylt **/
4794ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
4804ce2993fSjeremylt                                         CeedInt *numcomp) {
4814ce2993fSjeremylt   *numcomp = rstr->ncomp;
4824ce2993fSjeremylt   return 0;
4834ce2993fSjeremylt }
4844ce2993fSjeremylt 
4854ce2993fSjeremylt /**
4864ce2993fSjeremylt   @brief Get the number of blocks in a CeedElemRestriction
4874ce2993fSjeremylt 
4884ce2993fSjeremylt   @param rstr             CeedElemRestriction
4894ce2993fSjeremylt   @param[out] numblock    Variable to store number of blocks
4904ce2993fSjeremylt 
4914ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4924ce2993fSjeremylt 
49323617272Sjeremylt   @ref Advanced
4944ce2993fSjeremylt **/
4954ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
4964ce2993fSjeremylt                                     CeedInt *numblock) {
4974ce2993fSjeremylt   *numblock = rstr->nblk;
4984ce2993fSjeremylt   return 0;
4994ce2993fSjeremylt }
5004ce2993fSjeremylt 
5014ce2993fSjeremylt /**
5024ce2993fSjeremylt   @brief Get the size of blocks in the CeedElemRestriction
5034ce2993fSjeremylt 
5044ce2993fSjeremylt   @param r                CeedElemRestriction
5054ce2993fSjeremylt   @param[out] blksize     Variable to store size of blocks
5064ce2993fSjeremylt 
5074ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5084ce2993fSjeremylt 
50923617272Sjeremylt   @ref Advanced
5104ce2993fSjeremylt **/
5114ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
5124ce2993fSjeremylt                                     CeedInt *blksize) {
5134ce2993fSjeremylt   *blksize = rstr->blksize;
5144ce2993fSjeremylt   return 0;
5154ce2993fSjeremylt }
5164ce2993fSjeremylt 
5174ce2993fSjeremylt /**
5184ce2993fSjeremylt   @brief Get the backend data of a CeedElemRestriction
5194ce2993fSjeremylt 
5204ce2993fSjeremylt   @param r                CeedElemRestriction
5214ce2993fSjeremylt   @param[out] data        Variable to store data
5224ce2993fSjeremylt 
5234ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5244ce2993fSjeremylt 
52523617272Sjeremylt   @ref Advanced
5264ce2993fSjeremylt **/
5274ce2993fSjeremylt int CeedElemRestrictionGetData(CeedElemRestriction rstr,
5284ce2993fSjeremylt                                void* *data) {
5294ce2993fSjeremylt   *data = rstr->data;
530d7b241e6Sjeremylt   return 0;
531d7b241e6Sjeremylt }
532d7b241e6Sjeremylt 
533d7b241e6Sjeremylt /**
534fe2413ffSjeremylt   @brief Set the backend data of a CeedElemRestriction
535fe2413ffSjeremylt 
536fe2413ffSjeremylt   @param[out] r           CeedElemRestriction
537fe2413ffSjeremylt   @param data             Data to set
538fe2413ffSjeremylt 
539fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
540fe2413ffSjeremylt 
541fe2413ffSjeremylt   @ref Advanced
542fe2413ffSjeremylt **/
543fe2413ffSjeremylt int CeedElemRestrictionSetData(CeedElemRestriction rstr,
544fe2413ffSjeremylt                                void* *data) {
545fe2413ffSjeremylt   rstr->data = *data;
546fe2413ffSjeremylt   return 0;
547fe2413ffSjeremylt }
548fe2413ffSjeremylt 
549fe2413ffSjeremylt /**
550f02ca4a2SJed Brown   @brief View a CeedElemRestriction
551f02ca4a2SJed Brown 
552f02ca4a2SJed Brown   @param[in] rstr CeedElemRestriction to view
553f02ca4a2SJed Brown   @param[in] stream Stream to write; typically stdout/stderr or a file
554f02ca4a2SJed Brown 
555f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
556f02ca4a2SJed Brown 
557f02ca4a2SJed Brown   @ref Utility
558f02ca4a2SJed Brown **/
559f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
560f02ca4a2SJed Brown   fprintf(stream,
561f02ca4a2SJed Brown           "CeedElemRestriction from (%d, %d) to %d elements with %d nodes each\n",
5628795c945Sjeremylt           rstr->nnodes, rstr->ncomp, rstr->nelem, rstr->elemsize);
563f02ca4a2SJed Brown   return 0;
564f02ca4a2SJed Brown }
565f02ca4a2SJed Brown 
566f02ca4a2SJed Brown /**
567b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
568b11c1e72Sjeremylt 
5694ce2993fSjeremylt   @param rstr CeedElemRestriction to destroy
570b11c1e72Sjeremylt 
571b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
572dfdf5a53Sjeremylt 
573dfdf5a53Sjeremylt   @ref Basic
574b11c1e72Sjeremylt **/
5754ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
576d7b241e6Sjeremylt   int ierr;
577d7b241e6Sjeremylt 
5784ce2993fSjeremylt   if (!*rstr || --(*rstr)->refcount > 0) return 0;
5794ce2993fSjeremylt   if ((*rstr)->Destroy) {
5804ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
581d7b241e6Sjeremylt   }
5824ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
5834ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
584d7b241e6Sjeremylt   return 0;
585d7b241e6Sjeremylt }
586d7b241e6Sjeremylt 
587d7b241e6Sjeremylt /// @}
588