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, 607509a596Sjeremylt CeedInt nelem, CeedInt elemsize, CeedInt nnodes, 617509a596Sjeremylt CeedInt ncomp, CeedMemType mtype, 627509a596Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 634ce2993fSjeremylt CeedElemRestriction *rstr) { 64d7b241e6Sjeremylt int ierr; 65d7b241e6Sjeremylt 665fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 675fe0d4faSjeremylt Ceed delegate; 68aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 69aefd8378Sjeremylt CeedChk(ierr); 705fe0d4faSjeremylt 715fe0d4faSjeremylt if (!delegate) 72c042f62fSJeremy L Thompson // LCOV_EXCL_START 73d7b241e6Sjeremylt return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 74c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 755fe0d4faSjeremylt 7661dbc9d2Sjeremylt ierr = CeedElemRestrictionCreate(delegate, imode, nelem, elemsize, 778795c945Sjeremylt nnodes, ncomp, mtype, cmode, 784ce2993fSjeremylt indices, rstr); CeedChk(ierr); 795fe0d4faSjeremylt return 0; 805fe0d4faSjeremylt } 815fe0d4faSjeremylt 824ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 834ce2993fSjeremylt (*rstr)->ceed = ceed; 84d7b241e6Sjeremylt ceed->refcount++; 854ce2993fSjeremylt (*rstr)->refcount = 1; 8661dbc9d2Sjeremylt (*rstr)->imode = imode; 874ce2993fSjeremylt (*rstr)->nelem = nelem; 884ce2993fSjeremylt (*rstr)->elemsize = elemsize; 898795c945Sjeremylt (*rstr)->nnodes = nnodes; 904ce2993fSjeremylt (*rstr)->ncomp = ncomp; 914ce2993fSjeremylt (*rstr)->nblk = nelem; 924ce2993fSjeremylt (*rstr)->blksize = 1; 934ce2993fSjeremylt ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr); 94d7b241e6Sjeremylt return 0; 95d7b241e6Sjeremylt } 96d7b241e6Sjeremylt 97d7b241e6Sjeremylt /** 987509a596Sjeremylt @brief Create a strided CeedElemRestriction 99d7b241e6Sjeremylt 100b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 1017509a596Sjeremylt @param nelem Number of elements described by the restriction 102b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 1038795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 1048795c945Sjeremylt to which the restriction will be applied is of size 1058795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 106d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 1078795c945Sjeremylt different types of elements. 108b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 10995bb1877Svaleriabarra (1 for scalar fields) 1107509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 1117509a596Sjeremylt The data for node i, component j, element k in the 1127509a596Sjeremylt L-vector is given by 1137509a596Sjeremylt i*strides[0] + j*strides[1] + k*strides[2] 1144ce2993fSjeremylt @param rstr Address of the variable where the newly created 115b11c1e72Sjeremylt CeedElemRestriction will be stored 116d7b241e6Sjeremylt 117b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 118dfdf5a53Sjeremylt 119dfdf5a53Sjeremylt @ref Basic 120b11c1e72Sjeremylt **/ 1217509a596Sjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt nelem, CeedInt elemsize, 122a8d32208Sjeremylt CeedInt nnodes, CeedInt ncomp, 1237509a596Sjeremylt CeedInt strides[3], 124f90c8643Sjeremylt CeedElemRestriction *rstr) { 125d7b241e6Sjeremylt int ierr; 126d7b241e6Sjeremylt 1275fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 1285fe0d4faSjeremylt Ceed delegate; 129aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 130aefd8378Sjeremylt CeedChk(ierr); 1315fe0d4faSjeremylt 1325fe0d4faSjeremylt if (!delegate) 133c042f62fSJeremy L Thompson // LCOV_EXCL_START 1341d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 135c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1365fe0d4faSjeremylt 1377509a596Sjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, nelem, elemsize, nnodes, 1387509a596Sjeremylt ncomp, strides, rstr); CeedChk(ierr); 1395fe0d4faSjeremylt return 0; 1405fe0d4faSjeremylt } 1415fe0d4faSjeremylt 1424ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 1434ce2993fSjeremylt (*rstr)->ceed = ceed; 144d7b241e6Sjeremylt ceed->refcount++; 1454ce2993fSjeremylt (*rstr)->refcount = 1; 1464ce2993fSjeremylt (*rstr)->nelem = nelem; 1474ce2993fSjeremylt (*rstr)->elemsize = elemsize; 1488795c945Sjeremylt (*rstr)->nnodes = nnodes; 1494ce2993fSjeremylt (*rstr)->ncomp = ncomp; 1504ce2993fSjeremylt (*rstr)->nblk = nelem; 1514ce2993fSjeremylt (*rstr)->blksize = 1; 1527509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 1537509a596Sjeremylt for (int i = 0; i<3; i++) 1547509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 1551dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 1561dfeef1dSjeremylt *rstr); 1574b8bea3bSJed Brown CeedChk(ierr); 158d7b241e6Sjeremylt return 0; 159d7b241e6Sjeremylt } 160d7b241e6Sjeremylt 161d7b241e6Sjeremylt /** 162b11c1e72Sjeremylt @brief Permute and pad indices for a blocked restriction 163d7b241e6Sjeremylt 1648795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1658795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1668795c945Sjeremylt for the unknowns corresponding to element i, where 16734138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 1688795c945Sjeremylt [0, @a nnodes). 169ecf6354eSJed Brown @param blkindices Array of permuted and padded indices of 170ecf6354eSJed Brown shape [@a nblk, @a elemsize, @a blksize]. 171d7b241e6Sjeremylt @param nblk Number of blocks 172d7b241e6Sjeremylt @param nelem Number of elements 173d7b241e6Sjeremylt @param blksize Number of elements in a block 174d7b241e6Sjeremylt @param elemsize Size of each element 175d7b241e6Sjeremylt 176b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 177b11c1e72Sjeremylt 178dfdf5a53Sjeremylt @ref Utility 179b11c1e72Sjeremylt **/ 180dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices, 181692c2638Sjeremylt CeedInt nblk, CeedInt nelem, CeedInt blksize, 182692c2638Sjeremylt CeedInt elemsize) { 183d7b241e6Sjeremylt for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 184d7b241e6Sjeremylt for (int j = 0; j < blksize; j++) 185d7b241e6Sjeremylt for (int k = 0; k < elemsize; k++) 186d7b241e6Sjeremylt blkindices[e*elemsize + k*blksize + j] 187d7b241e6Sjeremylt = indices[CeedIntMin(e+j,nelem-1)*elemsize + k]; 188dfdf5a53Sjeremylt return 0; 189d7b241e6Sjeremylt } 190d7b241e6Sjeremylt 191d7b241e6Sjeremylt /** 192b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 193d7b241e6Sjeremylt 194d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 19561dbc9d2Sjeremylt @param imode Ordering of the ncomp components, i.e. it specifies 196a8d32208Sjeremylt the ordering of the components of the L-vector used 19761dbc9d2Sjeremylt by this CeedElemRestriction. CEED_NONINTERLACED indicates 19861dbc9d2Sjeremylt the component is the outermost index and CEED_INTERLACED 199a8d32208Sjeremylt indicates the component is the innermost index in 200a8d32208Sjeremylt ordering of the L-vector. 201d7b241e6Sjeremylt @param nelem Number of elements described in the @a indices array. 202b11c1e72Sjeremylt @param elemsize Size (number of unknowns) per element 203b11c1e72Sjeremylt @param blksize Number of elements in a block 2048795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 2058795c945Sjeremylt to which the restriction will be applied is of size 2068795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 207d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 208d7b241e6Sjeremylt different types of elements. 20995bb1877Svaleriabarra @param ncomp Number of field components per interpolation node 21095bb1877Svaleriabarra (1 for scalar fields) 211b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 212b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 2138795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 2148795c945Sjeremylt ordered list of the indices (into the input CeedVector) 2158795c945Sjeremylt for the unknowns corresponding to element i, where 21634138859Sjeremylt 0 <= i < @a nelem. All indices must be in the range 2178795c945Sjeremylt [0, @a nnodes). The backend will permute and pad this 2188795c945Sjeremylt array to the desired ordering for the blocksize, which is 2198795c945Sjeremylt typically given by the backend. The default reordering is 2208795c945Sjeremylt to interlace elements. 2214ce2993fSjeremylt @param rstr Address of the variable where the newly created 222b11c1e72Sjeremylt CeedElemRestriction will be stored 223d7b241e6Sjeremylt 224b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 225dfdf5a53Sjeremylt 226dfdf5a53Sjeremylt @ref Advanced 227b11c1e72Sjeremylt **/ 22861dbc9d2Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInterlaceMode imode, 229a8d32208Sjeremylt CeedInt nelem, CeedInt elemsize, 2308795c945Sjeremylt CeedInt blksize, CeedInt nnodes, 2318795c945Sjeremylt CeedInt ncomp, CeedMemType mtype, 2328795c945Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 2334ce2993fSjeremylt CeedElemRestriction *rstr) { 234d7b241e6Sjeremylt int ierr; 235d7b241e6Sjeremylt CeedInt *blkindices; 236d7b241e6Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 237d7b241e6Sjeremylt 2385fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 2395fe0d4faSjeremylt Ceed delegate; 240aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 241aefd8378Sjeremylt CeedChk(ierr); 2425fe0d4faSjeremylt 2435fe0d4faSjeremylt if (!delegate) 244c042f62fSJeremy L Thompson // LCOV_EXCL_START 2451d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 2461d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 247c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 2485fe0d4faSjeremylt 24961dbc9d2Sjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, imode, nelem, elemsize, 2508795c945Sjeremylt blksize, nnodes, ncomp, mtype, cmode, 2514ce2993fSjeremylt indices, rstr); CeedChk(ierr); 2525fe0d4faSjeremylt return 0; 2535fe0d4faSjeremylt } 254d7b241e6Sjeremylt 2554ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 256d7b241e6Sjeremylt 257de686571SJeremy L Thompson ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 2584b8bea3bSJed Brown ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 2594b8bea3bSJed Brown elemsize); 260dfdf5a53Sjeremylt CeedChk(ierr); 261d7b241e6Sjeremylt 2624ce2993fSjeremylt (*rstr)->ceed = ceed; 263d7b241e6Sjeremylt ceed->refcount++; 2644ce2993fSjeremylt (*rstr)->refcount = 1; 26561dbc9d2Sjeremylt (*rstr)->imode = imode; 2664ce2993fSjeremylt (*rstr)->nelem = nelem; 2674ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2688795c945Sjeremylt (*rstr)->nnodes = nnodes; 2694ce2993fSjeremylt (*rstr)->ncomp = ncomp; 2704ce2993fSjeremylt (*rstr)->nblk = nblk; 2714ce2993fSjeremylt (*rstr)->blksize = blksize; 272667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 2737f823360Sjeremylt (const CeedInt *) blkindices, *rstr); CeedChk(ierr); 274d7b241e6Sjeremylt 2751d102b48SJeremy L Thompson if (cmode == CEED_OWN_POINTER) { 276d7b241e6Sjeremylt ierr = CeedFree(&indices); CeedChk(ierr); 2771d102b48SJeremy L Thompson } 278d7b241e6Sjeremylt 279d7b241e6Sjeremylt return 0; 280d7b241e6Sjeremylt } 281d7b241e6Sjeremylt 282b11c1e72Sjeremylt /** 2837509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 2847509a596Sjeremylt 2857509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 2867509a596Sjeremylt @param nelem Number of elements described by the restriction 2877509a596Sjeremylt @param elemsize Size (number of "nodes") per element 2887509a596Sjeremylt @param blksize Number of elements in a block 2897509a596Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 2907509a596Sjeremylt to which the restriction will be applied is of size 2917509a596Sjeremylt @a nnodes * @a ncomp. This size may include data 2927509a596Sjeremylt used by other CeedElemRestriction objects describing 2937509a596Sjeremylt different types of elements. 2947509a596Sjeremylt @param ncomp Number of field components per interpolation node 2957509a596Sjeremylt (1 for scalar fields) 2967509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 2977509a596Sjeremylt The data for node i, component j, element k in the 2987509a596Sjeremylt L-vector is given by 2997509a596Sjeremylt i*strides[0] + j*strides[1] + k*strides[2] 3007509a596Sjeremylt @param rstr Address of the variable where the newly created 3017509a596Sjeremylt CeedElemRestriction will be stored 3027509a596Sjeremylt 3037509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 3047509a596Sjeremylt 3057509a596Sjeremylt @ref Basic 3067509a596Sjeremylt **/ 3077509a596Sjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt nelem, 3087509a596Sjeremylt CeedInt elemsize, CeedInt blksize, 3097509a596Sjeremylt CeedInt nnodes, CeedInt ncomp, 3107509a596Sjeremylt CeedInt strides[3], 3117509a596Sjeremylt CeedElemRestriction *rstr) { 3127509a596Sjeremylt int ierr; 3137509a596Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 3147509a596Sjeremylt 3157509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 3167509a596Sjeremylt Ceed delegate; 3177509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 3187509a596Sjeremylt CeedChk(ierr); 3197509a596Sjeremylt 3207509a596Sjeremylt if (!delegate) 3217509a596Sjeremylt // LCOV_EXCL_START 3227509a596Sjeremylt return CeedError(ceed, 1, "Backend does not support " 3237509a596Sjeremylt "ElemRestrictionCreateBlocked"); 3247509a596Sjeremylt // LCOV_EXCL_STOP 3257509a596Sjeremylt 3267509a596Sjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, nelem, elemsize, 3277509a596Sjeremylt blksize, nnodes, ncomp, 3287509a596Sjeremylt strides, rstr); 3297509a596Sjeremylt CeedChk(ierr); 3307509a596Sjeremylt return 0; 3317509a596Sjeremylt } 3327509a596Sjeremylt 3337509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3347509a596Sjeremylt 3357509a596Sjeremylt (*rstr)->ceed = ceed; 3367509a596Sjeremylt ceed->refcount++; 3377509a596Sjeremylt (*rstr)->refcount = 1; 3387509a596Sjeremylt (*rstr)->nelem = nelem; 3397509a596Sjeremylt (*rstr)->elemsize = elemsize; 3407509a596Sjeremylt (*rstr)->nnodes = nnodes; 3417509a596Sjeremylt (*rstr)->ncomp = ncomp; 3427509a596Sjeremylt (*rstr)->nblk = nblk; 3437509a596Sjeremylt (*rstr)->blksize = blksize; 3447509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 3457509a596Sjeremylt for (int i = 0; i<3; i++) 3467509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 3477509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 3487509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 3497509a596Sjeremylt 3507509a596Sjeremylt return 0; 3517509a596Sjeremylt } 3527509a596Sjeremylt 3537509a596Sjeremylt /** 354b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 355b11c1e72Sjeremylt 3564ce2993fSjeremylt @param rstr CeedElemRestriction 357b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 358b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 359b11c1e72Sjeremylt 360b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 361dfdf5a53Sjeremylt 362dfdf5a53Sjeremylt @ref Advanced 363b11c1e72Sjeremylt **/ 3644ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 365d7b241e6Sjeremylt CeedVector *evec) { 366d7b241e6Sjeremylt int ierr; 367d7b241e6Sjeremylt CeedInt n, m; 3688795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3694ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 370d7b241e6Sjeremylt if (lvec) { 3714ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 372d7b241e6Sjeremylt } 373d7b241e6Sjeremylt if (evec) { 3744ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 375d7b241e6Sjeremylt } 376d7b241e6Sjeremylt return 0; 377d7b241e6Sjeremylt } 378d7b241e6Sjeremylt 379d7b241e6Sjeremylt /** 380d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 381d7b241e6Sjeremylt 3824ce2993fSjeremylt @param rstr CeedElemRestriction 383d7b241e6Sjeremylt @param tmode Apply restriction or transpose 3847aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 38561dbc9d2Sjeremylt tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED) 386a8d32208Sjeremylt @param ru Output vector (of shape [@a nelem * @a elemsize] when 3877aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 3887aaeacdcSjeremylt by the backend. 389d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 390b11c1e72Sjeremylt 391b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 392dfdf5a53Sjeremylt 393dfdf5a53Sjeremylt @ref Advanced 394b11c1e72Sjeremylt **/ 3954ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 396a8d32208Sjeremylt CeedVector u, CeedVector ru, 397a8d32208Sjeremylt CeedRequest *request) { 398d7b241e6Sjeremylt CeedInt m,n; 399d7b241e6Sjeremylt int ierr; 400d7b241e6Sjeremylt 401d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 4024ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 4038795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 404d7b241e6Sjeremylt } else { 4058795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 4064ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 407d7b241e6Sjeremylt } 408d7b241e6Sjeremylt if (n != u->length) 409c042f62fSJeremy L Thompson // LCOV_EXCL_START 4101d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 4111d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 412c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 413a8d32208Sjeremylt if (m != ru->length) 414c042f62fSJeremy L Thompson // LCOV_EXCL_START 4151d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 416a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 417c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 418074cb416Sjeremylt ierr = rstr->Apply(rstr, tmode, u, ru, request); CeedChk(ierr); 419d7b241e6Sjeremylt 420d7b241e6Sjeremylt return 0; 421d7b241e6Sjeremylt } 422d7b241e6Sjeremylt 423d7b241e6Sjeremylt /** 424d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 425be9261b7Sjeremylt 426be9261b7Sjeremylt @param rstr CeedElemRestriction 4271f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 4281f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 4291f37b403Sjeremylt [3*blksize : 4*blksize] 430be9261b7Sjeremylt @param tmode Apply restriction or transpose 4317aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 43261dbc9d2Sjeremylt tmode=CEED_NOTRANSPOSE, imode=CEED_INTERLACED) 433a8d32208Sjeremylt @param ru Output vector (of shape [@a blksize * @a elemsize] when 4347aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 4357aaeacdcSjeremylt by the backend. 436be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 437be9261b7Sjeremylt 438be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 439be9261b7Sjeremylt 440be9261b7Sjeremylt @ref Advanced 441be9261b7Sjeremylt **/ 442be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 443a8d32208Sjeremylt CeedTransposeMode tmode, CeedVector u, 444a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 445be9261b7Sjeremylt CeedInt m,n; 446be9261b7Sjeremylt int ierr; 447be9261b7Sjeremylt 448be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 449be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 4508795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 451be9261b7Sjeremylt } else { 4528795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 453be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 454be9261b7Sjeremylt } 455be9261b7Sjeremylt if (n != u->length) 456c042f62fSJeremy L Thompson // LCOV_EXCL_START 4571d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 4581d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 459c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 460a8d32208Sjeremylt if (m != ru->length) 461c042f62fSJeremy L Thompson // LCOV_EXCL_START 4621d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 463a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 464c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 465be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 466c042f62fSJeremy L Thompson // LCOV_EXCL_START 4671d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 4681d102b48SJeremy L Thompson "total elements %d", block, rstr->blksize*block, 4691d102b48SJeremy L Thompson rstr->nelem); 470c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 471074cb416Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, u, ru, request); 472be9261b7Sjeremylt CeedChk(ierr); 473be9261b7Sjeremylt 474be9261b7Sjeremylt return 0; 475be9261b7Sjeremylt } 476be9261b7Sjeremylt 477be9261b7Sjeremylt /** 478d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 4791469ee4dSjeremylt 4801469ee4dSjeremylt @param rstr CeedElemRestriction 481b9c05c73SJed Brown @param[out] mult Vector to store multiplicity (of size nnodes*ncomp) 4821469ee4dSjeremylt 4831469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 4841469ee4dSjeremylt 4851469ee4dSjeremylt @ref Advanced 4861469ee4dSjeremylt **/ 4871469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 4881469ee4dSjeremylt CeedVector mult) { 4891469ee4dSjeremylt int ierr; 4901469ee4dSjeremylt CeedVector evec; 4911469ee4dSjeremylt 4921469ee4dSjeremylt // Create and set evec 4931469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 4941469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 495fa9eac48SJed Brown ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 4961469ee4dSjeremylt 4971469ee4dSjeremylt // Apply to get multiplicity 498a8d32208Sjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult, 499efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 5001469ee4dSjeremylt 5011469ee4dSjeremylt // Cleanup 5021469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 5031469ee4dSjeremylt 5041469ee4dSjeremylt return 0; 5051469ee4dSjeremylt } 5061469ee4dSjeremylt 5071469ee4dSjeremylt /** 5084ce2993fSjeremylt @brief Get the Ceed associated with a CeedElemRestriction 5094ce2993fSjeremylt 5104ce2993fSjeremylt @param rstr CeedElemRestriction 5114ce2993fSjeremylt @param[out] ceed Variable to store Ceed 5124ce2993fSjeremylt 5134ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5144ce2993fSjeremylt 51523617272Sjeremylt @ref Advanced 5164ce2993fSjeremylt **/ 5174ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 5184ce2993fSjeremylt *ceed = rstr->ceed; 5194ce2993fSjeremylt return 0; 5204ce2993fSjeremylt } 5214ce2993fSjeremylt 5224ce2993fSjeremylt /** 52361dbc9d2Sjeremylt @brief Get the L-vector interlaced mode of a CeedElemRestriction 524a8d32208Sjeremylt 525a8d32208Sjeremylt @param rstr CeedElemRestriction 52661dbc9d2Sjeremylt @param[out] imode Variable to store imode 527a8d32208Sjeremylt 528a8d32208Sjeremylt @return An error code: 0 - success, otherwise - failure 529a8d32208Sjeremylt 530a8d32208Sjeremylt @ref Advanced 531a8d32208Sjeremylt **/ 53261dbc9d2Sjeremylt int CeedElemRestrictionGetIMode(CeedElemRestriction rstr, 53361dbc9d2Sjeremylt CeedInterlaceMode *imode) { 5347509a596Sjeremylt if (rstr->strides) 5357509a596Sjeremylt // LCOV_EXCL_START 5367509a596Sjeremylt return CeedError(rstr->ceed, 1, "Strided ElemRestriction has no interlace " 5377509a596Sjeremylt "mode"); 5387509a596Sjeremylt // LCOV_EXCL_STOP 5397509a596Sjeremylt 54061dbc9d2Sjeremylt *imode = rstr->imode; 541a8d32208Sjeremylt return 0; 542a8d32208Sjeremylt } 543a8d32208Sjeremylt 544a8d32208Sjeremylt /** 545b11c1e72Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 546d7b241e6Sjeremylt 5474ce2993fSjeremylt @param rstr CeedElemRestriction 548288c0443SJeremy L Thompson @param[out] numelem Variable to store number of elements 549b11c1e72Sjeremylt 550b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 551dfdf5a53Sjeremylt 55223617272Sjeremylt @ref Advanced 553b11c1e72Sjeremylt **/ 5544ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 5554ce2993fSjeremylt CeedInt *numelem) { 5564ce2993fSjeremylt *numelem = rstr->nelem; 5574ce2993fSjeremylt return 0; 5584ce2993fSjeremylt } 5594ce2993fSjeremylt 5604ce2993fSjeremylt /** 5614ce2993fSjeremylt @brief Get the size of elements in the CeedElemRestriction 5624ce2993fSjeremylt 5634ce2993fSjeremylt @param rstr CeedElemRestriction 5644ce2993fSjeremylt @param[out] elemsize Variable to store size of elements 5654ce2993fSjeremylt 5664ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5674ce2993fSjeremylt 56823617272Sjeremylt @ref Advanced 5694ce2993fSjeremylt **/ 5704ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 5714ce2993fSjeremylt CeedInt *elemsize) { 5724ce2993fSjeremylt *elemsize = rstr->elemsize; 5734ce2993fSjeremylt return 0; 5744ce2993fSjeremylt } 5754ce2993fSjeremylt 5764ce2993fSjeremylt /** 5774ce2993fSjeremylt @brief Get the number of degrees of freedom in the range of a 5784ce2993fSjeremylt CeedElemRestriction 5794ce2993fSjeremylt 5804ce2993fSjeremylt @param rstr CeedElemRestriction 5818795c945Sjeremylt @param[out] numnodes Variable to store number of nodes 5824ce2993fSjeremylt 5834ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5844ce2993fSjeremylt 58523617272Sjeremylt @ref Advanced 5864ce2993fSjeremylt **/ 5878795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr, 5888795c945Sjeremylt CeedInt *numnodes) { 5898795c945Sjeremylt *numnodes = rstr->nnodes; 5904ce2993fSjeremylt return 0; 5914ce2993fSjeremylt } 5924ce2993fSjeremylt 5934ce2993fSjeremylt /** 5944ce2993fSjeremylt @brief Get the number of components in the elements of a 5954ce2993fSjeremylt CeedElemRestriction 5964ce2993fSjeremylt 5974ce2993fSjeremylt @param rstr CeedElemRestriction 5984ce2993fSjeremylt @param[out] numcomp Variable to store number of components 5994ce2993fSjeremylt 6004ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6014ce2993fSjeremylt 60223617272Sjeremylt @ref Advanced 6034ce2993fSjeremylt **/ 6044ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 6054ce2993fSjeremylt CeedInt *numcomp) { 6064ce2993fSjeremylt *numcomp = rstr->ncomp; 6074ce2993fSjeremylt return 0; 6084ce2993fSjeremylt } 6094ce2993fSjeremylt 6104ce2993fSjeremylt /** 6114ce2993fSjeremylt @brief Get the number of blocks in a CeedElemRestriction 6124ce2993fSjeremylt 6134ce2993fSjeremylt @param rstr CeedElemRestriction 6144ce2993fSjeremylt @param[out] numblock Variable to store number of blocks 6154ce2993fSjeremylt 6164ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6174ce2993fSjeremylt 61823617272Sjeremylt @ref Advanced 6194ce2993fSjeremylt **/ 6204ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 6214ce2993fSjeremylt CeedInt *numblock) { 6224ce2993fSjeremylt *numblock = rstr->nblk; 6234ce2993fSjeremylt return 0; 6244ce2993fSjeremylt } 6254ce2993fSjeremylt 6264ce2993fSjeremylt /** 6274ce2993fSjeremylt @brief Get the size of blocks in the CeedElemRestriction 6284ce2993fSjeremylt 629288c0443SJeremy L Thompson @param rstr CeedElemRestriction 6304ce2993fSjeremylt @param[out] blksize Variable to store size of blocks 6314ce2993fSjeremylt 6324ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6334ce2993fSjeremylt 63423617272Sjeremylt @ref Advanced 6354ce2993fSjeremylt **/ 6364ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 6374ce2993fSjeremylt CeedInt *blksize) { 6384ce2993fSjeremylt *blksize = rstr->blksize; 6394ce2993fSjeremylt return 0; 6404ce2993fSjeremylt } 6414ce2993fSjeremylt 6424ce2993fSjeremylt /** 6437509a596Sjeremylt @brief Get the strides of a strided CeedElemRestriction 6447509a596Sjeremylt 6457509a596Sjeremylt @param rstr CeedElemRestriction 6467509a596Sjeremylt @param[out] strides Variable to store strides array 6477509a596Sjeremylt 6487509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 6497509a596Sjeremylt 6507509a596Sjeremylt @ref Advanced 6517509a596Sjeremylt **/ 6527509a596Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 6537509a596Sjeremylt CeedInt (*strides)[3]) { 6547509a596Sjeremylt if (!rstr->strides) 6557509a596Sjeremylt // LCOV_EXCL_START 6567509a596Sjeremylt return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 6577509a596Sjeremylt // LCOV_EXCL_STOP 6587509a596Sjeremylt 6597509a596Sjeremylt for (int i = 0; i<3; i++) 6607509a596Sjeremylt (*strides)[i] = rstr->strides[i]; 6617509a596Sjeremylt return 0; 6627509a596Sjeremylt } 6637509a596Sjeremylt 6647509a596Sjeremylt /** 665*523b8ea0Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 666*523b8ea0Sjeremylt 667*523b8ea0Sjeremylt @param rstr CeedElemRestriction 668*523b8ea0Sjeremylt @param[out] bool Variable to store stride status 669*523b8ea0Sjeremylt 670*523b8ea0Sjeremylt @return An error code: 0 - success, otherwise - failure 671*523b8ea0Sjeremylt 672*523b8ea0Sjeremylt @ref Advanced 673*523b8ea0Sjeremylt **/ 674*523b8ea0Sjeremylt int CeedElemRestrictionGetBackendStridesStatus(CeedElemRestriction rstr, 675*523b8ea0Sjeremylt bool *status) { 676*523b8ea0Sjeremylt if (!rstr->strides) 677*523b8ea0Sjeremylt // LCOV_EXCL_START 678*523b8ea0Sjeremylt return CeedError(rstr->ceed, 1, "ElemRestriction has no stride data"); 679*523b8ea0Sjeremylt // LCOV_EXCL_STOP 680*523b8ea0Sjeremylt 681*523b8ea0Sjeremylt *status = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 682*523b8ea0Sjeremylt (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 683*523b8ea0Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 684*523b8ea0Sjeremylt return 0; 685*523b8ea0Sjeremylt } 686*523b8ea0Sjeremylt 687*523b8ea0Sjeremylt /** 6884ce2993fSjeremylt @brief Get the backend data of a CeedElemRestriction 6894ce2993fSjeremylt 690288c0443SJeremy L Thompson @param rstr CeedElemRestriction 6914ce2993fSjeremylt @param[out] data Variable to store data 6924ce2993fSjeremylt 6934ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6944ce2993fSjeremylt 69523617272Sjeremylt @ref Advanced 6964ce2993fSjeremylt **/ 6971d102b48SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 6984ce2993fSjeremylt *data = rstr->data; 699d7b241e6Sjeremylt return 0; 700d7b241e6Sjeremylt } 701d7b241e6Sjeremylt 702d7b241e6Sjeremylt /** 703fe2413ffSjeremylt @brief Set the backend data of a CeedElemRestriction 704fe2413ffSjeremylt 705288c0443SJeremy L Thompson @param[out] rstr CeedElemRestriction 706fe2413ffSjeremylt @param data Data to set 707fe2413ffSjeremylt 708fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 709fe2413ffSjeremylt 710fe2413ffSjeremylt @ref Advanced 711fe2413ffSjeremylt **/ 7121d102b48SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 713fe2413ffSjeremylt rstr->data = *data; 714fe2413ffSjeremylt return 0; 715fe2413ffSjeremylt } 716fe2413ffSjeremylt 717fe2413ffSjeremylt /** 718f02ca4a2SJed Brown @brief View a CeedElemRestriction 719f02ca4a2SJed Brown 720f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 721f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 722f02ca4a2SJed Brown 723f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 724f02ca4a2SJed Brown 725f02ca4a2SJed Brown @ref Utility 726f02ca4a2SJed Brown **/ 727f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 7287509a596Sjeremylt char stridesstr[500]; 7297509a596Sjeremylt if (rstr->strides) 7307509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 7317509a596Sjeremylt rstr->strides[2]); 7327509a596Sjeremylt 7330036de2cSjeremylt fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d " 7340036de2cSjeremylt "nodes each and %s %s\n", rstr->blksize > 1 ? "Blocked " : "", 7350036de2cSjeremylt rstr->nnodes, rstr->ncomp, rstr->nelem, rstr->elemsize, 7360036de2cSjeremylt rstr->strides ? "strides" : "L-vector components", 7377509a596Sjeremylt rstr->strides ? stridesstr : CeedInterlaceModes[rstr->imode]); 738f02ca4a2SJed Brown return 0; 739f02ca4a2SJed Brown } 740f02ca4a2SJed Brown 741f02ca4a2SJed Brown /** 742b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 743b11c1e72Sjeremylt 7444ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 745b11c1e72Sjeremylt 746b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 747dfdf5a53Sjeremylt 748dfdf5a53Sjeremylt @ref Basic 749b11c1e72Sjeremylt **/ 7504ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 751d7b241e6Sjeremylt int ierr; 752d7b241e6Sjeremylt 7531d102b48SJeremy L Thompson if (!*rstr || --(*rstr)->refcount > 0) 7541d102b48SJeremy L Thompson return 0; 7554ce2993fSjeremylt if ((*rstr)->Destroy) { 7564ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 757d7b241e6Sjeremylt } 7587509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 7594ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 7604ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 761d7b241e6Sjeremylt return 0; 762d7b241e6Sjeremylt } 763d7b241e6Sjeremylt 764*523b8ea0Sjeremylt /// @cond DOXYGEN_SKIP 765*523b8ea0Sjeremylt // Indicate that the stride is determined by the backend 766*523b8ea0Sjeremylt CeedInt CEED_STRIDES_BACKEND[3] = {}; 767*523b8ea0Sjeremylt /// @endcond 768*523b8ea0Sjeremylt 769d7b241e6Sjeremylt /// @} 770