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