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 3895bb1877Svaleriabarra (1 for scalar fields) 39b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 40b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 418795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 428795c945Sjeremylt ordered list of the indices (into the input CeedVector) 438795c945Sjeremylt for the unknowns corresponding to element i, where 4434138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 4523e8ed12Sjeremylt [0, @a nnodes - 1]. 464ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 47b11c1e72Sjeremylt CeedElemRestriction will be stored 48d7b241e6Sjeremylt 49b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 50dfdf5a53Sjeremylt 51dfdf5a53Sjeremylt @ref Basic 52b11c1e72Sjeremylt **/ 53d7b241e6Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize, 548795c945Sjeremylt CeedInt nnodes, CeedInt ncomp, CeedMemType mtype, 55d7b241e6Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 564ce2993fSjeremylt CeedElemRestriction *rstr) { 57d7b241e6Sjeremylt int ierr; 58d7b241e6Sjeremylt 595fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 605fe0d4faSjeremylt Ceed delegate; 61aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 62aefd8378Sjeremylt CeedChk(ierr); 635fe0d4faSjeremylt 645fe0d4faSjeremylt if (!delegate) 65c042f62fSJeremy L Thompson // LCOV_EXCL_START 66d7b241e6Sjeremylt return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 67c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 685fe0d4faSjeremylt 695fe0d4faSjeremylt ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, 708795c945Sjeremylt nnodes, ncomp, mtype, cmode, 714ce2993fSjeremylt indices, rstr); CeedChk(ierr); 725fe0d4faSjeremylt return 0; 735fe0d4faSjeremylt } 745fe0d4faSjeremylt 754ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 764ce2993fSjeremylt (*rstr)->ceed = ceed; 77d7b241e6Sjeremylt ceed->refcount++; 784ce2993fSjeremylt (*rstr)->refcount = 1; 794ce2993fSjeremylt (*rstr)->nelem = nelem; 804ce2993fSjeremylt (*rstr)->elemsize = elemsize; 818795c945Sjeremylt (*rstr)->nnodes = nnodes; 824ce2993fSjeremylt (*rstr)->ncomp = ncomp; 834ce2993fSjeremylt (*rstr)->nblk = nelem; 844ce2993fSjeremylt (*rstr)->blksize = 1; 854ce2993fSjeremylt ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr); 86d7b241e6Sjeremylt return 0; 87d7b241e6Sjeremylt } 88d7b241e6Sjeremylt 89d7b241e6Sjeremylt /** 90b11c1e72Sjeremylt @brief Create an identity CeedElemRestriction 91d7b241e6Sjeremylt 92b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 93b11c1e72Sjeremylt @param nelem Number of elements described in the @a indices array 94b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 958795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 968795c945Sjeremylt to which the restriction will be applied is of size 978795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 98d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 998795c945Sjeremylt different types of elements. 100b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 10195bb1877Svaleriabarra (1 for scalar fields) 1024ce2993fSjeremylt @param rstr Address of the variable where the newly created 103b11c1e72Sjeremylt CeedElemRestriction will be stored 104d7b241e6Sjeremylt 105b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 106dfdf5a53Sjeremylt 107dfdf5a53Sjeremylt @ref Basic 108b11c1e72Sjeremylt **/ 1094b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem, 110f90c8643Sjeremylt CeedInt elemsize, CeedInt nnodes, 111f90c8643Sjeremylt CeedInt ncomp, 112f90c8643Sjeremylt CeedElemRestriction *rstr) { 113d7b241e6Sjeremylt int ierr; 114d7b241e6Sjeremylt 1155fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 1165fe0d4faSjeremylt Ceed delegate; 117aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 118aefd8378Sjeremylt CeedChk(ierr); 1195fe0d4faSjeremylt 1205fe0d4faSjeremylt if (!delegate) 121c042f62fSJeremy L Thompson // LCOV_EXCL_START 1221d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 123c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1245fe0d4faSjeremylt 1255fe0d4faSjeremylt ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize, 1268795c945Sjeremylt nnodes, ncomp, rstr); CeedChk(ierr); 1275fe0d4faSjeremylt return 0; 1285fe0d4faSjeremylt } 1295fe0d4faSjeremylt 1304ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 1314ce2993fSjeremylt (*rstr)->ceed = ceed; 132d7b241e6Sjeremylt ceed->refcount++; 1334ce2993fSjeremylt (*rstr)->refcount = 1; 1344ce2993fSjeremylt (*rstr)->nelem = nelem; 1354ce2993fSjeremylt (*rstr)->elemsize = elemsize; 1368795c945Sjeremylt (*rstr)->nnodes = nnodes; 1374ce2993fSjeremylt (*rstr)->ncomp = ncomp; 1384ce2993fSjeremylt (*rstr)->nblk = nelem; 1394ce2993fSjeremylt (*rstr)->blksize = 1; 1401dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 1411dfeef1dSjeremylt *rstr); 1424b8bea3bSJed Brown CeedChk(ierr); 143d7b241e6Sjeremylt return 0; 144d7b241e6Sjeremylt } 145d7b241e6Sjeremylt 146d7b241e6Sjeremylt /** 147b11c1e72Sjeremylt @brief Permute and pad indices for a blocked restriction 148d7b241e6Sjeremylt 1498795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1508795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1518795c945Sjeremylt for the unknowns corresponding to element i, where 15234138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 1538795c945Sjeremylt [0, @a nnodes). 154ecf6354eSJed Brown @param blkindices Array of permuted and padded indices of 155ecf6354eSJed Brown shape [@a nblk, @a elemsize, @a blksize]. 156d7b241e6Sjeremylt @param nblk Number of blocks 157d7b241e6Sjeremylt @param nelem Number of elements 158d7b241e6Sjeremylt @param blksize Number of elements in a block 159d7b241e6Sjeremylt @param elemsize Size of each element 160d7b241e6Sjeremylt 161b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 162b11c1e72Sjeremylt 163dfdf5a53Sjeremylt @ref Utility 164b11c1e72Sjeremylt **/ 165dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices, 166692c2638Sjeremylt CeedInt nblk, CeedInt nelem, CeedInt blksize, 167692c2638Sjeremylt CeedInt elemsize) { 168d7b241e6Sjeremylt for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 169d7b241e6Sjeremylt for (int j = 0; j < blksize; j++) 170d7b241e6Sjeremylt for (int k = 0; k < elemsize; k++) 171d7b241e6Sjeremylt blkindices[e*elemsize + k*blksize + j] 172d7b241e6Sjeremylt = indices[CeedIntMin(e+j,nelem-1)*elemsize + k]; 173dfdf5a53Sjeremylt return 0; 174d7b241e6Sjeremylt } 175d7b241e6Sjeremylt 176d7b241e6Sjeremylt /** 177b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 178d7b241e6Sjeremylt 179d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 180d7b241e6Sjeremylt @param nelem Number of elements described in the @a indices array. 181b11c1e72Sjeremylt @param elemsize Size (number of unknowns) per element 182b11c1e72Sjeremylt @param blksize Number of elements in a block 1838795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 1848795c945Sjeremylt to which the restriction will be applied is of size 1858795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 186d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 187d7b241e6Sjeremylt different types of elements. 18895bb1877Svaleriabarra @param ncomp Number of field components per interpolation node 18995bb1877Svaleriabarra (1 for scalar fields) 190b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 191b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 1928795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1938795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1948795c945Sjeremylt for the unknowns corresponding to element i, where 19534138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 1968795c945Sjeremylt [0, @a nnodes). The backend will permute and pad this 1978795c945Sjeremylt array to the desired ordering for the blocksize, which is 1988795c945Sjeremylt typically given by the backend. The default reordering is 1998795c945Sjeremylt to interlace elements. 2004ce2993fSjeremylt @param rstr Address of the variable where the newly created 201b11c1e72Sjeremylt CeedElemRestriction will be stored 202d7b241e6Sjeremylt 203b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 204dfdf5a53Sjeremylt 205dfdf5a53Sjeremylt @ref Advanced 206b11c1e72Sjeremylt **/ 207d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize, 2088795c945Sjeremylt CeedInt blksize, CeedInt nnodes, 2098795c945Sjeremylt CeedInt ncomp, CeedMemType mtype, 2108795c945Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 2114ce2993fSjeremylt CeedElemRestriction *rstr) { 212d7b241e6Sjeremylt int ierr; 213d7b241e6Sjeremylt CeedInt *blkindices; 214d7b241e6Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 215d7b241e6Sjeremylt 2165fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 2175fe0d4faSjeremylt Ceed delegate; 218aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 219aefd8378Sjeremylt CeedChk(ierr); 2205fe0d4faSjeremylt 2215fe0d4faSjeremylt if (!delegate) 222c042f62fSJeremy L Thompson // LCOV_EXCL_START 2231d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 2241d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 225c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 2265fe0d4faSjeremylt 2275fe0d4faSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, 2288795c945Sjeremylt blksize, nnodes, ncomp, mtype, cmode, 2294ce2993fSjeremylt indices, rstr); CeedChk(ierr); 2305fe0d4faSjeremylt return 0; 2315fe0d4faSjeremylt } 232d7b241e6Sjeremylt 2334ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 234d7b241e6Sjeremylt 235d7b241e6Sjeremylt if (indices) { 236de686571SJeremy L Thompson ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 2374b8bea3bSJed Brown ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 2384b8bea3bSJed Brown elemsize); 239dfdf5a53Sjeremylt CeedChk(ierr); 240d7b241e6Sjeremylt } else { 241d7b241e6Sjeremylt blkindices = NULL; 242d7b241e6Sjeremylt } 243d7b241e6Sjeremylt 2444ce2993fSjeremylt (*rstr)->ceed = ceed; 245d7b241e6Sjeremylt ceed->refcount++; 2464ce2993fSjeremylt (*rstr)->refcount = 1; 2474ce2993fSjeremylt (*rstr)->nelem = nelem; 2484ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2498795c945Sjeremylt (*rstr)->nnodes = nnodes; 2504ce2993fSjeremylt (*rstr)->ncomp = ncomp; 2514ce2993fSjeremylt (*rstr)->nblk = nblk; 2524ce2993fSjeremylt (*rstr)->blksize = blksize; 253667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 2547f823360Sjeremylt (const CeedInt *) blkindices, *rstr); CeedChk(ierr); 255d7b241e6Sjeremylt 2561d102b48SJeremy L Thompson if (cmode == CEED_OWN_POINTER) { 257d7b241e6Sjeremylt ierr = CeedFree(&indices); CeedChk(ierr); 2581d102b48SJeremy L Thompson } 259d7b241e6Sjeremylt 260d7b241e6Sjeremylt return 0; 261d7b241e6Sjeremylt } 262d7b241e6Sjeremylt 263b11c1e72Sjeremylt /** 264b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 265b11c1e72Sjeremylt 2664ce2993fSjeremylt @param rstr CeedElemRestriction 267b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 268b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 269b11c1e72Sjeremylt 270b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 271dfdf5a53Sjeremylt 272dfdf5a53Sjeremylt @ref Advanced 273b11c1e72Sjeremylt **/ 2744ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 275d7b241e6Sjeremylt CeedVector *evec) { 276d7b241e6Sjeremylt int ierr; 277d7b241e6Sjeremylt CeedInt n, m; 2788795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 2794ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 280d7b241e6Sjeremylt if (lvec) { 2814ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 282d7b241e6Sjeremylt } 283d7b241e6Sjeremylt if (evec) { 2844ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 285d7b241e6Sjeremylt } 286d7b241e6Sjeremylt return 0; 287d7b241e6Sjeremylt } 288d7b241e6Sjeremylt 289d7b241e6Sjeremylt /** 290d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 291d7b241e6Sjeremylt 2924ce2993fSjeremylt @param rstr CeedElemRestriction 293d7b241e6Sjeremylt @param tmode Apply restriction or transpose 294d9e1f99aSValeria Barra @param lmode Ordering of the ncomp components, i.e. it specifies 295d9e1f99aSValeria Barra the ordering of the components of the l-vector used 296d9e1f99aSValeria Barra by this CeedElemRestriction. CEED_NOTRANSPOSE indicates 297d9e1f99aSValeria Barra the component is the outermost index and CEED_TRANSPOSE 298d9e1f99aSValeria Barra indicates the component is the innermost index in 299d9e1f99aSValeria Barra ordering of the l-vector 3007aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 3017aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE, lmode=CEED_TRANSPOSE) 3027aaeacdcSjeremylt @param v Output vector (of shape [@a nelem * @a elemsize] when 3037aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 3047aaeacdcSjeremylt by the backend. 305d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 306b11c1e72Sjeremylt 307b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 308dfdf5a53Sjeremylt 309dfdf5a53Sjeremylt @ref Advanced 310b11c1e72Sjeremylt **/ 3114ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 312692c2638Sjeremylt CeedTransposeMode lmode, CeedVector u, 313692c2638Sjeremylt CeedVector v, CeedRequest *request) { 314d7b241e6Sjeremylt CeedInt m,n; 315d7b241e6Sjeremylt int ierr; 316d7b241e6Sjeremylt 317d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 3184ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 3198795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 320d7b241e6Sjeremylt } else { 3218795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3224ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 323d7b241e6Sjeremylt } 324d7b241e6Sjeremylt if (n != u->length) 325c042f62fSJeremy L Thompson // LCOV_EXCL_START 3261d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3271d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 328c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 329d7b241e6Sjeremylt if (m != v->length) 330c042f62fSJeremy L Thompson // LCOV_EXCL_START 3311d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 3321d102b48SJeremy L Thompson "element restriction (%d, %d)", v->length, m, n); 333c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3344ce2993fSjeremylt ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr); 335d7b241e6Sjeremylt 336d7b241e6Sjeremylt return 0; 337d7b241e6Sjeremylt } 338d7b241e6Sjeremylt 339d7b241e6Sjeremylt /** 340d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 341be9261b7Sjeremylt 342be9261b7Sjeremylt @param rstr CeedElemRestriction 3431f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 3441f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 3451f37b403Sjeremylt [3*blksize : 4*blksize] 346be9261b7Sjeremylt @param tmode Apply restriction or transpose 347d9e1f99aSValeria Barra @param lmode Ordering of the ncomp components, i.e. it specifies 348d9e1f99aSValeria Barra the ordering of the components of the l-vector used 349d9e1f99aSValeria Barra by this CeedElemRestriction. CEED_NOTRANSPOSE indicates 350d9e1f99aSValeria Barra the component is the outermost index and CEED_TRANSPOSE 351d9e1f99aSValeria Barra indicates the component is the innermost index in 352d9e1f99aSValeria Barra ordering of the l-vector 3537aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 3547aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE, lmode=CEED_TRANSPOSE) 3557aaeacdcSjeremylt @param v Output vector (of shape [@a blksize * @a elemsize] when 3567aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 3577aaeacdcSjeremylt by the backend. 358be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 359be9261b7Sjeremylt 360be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 361be9261b7Sjeremylt 362be9261b7Sjeremylt @ref Advanced 363be9261b7Sjeremylt **/ 364be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 365be9261b7Sjeremylt CeedTransposeMode tmode, 366692c2638Sjeremylt CeedTransposeMode lmode, CeedVector u, 367692c2638Sjeremylt CeedVector v, CeedRequest *request) { 368be9261b7Sjeremylt CeedInt m,n; 369be9261b7Sjeremylt int ierr; 370be9261b7Sjeremylt 371be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 372be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 3738795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 374be9261b7Sjeremylt } else { 3758795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 376be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 377be9261b7Sjeremylt } 378be9261b7Sjeremylt if (n != u->length) 379c042f62fSJeremy L Thompson // LCOV_EXCL_START 3801d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3811d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 382c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 383be9261b7Sjeremylt if (m != v->length) 384c042f62fSJeremy L Thompson // LCOV_EXCL_START 3851d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 3861d102b48SJeremy L Thompson "element restriction (%d, %d)", v->length, m, n); 387c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 388be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 389c042f62fSJeremy L Thompson // LCOV_EXCL_START 3901d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 3911d102b48SJeremy L Thompson "total elements %d", block, rstr->blksize*block, 3921d102b48SJeremy L Thompson rstr->nelem); 393c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 394be9261b7Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request); 395be9261b7Sjeremylt CeedChk(ierr); 396be9261b7Sjeremylt 397be9261b7Sjeremylt return 0; 398be9261b7Sjeremylt } 399be9261b7Sjeremylt 400be9261b7Sjeremylt /** 401d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 4021469ee4dSjeremylt 4031469ee4dSjeremylt @param rstr CeedElemRestriction 404*efc78312Sjeremylt @param lmode Ordering of the ncomp components, i.e. it specifies 405*efc78312Sjeremylt the ordering of the components of the l-vector used 406*efc78312Sjeremylt by this CeedElemRestriction. CEED_NOTRANSPOSE 407*efc78312Sjeremylt indicates the component is the outermost index and 408*efc78312Sjeremylt CEED_TRANSPOSE indicates the component is the 409*efc78312Sjeremylt innermost index in ordering of the l-vector 410d9e1f99aSValeria Barra @param[out] mult Vector to store multiplicity (of size nnodes) 4111469ee4dSjeremylt 4121469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 4131469ee4dSjeremylt 4141469ee4dSjeremylt @ref Advanced 4151469ee4dSjeremylt **/ 4161469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 417*efc78312Sjeremylt CeedTransposeMode lmode, 4181469ee4dSjeremylt CeedVector mult) { 4191469ee4dSjeremylt int ierr; 4201469ee4dSjeremylt CeedVector evec; 4211469ee4dSjeremylt 4221469ee4dSjeremylt // Create and set evec 4231469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 4241469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 4251469ee4dSjeremylt 4261469ee4dSjeremylt // Apply to get multiplicity 427*efc78312Sjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, lmode, evec, mult, 428*efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 4291469ee4dSjeremylt 4301469ee4dSjeremylt // Cleanup 4311469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 4321469ee4dSjeremylt 4331469ee4dSjeremylt return 0; 4341469ee4dSjeremylt } 4351469ee4dSjeremylt 4361469ee4dSjeremylt /** 4374ce2993fSjeremylt @brief Get the Ceed associated with a CeedElemRestriction 4384ce2993fSjeremylt 4394ce2993fSjeremylt @param rstr CeedElemRestriction 4404ce2993fSjeremylt @param[out] ceed Variable to store Ceed 4414ce2993fSjeremylt 4424ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4434ce2993fSjeremylt 44423617272Sjeremylt @ref Advanced 4454ce2993fSjeremylt **/ 4464ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 4474ce2993fSjeremylt *ceed = rstr->ceed; 4484ce2993fSjeremylt return 0; 4494ce2993fSjeremylt } 4504ce2993fSjeremylt 4514ce2993fSjeremylt /** 452b11c1e72Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 453d7b241e6Sjeremylt 4544ce2993fSjeremylt @param rstr CeedElemRestriction 455288c0443SJeremy L Thompson @param[out] numelem Variable to store number of elements 456b11c1e72Sjeremylt 457b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 458dfdf5a53Sjeremylt 45923617272Sjeremylt @ref Advanced 460b11c1e72Sjeremylt **/ 4614ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 4624ce2993fSjeremylt CeedInt *numelem) { 4634ce2993fSjeremylt *numelem = rstr->nelem; 4644ce2993fSjeremylt return 0; 4654ce2993fSjeremylt } 4664ce2993fSjeremylt 4674ce2993fSjeremylt /** 4684ce2993fSjeremylt @brief Get the size of elements in the CeedElemRestriction 4694ce2993fSjeremylt 4704ce2993fSjeremylt @param rstr CeedElemRestriction 4714ce2993fSjeremylt @param[out] elemsize Variable to store size of elements 4724ce2993fSjeremylt 4734ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4744ce2993fSjeremylt 47523617272Sjeremylt @ref Advanced 4764ce2993fSjeremylt **/ 4774ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 4784ce2993fSjeremylt CeedInt *elemsize) { 4794ce2993fSjeremylt *elemsize = rstr->elemsize; 4804ce2993fSjeremylt return 0; 4814ce2993fSjeremylt } 4824ce2993fSjeremylt 4834ce2993fSjeremylt /** 4844ce2993fSjeremylt @brief Get the number of degrees of freedom in the range of a 4854ce2993fSjeremylt CeedElemRestriction 4864ce2993fSjeremylt 4874ce2993fSjeremylt @param rstr CeedElemRestriction 4888795c945Sjeremylt @param[out] numnodes Variable to store number of nodes 4894ce2993fSjeremylt 4904ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4914ce2993fSjeremylt 49223617272Sjeremylt @ref Advanced 4934ce2993fSjeremylt **/ 4948795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr, 4958795c945Sjeremylt CeedInt *numnodes) { 4968795c945Sjeremylt *numnodes = rstr->nnodes; 4974ce2993fSjeremylt return 0; 4984ce2993fSjeremylt } 4994ce2993fSjeremylt 5004ce2993fSjeremylt /** 5014ce2993fSjeremylt @brief Get the number of components in the elements of a 5024ce2993fSjeremylt CeedElemRestriction 5034ce2993fSjeremylt 5044ce2993fSjeremylt @param rstr CeedElemRestriction 5054ce2993fSjeremylt @param[out] numcomp Variable to store number of components 5064ce2993fSjeremylt 5074ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5084ce2993fSjeremylt 50923617272Sjeremylt @ref Advanced 5104ce2993fSjeremylt **/ 5114ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 5124ce2993fSjeremylt CeedInt *numcomp) { 5134ce2993fSjeremylt *numcomp = rstr->ncomp; 5144ce2993fSjeremylt return 0; 5154ce2993fSjeremylt } 5164ce2993fSjeremylt 5174ce2993fSjeremylt /** 5184ce2993fSjeremylt @brief Get the number of blocks in a CeedElemRestriction 5194ce2993fSjeremylt 5204ce2993fSjeremylt @param rstr CeedElemRestriction 5214ce2993fSjeremylt @param[out] numblock Variable to store number of blocks 5224ce2993fSjeremylt 5234ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5244ce2993fSjeremylt 52523617272Sjeremylt @ref Advanced 5264ce2993fSjeremylt **/ 5274ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 5284ce2993fSjeremylt CeedInt *numblock) { 5294ce2993fSjeremylt *numblock = rstr->nblk; 5304ce2993fSjeremylt return 0; 5314ce2993fSjeremylt } 5324ce2993fSjeremylt 5334ce2993fSjeremylt /** 5344ce2993fSjeremylt @brief Get the size of blocks in the CeedElemRestriction 5354ce2993fSjeremylt 536288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5374ce2993fSjeremylt @param[out] blksize Variable to store size of blocks 5384ce2993fSjeremylt 5394ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5404ce2993fSjeremylt 54123617272Sjeremylt @ref Advanced 5424ce2993fSjeremylt **/ 5434ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 5444ce2993fSjeremylt CeedInt *blksize) { 5454ce2993fSjeremylt *blksize = rstr->blksize; 5464ce2993fSjeremylt return 0; 5474ce2993fSjeremylt } 5484ce2993fSjeremylt 5494ce2993fSjeremylt /** 5504ce2993fSjeremylt @brief Get the backend data of a CeedElemRestriction 5514ce2993fSjeremylt 552288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5534ce2993fSjeremylt @param[out] data Variable to store data 5544ce2993fSjeremylt 5554ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5564ce2993fSjeremylt 55723617272Sjeremylt @ref Advanced 5584ce2993fSjeremylt **/ 5591d102b48SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 5604ce2993fSjeremylt *data = rstr->data; 561d7b241e6Sjeremylt return 0; 562d7b241e6Sjeremylt } 563d7b241e6Sjeremylt 564d7b241e6Sjeremylt /** 565fe2413ffSjeremylt @brief Set the backend data of a CeedElemRestriction 566fe2413ffSjeremylt 567288c0443SJeremy L Thompson @param[out] rstr CeedElemRestriction 568fe2413ffSjeremylt @param data Data to set 569fe2413ffSjeremylt 570fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 571fe2413ffSjeremylt 572fe2413ffSjeremylt @ref Advanced 573fe2413ffSjeremylt **/ 5741d102b48SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 575fe2413ffSjeremylt rstr->data = *data; 576fe2413ffSjeremylt return 0; 577fe2413ffSjeremylt } 578fe2413ffSjeremylt 579fe2413ffSjeremylt /** 580f02ca4a2SJed Brown @brief View a CeedElemRestriction 581f02ca4a2SJed Brown 582f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 583f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 584f02ca4a2SJed Brown 585f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 586f02ca4a2SJed Brown 587f02ca4a2SJed Brown @ref Utility 588f02ca4a2SJed Brown **/ 589f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 5901d102b48SJeremy L Thompson fprintf(stream, "CeedElemRestriction from (%d, %d) to %d elements with %d " 5911d102b48SJeremy L Thompson "nodes each\n", rstr->nnodes, rstr->ncomp, rstr->nelem, 5921d102b48SJeremy L Thompson rstr->elemsize); 593f02ca4a2SJed Brown return 0; 594f02ca4a2SJed Brown } 595f02ca4a2SJed Brown 596f02ca4a2SJed Brown /** 597b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 598b11c1e72Sjeremylt 5994ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 600b11c1e72Sjeremylt 601b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 602dfdf5a53Sjeremylt 603dfdf5a53Sjeremylt @ref Basic 604b11c1e72Sjeremylt **/ 6054ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 606d7b241e6Sjeremylt int ierr; 607d7b241e6Sjeremylt 6081d102b48SJeremy L Thompson if (!*rstr || --(*rstr)->refcount > 0) 6091d102b48SJeremy L Thompson return 0; 6104ce2993fSjeremylt if ((*rstr)->Destroy) { 6114ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 612d7b241e6Sjeremylt } 6134ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 6144ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 615d7b241e6Sjeremylt return 0; 616d7b241e6Sjeremylt } 617d7b241e6Sjeremylt 618d7b241e6Sjeremylt /// @} 619