xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-elemrestriction.c (revision 8795c9458136fc8cad6e4d699e4c8f3c99be02e2)
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
32*8795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
33*8795c945Sjeremylt                       to which the restriction will be applied is of size
34*8795c945Sjeremylt                       @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
40*8795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
41*8795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
42*8795c945Sjeremylt                       for the unknowns corresponding to element i, where
43*8795c945Sjeremylt                       0 <= i < @a nelements. All indices must be in the range
44*8795c945Sjeremylt                       [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,
53*8795c945Sjeremylt                               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,
67*8795c945Sjeremylt                                      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;
78*8795c945Sjeremylt   (*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
92*8795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
93*8795c945Sjeremylt                       to which the restriction will be applied is of size
94*8795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
95d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
96*8795c945Sjeremylt                       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,
1064b8bea3bSJed Brown                                       CeedInt elemsize,
107*8795c945Sjeremylt                                       CeedInt nnodes, CeedInt ncomp, CeedElemRestriction *rstr) {
108d7b241e6Sjeremylt   int ierr;
109d7b241e6Sjeremylt 
1105fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreate) {
1115fe0d4faSjeremylt     Ceed delegate;
112aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
113aefd8378Sjeremylt     CeedChk(ierr);
1145fe0d4faSjeremylt 
1155fe0d4faSjeremylt     if (!delegate)
1164b8bea3bSJed Brown       return CeedError(ceed, 1,
1175fe0d4faSjeremylt                        "Backend does not support ElemRestrictionCreate");
1185fe0d4faSjeremylt 
1195fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize,
120*8795c945Sjeremylt            nnodes, ncomp, rstr); CeedChk(ierr);
1215fe0d4faSjeremylt     return 0;
1225fe0d4faSjeremylt   }
1235fe0d4faSjeremylt 
1244ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
1254ce2993fSjeremylt   (*rstr)->ceed = ceed;
126d7b241e6Sjeremylt   ceed->refcount++;
1274ce2993fSjeremylt   (*rstr)->refcount = 1;
1284ce2993fSjeremylt   (*rstr)->nelem = nelem;
1294ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
130*8795c945Sjeremylt   (*rstr)->nnodes = nnodes;
1314ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
1324ce2993fSjeremylt   (*rstr)->nblk = nelem;
1334ce2993fSjeremylt   (*rstr)->blksize = 1;
1341dfeef1dSjeremylt   ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL,
1351dfeef1dSjeremylt                                      *rstr);
1364b8bea3bSJed Brown   CeedChk(ierr);
137d7b241e6Sjeremylt   return 0;
138d7b241e6Sjeremylt }
139d7b241e6Sjeremylt 
140d7b241e6Sjeremylt /**
141b11c1e72Sjeremylt   @brief Permute and pad indices for a blocked restriction
142d7b241e6Sjeremylt 
143*8795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
144*8795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
145*8795c945Sjeremylt                       for the unknowns corresponding to element i, where
146*8795c945Sjeremylt                       0 <= i < @a nelements. All indices must be in the range
147*8795c945Sjeremylt                       [0, @a nnodes).
148ecf6354eSJed Brown   @param blkindices Array of permuted and padded indices of
149ecf6354eSJed Brown                       shape [@a nblk, @a elemsize, @a blksize].
150d7b241e6Sjeremylt   @param nblk       Number of blocks
151d7b241e6Sjeremylt   @param nelem      Number of elements
152d7b241e6Sjeremylt   @param blksize    Number of elements in a block
153d7b241e6Sjeremylt   @param elemsize   Size of each element
154d7b241e6Sjeremylt 
155b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
156b11c1e72Sjeremylt 
157dfdf5a53Sjeremylt   @ref Utility
158b11c1e72Sjeremylt **/
159dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices,
160d7b241e6Sjeremylt                           CeedInt nblk, CeedInt nelem,
161d7b241e6Sjeremylt                           CeedInt blksize, CeedInt elemsize) {
162d7b241e6Sjeremylt   for (CeedInt e = 0; e < nblk*blksize; e+=blksize)
163d7b241e6Sjeremylt     for (int j = 0; j < blksize; j++)
164d7b241e6Sjeremylt       for (int k = 0; k < elemsize; k++)
165d7b241e6Sjeremylt         blkindices[e*elemsize + k*blksize + j]
166d7b241e6Sjeremylt           = indices[CeedIntMin(e+j,nelem-1)*elemsize + k];
167dfdf5a53Sjeremylt   return 0;
168d7b241e6Sjeremylt }
169d7b241e6Sjeremylt 
170d7b241e6Sjeremylt /**
171b11c1e72Sjeremylt   @brief Create a blocked CeedElemRestriction, typically only called by backends
172d7b241e6Sjeremylt 
173d7b241e6Sjeremylt   @param ceed       A Ceed object where the CeedElemRestriction will be created.
174d7b241e6Sjeremylt   @param nelem      Number of elements described in the @a indices array.
175b11c1e72Sjeremylt   @param elemsize   Size (number of unknowns) per element
176b11c1e72Sjeremylt   @param blksize    Number of elements in a block
177*8795c945Sjeremylt   @param nnodes     The number of nodes in the L-vector. The input CeedVector
178*8795c945Sjeremylt                       to which the restriction will be applied is of size
179*8795c945Sjeremylt                       @a nnodes * @a ncomp. This size may include data
180d7b241e6Sjeremylt                       used by other CeedElemRestriction objects describing
181d7b241e6Sjeremylt                       different types of elements.
182b11c1e72Sjeremylt   @param ncomp      Number of components stored at each node
183b11c1e72Sjeremylt   @param mtype      Memory type of the @a indices array, see CeedMemType
184b11c1e72Sjeremylt   @param cmode      Copy mode for the @a indices array, see CeedCopyMode
185*8795c945Sjeremylt   @param indices    Array of shape [@a nelem, @a elemsize]. Row i holds the
186*8795c945Sjeremylt                       ordered list of the indices (into the input CeedVector)
187*8795c945Sjeremylt                       for the unknowns corresponding to element i, where
188*8795c945Sjeremylt                       0 <= i < @a nelements. All indices must be in the range
189*8795c945Sjeremylt                       [0, @a nnodes). The backend will permute and pad this
190*8795c945Sjeremylt                       array to the desired ordering for the blocksize, which is
191*8795c945Sjeremylt                       typically given by the backend. The default reordering is
192*8795c945Sjeremylt                       to interlace elements.
1934ce2993fSjeremylt   @param rstr       Address of the variable where the newly created
194b11c1e72Sjeremylt                       CeedElemRestriction will be stored
195d7b241e6Sjeremylt 
196b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
197dfdf5a53Sjeremylt 
198dfdf5a53Sjeremylt   @ref Advanced
199b11c1e72Sjeremylt  **/
200d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize,
201*8795c945Sjeremylt                                      CeedInt blksize, CeedInt nnodes,
202*8795c945Sjeremylt                                      CeedInt ncomp, CeedMemType mtype,
203*8795c945Sjeremylt                                      CeedCopyMode cmode, const CeedInt *indices,
2044ce2993fSjeremylt                                      CeedElemRestriction *rstr) {
205d7b241e6Sjeremylt   int ierr;
206d7b241e6Sjeremylt   CeedInt *blkindices;
207d7b241e6Sjeremylt   CeedInt nblk = (nelem / blksize) + !!(nelem % blksize);
208d7b241e6Sjeremylt 
2095fe0d4faSjeremylt   if (!ceed->ElemRestrictionCreateBlocked) {
2105fe0d4faSjeremylt     Ceed delegate;
211aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
212aefd8378Sjeremylt     CeedChk(ierr);
2135fe0d4faSjeremylt 
2145fe0d4faSjeremylt     if (!delegate)
215d7b241e6Sjeremylt       return CeedError(ceed, 1,
216d7b241e6Sjeremylt                        "Backend does not support ElemRestrictionCreateBlocked");
2175fe0d4faSjeremylt 
2185fe0d4faSjeremylt     ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize,
219*8795c945Sjeremylt                                             blksize, nnodes, ncomp, mtype, cmode,
2204ce2993fSjeremylt                                             indices, rstr); CeedChk(ierr);
2215fe0d4faSjeremylt     return 0;
2225fe0d4faSjeremylt   }
223d7b241e6Sjeremylt 
2244ce2993fSjeremylt   ierr = CeedCalloc(1, rstr); CeedChk(ierr);
225d7b241e6Sjeremylt 
226d7b241e6Sjeremylt   if (indices) {
227de686571SJeremy L Thompson     ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr);
2284b8bea3bSJed Brown     ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize,
2294b8bea3bSJed Brown                                  elemsize);
230dfdf5a53Sjeremylt     CeedChk(ierr);
231d7b241e6Sjeremylt   } else {
232d7b241e6Sjeremylt     blkindices = NULL;
233d7b241e6Sjeremylt   }
234d7b241e6Sjeremylt 
2354ce2993fSjeremylt   (*rstr)->ceed = ceed;
236d7b241e6Sjeremylt   ceed->refcount++;
2374ce2993fSjeremylt   (*rstr)->refcount = 1;
2384ce2993fSjeremylt   (*rstr)->nelem = nelem;
2394ce2993fSjeremylt   (*rstr)->elemsize = elemsize;
240*8795c945Sjeremylt   (*rstr)->nnodes = nnodes;
2414ce2993fSjeremylt   (*rstr)->ncomp = ncomp;
2424ce2993fSjeremylt   (*rstr)->nblk = nblk;
2434ce2993fSjeremylt   (*rstr)->blksize = blksize;
244667bc5fcSjeremylt   ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
2454ce2993fSjeremylt          (const CeedInt *) blkindices, *rstr);
246d7b241e6Sjeremylt   CeedChk(ierr);
247d7b241e6Sjeremylt 
248d7b241e6Sjeremylt   if (cmode == CEED_OWN_POINTER)
249d7b241e6Sjeremylt     ierr = CeedFree(&indices); CeedChk(ierr);
250d7b241e6Sjeremylt 
251d7b241e6Sjeremylt   return 0;
252d7b241e6Sjeremylt }
253d7b241e6Sjeremylt 
254b11c1e72Sjeremylt /**
255b11c1e72Sjeremylt   @brief Create CeedVectors associated with a CeedElemRestriction
256b11c1e72Sjeremylt 
2574ce2993fSjeremylt   @param rstr  CeedElemRestriction
258b11c1e72Sjeremylt   @param lvec  The address of the L-vector to be created, or NULL
259b11c1e72Sjeremylt   @param evec  The address of the E-vector to be created, or NULL
260b11c1e72Sjeremylt 
261b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
262dfdf5a53Sjeremylt 
263dfdf5a53Sjeremylt   @ref Advanced
264b11c1e72Sjeremylt **/
2654ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec,
266d7b241e6Sjeremylt                                     CeedVector *evec) {
267d7b241e6Sjeremylt   int ierr;
268d7b241e6Sjeremylt   CeedInt n, m;
269*8795c945Sjeremylt   m = rstr->nnodes * rstr->ncomp;
2704ce2993fSjeremylt   n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
271d7b241e6Sjeremylt   if (lvec) {
2724ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr);
273d7b241e6Sjeremylt   }
274d7b241e6Sjeremylt   if (evec) {
2754ce2993fSjeremylt     ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr);
276d7b241e6Sjeremylt   }
277d7b241e6Sjeremylt   return 0;
278d7b241e6Sjeremylt }
279d7b241e6Sjeremylt 
280d7b241e6Sjeremylt /**
281b11c1e72Sjeremylt   @brief Restrict an L-vector to an E-vector or apply transpose
282d7b241e6Sjeremylt 
2834ce2993fSjeremylt   @param rstr    CeedElemRestriction
284d7b241e6Sjeremylt   @param tmode   Apply restriction or transpose
285d7b241e6Sjeremylt   @param lmode   Ordering of the ncomp components
286*8795c945Sjeremylt   @param u       Input vector (of size @a nnodes * @a ncomp when
287*8795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
288*8795c945Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when
289*8795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
290d7b241e6Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
291b11c1e72Sjeremylt 
292b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
293dfdf5a53Sjeremylt 
294dfdf5a53Sjeremylt   @ref Advanced
295b11c1e72Sjeremylt **/
2964ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode,
297d7b241e6Sjeremylt                              CeedTransposeMode lmode,
298d7b241e6Sjeremylt                              CeedVector u, CeedVector v, CeedRequest *request) {
299d7b241e6Sjeremylt   CeedInt m,n;
300d7b241e6Sjeremylt   int ierr;
301d7b241e6Sjeremylt 
302d7b241e6Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
3034ce2993fSjeremylt     m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
304*8795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
305d7b241e6Sjeremylt   } else {
306*8795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
3074ce2993fSjeremylt     n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp;
308d7b241e6Sjeremylt   }
309d7b241e6Sjeremylt   if (n != u->length)
3104ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
311d7b241e6Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
312d7b241e6Sjeremylt                      u->length, m, n);
313d7b241e6Sjeremylt   if (m != v->length)
3144ce2993fSjeremylt     return CeedError(rstr->ceed, 2,
315d7b241e6Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
316d7b241e6Sjeremylt                      v->length, m, n);
3174ce2993fSjeremylt   ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr);
318d7b241e6Sjeremylt 
319d7b241e6Sjeremylt   return 0;
320d7b241e6Sjeremylt }
321d7b241e6Sjeremylt 
322d7b241e6Sjeremylt /**
323be9261b7Sjeremylt   @brief Restrict an L-vector to a block of an E-vector or apply transpose
324be9261b7Sjeremylt 
325be9261b7Sjeremylt   @param rstr    CeedElemRestriction
3261f37b403Sjeremylt   @param block   Block number to restrict to/from, i.e. block=0 will handle
3271f37b403Sjeremylt                  elements [0 : blksize] and block=3 will handle elements
3281f37b403Sjeremylt                  [3*blksize : 4*blksize]
329be9261b7Sjeremylt   @param tmode   Apply restriction or transpose
330be9261b7Sjeremylt   @param lmode   Ordering of the ncomp components
331*8795c945Sjeremylt   @param u       Input vector (of size @a nnodes * @a ncomp when
332*8795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
333*8795c945Sjeremylt   @param v       Output vector (of size @a nelem * @a elemsize when
334*8795c945Sjeremylt                    tmode=CEED_NOTRANSPOSE)
335be9261b7Sjeremylt   @param request Request or CEED_REQUEST_IMMEDIATE
336be9261b7Sjeremylt 
337be9261b7Sjeremylt   @return An error code: 0 - success, otherwise - failure
338be9261b7Sjeremylt 
339be9261b7Sjeremylt   @ref Advanced
340be9261b7Sjeremylt **/
341be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block,
342be9261b7Sjeremylt                                   CeedTransposeMode tmode,
343be9261b7Sjeremylt                                   CeedTransposeMode lmode,
344be9261b7Sjeremylt                                   CeedVector u, CeedVector v,
345be9261b7Sjeremylt                                   CeedRequest *request) {
346be9261b7Sjeremylt   CeedInt m,n;
347be9261b7Sjeremylt   int ierr;
348be9261b7Sjeremylt 
349be9261b7Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
350be9261b7Sjeremylt     m = rstr->blksize * rstr->elemsize * rstr->ncomp;
351*8795c945Sjeremylt     n = rstr->nnodes * rstr->ncomp;
352be9261b7Sjeremylt   } else {
353*8795c945Sjeremylt     m = rstr->nnodes * rstr->ncomp;
354be9261b7Sjeremylt     n = rstr->blksize * rstr->elemsize * rstr->ncomp;
355be9261b7Sjeremylt   }
356be9261b7Sjeremylt   if (n != u->length)
357be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
358be9261b7Sjeremylt                      "Input vector size %d not compatible with element restriction (%d, %d)",
359be9261b7Sjeremylt                      u->length, m, n);
360be9261b7Sjeremylt   if (m != v->length)
361be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
362be9261b7Sjeremylt                      "Output vector size %d not compatible with element restriction (%d, %d)",
363be9261b7Sjeremylt                      v->length, m, n);
364be9261b7Sjeremylt   if (rstr->blksize*block > rstr->nelem)
365be9261b7Sjeremylt     return CeedError(rstr->ceed, 2,
366be9261b7Sjeremylt                      "Cannot retrieve block %d, element %d > total elements %d",
367be9261b7Sjeremylt                      block, rstr->blksize*block, rstr->nelem);
368be9261b7Sjeremylt   ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request);
369be9261b7Sjeremylt   CeedChk(ierr);
370be9261b7Sjeremylt 
371be9261b7Sjeremylt   return 0;
372be9261b7Sjeremylt }
373be9261b7Sjeremylt 
374be9261b7Sjeremylt /**
3751469ee4dSjeremylt   @brief Get the multiplicity of DoFs in a CeedElemRestriction
3761469ee4dSjeremylt 
3771469ee4dSjeremylt   @param rstr      CeedElemRestriction
3781469ee4dSjeremylt   @param[out] mult Vector to store multiplicity (of size ndof)
3791469ee4dSjeremylt 
3801469ee4dSjeremylt   @return An error code: 0 - success, otherwise - failure
3811469ee4dSjeremylt 
3821469ee4dSjeremylt   @ref Advanced
3831469ee4dSjeremylt **/
3841469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
3851469ee4dSjeremylt                              CeedVector mult) {
3861469ee4dSjeremylt   int ierr;
3871469ee4dSjeremylt   CeedVector evec;
3881469ee4dSjeremylt 
3891469ee4dSjeremylt   // Create and set evec
3901469ee4dSjeremylt   ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr);
3911469ee4dSjeremylt   ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr);
3921469ee4dSjeremylt 
3931469ee4dSjeremylt   // Apply to get multiplicity
3941469ee4dSjeremylt   ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, CEED_NOTRANSPOSE, evec,
3951469ee4dSjeremylt                                   mult, CEED_REQUEST_IMMEDIATE); CeedChk(ierr);
3961469ee4dSjeremylt 
3971469ee4dSjeremylt   // Cleanup
3981469ee4dSjeremylt   ierr = CeedVectorDestroy(&evec); CeedChk(ierr);
3991469ee4dSjeremylt 
4001469ee4dSjeremylt   return 0;
4011469ee4dSjeremylt }
4021469ee4dSjeremylt 
4031469ee4dSjeremylt /**
4044ce2993fSjeremylt   @brief Get the Ceed associated with a CeedElemRestriction
4054ce2993fSjeremylt 
4064ce2993fSjeremylt   @param rstr             CeedElemRestriction
4074ce2993fSjeremylt   @param[out] ceed        Variable to store Ceed
4084ce2993fSjeremylt 
4094ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4104ce2993fSjeremylt 
41123617272Sjeremylt   @ref Advanced
4124ce2993fSjeremylt **/
4134ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
4144ce2993fSjeremylt   *ceed = rstr->ceed;
4154ce2993fSjeremylt   return 0;
4164ce2993fSjeremylt }
4174ce2993fSjeremylt 
4184ce2993fSjeremylt /**
419b11c1e72Sjeremylt   @brief Get the total number of elements in the range of a CeedElemRestriction
420d7b241e6Sjeremylt 
4214ce2993fSjeremylt   @param rstr             CeedElemRestriction
4224ce2993fSjeremylt   @param[out] numelements Variable to store number of elements
423b11c1e72Sjeremylt 
424b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
425dfdf5a53Sjeremylt 
42623617272Sjeremylt   @ref Advanced
427b11c1e72Sjeremylt **/
4284ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
4294ce2993fSjeremylt                                       CeedInt *numelem) {
4304ce2993fSjeremylt   *numelem = rstr->nelem;
4314ce2993fSjeremylt   return 0;
4324ce2993fSjeremylt }
4334ce2993fSjeremylt 
4344ce2993fSjeremylt /**
4354ce2993fSjeremylt   @brief Get the size of elements in the CeedElemRestriction
4364ce2993fSjeremylt 
4374ce2993fSjeremylt   @param rstr             CeedElemRestriction
4384ce2993fSjeremylt   @param[out] elemsize    Variable to store size of elements
4394ce2993fSjeremylt 
4404ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4414ce2993fSjeremylt 
44223617272Sjeremylt   @ref Advanced
4434ce2993fSjeremylt **/
4444ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
4454ce2993fSjeremylt                                       CeedInt *elemsize) {
4464ce2993fSjeremylt   *elemsize = rstr->elemsize;
4474ce2993fSjeremylt   return 0;
4484ce2993fSjeremylt }
4494ce2993fSjeremylt 
4504ce2993fSjeremylt /**
4514ce2993fSjeremylt   @brief Get the number of degrees of freedom in the range of a
4524ce2993fSjeremylt          CeedElemRestriction
4534ce2993fSjeremylt 
4544ce2993fSjeremylt   @param rstr             CeedElemRestriction
455*8795c945Sjeremylt   @param[out] numnodes    Variable to store number of nodes
4564ce2993fSjeremylt 
4574ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4584ce2993fSjeremylt 
45923617272Sjeremylt   @ref Advanced
4604ce2993fSjeremylt **/
461*8795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr,
462*8795c945Sjeremylt                                    CeedInt *numnodes) {
463*8795c945Sjeremylt   *numnodes = rstr->nnodes;
4644ce2993fSjeremylt   return 0;
4654ce2993fSjeremylt }
4664ce2993fSjeremylt 
4674ce2993fSjeremylt /**
4684ce2993fSjeremylt   @brief Get the number of components in the elements of a
4694ce2993fSjeremylt          CeedElemRestriction
4704ce2993fSjeremylt 
4714ce2993fSjeremylt   @param rstr             CeedElemRestriction
4724ce2993fSjeremylt   @param[out] numcomp     Variable to store number of components
4734ce2993fSjeremylt 
4744ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4754ce2993fSjeremylt 
47623617272Sjeremylt   @ref Advanced
4774ce2993fSjeremylt **/
4784ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
4794ce2993fSjeremylt                                         CeedInt *numcomp) {
4804ce2993fSjeremylt   *numcomp = rstr->ncomp;
4814ce2993fSjeremylt   return 0;
4824ce2993fSjeremylt }
4834ce2993fSjeremylt 
4844ce2993fSjeremylt /**
4854ce2993fSjeremylt   @brief Get the number of blocks in a CeedElemRestriction
4864ce2993fSjeremylt 
4874ce2993fSjeremylt   @param rstr             CeedElemRestriction
4884ce2993fSjeremylt   @param[out] numblock    Variable to store number of blocks
4894ce2993fSjeremylt 
4904ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4914ce2993fSjeremylt 
49223617272Sjeremylt   @ref Advanced
4934ce2993fSjeremylt **/
4944ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
4954ce2993fSjeremylt                                     CeedInt *numblock) {
4964ce2993fSjeremylt   *numblock = rstr->nblk;
4974ce2993fSjeremylt   return 0;
4984ce2993fSjeremylt }
4994ce2993fSjeremylt 
5004ce2993fSjeremylt /**
5014ce2993fSjeremylt   @brief Get the size of blocks in the CeedElemRestriction
5024ce2993fSjeremylt 
5034ce2993fSjeremylt   @param r                CeedElemRestriction
5044ce2993fSjeremylt   @param[out] blksize     Variable to store size of blocks
5054ce2993fSjeremylt 
5064ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5074ce2993fSjeremylt 
50823617272Sjeremylt   @ref Advanced
5094ce2993fSjeremylt **/
5104ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
5114ce2993fSjeremylt                                     CeedInt *blksize) {
5124ce2993fSjeremylt   *blksize = rstr->blksize;
5134ce2993fSjeremylt   return 0;
5144ce2993fSjeremylt }
5154ce2993fSjeremylt 
5164ce2993fSjeremylt /**
5174ce2993fSjeremylt   @brief Get the backend data of a CeedElemRestriction
5184ce2993fSjeremylt 
5194ce2993fSjeremylt   @param r                CeedElemRestriction
5204ce2993fSjeremylt   @param[out] data        Variable to store data
5214ce2993fSjeremylt 
5224ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5234ce2993fSjeremylt 
52423617272Sjeremylt   @ref Advanced
5254ce2993fSjeremylt **/
5264ce2993fSjeremylt int CeedElemRestrictionGetData(CeedElemRestriction rstr,
5274ce2993fSjeremylt                                void* *data) {
5284ce2993fSjeremylt   *data = rstr->data;
529d7b241e6Sjeremylt   return 0;
530d7b241e6Sjeremylt }
531d7b241e6Sjeremylt 
532d7b241e6Sjeremylt /**
533fe2413ffSjeremylt   @brief Set the backend data of a CeedElemRestriction
534fe2413ffSjeremylt 
535fe2413ffSjeremylt   @param[out] r           CeedElemRestriction
536fe2413ffSjeremylt   @param data             Data to set
537fe2413ffSjeremylt 
538fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
539fe2413ffSjeremylt 
540fe2413ffSjeremylt   @ref Advanced
541fe2413ffSjeremylt **/
542fe2413ffSjeremylt int CeedElemRestrictionSetData(CeedElemRestriction rstr,
543fe2413ffSjeremylt                                void* *data) {
544fe2413ffSjeremylt   rstr->data = *data;
545fe2413ffSjeremylt   return 0;
546fe2413ffSjeremylt }
547fe2413ffSjeremylt 
548fe2413ffSjeremylt /**
549f02ca4a2SJed Brown   @brief View a CeedElemRestriction
550f02ca4a2SJed Brown 
551f02ca4a2SJed Brown   @param[in] rstr CeedElemRestriction to view
552f02ca4a2SJed Brown   @param[in] stream Stream to write; typically stdout/stderr or a file
553f02ca4a2SJed Brown 
554f02ca4a2SJed Brown   @return Error code: 0 - success, otherwise - failure
555f02ca4a2SJed Brown 
556f02ca4a2SJed Brown   @ref Utility
557f02ca4a2SJed Brown **/
558f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
559f02ca4a2SJed Brown   fprintf(stream,
560f02ca4a2SJed Brown           "CeedElemRestriction from (%d, %d) to %d elements with %d nodes each\n",
561*8795c945Sjeremylt           rstr->nnodes, rstr->ncomp, rstr->nelem, rstr->elemsize);
562f02ca4a2SJed Brown   return 0;
563f02ca4a2SJed Brown }
564f02ca4a2SJed Brown 
565f02ca4a2SJed Brown /**
566b11c1e72Sjeremylt   @brief Destroy a CeedElemRestriction
567b11c1e72Sjeremylt 
5684ce2993fSjeremylt   @param rstr CeedElemRestriction to destroy
569b11c1e72Sjeremylt 
570b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
571dfdf5a53Sjeremylt 
572dfdf5a53Sjeremylt   @ref Basic
573b11c1e72Sjeremylt **/
5744ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
575d7b241e6Sjeremylt   int ierr;
576d7b241e6Sjeremylt 
5774ce2993fSjeremylt   if (!*rstr || --(*rstr)->refcount > 0) return 0;
5784ce2993fSjeremylt   if ((*rstr)->Destroy) {
5794ce2993fSjeremylt     ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr);
580d7b241e6Sjeremylt   }
5814ce2993fSjeremylt   ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr);
5824ce2993fSjeremylt   ierr = CeedFree(rstr); CeedChk(ierr);
583d7b241e6Sjeremylt   return 0;
584d7b241e6Sjeremylt }
585d7b241e6Sjeremylt 
586d7b241e6Sjeremylt /// @}
587