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 32d7b241e6Sjeremylt @param ndof The total size of the input CeedVector to which the 33d7b241e6Sjeremylt restriction will be applied. This size may include data 34d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 35d7b241e6Sjeremylt different types of elements. 36b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 37b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 38b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 39ecf6354eSJed Brown @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list 40d7b241e6Sjeremylt of the indices (into the input CeedVector) for the unknowns 41d7b241e6Sjeremylt corresponding to element i, where 0 <= i < @a nelements. 42d7b241e6Sjeremylt All indices must be in the range [0, @a ndof). 434ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 44b11c1e72Sjeremylt CeedElemRestriction will be stored 45d7b241e6Sjeremylt 46b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 47dfdf5a53Sjeremylt 48dfdf5a53Sjeremylt @ref Basic 49b11c1e72Sjeremylt **/ 50d7b241e6Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize, 51d7b241e6Sjeremylt CeedInt ndof, CeedInt ncomp, CeedMemType mtype, 52d7b241e6Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 534ce2993fSjeremylt CeedElemRestriction *rstr) { 54d7b241e6Sjeremylt int ierr; 55d7b241e6Sjeremylt 565fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 575fe0d4faSjeremylt Ceed delegate; 58aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 59aefd8378Sjeremylt CeedChk(ierr); 605fe0d4faSjeremylt 615fe0d4faSjeremylt if (!delegate) 62d7b241e6Sjeremylt return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 635fe0d4faSjeremylt 645fe0d4faSjeremylt ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, 655fe0d4faSjeremylt ndof, ncomp, mtype, cmode, 664ce2993fSjeremylt indices, rstr); CeedChk(ierr); 675fe0d4faSjeremylt return 0; 685fe0d4faSjeremylt } 695fe0d4faSjeremylt 704ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 714ce2993fSjeremylt (*rstr)->ceed = ceed; 72d7b241e6Sjeremylt ceed->refcount++; 734ce2993fSjeremylt (*rstr)->refcount = 1; 744ce2993fSjeremylt (*rstr)->nelem = nelem; 754ce2993fSjeremylt (*rstr)->elemsize = elemsize; 764ce2993fSjeremylt (*rstr)->ndof = ndof; 774ce2993fSjeremylt (*rstr)->ncomp = ncomp; 784ce2993fSjeremylt (*rstr)->nblk = nelem; 794ce2993fSjeremylt (*rstr)->blksize = 1; 804ce2993fSjeremylt ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr); 81d7b241e6Sjeremylt return 0; 82d7b241e6Sjeremylt } 83d7b241e6Sjeremylt 84d7b241e6Sjeremylt /** 85b11c1e72Sjeremylt @brief Create an identity CeedElemRestriction 86d7b241e6Sjeremylt 87b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 88b11c1e72Sjeremylt @param nelem Number of elements described in the @a indices array 89b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 90d7b241e6Sjeremylt @param ndof The total size of the input CeedVector to which the 91d7b241e6Sjeremylt restriction will be applied. This size may include data 92d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 93b11c1e72Sjeremylt different types of elements 94b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 954ce2993fSjeremylt @param rstr Address of the variable where the newly created 96b11c1e72Sjeremylt CeedElemRestriction will be stored 97d7b241e6Sjeremylt 98b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 99dfdf5a53Sjeremylt 100dfdf5a53Sjeremylt @ref Basic 101b11c1e72Sjeremylt **/ 1024b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem, 1034b8bea3bSJed Brown CeedInt elemsize, 1044ce2993fSjeremylt CeedInt ndof, CeedInt ncomp, CeedElemRestriction *rstr) { 105d7b241e6Sjeremylt int ierr; 106d7b241e6Sjeremylt 1075fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 1085fe0d4faSjeremylt Ceed delegate; 109aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 110aefd8378Sjeremylt CeedChk(ierr); 1115fe0d4faSjeremylt 1125fe0d4faSjeremylt if (!delegate) 1134b8bea3bSJed Brown return CeedError(ceed, 1, 1145fe0d4faSjeremylt "Backend does not support ElemRestrictionCreate"); 1155fe0d4faSjeremylt 1165fe0d4faSjeremylt ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize, 1174ce2993fSjeremylt ndof, ncomp, rstr); CeedChk(ierr); 1185fe0d4faSjeremylt return 0; 1195fe0d4faSjeremylt } 1205fe0d4faSjeremylt 1214ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 1224ce2993fSjeremylt (*rstr)->ceed = ceed; 123d7b241e6Sjeremylt ceed->refcount++; 1244ce2993fSjeremylt (*rstr)->refcount = 1; 1254ce2993fSjeremylt (*rstr)->nelem = nelem; 1264ce2993fSjeremylt (*rstr)->elemsize = elemsize; 1274ce2993fSjeremylt (*rstr)->ndof = ndof; 1284ce2993fSjeremylt (*rstr)->ncomp = ncomp; 1294ce2993fSjeremylt (*rstr)->nblk = nelem; 1304ce2993fSjeremylt (*rstr)->blksize = 1; 1311dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 1321dfeef1dSjeremylt *rstr); 1334b8bea3bSJed Brown CeedChk(ierr); 134d7b241e6Sjeremylt return 0; 135d7b241e6Sjeremylt } 136d7b241e6Sjeremylt 137d7b241e6Sjeremylt /** 138b11c1e72Sjeremylt @brief Permute and pad indices for a blocked restriction 139d7b241e6Sjeremylt 140ecf6354eSJed Brown @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list 141d7b241e6Sjeremylt of the indices (into the input CeedVector) for the unknowns 142d7b241e6Sjeremylt corresponding to element i, where 0 <= i < @a nelements. 143d7b241e6Sjeremylt All indices must be in the range [0, @a ndof). 144ecf6354eSJed Brown @param blkindices Array of permuted and padded indices of 145ecf6354eSJed Brown shape [@a nblk, @a elemsize, @a blksize]. 146d7b241e6Sjeremylt @param nblk Number of blocks 147d7b241e6Sjeremylt @param nelem Number of elements 148d7b241e6Sjeremylt @param blksize Number of elements in a block 149d7b241e6Sjeremylt @param elemsize Size of each element 150d7b241e6Sjeremylt 151b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 152b11c1e72Sjeremylt 153dfdf5a53Sjeremylt @ref Utility 154b11c1e72Sjeremylt **/ 155dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices, 156d7b241e6Sjeremylt CeedInt nblk, CeedInt nelem, 157d7b241e6Sjeremylt CeedInt blksize, CeedInt elemsize) { 158d7b241e6Sjeremylt for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 159d7b241e6Sjeremylt for (int j = 0; j < blksize; j++) 160d7b241e6Sjeremylt for (int k = 0; k < elemsize; k++) 161d7b241e6Sjeremylt blkindices[e*elemsize + k*blksize + j] 162d7b241e6Sjeremylt = indices[CeedIntMin(e+j,nelem-1)*elemsize + k]; 163dfdf5a53Sjeremylt return 0; 164d7b241e6Sjeremylt } 165d7b241e6Sjeremylt 166d7b241e6Sjeremylt /** 167b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 168d7b241e6Sjeremylt 169d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 170d7b241e6Sjeremylt @param nelem Number of elements described in the @a indices array. 171b11c1e72Sjeremylt @param elemsize Size (number of unknowns) per element 172b11c1e72Sjeremylt @param blksize Number of elements in a block 173d7b241e6Sjeremylt @param ndof The total size of the input CeedVector to which the 174d7b241e6Sjeremylt restriction will be applied. This size may include data 175d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 176d7b241e6Sjeremylt different types of elements. 177b11c1e72Sjeremylt @param ncomp Number of components stored at each node 178b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 179b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 180ecf6354eSJed Brown @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the ordered list 181d7b241e6Sjeremylt of the indices (into the input CeedVector) for the unknowns 182d7b241e6Sjeremylt corresponding to element i, where 0 <= i < @a nelements. 183d7b241e6Sjeremylt All indices must be in the range [0, @a ndof). The 184d7b241e6Sjeremylt backend will permute and pad this array to the desired 185d7b241e6Sjeremylt ordering for the blocksize, which is typically given by the 186d7b241e6Sjeremylt backend. The default reordering is to interlace elements. 1874ce2993fSjeremylt @param rstr Address of the variable where the newly created 188b11c1e72Sjeremylt CeedElemRestriction will be stored 189d7b241e6Sjeremylt 190b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 191dfdf5a53Sjeremylt 192dfdf5a53Sjeremylt @ref Advanced 193b11c1e72Sjeremylt **/ 194d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize, 195d7b241e6Sjeremylt CeedInt blksize, CeedInt ndof, CeedInt ncomp, 196d7b241e6Sjeremylt CeedMemType mtype, CeedCopyMode cmode, 1974ce2993fSjeremylt const CeedInt *indices, 1984ce2993fSjeremylt CeedElemRestriction *rstr) { 199d7b241e6Sjeremylt int ierr; 200d7b241e6Sjeremylt CeedInt *blkindices; 201d7b241e6Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 202d7b241e6Sjeremylt 2035fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 2045fe0d4faSjeremylt Ceed delegate; 205aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 206aefd8378Sjeremylt CeedChk(ierr); 2075fe0d4faSjeremylt 2085fe0d4faSjeremylt if (!delegate) 209d7b241e6Sjeremylt return CeedError(ceed, 1, 210d7b241e6Sjeremylt "Backend does not support ElemRestrictionCreateBlocked"); 2115fe0d4faSjeremylt 2125fe0d4faSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, 2135fe0d4faSjeremylt blksize, ndof, ncomp, mtype, cmode, 2144ce2993fSjeremylt indices, rstr); CeedChk(ierr); 2155fe0d4faSjeremylt return 0; 2165fe0d4faSjeremylt } 217d7b241e6Sjeremylt 2184ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 219d7b241e6Sjeremylt 220d7b241e6Sjeremylt if (indices) { 221de686571SJeremy L Thompson ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 2224b8bea3bSJed Brown ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 2234b8bea3bSJed Brown elemsize); 224dfdf5a53Sjeremylt CeedChk(ierr); 225d7b241e6Sjeremylt } else { 226d7b241e6Sjeremylt blkindices = NULL; 227d7b241e6Sjeremylt } 228d7b241e6Sjeremylt 2294ce2993fSjeremylt (*rstr)->ceed = ceed; 230d7b241e6Sjeremylt ceed->refcount++; 2314ce2993fSjeremylt (*rstr)->refcount = 1; 2324ce2993fSjeremylt (*rstr)->nelem = nelem; 2334ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2344ce2993fSjeremylt (*rstr)->ndof = ndof; 2354ce2993fSjeremylt (*rstr)->ncomp = ncomp; 2364ce2993fSjeremylt (*rstr)->nblk = nblk; 2374ce2993fSjeremylt (*rstr)->blksize = blksize; 238667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 2394ce2993fSjeremylt (const CeedInt *) blkindices, *rstr); 240d7b241e6Sjeremylt CeedChk(ierr); 241d7b241e6Sjeremylt 242d7b241e6Sjeremylt if (cmode == CEED_OWN_POINTER) 243d7b241e6Sjeremylt ierr = CeedFree(&indices); CeedChk(ierr); 244d7b241e6Sjeremylt 245d7b241e6Sjeremylt return 0; 246d7b241e6Sjeremylt } 247d7b241e6Sjeremylt 248b11c1e72Sjeremylt /** 249b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 250b11c1e72Sjeremylt 2514ce2993fSjeremylt @param rstr CeedElemRestriction 252b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 253b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 254b11c1e72Sjeremylt 255b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 256dfdf5a53Sjeremylt 257dfdf5a53Sjeremylt @ref Advanced 258b11c1e72Sjeremylt **/ 2594ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 260d7b241e6Sjeremylt CeedVector *evec) { 261d7b241e6Sjeremylt int ierr; 262d7b241e6Sjeremylt CeedInt n, m; 2634ce2993fSjeremylt m = rstr->ndof * rstr->ncomp; 2644ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 265d7b241e6Sjeremylt if (lvec) { 2664ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 267d7b241e6Sjeremylt } 268d7b241e6Sjeremylt if (evec) { 2694ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 270d7b241e6Sjeremylt } 271d7b241e6Sjeremylt return 0; 272d7b241e6Sjeremylt } 273d7b241e6Sjeremylt 274d7b241e6Sjeremylt /** 275b11c1e72Sjeremylt @brief Restrict an L-vector to an E-vector or apply transpose 276d7b241e6Sjeremylt 2774ce2993fSjeremylt @param rstr CeedElemRestriction 278d7b241e6Sjeremylt @param tmode Apply restriction or transpose 279d7b241e6Sjeremylt @param lmode Ordering of the ncomp components 280d7b241e6Sjeremylt @param u Input vector (of size @a ndof when tmode=CEED_NOTRANSPOSE) 281d7b241e6Sjeremylt @param v Output vector (of size @a nelem * @a elemsize when tmode=CEED_NOTRANSPOSE) 282d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 283b11c1e72Sjeremylt 284b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 285dfdf5a53Sjeremylt 286dfdf5a53Sjeremylt @ref Advanced 287b11c1e72Sjeremylt **/ 2884ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 289d7b241e6Sjeremylt CeedTransposeMode lmode, 290d7b241e6Sjeremylt CeedVector u, CeedVector v, CeedRequest *request) { 291d7b241e6Sjeremylt CeedInt m,n; 292d7b241e6Sjeremylt int ierr; 293d7b241e6Sjeremylt 294d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 2954ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 2964ce2993fSjeremylt n = rstr->ndof * rstr->ncomp; 297d7b241e6Sjeremylt } else { 2984ce2993fSjeremylt m = rstr->ndof * rstr->ncomp; 2994ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 300d7b241e6Sjeremylt } 301d7b241e6Sjeremylt if (n != u->length) 3024ce2993fSjeremylt return CeedError(rstr->ceed, 2, 303d7b241e6Sjeremylt "Input vector size %d not compatible with element restriction (%d, %d)", 304d7b241e6Sjeremylt u->length, m, n); 305d7b241e6Sjeremylt if (m != v->length) 3064ce2993fSjeremylt return CeedError(rstr->ceed, 2, 307d7b241e6Sjeremylt "Output vector size %d not compatible with element restriction (%d, %d)", 308d7b241e6Sjeremylt v->length, m, n); 3094ce2993fSjeremylt ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr); 310d7b241e6Sjeremylt 311d7b241e6Sjeremylt return 0; 312d7b241e6Sjeremylt } 313d7b241e6Sjeremylt 314d7b241e6Sjeremylt /** 315be9261b7Sjeremylt @brief Restrict an L-vector to a block of an E-vector or apply transpose 316be9261b7Sjeremylt 317be9261b7Sjeremylt @param rstr CeedElemRestriction 3181f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 3191f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 3201f37b403Sjeremylt [3*blksize : 4*blksize] 321be9261b7Sjeremylt @param tmode Apply restriction or transpose 322be9261b7Sjeremylt @param lmode Ordering of the ncomp components 323be9261b7Sjeremylt @param u Input vector (of size @a ndof when tmode=CEED_NOTRANSPOSE) 324be9261b7Sjeremylt @param v Output vector (of size @a nelem * @a elemsize when tmode=CEED_NOTRANSPOSE) 325be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 326be9261b7Sjeremylt 327be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 328be9261b7Sjeremylt 329be9261b7Sjeremylt @ref Advanced 330be9261b7Sjeremylt **/ 331be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 332be9261b7Sjeremylt CeedTransposeMode tmode, 333be9261b7Sjeremylt CeedTransposeMode lmode, 334be9261b7Sjeremylt CeedVector u, CeedVector v, 335be9261b7Sjeremylt CeedRequest *request) { 336be9261b7Sjeremylt CeedInt m,n; 337be9261b7Sjeremylt int ierr; 338be9261b7Sjeremylt 339be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 340be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 341be9261b7Sjeremylt n = rstr->ndof * rstr->ncomp; 342be9261b7Sjeremylt } else { 343be9261b7Sjeremylt m = rstr->ndof * rstr->ncomp; 344be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 345be9261b7Sjeremylt } 346be9261b7Sjeremylt if (n != u->length) 347be9261b7Sjeremylt return CeedError(rstr->ceed, 2, 348be9261b7Sjeremylt "Input vector size %d not compatible with element restriction (%d, %d)", 349be9261b7Sjeremylt u->length, m, n); 350be9261b7Sjeremylt if (m != v->length) 351be9261b7Sjeremylt return CeedError(rstr->ceed, 2, 352be9261b7Sjeremylt "Output vector size %d not compatible with element restriction (%d, %d)", 353be9261b7Sjeremylt v->length, m, n); 354be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 355be9261b7Sjeremylt return CeedError(rstr->ceed, 2, 356be9261b7Sjeremylt "Cannot retrieve block %d, element %d > total elements %d", 357be9261b7Sjeremylt block, rstr->blksize*block, rstr->nelem); 358be9261b7Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request); 359be9261b7Sjeremylt CeedChk(ierr); 360be9261b7Sjeremylt 361be9261b7Sjeremylt return 0; 362be9261b7Sjeremylt } 363be9261b7Sjeremylt 364be9261b7Sjeremylt /** 365*1469ee4dSjeremylt @brief Get the multiplicity of DoFs in a CeedElemRestriction 366*1469ee4dSjeremylt 367*1469ee4dSjeremylt @param rstr CeedElemRestriction 368*1469ee4dSjeremylt @param[out] mult Vector to store multiplicity (of size ndof) 369*1469ee4dSjeremylt 370*1469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 371*1469ee4dSjeremylt 372*1469ee4dSjeremylt @ref Advanced 373*1469ee4dSjeremylt **/ 374*1469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 375*1469ee4dSjeremylt CeedVector mult) { 376*1469ee4dSjeremylt int ierr; 377*1469ee4dSjeremylt CeedVector evec; 378*1469ee4dSjeremylt 379*1469ee4dSjeremylt // Create and set evec 380*1469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 381*1469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 382*1469ee4dSjeremylt 383*1469ee4dSjeremylt // Apply to get multiplicity 384*1469ee4dSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, CEED_NOTRANSPOSE, evec, 385*1469ee4dSjeremylt mult, CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 386*1469ee4dSjeremylt 387*1469ee4dSjeremylt // Cleanup 388*1469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 389*1469ee4dSjeremylt 390*1469ee4dSjeremylt return 0; 391*1469ee4dSjeremylt } 392*1469ee4dSjeremylt 393*1469ee4dSjeremylt /** 3944ce2993fSjeremylt @brief Get the Ceed associated with a CeedElemRestriction 3954ce2993fSjeremylt 3964ce2993fSjeremylt @param rstr CeedElemRestriction 3974ce2993fSjeremylt @param[out] ceed Variable to store Ceed 3984ce2993fSjeremylt 3994ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4004ce2993fSjeremylt 40123617272Sjeremylt @ref Advanced 4024ce2993fSjeremylt **/ 4034ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 4044ce2993fSjeremylt *ceed = rstr->ceed; 4054ce2993fSjeremylt return 0; 4064ce2993fSjeremylt } 4074ce2993fSjeremylt 4084ce2993fSjeremylt /** 409b11c1e72Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 410d7b241e6Sjeremylt 4114ce2993fSjeremylt @param rstr CeedElemRestriction 4124ce2993fSjeremylt @param[out] numelements Variable to store number of elements 413b11c1e72Sjeremylt 414b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 415dfdf5a53Sjeremylt 41623617272Sjeremylt @ref Advanced 417b11c1e72Sjeremylt **/ 4184ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 4194ce2993fSjeremylt CeedInt *numelem) { 4204ce2993fSjeremylt *numelem = rstr->nelem; 4214ce2993fSjeremylt return 0; 4224ce2993fSjeremylt } 4234ce2993fSjeremylt 4244ce2993fSjeremylt /** 4254ce2993fSjeremylt @brief Get the size of elements in the CeedElemRestriction 4264ce2993fSjeremylt 4274ce2993fSjeremylt @param rstr CeedElemRestriction 4284ce2993fSjeremylt @param[out] elemsize Variable to store size of elements 4294ce2993fSjeremylt 4304ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4314ce2993fSjeremylt 43223617272Sjeremylt @ref Advanced 4334ce2993fSjeremylt **/ 4344ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 4354ce2993fSjeremylt CeedInt *elemsize) { 4364ce2993fSjeremylt *elemsize = rstr->elemsize; 4374ce2993fSjeremylt return 0; 4384ce2993fSjeremylt } 4394ce2993fSjeremylt 4404ce2993fSjeremylt /** 4414ce2993fSjeremylt @brief Get the number of degrees of freedom in the range of a 4424ce2993fSjeremylt CeedElemRestriction 4434ce2993fSjeremylt 4444ce2993fSjeremylt @param rstr CeedElemRestriction 4454ce2993fSjeremylt @param[out] numdof Variable to store number of DoFs 4464ce2993fSjeremylt 4474ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4484ce2993fSjeremylt 44923617272Sjeremylt @ref Advanced 4504ce2993fSjeremylt **/ 4514ce2993fSjeremylt int CeedElemRestrictionGetNumDoF(CeedElemRestriction rstr, 4524ce2993fSjeremylt CeedInt *numdof) { 4534ce2993fSjeremylt *numdof = rstr->ndof; 4544ce2993fSjeremylt return 0; 4554ce2993fSjeremylt } 4564ce2993fSjeremylt 4574ce2993fSjeremylt /** 4584ce2993fSjeremylt @brief Get the number of components in the elements of a 4594ce2993fSjeremylt CeedElemRestriction 4604ce2993fSjeremylt 4614ce2993fSjeremylt @param rstr CeedElemRestriction 4624ce2993fSjeremylt @param[out] numcomp Variable to store number of components 4634ce2993fSjeremylt 4644ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4654ce2993fSjeremylt 46623617272Sjeremylt @ref Advanced 4674ce2993fSjeremylt **/ 4684ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 4694ce2993fSjeremylt CeedInt *numcomp) { 4704ce2993fSjeremylt *numcomp = rstr->ncomp; 4714ce2993fSjeremylt return 0; 4724ce2993fSjeremylt } 4734ce2993fSjeremylt 4744ce2993fSjeremylt /** 4754ce2993fSjeremylt @brief Get the number of blocks in a CeedElemRestriction 4764ce2993fSjeremylt 4774ce2993fSjeremylt @param rstr CeedElemRestriction 4784ce2993fSjeremylt @param[out] numblock Variable to store number of blocks 4794ce2993fSjeremylt 4804ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4814ce2993fSjeremylt 48223617272Sjeremylt @ref Advanced 4834ce2993fSjeremylt **/ 4844ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 4854ce2993fSjeremylt CeedInt *numblock) { 4864ce2993fSjeremylt *numblock = rstr->nblk; 4874ce2993fSjeremylt return 0; 4884ce2993fSjeremylt } 4894ce2993fSjeremylt 4904ce2993fSjeremylt /** 4914ce2993fSjeremylt @brief Get the size of blocks in the CeedElemRestriction 4924ce2993fSjeremylt 4934ce2993fSjeremylt @param r CeedElemRestriction 4944ce2993fSjeremylt @param[out] blksize Variable to store size of blocks 4954ce2993fSjeremylt 4964ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4974ce2993fSjeremylt 49823617272Sjeremylt @ref Advanced 4994ce2993fSjeremylt **/ 5004ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 5014ce2993fSjeremylt CeedInt *blksize) { 5024ce2993fSjeremylt *blksize = rstr->blksize; 5034ce2993fSjeremylt return 0; 5044ce2993fSjeremylt } 5054ce2993fSjeremylt 5064ce2993fSjeremylt /** 5074ce2993fSjeremylt @brief Get the backend data of a CeedElemRestriction 5084ce2993fSjeremylt 5094ce2993fSjeremylt @param r CeedElemRestriction 5104ce2993fSjeremylt @param[out] data Variable to store data 5114ce2993fSjeremylt 5124ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5134ce2993fSjeremylt 51423617272Sjeremylt @ref Advanced 5154ce2993fSjeremylt **/ 5164ce2993fSjeremylt int CeedElemRestrictionGetData(CeedElemRestriction rstr, 5174ce2993fSjeremylt void* *data) { 5184ce2993fSjeremylt *data = rstr->data; 519d7b241e6Sjeremylt return 0; 520d7b241e6Sjeremylt } 521d7b241e6Sjeremylt 522d7b241e6Sjeremylt /** 523fe2413ffSjeremylt @brief Set the backend data of a CeedElemRestriction 524fe2413ffSjeremylt 525fe2413ffSjeremylt @param[out] r CeedElemRestriction 526fe2413ffSjeremylt @param data Data to set 527fe2413ffSjeremylt 528fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 529fe2413ffSjeremylt 530fe2413ffSjeremylt @ref Advanced 531fe2413ffSjeremylt **/ 532fe2413ffSjeremylt int CeedElemRestrictionSetData(CeedElemRestriction rstr, 533fe2413ffSjeremylt void* *data) { 534fe2413ffSjeremylt rstr->data = *data; 535fe2413ffSjeremylt return 0; 536fe2413ffSjeremylt } 537fe2413ffSjeremylt 538fe2413ffSjeremylt /** 539b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 540b11c1e72Sjeremylt 5414ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 542b11c1e72Sjeremylt 543b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 544dfdf5a53Sjeremylt 545dfdf5a53Sjeremylt @ref Basic 546b11c1e72Sjeremylt **/ 5474ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 548d7b241e6Sjeremylt int ierr; 549d7b241e6Sjeremylt 5504ce2993fSjeremylt if (!*rstr || --(*rstr)->refcount > 0) return 0; 5514ce2993fSjeremylt if ((*rstr)->Destroy) { 5524ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 553d7b241e6Sjeremylt } 5544ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 5554ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 556d7b241e6Sjeremylt return 0; 557d7b241e6Sjeremylt } 558d7b241e6Sjeremylt 559d7b241e6Sjeremylt /// @} 560