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 3061dbc9d2Sjeremylt @param imode Ordering of the ncomp components, i.e. it specifies 31a8d32208Sjeremylt the ordering of the components of the L-vector used 3261dbc9d2Sjeremylt by this CeedElemRestriction. CEED_NONINTERLACED indicates 3361dbc9d2Sjeremylt the component is the outermost index and CEED_INTERLACED 34a8d32208Sjeremylt indicates the component is the innermost index in 35a8d32208Sjeremylt ordering of the L-vector. 36b11c1e72Sjeremylt @param nelem Number of elements described in the @a indices array 37b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 388795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 398795c945Sjeremylt to which the restriction will be applied is of size 408795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 41d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 42d7b241e6Sjeremylt different types of elements. 43b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 4495bb1877Svaleriabarra (1 for scalar fields) 45b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 46b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 478795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 488795c945Sjeremylt ordered list of the indices (into the input CeedVector) 498795c945Sjeremylt for the unknowns corresponding to element i, where 5034138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 5123e8ed12Sjeremylt [0, @a nnodes - 1]. 524ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 53b11c1e72Sjeremylt CeedElemRestriction will be stored 54d7b241e6Sjeremylt 55b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 56dfdf5a53Sjeremylt 57dfdf5a53Sjeremylt @ref Basic 58b11c1e72Sjeremylt **/ 5961dbc9d2Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInterlaceMode imode, 6061dbc9d2Sjeremylt CeedInt nelem, 6161dbc9d2Sjeremylt CeedInt elemsize, CeedInt nnodes, CeedInt ncomp, 6261dbc9d2Sjeremylt CeedMemType mtype, CeedCopyMode cmode, 6361dbc9d2Sjeremylt const CeedInt *indices, 644ce2993fSjeremylt CeedElemRestriction *rstr) { 65d7b241e6Sjeremylt int ierr; 66d7b241e6Sjeremylt 675fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 685fe0d4faSjeremylt Ceed delegate; 69aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 70aefd8378Sjeremylt CeedChk(ierr); 715fe0d4faSjeremylt 725fe0d4faSjeremylt if (!delegate) 73c042f62fSJeremy L Thompson // LCOV_EXCL_START 74d7b241e6Sjeremylt return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 75c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 765fe0d4faSjeremylt 7761dbc9d2Sjeremylt ierr = CeedElemRestrictionCreate(delegate, imode, nelem, elemsize, 788795c945Sjeremylt nnodes, ncomp, mtype, cmode, 794ce2993fSjeremylt indices, rstr); CeedChk(ierr); 805fe0d4faSjeremylt return 0; 815fe0d4faSjeremylt } 825fe0d4faSjeremylt 834ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 844ce2993fSjeremylt (*rstr)->ceed = ceed; 85d7b241e6Sjeremylt ceed->refcount++; 864ce2993fSjeremylt (*rstr)->refcount = 1; 8761dbc9d2Sjeremylt (*rstr)->imode = imode; 884ce2993fSjeremylt (*rstr)->nelem = nelem; 894ce2993fSjeremylt (*rstr)->elemsize = elemsize; 908795c945Sjeremylt (*rstr)->nnodes = nnodes; 914ce2993fSjeremylt (*rstr)->ncomp = ncomp; 924ce2993fSjeremylt (*rstr)->nblk = nelem; 934ce2993fSjeremylt (*rstr)->blksize = 1; 944ce2993fSjeremylt ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr); 95d7b241e6Sjeremylt return 0; 96d7b241e6Sjeremylt } 97d7b241e6Sjeremylt 98d7b241e6Sjeremylt /** 99b11c1e72Sjeremylt @brief Create an identity CeedElemRestriction 100d7b241e6Sjeremylt 101b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 10261dbc9d2Sjeremylt @param imode Ordering of the ncomp components, i.e. it specifies 103a8d32208Sjeremylt the ordering of the components of the L-vector used 10461dbc9d2Sjeremylt by this CeedElemRestriction. CEED_NONINTERLACED indicates 10561dbc9d2Sjeremylt the component is the outermost index and CEED_INTERLACED 106a8d32208Sjeremylt indicates the component is the innermost index in 107a8d32208Sjeremylt ordering of the L-vector. 108b11c1e72Sjeremylt @param nelem Number of elements described in the @a indices array 109b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 1108795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 1118795c945Sjeremylt to which the restriction will be applied is of size 1128795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 113d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 1148795c945Sjeremylt different types of elements. 115b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 11695bb1877Svaleriabarra (1 for scalar fields) 1174ce2993fSjeremylt @param rstr Address of the variable where the newly created 118b11c1e72Sjeremylt CeedElemRestriction will be stored 119d7b241e6Sjeremylt 120b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 121dfdf5a53Sjeremylt 122dfdf5a53Sjeremylt @ref Basic 123b11c1e72Sjeremylt **/ 12461dbc9d2Sjeremylt int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInterlaceMode imode, 125a8d32208Sjeremylt CeedInt nelem, CeedInt elemsize, 126a8d32208Sjeremylt CeedInt nnodes, CeedInt ncomp, 127f90c8643Sjeremylt CeedElemRestriction *rstr) { 128d7b241e6Sjeremylt int ierr; 129d7b241e6Sjeremylt 1305fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 1315fe0d4faSjeremylt Ceed delegate; 132aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 133aefd8378Sjeremylt CeedChk(ierr); 1345fe0d4faSjeremylt 1355fe0d4faSjeremylt if (!delegate) 136c042f62fSJeremy L Thompson // LCOV_EXCL_START 1371d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 138c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1395fe0d4faSjeremylt 14061dbc9d2Sjeremylt ierr = CeedElemRestrictionCreateIdentity(delegate, imode, nelem, elemsize, 1418795c945Sjeremylt nnodes, ncomp, rstr); CeedChk(ierr); 1425fe0d4faSjeremylt return 0; 1435fe0d4faSjeremylt } 1445fe0d4faSjeremylt 1454ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 1464ce2993fSjeremylt (*rstr)->ceed = ceed; 147d7b241e6Sjeremylt ceed->refcount++; 1484ce2993fSjeremylt (*rstr)->refcount = 1; 14961dbc9d2Sjeremylt (*rstr)->imode = imode; 1504ce2993fSjeremylt (*rstr)->nelem = nelem; 1514ce2993fSjeremylt (*rstr)->elemsize = elemsize; 1528795c945Sjeremylt (*rstr)->nnodes = nnodes; 1534ce2993fSjeremylt (*rstr)->ncomp = ncomp; 1544ce2993fSjeremylt (*rstr)->nblk = nelem; 1554ce2993fSjeremylt (*rstr)->blksize = 1; 1561dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 1571dfeef1dSjeremylt *rstr); 1584b8bea3bSJed Brown CeedChk(ierr); 159d7b241e6Sjeremylt return 0; 160d7b241e6Sjeremylt } 161d7b241e6Sjeremylt 162d7b241e6Sjeremylt /** 163b11c1e72Sjeremylt @brief Permute and pad indices for a blocked restriction 164d7b241e6Sjeremylt 1658795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1668795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1678795c945Sjeremylt for the unknowns corresponding to element i, where 16834138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 1698795c945Sjeremylt [0, @a nnodes). 170ecf6354eSJed Brown @param blkindices Array of permuted and padded indices of 171ecf6354eSJed Brown shape [@a nblk, @a elemsize, @a blksize]. 172d7b241e6Sjeremylt @param nblk Number of blocks 173d7b241e6Sjeremylt @param nelem Number of elements 174d7b241e6Sjeremylt @param blksize Number of elements in a block 175d7b241e6Sjeremylt @param elemsize Size of each element 176d7b241e6Sjeremylt 177b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 178b11c1e72Sjeremylt 179dfdf5a53Sjeremylt @ref Utility 180b11c1e72Sjeremylt **/ 181dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices, 182692c2638Sjeremylt CeedInt nblk, CeedInt nelem, CeedInt blksize, 183692c2638Sjeremylt CeedInt elemsize) { 184d7b241e6Sjeremylt for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 185d7b241e6Sjeremylt for (int j = 0; j < blksize; j++) 186d7b241e6Sjeremylt for (int k = 0; k < elemsize; k++) 187d7b241e6Sjeremylt blkindices[e*elemsize + k*blksize + j] 188d7b241e6Sjeremylt = indices[CeedIntMin(e+j,nelem-1)*elemsize + k]; 189dfdf5a53Sjeremylt return 0; 190d7b241e6Sjeremylt } 191d7b241e6Sjeremylt 192d7b241e6Sjeremylt /** 193b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 194d7b241e6Sjeremylt 195d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 19661dbc9d2Sjeremylt @param imode Ordering of the ncomp components, i.e. it specifies 197a8d32208Sjeremylt the ordering of the components of the L-vector used 19861dbc9d2Sjeremylt by this CeedElemRestriction. CEED_NONINTERLACED indicates 19961dbc9d2Sjeremylt the component is the outermost index and CEED_INTERLACED 200a8d32208Sjeremylt indicates the component is the innermost index in 201a8d32208Sjeremylt ordering of the L-vector. 202d7b241e6Sjeremylt @param nelem Number of elements described in the @a indices array. 203b11c1e72Sjeremylt @param elemsize Size (number of unknowns) per element 204b11c1e72Sjeremylt @param blksize Number of elements in a block 2058795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 2068795c945Sjeremylt to which the restriction will be applied is of size 2078795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 208d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 209d7b241e6Sjeremylt different types of elements. 21095bb1877Svaleriabarra @param ncomp Number of field components per interpolation node 21195bb1877Svaleriabarra (1 for scalar fields) 212b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 213b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 2148795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 2158795c945Sjeremylt ordered list of the indices (into the input CeedVector) 2168795c945Sjeremylt for the unknowns corresponding to element i, where 21734138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 2188795c945Sjeremylt [0, @a nnodes). The backend will permute and pad this 2198795c945Sjeremylt array to the desired ordering for the blocksize, which is 2208795c945Sjeremylt typically given by the backend. The default reordering is 2218795c945Sjeremylt to interlace elements. 2224ce2993fSjeremylt @param rstr Address of the variable where the newly created 223b11c1e72Sjeremylt CeedElemRestriction will be stored 224d7b241e6Sjeremylt 225b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 226dfdf5a53Sjeremylt 227dfdf5a53Sjeremylt @ref Advanced 228b11c1e72Sjeremylt **/ 22961dbc9d2Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInterlaceMode imode, 230a8d32208Sjeremylt CeedInt nelem, CeedInt elemsize, 2318795c945Sjeremylt CeedInt blksize, CeedInt nnodes, 2328795c945Sjeremylt CeedInt ncomp, CeedMemType mtype, 2338795c945Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 2344ce2993fSjeremylt CeedElemRestriction *rstr) { 235d7b241e6Sjeremylt int ierr; 236d7b241e6Sjeremylt CeedInt *blkindices; 237d7b241e6Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 238d7b241e6Sjeremylt 2395fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 2405fe0d4faSjeremylt Ceed delegate; 241aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 242aefd8378Sjeremylt CeedChk(ierr); 2435fe0d4faSjeremylt 2445fe0d4faSjeremylt if (!delegate) 245c042f62fSJeremy L Thompson // LCOV_EXCL_START 2461d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 2471d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 248c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 2495fe0d4faSjeremylt 25061dbc9d2Sjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, imode, nelem, elemsize, 2518795c945Sjeremylt blksize, nnodes, ncomp, mtype, cmode, 2524ce2993fSjeremylt indices, rstr); CeedChk(ierr); 2535fe0d4faSjeremylt return 0; 2545fe0d4faSjeremylt } 255d7b241e6Sjeremylt 2564ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 257d7b241e6Sjeremylt 258d7b241e6Sjeremylt if (indices) { 259de686571SJeremy L Thompson ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 2604b8bea3bSJed Brown ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 2614b8bea3bSJed Brown elemsize); 262dfdf5a53Sjeremylt CeedChk(ierr); 263d7b241e6Sjeremylt } else { 264d7b241e6Sjeremylt blkindices = NULL; 265d7b241e6Sjeremylt } 266d7b241e6Sjeremylt 2674ce2993fSjeremylt (*rstr)->ceed = ceed; 268d7b241e6Sjeremylt ceed->refcount++; 2694ce2993fSjeremylt (*rstr)->refcount = 1; 27061dbc9d2Sjeremylt (*rstr)->imode = imode; 2714ce2993fSjeremylt (*rstr)->nelem = nelem; 2724ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2738795c945Sjeremylt (*rstr)->nnodes = nnodes; 2744ce2993fSjeremylt (*rstr)->ncomp = ncomp; 2754ce2993fSjeremylt (*rstr)->nblk = nblk; 2764ce2993fSjeremylt (*rstr)->blksize = blksize; 277667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 2787f823360Sjeremylt (const CeedInt *) blkindices, *rstr); CeedChk(ierr); 279d7b241e6Sjeremylt 2801d102b48SJeremy L Thompson if (cmode == CEED_OWN_POINTER) { 281d7b241e6Sjeremylt ierr = CeedFree(&indices); CeedChk(ierr); 2821d102b48SJeremy L Thompson } 283d7b241e6Sjeremylt 284d7b241e6Sjeremylt return 0; 285d7b241e6Sjeremylt } 286d7b241e6Sjeremylt 287b11c1e72Sjeremylt /** 288b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 289b11c1e72Sjeremylt 2904ce2993fSjeremylt @param rstr CeedElemRestriction 291b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 292b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 293b11c1e72Sjeremylt 294b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 295dfdf5a53Sjeremylt 296dfdf5a53Sjeremylt @ref Advanced 297b11c1e72Sjeremylt **/ 2984ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 299d7b241e6Sjeremylt CeedVector *evec) { 300d7b241e6Sjeremylt int ierr; 301d7b241e6Sjeremylt CeedInt n, m; 3028795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3034ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 304d7b241e6Sjeremylt if (lvec) { 3054ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 306d7b241e6Sjeremylt } 307d7b241e6Sjeremylt if (evec) { 3084ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 309d7b241e6Sjeremylt } 310d7b241e6Sjeremylt return 0; 311d7b241e6Sjeremylt } 312d7b241e6Sjeremylt 313d7b241e6Sjeremylt /** 314d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 315d7b241e6Sjeremylt 3164ce2993fSjeremylt @param rstr CeedElemRestriction 317d7b241e6Sjeremylt @param tmode Apply restriction or transpose 3187aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 31961dbc9d2Sjeremylt tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED) 320a8d32208Sjeremylt @param ru Output vector (of shape [@a nelem * @a elemsize] when 3217aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 3227aaeacdcSjeremylt by the backend. 323d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 324b11c1e72Sjeremylt 325b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 326dfdf5a53Sjeremylt 327dfdf5a53Sjeremylt @ref Advanced 328b11c1e72Sjeremylt **/ 3294ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 330a8d32208Sjeremylt CeedVector u, CeedVector ru, 331a8d32208Sjeremylt CeedRequest *request) { 332d7b241e6Sjeremylt CeedInt m,n; 333d7b241e6Sjeremylt int ierr; 334d7b241e6Sjeremylt 335d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 3364ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 3378795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 338d7b241e6Sjeremylt } else { 3398795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3404ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 341d7b241e6Sjeremylt } 342d7b241e6Sjeremylt if (n != u->length) 343c042f62fSJeremy L Thompson // LCOV_EXCL_START 3441d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3451d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 346c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 347a8d32208Sjeremylt if (m != ru->length) 348c042f62fSJeremy L Thompson // LCOV_EXCL_START 3491d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 350a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 351c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 352074cb416Sjeremylt ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr); 353d7b241e6Sjeremylt 354d7b241e6Sjeremylt return 0; 355d7b241e6Sjeremylt } 356d7b241e6Sjeremylt 357d7b241e6Sjeremylt /** 358d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 359be9261b7Sjeremylt 360be9261b7Sjeremylt @param rstr CeedElemRestriction 3611f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 3621f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 3631f37b403Sjeremylt [3*blksize : 4*blksize] 364be9261b7Sjeremylt @param tmode Apply restriction or transpose 3657aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 36661dbc9d2Sjeremylt tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED) 367a8d32208Sjeremylt @param ru Output vector (of shape [@a blksize * @a elemsize] when 3687aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 3697aaeacdcSjeremylt by the backend. 370be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 371be9261b7Sjeremylt 372be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 373be9261b7Sjeremylt 374be9261b7Sjeremylt @ref Advanced 375be9261b7Sjeremylt **/ 376be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 377a8d32208Sjeremylt CeedTransposeMode tmode, CeedVector u, 378a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 379be9261b7Sjeremylt CeedInt m,n; 380be9261b7Sjeremylt int ierr; 381be9261b7Sjeremylt 382be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 383be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 3848795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 385be9261b7Sjeremylt } else { 3868795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 387be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 388be9261b7Sjeremylt } 389be9261b7Sjeremylt if (n != u->length) 390c042f62fSJeremy L Thompson // LCOV_EXCL_START 3911d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3921d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 393c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 394a8d32208Sjeremylt if (m != ru->length) 395c042f62fSJeremy L Thompson // LCOV_EXCL_START 3961d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 397a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 398c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 399be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 400c042f62fSJeremy L Thompson // LCOV_EXCL_START 4011d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 4021d102b48SJeremy L Thompson "total elements %d", block, rstr->blksize*block, 4031d102b48SJeremy L Thompson rstr->nelem); 404c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 405074cb416Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request); 406be9261b7Sjeremylt CeedChk(ierr); 407be9261b7Sjeremylt 408be9261b7Sjeremylt return 0; 409be9261b7Sjeremylt } 410be9261b7Sjeremylt 411be9261b7Sjeremylt /** 412d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 4131469ee4dSjeremylt 4141469ee4dSjeremylt @param rstr CeedElemRestriction 415*b9c05c73SJed Brown @param[out] mult Vector to store multiplicity (of size nnodes*ncomp) 4161469ee4dSjeremylt 4171469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 4181469ee4dSjeremylt 4191469ee4dSjeremylt @ref Advanced 4201469ee4dSjeremylt **/ 4211469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 4221469ee4dSjeremylt CeedVector mult) { 4231469ee4dSjeremylt int ierr; 4241469ee4dSjeremylt CeedVector evec; 4251469ee4dSjeremylt 4261469ee4dSjeremylt // Create and set evec 4271469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 4281469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 429fa9eac48SJed Brown ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 4301469ee4dSjeremylt 4311469ee4dSjeremylt // Apply to get multiplicity 432a8d32208Sjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult, 433efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 4341469ee4dSjeremylt 4351469ee4dSjeremylt // Cleanup 4361469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 4371469ee4dSjeremylt 4381469ee4dSjeremylt return 0; 4391469ee4dSjeremylt } 4401469ee4dSjeremylt 4411469ee4dSjeremylt /** 4424ce2993fSjeremylt @brief Get the Ceed associated with a CeedElemRestriction 4434ce2993fSjeremylt 4444ce2993fSjeremylt @param rstr CeedElemRestriction 4454ce2993fSjeremylt @param[out] ceed Variable to store Ceed 4464ce2993fSjeremylt 4474ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4484ce2993fSjeremylt 44923617272Sjeremylt @ref Advanced 4504ce2993fSjeremylt **/ 4514ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 4524ce2993fSjeremylt *ceed = rstr->ceed; 4534ce2993fSjeremylt return 0; 4544ce2993fSjeremylt } 4554ce2993fSjeremylt 4564ce2993fSjeremylt /** 45761dbc9d2Sjeremylt @brief Get the L-vector interlaced mode of a CeedElemRestriction 458a8d32208Sjeremylt 459a8d32208Sjeremylt @param rstr CeedElemRestriction 46061dbc9d2Sjeremylt @param[out] imode Variable to store imode 461a8d32208Sjeremylt 462a8d32208Sjeremylt @return An error code: 0 - success, otherwise - failure 463a8d32208Sjeremylt 464a8d32208Sjeremylt @ref Advanced 465a8d32208Sjeremylt **/ 46661dbc9d2Sjeremylt int CeedElemRestrictionGetIMode(CeedElemRestriction rstr, 46761dbc9d2Sjeremylt CeedInterlaceMode *imode) { 46861dbc9d2Sjeremylt *imode = rstr->imode; 469a8d32208Sjeremylt return 0; 470a8d32208Sjeremylt } 471a8d32208Sjeremylt 472a8d32208Sjeremylt /** 473b11c1e72Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 474d7b241e6Sjeremylt 4754ce2993fSjeremylt @param rstr CeedElemRestriction 476288c0443SJeremy L Thompson @param[out] numelem Variable to store number of elements 477b11c1e72Sjeremylt 478b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 479dfdf5a53Sjeremylt 48023617272Sjeremylt @ref Advanced 481b11c1e72Sjeremylt **/ 4824ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 4834ce2993fSjeremylt CeedInt *numelem) { 4844ce2993fSjeremylt *numelem = rstr->nelem; 4854ce2993fSjeremylt return 0; 4864ce2993fSjeremylt } 4874ce2993fSjeremylt 4884ce2993fSjeremylt /** 4894ce2993fSjeremylt @brief Get the size of elements in the CeedElemRestriction 4904ce2993fSjeremylt 4914ce2993fSjeremylt @param rstr CeedElemRestriction 4924ce2993fSjeremylt @param[out] elemsize Variable to store size of elements 4934ce2993fSjeremylt 4944ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4954ce2993fSjeremylt 49623617272Sjeremylt @ref Advanced 4974ce2993fSjeremylt **/ 4984ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 4994ce2993fSjeremylt CeedInt *elemsize) { 5004ce2993fSjeremylt *elemsize = rstr->elemsize; 5014ce2993fSjeremylt return 0; 5024ce2993fSjeremylt } 5034ce2993fSjeremylt 5044ce2993fSjeremylt /** 5054ce2993fSjeremylt @brief Get the number of degrees of freedom in the range of a 5064ce2993fSjeremylt CeedElemRestriction 5074ce2993fSjeremylt 5084ce2993fSjeremylt @param rstr CeedElemRestriction 5098795c945Sjeremylt @param[out] numnodes Variable to store number of nodes 5104ce2993fSjeremylt 5114ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5124ce2993fSjeremylt 51323617272Sjeremylt @ref Advanced 5144ce2993fSjeremylt **/ 5158795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr, 5168795c945Sjeremylt CeedInt *numnodes) { 5178795c945Sjeremylt *numnodes = rstr->nnodes; 5184ce2993fSjeremylt return 0; 5194ce2993fSjeremylt } 5204ce2993fSjeremylt 5214ce2993fSjeremylt /** 5224ce2993fSjeremylt @brief Get the number of components in the elements of a 5234ce2993fSjeremylt CeedElemRestriction 5244ce2993fSjeremylt 5254ce2993fSjeremylt @param rstr CeedElemRestriction 5264ce2993fSjeremylt @param[out] numcomp Variable to store number of components 5274ce2993fSjeremylt 5284ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5294ce2993fSjeremylt 53023617272Sjeremylt @ref Advanced 5314ce2993fSjeremylt **/ 5324ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 5334ce2993fSjeremylt CeedInt *numcomp) { 5344ce2993fSjeremylt *numcomp = rstr->ncomp; 5354ce2993fSjeremylt return 0; 5364ce2993fSjeremylt } 5374ce2993fSjeremylt 5384ce2993fSjeremylt /** 5394ce2993fSjeremylt @brief Get the number of blocks in a CeedElemRestriction 5404ce2993fSjeremylt 5414ce2993fSjeremylt @param rstr CeedElemRestriction 5424ce2993fSjeremylt @param[out] numblock Variable to store number of blocks 5434ce2993fSjeremylt 5444ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5454ce2993fSjeremylt 54623617272Sjeremylt @ref Advanced 5474ce2993fSjeremylt **/ 5484ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 5494ce2993fSjeremylt CeedInt *numblock) { 5504ce2993fSjeremylt *numblock = rstr->nblk; 5514ce2993fSjeremylt return 0; 5524ce2993fSjeremylt } 5534ce2993fSjeremylt 5544ce2993fSjeremylt /** 5554ce2993fSjeremylt @brief Get the size of blocks in the CeedElemRestriction 5564ce2993fSjeremylt 557288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5584ce2993fSjeremylt @param[out] blksize Variable to store size of blocks 5594ce2993fSjeremylt 5604ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5614ce2993fSjeremylt 56223617272Sjeremylt @ref Advanced 5634ce2993fSjeremylt **/ 5644ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 5654ce2993fSjeremylt CeedInt *blksize) { 5664ce2993fSjeremylt *blksize = rstr->blksize; 5674ce2993fSjeremylt return 0; 5684ce2993fSjeremylt } 5694ce2993fSjeremylt 5704ce2993fSjeremylt /** 5714ce2993fSjeremylt @brief Get the backend data of a CeedElemRestriction 5724ce2993fSjeremylt 573288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5744ce2993fSjeremylt @param[out] data Variable to store data 5754ce2993fSjeremylt 5764ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5774ce2993fSjeremylt 57823617272Sjeremylt @ref Advanced 5794ce2993fSjeremylt **/ 5801d102b48SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 5814ce2993fSjeremylt *data = rstr->data; 582d7b241e6Sjeremylt return 0; 583d7b241e6Sjeremylt } 584d7b241e6Sjeremylt 585d7b241e6Sjeremylt /** 586fe2413ffSjeremylt @brief Set the backend data of a CeedElemRestriction 587fe2413ffSjeremylt 588288c0443SJeremy L Thompson @param[out] rstr CeedElemRestriction 589fe2413ffSjeremylt @param data Data to set 590fe2413ffSjeremylt 591fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 592fe2413ffSjeremylt 593fe2413ffSjeremylt @ref Advanced 594fe2413ffSjeremylt **/ 5951d102b48SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 596fe2413ffSjeremylt rstr->data = *data; 597fe2413ffSjeremylt return 0; 598fe2413ffSjeremylt } 599fe2413ffSjeremylt 600fe2413ffSjeremylt /** 601f02ca4a2SJed Brown @brief View a CeedElemRestriction 602f02ca4a2SJed Brown 603f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 604f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 605f02ca4a2SJed Brown 606f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 607f02ca4a2SJed Brown 608f02ca4a2SJed Brown @ref Utility 609f02ca4a2SJed Brown **/ 610f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 6111d102b48SJeremy L Thompson fprintf(stream, "CeedElemRestriction from (%d, %d) to %d elements with %d " 61261dbc9d2Sjeremylt "nodes each and L-vector components %s\n", rstr->nnodes, rstr->ncomp, 61361dbc9d2Sjeremylt rstr->nelem, rstr->elemsize, CeedInterlaceModes[rstr->imode]); 614f02ca4a2SJed Brown return 0; 615f02ca4a2SJed Brown } 616f02ca4a2SJed Brown 617f02ca4a2SJed Brown /** 618b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 619b11c1e72Sjeremylt 6204ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 621b11c1e72Sjeremylt 622b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 623dfdf5a53Sjeremylt 624dfdf5a53Sjeremylt @ref Basic 625b11c1e72Sjeremylt **/ 6264ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 627d7b241e6Sjeremylt int ierr; 628d7b241e6Sjeremylt 6291d102b48SJeremy L Thompson if (!*rstr || --(*rstr)->refcount > 0) 6301d102b48SJeremy L Thompson return 0; 6314ce2993fSjeremylt if ((*rstr)->Destroy) { 6324ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 633d7b241e6Sjeremylt } 6344ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 6354ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 636d7b241e6Sjeremylt return 0; 637d7b241e6Sjeremylt } 638d7b241e6Sjeremylt 639d7b241e6Sjeremylt /// @} 640