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 38b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 39b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 408795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 418795c945Sjeremylt ordered list of the indices (into the input CeedVector) 428795c945Sjeremylt for the unknowns corresponding to element i, where 438795c945Sjeremylt 0 <= i < @a nelements. All indices must be in the range 4423e8ed12Sjeremylt [0, @a nnodes - 1]. 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, 538795c945Sjeremylt 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) 64c042f62fSJeremy L Thompson // LCOV_EXCL_START 65d7b241e6Sjeremylt return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 66c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 675fe0d4faSjeremylt 685fe0d4faSjeremylt ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, 698795c945Sjeremylt nnodes, ncomp, mtype, cmode, 704ce2993fSjeremylt indices, rstr); CeedChk(ierr); 715fe0d4faSjeremylt return 0; 725fe0d4faSjeremylt } 735fe0d4faSjeremylt 744ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 754ce2993fSjeremylt (*rstr)->ceed = ceed; 76d7b241e6Sjeremylt ceed->refcount++; 774ce2993fSjeremylt (*rstr)->refcount = 1; 784ce2993fSjeremylt (*rstr)->nelem = nelem; 794ce2993fSjeremylt (*rstr)->elemsize = elemsize; 808795c945Sjeremylt (*rstr)->nnodes = nnodes; 814ce2993fSjeremylt (*rstr)->ncomp = ncomp; 824ce2993fSjeremylt (*rstr)->nblk = nelem; 834ce2993fSjeremylt (*rstr)->blksize = 1; 844ce2993fSjeremylt ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr); 85d7b241e6Sjeremylt return 0; 86d7b241e6Sjeremylt } 87d7b241e6Sjeremylt 88d7b241e6Sjeremylt /** 89b11c1e72Sjeremylt @brief Create an identity CeedElemRestriction 90d7b241e6Sjeremylt 91b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 92b11c1e72Sjeremylt @param nelem Number of elements described in the @a indices array 93b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 948795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 958795c945Sjeremylt to which the restriction will be applied is of size 968795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 97d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 988795c945Sjeremylt different types of elements. 99b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 1004ce2993fSjeremylt @param rstr Address of the variable where the newly created 101b11c1e72Sjeremylt CeedElemRestriction will be stored 102d7b241e6Sjeremylt 103b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 104dfdf5a53Sjeremylt 105dfdf5a53Sjeremylt @ref Basic 106b11c1e72Sjeremylt **/ 1074b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem, 108f90c8643Sjeremylt CeedInt elemsize, CeedInt nnodes, 109f90c8643Sjeremylt CeedInt ncomp, 110f90c8643Sjeremylt CeedElemRestriction *rstr) { 111d7b241e6Sjeremylt int ierr; 112d7b241e6Sjeremylt 1135fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 1145fe0d4faSjeremylt Ceed delegate; 115aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 116aefd8378Sjeremylt CeedChk(ierr); 1175fe0d4faSjeremylt 1185fe0d4faSjeremylt if (!delegate) 119c042f62fSJeremy L Thompson // LCOV_EXCL_START 1201d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 121c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1225fe0d4faSjeremylt 1235fe0d4faSjeremylt ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize, 1248795c945Sjeremylt nnodes, ncomp, rstr); CeedChk(ierr); 1255fe0d4faSjeremylt return 0; 1265fe0d4faSjeremylt } 1275fe0d4faSjeremylt 1284ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 1294ce2993fSjeremylt (*rstr)->ceed = ceed; 130d7b241e6Sjeremylt ceed->refcount++; 1314ce2993fSjeremylt (*rstr)->refcount = 1; 1324ce2993fSjeremylt (*rstr)->nelem = nelem; 1334ce2993fSjeremylt (*rstr)->elemsize = elemsize; 1348795c945Sjeremylt (*rstr)->nnodes = nnodes; 1354ce2993fSjeremylt (*rstr)->ncomp = ncomp; 1364ce2993fSjeremylt (*rstr)->nblk = nelem; 1374ce2993fSjeremylt (*rstr)->blksize = 1; 1381dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 1391dfeef1dSjeremylt *rstr); 1404b8bea3bSJed Brown CeedChk(ierr); 141d7b241e6Sjeremylt return 0; 142d7b241e6Sjeremylt } 143d7b241e6Sjeremylt 144d7b241e6Sjeremylt /** 145b11c1e72Sjeremylt @brief Permute and pad indices for a blocked restriction 146d7b241e6Sjeremylt 1478795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1488795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1498795c945Sjeremylt for the unknowns corresponding to element i, where 1508795c945Sjeremylt 0 <= i < @a nelements. All indices must be in the range 1518795c945Sjeremylt [0, @a nnodes). 152ecf6354eSJed Brown @param blkindices Array of permuted and padded indices of 153ecf6354eSJed Brown shape [@a nblk, @a elemsize, @a blksize]. 154d7b241e6Sjeremylt @param nblk Number of blocks 155d7b241e6Sjeremylt @param nelem Number of elements 156d7b241e6Sjeremylt @param blksize Number of elements in a block 157d7b241e6Sjeremylt @param elemsize Size of each element 158d7b241e6Sjeremylt 159b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 160b11c1e72Sjeremylt 161dfdf5a53Sjeremylt @ref Utility 162b11c1e72Sjeremylt **/ 163dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices, 164*692c2638Sjeremylt CeedInt nblk, CeedInt nelem, CeedInt blksize, 165*692c2638Sjeremylt CeedInt elemsize) { 166d7b241e6Sjeremylt for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 167d7b241e6Sjeremylt for (int j = 0; j < blksize; j++) 168d7b241e6Sjeremylt for (int k = 0; k < elemsize; k++) 169d7b241e6Sjeremylt blkindices[e*elemsize + k*blksize + j] 170d7b241e6Sjeremylt = indices[CeedIntMin(e+j,nelem-1)*elemsize + k]; 171dfdf5a53Sjeremylt return 0; 172d7b241e6Sjeremylt } 173d7b241e6Sjeremylt 174d7b241e6Sjeremylt /** 175b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 176d7b241e6Sjeremylt 177d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 178d7b241e6Sjeremylt @param nelem Number of elements described in the @a indices array. 179b11c1e72Sjeremylt @param elemsize Size (number of unknowns) per element 180b11c1e72Sjeremylt @param blksize Number of elements in a block 1818795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 1828795c945Sjeremylt to which the restriction will be applied is of size 1838795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 184d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 185d7b241e6Sjeremylt different types of elements. 186b11c1e72Sjeremylt @param ncomp Number of components stored at each node 187b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 188b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 1898795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1908795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1918795c945Sjeremylt for the unknowns corresponding to element i, where 1928795c945Sjeremylt 0 <= i < @a nelements. All indices must be in the range 1938795c945Sjeremylt [0, @a nnodes). The backend will permute and pad this 1948795c945Sjeremylt array to the desired ordering for the blocksize, which is 1958795c945Sjeremylt typically given by the backend. The default reordering is 1968795c945Sjeremylt to interlace elements. 1974ce2993fSjeremylt @param rstr Address of the variable where the newly created 198b11c1e72Sjeremylt CeedElemRestriction will be stored 199d7b241e6Sjeremylt 200b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 201dfdf5a53Sjeremylt 202dfdf5a53Sjeremylt @ref Advanced 203b11c1e72Sjeremylt **/ 204d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize, 2058795c945Sjeremylt CeedInt blksize, CeedInt nnodes, 2068795c945Sjeremylt CeedInt ncomp, CeedMemType mtype, 2078795c945Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 2084ce2993fSjeremylt CeedElemRestriction *rstr) { 209d7b241e6Sjeremylt int ierr; 210d7b241e6Sjeremylt CeedInt *blkindices; 211d7b241e6Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 212d7b241e6Sjeremylt 2135fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 2145fe0d4faSjeremylt Ceed delegate; 215aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 216aefd8378Sjeremylt CeedChk(ierr); 2175fe0d4faSjeremylt 2185fe0d4faSjeremylt if (!delegate) 219c042f62fSJeremy L Thompson // LCOV_EXCL_START 2201d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 2211d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 222c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 2235fe0d4faSjeremylt 2245fe0d4faSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, 2258795c945Sjeremylt blksize, nnodes, ncomp, mtype, cmode, 2264ce2993fSjeremylt indices, rstr); CeedChk(ierr); 2275fe0d4faSjeremylt return 0; 2285fe0d4faSjeremylt } 229d7b241e6Sjeremylt 2304ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 231d7b241e6Sjeremylt 232d7b241e6Sjeremylt if (indices) { 233de686571SJeremy L Thompson ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 2344b8bea3bSJed Brown ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 2354b8bea3bSJed Brown elemsize); 236dfdf5a53Sjeremylt CeedChk(ierr); 237d7b241e6Sjeremylt } else { 238d7b241e6Sjeremylt blkindices = NULL; 239d7b241e6Sjeremylt } 240d7b241e6Sjeremylt 2414ce2993fSjeremylt (*rstr)->ceed = ceed; 242d7b241e6Sjeremylt ceed->refcount++; 2434ce2993fSjeremylt (*rstr)->refcount = 1; 2444ce2993fSjeremylt (*rstr)->nelem = nelem; 2454ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2468795c945Sjeremylt (*rstr)->nnodes = nnodes; 2474ce2993fSjeremylt (*rstr)->ncomp = ncomp; 2484ce2993fSjeremylt (*rstr)->nblk = nblk; 2494ce2993fSjeremylt (*rstr)->blksize = blksize; 250667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 2517f823360Sjeremylt (const CeedInt *) blkindices, *rstr); CeedChk(ierr); 252d7b241e6Sjeremylt 2531d102b48SJeremy L Thompson if (cmode == CEED_OWN_POINTER) { 254d7b241e6Sjeremylt ierr = CeedFree(&indices); CeedChk(ierr); 2551d102b48SJeremy L Thompson } 256d7b241e6Sjeremylt 257d7b241e6Sjeremylt return 0; 258d7b241e6Sjeremylt } 259d7b241e6Sjeremylt 260b11c1e72Sjeremylt /** 261b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 262b11c1e72Sjeremylt 2634ce2993fSjeremylt @param rstr CeedElemRestriction 264b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 265b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 266b11c1e72Sjeremylt 267b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 268dfdf5a53Sjeremylt 269dfdf5a53Sjeremylt @ref Advanced 270b11c1e72Sjeremylt **/ 2714ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 272d7b241e6Sjeremylt CeedVector *evec) { 273d7b241e6Sjeremylt int ierr; 274d7b241e6Sjeremylt CeedInt n, m; 2758795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 2764ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 277d7b241e6Sjeremylt if (lvec) { 2784ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 279d7b241e6Sjeremylt } 280d7b241e6Sjeremylt if (evec) { 2814ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 282d7b241e6Sjeremylt } 283d7b241e6Sjeremylt return 0; 284d7b241e6Sjeremylt } 285d7b241e6Sjeremylt 286d7b241e6Sjeremylt /** 287d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 288d7b241e6Sjeremylt 2894ce2993fSjeremylt @param rstr CeedElemRestriction 290d7b241e6Sjeremylt @param tmode Apply restriction or transpose 291d9e1f99aSValeria Barra @param lmode Ordering of the ncomp components, i.e. it specifies 292d9e1f99aSValeria Barra the ordering of the components of the l-vector used 293d9e1f99aSValeria Barra by this CeedElemRestriction. CEED_NOTRANSPOSE indicates 294d9e1f99aSValeria Barra the component is the outermost index and CEED_TRANSPOSE 295d9e1f99aSValeria Barra indicates the component is the innermost index in 296d9e1f99aSValeria Barra ordering of the l-vector 2978795c945Sjeremylt @param u Input vector (of size @a nnodes * @a ncomp when 2988795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 2998795c945Sjeremylt @param v Output vector (of size @a nelem * @a elemsize when 3008795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 301d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 302b11c1e72Sjeremylt 303b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 304dfdf5a53Sjeremylt 305dfdf5a53Sjeremylt @ref Advanced 306b11c1e72Sjeremylt **/ 3074ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 308*692c2638Sjeremylt CeedTransposeMode lmode, CeedVector u, 309*692c2638Sjeremylt CeedVector v, CeedRequest *request) { 310d7b241e6Sjeremylt CeedInt m,n; 311d7b241e6Sjeremylt int ierr; 312d7b241e6Sjeremylt 313d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 3144ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 3158795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 316d7b241e6Sjeremylt } else { 3178795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3184ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 319d7b241e6Sjeremylt } 320d7b241e6Sjeremylt if (n != u->length) 321c042f62fSJeremy L Thompson // LCOV_EXCL_START 3221d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3231d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 324c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 325d7b241e6Sjeremylt if (m != v->length) 326c042f62fSJeremy L Thompson // LCOV_EXCL_START 3271d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 3281d102b48SJeremy L Thompson "element restriction (%d, %d)", v->length, m, n); 329c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3304ce2993fSjeremylt ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr); 331d7b241e6Sjeremylt 332d7b241e6Sjeremylt return 0; 333d7b241e6Sjeremylt } 334d7b241e6Sjeremylt 335d7b241e6Sjeremylt /** 336d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 337be9261b7Sjeremylt 338be9261b7Sjeremylt @param rstr CeedElemRestriction 3391f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 3401f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 3411f37b403Sjeremylt [3*blksize : 4*blksize] 342be9261b7Sjeremylt @param tmode Apply restriction or transpose 343d9e1f99aSValeria Barra @param lmode Ordering of the ncomp components, i.e. it specifies 344d9e1f99aSValeria Barra the ordering of the components of the l-vector used 345d9e1f99aSValeria Barra by this CeedElemRestriction. CEED_NOTRANSPOSE indicates 346d9e1f99aSValeria Barra the component is the outermost index and CEED_TRANSPOSE 347d9e1f99aSValeria Barra indicates the component is the innermost index in 348d9e1f99aSValeria Barra ordering of the l-vector 3498795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 3508795c945Sjeremylt @param v Output vector (of size @a nelem * @a elemsize when 3518795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 352be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 353be9261b7Sjeremylt 354be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 355be9261b7Sjeremylt 356be9261b7Sjeremylt @ref Advanced 357be9261b7Sjeremylt **/ 358be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 359be9261b7Sjeremylt CeedTransposeMode tmode, 360*692c2638Sjeremylt CeedTransposeMode lmode, CeedVector u, 361*692c2638Sjeremylt CeedVector v, CeedRequest *request) { 362be9261b7Sjeremylt CeedInt m,n; 363be9261b7Sjeremylt int ierr; 364be9261b7Sjeremylt 365be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 366be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 3678795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 368be9261b7Sjeremylt } else { 3698795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 370be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 371be9261b7Sjeremylt } 372be9261b7Sjeremylt if (n != u->length) 373c042f62fSJeremy L Thompson // LCOV_EXCL_START 3741d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3751d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 376c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 377be9261b7Sjeremylt if (m != v->length) 378c042f62fSJeremy L Thompson // LCOV_EXCL_START 3791d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 3801d102b48SJeremy L Thompson "element restriction (%d, %d)", v->length, m, n); 381c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 382be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 383c042f62fSJeremy L Thompson // LCOV_EXCL_START 3841d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 3851d102b48SJeremy L Thompson "total elements %d", block, rstr->blksize*block, 3861d102b48SJeremy L Thompson rstr->nelem); 387c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 388be9261b7Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request); 389be9261b7Sjeremylt CeedChk(ierr); 390be9261b7Sjeremylt 391be9261b7Sjeremylt return 0; 392be9261b7Sjeremylt } 393be9261b7Sjeremylt 394be9261b7Sjeremylt /** 395d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 3961469ee4dSjeremylt 3971469ee4dSjeremylt @param rstr CeedElemRestriction 398d9e1f99aSValeria Barra @param[out] mult Vector to store multiplicity (of size nnodes) 3991469ee4dSjeremylt 4001469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 4011469ee4dSjeremylt 4021469ee4dSjeremylt @ref Advanced 4031469ee4dSjeremylt **/ 4041469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 4051469ee4dSjeremylt CeedVector mult) { 4061469ee4dSjeremylt int ierr; 4071469ee4dSjeremylt CeedVector evec; 4081469ee4dSjeremylt 4091469ee4dSjeremylt // Create and set evec 4101469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 4111469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 4121469ee4dSjeremylt 4131469ee4dSjeremylt // Apply to get multiplicity 4141469ee4dSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, CEED_NOTRANSPOSE, evec, 4151469ee4dSjeremylt mult, CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 4161469ee4dSjeremylt 4171469ee4dSjeremylt // Cleanup 4181469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 4191469ee4dSjeremylt 4201469ee4dSjeremylt return 0; 4211469ee4dSjeremylt } 4221469ee4dSjeremylt 4231469ee4dSjeremylt /** 4244ce2993fSjeremylt @brief Get the Ceed associated with a CeedElemRestriction 4254ce2993fSjeremylt 4264ce2993fSjeremylt @param rstr CeedElemRestriction 4274ce2993fSjeremylt @param[out] ceed Variable to store Ceed 4284ce2993fSjeremylt 4294ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4304ce2993fSjeremylt 43123617272Sjeremylt @ref Advanced 4324ce2993fSjeremylt **/ 4334ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 4344ce2993fSjeremylt *ceed = rstr->ceed; 4354ce2993fSjeremylt return 0; 4364ce2993fSjeremylt } 4374ce2993fSjeremylt 4384ce2993fSjeremylt /** 439b11c1e72Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 440d7b241e6Sjeremylt 4414ce2993fSjeremylt @param rstr CeedElemRestriction 442288c0443SJeremy L Thompson @param[out] numelem Variable to store number of elements 443b11c1e72Sjeremylt 444b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 445dfdf5a53Sjeremylt 44623617272Sjeremylt @ref Advanced 447b11c1e72Sjeremylt **/ 4484ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 4494ce2993fSjeremylt CeedInt *numelem) { 4504ce2993fSjeremylt *numelem = rstr->nelem; 4514ce2993fSjeremylt return 0; 4524ce2993fSjeremylt } 4534ce2993fSjeremylt 4544ce2993fSjeremylt /** 4554ce2993fSjeremylt @brief Get the size of elements in the CeedElemRestriction 4564ce2993fSjeremylt 4574ce2993fSjeremylt @param rstr CeedElemRestriction 4584ce2993fSjeremylt @param[out] elemsize Variable to store size of elements 4594ce2993fSjeremylt 4604ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4614ce2993fSjeremylt 46223617272Sjeremylt @ref Advanced 4634ce2993fSjeremylt **/ 4644ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 4654ce2993fSjeremylt CeedInt *elemsize) { 4664ce2993fSjeremylt *elemsize = rstr->elemsize; 4674ce2993fSjeremylt return 0; 4684ce2993fSjeremylt } 4694ce2993fSjeremylt 4704ce2993fSjeremylt /** 4714ce2993fSjeremylt @brief Get the number of degrees of freedom in the range of a 4724ce2993fSjeremylt CeedElemRestriction 4734ce2993fSjeremylt 4744ce2993fSjeremylt @param rstr CeedElemRestriction 4758795c945Sjeremylt @param[out] numnodes Variable to store number of nodes 4764ce2993fSjeremylt 4774ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4784ce2993fSjeremylt 47923617272Sjeremylt @ref Advanced 4804ce2993fSjeremylt **/ 4818795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr, 4828795c945Sjeremylt CeedInt *numnodes) { 4838795c945Sjeremylt *numnodes = rstr->nnodes; 4844ce2993fSjeremylt return 0; 4854ce2993fSjeremylt } 4864ce2993fSjeremylt 4874ce2993fSjeremylt /** 4884ce2993fSjeremylt @brief Get the number of components in the elements of a 4894ce2993fSjeremylt CeedElemRestriction 4904ce2993fSjeremylt 4914ce2993fSjeremylt @param rstr CeedElemRestriction 4924ce2993fSjeremylt @param[out] numcomp Variable to store number of components 4934ce2993fSjeremylt 4944ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4954ce2993fSjeremylt 49623617272Sjeremylt @ref Advanced 4974ce2993fSjeremylt **/ 4984ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 4994ce2993fSjeremylt CeedInt *numcomp) { 5004ce2993fSjeremylt *numcomp = rstr->ncomp; 5014ce2993fSjeremylt return 0; 5024ce2993fSjeremylt } 5034ce2993fSjeremylt 5044ce2993fSjeremylt /** 5054ce2993fSjeremylt @brief Get the number of blocks in a CeedElemRestriction 5064ce2993fSjeremylt 5074ce2993fSjeremylt @param rstr CeedElemRestriction 5084ce2993fSjeremylt @param[out] numblock Variable to store number of blocks 5094ce2993fSjeremylt 5104ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5114ce2993fSjeremylt 51223617272Sjeremylt @ref Advanced 5134ce2993fSjeremylt **/ 5144ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 5154ce2993fSjeremylt CeedInt *numblock) { 5164ce2993fSjeremylt *numblock = rstr->nblk; 5174ce2993fSjeremylt return 0; 5184ce2993fSjeremylt } 5194ce2993fSjeremylt 5204ce2993fSjeremylt /** 5214ce2993fSjeremylt @brief Get the size of blocks in the CeedElemRestriction 5224ce2993fSjeremylt 523288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5244ce2993fSjeremylt @param[out] blksize Variable to store size of blocks 5254ce2993fSjeremylt 5264ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5274ce2993fSjeremylt 52823617272Sjeremylt @ref Advanced 5294ce2993fSjeremylt **/ 5304ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 5314ce2993fSjeremylt CeedInt *blksize) { 5324ce2993fSjeremylt *blksize = rstr->blksize; 5334ce2993fSjeremylt return 0; 5344ce2993fSjeremylt } 5354ce2993fSjeremylt 5364ce2993fSjeremylt /** 5374ce2993fSjeremylt @brief Get the backend data of a CeedElemRestriction 5384ce2993fSjeremylt 539288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5404ce2993fSjeremylt @param[out] data Variable to store data 5414ce2993fSjeremylt 5424ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5434ce2993fSjeremylt 54423617272Sjeremylt @ref Advanced 5454ce2993fSjeremylt **/ 5461d102b48SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 5474ce2993fSjeremylt *data = rstr->data; 548d7b241e6Sjeremylt return 0; 549d7b241e6Sjeremylt } 550d7b241e6Sjeremylt 551d7b241e6Sjeremylt /** 552fe2413ffSjeremylt @brief Set the backend data of a CeedElemRestriction 553fe2413ffSjeremylt 554288c0443SJeremy L Thompson @param[out] rstr CeedElemRestriction 555fe2413ffSjeremylt @param data Data to set 556fe2413ffSjeremylt 557fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 558fe2413ffSjeremylt 559fe2413ffSjeremylt @ref Advanced 560fe2413ffSjeremylt **/ 5611d102b48SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 562fe2413ffSjeremylt rstr->data = *data; 563fe2413ffSjeremylt return 0; 564fe2413ffSjeremylt } 565fe2413ffSjeremylt 566fe2413ffSjeremylt /** 567f02ca4a2SJed Brown @brief View a CeedElemRestriction 568f02ca4a2SJed Brown 569f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 570f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 571f02ca4a2SJed Brown 572f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 573f02ca4a2SJed Brown 574f02ca4a2SJed Brown @ref Utility 575f02ca4a2SJed Brown **/ 576f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 5771d102b48SJeremy L Thompson fprintf(stream, "CeedElemRestriction from (%d, %d) to %d elements with %d " 5781d102b48SJeremy L Thompson "nodes each\n", rstr->nnodes, rstr->ncomp, rstr->nelem, 5791d102b48SJeremy L Thompson rstr->elemsize); 580f02ca4a2SJed Brown return 0; 581f02ca4a2SJed Brown } 582f02ca4a2SJed Brown 583f02ca4a2SJed Brown /** 584b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 585b11c1e72Sjeremylt 5864ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 587b11c1e72Sjeremylt 588b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 589dfdf5a53Sjeremylt 590dfdf5a53Sjeremylt @ref Basic 591b11c1e72Sjeremylt **/ 5924ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 593d7b241e6Sjeremylt int ierr; 594d7b241e6Sjeremylt 5951d102b48SJeremy L Thompson if (!*rstr || --(*rstr)->refcount > 0) 5961d102b48SJeremy L Thompson return 0; 5974ce2993fSjeremylt if ((*rstr)->Destroy) { 5984ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 599d7b241e6Sjeremylt } 6004ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 6014ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 602d7b241e6Sjeremylt return 0; 603d7b241e6Sjeremylt } 604d7b241e6Sjeremylt 605d7b241e6Sjeremylt /// @} 606