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 17ec3da8bcSJed Brown #include <ceed/ceed.h> 18ec3da8bcSJed Brown #include <ceed/backend.h> 193d576824SJeremy L Thompson #include <ceed-impl.h> 203d576824SJeremy L Thompson #include <stdbool.h> 213d576824SJeremy L Thompson #include <stdio.h> 22d7b241e6Sjeremylt 237a982d89SJeremy L. Thompson /// @file 247a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces 257a982d89SJeremy L. Thompson 267a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 277a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions 287a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 297a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper 307a982d89SJeremy L. Thompson /// @{ 317a982d89SJeremy L. Thompson 327a982d89SJeremy L. Thompson /** 33d979a051Sjeremylt @brief Permute and pad offsets for a blocked restriction 347a982d89SJeremy L. Thompson 35d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 36d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 377a982d89SJeremy L. Thompson for the unknowns corresponding to element i, where 38d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 39d1d35e2fSjeremylt [0, @a l_size - 1]. 40d1d35e2fSjeremylt @param blk_offsets Array of permuted and padded offsets of 41d1d35e2fSjeremylt shape [@a num_blk, @a elem_size, @a blk_size]. 42d1d35e2fSjeremylt @param num_blk Number of blocks 43d1d35e2fSjeremylt @param num_elem Number of elements 44d1d35e2fSjeremylt @param blk_size Number of elements in a block 45d1d35e2fSjeremylt @param elem_size Size of each element 467a982d89SJeremy L. Thompson 477a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 487a982d89SJeremy L. Thompson 497a982d89SJeremy L. Thompson @ref Utility 507a982d89SJeremy L. Thompson **/ 51d1d35e2fSjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, 52d1d35e2fSjeremylt CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, 53d1d35e2fSjeremylt CeedInt elem_size) { 54d1d35e2fSjeremylt for (CeedInt e=0; e<num_blk*blk_size; e+=blk_size) 55d1d35e2fSjeremylt for (int j=0; j<blk_size; j++) 56d1d35e2fSjeremylt for (int k=0; k<elem_size; k++) 57d1d35e2fSjeremylt blk_offsets[e*elem_size + k*blk_size + j] 58d1d35e2fSjeremylt = offsets[CeedIntMin(e+j,num_elem-1)*elem_size + k]; 59e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 607a982d89SJeremy L. Thompson } 617a982d89SJeremy L. Thompson 627a982d89SJeremy L. Thompson /// @} 637a982d89SJeremy L. Thompson 647a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 657a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 667a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 677a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 687a982d89SJeremy L. Thompson /// @{ 697a982d89SJeremy L. Thompson 707a982d89SJeremy L. Thompson /** 717a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedElemRestriction 727a982d89SJeremy L. Thompson 737a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 747a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 757a982d89SJeremy L. Thompson 767a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 777a982d89SJeremy L. Thompson 787a982d89SJeremy L. Thompson @ref Backend 797a982d89SJeremy L. Thompson **/ 807a982d89SJeremy L. Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 817a982d89SJeremy L. Thompson *ceed = rstr->ceed; 82e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 837a982d89SJeremy L. Thompson } 847a982d89SJeremy L. Thompson 857a982d89SJeremy L. Thompson /** 86a681ae63Sjeremylt 87a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 887a982d89SJeremy L. Thompson 897a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 90a681ae63Sjeremylt @param[out] strides Variable to store strides array 917a982d89SJeremy L. Thompson 927a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 937a982d89SJeremy L. Thompson 947a982d89SJeremy L. Thompson @ref Backend 957a982d89SJeremy L. Thompson **/ 96a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 97a681ae63Sjeremylt CeedInt (*strides)[3]) { 98a681ae63Sjeremylt if (!rstr->strides) 99a681ae63Sjeremylt // LCOV_EXCL_START 100e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 101e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 102a681ae63Sjeremylt // LCOV_EXCL_STOP 103a681ae63Sjeremylt 104a681ae63Sjeremylt for (int i=0; i<3; i++) 105a681ae63Sjeremylt (*strides)[i] = rstr->strides[i]; 106e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1077a982d89SJeremy L. Thompson } 1087a982d89SJeremy L. Thompson 1097a982d89SJeremy L. Thompson /** 110bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 111bd33150aSjeremylt 112bd33150aSjeremylt @param rstr CeedElemRestriction to retrieve offsets 113d1d35e2fSjeremylt @param mem_type Memory type on which to access the array. If the backend 114bd33150aSjeremylt uses a different memory type, this will perform a copy 115bd33150aSjeremylt (possibly cached). 116d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 117bd33150aSjeremylt 118bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 119bd33150aSjeremylt 120bd33150aSjeremylt @ref User 121bd33150aSjeremylt **/ 122d1d35e2fSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, 123d1d35e2fSjeremylt CeedMemType mem_type, 124bd33150aSjeremylt const CeedInt **offsets) { 125bd33150aSjeremylt int ierr; 126bd33150aSjeremylt 127bd33150aSjeremylt if (!rstr->GetOffsets) 128bd33150aSjeremylt // LCOV_EXCL_START 129e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED, 130e15f9bd0SJeremy L Thompson "Backend does not support GetOffsets"); 131bd33150aSjeremylt // LCOV_EXCL_STOP 132bd33150aSjeremylt 133d1d35e2fSjeremylt ierr = rstr->GetOffsets(rstr, mem_type, offsets); CeedChk(ierr); 134d1d35e2fSjeremylt rstr->num_readers++; 135e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 136430758c8SJeremy L Thompson } 137430758c8SJeremy L Thompson 138430758c8SJeremy L Thompson /** 139430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 140430758c8SJeremy L Thompson 141430758c8SJeremy L Thompson @param rstr CeedElemRestriction to restore 142430758c8SJeremy L Thompson @param offsets Array of offset data 143430758c8SJeremy L Thompson 144430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 145430758c8SJeremy L Thompson 146430758c8SJeremy L Thompson @ref User 147430758c8SJeremy L Thompson **/ 148430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, 149430758c8SJeremy L Thompson const CeedInt **offsets) { 150430758c8SJeremy L Thompson *offsets = NULL; 151d1d35e2fSjeremylt rstr->num_readers--; 152e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 153bd33150aSjeremylt } 154bd33150aSjeremylt 155bd33150aSjeremylt /** 1563ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1573ac43b2cSJeremy L Thompson 1583ac43b2cSJeremy L Thompson @param rstr CeedElemRestriction 159d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1603ac43b2cSJeremy L Thompson 1613ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1623ac43b2cSJeremy L Thompson 1633ac43b2cSJeremy L Thompson @ref Backend 1643ac43b2cSJeremy L Thompson **/ 165d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 166d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 167e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1683ac43b2cSJeremy L Thompson } 1693ac43b2cSJeremy L Thompson 1703ac43b2cSJeremy L Thompson /** 171a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1727a982d89SJeremy L. Thompson 1737a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 17496b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1757a982d89SJeremy L. Thompson 1767a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1777a982d89SJeremy L. Thompson 1787a982d89SJeremy L. Thompson @ref Backend 1797a982d89SJeremy L. Thompson **/ 180fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, 181d1d35e2fSjeremylt bool *has_backend_strides) { 182a681ae63Sjeremylt if (!rstr->strides) 183a681ae63Sjeremylt // LCOV_EXCL_START 184e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 185e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 186a681ae63Sjeremylt // LCOV_EXCL_STOP 1877a982d89SJeremy L. Thompson 188d1d35e2fSjeremylt *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 189a681ae63Sjeremylt (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 190a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 191e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1927a982d89SJeremy L. Thompson } 1937a982d89SJeremy L. Thompson 1947a982d89SJeremy L. Thompson /** 19549fd234cSJeremy L Thompson 19649fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 19749fd234cSJeremy L Thompson 19849fd234cSJeremy L Thompson @param rstr CeedElemRestriction 19949fd234cSJeremy L Thompson @param[out] layout Variable to store layout array, 20049fd234cSJeremy L Thompson stored as [nodes, components, elements]. 20149fd234cSJeremy L Thompson The data for node i, component j, element k in the 20249fd234cSJeremy L Thompson E-vector is given by 20395e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 20449fd234cSJeremy L Thompson 20549fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20649fd234cSJeremy L Thompson 20749fd234cSJeremy L Thompson @ref Backend 20849fd234cSJeremy L Thompson **/ 20949fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, 21049fd234cSJeremy L Thompson CeedInt (*layout)[3]) { 21149fd234cSJeremy L Thompson if (!rstr->layout[0]) 21249fd234cSJeremy L Thompson // LCOV_EXCL_START 213e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 214e15f9bd0SJeremy L Thompson "ElemRestriction has no layout data"); 21549fd234cSJeremy L Thompson // LCOV_EXCL_STOP 21649fd234cSJeremy L Thompson 21749fd234cSJeremy L Thompson for (int i=0; i<3; i++) 21849fd234cSJeremy L Thompson (*layout)[i] = rstr->layout[i]; 219e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 22049fd234cSJeremy L Thompson } 22149fd234cSJeremy L Thompson 22249fd234cSJeremy L Thompson /** 22349fd234cSJeremy L Thompson 22449fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 22549fd234cSJeremy L Thompson 22649fd234cSJeremy L Thompson @param rstr CeedElemRestriction 22749fd234cSJeremy L Thompson @param layout Variable to containing layout array, 22849fd234cSJeremy L Thompson stored as [nodes, components, elements]. 22949fd234cSJeremy L Thompson The data for node i, component j, element k in the 23049fd234cSJeremy L Thompson E-vector is given by 23195e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 23249fd234cSJeremy L Thompson 23349fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23449fd234cSJeremy L Thompson 23549fd234cSJeremy L Thompson @ref Backend 23649fd234cSJeremy L Thompson **/ 23749fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, 23849fd234cSJeremy L Thompson CeedInt layout[3]) { 23949fd234cSJeremy L Thompson for (int i = 0; i<3; i++) 24049fd234cSJeremy L Thompson rstr->layout[i] = layout[i]; 241e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 24249fd234cSJeremy L Thompson } 24349fd234cSJeremy L Thompson 24449fd234cSJeremy L Thompson /** 2457a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2467a982d89SJeremy L. Thompson 2477a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 2487a982d89SJeremy L. Thompson @param[out] data Variable to store data 2497a982d89SJeremy L. Thompson 2507a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2517a982d89SJeremy L. Thompson 2527a982d89SJeremy L. Thompson @ref Backend 2537a982d89SJeremy L. Thompson **/ 254777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 255777ff853SJeremy L Thompson *(void **)data = rstr->data; 256e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2577a982d89SJeremy L. Thompson } 2587a982d89SJeremy L. Thompson 2597a982d89SJeremy L. Thompson /** 2607a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2617a982d89SJeremy L. Thompson 2627a982d89SJeremy L. Thompson @param[out] rstr CeedElemRestriction 2637a982d89SJeremy L. Thompson @param data Data to set 2647a982d89SJeremy L. Thompson 2657a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2667a982d89SJeremy L. Thompson 2677a982d89SJeremy L. Thompson @ref Backend 2687a982d89SJeremy L. Thompson **/ 269777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 270777ff853SJeremy L Thompson rstr->data = data; 271e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2727a982d89SJeremy L. Thompson } 2737a982d89SJeremy L. Thompson 27434359f16Sjeremylt /** 27534359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 27634359f16Sjeremylt 27734359f16Sjeremylt @param rstr ElemRestriction to increment the reference counter 27834359f16Sjeremylt 27934359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 28034359f16Sjeremylt 28134359f16Sjeremylt @ref Backend 28234359f16Sjeremylt **/ 2839560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 28434359f16Sjeremylt rstr->ref_count++; 28534359f16Sjeremylt return CEED_ERROR_SUCCESS; 28634359f16Sjeremylt } 28734359f16Sjeremylt 2887a982d89SJeremy L. Thompson /// @} 2897a982d89SJeremy L. Thompson 29015910d16Sjeremylt /// @cond DOXYGEN_SKIP 29115910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 29215910d16Sjeremylt /// @endcond 29315910d16Sjeremylt 2947a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2957a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2967a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2977a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 298d7b241e6Sjeremylt /// @{ 299d7b241e6Sjeremylt 3007a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 3017a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {}; 3027a982d89SJeremy L. Thompson 3034cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 3047a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 3057a982d89SJeremy L. Thompson &ceed_elemrestriction_none; 3067a982d89SJeremy L. Thompson 307d7b241e6Sjeremylt /** 308b11c1e72Sjeremylt @brief Create a CeedElemRestriction 309d7b241e6Sjeremylt 310b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 311d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array 312d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 313d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 31495bb1877Svaleriabarra (1 for scalar fields) 315d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 31695e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 31795e93d34SJeremy L Thompson the L-vector at index 318d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 319d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 320d979a051Sjeremylt the elements and fields given by this restriction. 321d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 322d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 323d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 324d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3258795c945Sjeremylt for the unknowns corresponding to element i, where 326d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 327d1d35e2fSjeremylt [0, @a l_size - 1]. 3284ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 329b11c1e72Sjeremylt CeedElemRestriction will be stored 330d7b241e6Sjeremylt 331b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 332dfdf5a53Sjeremylt 3337a982d89SJeremy L. Thompson @ref User 334b11c1e72Sjeremylt **/ 335d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, 336d1d35e2fSjeremylt CeedInt num_comp, CeedInt comp_stride, 337d1d35e2fSjeremylt CeedInt l_size, CeedMemType mem_type, 338d1d35e2fSjeremylt CeedCopyMode copy_mode, const CeedInt *offsets, 3394ce2993fSjeremylt CeedElemRestriction *rstr) { 340d7b241e6Sjeremylt int ierr; 341d7b241e6Sjeremylt 3425fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3435fe0d4faSjeremylt Ceed delegate; 344aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 345aefd8378Sjeremylt CeedChk(ierr); 3465fe0d4faSjeremylt 3475fe0d4faSjeremylt if (!delegate) 348c042f62fSJeremy L Thompson // LCOV_EXCL_START 349e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 350e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 351c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3525fe0d4faSjeremylt 353d1d35e2fSjeremylt ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, 354d1d35e2fSjeremylt comp_stride, l_size, mem_type, copy_mode, 355d979a051Sjeremylt offsets, rstr); CeedChk(ierr); 356e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3575fe0d4faSjeremylt } 3585fe0d4faSjeremylt 3594ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3604ce2993fSjeremylt (*rstr)->ceed = ceed; 3619560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 362d1d35e2fSjeremylt (*rstr)->ref_count = 1; 363d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 364d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 365d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 366d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 367d1d35e2fSjeremylt (*rstr)->l_size = l_size; 368d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 369d1d35e2fSjeremylt (*rstr)->blk_size = 1; 370d1d35e2fSjeremylt ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr); 371d979a051Sjeremylt CeedChk(ierr); 372e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 373d7b241e6Sjeremylt } 374d7b241e6Sjeremylt 375d7b241e6Sjeremylt /** 3767509a596Sjeremylt @brief Create a strided CeedElemRestriction 377d7b241e6Sjeremylt 378b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 379d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 380d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 381d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 38295bb1877Svaleriabarra (1 for scalar fields) 383d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 384d979a051Sjeremylt the elements and fields given by this restriction. 3857509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 38695e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 38795e93d34SJeremy L Thompson the L-vector at index 38895e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 38995e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 39095e93d34SJeremy L Thompson by a Ceed backend. 3914ce2993fSjeremylt @param rstr Address of the variable where the newly created 392b11c1e72Sjeremylt CeedElemRestriction will be stored 393d7b241e6Sjeremylt 394b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 395dfdf5a53Sjeremylt 3967a982d89SJeremy L. Thompson @ref User 397b11c1e72Sjeremylt **/ 398d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, 399d1d35e2fSjeremylt CeedInt elem_size, 400d1d35e2fSjeremylt CeedInt num_comp, CeedInt l_size, 4018621c6c6SJeremy L Thompson const CeedInt strides[3], 402f90c8643Sjeremylt CeedElemRestriction *rstr) { 403d7b241e6Sjeremylt int ierr; 404d7b241e6Sjeremylt 4055fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4065fe0d4faSjeremylt Ceed delegate; 407aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 408aefd8378Sjeremylt CeedChk(ierr); 4095fe0d4faSjeremylt 4105fe0d4faSjeremylt if (!delegate) 411c042f62fSJeremy L Thompson // LCOV_EXCL_START 412e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 413e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 414c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4155fe0d4faSjeremylt 416d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, 417d1d35e2fSjeremylt l_size, strides, rstr); 418d979a051Sjeremylt CeedChk(ierr); 419e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4205fe0d4faSjeremylt } 4215fe0d4faSjeremylt 4224ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 4234ce2993fSjeremylt (*rstr)->ceed = ceed; 4249560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 425d1d35e2fSjeremylt (*rstr)->ref_count = 1; 426d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 427d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 428d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 429d1d35e2fSjeremylt (*rstr)->l_size = l_size; 430d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 431d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4327509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 4337509a596Sjeremylt for (int i=0; i<3; i++) 4347509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 4351dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 4361dfeef1dSjeremylt *rstr); 4374b8bea3bSJed Brown CeedChk(ierr); 438e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 439d7b241e6Sjeremylt } 440d7b241e6Sjeremylt 441d7b241e6Sjeremylt /** 442b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 443d7b241e6Sjeremylt 444d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 445d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 446d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 447d1d35e2fSjeremylt @param blk_size Number of elements in a block 448d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 44995bb1877Svaleriabarra (1 for scalar fields) 450d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 45195e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 45295e93d34SJeremy L Thompson the L-vector at index 453d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 454d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 455d979a051Sjeremylt the elements and fields given by this restriction. 456d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 457d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 458d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 459d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 4608795c945Sjeremylt for the unknowns corresponding to element i, where 461d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 462d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 4638795c945Sjeremylt array to the desired ordering for the blocksize, which is 4648795c945Sjeremylt typically given by the backend. The default reordering is 4658795c945Sjeremylt to interlace elements. 4664ce2993fSjeremylt @param rstr Address of the variable where the newly created 467b11c1e72Sjeremylt CeedElemRestriction will be stored 468d7b241e6Sjeremylt 469b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 470dfdf5a53Sjeremylt 4717a982d89SJeremy L. Thompson @ref Backend 472b11c1e72Sjeremylt **/ 473d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, 474d1d35e2fSjeremylt CeedInt elem_size, 475d1d35e2fSjeremylt CeedInt blk_size, CeedInt num_comp, 476d1d35e2fSjeremylt CeedInt comp_stride, CeedInt l_size, 477d1d35e2fSjeremylt CeedMemType mem_type, CeedCopyMode copy_mode, 478d979a051Sjeremylt const CeedInt *offsets, 4794ce2993fSjeremylt CeedElemRestriction *rstr) { 480d7b241e6Sjeremylt int ierr; 481d1d35e2fSjeremylt CeedInt *blk_offsets; 482d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 483d7b241e6Sjeremylt 4845fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 4855fe0d4faSjeremylt Ceed delegate; 486aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 487aefd8378Sjeremylt CeedChk(ierr); 4885fe0d4faSjeremylt 4895fe0d4faSjeremylt if (!delegate) 490c042f62fSJeremy L Thompson // LCOV_EXCL_START 491e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 4921d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 493c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4945fe0d4faSjeremylt 495d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, 496d1d35e2fSjeremylt num_comp, comp_stride, l_size, mem_type, 497d1d35e2fSjeremylt copy_mode, offsets, rstr); 498d979a051Sjeremylt CeedChk(ierr); 499e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5005fe0d4faSjeremylt } 501d7b241e6Sjeremylt 5024ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 503d7b241e6Sjeremylt 504d1d35e2fSjeremylt ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr); 505d1d35e2fSjeremylt ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, 506d1d35e2fSjeremylt elem_size); CeedChk(ierr); 507d7b241e6Sjeremylt 5084ce2993fSjeremylt (*rstr)->ceed = ceed; 5099560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 510d1d35e2fSjeremylt (*rstr)->ref_count = 1; 511d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 512d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 513d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 514d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 515d1d35e2fSjeremylt (*rstr)->l_size = l_size; 516d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 517d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 518667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 519d1d35e2fSjeremylt (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr); 520d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 521d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 5221d102b48SJeremy L Thompson } 523e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 524d7b241e6Sjeremylt } 525d7b241e6Sjeremylt 526b11c1e72Sjeremylt /** 5277509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5287509a596Sjeremylt 5297509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 530d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 531d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 532d1d35e2fSjeremylt @param blk_size Number of elements in a block 533d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 5347509a596Sjeremylt (1 for scalar fields) 535d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 536d979a051Sjeremylt the elements and fields given by this restriction. 5377509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 53895e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 53995e93d34SJeremy L Thompson the L-vector at index 54095e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 54195e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 54295e93d34SJeremy L Thompson by a Ceed backend. 5437509a596Sjeremylt @param rstr Address of the variable where the newly created 5447509a596Sjeremylt CeedElemRestriction will be stored 5457509a596Sjeremylt 5467509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 5477509a596Sjeremylt 5487a982d89SJeremy L. Thompson @ref User 5497509a596Sjeremylt **/ 550d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, 551d1d35e2fSjeremylt CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt l_size, 5528621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 5537509a596Sjeremylt int ierr; 554d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 5557509a596Sjeremylt 5567509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5577509a596Sjeremylt Ceed delegate; 5587509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 5597509a596Sjeremylt CeedChk(ierr); 5607509a596Sjeremylt 5617509a596Sjeremylt if (!delegate) 5627509a596Sjeremylt // LCOV_EXCL_START 563e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 5647509a596Sjeremylt "ElemRestrictionCreateBlocked"); 5657509a596Sjeremylt // LCOV_EXCL_STOP 5667509a596Sjeremylt 567d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, 568d1d35e2fSjeremylt blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr); 569e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5707509a596Sjeremylt } 5717509a596Sjeremylt 5727509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 5737509a596Sjeremylt 5747509a596Sjeremylt (*rstr)->ceed = ceed; 5759560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 576d1d35e2fSjeremylt (*rstr)->ref_count = 1; 577d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 578d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 579d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 580d1d35e2fSjeremylt (*rstr)->l_size = l_size; 581d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 582d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5837509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 5847509a596Sjeremylt for (int i=0; i<3; i++) 5857509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 5867509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 5877509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 588e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5897509a596Sjeremylt } 5907509a596Sjeremylt 5917509a596Sjeremylt /** 5929560d06aSjeremylt @brief Copy the pointer to a CeedElemRestriction. Both pointers should 5939560d06aSjeremylt be destroyed with `CeedElemRestrictionDestroy()`; 5949560d06aSjeremylt Note: If `*rstr_copy` is non-NULL, then it is assumed that 5959560d06aSjeremylt `*rstr_copy` is a pointer to a CeedElemRestriction. This 5969560d06aSjeremylt CeedElemRestriction will be destroyed if `*rstr_copy` is the 5979560d06aSjeremylt only reference to this CeedElemRestriction. 5989560d06aSjeremylt 5999560d06aSjeremylt @param rstr CeedElemRestriction to copy reference to 6009560d06aSjeremylt @param[out] rstr_copy Variable to store copied reference 6019560d06aSjeremylt 6029560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6039560d06aSjeremylt 6049560d06aSjeremylt @ref User 6059560d06aSjeremylt **/ 6069560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, 6079560d06aSjeremylt CeedElemRestriction *rstr_copy) { 6089560d06aSjeremylt int ierr; 6099560d06aSjeremylt 6109560d06aSjeremylt ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr); 6119560d06aSjeremylt ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr); 6129560d06aSjeremylt *rstr_copy = rstr; 6139560d06aSjeremylt return CEED_ERROR_SUCCESS; 6149560d06aSjeremylt } 6159560d06aSjeremylt 6169560d06aSjeremylt /** 617b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 618b11c1e72Sjeremylt 6194ce2993fSjeremylt @param rstr CeedElemRestriction 620d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 621d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 622b11c1e72Sjeremylt 623b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 624dfdf5a53Sjeremylt 6257a982d89SJeremy L. Thompson @ref User 626b11c1e72Sjeremylt **/ 627d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, 628d1d35e2fSjeremylt CeedVector *e_vec) { 629d7b241e6Sjeremylt int ierr; 630d1d35e2fSjeremylt CeedInt e_size, l_size; 631d1d35e2fSjeremylt l_size = rstr->l_size; 632d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 633d1d35e2fSjeremylt if (l_vec) { 634d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr); 635d7b241e6Sjeremylt } 636d1d35e2fSjeremylt if (e_vec) { 637d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr); 638d7b241e6Sjeremylt } 639e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 640d7b241e6Sjeremylt } 641d7b241e6Sjeremylt 642d7b241e6Sjeremylt /** 643d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 644d7b241e6Sjeremylt 6454ce2993fSjeremylt @param rstr CeedElemRestriction 646d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 647d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 648d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 649d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 6507aaeacdcSjeremylt by the backend. 6514cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 652b11c1e72Sjeremylt 653b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 654dfdf5a53Sjeremylt 6557a982d89SJeremy L. Thompson @ref User 656b11c1e72Sjeremylt **/ 657d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, 658a8d32208Sjeremylt CeedVector u, CeedVector ru, 659a8d32208Sjeremylt CeedRequest *request) { 660d7b241e6Sjeremylt CeedInt m, n; 661d7b241e6Sjeremylt int ierr; 662d7b241e6Sjeremylt 663d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 664d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 665d1d35e2fSjeremylt n = rstr->l_size; 666d7b241e6Sjeremylt } else { 667d1d35e2fSjeremylt m = rstr->l_size; 668d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 669d7b241e6Sjeremylt } 670d7b241e6Sjeremylt if (n != u->length) 671c042f62fSJeremy L Thompson // LCOV_EXCL_START 672e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 673e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 6741d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 675c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 676a8d32208Sjeremylt if (m != ru->length) 677c042f62fSJeremy L Thompson // LCOV_EXCL_START 678e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 679e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 680a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 681c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 682d1d35e2fSjeremylt ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr); 683e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 684d7b241e6Sjeremylt } 685d7b241e6Sjeremylt 686d7b241e6Sjeremylt /** 687d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 688be9261b7Sjeremylt 689be9261b7Sjeremylt @param rstr CeedElemRestriction 6901f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 691d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 692d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 693d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 694d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 695d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 696d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 6977aaeacdcSjeremylt by the backend. 6984cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 699be9261b7Sjeremylt 700be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 701be9261b7Sjeremylt 7027a982d89SJeremy L. Thompson @ref Backend 703be9261b7Sjeremylt **/ 704be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 705d1d35e2fSjeremylt CeedTransposeMode t_mode, CeedVector u, 706a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 707be9261b7Sjeremylt CeedInt m, n; 708be9261b7Sjeremylt int ierr; 709be9261b7Sjeremylt 710d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 711d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 712d1d35e2fSjeremylt n = rstr->l_size; 713be9261b7Sjeremylt } else { 714d1d35e2fSjeremylt m = rstr->l_size; 715d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 716be9261b7Sjeremylt } 717be9261b7Sjeremylt if (n != u->length) 718c042f62fSJeremy L Thompson // LCOV_EXCL_START 719e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 720e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7211d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 722c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 723a8d32208Sjeremylt if (m != ru->length) 724c042f62fSJeremy L Thompson // LCOV_EXCL_START 725e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 726e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 727a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 728c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 729d1d35e2fSjeremylt if (rstr->blk_size*block > rstr->num_elem) 730c042f62fSJeremy L Thompson // LCOV_EXCL_START 731e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 732e15f9bd0SJeremy L Thompson "Cannot retrieve block %d, element %d > " 733d1d35e2fSjeremylt "total elements %d", block, rstr->blk_size*block, 734d1d35e2fSjeremylt rstr->num_elem); 735c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 736d1d35e2fSjeremylt ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request); 737be9261b7Sjeremylt CeedChk(ierr); 738e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 739be9261b7Sjeremylt } 740be9261b7Sjeremylt 741be9261b7Sjeremylt /** 742d979a051Sjeremylt @brief Get the L-vector component stride 743a681ae63Sjeremylt 744a681ae63Sjeremylt @param rstr CeedElemRestriction 745d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 746a681ae63Sjeremylt 747a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 748a681ae63Sjeremylt 749a681ae63Sjeremylt @ref Backend 750a681ae63Sjeremylt **/ 751d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 752d1d35e2fSjeremylt CeedInt *comp_stride) { 753d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 754e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 755a681ae63Sjeremylt } 756a681ae63Sjeremylt 757a681ae63Sjeremylt /** 758a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 759a681ae63Sjeremylt 760a681ae63Sjeremylt @param rstr CeedElemRestriction 761d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 762a681ae63Sjeremylt 763a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 764a681ae63Sjeremylt 765a681ae63Sjeremylt @ref Backend 766a681ae63Sjeremylt **/ 767a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 768d1d35e2fSjeremylt CeedInt *num_elem) { 769d1d35e2fSjeremylt *num_elem = rstr->num_elem; 770e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 771a681ae63Sjeremylt } 772a681ae63Sjeremylt 773a681ae63Sjeremylt /** 774a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 775a681ae63Sjeremylt 776a681ae63Sjeremylt @param rstr CeedElemRestriction 777d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 778a681ae63Sjeremylt 779a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 780a681ae63Sjeremylt 781a681ae63Sjeremylt @ref Backend 782a681ae63Sjeremylt **/ 783a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 784d1d35e2fSjeremylt CeedInt *elem_size) { 785d1d35e2fSjeremylt *elem_size = rstr->elem_size; 786e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 787a681ae63Sjeremylt } 788a681ae63Sjeremylt 789a681ae63Sjeremylt /** 790d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 791a681ae63Sjeremylt 792a681ae63Sjeremylt @param rstr CeedElemRestriction 793d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 794a681ae63Sjeremylt 795a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 796a681ae63Sjeremylt 797a681ae63Sjeremylt @ref Backend 798a681ae63Sjeremylt **/ 799d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 800d1d35e2fSjeremylt CeedInt *l_size) { 801d1d35e2fSjeremylt *l_size = rstr->l_size; 802e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 803a681ae63Sjeremylt } 804a681ae63Sjeremylt 805a681ae63Sjeremylt /** 806a681ae63Sjeremylt @brief Get the number of components in the elements of a 807a681ae63Sjeremylt CeedElemRestriction 808a681ae63Sjeremylt 809a681ae63Sjeremylt @param rstr CeedElemRestriction 810d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 811a681ae63Sjeremylt 812a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 813a681ae63Sjeremylt 814a681ae63Sjeremylt @ref Backend 815a681ae63Sjeremylt **/ 816a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 817d1d35e2fSjeremylt CeedInt *num_comp) { 818d1d35e2fSjeremylt *num_comp = rstr->num_comp; 819e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 820a681ae63Sjeremylt } 821a681ae63Sjeremylt 822a681ae63Sjeremylt /** 823a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 824a681ae63Sjeremylt 825a681ae63Sjeremylt @param rstr CeedElemRestriction 826d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 827a681ae63Sjeremylt 828a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 829a681ae63Sjeremylt 830a681ae63Sjeremylt @ref Backend 831a681ae63Sjeremylt **/ 832a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 833d1d35e2fSjeremylt CeedInt *num_block) { 834d1d35e2fSjeremylt *num_block = rstr->num_blk; 835e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 836a681ae63Sjeremylt } 837a681ae63Sjeremylt 838a681ae63Sjeremylt /** 839a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 840a681ae63Sjeremylt 841a681ae63Sjeremylt @param rstr CeedElemRestriction 842d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 843a681ae63Sjeremylt 844a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 845a681ae63Sjeremylt 846a681ae63Sjeremylt @ref Backend 847a681ae63Sjeremylt **/ 848a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 849d1d35e2fSjeremylt CeedInt *blk_size) { 850d1d35e2fSjeremylt *blk_size = rstr->blk_size; 851e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 852a681ae63Sjeremylt } 853a681ae63Sjeremylt 854a681ae63Sjeremylt /** 855d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 8561469ee4dSjeremylt 8571469ee4dSjeremylt @param rstr CeedElemRestriction 858d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 8591469ee4dSjeremylt 8601469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 8611469ee4dSjeremylt 8627a982d89SJeremy L. Thompson @ref User 8631469ee4dSjeremylt **/ 8641469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 8651469ee4dSjeremylt CeedVector mult) { 8661469ee4dSjeremylt int ierr; 867d1d35e2fSjeremylt CeedVector e_vec; 8681469ee4dSjeremylt 869d1d35e2fSjeremylt // Create and set e_vec 870d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr); 871d1d35e2fSjeremylt ierr = CeedVectorSetValue(e_vec, 1.0); CeedChk(ierr); 872fa9eac48SJed Brown ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 8731469ee4dSjeremylt 8741469ee4dSjeremylt // Apply to get multiplicity 875d1d35e2fSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, 876efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 8771469ee4dSjeremylt 8781469ee4dSjeremylt // Cleanup 879d1d35e2fSjeremylt ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr); 880e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8811469ee4dSjeremylt } 8821469ee4dSjeremylt 8831469ee4dSjeremylt /** 884f02ca4a2SJed Brown @brief View a CeedElemRestriction 885f02ca4a2SJed Brown 886f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 887f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 888f02ca4a2SJed Brown 889f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 890f02ca4a2SJed Brown 8917a982d89SJeremy L. Thompson @ref User 892f02ca4a2SJed Brown **/ 893f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 8947509a596Sjeremylt char stridesstr[500]; 8957509a596Sjeremylt if (rstr->strides) 8967509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 8977509a596Sjeremylt rstr->strides[2]); 898d979a051Sjeremylt else 899d1d35e2fSjeremylt sprintf(stridesstr, "%d", rstr->comp_stride); 9007509a596Sjeremylt 9010036de2cSjeremylt fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d " 902d1d35e2fSjeremylt "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "", 903d1d35e2fSjeremylt rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 904d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 905e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 906f02ca4a2SJed Brown } 907f02ca4a2SJed Brown 908f02ca4a2SJed Brown /** 909b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 910b11c1e72Sjeremylt 9114ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 912b11c1e72Sjeremylt 913b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 914dfdf5a53Sjeremylt 9157a982d89SJeremy L. Thompson @ref User 916b11c1e72Sjeremylt **/ 9174ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 918d7b241e6Sjeremylt int ierr; 919d7b241e6Sjeremylt 920d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 921d1d35e2fSjeremylt if ((*rstr)->num_readers) 922*8229195eSjeremylt // LCOV_EXCL_START 923e15f9bd0SJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, 924e15f9bd0SJeremy L Thompson "Cannot destroy CeedElemRestriction, " 925430758c8SJeremy L Thompson "a process has read access to the offset data"); 926*8229195eSjeremylt // LCOV_EXCL_STOP 9274ce2993fSjeremylt if ((*rstr)->Destroy) { 9284ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 929d7b241e6Sjeremylt } 9307509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 9314ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 9324ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 933e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 934d7b241e6Sjeremylt } 935d7b241e6Sjeremylt 936d7b241e6Sjeremylt /// @} 937