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 30*a8d32208Sjeremylt @param lmode Ordering of the ncomp components, i.e. it specifies 31*a8d32208Sjeremylt the ordering of the components of the L-vector used 32*a8d32208Sjeremylt by this CeedElemRestriction. CEED_NOTRANSPOSE indicates 33*a8d32208Sjeremylt the component is the outermost index and CEED_TRANSPOSE 34*a8d32208Sjeremylt indicates the component is the innermost index in 35*a8d32208Sjeremylt 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 **/ 59*a8d32208Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedTransposeMode lmode, 60*a8d32208Sjeremylt CeedInt nelem, CeedInt elemsize, CeedInt nnodes, 61*a8d32208Sjeremylt CeedInt ncomp, CeedMemType mtype, 62d7b241e6Sjeremylt 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 76*a8d32208Sjeremylt ierr = CeedElemRestrictionCreate(delegate, lmode, 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; 86*a8d32208Sjeremylt (*rstr)->lmode = lmode; 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 /** 98b11c1e72Sjeremylt @brief Create an identity CeedElemRestriction 99d7b241e6Sjeremylt 100b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 101*a8d32208Sjeremylt @param lmode Ordering of the ncomp components, i.e. it specifies 102*a8d32208Sjeremylt the ordering of the components of the L-vector used 103*a8d32208Sjeremylt by this CeedElemRestriction. CEED_NOTRANSPOSE indicates 104*a8d32208Sjeremylt the component is the outermost index and CEED_TRANSPOSE 105*a8d32208Sjeremylt indicates the component is the innermost index in 106*a8d32208Sjeremylt ordering of the L-vector. 107b11c1e72Sjeremylt @param nelem Number of elements described in the @a indices array 108b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 1098795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 1108795c945Sjeremylt to which the restriction will be applied is of size 1118795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 112d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 1138795c945Sjeremylt different types of elements. 114b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 11595bb1877Svaleriabarra (1 for scalar fields) 1164ce2993fSjeremylt @param rstr Address of the variable where the newly created 117b11c1e72Sjeremylt CeedElemRestriction will be stored 118d7b241e6Sjeremylt 119b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 120dfdf5a53Sjeremylt 121dfdf5a53Sjeremylt @ref Basic 122b11c1e72Sjeremylt **/ 123*a8d32208Sjeremylt int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedTransposeMode lmode, 124*a8d32208Sjeremylt CeedInt nelem, CeedInt elemsize, 125*a8d32208Sjeremylt CeedInt nnodes, CeedInt ncomp, 126f90c8643Sjeremylt CeedElemRestriction *rstr) { 127d7b241e6Sjeremylt int ierr; 128d7b241e6Sjeremylt 1295fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 1305fe0d4faSjeremylt Ceed delegate; 131aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 132aefd8378Sjeremylt CeedChk(ierr); 1335fe0d4faSjeremylt 1345fe0d4faSjeremylt if (!delegate) 135c042f62fSJeremy L Thompson // LCOV_EXCL_START 1361d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 137c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1385fe0d4faSjeremylt 139*a8d32208Sjeremylt ierr = CeedElemRestrictionCreateIdentity(delegate, lmode, nelem, elemsize, 1408795c945Sjeremylt nnodes, ncomp, rstr); CeedChk(ierr); 1415fe0d4faSjeremylt return 0; 1425fe0d4faSjeremylt } 1435fe0d4faSjeremylt 1444ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 1454ce2993fSjeremylt (*rstr)->ceed = ceed; 146d7b241e6Sjeremylt ceed->refcount++; 1474ce2993fSjeremylt (*rstr)->refcount = 1; 148*a8d32208Sjeremylt (*rstr)->lmode = lmode; 1494ce2993fSjeremylt (*rstr)->nelem = nelem; 1504ce2993fSjeremylt (*rstr)->elemsize = elemsize; 1518795c945Sjeremylt (*rstr)->nnodes = nnodes; 1524ce2993fSjeremylt (*rstr)->ncomp = ncomp; 1534ce2993fSjeremylt (*rstr)->nblk = nelem; 1544ce2993fSjeremylt (*rstr)->blksize = 1; 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. 195*a8d32208Sjeremylt @param lmode Ordering of the ncomp components, i.e. it specifies 196*a8d32208Sjeremylt the ordering of the components of the L-vector used 197*a8d32208Sjeremylt by this CeedElemRestriction. CEED_NOTRANSPOSE indicates 198*a8d32208Sjeremylt the component is the outermost index and CEED_TRANSPOSE 199*a8d32208Sjeremylt indicates the component is the innermost index in 200*a8d32208Sjeremylt 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 **/ 228*a8d32208Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedTransposeMode lmode, 229*a8d32208Sjeremylt 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 249*a8d32208Sjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, lmode, 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 257d7b241e6Sjeremylt if (indices) { 258de686571SJeremy L Thompson ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 2594b8bea3bSJed Brown ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 2604b8bea3bSJed Brown elemsize); 261dfdf5a53Sjeremylt CeedChk(ierr); 262d7b241e6Sjeremylt } else { 263d7b241e6Sjeremylt blkindices = NULL; 264d7b241e6Sjeremylt } 265d7b241e6Sjeremylt 2664ce2993fSjeremylt (*rstr)->ceed = ceed; 267d7b241e6Sjeremylt ceed->refcount++; 2684ce2993fSjeremylt (*rstr)->refcount = 1; 269*a8d32208Sjeremylt (*rstr)->lmode = lmode; 2704ce2993fSjeremylt (*rstr)->nelem = nelem; 2714ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2728795c945Sjeremylt (*rstr)->nnodes = nnodes; 2734ce2993fSjeremylt (*rstr)->ncomp = ncomp; 2744ce2993fSjeremylt (*rstr)->nblk = nblk; 2754ce2993fSjeremylt (*rstr)->blksize = blksize; 276667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 2777f823360Sjeremylt (const CeedInt *) blkindices, *rstr); CeedChk(ierr); 278d7b241e6Sjeremylt 2791d102b48SJeremy L Thompson if (cmode == CEED_OWN_POINTER) { 280d7b241e6Sjeremylt ierr = CeedFree(&indices); CeedChk(ierr); 2811d102b48SJeremy L Thompson } 282d7b241e6Sjeremylt 283d7b241e6Sjeremylt return 0; 284d7b241e6Sjeremylt } 285d7b241e6Sjeremylt 286b11c1e72Sjeremylt /** 287b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 288b11c1e72Sjeremylt 2894ce2993fSjeremylt @param rstr CeedElemRestriction 290b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 291b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 292b11c1e72Sjeremylt 293b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 294dfdf5a53Sjeremylt 295dfdf5a53Sjeremylt @ref Advanced 296b11c1e72Sjeremylt **/ 2974ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 298d7b241e6Sjeremylt CeedVector *evec) { 299d7b241e6Sjeremylt int ierr; 300d7b241e6Sjeremylt CeedInt n, m; 3018795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3024ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 303d7b241e6Sjeremylt if (lvec) { 3044ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 305d7b241e6Sjeremylt } 306d7b241e6Sjeremylt if (evec) { 3074ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 308d7b241e6Sjeremylt } 309d7b241e6Sjeremylt return 0; 310d7b241e6Sjeremylt } 311d7b241e6Sjeremylt 312d7b241e6Sjeremylt /** 313d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 314d7b241e6Sjeremylt 3154ce2993fSjeremylt @param rstr CeedElemRestriction 316d7b241e6Sjeremylt @param tmode Apply restriction or transpose 3177aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 3187aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE, lmode=CEED_TRANSPOSE) 319*a8d32208Sjeremylt @param ru Output vector (of shape [@a nelem * @a elemsize] when 3207aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 3217aaeacdcSjeremylt by the backend. 322d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 323b11c1e72Sjeremylt 324b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 325dfdf5a53Sjeremylt 326dfdf5a53Sjeremylt @ref Advanced 327b11c1e72Sjeremylt **/ 3284ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 329*a8d32208Sjeremylt CeedVector u, CeedVector ru, 330*a8d32208Sjeremylt CeedRequest *request) { 331d7b241e6Sjeremylt CeedInt m,n; 332d7b241e6Sjeremylt int ierr; 333d7b241e6Sjeremylt 334d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 3354ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 3368795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 337d7b241e6Sjeremylt } else { 3388795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3394ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 340d7b241e6Sjeremylt } 341d7b241e6Sjeremylt if (n != u->length) 342c042f62fSJeremy L Thompson // LCOV_EXCL_START 3431d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3441d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 345c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 346*a8d32208Sjeremylt if (m != ru->length) 347c042f62fSJeremy L Thompson // LCOV_EXCL_START 3481d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 349*a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 350c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 351*a8d32208Sjeremylt ierr = rstr->Apply(rstr, tmode, rstr->lmode, u, ru, request); CeedChk(ierr); 352d7b241e6Sjeremylt 353d7b241e6Sjeremylt return 0; 354d7b241e6Sjeremylt } 355d7b241e6Sjeremylt 356d7b241e6Sjeremylt /** 357d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 358be9261b7Sjeremylt 359be9261b7Sjeremylt @param rstr CeedElemRestriction 3601f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 3611f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 3621f37b403Sjeremylt [3*blksize : 4*blksize] 363be9261b7Sjeremylt @param tmode Apply restriction or transpose 3647aaeacdcSjeremylt @param u Input vector (of shape [@a nnodes, @a ncomp] when 3657aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE, lmode=CEED_TRANSPOSE) 366*a8d32208Sjeremylt @param ru Output vector (of shape [@a blksize * @a elemsize] when 3677aaeacdcSjeremylt tmode=CEED_NOTRANSPOSE). Ordering of the e-vector is decided 3687aaeacdcSjeremylt by the backend. 369be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 370be9261b7Sjeremylt 371be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 372be9261b7Sjeremylt 373be9261b7Sjeremylt @ref Advanced 374be9261b7Sjeremylt **/ 375be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 376*a8d32208Sjeremylt CeedTransposeMode tmode, CeedVector u, 377*a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 378be9261b7Sjeremylt CeedInt m,n; 379be9261b7Sjeremylt int ierr; 380be9261b7Sjeremylt 381be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 382be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 3838795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 384be9261b7Sjeremylt } else { 3858795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 386be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 387be9261b7Sjeremylt } 388be9261b7Sjeremylt if (n != u->length) 389c042f62fSJeremy L Thompson // LCOV_EXCL_START 3901d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Input vector size %d not compatible with " 3911d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 392c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 393*a8d32208Sjeremylt if (m != ru->length) 394c042f62fSJeremy L Thompson // LCOV_EXCL_START 3951d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Output vector size %d not compatible with " 396*a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 397c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 398be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 399c042f62fSJeremy L Thompson // LCOV_EXCL_START 4001d102b48SJeremy L Thompson return CeedError(rstr->ceed, 2, "Cannot retrieve block %d, element %d > " 4011d102b48SJeremy L Thompson "total elements %d", block, rstr->blksize*block, 4021d102b48SJeremy L Thompson rstr->nelem); 403c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 404*a8d32208Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, rstr->lmode, u, ru, request); 405be9261b7Sjeremylt CeedChk(ierr); 406be9261b7Sjeremylt 407be9261b7Sjeremylt return 0; 408be9261b7Sjeremylt } 409be9261b7Sjeremylt 410be9261b7Sjeremylt /** 411d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 4121469ee4dSjeremylt 4131469ee4dSjeremylt @param rstr CeedElemRestriction 414d9e1f99aSValeria Barra @param[out] mult Vector to store multiplicity (of size nnodes) 4151469ee4dSjeremylt 4161469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 4171469ee4dSjeremylt 4181469ee4dSjeremylt @ref Advanced 4191469ee4dSjeremylt **/ 4201469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 4211469ee4dSjeremylt CeedVector mult) { 4221469ee4dSjeremylt int ierr; 4231469ee4dSjeremylt CeedVector evec; 4241469ee4dSjeremylt 4251469ee4dSjeremylt // Create and set evec 4261469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 4271469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 4281469ee4dSjeremylt 4291469ee4dSjeremylt // Apply to get multiplicity 430*a8d32208Sjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, evec, mult, 431efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 4321469ee4dSjeremylt 4331469ee4dSjeremylt // Cleanup 4341469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 4351469ee4dSjeremylt 4361469ee4dSjeremylt return 0; 4371469ee4dSjeremylt } 4381469ee4dSjeremylt 4391469ee4dSjeremylt /** 4404ce2993fSjeremylt @brief Get the Ceed associated with a CeedElemRestriction 4414ce2993fSjeremylt 4424ce2993fSjeremylt @param rstr CeedElemRestriction 4434ce2993fSjeremylt @param[out] ceed Variable to store Ceed 4444ce2993fSjeremylt 4454ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4464ce2993fSjeremylt 44723617272Sjeremylt @ref Advanced 4484ce2993fSjeremylt **/ 4494ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 4504ce2993fSjeremylt *ceed = rstr->ceed; 4514ce2993fSjeremylt return 0; 4524ce2993fSjeremylt } 4534ce2993fSjeremylt 4544ce2993fSjeremylt /** 455*a8d32208Sjeremylt @brief Get the L-vector layout mode of a CeedElemRestriction 456*a8d32208Sjeremylt 457*a8d32208Sjeremylt @param rstr CeedElemRestriction 458*a8d32208Sjeremylt @param[out] lmode Variable to store lmode 459*a8d32208Sjeremylt 460*a8d32208Sjeremylt @return An error code: 0 - success, otherwise - failure 461*a8d32208Sjeremylt 462*a8d32208Sjeremylt @ref Advanced 463*a8d32208Sjeremylt **/ 464*a8d32208Sjeremylt int CeedElemRestrictionGetLMode(CeedElemRestriction rstr, 465*a8d32208Sjeremylt CeedTransposeMode *lmode) { 466*a8d32208Sjeremylt *lmode = rstr->lmode; 467*a8d32208Sjeremylt return 0; 468*a8d32208Sjeremylt } 469*a8d32208Sjeremylt 470*a8d32208Sjeremylt /** 471b11c1e72Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 472d7b241e6Sjeremylt 4734ce2993fSjeremylt @param rstr CeedElemRestriction 474288c0443SJeremy L Thompson @param[out] numelem Variable to store number of elements 475b11c1e72Sjeremylt 476b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 477dfdf5a53Sjeremylt 47823617272Sjeremylt @ref Advanced 479b11c1e72Sjeremylt **/ 4804ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 4814ce2993fSjeremylt CeedInt *numelem) { 4824ce2993fSjeremylt *numelem = rstr->nelem; 4834ce2993fSjeremylt return 0; 4844ce2993fSjeremylt } 4854ce2993fSjeremylt 4864ce2993fSjeremylt /** 4874ce2993fSjeremylt @brief Get the size of elements in the CeedElemRestriction 4884ce2993fSjeremylt 4894ce2993fSjeremylt @param rstr CeedElemRestriction 4904ce2993fSjeremylt @param[out] elemsize Variable to store size of elements 4914ce2993fSjeremylt 4924ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4934ce2993fSjeremylt 49423617272Sjeremylt @ref Advanced 4954ce2993fSjeremylt **/ 4964ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 4974ce2993fSjeremylt CeedInt *elemsize) { 4984ce2993fSjeremylt *elemsize = rstr->elemsize; 4994ce2993fSjeremylt return 0; 5004ce2993fSjeremylt } 5014ce2993fSjeremylt 5024ce2993fSjeremylt /** 5034ce2993fSjeremylt @brief Get the number of degrees of freedom in the range of a 5044ce2993fSjeremylt CeedElemRestriction 5054ce2993fSjeremylt 5064ce2993fSjeremylt @param rstr CeedElemRestriction 5078795c945Sjeremylt @param[out] numnodes Variable to store number of nodes 5084ce2993fSjeremylt 5094ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5104ce2993fSjeremylt 51123617272Sjeremylt @ref Advanced 5124ce2993fSjeremylt **/ 5138795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr, 5148795c945Sjeremylt CeedInt *numnodes) { 5158795c945Sjeremylt *numnodes = rstr->nnodes; 5164ce2993fSjeremylt return 0; 5174ce2993fSjeremylt } 5184ce2993fSjeremylt 5194ce2993fSjeremylt /** 5204ce2993fSjeremylt @brief Get the number of components in the elements of a 5214ce2993fSjeremylt CeedElemRestriction 5224ce2993fSjeremylt 5234ce2993fSjeremylt @param rstr CeedElemRestriction 5244ce2993fSjeremylt @param[out] numcomp Variable to store number of components 5254ce2993fSjeremylt 5264ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5274ce2993fSjeremylt 52823617272Sjeremylt @ref Advanced 5294ce2993fSjeremylt **/ 5304ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 5314ce2993fSjeremylt CeedInt *numcomp) { 5324ce2993fSjeremylt *numcomp = rstr->ncomp; 5334ce2993fSjeremylt return 0; 5344ce2993fSjeremylt } 5354ce2993fSjeremylt 5364ce2993fSjeremylt /** 5374ce2993fSjeremylt @brief Get the number of blocks in a CeedElemRestriction 5384ce2993fSjeremylt 5394ce2993fSjeremylt @param rstr CeedElemRestriction 5404ce2993fSjeremylt @param[out] numblock Variable to store number of blocks 5414ce2993fSjeremylt 5424ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5434ce2993fSjeremylt 54423617272Sjeremylt @ref Advanced 5454ce2993fSjeremylt **/ 5464ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 5474ce2993fSjeremylt CeedInt *numblock) { 5484ce2993fSjeremylt *numblock = rstr->nblk; 5494ce2993fSjeremylt return 0; 5504ce2993fSjeremylt } 5514ce2993fSjeremylt 5524ce2993fSjeremylt /** 5534ce2993fSjeremylt @brief Get the size of blocks in the CeedElemRestriction 5544ce2993fSjeremylt 555288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5564ce2993fSjeremylt @param[out] blksize Variable to store size of blocks 5574ce2993fSjeremylt 5584ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5594ce2993fSjeremylt 56023617272Sjeremylt @ref Advanced 5614ce2993fSjeremylt **/ 5624ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 5634ce2993fSjeremylt CeedInt *blksize) { 5644ce2993fSjeremylt *blksize = rstr->blksize; 5654ce2993fSjeremylt return 0; 5664ce2993fSjeremylt } 5674ce2993fSjeremylt 5684ce2993fSjeremylt /** 5694ce2993fSjeremylt @brief Get the backend data of a CeedElemRestriction 5704ce2993fSjeremylt 571288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5724ce2993fSjeremylt @param[out] data Variable to store data 5734ce2993fSjeremylt 5744ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5754ce2993fSjeremylt 57623617272Sjeremylt @ref Advanced 5774ce2993fSjeremylt **/ 5781d102b48SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void **data) { 5794ce2993fSjeremylt *data = rstr->data; 580d7b241e6Sjeremylt return 0; 581d7b241e6Sjeremylt } 582d7b241e6Sjeremylt 583d7b241e6Sjeremylt /** 584fe2413ffSjeremylt @brief Set the backend data of a CeedElemRestriction 585fe2413ffSjeremylt 586288c0443SJeremy L Thompson @param[out] rstr CeedElemRestriction 587fe2413ffSjeremylt @param data Data to set 588fe2413ffSjeremylt 589fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 590fe2413ffSjeremylt 591fe2413ffSjeremylt @ref Advanced 592fe2413ffSjeremylt **/ 5931d102b48SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void **data) { 594fe2413ffSjeremylt rstr->data = *data; 595fe2413ffSjeremylt return 0; 596fe2413ffSjeremylt } 597fe2413ffSjeremylt 598fe2413ffSjeremylt /** 599f02ca4a2SJed Brown @brief View a CeedElemRestriction 600f02ca4a2SJed Brown 601f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 602f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 603f02ca4a2SJed Brown 604f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 605f02ca4a2SJed Brown 606f02ca4a2SJed Brown @ref Utility 607f02ca4a2SJed Brown **/ 608f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 6091d102b48SJeremy L Thompson fprintf(stream, "CeedElemRestriction from (%d, %d) to %d elements with %d " 610*a8d32208Sjeremylt "nodes each and L-vector layout %s\n", rstr->nnodes, rstr->ncomp, 611*a8d32208Sjeremylt rstr->nelem, rstr->elemsize, rstr->lmode == CEED_NOTRANSPOSE ? 612*a8d32208Sjeremylt "CEED_NOTRANSPOSE" : "CEED_TRANSPOSE"); 613f02ca4a2SJed Brown return 0; 614f02ca4a2SJed Brown } 615f02ca4a2SJed Brown 616f02ca4a2SJed Brown /** 617b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 618b11c1e72Sjeremylt 6194ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 620b11c1e72Sjeremylt 621b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 622dfdf5a53Sjeremylt 623dfdf5a53Sjeremylt @ref Basic 624b11c1e72Sjeremylt **/ 6254ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 626d7b241e6Sjeremylt int ierr; 627d7b241e6Sjeremylt 6281d102b48SJeremy L Thompson if (!*rstr || --(*rstr)->refcount > 0) 6291d102b48SJeremy L Thompson return 0; 6304ce2993fSjeremylt if ((*rstr)->Destroy) { 6314ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 632d7b241e6Sjeremylt } 6334ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 6344ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 635d7b241e6Sjeremylt return 0; 636d7b241e6Sjeremylt } 637d7b241e6Sjeremylt 638d7b241e6Sjeremylt /// @} 639