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 /** 71a681ae63Sjeremylt 72a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 737a982d89SJeremy L. Thompson 747a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 75a681ae63Sjeremylt @param[out] strides Variable to store strides array 767a982d89SJeremy L. Thompson 777a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 787a982d89SJeremy L. Thompson 797a982d89SJeremy L. Thompson @ref Backend 807a982d89SJeremy L. Thompson **/ 81a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 82a681ae63Sjeremylt CeedInt (*strides)[3]) { 83a681ae63Sjeremylt if (!rstr->strides) 84a681ae63Sjeremylt // LCOV_EXCL_START 85e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 86e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 87a681ae63Sjeremylt // LCOV_EXCL_STOP 88a681ae63Sjeremylt 89a681ae63Sjeremylt for (int i=0; i<3; i++) 90a681ae63Sjeremylt (*strides)[i] = rstr->strides[i]; 91e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 927a982d89SJeremy L. Thompson } 937a982d89SJeremy L. Thompson 947a982d89SJeremy L. Thompson /** 95bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 96bd33150aSjeremylt 97bd33150aSjeremylt @param rstr CeedElemRestriction to retrieve offsets 98d1d35e2fSjeremylt @param mem_type Memory type on which to access the array. If the backend 99bd33150aSjeremylt uses a different memory type, this will perform a copy 100bd33150aSjeremylt (possibly cached). 101d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 102bd33150aSjeremylt 103bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 104bd33150aSjeremylt 105bd33150aSjeremylt @ref User 106bd33150aSjeremylt **/ 107d1d35e2fSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, 108d1d35e2fSjeremylt CeedMemType mem_type, 109bd33150aSjeremylt const CeedInt **offsets) { 110bd33150aSjeremylt int ierr; 111bd33150aSjeremylt 112bd33150aSjeremylt if (!rstr->GetOffsets) 113bd33150aSjeremylt // LCOV_EXCL_START 114e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED, 115e15f9bd0SJeremy L Thompson "Backend does not support GetOffsets"); 116bd33150aSjeremylt // LCOV_EXCL_STOP 117bd33150aSjeremylt 118d1d35e2fSjeremylt ierr = rstr->GetOffsets(rstr, mem_type, offsets); CeedChk(ierr); 119d1d35e2fSjeremylt rstr->num_readers++; 120e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 121430758c8SJeremy L Thompson } 122430758c8SJeremy L Thompson 123430758c8SJeremy L Thompson /** 124430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 125430758c8SJeremy L Thompson 126430758c8SJeremy L Thompson @param rstr CeedElemRestriction to restore 127430758c8SJeremy L Thompson @param offsets Array of offset data 128430758c8SJeremy L Thompson 129430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 130430758c8SJeremy L Thompson 131430758c8SJeremy L Thompson @ref User 132430758c8SJeremy L Thompson **/ 133430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, 134430758c8SJeremy L Thompson const CeedInt **offsets) { 135430758c8SJeremy L Thompson *offsets = NULL; 136d1d35e2fSjeremylt rstr->num_readers--; 137e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 138bd33150aSjeremylt } 139bd33150aSjeremylt 140bd33150aSjeremylt /** 1413ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1423ac43b2cSJeremy L Thompson 1433ac43b2cSJeremy L Thompson @param rstr CeedElemRestriction 144d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1453ac43b2cSJeremy L Thompson 1463ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1473ac43b2cSJeremy L Thompson 1483ac43b2cSJeremy L Thompson @ref Backend 1493ac43b2cSJeremy L Thompson **/ 150d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 151d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 152e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1533ac43b2cSJeremy L Thompson } 1543ac43b2cSJeremy L Thompson 1553ac43b2cSJeremy L Thompson /** 156b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 157b435c5a6Srezgarshakeri 158b435c5a6Srezgarshakeri @param rstr CeedElemRestriction 159b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 160b435c5a6Srezgarshakeri 161b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 162b435c5a6Srezgarshakeri 163b435c5a6Srezgarshakeri @ref Backend 164b435c5a6Srezgarshakeri **/ 165b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 166b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 167b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 168b435c5a6Srezgarshakeri } 169b435c5a6Srezgarshakeri 170b435c5a6Srezgarshakeri /** 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 30145f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 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, 337*e79b91d9SJeremy L Thompson CeedSize 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; 370b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 371d1d35e2fSjeremylt ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr); 372d979a051Sjeremylt CeedChk(ierr); 373e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 374d7b241e6Sjeremylt } 375d7b241e6Sjeremylt 376d7b241e6Sjeremylt /** 377fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 378fc0567d9Srezgarshakeri 379fc0567d9Srezgarshakeri @param ceed A Ceed object where the CeedElemRestriction will be created 380fc0567d9Srezgarshakeri @param num_elem Number of elements described in the @a offsets array 381fc0567d9Srezgarshakeri @param elem_size Size (number of "nodes") per element 382fc0567d9Srezgarshakeri @param num_comp Number of field components per interpolation node 383fc0567d9Srezgarshakeri (1 for scalar fields) 384fc0567d9Srezgarshakeri @param comp_stride Stride between components for the same L-vector "node". 385fc0567d9Srezgarshakeri Data for node i, component j, element k can be found in 386fc0567d9Srezgarshakeri the L-vector at index 387fc0567d9Srezgarshakeri offsets[i + k*elem_size] + j*comp_stride. 388fc0567d9Srezgarshakeri @param l_size The size of the L-vector. This vector may be larger than 389fc0567d9Srezgarshakeri the elements and fields given by this restriction. 390fc0567d9Srezgarshakeri @param mem_type Memory type of the @a offsets array, see CeedMemType 391fc0567d9Srezgarshakeri @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 392fc0567d9Srezgarshakeri @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 393fc0567d9Srezgarshakeri ordered list of the offsets (into the input CeedVector) 394fc0567d9Srezgarshakeri for the unknowns corresponding to element i, where 395fc0567d9Srezgarshakeri 0 <= i < @a num_elem. All offsets must be in the range 396fc0567d9Srezgarshakeri [0, @a l_size - 1]. 397fc0567d9Srezgarshakeri @param orient Array of shape [@a num_elem, @a elem_size] with bool false 398fc0567d9Srezgarshakeri for positively oriented and true to flip the orientation. 399fc0567d9Srezgarshakeri @param[out] rstr Address of the variable where the newly created 400fc0567d9Srezgarshakeri CeedElemRestriction will be stored 401fc0567d9Srezgarshakeri 402fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 403fc0567d9Srezgarshakeri 404fc0567d9Srezgarshakeri @ref User 405fc0567d9Srezgarshakeri **/ 406fc0567d9Srezgarshakeri int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, 407fc0567d9Srezgarshakeri CeedInt elem_size, CeedInt num_comp, 408*e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 409fc0567d9Srezgarshakeri CeedMemType mem_type, CeedCopyMode copy_mode, 410fc0567d9Srezgarshakeri const CeedInt *offsets, const bool *orient, 411fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 412fc0567d9Srezgarshakeri int ierr; 413fc0567d9Srezgarshakeri 414c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 415fc0567d9Srezgarshakeri Ceed delegate; 416fc0567d9Srezgarshakeri ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 417fc0567d9Srezgarshakeri CeedChk(ierr); 418fc0567d9Srezgarshakeri 419fc0567d9Srezgarshakeri if (!delegate) 420fc0567d9Srezgarshakeri // LCOV_EXCL_START 421fc0567d9Srezgarshakeri return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 42261e7462cSRezgar Shakeri "Backend does not implement ElemRestrictionCreateOriented"); 423fc0567d9Srezgarshakeri // LCOV_EXCL_STOP 424fc0567d9Srezgarshakeri 425fc0567d9Srezgarshakeri ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, 426c7745053SRezgar Shakeri num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 4274dd06d33Srezgarshakeri orient, rstr); CeedChk(ierr); 428fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 429fc0567d9Srezgarshakeri } 430fc0567d9Srezgarshakeri 431fc0567d9Srezgarshakeri ierr = CeedCalloc(1, rstr); CeedChk(ierr); 432fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 433fc0567d9Srezgarshakeri ierr = CeedReference(ceed); CeedChk(ierr); 434fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 435fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 436fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 437fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 438fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 439fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 440fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 441fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 442b435c5a6Srezgarshakeri (*rstr)->is_oriented = 1; 4434dd06d33Srezgarshakeri ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, 4444dd06d33Srezgarshakeri offsets, orient, *rstr); CeedChk(ierr); 445fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 446fc0567d9Srezgarshakeri } 447fc0567d9Srezgarshakeri 448fc0567d9Srezgarshakeri /** 4497509a596Sjeremylt @brief Create a strided CeedElemRestriction 450d7b241e6Sjeremylt 451b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 452d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 453d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 454d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 45595bb1877Svaleriabarra (1 for scalar fields) 456d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 457d979a051Sjeremylt the elements and fields given by this restriction. 4587509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 45995e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 46095e93d34SJeremy L Thompson the L-vector at index 46195e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 46295e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 46395e93d34SJeremy L Thompson by a Ceed backend. 4644ce2993fSjeremylt @param rstr Address of the variable where the newly created 465b11c1e72Sjeremylt CeedElemRestriction will be stored 466d7b241e6Sjeremylt 467b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 468dfdf5a53Sjeremylt 4697a982d89SJeremy L. Thompson @ref User 470b11c1e72Sjeremylt **/ 471d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, 472d1d35e2fSjeremylt CeedInt elem_size, 473*e79b91d9SJeremy L Thompson CeedInt num_comp, CeedSize l_size, 4748621c6c6SJeremy L Thompson const CeedInt strides[3], 475f90c8643Sjeremylt CeedElemRestriction *rstr) { 476d7b241e6Sjeremylt int ierr; 477d7b241e6Sjeremylt 4785fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4795fe0d4faSjeremylt Ceed delegate; 480aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 481aefd8378Sjeremylt CeedChk(ierr); 4825fe0d4faSjeremylt 4835fe0d4faSjeremylt if (!delegate) 484c042f62fSJeremy L Thompson // LCOV_EXCL_START 485e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 486e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 487c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4885fe0d4faSjeremylt 489d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, 490d1d35e2fSjeremylt l_size, strides, rstr); 491d979a051Sjeremylt CeedChk(ierr); 492e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4935fe0d4faSjeremylt } 4945fe0d4faSjeremylt 4954ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 4964ce2993fSjeremylt (*rstr)->ceed = ceed; 4979560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 498d1d35e2fSjeremylt (*rstr)->ref_count = 1; 499d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 500d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 501d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 502d1d35e2fSjeremylt (*rstr)->l_size = l_size; 503d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 504d1d35e2fSjeremylt (*rstr)->blk_size = 1; 505b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 5067509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 5077509a596Sjeremylt for (int i=0; i<3; i++) 5087509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 5091dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 5101dfeef1dSjeremylt *rstr); 5114b8bea3bSJed Brown CeedChk(ierr); 512e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 513d7b241e6Sjeremylt } 514d7b241e6Sjeremylt 515d7b241e6Sjeremylt /** 516b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 517d7b241e6Sjeremylt 518d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 519d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 520d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 521d1d35e2fSjeremylt @param blk_size Number of elements in a block 522d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 52395bb1877Svaleriabarra (1 for scalar fields) 524d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 52595e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 52695e93d34SJeremy L Thompson the L-vector at index 527d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 528d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 529d979a051Sjeremylt the elements and fields given by this restriction. 530d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 531d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 532d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 533d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 5348795c945Sjeremylt for the unknowns corresponding to element i, where 535d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 536d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 5378795c945Sjeremylt array to the desired ordering for the blocksize, which is 5388795c945Sjeremylt typically given by the backend. The default reordering is 5398795c945Sjeremylt to interlace elements. 5404ce2993fSjeremylt @param rstr Address of the variable where the newly created 541b11c1e72Sjeremylt CeedElemRestriction will be stored 542d7b241e6Sjeremylt 543b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 544dfdf5a53Sjeremylt 5457a982d89SJeremy L. Thompson @ref Backend 546b11c1e72Sjeremylt **/ 547d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, 548d1d35e2fSjeremylt CeedInt elem_size, 549d1d35e2fSjeremylt CeedInt blk_size, CeedInt num_comp, 550*e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 551d1d35e2fSjeremylt CeedMemType mem_type, CeedCopyMode copy_mode, 552d979a051Sjeremylt const CeedInt *offsets, 5534ce2993fSjeremylt CeedElemRestriction *rstr) { 554d7b241e6Sjeremylt int ierr; 555d1d35e2fSjeremylt CeedInt *blk_offsets; 556d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 557d7b241e6Sjeremylt 5585fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5595fe0d4faSjeremylt Ceed delegate; 560aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 561aefd8378Sjeremylt CeedChk(ierr); 5625fe0d4faSjeremylt 5635fe0d4faSjeremylt if (!delegate) 564c042f62fSJeremy L Thompson // LCOV_EXCL_START 565e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 5661d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 567c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5685fe0d4faSjeremylt 569d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, 570d1d35e2fSjeremylt num_comp, comp_stride, l_size, mem_type, 571d1d35e2fSjeremylt copy_mode, offsets, rstr); 572d979a051Sjeremylt CeedChk(ierr); 573e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5745fe0d4faSjeremylt } 575d7b241e6Sjeremylt 5764ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 577d7b241e6Sjeremylt 578d1d35e2fSjeremylt ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr); 579d1d35e2fSjeremylt ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, 580d1d35e2fSjeremylt elem_size); CeedChk(ierr); 581d7b241e6Sjeremylt 5824ce2993fSjeremylt (*rstr)->ceed = ceed; 5839560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 584d1d35e2fSjeremylt (*rstr)->ref_count = 1; 585d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 586d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 587d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 588d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 589d1d35e2fSjeremylt (*rstr)->l_size = l_size; 590d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 591d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 592b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 593667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 594d1d35e2fSjeremylt (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr); 595d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 596d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 5971d102b48SJeremy L Thompson } 598e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 599d7b241e6Sjeremylt } 600d7b241e6Sjeremylt 601b11c1e72Sjeremylt /** 6027509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 6037509a596Sjeremylt 6047509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 605d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 606d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 607d1d35e2fSjeremylt @param blk_size Number of elements in a block 608d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 6097509a596Sjeremylt (1 for scalar fields) 610d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 611d979a051Sjeremylt the elements and fields given by this restriction. 6127509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 61395e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 61495e93d34SJeremy L Thompson the L-vector at index 61595e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 61695e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 61795e93d34SJeremy L Thompson by a Ceed backend. 6187509a596Sjeremylt @param rstr Address of the variable where the newly created 6197509a596Sjeremylt CeedElemRestriction will be stored 6207509a596Sjeremylt 6217509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 6227509a596Sjeremylt 6237a982d89SJeremy L. Thompson @ref User 6247509a596Sjeremylt **/ 625d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, 626*e79b91d9SJeremy L Thompson CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 6278621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 6287509a596Sjeremylt int ierr; 629d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 6307509a596Sjeremylt 6317509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6327509a596Sjeremylt Ceed delegate; 6337509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 6347509a596Sjeremylt CeedChk(ierr); 6357509a596Sjeremylt 6367509a596Sjeremylt if (!delegate) 6377509a596Sjeremylt // LCOV_EXCL_START 638e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 6397509a596Sjeremylt "ElemRestrictionCreateBlocked"); 6407509a596Sjeremylt // LCOV_EXCL_STOP 6417509a596Sjeremylt 642d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, 643d1d35e2fSjeremylt blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr); 644e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6457509a596Sjeremylt } 6467509a596Sjeremylt 6477509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 6487509a596Sjeremylt 6497509a596Sjeremylt (*rstr)->ceed = ceed; 6509560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 651d1d35e2fSjeremylt (*rstr)->ref_count = 1; 652d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 653d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 654d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 655d1d35e2fSjeremylt (*rstr)->l_size = l_size; 656d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 657d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 658b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 6597509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 6607509a596Sjeremylt for (int i=0; i<3; i++) 6617509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 6627509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 6637509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 664e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6657509a596Sjeremylt } 6667509a596Sjeremylt 6677509a596Sjeremylt /** 6689560d06aSjeremylt @brief Copy the pointer to a CeedElemRestriction. Both pointers should 6699560d06aSjeremylt be destroyed with `CeedElemRestrictionDestroy()`; 6709560d06aSjeremylt Note: If `*rstr_copy` is non-NULL, then it is assumed that 6719560d06aSjeremylt `*rstr_copy` is a pointer to a CeedElemRestriction. This 6729560d06aSjeremylt CeedElemRestriction will be destroyed if `*rstr_copy` is the 6739560d06aSjeremylt only reference to this CeedElemRestriction. 6749560d06aSjeremylt 6759560d06aSjeremylt @param rstr CeedElemRestriction to copy reference to 6769560d06aSjeremylt @param[out] rstr_copy Variable to store copied reference 6779560d06aSjeremylt 6789560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6799560d06aSjeremylt 6809560d06aSjeremylt @ref User 6819560d06aSjeremylt **/ 6829560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, 6839560d06aSjeremylt CeedElemRestriction *rstr_copy) { 6849560d06aSjeremylt int ierr; 6859560d06aSjeremylt 6869560d06aSjeremylt ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr); 6879560d06aSjeremylt ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr); 6889560d06aSjeremylt *rstr_copy = rstr; 6899560d06aSjeremylt return CEED_ERROR_SUCCESS; 6909560d06aSjeremylt } 6919560d06aSjeremylt 6929560d06aSjeremylt /** 693b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 694b11c1e72Sjeremylt 6954ce2993fSjeremylt @param rstr CeedElemRestriction 696d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 697d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 698b11c1e72Sjeremylt 699b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 700dfdf5a53Sjeremylt 7017a982d89SJeremy L. Thompson @ref User 702b11c1e72Sjeremylt **/ 703d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, 704d1d35e2fSjeremylt CeedVector *e_vec) { 705d7b241e6Sjeremylt int ierr; 706d1d35e2fSjeremylt CeedInt e_size, l_size; 707d1d35e2fSjeremylt l_size = rstr->l_size; 708d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 709d1d35e2fSjeremylt if (l_vec) { 710d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr); 711d7b241e6Sjeremylt } 712d1d35e2fSjeremylt if (e_vec) { 713d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr); 714d7b241e6Sjeremylt } 715e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 716d7b241e6Sjeremylt } 717d7b241e6Sjeremylt 718d7b241e6Sjeremylt /** 719d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 720d7b241e6Sjeremylt 7214ce2993fSjeremylt @param rstr CeedElemRestriction 722d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 723d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 724d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 725d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7267aaeacdcSjeremylt by the backend. 7274cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 728b11c1e72Sjeremylt 729b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 730dfdf5a53Sjeremylt 7317a982d89SJeremy L. Thompson @ref User 732b11c1e72Sjeremylt **/ 733d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, 734a8d32208Sjeremylt CeedVector u, CeedVector ru, 735a8d32208Sjeremylt CeedRequest *request) { 736d7b241e6Sjeremylt CeedInt m, n; 737d7b241e6Sjeremylt int ierr; 738d7b241e6Sjeremylt 739d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 740d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 741d1d35e2fSjeremylt n = rstr->l_size; 742d7b241e6Sjeremylt } else { 743d1d35e2fSjeremylt m = rstr->l_size; 744d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 745d7b241e6Sjeremylt } 746d7b241e6Sjeremylt if (n != u->length) 747c042f62fSJeremy L Thompson // LCOV_EXCL_START 748e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 749e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7501d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 751c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 752a8d32208Sjeremylt if (m != ru->length) 753c042f62fSJeremy L Thompson // LCOV_EXCL_START 754e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 755e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 756a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 757c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 758d1d35e2fSjeremylt ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr); 759e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 760d7b241e6Sjeremylt } 761d7b241e6Sjeremylt 762d7b241e6Sjeremylt /** 763d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 764be9261b7Sjeremylt 765be9261b7Sjeremylt @param rstr CeedElemRestriction 7661f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 767d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 768d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 769d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 770d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 771d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 772d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7737aaeacdcSjeremylt by the backend. 7744cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 775be9261b7Sjeremylt 776be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 777be9261b7Sjeremylt 7787a982d89SJeremy L. Thompson @ref Backend 779be9261b7Sjeremylt **/ 780be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 781d1d35e2fSjeremylt CeedTransposeMode t_mode, CeedVector u, 782a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 783be9261b7Sjeremylt CeedInt m, n; 784be9261b7Sjeremylt int ierr; 785be9261b7Sjeremylt 786d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 787d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 788d1d35e2fSjeremylt n = rstr->l_size; 789be9261b7Sjeremylt } else { 790d1d35e2fSjeremylt m = rstr->l_size; 791d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 792be9261b7Sjeremylt } 793be9261b7Sjeremylt if (n != u->length) 794c042f62fSJeremy L Thompson // LCOV_EXCL_START 795e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 796e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7971d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 798c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 799a8d32208Sjeremylt if (m != ru->length) 800c042f62fSJeremy L Thompson // LCOV_EXCL_START 801e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 802e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 803a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 804c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 805d1d35e2fSjeremylt if (rstr->blk_size*block > rstr->num_elem) 806c042f62fSJeremy L Thompson // LCOV_EXCL_START 807e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 808e15f9bd0SJeremy L Thompson "Cannot retrieve block %d, element %d > " 809d1d35e2fSjeremylt "total elements %d", block, rstr->blk_size*block, 810d1d35e2fSjeremylt rstr->num_elem); 811c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 812d1d35e2fSjeremylt ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request); 813be9261b7Sjeremylt CeedChk(ierr); 814e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 815be9261b7Sjeremylt } 816be9261b7Sjeremylt 817be9261b7Sjeremylt /** 818b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 819b7c9bbdaSJeremy L Thompson 820b7c9bbdaSJeremy L Thompson @param rstr CeedElemRestriction 821b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 822b7c9bbdaSJeremy L Thompson 823b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 824b7c9bbdaSJeremy L Thompson 825b7c9bbdaSJeremy L Thompson @ref Advanced 826b7c9bbdaSJeremy L Thompson **/ 827b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 828b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 829b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 830b7c9bbdaSJeremy L Thompson } 831b7c9bbdaSJeremy L Thompson 832b7c9bbdaSJeremy L Thompson /** 833d979a051Sjeremylt @brief Get the L-vector component stride 834a681ae63Sjeremylt 835a681ae63Sjeremylt @param rstr CeedElemRestriction 836d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 837a681ae63Sjeremylt 838a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 839a681ae63Sjeremylt 840b7c9bbdaSJeremy L Thompson @ref Advanced 841a681ae63Sjeremylt **/ 842d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 843d1d35e2fSjeremylt CeedInt *comp_stride) { 844d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 845e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 846a681ae63Sjeremylt } 847a681ae63Sjeremylt 848a681ae63Sjeremylt /** 849a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 850a681ae63Sjeremylt 851a681ae63Sjeremylt @param rstr CeedElemRestriction 852d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 853a681ae63Sjeremylt 854a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 855a681ae63Sjeremylt 856b7c9bbdaSJeremy L Thompson @ref Advanced 857a681ae63Sjeremylt **/ 858a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 859d1d35e2fSjeremylt CeedInt *num_elem) { 860d1d35e2fSjeremylt *num_elem = rstr->num_elem; 861e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 862a681ae63Sjeremylt } 863a681ae63Sjeremylt 864a681ae63Sjeremylt /** 865a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 866a681ae63Sjeremylt 867a681ae63Sjeremylt @param rstr CeedElemRestriction 868d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 869a681ae63Sjeremylt 870a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 871a681ae63Sjeremylt 872b7c9bbdaSJeremy L Thompson @ref Advanced 873a681ae63Sjeremylt **/ 874a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 875d1d35e2fSjeremylt CeedInt *elem_size) { 876d1d35e2fSjeremylt *elem_size = rstr->elem_size; 877e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 878a681ae63Sjeremylt } 879a681ae63Sjeremylt 880a681ae63Sjeremylt /** 881d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 882a681ae63Sjeremylt 883a681ae63Sjeremylt @param rstr CeedElemRestriction 884d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 885a681ae63Sjeremylt 886a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 887a681ae63Sjeremylt 888b7c9bbdaSJeremy L Thompson @ref Advanced 889a681ae63Sjeremylt **/ 890d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 891*e79b91d9SJeremy L Thompson CeedSize *l_size) { 892d1d35e2fSjeremylt *l_size = rstr->l_size; 893e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 894a681ae63Sjeremylt } 895a681ae63Sjeremylt 896a681ae63Sjeremylt /** 897a681ae63Sjeremylt @brief Get the number of components in the elements of a 898a681ae63Sjeremylt CeedElemRestriction 899a681ae63Sjeremylt 900a681ae63Sjeremylt @param rstr CeedElemRestriction 901d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 902a681ae63Sjeremylt 903a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 904a681ae63Sjeremylt 905b7c9bbdaSJeremy L Thompson @ref Advanced 906a681ae63Sjeremylt **/ 907a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 908d1d35e2fSjeremylt CeedInt *num_comp) { 909d1d35e2fSjeremylt *num_comp = rstr->num_comp; 910e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 911a681ae63Sjeremylt } 912a681ae63Sjeremylt 913a681ae63Sjeremylt /** 914a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 915a681ae63Sjeremylt 916a681ae63Sjeremylt @param rstr CeedElemRestriction 917d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 918a681ae63Sjeremylt 919a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 920a681ae63Sjeremylt 921b7c9bbdaSJeremy L Thompson @ref Advanced 922a681ae63Sjeremylt **/ 923a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 924d1d35e2fSjeremylt CeedInt *num_block) { 925d1d35e2fSjeremylt *num_block = rstr->num_blk; 926e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 927a681ae63Sjeremylt } 928a681ae63Sjeremylt 929a681ae63Sjeremylt /** 930a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 931a681ae63Sjeremylt 932a681ae63Sjeremylt @param rstr CeedElemRestriction 933d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 934a681ae63Sjeremylt 935a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 936a681ae63Sjeremylt 937b7c9bbdaSJeremy L Thompson @ref Advanced 938a681ae63Sjeremylt **/ 939a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 940d1d35e2fSjeremylt CeedInt *blk_size) { 941d1d35e2fSjeremylt *blk_size = rstr->blk_size; 942e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 943a681ae63Sjeremylt } 944a681ae63Sjeremylt 945a681ae63Sjeremylt /** 946d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 9471469ee4dSjeremylt 9481469ee4dSjeremylt @param rstr CeedElemRestriction 949d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 9501469ee4dSjeremylt 9511469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 9521469ee4dSjeremylt 9537a982d89SJeremy L. Thompson @ref User 9541469ee4dSjeremylt **/ 9551469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 9561469ee4dSjeremylt CeedVector mult) { 9571469ee4dSjeremylt int ierr; 958d1d35e2fSjeremylt CeedVector e_vec; 9591469ee4dSjeremylt 96025509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 961d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr); 9621469ee4dSjeremylt 96325509ebbSRezgar Shakeri // Compute e_vec = E * 1 96425509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 1.0); CeedChk(ierr); 96525509ebbSRezgar Shakeri ierr = CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, 96625509ebbSRezgar Shakeri CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 96725509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 96825509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 969d1d35e2fSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, 970efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 9711469ee4dSjeremylt // Cleanup 972d1d35e2fSjeremylt ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr); 973e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9741469ee4dSjeremylt } 9751469ee4dSjeremylt 9761469ee4dSjeremylt /** 977f02ca4a2SJed Brown @brief View a CeedElemRestriction 978f02ca4a2SJed Brown 979f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 980f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 981f02ca4a2SJed Brown 982f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 983f02ca4a2SJed Brown 9847a982d89SJeremy L. Thompson @ref User 985f02ca4a2SJed Brown **/ 986f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 9877509a596Sjeremylt char stridesstr[500]; 9887509a596Sjeremylt if (rstr->strides) 9897509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 9907509a596Sjeremylt rstr->strides[2]); 991d979a051Sjeremylt else 992d1d35e2fSjeremylt sprintf(stridesstr, "%d", rstr->comp_stride); 9937509a596Sjeremylt 994*e79b91d9SJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%ld, %d) to %d elements with %d " 995d1d35e2fSjeremylt "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "", 996d1d35e2fSjeremylt rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 997d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 998e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 999f02ca4a2SJed Brown } 1000f02ca4a2SJed Brown 1001f02ca4a2SJed Brown /** 1002b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1003b11c1e72Sjeremylt 10044ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 1005b11c1e72Sjeremylt 1006b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1007dfdf5a53Sjeremylt 10087a982d89SJeremy L. Thompson @ref User 1009b11c1e72Sjeremylt **/ 10104ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1011d7b241e6Sjeremylt int ierr; 1012d7b241e6Sjeremylt 1013d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 1014d1d35e2fSjeremylt if ((*rstr)->num_readers) 10158229195eSjeremylt // LCOV_EXCL_START 1016e15f9bd0SJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, 1017e15f9bd0SJeremy L Thompson "Cannot destroy CeedElemRestriction, " 1018430758c8SJeremy L Thompson "a process has read access to the offset data"); 10198229195eSjeremylt // LCOV_EXCL_STOP 10204ce2993fSjeremylt if ((*rstr)->Destroy) { 10214ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 1022d7b241e6Sjeremylt } 10237509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 10244ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 10254ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 1026e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1027d7b241e6Sjeremylt } 1028d7b241e6Sjeremylt 1029d7b241e6Sjeremylt /// @} 1030