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 448795c945Sjeremylt [0, @a nnodes]. 454ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 46b11c1e72Sjeremylt CeedElemRestriction will be stored 47d7b241e6Sjeremylt 48b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 49dfdf5a53Sjeremylt 50dfdf5a53Sjeremylt @ref Basic 51b11c1e72Sjeremylt **/ 52d7b241e6Sjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem, CeedInt elemsize, 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) 64d7b241e6Sjeremylt return CeedError(ceed, 1, "Backend does not support ElemRestrictionCreate"); 655fe0d4faSjeremylt 665fe0d4faSjeremylt ierr = CeedElemRestrictionCreate(delegate, nelem, elemsize, 678795c945Sjeremylt nnodes, ncomp, mtype, cmode, 684ce2993fSjeremylt indices, rstr); CeedChk(ierr); 695fe0d4faSjeremylt return 0; 705fe0d4faSjeremylt } 715fe0d4faSjeremylt 724ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 734ce2993fSjeremylt (*rstr)->ceed = ceed; 74d7b241e6Sjeremylt ceed->refcount++; 754ce2993fSjeremylt (*rstr)->refcount = 1; 764ce2993fSjeremylt (*rstr)->nelem = nelem; 774ce2993fSjeremylt (*rstr)->elemsize = elemsize; 788795c945Sjeremylt (*rstr)->nnodes = nnodes; 794ce2993fSjeremylt (*rstr)->ncomp = ncomp; 804ce2993fSjeremylt (*rstr)->nblk = nelem; 814ce2993fSjeremylt (*rstr)->blksize = 1; 824ce2993fSjeremylt ierr = ceed->ElemRestrictionCreate(mtype, cmode, indices, *rstr); CeedChk(ierr); 83d7b241e6Sjeremylt return 0; 84d7b241e6Sjeremylt } 85d7b241e6Sjeremylt 86d7b241e6Sjeremylt /** 87b11c1e72Sjeremylt @brief Create an identity CeedElemRestriction 88d7b241e6Sjeremylt 89b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 90b11c1e72Sjeremylt @param nelem Number of elements described in the @a indices array 91b11c1e72Sjeremylt @param elemsize Size (number of "nodes") per element 928795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 938795c945Sjeremylt to which the restriction will be applied is of size 948795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 95d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 968795c945Sjeremylt different types of elements. 97b11c1e72Sjeremylt @param ncomp Number of field components per interpolation node 984ce2993fSjeremylt @param rstr Address of the variable where the newly created 99b11c1e72Sjeremylt CeedElemRestriction will be stored 100d7b241e6Sjeremylt 101b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 102dfdf5a53Sjeremylt 103dfdf5a53Sjeremylt @ref Basic 104b11c1e72Sjeremylt **/ 1054b8bea3bSJed Brown int CeedElemRestrictionCreateIdentity(Ceed ceed, CeedInt nelem, 106f90c8643Sjeremylt CeedInt elemsize, CeedInt nnodes, 107f90c8643Sjeremylt CeedInt ncomp, 108f90c8643Sjeremylt CeedElemRestriction *rstr) { 109d7b241e6Sjeremylt int ierr; 110d7b241e6Sjeremylt 1115fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 1125fe0d4faSjeremylt Ceed delegate; 113aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 114aefd8378Sjeremylt CeedChk(ierr); 1155fe0d4faSjeremylt 1165fe0d4faSjeremylt if (!delegate) 1174b8bea3bSJed Brown return CeedError(ceed, 1, 1185fe0d4faSjeremylt "Backend does not support ElemRestrictionCreate"); 1195fe0d4faSjeremylt 1205fe0d4faSjeremylt ierr = CeedElemRestrictionCreateIdentity(delegate, nelem, elemsize, 1218795c945Sjeremylt nnodes, ncomp, rstr); CeedChk(ierr); 1225fe0d4faSjeremylt return 0; 1235fe0d4faSjeremylt } 1245fe0d4faSjeremylt 1254ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 1264ce2993fSjeremylt (*rstr)->ceed = ceed; 127d7b241e6Sjeremylt ceed->refcount++; 1284ce2993fSjeremylt (*rstr)->refcount = 1; 1294ce2993fSjeremylt (*rstr)->nelem = nelem; 1304ce2993fSjeremylt (*rstr)->elemsize = elemsize; 1318795c945Sjeremylt (*rstr)->nnodes = nnodes; 1324ce2993fSjeremylt (*rstr)->ncomp = ncomp; 1334ce2993fSjeremylt (*rstr)->nblk = nelem; 1344ce2993fSjeremylt (*rstr)->blksize = 1; 1351dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 1361dfeef1dSjeremylt *rstr); 1374b8bea3bSJed Brown CeedChk(ierr); 138d7b241e6Sjeremylt return 0; 139d7b241e6Sjeremylt } 140d7b241e6Sjeremylt 141d7b241e6Sjeremylt /** 142b11c1e72Sjeremylt @brief Permute and pad indices for a blocked restriction 143d7b241e6Sjeremylt 1448795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1458795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1468795c945Sjeremylt for the unknowns corresponding to element i, where 1478795c945Sjeremylt 0 <= i < @a nelements. All indices must be in the range 1488795c945Sjeremylt [0, @a nnodes). 149ecf6354eSJed Brown @param blkindices Array of permuted and padded indices of 150ecf6354eSJed Brown shape [@a nblk, @a elemsize, @a blksize]. 151d7b241e6Sjeremylt @param nblk Number of blocks 152d7b241e6Sjeremylt @param nelem Number of elements 153d7b241e6Sjeremylt @param blksize Number of elements in a block 154d7b241e6Sjeremylt @param elemsize Size of each element 155d7b241e6Sjeremylt 156b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 157b11c1e72Sjeremylt 158dfdf5a53Sjeremylt @ref Utility 159b11c1e72Sjeremylt **/ 160dfdf5a53Sjeremylt int CeedPermutePadIndices(const CeedInt *indices, CeedInt *blkindices, 161d7b241e6Sjeremylt CeedInt nblk, CeedInt nelem, 162d7b241e6Sjeremylt CeedInt blksize, CeedInt elemsize) { 163d7b241e6Sjeremylt for (CeedInt e = 0; e < nblk*blksize; e+=blksize) 164d7b241e6Sjeremylt for (int j = 0; j < blksize; j++) 165d7b241e6Sjeremylt for (int k = 0; k < elemsize; k++) 166d7b241e6Sjeremylt blkindices[e*elemsize + k*blksize + j] 167d7b241e6Sjeremylt = indices[CeedIntMin(e+j,nelem-1)*elemsize + k]; 168dfdf5a53Sjeremylt return 0; 169d7b241e6Sjeremylt } 170d7b241e6Sjeremylt 171d7b241e6Sjeremylt /** 172b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 173d7b241e6Sjeremylt 174d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 175d7b241e6Sjeremylt @param nelem Number of elements described in the @a indices array. 176b11c1e72Sjeremylt @param elemsize Size (number of unknowns) per element 177b11c1e72Sjeremylt @param blksize Number of elements in a block 1788795c945Sjeremylt @param nnodes The number of nodes in the L-vector. The input CeedVector 1798795c945Sjeremylt to which the restriction will be applied is of size 1808795c945Sjeremylt @a nnodes * @a ncomp. This size may include data 181d7b241e6Sjeremylt used by other CeedElemRestriction objects describing 182d7b241e6Sjeremylt different types of elements. 183b11c1e72Sjeremylt @param ncomp Number of components stored at each node 184b11c1e72Sjeremylt @param mtype Memory type of the @a indices array, see CeedMemType 185b11c1e72Sjeremylt @param cmode Copy mode for the @a indices array, see CeedCopyMode 1868795c945Sjeremylt @param indices Array of shape [@a nelem, @a elemsize]. Row i holds the 1878795c945Sjeremylt ordered list of the indices (into the input CeedVector) 1888795c945Sjeremylt for the unknowns corresponding to element i, where 1898795c945Sjeremylt 0 <= i < @a nelements. All indices must be in the range 1908795c945Sjeremylt [0, @a nnodes). The backend will permute and pad this 1918795c945Sjeremylt array to the desired ordering for the blocksize, which is 1928795c945Sjeremylt typically given by the backend. The default reordering is 1938795c945Sjeremylt to interlace elements. 1944ce2993fSjeremylt @param rstr Address of the variable where the newly created 195b11c1e72Sjeremylt CeedElemRestriction will be stored 196d7b241e6Sjeremylt 197b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 198dfdf5a53Sjeremylt 199dfdf5a53Sjeremylt @ref Advanced 200b11c1e72Sjeremylt **/ 201d7b241e6Sjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem, CeedInt elemsize, 2028795c945Sjeremylt CeedInt blksize, CeedInt nnodes, 2038795c945Sjeremylt CeedInt ncomp, CeedMemType mtype, 2048795c945Sjeremylt CeedCopyMode cmode, const CeedInt *indices, 2054ce2993fSjeremylt CeedElemRestriction *rstr) { 206d7b241e6Sjeremylt int ierr; 207d7b241e6Sjeremylt CeedInt *blkindices; 208d7b241e6Sjeremylt CeedInt nblk = (nelem / blksize) + !!(nelem % blksize); 209d7b241e6Sjeremylt 2105fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 2115fe0d4faSjeremylt Ceed delegate; 212aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 213aefd8378Sjeremylt CeedChk(ierr); 2145fe0d4faSjeremylt 2155fe0d4faSjeremylt if (!delegate) 216d7b241e6Sjeremylt return CeedError(ceed, 1, 217d7b241e6Sjeremylt "Backend does not support ElemRestrictionCreateBlocked"); 2185fe0d4faSjeremylt 2195fe0d4faSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, nelem, elemsize, 2208795c945Sjeremylt blksize, nnodes, ncomp, mtype, cmode, 2214ce2993fSjeremylt indices, rstr); CeedChk(ierr); 2225fe0d4faSjeremylt return 0; 2235fe0d4faSjeremylt } 224d7b241e6Sjeremylt 2254ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 226d7b241e6Sjeremylt 227d7b241e6Sjeremylt if (indices) { 228de686571SJeremy L Thompson ierr = CeedCalloc(nblk*blksize*elemsize, &blkindices); CeedChk(ierr); 2294b8bea3bSJed Brown ierr = CeedPermutePadIndices(indices, blkindices, nblk, nelem, blksize, 2304b8bea3bSJed Brown elemsize); 231dfdf5a53Sjeremylt CeedChk(ierr); 232d7b241e6Sjeremylt } else { 233d7b241e6Sjeremylt blkindices = NULL; 234d7b241e6Sjeremylt } 235d7b241e6Sjeremylt 2364ce2993fSjeremylt (*rstr)->ceed = ceed; 237d7b241e6Sjeremylt ceed->refcount++; 2384ce2993fSjeremylt (*rstr)->refcount = 1; 2394ce2993fSjeremylt (*rstr)->nelem = nelem; 2404ce2993fSjeremylt (*rstr)->elemsize = elemsize; 2418795c945Sjeremylt (*rstr)->nnodes = nnodes; 2424ce2993fSjeremylt (*rstr)->ncomp = ncomp; 2434ce2993fSjeremylt (*rstr)->nblk = nblk; 2444ce2993fSjeremylt (*rstr)->blksize = blksize; 245667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 2464ce2993fSjeremylt (const CeedInt *) blkindices, *rstr); 247d7b241e6Sjeremylt CeedChk(ierr); 248d7b241e6Sjeremylt 249d7b241e6Sjeremylt if (cmode == CEED_OWN_POINTER) 250d7b241e6Sjeremylt ierr = CeedFree(&indices); CeedChk(ierr); 251d7b241e6Sjeremylt 252d7b241e6Sjeremylt return 0; 253d7b241e6Sjeremylt } 254d7b241e6Sjeremylt 255b11c1e72Sjeremylt /** 256b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 257b11c1e72Sjeremylt 2584ce2993fSjeremylt @param rstr CeedElemRestriction 259b11c1e72Sjeremylt @param lvec The address of the L-vector to be created, or NULL 260b11c1e72Sjeremylt @param evec The address of the E-vector to be created, or NULL 261b11c1e72Sjeremylt 262b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 263dfdf5a53Sjeremylt 264dfdf5a53Sjeremylt @ref Advanced 265b11c1e72Sjeremylt **/ 2664ce2993fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *lvec, 267d7b241e6Sjeremylt CeedVector *evec) { 268d7b241e6Sjeremylt int ierr; 269d7b241e6Sjeremylt CeedInt n, m; 2708795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 2714ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 272d7b241e6Sjeremylt if (lvec) { 2734ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, m, lvec); CeedChk(ierr); 274d7b241e6Sjeremylt } 275d7b241e6Sjeremylt if (evec) { 2764ce2993fSjeremylt ierr = CeedVectorCreate(rstr->ceed, n, evec); CeedChk(ierr); 277d7b241e6Sjeremylt } 278d7b241e6Sjeremylt return 0; 279d7b241e6Sjeremylt } 280d7b241e6Sjeremylt 281d7b241e6Sjeremylt /** 282b11c1e72Sjeremylt @brief Restrict an L-vector to an E-vector or apply transpose 283d7b241e6Sjeremylt 2844ce2993fSjeremylt @param rstr CeedElemRestriction 285d7b241e6Sjeremylt @param tmode Apply restriction or transpose 286d7b241e6Sjeremylt @param lmode Ordering of the ncomp components 2878795c945Sjeremylt @param u Input vector (of size @a nnodes * @a ncomp when 2888795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 2898795c945Sjeremylt @param v Output vector (of size @a nelem * @a elemsize when 2908795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 291d7b241e6Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 292b11c1e72Sjeremylt 293b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 294dfdf5a53Sjeremylt 295dfdf5a53Sjeremylt @ref Advanced 296b11c1e72Sjeremylt **/ 2974ce2993fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode tmode, 298d7b241e6Sjeremylt CeedTransposeMode lmode, 299d7b241e6Sjeremylt CeedVector u, CeedVector v, CeedRequest *request) { 300d7b241e6Sjeremylt CeedInt m,n; 301d7b241e6Sjeremylt int ierr; 302d7b241e6Sjeremylt 303d7b241e6Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 3044ce2993fSjeremylt m = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 3058795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 306d7b241e6Sjeremylt } else { 3078795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 3084ce2993fSjeremylt n = rstr->nblk * rstr->blksize * rstr->elemsize * rstr->ncomp; 309d7b241e6Sjeremylt } 310d7b241e6Sjeremylt if (n != u->length) 3114ce2993fSjeremylt return CeedError(rstr->ceed, 2, 312d7b241e6Sjeremylt "Input vector size %d not compatible with element restriction (%d, %d)", 313d7b241e6Sjeremylt u->length, m, n); 314d7b241e6Sjeremylt if (m != v->length) 3154ce2993fSjeremylt return CeedError(rstr->ceed, 2, 316d7b241e6Sjeremylt "Output vector size %d not compatible with element restriction (%d, %d)", 317d7b241e6Sjeremylt v->length, m, n); 3184ce2993fSjeremylt ierr = rstr->Apply(rstr, tmode, lmode, u, v, request); CeedChk(ierr); 319d7b241e6Sjeremylt 320d7b241e6Sjeremylt return 0; 321d7b241e6Sjeremylt } 322d7b241e6Sjeremylt 323d7b241e6Sjeremylt /** 324be9261b7Sjeremylt @brief Restrict an L-vector to a block of an E-vector or apply transpose 325be9261b7Sjeremylt 326be9261b7Sjeremylt @param rstr CeedElemRestriction 3271f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 3281f37b403Sjeremylt elements [0 : blksize] and block=3 will handle elements 3291f37b403Sjeremylt [3*blksize : 4*blksize] 330be9261b7Sjeremylt @param tmode Apply restriction or transpose 331be9261b7Sjeremylt @param lmode Ordering of the ncomp components 3328795c945Sjeremylt @param u Input vector (of size @a nnodes * @a ncomp when 3338795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 3348795c945Sjeremylt @param v Output vector (of size @a nelem * @a elemsize when 3358795c945Sjeremylt tmode=CEED_NOTRANSPOSE) 336be9261b7Sjeremylt @param request Request or CEED_REQUEST_IMMEDIATE 337be9261b7Sjeremylt 338be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 339be9261b7Sjeremylt 340be9261b7Sjeremylt @ref Advanced 341be9261b7Sjeremylt **/ 342be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 343be9261b7Sjeremylt CeedTransposeMode tmode, 344be9261b7Sjeremylt CeedTransposeMode lmode, 345be9261b7Sjeremylt CeedVector u, CeedVector v, 346be9261b7Sjeremylt CeedRequest *request) { 347be9261b7Sjeremylt CeedInt m,n; 348be9261b7Sjeremylt int ierr; 349be9261b7Sjeremylt 350be9261b7Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 351be9261b7Sjeremylt m = rstr->blksize * rstr->elemsize * rstr->ncomp; 3528795c945Sjeremylt n = rstr->nnodes * rstr->ncomp; 353be9261b7Sjeremylt } else { 3548795c945Sjeremylt m = rstr->nnodes * rstr->ncomp; 355be9261b7Sjeremylt n = rstr->blksize * rstr->elemsize * rstr->ncomp; 356be9261b7Sjeremylt } 357be9261b7Sjeremylt if (n != u->length) 358be9261b7Sjeremylt return CeedError(rstr->ceed, 2, 359be9261b7Sjeremylt "Input vector size %d not compatible with element restriction (%d, %d)", 360be9261b7Sjeremylt u->length, m, n); 361be9261b7Sjeremylt if (m != v->length) 362be9261b7Sjeremylt return CeedError(rstr->ceed, 2, 363be9261b7Sjeremylt "Output vector size %d not compatible with element restriction (%d, %d)", 364be9261b7Sjeremylt v->length, m, n); 365be9261b7Sjeremylt if (rstr->blksize*block > rstr->nelem) 366be9261b7Sjeremylt return CeedError(rstr->ceed, 2, 367be9261b7Sjeremylt "Cannot retrieve block %d, element %d > total elements %d", 368be9261b7Sjeremylt block, rstr->blksize*block, rstr->nelem); 369be9261b7Sjeremylt ierr = rstr->ApplyBlock(rstr, block, tmode, lmode, u, v, request); 370be9261b7Sjeremylt CeedChk(ierr); 371be9261b7Sjeremylt 372be9261b7Sjeremylt return 0; 373be9261b7Sjeremylt } 374be9261b7Sjeremylt 375be9261b7Sjeremylt /** 3761469ee4dSjeremylt @brief Get the multiplicity of DoFs in a CeedElemRestriction 3771469ee4dSjeremylt 3781469ee4dSjeremylt @param rstr CeedElemRestriction 3791469ee4dSjeremylt @param[out] mult Vector to store multiplicity (of size ndof) 3801469ee4dSjeremylt 3811469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 3821469ee4dSjeremylt 3831469ee4dSjeremylt @ref Advanced 3841469ee4dSjeremylt **/ 3851469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 3861469ee4dSjeremylt CeedVector mult) { 3871469ee4dSjeremylt int ierr; 3881469ee4dSjeremylt CeedVector evec; 3891469ee4dSjeremylt 3901469ee4dSjeremylt // Create and set evec 3911469ee4dSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &evec); CeedChk(ierr); 3921469ee4dSjeremylt ierr = CeedVectorSetValue(evec, 1.0); CeedChk(ierr); 3931469ee4dSjeremylt 3941469ee4dSjeremylt // Apply to get multiplicity 3951469ee4dSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, CEED_NOTRANSPOSE, evec, 3961469ee4dSjeremylt mult, CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 3971469ee4dSjeremylt 3981469ee4dSjeremylt // Cleanup 3991469ee4dSjeremylt ierr = CeedVectorDestroy(&evec); CeedChk(ierr); 4001469ee4dSjeremylt 4011469ee4dSjeremylt return 0; 4021469ee4dSjeremylt } 4031469ee4dSjeremylt 4041469ee4dSjeremylt /** 4054ce2993fSjeremylt @brief Get the Ceed associated with a CeedElemRestriction 4064ce2993fSjeremylt 4074ce2993fSjeremylt @param rstr CeedElemRestriction 4084ce2993fSjeremylt @param[out] ceed Variable to store Ceed 4094ce2993fSjeremylt 4104ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4114ce2993fSjeremylt 41223617272Sjeremylt @ref Advanced 4134ce2993fSjeremylt **/ 4144ce2993fSjeremylt int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 4154ce2993fSjeremylt *ceed = rstr->ceed; 4164ce2993fSjeremylt return 0; 4174ce2993fSjeremylt } 4184ce2993fSjeremylt 4194ce2993fSjeremylt /** 420b11c1e72Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 421d7b241e6Sjeremylt 4224ce2993fSjeremylt @param rstr CeedElemRestriction 423*288c0443SJeremy L Thompson @param[out] numelem Variable to store number of elements 424b11c1e72Sjeremylt 425b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 426dfdf5a53Sjeremylt 42723617272Sjeremylt @ref Advanced 428b11c1e72Sjeremylt **/ 4294ce2993fSjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 4304ce2993fSjeremylt CeedInt *numelem) { 4314ce2993fSjeremylt *numelem = rstr->nelem; 4324ce2993fSjeremylt return 0; 4334ce2993fSjeremylt } 4344ce2993fSjeremylt 4354ce2993fSjeremylt /** 4364ce2993fSjeremylt @brief Get the size of elements in the CeedElemRestriction 4374ce2993fSjeremylt 4384ce2993fSjeremylt @param rstr CeedElemRestriction 4394ce2993fSjeremylt @param[out] elemsize Variable to store size of elements 4404ce2993fSjeremylt 4414ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4424ce2993fSjeremylt 44323617272Sjeremylt @ref Advanced 4444ce2993fSjeremylt **/ 4454ce2993fSjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 4464ce2993fSjeremylt CeedInt *elemsize) { 4474ce2993fSjeremylt *elemsize = rstr->elemsize; 4484ce2993fSjeremylt return 0; 4494ce2993fSjeremylt } 4504ce2993fSjeremylt 4514ce2993fSjeremylt /** 4524ce2993fSjeremylt @brief Get the number of degrees of freedom in the range of a 4534ce2993fSjeremylt CeedElemRestriction 4544ce2993fSjeremylt 4554ce2993fSjeremylt @param rstr CeedElemRestriction 4568795c945Sjeremylt @param[out] numnodes Variable to store number of nodes 4574ce2993fSjeremylt 4584ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4594ce2993fSjeremylt 46023617272Sjeremylt @ref Advanced 4614ce2993fSjeremylt **/ 4628795c945Sjeremylt int CeedElemRestrictionGetNumNodes(CeedElemRestriction rstr, 4638795c945Sjeremylt CeedInt *numnodes) { 4648795c945Sjeremylt *numnodes = rstr->nnodes; 4654ce2993fSjeremylt return 0; 4664ce2993fSjeremylt } 4674ce2993fSjeremylt 4684ce2993fSjeremylt /** 4694ce2993fSjeremylt @brief Get the number of components in the elements of a 4704ce2993fSjeremylt CeedElemRestriction 4714ce2993fSjeremylt 4724ce2993fSjeremylt @param rstr CeedElemRestriction 4734ce2993fSjeremylt @param[out] numcomp Variable to store number of components 4744ce2993fSjeremylt 4754ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4764ce2993fSjeremylt 47723617272Sjeremylt @ref Advanced 4784ce2993fSjeremylt **/ 4794ce2993fSjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 4804ce2993fSjeremylt CeedInt *numcomp) { 4814ce2993fSjeremylt *numcomp = rstr->ncomp; 4824ce2993fSjeremylt return 0; 4834ce2993fSjeremylt } 4844ce2993fSjeremylt 4854ce2993fSjeremylt /** 4864ce2993fSjeremylt @brief Get the number of blocks in a CeedElemRestriction 4874ce2993fSjeremylt 4884ce2993fSjeremylt @param rstr CeedElemRestriction 4894ce2993fSjeremylt @param[out] numblock Variable to store number of blocks 4904ce2993fSjeremylt 4914ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4924ce2993fSjeremylt 49323617272Sjeremylt @ref Advanced 4944ce2993fSjeremylt **/ 4954ce2993fSjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 4964ce2993fSjeremylt CeedInt *numblock) { 4974ce2993fSjeremylt *numblock = rstr->nblk; 4984ce2993fSjeremylt return 0; 4994ce2993fSjeremylt } 5004ce2993fSjeremylt 5014ce2993fSjeremylt /** 5024ce2993fSjeremylt @brief Get the size of blocks in the CeedElemRestriction 5034ce2993fSjeremylt 504*288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5054ce2993fSjeremylt @param[out] blksize Variable to store size of blocks 5064ce2993fSjeremylt 5074ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5084ce2993fSjeremylt 50923617272Sjeremylt @ref Advanced 5104ce2993fSjeremylt **/ 5114ce2993fSjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 5124ce2993fSjeremylt CeedInt *blksize) { 5134ce2993fSjeremylt *blksize = rstr->blksize; 5144ce2993fSjeremylt return 0; 5154ce2993fSjeremylt } 5164ce2993fSjeremylt 5174ce2993fSjeremylt /** 5184ce2993fSjeremylt @brief Get the backend data of a CeedElemRestriction 5194ce2993fSjeremylt 520*288c0443SJeremy L Thompson @param rstr CeedElemRestriction 5214ce2993fSjeremylt @param[out] data Variable to store data 5224ce2993fSjeremylt 5234ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5244ce2993fSjeremylt 52523617272Sjeremylt @ref Advanced 5264ce2993fSjeremylt **/ 5274ce2993fSjeremylt int CeedElemRestrictionGetData(CeedElemRestriction rstr, 5284ce2993fSjeremylt void* *data) { 5294ce2993fSjeremylt *data = rstr->data; 530d7b241e6Sjeremylt return 0; 531d7b241e6Sjeremylt } 532d7b241e6Sjeremylt 533d7b241e6Sjeremylt /** 534fe2413ffSjeremylt @brief Set the backend data of a CeedElemRestriction 535fe2413ffSjeremylt 536*288c0443SJeremy L Thompson @param[out] rstr CeedElemRestriction 537fe2413ffSjeremylt @param data Data to set 538fe2413ffSjeremylt 539fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 540fe2413ffSjeremylt 541fe2413ffSjeremylt @ref Advanced 542fe2413ffSjeremylt **/ 543fe2413ffSjeremylt int CeedElemRestrictionSetData(CeedElemRestriction rstr, 544fe2413ffSjeremylt void* *data) { 545fe2413ffSjeremylt rstr->data = *data; 546fe2413ffSjeremylt return 0; 547fe2413ffSjeremylt } 548fe2413ffSjeremylt 549fe2413ffSjeremylt /** 550f02ca4a2SJed Brown @brief View a CeedElemRestriction 551f02ca4a2SJed Brown 552f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 553f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 554f02ca4a2SJed Brown 555f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 556f02ca4a2SJed Brown 557f02ca4a2SJed Brown @ref Utility 558f02ca4a2SJed Brown **/ 559f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 560f02ca4a2SJed Brown fprintf(stream, 561f02ca4a2SJed Brown "CeedElemRestriction from (%d, %d) to %d elements with %d nodes each\n", 5628795c945Sjeremylt rstr->nnodes, rstr->ncomp, rstr->nelem, rstr->elemsize); 563f02ca4a2SJed Brown return 0; 564f02ca4a2SJed Brown } 565f02ca4a2SJed Brown 566f02ca4a2SJed Brown /** 567b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 568b11c1e72Sjeremylt 5694ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 570b11c1e72Sjeremylt 571b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 572dfdf5a53Sjeremylt 573dfdf5a53Sjeremylt @ref Basic 574b11c1e72Sjeremylt **/ 5754ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 576d7b241e6Sjeremylt int ierr; 577d7b241e6Sjeremylt 5784ce2993fSjeremylt if (!*rstr || --(*rstr)->refcount > 0) return 0; 5794ce2993fSjeremylt if ((*rstr)->Destroy) { 5804ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 581d7b241e6Sjeremylt } 5824ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 5834ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 584d7b241e6Sjeremylt return 0; 585d7b241e6Sjeremylt } 586d7b241e6Sjeremylt 587d7b241e6Sjeremylt /// @} 588