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 35*d1d35e2fSjeremylt @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 38*d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 39*d1d35e2fSjeremylt [0, @a l_size - 1]. 40*d1d35e2fSjeremylt @param blk_offsets Array of permuted and padded offsets of 41*d1d35e2fSjeremylt shape [@a num_blk, @a elem_size, @a blk_size]. 42*d1d35e2fSjeremylt @param num_blk Number of blocks 43*d1d35e2fSjeremylt @param num_elem Number of elements 44*d1d35e2fSjeremylt @param blk_size Number of elements in a block 45*d1d35e2fSjeremylt @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 **/ 51*d1d35e2fSjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, 52*d1d35e2fSjeremylt CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, 53*d1d35e2fSjeremylt CeedInt elem_size) { 54*d1d35e2fSjeremylt for (CeedInt e=0; e<num_blk*blk_size; e+=blk_size) 55*d1d35e2fSjeremylt for (int j=0; j<blk_size; j++) 56*d1d35e2fSjeremylt for (int k=0; k<elem_size; k++) 57*d1d35e2fSjeremylt blk_offsets[e*elem_size + k*blk_size + j] 58*d1d35e2fSjeremylt = offsets[CeedIntMin(e+j,num_elem-1)*elem_size + k]; 59e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 607a982d89SJeremy L. Thompson } 617a982d89SJeremy L. Thompson 627a982d89SJeremy L. Thompson /// @} 637a982d89SJeremy L. Thompson 647a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 657a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 667a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 677a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 687a982d89SJeremy L. Thompson /// @{ 697a982d89SJeremy L. Thompson 707a982d89SJeremy L. Thompson /** 717a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedElemRestriction 727a982d89SJeremy L. Thompson 737a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 747a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 757a982d89SJeremy L. Thompson 767a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 777a982d89SJeremy L. Thompson 787a982d89SJeremy L. Thompson @ref Backend 797a982d89SJeremy L. Thompson **/ 807a982d89SJeremy L. Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 817a982d89SJeremy L. Thompson *ceed = rstr->ceed; 82e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 837a982d89SJeremy L. Thompson } 847a982d89SJeremy L. Thompson 857a982d89SJeremy L. Thompson /** 86a681ae63Sjeremylt 87a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 887a982d89SJeremy L. Thompson 897a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 90a681ae63Sjeremylt @param[out] strides Variable to store strides array 917a982d89SJeremy L. Thompson 927a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 937a982d89SJeremy L. Thompson 947a982d89SJeremy L. Thompson @ref Backend 957a982d89SJeremy L. Thompson **/ 96a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 97a681ae63Sjeremylt CeedInt (*strides)[3]) { 98a681ae63Sjeremylt if (!rstr->strides) 99a681ae63Sjeremylt // LCOV_EXCL_START 100e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 101e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 102a681ae63Sjeremylt // LCOV_EXCL_STOP 103a681ae63Sjeremylt 104a681ae63Sjeremylt for (int i=0; i<3; i++) 105a681ae63Sjeremylt (*strides)[i] = rstr->strides[i]; 106e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1077a982d89SJeremy L. Thompson } 1087a982d89SJeremy L. Thompson 1097a982d89SJeremy L. Thompson /** 110bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 111bd33150aSjeremylt 112bd33150aSjeremylt @param rstr CeedElemRestriction to retrieve offsets 113*d1d35e2fSjeremylt @param mem_type Memory type on which to access the array. If the backend 114bd33150aSjeremylt uses a different memory type, this will perform a copy 115bd33150aSjeremylt (possibly cached). 116*d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 117bd33150aSjeremylt 118bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 119bd33150aSjeremylt 120bd33150aSjeremylt @ref User 121bd33150aSjeremylt **/ 122*d1d35e2fSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, 123*d1d35e2fSjeremylt CeedMemType mem_type, 124bd33150aSjeremylt const CeedInt **offsets) { 125bd33150aSjeremylt int ierr; 126bd33150aSjeremylt 127bd33150aSjeremylt if (!rstr->GetOffsets) 128bd33150aSjeremylt // LCOV_EXCL_START 129e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED, 130e15f9bd0SJeremy L Thompson "Backend does not support GetOffsets"); 131bd33150aSjeremylt // LCOV_EXCL_STOP 132bd33150aSjeremylt 133*d1d35e2fSjeremylt ierr = rstr->GetOffsets(rstr, mem_type, offsets); CeedChk(ierr); 134*d1d35e2fSjeremylt rstr->num_readers++; 135e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 136430758c8SJeremy L Thompson } 137430758c8SJeremy L Thompson 138430758c8SJeremy L Thompson /** 139430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 140430758c8SJeremy L Thompson 141430758c8SJeremy L Thompson @param rstr CeedElemRestriction to restore 142430758c8SJeremy L Thompson @param offsets Array of offset data 143430758c8SJeremy L Thompson 144430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 145430758c8SJeremy L Thompson 146430758c8SJeremy L Thompson @ref User 147430758c8SJeremy L Thompson **/ 148430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, 149430758c8SJeremy L Thompson const CeedInt **offsets) { 150430758c8SJeremy L Thompson *offsets = NULL; 151*d1d35e2fSjeremylt rstr->num_readers--; 152e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 153bd33150aSjeremylt } 154bd33150aSjeremylt 155bd33150aSjeremylt /** 1563ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1573ac43b2cSJeremy L Thompson 1583ac43b2cSJeremy L Thompson @param rstr CeedElemRestriction 159*d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1603ac43b2cSJeremy L Thompson 1613ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1623ac43b2cSJeremy L Thompson 1633ac43b2cSJeremy L Thompson @ref Backend 1643ac43b2cSJeremy L Thompson **/ 165*d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 166*d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 167e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1683ac43b2cSJeremy L Thompson } 1693ac43b2cSJeremy L Thompson 1703ac43b2cSJeremy L Thompson /** 171a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1727a982d89SJeremy L. Thompson 1737a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 174a681ae63Sjeremylt @param[out] status 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, 181*d1d35e2fSjeremylt 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 188*d1d35e2fSjeremylt *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 2747a982d89SJeremy L. Thompson /// @} 2757a982d89SJeremy L. Thompson 27615910d16Sjeremylt /// @cond DOXYGEN_SKIP 27715910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 27815910d16Sjeremylt /// @endcond 27915910d16Sjeremylt 2807a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2817a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2827a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2837a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 284d7b241e6Sjeremylt /// @{ 285d7b241e6Sjeremylt 2867a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 2877a982d89SJeremy L. Thompson const CeedInt CEED_STRIDES_BACKEND[3] = {}; 2887a982d89SJeremy L. Thompson 2894cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 2907a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 2917a982d89SJeremy L. Thompson &ceed_elemrestriction_none; 2927a982d89SJeremy L. Thompson 293d7b241e6Sjeremylt /** 294b11c1e72Sjeremylt @brief Create a CeedElemRestriction 295d7b241e6Sjeremylt 296b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 297*d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array 298*d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 299*d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 30095bb1877Svaleriabarra (1 for scalar fields) 301*d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 30295e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 30395e93d34SJeremy L Thompson the L-vector at index 304*d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 305*d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 306d979a051Sjeremylt the elements and fields given by this restriction. 307*d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 308*d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 309*d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 310d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3118795c945Sjeremylt for the unknowns corresponding to element i, where 312*d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 313*d1d35e2fSjeremylt [0, @a l_size - 1]. 3144ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 315b11c1e72Sjeremylt CeedElemRestriction will be stored 316d7b241e6Sjeremylt 317b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 318dfdf5a53Sjeremylt 3197a982d89SJeremy L. Thompson @ref User 320b11c1e72Sjeremylt **/ 321*d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, 322*d1d35e2fSjeremylt CeedInt num_comp, CeedInt comp_stride, 323*d1d35e2fSjeremylt CeedInt l_size, CeedMemType mem_type, 324*d1d35e2fSjeremylt CeedCopyMode copy_mode, const CeedInt *offsets, 3254ce2993fSjeremylt CeedElemRestriction *rstr) { 326d7b241e6Sjeremylt int ierr; 327d7b241e6Sjeremylt 3285fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3295fe0d4faSjeremylt Ceed delegate; 330aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 331aefd8378Sjeremylt CeedChk(ierr); 3325fe0d4faSjeremylt 3335fe0d4faSjeremylt if (!delegate) 334c042f62fSJeremy L Thompson // LCOV_EXCL_START 335e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 336e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 337c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3385fe0d4faSjeremylt 339*d1d35e2fSjeremylt ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, 340*d1d35e2fSjeremylt comp_stride, l_size, mem_type, copy_mode, 341d979a051Sjeremylt offsets, rstr); CeedChk(ierr); 342e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3435fe0d4faSjeremylt } 3445fe0d4faSjeremylt 3454ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3464ce2993fSjeremylt (*rstr)->ceed = ceed; 347*d1d35e2fSjeremylt ceed->ref_count++; 348*d1d35e2fSjeremylt (*rstr)->ref_count = 1; 349*d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 350*d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 351*d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 352*d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 353*d1d35e2fSjeremylt (*rstr)->l_size = l_size; 354*d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 355*d1d35e2fSjeremylt (*rstr)->blk_size = 1; 356*d1d35e2fSjeremylt ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr); 357d979a051Sjeremylt CeedChk(ierr); 358e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 359d7b241e6Sjeremylt } 360d7b241e6Sjeremylt 361d7b241e6Sjeremylt /** 3627509a596Sjeremylt @brief Create a strided CeedElemRestriction 363d7b241e6Sjeremylt 364b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 365*d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 366*d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 367*d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 36895bb1877Svaleriabarra (1 for scalar fields) 369*d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 370d979a051Sjeremylt the elements and fields given by this restriction. 3717509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 37295e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 37395e93d34SJeremy L Thompson the L-vector at index 37495e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 37595e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 37695e93d34SJeremy L Thompson by a Ceed backend. 3774ce2993fSjeremylt @param rstr Address of the variable where the newly created 378b11c1e72Sjeremylt CeedElemRestriction will be stored 379d7b241e6Sjeremylt 380b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 381dfdf5a53Sjeremylt 3827a982d89SJeremy L. Thompson @ref User 383b11c1e72Sjeremylt **/ 384*d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, 385*d1d35e2fSjeremylt CeedInt elem_size, 386*d1d35e2fSjeremylt CeedInt num_comp, CeedInt l_size, 3878621c6c6SJeremy L Thompson const CeedInt strides[3], 388f90c8643Sjeremylt CeedElemRestriction *rstr) { 389d7b241e6Sjeremylt int ierr; 390d7b241e6Sjeremylt 3915fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3925fe0d4faSjeremylt Ceed delegate; 393aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 394aefd8378Sjeremylt CeedChk(ierr); 3955fe0d4faSjeremylt 3965fe0d4faSjeremylt if (!delegate) 397c042f62fSJeremy L Thompson // LCOV_EXCL_START 398e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 399e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 400c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4015fe0d4faSjeremylt 402*d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, 403*d1d35e2fSjeremylt l_size, strides, rstr); 404d979a051Sjeremylt CeedChk(ierr); 405e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4065fe0d4faSjeremylt } 4075fe0d4faSjeremylt 4084ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 4094ce2993fSjeremylt (*rstr)->ceed = ceed; 410*d1d35e2fSjeremylt ceed->ref_count++; 411*d1d35e2fSjeremylt (*rstr)->ref_count = 1; 412*d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 413*d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 414*d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 415*d1d35e2fSjeremylt (*rstr)->l_size = l_size; 416*d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 417*d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4187509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 4197509a596Sjeremylt for (int i=0; i<3; i++) 4207509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 4211dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 4221dfeef1dSjeremylt *rstr); 4234b8bea3bSJed Brown CeedChk(ierr); 424e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 425d7b241e6Sjeremylt } 426d7b241e6Sjeremylt 427d7b241e6Sjeremylt /** 428b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 429d7b241e6Sjeremylt 430d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 431*d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 432*d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 433*d1d35e2fSjeremylt @param blk_size Number of elements in a block 434*d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 43595bb1877Svaleriabarra (1 for scalar fields) 436*d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 43795e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 43895e93d34SJeremy L Thompson the L-vector at index 439*d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 440*d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 441d979a051Sjeremylt the elements and fields given by this restriction. 442*d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 443*d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 444*d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 445d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 4468795c945Sjeremylt for the unknowns corresponding to element i, where 447*d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 448*d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 4498795c945Sjeremylt array to the desired ordering for the blocksize, which is 4508795c945Sjeremylt typically given by the backend. The default reordering is 4518795c945Sjeremylt to interlace elements. 4524ce2993fSjeremylt @param rstr Address of the variable where the newly created 453b11c1e72Sjeremylt CeedElemRestriction will be stored 454d7b241e6Sjeremylt 455b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 456dfdf5a53Sjeremylt 4577a982d89SJeremy L. Thompson @ref Backend 458b11c1e72Sjeremylt **/ 459*d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, 460*d1d35e2fSjeremylt CeedInt elem_size, 461*d1d35e2fSjeremylt CeedInt blk_size, CeedInt num_comp, 462*d1d35e2fSjeremylt CeedInt comp_stride, CeedInt l_size, 463*d1d35e2fSjeremylt CeedMemType mem_type, CeedCopyMode copy_mode, 464d979a051Sjeremylt const CeedInt *offsets, 4654ce2993fSjeremylt CeedElemRestriction *rstr) { 466d7b241e6Sjeremylt int ierr; 467*d1d35e2fSjeremylt CeedInt *blk_offsets; 468*d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 469d7b241e6Sjeremylt 4705fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 4715fe0d4faSjeremylt Ceed delegate; 472aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 473aefd8378Sjeremylt CeedChk(ierr); 4745fe0d4faSjeremylt 4755fe0d4faSjeremylt if (!delegate) 476c042f62fSJeremy L Thompson // LCOV_EXCL_START 477e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 4781d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 479c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4805fe0d4faSjeremylt 481*d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, 482*d1d35e2fSjeremylt num_comp, comp_stride, l_size, mem_type, 483*d1d35e2fSjeremylt copy_mode, offsets, rstr); 484d979a051Sjeremylt CeedChk(ierr); 485e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4865fe0d4faSjeremylt } 487d7b241e6Sjeremylt 4884ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 489d7b241e6Sjeremylt 490*d1d35e2fSjeremylt ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr); 491*d1d35e2fSjeremylt ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, 492*d1d35e2fSjeremylt elem_size); CeedChk(ierr); 493d7b241e6Sjeremylt 4944ce2993fSjeremylt (*rstr)->ceed = ceed; 495*d1d35e2fSjeremylt ceed->ref_count++; 496*d1d35e2fSjeremylt (*rstr)->ref_count = 1; 497*d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 498*d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 499*d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 500*d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 501*d1d35e2fSjeremylt (*rstr)->l_size = l_size; 502*d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 503*d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 504667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 505*d1d35e2fSjeremylt (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr); 506*d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 507d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 5081d102b48SJeremy L Thompson } 509e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 510d7b241e6Sjeremylt } 511d7b241e6Sjeremylt 512b11c1e72Sjeremylt /** 5137509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5147509a596Sjeremylt 5157509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 516*d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 517*d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 518*d1d35e2fSjeremylt @param blk_size Number of elements in a block 519*d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 5207509a596Sjeremylt (1 for scalar fields) 521*d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 522d979a051Sjeremylt the elements and fields given by this restriction. 5237509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 52495e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 52595e93d34SJeremy L Thompson the L-vector at index 52695e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 52795e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 52895e93d34SJeremy L Thompson by a Ceed backend. 5297509a596Sjeremylt @param rstr Address of the variable where the newly created 5307509a596Sjeremylt CeedElemRestriction will be stored 5317509a596Sjeremylt 5327509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 5337509a596Sjeremylt 5347a982d89SJeremy L. Thompson @ref User 5357509a596Sjeremylt **/ 536*d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, 537*d1d35e2fSjeremylt CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt l_size, 5388621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 5397509a596Sjeremylt int ierr; 540*d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 5417509a596Sjeremylt 5427509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5437509a596Sjeremylt Ceed delegate; 5447509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 5457509a596Sjeremylt CeedChk(ierr); 5467509a596Sjeremylt 5477509a596Sjeremylt if (!delegate) 5487509a596Sjeremylt // LCOV_EXCL_START 549e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 5507509a596Sjeremylt "ElemRestrictionCreateBlocked"); 5517509a596Sjeremylt // LCOV_EXCL_STOP 5527509a596Sjeremylt 553*d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, 554*d1d35e2fSjeremylt blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr); 555e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5567509a596Sjeremylt } 5577509a596Sjeremylt 5587509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 5597509a596Sjeremylt 5607509a596Sjeremylt (*rstr)->ceed = ceed; 561*d1d35e2fSjeremylt ceed->ref_count++; 562*d1d35e2fSjeremylt (*rstr)->ref_count = 1; 563*d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 564*d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 565*d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 566*d1d35e2fSjeremylt (*rstr)->l_size = l_size; 567*d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 568*d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5697509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 5707509a596Sjeremylt for (int i=0; i<3; i++) 5717509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 5727509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 5737509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 574e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5757509a596Sjeremylt } 5767509a596Sjeremylt 5777509a596Sjeremylt /** 578b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 579b11c1e72Sjeremylt 5804ce2993fSjeremylt @param rstr CeedElemRestriction 581*d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 582*d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 583b11c1e72Sjeremylt 584b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 585dfdf5a53Sjeremylt 5867a982d89SJeremy L. Thompson @ref User 587b11c1e72Sjeremylt **/ 588*d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, 589*d1d35e2fSjeremylt CeedVector *e_vec) { 590d7b241e6Sjeremylt int ierr; 591*d1d35e2fSjeremylt CeedInt e_size, l_size; 592*d1d35e2fSjeremylt l_size = rstr->l_size; 593*d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 594*d1d35e2fSjeremylt if (l_vec) { 595*d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr); 596d7b241e6Sjeremylt } 597*d1d35e2fSjeremylt if (e_vec) { 598*d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr); 599d7b241e6Sjeremylt } 600e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 601d7b241e6Sjeremylt } 602d7b241e6Sjeremylt 603d7b241e6Sjeremylt /** 604d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 605d7b241e6Sjeremylt 6064ce2993fSjeremylt @param rstr CeedElemRestriction 607*d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 608*d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 609*d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 610*d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 6117aaeacdcSjeremylt by the backend. 6124cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 613b11c1e72Sjeremylt 614b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 615dfdf5a53Sjeremylt 6167a982d89SJeremy L. Thompson @ref User 617b11c1e72Sjeremylt **/ 618*d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, 619a8d32208Sjeremylt CeedVector u, CeedVector ru, 620a8d32208Sjeremylt CeedRequest *request) { 621d7b241e6Sjeremylt CeedInt m, n; 622d7b241e6Sjeremylt int ierr; 623d7b241e6Sjeremylt 624*d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 625*d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 626*d1d35e2fSjeremylt n = rstr->l_size; 627d7b241e6Sjeremylt } else { 628*d1d35e2fSjeremylt m = rstr->l_size; 629*d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 630d7b241e6Sjeremylt } 631d7b241e6Sjeremylt if (n != u->length) 632c042f62fSJeremy L Thompson // LCOV_EXCL_START 633e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 634e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 6351d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 636c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 637a8d32208Sjeremylt if (m != ru->length) 638c042f62fSJeremy L Thompson // LCOV_EXCL_START 639e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 640e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 641a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 642c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 643*d1d35e2fSjeremylt ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr); 644e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 645d7b241e6Sjeremylt } 646d7b241e6Sjeremylt 647d7b241e6Sjeremylt /** 648d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 649be9261b7Sjeremylt 650be9261b7Sjeremylt @param rstr CeedElemRestriction 6511f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 652*d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 653*d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 654*d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 655*d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 656*d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 657*d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 6587aaeacdcSjeremylt by the backend. 6594cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 660be9261b7Sjeremylt 661be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 662be9261b7Sjeremylt 6637a982d89SJeremy L. Thompson @ref Backend 664be9261b7Sjeremylt **/ 665be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 666*d1d35e2fSjeremylt CeedTransposeMode t_mode, CeedVector u, 667a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 668be9261b7Sjeremylt CeedInt m, n; 669be9261b7Sjeremylt int ierr; 670be9261b7Sjeremylt 671*d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 672*d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 673*d1d35e2fSjeremylt n = rstr->l_size; 674be9261b7Sjeremylt } else { 675*d1d35e2fSjeremylt m = rstr->l_size; 676*d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 677be9261b7Sjeremylt } 678be9261b7Sjeremylt if (n != u->length) 679c042f62fSJeremy L Thompson // LCOV_EXCL_START 680e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 681e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 6821d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 683c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 684a8d32208Sjeremylt if (m != ru->length) 685c042f62fSJeremy L Thompson // LCOV_EXCL_START 686e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 687e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 688a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 689c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 690*d1d35e2fSjeremylt if (rstr->blk_size*block > rstr->num_elem) 691c042f62fSJeremy L Thompson // LCOV_EXCL_START 692e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 693e15f9bd0SJeremy L Thompson "Cannot retrieve block %d, element %d > " 694*d1d35e2fSjeremylt "total elements %d", block, rstr->blk_size*block, 695*d1d35e2fSjeremylt rstr->num_elem); 696c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 697*d1d35e2fSjeremylt ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request); 698be9261b7Sjeremylt CeedChk(ierr); 699e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 700be9261b7Sjeremylt } 701be9261b7Sjeremylt 702be9261b7Sjeremylt /** 703d979a051Sjeremylt @brief Get the L-vector component stride 704a681ae63Sjeremylt 705a681ae63Sjeremylt @param rstr CeedElemRestriction 706*d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 707a681ae63Sjeremylt 708a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 709a681ae63Sjeremylt 710a681ae63Sjeremylt @ref Backend 711a681ae63Sjeremylt **/ 712d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 713*d1d35e2fSjeremylt CeedInt *comp_stride) { 714*d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 715e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 716a681ae63Sjeremylt } 717a681ae63Sjeremylt 718a681ae63Sjeremylt /** 719a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 720a681ae63Sjeremylt 721a681ae63Sjeremylt @param rstr CeedElemRestriction 722*d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 723a681ae63Sjeremylt 724a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 725a681ae63Sjeremylt 726a681ae63Sjeremylt @ref Backend 727a681ae63Sjeremylt **/ 728a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 729*d1d35e2fSjeremylt CeedInt *num_elem) { 730*d1d35e2fSjeremylt *num_elem = rstr->num_elem; 731e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 732a681ae63Sjeremylt } 733a681ae63Sjeremylt 734a681ae63Sjeremylt /** 735a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 736a681ae63Sjeremylt 737a681ae63Sjeremylt @param rstr CeedElemRestriction 738*d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 739a681ae63Sjeremylt 740a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 741a681ae63Sjeremylt 742a681ae63Sjeremylt @ref Backend 743a681ae63Sjeremylt **/ 744a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 745*d1d35e2fSjeremylt CeedInt *elem_size) { 746*d1d35e2fSjeremylt *elem_size = rstr->elem_size; 747e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 748a681ae63Sjeremylt } 749a681ae63Sjeremylt 750a681ae63Sjeremylt /** 751d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 752a681ae63Sjeremylt 753a681ae63Sjeremylt @param rstr CeedElemRestriction 754*d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 755a681ae63Sjeremylt 756a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 757a681ae63Sjeremylt 758a681ae63Sjeremylt @ref Backend 759a681ae63Sjeremylt **/ 760d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 761*d1d35e2fSjeremylt CeedInt *l_size) { 762*d1d35e2fSjeremylt *l_size = rstr->l_size; 763e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 764a681ae63Sjeremylt } 765a681ae63Sjeremylt 766a681ae63Sjeremylt /** 767a681ae63Sjeremylt @brief Get the number of components in the elements of a 768a681ae63Sjeremylt CeedElemRestriction 769a681ae63Sjeremylt 770a681ae63Sjeremylt @param rstr CeedElemRestriction 771*d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 772a681ae63Sjeremylt 773a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 774a681ae63Sjeremylt 775a681ae63Sjeremylt @ref Backend 776a681ae63Sjeremylt **/ 777a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 778*d1d35e2fSjeremylt CeedInt *num_comp) { 779*d1d35e2fSjeremylt *num_comp = rstr->num_comp; 780e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 781a681ae63Sjeremylt } 782a681ae63Sjeremylt 783a681ae63Sjeremylt /** 784a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 785a681ae63Sjeremylt 786a681ae63Sjeremylt @param rstr CeedElemRestriction 787*d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 788a681ae63Sjeremylt 789a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 790a681ae63Sjeremylt 791a681ae63Sjeremylt @ref Backend 792a681ae63Sjeremylt **/ 793a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 794*d1d35e2fSjeremylt CeedInt *num_block) { 795*d1d35e2fSjeremylt *num_block = rstr->num_blk; 796e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 797a681ae63Sjeremylt } 798a681ae63Sjeremylt 799a681ae63Sjeremylt /** 800a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 801a681ae63Sjeremylt 802a681ae63Sjeremylt @param rstr CeedElemRestriction 803*d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 804a681ae63Sjeremylt 805a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 806a681ae63Sjeremylt 807a681ae63Sjeremylt @ref Backend 808a681ae63Sjeremylt **/ 809a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 810*d1d35e2fSjeremylt CeedInt *blk_size) { 811*d1d35e2fSjeremylt *blk_size = rstr->blk_size; 812e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 813a681ae63Sjeremylt } 814a681ae63Sjeremylt 815a681ae63Sjeremylt /** 816d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 8171469ee4dSjeremylt 8181469ee4dSjeremylt @param rstr CeedElemRestriction 819*d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 8201469ee4dSjeremylt 8211469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 8221469ee4dSjeremylt 8237a982d89SJeremy L. Thompson @ref User 8241469ee4dSjeremylt **/ 8251469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 8261469ee4dSjeremylt CeedVector mult) { 8271469ee4dSjeremylt int ierr; 828*d1d35e2fSjeremylt CeedVector e_vec; 8291469ee4dSjeremylt 830*d1d35e2fSjeremylt // Create and set e_vec 831*d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr); 832*d1d35e2fSjeremylt ierr = CeedVectorSetValue(e_vec, 1.0); CeedChk(ierr); 833fa9eac48SJed Brown ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 8341469ee4dSjeremylt 8351469ee4dSjeremylt // Apply to get multiplicity 836*d1d35e2fSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, 837efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 8381469ee4dSjeremylt 8391469ee4dSjeremylt // Cleanup 840*d1d35e2fSjeremylt ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr); 841e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8421469ee4dSjeremylt } 8431469ee4dSjeremylt 8441469ee4dSjeremylt /** 845f02ca4a2SJed Brown @brief View a CeedElemRestriction 846f02ca4a2SJed Brown 847f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 848f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 849f02ca4a2SJed Brown 850f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 851f02ca4a2SJed Brown 8527a982d89SJeremy L. Thompson @ref User 853f02ca4a2SJed Brown **/ 854f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 8557509a596Sjeremylt char stridesstr[500]; 8567509a596Sjeremylt if (rstr->strides) 8577509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 8587509a596Sjeremylt rstr->strides[2]); 859d979a051Sjeremylt else 860*d1d35e2fSjeremylt sprintf(stridesstr, "%d", rstr->comp_stride); 8617509a596Sjeremylt 8620036de2cSjeremylt fprintf(stream, "%sCeedElemRestriction from (%d, %d) to %d elements with %d " 863*d1d35e2fSjeremylt "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "", 864*d1d35e2fSjeremylt rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 865d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 866e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 867f02ca4a2SJed Brown } 868f02ca4a2SJed Brown 869f02ca4a2SJed Brown /** 870b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 871b11c1e72Sjeremylt 8724ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 873b11c1e72Sjeremylt 874b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 875dfdf5a53Sjeremylt 8767a982d89SJeremy L. Thompson @ref User 877b11c1e72Sjeremylt **/ 8784ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 879d7b241e6Sjeremylt int ierr; 880d7b241e6Sjeremylt 881*d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 882*d1d35e2fSjeremylt if ((*rstr)->num_readers) 883e15f9bd0SJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, 884e15f9bd0SJeremy L Thompson "Cannot destroy CeedElemRestriction, " 885430758c8SJeremy L Thompson "a process has read access to the offset data"); 8864ce2993fSjeremylt if ((*rstr)->Destroy) { 8874ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 888d7b241e6Sjeremylt } 8897509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 8904ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 8914ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 892e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 893d7b241e6Sjeremylt } 894d7b241e6Sjeremylt 895d7b241e6Sjeremylt /// @} 896