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 /** 156a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1577a982d89SJeremy L. Thompson 1587a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 15996b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1607a982d89SJeremy L. Thompson 1617a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1627a982d89SJeremy L. Thompson 1637a982d89SJeremy L. Thompson @ref Backend 1647a982d89SJeremy L. Thompson **/ 165fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, 166d1d35e2fSjeremylt bool *has_backend_strides) { 167a681ae63Sjeremylt if (!rstr->strides) 168a681ae63Sjeremylt // LCOV_EXCL_START 169e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 170e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 171a681ae63Sjeremylt // LCOV_EXCL_STOP 1727a982d89SJeremy L. Thompson 173d1d35e2fSjeremylt *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 174a681ae63Sjeremylt (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 175a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 176e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1777a982d89SJeremy L. Thompson } 1787a982d89SJeremy L. Thompson 1797a982d89SJeremy L. Thompson /** 18049fd234cSJeremy L Thompson 18149fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 18249fd234cSJeremy L Thompson 18349fd234cSJeremy L Thompson @param rstr CeedElemRestriction 18449fd234cSJeremy L Thompson @param[out] layout Variable to store layout array, 18549fd234cSJeremy L Thompson stored as [nodes, components, elements]. 18649fd234cSJeremy L Thompson The data for node i, component j, element k in the 18749fd234cSJeremy L Thompson E-vector is given by 18895e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 18949fd234cSJeremy L Thompson 19049fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19149fd234cSJeremy L Thompson 19249fd234cSJeremy L Thompson @ref Backend 19349fd234cSJeremy L Thompson **/ 19449fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, 19549fd234cSJeremy L Thompson CeedInt (*layout)[3]) { 19649fd234cSJeremy L Thompson if (!rstr->layout[0]) 19749fd234cSJeremy L Thompson // LCOV_EXCL_START 198e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 199e15f9bd0SJeremy L Thompson "ElemRestriction has no layout data"); 20049fd234cSJeremy L Thompson // LCOV_EXCL_STOP 20149fd234cSJeremy L Thompson 20249fd234cSJeremy L Thompson for (int i=0; i<3; i++) 20349fd234cSJeremy L Thompson (*layout)[i] = rstr->layout[i]; 204e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 20549fd234cSJeremy L Thompson } 20649fd234cSJeremy L Thompson 20749fd234cSJeremy L Thompson /** 20849fd234cSJeremy L Thompson 20949fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 21049fd234cSJeremy L Thompson 21149fd234cSJeremy L Thompson @param rstr CeedElemRestriction 21249fd234cSJeremy L Thompson @param layout Variable to containing layout array, 21349fd234cSJeremy L Thompson stored as [nodes, components, elements]. 21449fd234cSJeremy L Thompson The data for node i, component j, element k in the 21549fd234cSJeremy L Thompson E-vector is given by 21695e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 21749fd234cSJeremy L Thompson 21849fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21949fd234cSJeremy L Thompson 22049fd234cSJeremy L Thompson @ref Backend 22149fd234cSJeremy L Thompson **/ 22249fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, 22349fd234cSJeremy L Thompson CeedInt layout[3]) { 22449fd234cSJeremy L Thompson for (int i = 0; i<3; i++) 22549fd234cSJeremy L Thompson rstr->layout[i] = layout[i]; 226e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 22749fd234cSJeremy L Thompson } 22849fd234cSJeremy L Thompson 22949fd234cSJeremy L Thompson /** 2307a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2317a982d89SJeremy L. Thompson 2327a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 2337a982d89SJeremy L. Thompson @param[out] data Variable to store data 2347a982d89SJeremy L. Thompson 2357a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2367a982d89SJeremy L. Thompson 2377a982d89SJeremy L. Thompson @ref Backend 2387a982d89SJeremy L. Thompson **/ 239777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 240777ff853SJeremy L Thompson *(void **)data = rstr->data; 241e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2427a982d89SJeremy L. Thompson } 2437a982d89SJeremy L. Thompson 2447a982d89SJeremy L. Thompson /** 2457a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2467a982d89SJeremy L. Thompson 2477a982d89SJeremy L. Thompson @param[out] rstr CeedElemRestriction 2487a982d89SJeremy L. Thompson @param data Data to set 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 CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 255777ff853SJeremy L Thompson rstr->data = data; 256e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2577a982d89SJeremy L. Thompson } 2587a982d89SJeremy L. Thompson 25934359f16Sjeremylt /** 26034359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 26134359f16Sjeremylt 26234359f16Sjeremylt @param rstr ElemRestriction to increment the reference counter 26334359f16Sjeremylt 26434359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 26534359f16Sjeremylt 26634359f16Sjeremylt @ref Backend 26734359f16Sjeremylt **/ 2689560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 26934359f16Sjeremylt rstr->ref_count++; 27034359f16Sjeremylt return CEED_ERROR_SUCCESS; 27134359f16Sjeremylt } 27234359f16Sjeremylt 2737a982d89SJeremy L. Thompson /// @} 2747a982d89SJeremy L. Thompson 27515910d16Sjeremylt /// @cond DOXYGEN_SKIP 27615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 27715910d16Sjeremylt /// @endcond 27815910d16Sjeremylt 2797a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2807a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2817a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2827a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 283d7b241e6Sjeremylt /// @{ 284d7b241e6Sjeremylt 2857a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 28645f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 2877a982d89SJeremy L. Thompson 2884cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 2897a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 2907a982d89SJeremy L. Thompson &ceed_elemrestriction_none; 2917a982d89SJeremy L. Thompson 292d7b241e6Sjeremylt /** 293b11c1e72Sjeremylt @brief Create a CeedElemRestriction 294d7b241e6Sjeremylt 295b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 296d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array 297d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 298d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 29995bb1877Svaleriabarra (1 for scalar fields) 300d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 30195e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 30295e93d34SJeremy L Thompson the L-vector at index 303d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 304d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 305d979a051Sjeremylt the elements and fields given by this restriction. 306d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 307d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 308d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 309d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3108795c945Sjeremylt for the unknowns corresponding to element i, where 311d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 312d1d35e2fSjeremylt [0, @a l_size - 1]. 3134ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 314b11c1e72Sjeremylt CeedElemRestriction will be stored 315d7b241e6Sjeremylt 316b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 317dfdf5a53Sjeremylt 3187a982d89SJeremy L. Thompson @ref User 319b11c1e72Sjeremylt **/ 320d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, 321d1d35e2fSjeremylt CeedInt num_comp, CeedInt comp_stride, 322d1d35e2fSjeremylt CeedInt l_size, CeedMemType mem_type, 323d1d35e2fSjeremylt CeedCopyMode copy_mode, const CeedInt *offsets, 3244ce2993fSjeremylt CeedElemRestriction *rstr) { 325d7b241e6Sjeremylt int ierr; 326d7b241e6Sjeremylt 3275fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3285fe0d4faSjeremylt Ceed delegate; 329aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 330aefd8378Sjeremylt CeedChk(ierr); 3315fe0d4faSjeremylt 3325fe0d4faSjeremylt if (!delegate) 333c042f62fSJeremy L Thompson // LCOV_EXCL_START 334e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 335e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 336c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3375fe0d4faSjeremylt 338d1d35e2fSjeremylt ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, 339d1d35e2fSjeremylt comp_stride, l_size, mem_type, copy_mode, 340d979a051Sjeremylt offsets, rstr); CeedChk(ierr); 341e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3425fe0d4faSjeremylt } 3435fe0d4faSjeremylt 3444ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3454ce2993fSjeremylt (*rstr)->ceed = ceed; 3469560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 347d1d35e2fSjeremylt (*rstr)->ref_count = 1; 348d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 349d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 350d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 351d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 352d1d35e2fSjeremylt (*rstr)->l_size = l_size; 353d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 354d1d35e2fSjeremylt (*rstr)->blk_size = 1; 355d1d35e2fSjeremylt ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr); 356d979a051Sjeremylt CeedChk(ierr); 357e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 358d7b241e6Sjeremylt } 359d7b241e6Sjeremylt 360d7b241e6Sjeremylt /** 361*fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 362*fc0567d9Srezgarshakeri 363*fc0567d9Srezgarshakeri @param ceed A Ceed object where the CeedElemRestriction will be created 364*fc0567d9Srezgarshakeri @param num_elem Number of elements described in the @a offsets array 365*fc0567d9Srezgarshakeri @param elem_size Size (number of "nodes") per element 366*fc0567d9Srezgarshakeri @param num_comp Number of field components per interpolation node 367*fc0567d9Srezgarshakeri (1 for scalar fields) 368*fc0567d9Srezgarshakeri @param comp_stride Stride between components for the same L-vector "node". 369*fc0567d9Srezgarshakeri Data for node i, component j, element k can be found in 370*fc0567d9Srezgarshakeri the L-vector at index 371*fc0567d9Srezgarshakeri offsets[i + k*elem_size] + j*comp_stride. 372*fc0567d9Srezgarshakeri @param l_size The size of the L-vector. This vector may be larger than 373*fc0567d9Srezgarshakeri the elements and fields given by this restriction. 374*fc0567d9Srezgarshakeri @param mem_type Memory type of the @a offsets array, see CeedMemType 375*fc0567d9Srezgarshakeri @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 376*fc0567d9Srezgarshakeri @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 377*fc0567d9Srezgarshakeri ordered list of the offsets (into the input CeedVector) 378*fc0567d9Srezgarshakeri for the unknowns corresponding to element i, where 379*fc0567d9Srezgarshakeri 0 <= i < @a num_elem. All offsets must be in the range 380*fc0567d9Srezgarshakeri [0, @a l_size - 1]. 381*fc0567d9Srezgarshakeri @param orient Array of shape [@a num_elem, @a elem_size] with bool false 382*fc0567d9Srezgarshakeri for positively oriented and true to flip the orientation. 383*fc0567d9Srezgarshakeri @param scale An scalar value that scales the dofs in assembly. 384*fc0567d9Srezgarshakeri @param[out] rstr Address of the variable where the newly created 385*fc0567d9Srezgarshakeri CeedElemRestriction will be stored 386*fc0567d9Srezgarshakeri 387*fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 388*fc0567d9Srezgarshakeri 389*fc0567d9Srezgarshakeri @ref User 390*fc0567d9Srezgarshakeri **/ 391*fc0567d9Srezgarshakeri int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, 392*fc0567d9Srezgarshakeri CeedInt elem_size, CeedInt num_comp, 393*fc0567d9Srezgarshakeri CeedInt comp_stride, CeedInt l_size, 394*fc0567d9Srezgarshakeri CeedMemType mem_type, CeedCopyMode copy_mode, 395*fc0567d9Srezgarshakeri const CeedInt *offsets, const bool *orient, 396*fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 397*fc0567d9Srezgarshakeri int ierr; 398*fc0567d9Srezgarshakeri 399*fc0567d9Srezgarshakeri if (!ceed->ElemRestrictionCreate) { 400*fc0567d9Srezgarshakeri Ceed delegate; 401*fc0567d9Srezgarshakeri ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 402*fc0567d9Srezgarshakeri CeedChk(ierr); 403*fc0567d9Srezgarshakeri 404*fc0567d9Srezgarshakeri if (!delegate) 405*fc0567d9Srezgarshakeri // LCOV_EXCL_START 406*fc0567d9Srezgarshakeri return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 407*fc0567d9Srezgarshakeri "Backend does not support ElemRestrictionCreateOriented"); 408*fc0567d9Srezgarshakeri // LCOV_EXCL_STOP 409*fc0567d9Srezgarshakeri 410*fc0567d9Srezgarshakeri ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, 411*fc0567d9Srezgarshakeri num_comp, 412*fc0567d9Srezgarshakeri comp_stride, l_size, mem_type, copy_mode, 413*fc0567d9Srezgarshakeri offsets, orient, rstr); CeedChk(ierr); 414*fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 415*fc0567d9Srezgarshakeri } 416*fc0567d9Srezgarshakeri 417*fc0567d9Srezgarshakeri ierr = CeedCalloc(1, rstr); CeedChk(ierr); 418*fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 419*fc0567d9Srezgarshakeri ierr = CeedReference(ceed); CeedChk(ierr); 420*fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 421*fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 422*fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 423*fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 424*fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 425*fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 426*fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 427*fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 428*fc0567d9Srezgarshakeri ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient, 429*fc0567d9Srezgarshakeri *rstr); 430*fc0567d9Srezgarshakeri CeedChk(ierr); 431*fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 432*fc0567d9Srezgarshakeri } 433*fc0567d9Srezgarshakeri 434*fc0567d9Srezgarshakeri /** 4357509a596Sjeremylt @brief Create a strided CeedElemRestriction 436d7b241e6Sjeremylt 437b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 438d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 439d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 440d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 44195bb1877Svaleriabarra (1 for scalar fields) 442d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 443d979a051Sjeremylt the elements and fields given by this restriction. 4447509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 44595e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 44695e93d34SJeremy L Thompson the L-vector at index 44795e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 44895e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 44995e93d34SJeremy L Thompson by a Ceed backend. 4504ce2993fSjeremylt @param rstr Address of the variable where the newly created 451b11c1e72Sjeremylt CeedElemRestriction will be stored 452d7b241e6Sjeremylt 453b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 454dfdf5a53Sjeremylt 4557a982d89SJeremy L. Thompson @ref User 456b11c1e72Sjeremylt **/ 457d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, 458d1d35e2fSjeremylt CeedInt elem_size, 459d1d35e2fSjeremylt CeedInt num_comp, CeedInt l_size, 4608621c6c6SJeremy L Thompson const CeedInt strides[3], 461f90c8643Sjeremylt CeedElemRestriction *rstr) { 462d7b241e6Sjeremylt int ierr; 463d7b241e6Sjeremylt 4645fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4655fe0d4faSjeremylt Ceed delegate; 466aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 467aefd8378Sjeremylt CeedChk(ierr); 4685fe0d4faSjeremylt 4695fe0d4faSjeremylt if (!delegate) 470c042f62fSJeremy L Thompson // LCOV_EXCL_START 471e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 472e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 473c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4745fe0d4faSjeremylt 475d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, 476d1d35e2fSjeremylt l_size, strides, rstr); 477d979a051Sjeremylt CeedChk(ierr); 478e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4795fe0d4faSjeremylt } 4805fe0d4faSjeremylt 4814ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 4824ce2993fSjeremylt (*rstr)->ceed = ceed; 4839560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 484d1d35e2fSjeremylt (*rstr)->ref_count = 1; 485d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 486d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 487d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 488d1d35e2fSjeremylt (*rstr)->l_size = l_size; 489d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 490d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4917509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 4927509a596Sjeremylt for (int i=0; i<3; i++) 4937509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 4941dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 4951dfeef1dSjeremylt *rstr); 4964b8bea3bSJed Brown CeedChk(ierr); 497e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 498d7b241e6Sjeremylt } 499d7b241e6Sjeremylt 500d7b241e6Sjeremylt /** 501b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 502d7b241e6Sjeremylt 503d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 504d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 505d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 506d1d35e2fSjeremylt @param blk_size Number of elements in a block 507d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 50895bb1877Svaleriabarra (1 for scalar fields) 509d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 51095e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 51195e93d34SJeremy L Thompson the L-vector at index 512d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 513d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 514d979a051Sjeremylt the elements and fields given by this restriction. 515d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 516d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 517d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 518d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 5198795c945Sjeremylt for the unknowns corresponding to element i, where 520d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 521d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 5228795c945Sjeremylt array to the desired ordering for the blocksize, which is 5238795c945Sjeremylt typically given by the backend. The default reordering is 5248795c945Sjeremylt to interlace elements. 5254ce2993fSjeremylt @param rstr Address of the variable where the newly created 526b11c1e72Sjeremylt CeedElemRestriction will be stored 527d7b241e6Sjeremylt 528b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 529dfdf5a53Sjeremylt 5307a982d89SJeremy L. Thompson @ref Backend 531b11c1e72Sjeremylt **/ 532d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, 533d1d35e2fSjeremylt CeedInt elem_size, 534d1d35e2fSjeremylt CeedInt blk_size, CeedInt num_comp, 535d1d35e2fSjeremylt CeedInt comp_stride, CeedInt l_size, 536d1d35e2fSjeremylt CeedMemType mem_type, CeedCopyMode copy_mode, 537d979a051Sjeremylt const CeedInt *offsets, 5384ce2993fSjeremylt CeedElemRestriction *rstr) { 539d7b241e6Sjeremylt int ierr; 540d1d35e2fSjeremylt CeedInt *blk_offsets; 541d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 542d7b241e6Sjeremylt 5435fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5445fe0d4faSjeremylt Ceed delegate; 545aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 546aefd8378Sjeremylt CeedChk(ierr); 5475fe0d4faSjeremylt 5485fe0d4faSjeremylt if (!delegate) 549c042f62fSJeremy L Thompson // LCOV_EXCL_START 550e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 5511d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 552c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5535fe0d4faSjeremylt 554d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, 555d1d35e2fSjeremylt num_comp, comp_stride, l_size, mem_type, 556d1d35e2fSjeremylt copy_mode, offsets, rstr); 557d979a051Sjeremylt CeedChk(ierr); 558e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5595fe0d4faSjeremylt } 560d7b241e6Sjeremylt 5614ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 562d7b241e6Sjeremylt 563d1d35e2fSjeremylt ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr); 564d1d35e2fSjeremylt ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, 565d1d35e2fSjeremylt elem_size); CeedChk(ierr); 566d7b241e6Sjeremylt 5674ce2993fSjeremylt (*rstr)->ceed = ceed; 5689560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 569d1d35e2fSjeremylt (*rstr)->ref_count = 1; 570d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 571d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 572d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 573d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 574d1d35e2fSjeremylt (*rstr)->l_size = l_size; 575d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 576d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 577667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 578d1d35e2fSjeremylt (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr); 579d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 580d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 5811d102b48SJeremy L Thompson } 582e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 583d7b241e6Sjeremylt } 584d7b241e6Sjeremylt 585b11c1e72Sjeremylt /** 5867509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5877509a596Sjeremylt 5887509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 589d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 590d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 591d1d35e2fSjeremylt @param blk_size Number of elements in a block 592d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 5937509a596Sjeremylt (1 for scalar fields) 594d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 595d979a051Sjeremylt the elements and fields given by this restriction. 5967509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 59795e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 59895e93d34SJeremy L Thompson the L-vector at index 59995e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 60095e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 60195e93d34SJeremy L Thompson by a Ceed backend. 6027509a596Sjeremylt @param rstr Address of the variable where the newly created 6037509a596Sjeremylt CeedElemRestriction will be stored 6047509a596Sjeremylt 6057509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 6067509a596Sjeremylt 6077a982d89SJeremy L. Thompson @ref User 6087509a596Sjeremylt **/ 609d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, 610d1d35e2fSjeremylt CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt l_size, 6118621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 6127509a596Sjeremylt int ierr; 613d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 6147509a596Sjeremylt 6157509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6167509a596Sjeremylt Ceed delegate; 6177509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 6187509a596Sjeremylt CeedChk(ierr); 6197509a596Sjeremylt 6207509a596Sjeremylt if (!delegate) 6217509a596Sjeremylt // LCOV_EXCL_START 622e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 6237509a596Sjeremylt "ElemRestrictionCreateBlocked"); 6247509a596Sjeremylt // LCOV_EXCL_STOP 6257509a596Sjeremylt 626d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, 627d1d35e2fSjeremylt blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr); 628e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6297509a596Sjeremylt } 6307509a596Sjeremylt 6317509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 6327509a596Sjeremylt 6337509a596Sjeremylt (*rstr)->ceed = ceed; 6349560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 635d1d35e2fSjeremylt (*rstr)->ref_count = 1; 636d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 637d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 638d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 639d1d35e2fSjeremylt (*rstr)->l_size = l_size; 640d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 641d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 6427509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 6437509a596Sjeremylt for (int i=0; i<3; i++) 6447509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 6457509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 6467509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 647e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6487509a596Sjeremylt } 6497509a596Sjeremylt 6507509a596Sjeremylt /** 6519560d06aSjeremylt @brief Copy the pointer to a CeedElemRestriction. Both pointers should 6529560d06aSjeremylt be destroyed with `CeedElemRestrictionDestroy()`; 6539560d06aSjeremylt Note: If `*rstr_copy` is non-NULL, then it is assumed that 6549560d06aSjeremylt `*rstr_copy` is a pointer to a CeedElemRestriction. This 6559560d06aSjeremylt CeedElemRestriction will be destroyed if `*rstr_copy` is the 6569560d06aSjeremylt only reference to this CeedElemRestriction. 6579560d06aSjeremylt 6589560d06aSjeremylt @param rstr CeedElemRestriction to copy reference to 6599560d06aSjeremylt @param[out] rstr_copy Variable to store copied reference 6609560d06aSjeremylt 6619560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6629560d06aSjeremylt 6639560d06aSjeremylt @ref User 6649560d06aSjeremylt **/ 6659560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, 6669560d06aSjeremylt CeedElemRestriction *rstr_copy) { 6679560d06aSjeremylt int ierr; 6689560d06aSjeremylt 6699560d06aSjeremylt ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr); 6709560d06aSjeremylt ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr); 6719560d06aSjeremylt *rstr_copy = rstr; 6729560d06aSjeremylt return CEED_ERROR_SUCCESS; 6739560d06aSjeremylt } 6749560d06aSjeremylt 6759560d06aSjeremylt /** 676b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 677b11c1e72Sjeremylt 6784ce2993fSjeremylt @param rstr CeedElemRestriction 679d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 680d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 681b11c1e72Sjeremylt 682b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 683dfdf5a53Sjeremylt 6847a982d89SJeremy L. Thompson @ref User 685b11c1e72Sjeremylt **/ 686d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, 687d1d35e2fSjeremylt CeedVector *e_vec) { 688d7b241e6Sjeremylt int ierr; 689d1d35e2fSjeremylt CeedInt e_size, l_size; 690d1d35e2fSjeremylt l_size = rstr->l_size; 691d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 692d1d35e2fSjeremylt if (l_vec) { 693d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr); 694d7b241e6Sjeremylt } 695d1d35e2fSjeremylt if (e_vec) { 696d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr); 697d7b241e6Sjeremylt } 698e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 699d7b241e6Sjeremylt } 700d7b241e6Sjeremylt 701d7b241e6Sjeremylt /** 702d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 703d7b241e6Sjeremylt 7044ce2993fSjeremylt @param rstr CeedElemRestriction 705d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 706d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 707d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 708d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7097aaeacdcSjeremylt by the backend. 7104cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 711b11c1e72Sjeremylt 712b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 713dfdf5a53Sjeremylt 7147a982d89SJeremy L. Thompson @ref User 715b11c1e72Sjeremylt **/ 716d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, 717a8d32208Sjeremylt CeedVector u, CeedVector ru, 718a8d32208Sjeremylt CeedRequest *request) { 719d7b241e6Sjeremylt CeedInt m, n; 720d7b241e6Sjeremylt int ierr; 721d7b241e6Sjeremylt 722d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 723d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 724d1d35e2fSjeremylt n = rstr->l_size; 725d7b241e6Sjeremylt } else { 726d1d35e2fSjeremylt m = rstr->l_size; 727d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 728d7b241e6Sjeremylt } 729d7b241e6Sjeremylt if (n != u->length) 730c042f62fSJeremy L Thompson // LCOV_EXCL_START 731e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 732e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7331d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 734c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 735a8d32208Sjeremylt if (m != ru->length) 736c042f62fSJeremy L Thompson // LCOV_EXCL_START 737e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 738e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 739a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 740c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 741d1d35e2fSjeremylt ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr); 742e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 743d7b241e6Sjeremylt } 744d7b241e6Sjeremylt 745d7b241e6Sjeremylt /** 746d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 747be9261b7Sjeremylt 748be9261b7Sjeremylt @param rstr CeedElemRestriction 7491f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 750d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 751d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 752d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 753d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 754d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 755d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7567aaeacdcSjeremylt by the backend. 7574cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 758be9261b7Sjeremylt 759be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 760be9261b7Sjeremylt 7617a982d89SJeremy L. Thompson @ref Backend 762be9261b7Sjeremylt **/ 763be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 764d1d35e2fSjeremylt CeedTransposeMode t_mode, CeedVector u, 765a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 766be9261b7Sjeremylt CeedInt m, n; 767be9261b7Sjeremylt int ierr; 768be9261b7Sjeremylt 769d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 770d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 771d1d35e2fSjeremylt n = rstr->l_size; 772be9261b7Sjeremylt } else { 773d1d35e2fSjeremylt m = rstr->l_size; 774d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 775be9261b7Sjeremylt } 776be9261b7Sjeremylt if (n != u->length) 777c042f62fSJeremy L Thompson // LCOV_EXCL_START 778e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 779e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7801d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 781c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 782a8d32208Sjeremylt if (m != ru->length) 783c042f62fSJeremy L Thompson // LCOV_EXCL_START 784e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 785e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 786a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 787c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 788d1d35e2fSjeremylt if (rstr->blk_size*block > rstr->num_elem) 789c042f62fSJeremy L Thompson // LCOV_EXCL_START 790e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 791e15f9bd0SJeremy L Thompson "Cannot retrieve block %d, element %d > " 792d1d35e2fSjeremylt "total elements %d", block, rstr->blk_size*block, 793d1d35e2fSjeremylt rstr->num_elem); 794c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 795d1d35e2fSjeremylt ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request); 796be9261b7Sjeremylt CeedChk(ierr); 797e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 798be9261b7Sjeremylt } 799be9261b7Sjeremylt 800be9261b7Sjeremylt /** 801b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 802b7c9bbdaSJeremy L Thompson 803b7c9bbdaSJeremy L Thompson @param rstr CeedElemRestriction 804b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 805b7c9bbdaSJeremy L Thompson 806b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 807b7c9bbdaSJeremy L Thompson 808b7c9bbdaSJeremy L Thompson @ref Advanced 809b7c9bbdaSJeremy L Thompson **/ 810b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 811b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 812b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 813b7c9bbdaSJeremy L Thompson } 814b7c9bbdaSJeremy L Thompson 815b7c9bbdaSJeremy L Thompson /** 816d979a051Sjeremylt @brief Get the L-vector component stride 817a681ae63Sjeremylt 818a681ae63Sjeremylt @param rstr CeedElemRestriction 819d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 820a681ae63Sjeremylt 821a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 822a681ae63Sjeremylt 823b7c9bbdaSJeremy L Thompson @ref Advanced 824a681ae63Sjeremylt **/ 825d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 826d1d35e2fSjeremylt CeedInt *comp_stride) { 827d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 828e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 829a681ae63Sjeremylt } 830a681ae63Sjeremylt 831a681ae63Sjeremylt /** 832a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 833a681ae63Sjeremylt 834a681ae63Sjeremylt @param rstr CeedElemRestriction 835d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 836a681ae63Sjeremylt 837a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 838a681ae63Sjeremylt 839b7c9bbdaSJeremy L Thompson @ref Advanced 840a681ae63Sjeremylt **/ 841a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 842d1d35e2fSjeremylt CeedInt *num_elem) { 843d1d35e2fSjeremylt *num_elem = rstr->num_elem; 844e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 845a681ae63Sjeremylt } 846a681ae63Sjeremylt 847a681ae63Sjeremylt /** 848a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 849a681ae63Sjeremylt 850a681ae63Sjeremylt @param rstr CeedElemRestriction 851d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 852a681ae63Sjeremylt 853a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 854a681ae63Sjeremylt 855b7c9bbdaSJeremy L Thompson @ref Advanced 856a681ae63Sjeremylt **/ 857a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 858d1d35e2fSjeremylt CeedInt *elem_size) { 859d1d35e2fSjeremylt *elem_size = rstr->elem_size; 860e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 861a681ae63Sjeremylt } 862a681ae63Sjeremylt 863a681ae63Sjeremylt /** 864d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 865a681ae63Sjeremylt 866a681ae63Sjeremylt @param rstr CeedElemRestriction 867d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 868a681ae63Sjeremylt 869a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 870a681ae63Sjeremylt 871b7c9bbdaSJeremy L Thompson @ref Advanced 872a681ae63Sjeremylt **/ 873d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 874d1d35e2fSjeremylt CeedInt *l_size) { 875d1d35e2fSjeremylt *l_size = rstr->l_size; 876e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 877a681ae63Sjeremylt } 878a681ae63Sjeremylt 879a681ae63Sjeremylt /** 880a681ae63Sjeremylt @brief Get the number of components in the elements of a 881a681ae63Sjeremylt CeedElemRestriction 882a681ae63Sjeremylt 883a681ae63Sjeremylt @param rstr CeedElemRestriction 884d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 885a681ae63Sjeremylt 886a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 887a681ae63Sjeremylt 888b7c9bbdaSJeremy L Thompson @ref Advanced 889a681ae63Sjeremylt **/ 890a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 891d1d35e2fSjeremylt CeedInt *num_comp) { 892d1d35e2fSjeremylt *num_comp = rstr->num_comp; 893e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 894a681ae63Sjeremylt } 895a681ae63Sjeremylt 896a681ae63Sjeremylt /** 897a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 898a681ae63Sjeremylt 899a681ae63Sjeremylt @param rstr CeedElemRestriction 900d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 901a681ae63Sjeremylt 902a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 903a681ae63Sjeremylt 904b7c9bbdaSJeremy L Thompson @ref Advanced 905a681ae63Sjeremylt **/ 906a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 907d1d35e2fSjeremylt CeedInt *num_block) { 908d1d35e2fSjeremylt *num_block = rstr->num_blk; 909e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 910a681ae63Sjeremylt } 911a681ae63Sjeremylt 912a681ae63Sjeremylt /** 913a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 914a681ae63Sjeremylt 915a681ae63Sjeremylt @param rstr CeedElemRestriction 916d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 917a681ae63Sjeremylt 918a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 919a681ae63Sjeremylt 920b7c9bbdaSJeremy L Thompson @ref Advanced 921a681ae63Sjeremylt **/ 922a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 923d1d35e2fSjeremylt CeedInt *blk_size) { 924d1d35e2fSjeremylt *blk_size = rstr->blk_size; 925e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 926a681ae63Sjeremylt } 927a681ae63Sjeremylt 928a681ae63Sjeremylt /** 929d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 9301469ee4dSjeremylt 9311469ee4dSjeremylt @param rstr CeedElemRestriction 932d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 9331469ee4dSjeremylt 9341469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 9351469ee4dSjeremylt 9367a982d89SJeremy L. Thompson @ref User 9371469ee4dSjeremylt **/ 9381469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 9391469ee4dSjeremylt CeedVector mult) { 9401469ee4dSjeremylt int ierr; 941d1d35e2fSjeremylt CeedVector e_vec; 9421469ee4dSjeremylt 94325509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 944d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr); 9451469ee4dSjeremylt 94625509ebbSRezgar Shakeri // Compute e_vec = E * 1 94725509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 1.0); CeedChk(ierr); 94825509ebbSRezgar Shakeri ierr = CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, 94925509ebbSRezgar Shakeri CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 95025509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 95125509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 952d1d35e2fSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, 953efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 9541469ee4dSjeremylt // Cleanup 955d1d35e2fSjeremylt ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr); 956e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9571469ee4dSjeremylt } 9581469ee4dSjeremylt 9591469ee4dSjeremylt /** 960f02ca4a2SJed Brown @brief View a CeedElemRestriction 961f02ca4a2SJed Brown 962f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 963f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 964f02ca4a2SJed Brown 965f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 966f02ca4a2SJed Brown 9677a982d89SJeremy L. Thompson @ref User 968f02ca4a2SJed Brown **/ 969f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 9707509a596Sjeremylt char stridesstr[500]; 9717509a596Sjeremylt if (rstr->strides) 9727509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 9737509a596Sjeremylt rstr->strides[2]); 974d979a051Sjeremylt else 975d1d35e2fSjeremylt sprintf(stridesstr, "%d", rstr->comp_stride); 9767509a596Sjeremylt 9770036de2cSjeremylt fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d " 978d1d35e2fSjeremylt "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "", 979d1d35e2fSjeremylt rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 980d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 981e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 982f02ca4a2SJed Brown } 983f02ca4a2SJed Brown 984f02ca4a2SJed Brown /** 985b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 986b11c1e72Sjeremylt 9874ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 988b11c1e72Sjeremylt 989b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 990dfdf5a53Sjeremylt 9917a982d89SJeremy L. Thompson @ref User 992b11c1e72Sjeremylt **/ 9934ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 994d7b241e6Sjeremylt int ierr; 995d7b241e6Sjeremylt 996d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 997d1d35e2fSjeremylt if ((*rstr)->num_readers) 9988229195eSjeremylt // LCOV_EXCL_START 999e15f9bd0SJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, 1000e15f9bd0SJeremy L Thompson "Cannot destroy CeedElemRestriction, " 1001430758c8SJeremy L Thompson "a process has read access to the offset data"); 10028229195eSjeremylt // LCOV_EXCL_STOP 10034ce2993fSjeremylt if ((*rstr)->Destroy) { 10044ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 1005d7b241e6Sjeremylt } 10067509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 10074ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 10084ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 1009e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1010d7b241e6Sjeremylt } 1011d7b241e6Sjeremylt 1012d7b241e6Sjeremylt /// @} 1013