13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 8ec3da8bcSJed Brown #include <ceed/ceed.h> 9ec3da8bcSJed Brown #include <ceed/backend.h> 103d576824SJeremy L Thompson #include <ceed-impl.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 13d7b241e6Sjeremylt 147a982d89SJeremy L. Thompson /// @file 157a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces 167a982d89SJeremy L. Thompson 177a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 187a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions 197a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 207a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper 217a982d89SJeremy L. Thompson /// @{ 227a982d89SJeremy L. Thompson 237a982d89SJeremy L. Thompson /** 24d979a051Sjeremylt @brief Permute and pad offsets for a blocked restriction 257a982d89SJeremy L. Thompson 26d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 27d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 287a982d89SJeremy L. Thompson for the unknowns corresponding to element i, where 29d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 30d1d35e2fSjeremylt [0, @a l_size - 1]. 31d1d35e2fSjeremylt @param blk_offsets Array of permuted and padded offsets of 32d1d35e2fSjeremylt shape [@a num_blk, @a elem_size, @a blk_size]. 33d1d35e2fSjeremylt @param num_blk Number of blocks 34d1d35e2fSjeremylt @param num_elem Number of elements 35d1d35e2fSjeremylt @param blk_size Number of elements in a block 36d1d35e2fSjeremylt @param elem_size Size of each element 377a982d89SJeremy L. Thompson 387a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 397a982d89SJeremy L. Thompson 407a982d89SJeremy L. Thompson @ref Utility 417a982d89SJeremy L. Thompson **/ 42d1d35e2fSjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, 43d1d35e2fSjeremylt CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, 44d1d35e2fSjeremylt CeedInt elem_size) { 45d1d35e2fSjeremylt for (CeedInt e=0; e<num_blk*blk_size; e+=blk_size) 4692ae7e47SJeremy L Thompson for (CeedInt j=0; j<blk_size; j++) 4792ae7e47SJeremy L Thompson for (CeedInt k=0; k<elem_size; k++) 48d1d35e2fSjeremylt blk_offsets[e*elem_size + k*blk_size + j] 49d1d35e2fSjeremylt = offsets[CeedIntMin(e+j,num_elem-1)*elem_size + k]; 50e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 517a982d89SJeremy L. Thompson } 527a982d89SJeremy L. Thompson 537a982d89SJeremy L. Thompson /// @} 547a982d89SJeremy L. Thompson 557a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 567a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 577a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 587a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 597a982d89SJeremy L. Thompson /// @{ 607a982d89SJeremy L. Thompson 617a982d89SJeremy L. Thompson /** 62a681ae63Sjeremylt 63a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 647a982d89SJeremy L. Thompson 657a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 66a681ae63Sjeremylt @param[out] strides Variable to store strides array 677a982d89SJeremy L. Thompson 687a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 697a982d89SJeremy L. Thompson 707a982d89SJeremy L. Thompson @ref Backend 717a982d89SJeremy L. Thompson **/ 72a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 73a681ae63Sjeremylt CeedInt (*strides)[3]) { 74a681ae63Sjeremylt if (!rstr->strides) 75a681ae63Sjeremylt // LCOV_EXCL_START 76e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 77e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 78a681ae63Sjeremylt // LCOV_EXCL_STOP 79a681ae63Sjeremylt 8092ae7e47SJeremy L Thompson for (CeedInt i=0; i<3; i++) 81a681ae63Sjeremylt (*strides)[i] = rstr->strides[i]; 82e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 837a982d89SJeremy L. Thompson } 847a982d89SJeremy L. Thompson 857a982d89SJeremy L. Thompson /** 86bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 87bd33150aSjeremylt 88bd33150aSjeremylt @param rstr CeedElemRestriction to retrieve offsets 89d1d35e2fSjeremylt @param mem_type Memory type on which to access the array. If the backend 90bd33150aSjeremylt uses a different memory type, this will perform a copy 91bd33150aSjeremylt (possibly cached). 92d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 93bd33150aSjeremylt 94bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 95bd33150aSjeremylt 96bd33150aSjeremylt @ref User 97bd33150aSjeremylt **/ 98d1d35e2fSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, 99d1d35e2fSjeremylt CeedMemType mem_type, 100bd33150aSjeremylt const CeedInt **offsets) { 101bd33150aSjeremylt int ierr; 102bd33150aSjeremylt 103bd33150aSjeremylt if (!rstr->GetOffsets) 104bd33150aSjeremylt // LCOV_EXCL_START 105e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED, 106e15f9bd0SJeremy L Thompson "Backend does not support GetOffsets"); 107bd33150aSjeremylt // LCOV_EXCL_STOP 108bd33150aSjeremylt 109d1d35e2fSjeremylt ierr = rstr->GetOffsets(rstr, mem_type, offsets); CeedChk(ierr); 110d1d35e2fSjeremylt rstr->num_readers++; 111e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 112430758c8SJeremy L Thompson } 113430758c8SJeremy L Thompson 114430758c8SJeremy L Thompson /** 115430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 116430758c8SJeremy L Thompson 117430758c8SJeremy L Thompson @param rstr CeedElemRestriction to restore 118430758c8SJeremy L Thompson @param offsets Array of offset data 119430758c8SJeremy L Thompson 120430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 121430758c8SJeremy L Thompson 122430758c8SJeremy L Thompson @ref User 123430758c8SJeremy L Thompson **/ 124430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, 125430758c8SJeremy L Thompson const CeedInt **offsets) { 126430758c8SJeremy L Thompson *offsets = NULL; 127d1d35e2fSjeremylt rstr->num_readers--; 128e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 129bd33150aSjeremylt } 130bd33150aSjeremylt 131bd33150aSjeremylt /** 1323ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1333ac43b2cSJeremy L Thompson 1343ac43b2cSJeremy L Thompson @param rstr CeedElemRestriction 135d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1363ac43b2cSJeremy L Thompson 1373ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1383ac43b2cSJeremy L Thompson 1393ac43b2cSJeremy L Thompson @ref Backend 1403ac43b2cSJeremy L Thompson **/ 141d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 142d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 143e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1443ac43b2cSJeremy L Thompson } 1453ac43b2cSJeremy L Thompson 1463ac43b2cSJeremy L Thompson /** 147b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 148b435c5a6Srezgarshakeri 149b435c5a6Srezgarshakeri @param rstr CeedElemRestriction 150b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 151b435c5a6Srezgarshakeri 152b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 153b435c5a6Srezgarshakeri 154b435c5a6Srezgarshakeri @ref Backend 155b435c5a6Srezgarshakeri **/ 156b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 157b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 158b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 159b435c5a6Srezgarshakeri } 160b435c5a6Srezgarshakeri 161b435c5a6Srezgarshakeri /** 162a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1637a982d89SJeremy L. Thompson 1647a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 16596b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1667a982d89SJeremy L. Thompson 1677a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1687a982d89SJeremy L. Thompson 1697a982d89SJeremy L. Thompson @ref Backend 1707a982d89SJeremy L. Thompson **/ 171fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, 172d1d35e2fSjeremylt bool *has_backend_strides) { 173a681ae63Sjeremylt if (!rstr->strides) 174a681ae63Sjeremylt // LCOV_EXCL_START 175e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 176e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 177a681ae63Sjeremylt // LCOV_EXCL_STOP 1787a982d89SJeremy L. Thompson 179d1d35e2fSjeremylt *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 180a681ae63Sjeremylt (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 181a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 182e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1837a982d89SJeremy L. Thompson } 1847a982d89SJeremy L. Thompson 1857a982d89SJeremy L. Thompson /** 18649fd234cSJeremy L Thompson 18749fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 18849fd234cSJeremy L Thompson 18949fd234cSJeremy L Thompson @param rstr CeedElemRestriction 19049fd234cSJeremy L Thompson @param[out] layout Variable to store layout array, 19149fd234cSJeremy L Thompson stored as [nodes, components, elements]. 19249fd234cSJeremy L Thompson The data for node i, component j, element k in the 19349fd234cSJeremy L Thompson E-vector is given by 19495e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 19549fd234cSJeremy L Thompson 19649fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19749fd234cSJeremy L Thompson 19849fd234cSJeremy L Thompson @ref Backend 19949fd234cSJeremy L Thompson **/ 20049fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, 20149fd234cSJeremy L Thompson CeedInt (*layout)[3]) { 20249fd234cSJeremy L Thompson if (!rstr->layout[0]) 20349fd234cSJeremy L Thompson // LCOV_EXCL_START 204e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 205e15f9bd0SJeremy L Thompson "ElemRestriction has no layout data"); 20649fd234cSJeremy L Thompson // LCOV_EXCL_STOP 20749fd234cSJeremy L Thompson 20892ae7e47SJeremy L Thompson for (CeedInt i=0; i<3; i++) 20949fd234cSJeremy L Thompson (*layout)[i] = rstr->layout[i]; 210e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 21149fd234cSJeremy L Thompson } 21249fd234cSJeremy L Thompson 21349fd234cSJeremy L Thompson /** 21449fd234cSJeremy L Thompson 21549fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 21649fd234cSJeremy L Thompson 21749fd234cSJeremy L Thompson @param rstr CeedElemRestriction 21849fd234cSJeremy L Thompson @param layout Variable to containing layout array, 21949fd234cSJeremy L Thompson stored as [nodes, components, elements]. 22049fd234cSJeremy L Thompson The data for node i, component j, element k in the 22149fd234cSJeremy L Thompson E-vector is given by 22295e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 22349fd234cSJeremy L Thompson 22449fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 22549fd234cSJeremy L Thompson 22649fd234cSJeremy L Thompson @ref Backend 22749fd234cSJeremy L Thompson **/ 22849fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, 22949fd234cSJeremy L Thompson CeedInt layout[3]) { 23092ae7e47SJeremy L Thompson for (CeedInt i = 0; i<3; i++) 23149fd234cSJeremy L Thompson rstr->layout[i] = layout[i]; 232e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 23349fd234cSJeremy L Thompson } 23449fd234cSJeremy L Thompson 23549fd234cSJeremy L Thompson /** 2367a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2377a982d89SJeremy L. Thompson 2387a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 2397a982d89SJeremy L. Thompson @param[out] data Variable to store data 2407a982d89SJeremy L. Thompson 2417a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2427a982d89SJeremy L. Thompson 2437a982d89SJeremy L. Thompson @ref Backend 2447a982d89SJeremy L. Thompson **/ 245777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 246777ff853SJeremy L Thompson *(void **)data = rstr->data; 247e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2487a982d89SJeremy L. Thompson } 2497a982d89SJeremy L. Thompson 2507a982d89SJeremy L. Thompson /** 2517a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2527a982d89SJeremy L. Thompson 2537a982d89SJeremy L. Thompson @param[out] rstr CeedElemRestriction 2547a982d89SJeremy L. Thompson @param data Data to set 2557a982d89SJeremy L. Thompson 2567a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2577a982d89SJeremy L. Thompson 2587a982d89SJeremy L. Thompson @ref Backend 2597a982d89SJeremy L. Thompson **/ 260777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 261777ff853SJeremy L Thompson rstr->data = data; 262e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2637a982d89SJeremy L. Thompson } 2647a982d89SJeremy L. Thompson 26534359f16Sjeremylt /** 26634359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 26734359f16Sjeremylt 26834359f16Sjeremylt @param rstr ElemRestriction to increment the reference counter 26934359f16Sjeremylt 27034359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 27134359f16Sjeremylt 27234359f16Sjeremylt @ref Backend 27334359f16Sjeremylt **/ 2749560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 27534359f16Sjeremylt rstr->ref_count++; 27634359f16Sjeremylt return CEED_ERROR_SUCCESS; 27734359f16Sjeremylt } 27834359f16Sjeremylt 2796e15d496SJeremy L Thompson /** 2806e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 2816e15d496SJeremy L Thompson 2826e15d496SJeremy L Thompson @param rstr ElemRestriction to estimate FLOPs for 2836e15d496SJeremy L Thompson @param t_mode Apply restriction or transpose 2846e15d496SJeremy L Thompson @param flops Address of variable to hold FLOPs estimate 2856e15d496SJeremy L Thompson 2866e15d496SJeremy L Thompson @ref Backend 2876e15d496SJeremy L Thompson **/ 2886e15d496SJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, 2899d36ca50SJeremy L Thompson CeedTransposeMode t_mode, CeedSize *flops) { 2906e15d496SJeremy L Thompson int ierr; 2916e15d496SJeremy L Thompson bool is_oriented; 2926e15d496SJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * 2936e15d496SJeremy L Thompson rstr->num_comp, 2946e15d496SJeremy L Thompson scale = 0; 2956e15d496SJeremy L Thompson 2966e15d496SJeremy L Thompson ierr = CeedElemRestrictionIsOriented(rstr, &is_oriented); CeedChk(ierr); 2976e15d496SJeremy L Thompson switch (t_mode) { 2986e15d496SJeremy L Thompson case CEED_NOTRANSPOSE: scale = is_oriented ? 1 : 0; break; 2996e15d496SJeremy L Thompson case CEED_TRANSPOSE: scale = is_oriented ? 2 : 1; break; 3006e15d496SJeremy L Thompson } 3016e15d496SJeremy L Thompson *flops = e_size * scale; 3026e15d496SJeremy L Thompson 3036e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 3046e15d496SJeremy L Thompson } 3056e15d496SJeremy L Thompson 3067a982d89SJeremy L. Thompson /// @} 3077a982d89SJeremy L. Thompson 30815910d16Sjeremylt /// @cond DOXYGEN_SKIP 30915910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 31015910d16Sjeremylt /// @endcond 31115910d16Sjeremylt 3127a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3137a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 3147a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3157a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 316d7b241e6Sjeremylt /// @{ 317d7b241e6Sjeremylt 3187a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 31945f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 3207a982d89SJeremy L. Thompson 3214cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 3227a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 3237a982d89SJeremy L. Thompson &ceed_elemrestriction_none; 3247a982d89SJeremy L. Thompson 325d7b241e6Sjeremylt /** 326b11c1e72Sjeremylt @brief Create a CeedElemRestriction 327d7b241e6Sjeremylt 328b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 329d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array 330d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 331d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 33295bb1877Svaleriabarra (1 for scalar fields) 333d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 33495e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 33595e93d34SJeremy L Thompson the L-vector at index 336d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 337d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 338d979a051Sjeremylt the elements and fields given by this restriction. 339d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 340d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 341d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 342d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3438795c945Sjeremylt for the unknowns corresponding to element i, where 344d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 345d1d35e2fSjeremylt [0, @a l_size - 1]. 3464ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 347b11c1e72Sjeremylt CeedElemRestriction will be stored 348d7b241e6Sjeremylt 349b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 350dfdf5a53Sjeremylt 3517a982d89SJeremy L. Thompson @ref User 352b11c1e72Sjeremylt **/ 353d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, 354d1d35e2fSjeremylt CeedInt num_comp, CeedInt comp_stride, 355e79b91d9SJeremy L Thompson CeedSize l_size, CeedMemType mem_type, 356d1d35e2fSjeremylt CeedCopyMode copy_mode, const CeedInt *offsets, 3574ce2993fSjeremylt CeedElemRestriction *rstr) { 358d7b241e6Sjeremylt int ierr; 359d7b241e6Sjeremylt 3605fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3615fe0d4faSjeremylt Ceed delegate; 362aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 363aefd8378Sjeremylt CeedChk(ierr); 3645fe0d4faSjeremylt 3655fe0d4faSjeremylt if (!delegate) 366c042f62fSJeremy L Thompson // LCOV_EXCL_START 367e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 368e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 369c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3705fe0d4faSjeremylt 371d1d35e2fSjeremylt ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, 372d1d35e2fSjeremylt comp_stride, l_size, mem_type, copy_mode, 373d979a051Sjeremylt offsets, rstr); CeedChk(ierr); 374e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3755fe0d4faSjeremylt } 3765fe0d4faSjeremylt 377e022e1f8SJeremy L Thompson if (elem_size < 1) 378e022e1f8SJeremy L Thompson // LCOV_EXCL_START 379e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 380e022e1f8SJeremy L Thompson "Element size must be at least 1"); 381e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 382e022e1f8SJeremy L Thompson 383e022e1f8SJeremy L Thompson if (num_comp < 1) 384e022e1f8SJeremy L Thompson // LCOV_EXCL_START 385e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 386e022e1f8SJeremy L Thompson "ElemRestriction must have at least 1 component"); 387e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 388e022e1f8SJeremy L Thompson 3896838cee0SJeremy L Thompson if (num_comp > 1 && comp_stride < 1) 390e022e1f8SJeremy L Thompson // LCOV_EXCL_START 391e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 392e022e1f8SJeremy L Thompson "ElemRestriction component stride must be at least 1"); 393e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 394e022e1f8SJeremy L Thompson 3954ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3964ce2993fSjeremylt (*rstr)->ceed = ceed; 3979560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 398d1d35e2fSjeremylt (*rstr)->ref_count = 1; 399d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 400d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 401d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 402d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 403d1d35e2fSjeremylt (*rstr)->l_size = l_size; 404d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 405d1d35e2fSjeremylt (*rstr)->blk_size = 1; 406b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 407d1d35e2fSjeremylt ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr); 408d979a051Sjeremylt CeedChk(ierr); 409e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 410d7b241e6Sjeremylt } 411d7b241e6Sjeremylt 412d7b241e6Sjeremylt /** 413fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 414fc0567d9Srezgarshakeri 415fc0567d9Srezgarshakeri @param ceed A Ceed object where the CeedElemRestriction will be created 416fc0567d9Srezgarshakeri @param num_elem Number of elements described in the @a offsets array 417fc0567d9Srezgarshakeri @param elem_size Size (number of "nodes") per element 418fc0567d9Srezgarshakeri @param num_comp Number of field components per interpolation node 419fc0567d9Srezgarshakeri (1 for scalar fields) 420fc0567d9Srezgarshakeri @param comp_stride Stride between components for the same L-vector "node". 421fc0567d9Srezgarshakeri Data for node i, component j, element k can be found in 422fc0567d9Srezgarshakeri the L-vector at index 423fc0567d9Srezgarshakeri offsets[i + k*elem_size] + j*comp_stride. 424fc0567d9Srezgarshakeri @param l_size The size of the L-vector. This vector may be larger than 425fc0567d9Srezgarshakeri the elements and fields given by this restriction. 426fc0567d9Srezgarshakeri @param mem_type Memory type of the @a offsets array, see CeedMemType 427fc0567d9Srezgarshakeri @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 428fc0567d9Srezgarshakeri @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 429fc0567d9Srezgarshakeri ordered list of the offsets (into the input CeedVector) 430fc0567d9Srezgarshakeri for the unknowns corresponding to element i, where 431fc0567d9Srezgarshakeri 0 <= i < @a num_elem. All offsets must be in the range 432fc0567d9Srezgarshakeri [0, @a l_size - 1]. 433fc0567d9Srezgarshakeri @param orient Array of shape [@a num_elem, @a elem_size] with bool false 434fc0567d9Srezgarshakeri for positively oriented and true to flip the orientation. 435fc0567d9Srezgarshakeri @param[out] rstr Address of the variable where the newly created 436fc0567d9Srezgarshakeri CeedElemRestriction will be stored 437fc0567d9Srezgarshakeri 438fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 439fc0567d9Srezgarshakeri 440fc0567d9Srezgarshakeri @ref User 441fc0567d9Srezgarshakeri **/ 442fc0567d9Srezgarshakeri int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, 443fc0567d9Srezgarshakeri CeedInt elem_size, CeedInt num_comp, 444e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 445fc0567d9Srezgarshakeri CeedMemType mem_type, CeedCopyMode copy_mode, 446fc0567d9Srezgarshakeri const CeedInt *offsets, const bool *orient, 447fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 448fc0567d9Srezgarshakeri int ierr; 449fc0567d9Srezgarshakeri 450c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 451fc0567d9Srezgarshakeri Ceed delegate; 452fc0567d9Srezgarshakeri ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 453fc0567d9Srezgarshakeri CeedChk(ierr); 454fc0567d9Srezgarshakeri 455fc0567d9Srezgarshakeri if (!delegate) 456fc0567d9Srezgarshakeri // LCOV_EXCL_START 457fc0567d9Srezgarshakeri return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 45861e7462cSRezgar Shakeri "Backend does not implement ElemRestrictionCreateOriented"); 459fc0567d9Srezgarshakeri // LCOV_EXCL_STOP 460fc0567d9Srezgarshakeri 461fc0567d9Srezgarshakeri ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, 462c7745053SRezgar Shakeri num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 4634dd06d33Srezgarshakeri orient, rstr); CeedChk(ierr); 464fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 465fc0567d9Srezgarshakeri } 466fc0567d9Srezgarshakeri 467e022e1f8SJeremy L Thompson if (elem_size < 1) 468e022e1f8SJeremy L Thompson // LCOV_EXCL_START 469e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 470e022e1f8SJeremy L Thompson "Element size must be at least 1"); 471e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 472e022e1f8SJeremy L Thompson 473e022e1f8SJeremy L Thompson if (num_comp < 1) 474e022e1f8SJeremy L Thompson // LCOV_EXCL_START 475e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 476e022e1f8SJeremy L Thompson "ElemRestriction must have at least 1 component"); 477e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 478e022e1f8SJeremy L Thompson 4796838cee0SJeremy L Thompson if (num_comp > 1 && comp_stride < 1) 480e022e1f8SJeremy L Thompson // LCOV_EXCL_START 481e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 482e022e1f8SJeremy L Thompson "ElemRestriction component stride must be at least 1"); 483e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 484e022e1f8SJeremy L Thompson 485fc0567d9Srezgarshakeri ierr = CeedCalloc(1, rstr); CeedChk(ierr); 486fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 487fc0567d9Srezgarshakeri ierr = CeedReference(ceed); CeedChk(ierr); 488fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 489fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 490fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 491fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 492fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 493fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 494fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 495fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 496b435c5a6Srezgarshakeri (*rstr)->is_oriented = 1; 4974dd06d33Srezgarshakeri ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, 4984dd06d33Srezgarshakeri offsets, orient, *rstr); CeedChk(ierr); 499fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 500fc0567d9Srezgarshakeri } 501fc0567d9Srezgarshakeri 502fc0567d9Srezgarshakeri /** 5037509a596Sjeremylt @brief Create a strided CeedElemRestriction 504d7b241e6Sjeremylt 505b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 506d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 507d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 508d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 50995bb1877Svaleriabarra (1 for scalar fields) 510d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 511d979a051Sjeremylt the elements and fields given by this restriction. 5127509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 51395e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 51495e93d34SJeremy L Thompson the L-vector at index 51595e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 51695e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 51795e93d34SJeremy L Thompson by a Ceed backend. 5184ce2993fSjeremylt @param rstr Address of the variable where the newly created 519b11c1e72Sjeremylt CeedElemRestriction will be stored 520d7b241e6Sjeremylt 521b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 522dfdf5a53Sjeremylt 5237a982d89SJeremy L. Thompson @ref User 524b11c1e72Sjeremylt **/ 525d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, 526d1d35e2fSjeremylt CeedInt elem_size, 527e79b91d9SJeremy L Thompson CeedInt num_comp, CeedSize l_size, 5288621c6c6SJeremy L Thompson const CeedInt strides[3], 529f90c8643Sjeremylt CeedElemRestriction *rstr) { 530d7b241e6Sjeremylt int ierr; 531d7b241e6Sjeremylt 5325fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 5335fe0d4faSjeremylt Ceed delegate; 534aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 535aefd8378Sjeremylt CeedChk(ierr); 5365fe0d4faSjeremylt 5375fe0d4faSjeremylt if (!delegate) 538c042f62fSJeremy L Thompson // LCOV_EXCL_START 539e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 540e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 541c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5425fe0d4faSjeremylt 543d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, 544d1d35e2fSjeremylt l_size, strides, rstr); 545d979a051Sjeremylt CeedChk(ierr); 546e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5475fe0d4faSjeremylt } 5485fe0d4faSjeremylt 549e022e1f8SJeremy L Thompson if (elem_size < 1) 550e022e1f8SJeremy L Thompson // LCOV_EXCL_START 551e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 552e022e1f8SJeremy L Thompson "Element size must be at least 1"); 553e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 554e022e1f8SJeremy L Thompson 555e022e1f8SJeremy L Thompson if (num_comp < 1) 556e022e1f8SJeremy L Thompson // LCOV_EXCL_START 557e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 558e022e1f8SJeremy L Thompson "ElemRestriction must have at least 1 component"); 559e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 560e022e1f8SJeremy L Thompson 5614ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 5624ce2993fSjeremylt (*rstr)->ceed = ceed; 5639560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 564d1d35e2fSjeremylt (*rstr)->ref_count = 1; 565d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 566d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 567d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 568d1d35e2fSjeremylt (*rstr)->l_size = l_size; 569d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 570d1d35e2fSjeremylt (*rstr)->blk_size = 1; 571b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 5727509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 57392ae7e47SJeremy L Thompson for (CeedInt i=0; i<3; i++) 5747509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 5751dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 5761dfeef1dSjeremylt *rstr); 5774b8bea3bSJed Brown CeedChk(ierr); 578e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 579d7b241e6Sjeremylt } 580d7b241e6Sjeremylt 581d7b241e6Sjeremylt /** 582b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 583d7b241e6Sjeremylt 584d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 585d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 586d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 587d1d35e2fSjeremylt @param blk_size Number of elements in a block 588d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 58995bb1877Svaleriabarra (1 for scalar fields) 590d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 59195e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 59295e93d34SJeremy L Thompson the L-vector at index 593d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 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. 596d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 597d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 598d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 599d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 6008795c945Sjeremylt for the unknowns corresponding to element i, where 601d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 602d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 6038795c945Sjeremylt array to the desired ordering for the blocksize, which is 6048795c945Sjeremylt typically given by the backend. The default reordering is 6058795c945Sjeremylt to interlace elements. 6064ce2993fSjeremylt @param rstr Address of the variable where the newly created 607b11c1e72Sjeremylt CeedElemRestriction will be stored 608d7b241e6Sjeremylt 609b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 610dfdf5a53Sjeremylt 6117a982d89SJeremy L. Thompson @ref Backend 612b11c1e72Sjeremylt **/ 613d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, 614d1d35e2fSjeremylt CeedInt elem_size, 615d1d35e2fSjeremylt CeedInt blk_size, CeedInt num_comp, 616e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 617d1d35e2fSjeremylt CeedMemType mem_type, CeedCopyMode copy_mode, 618d979a051Sjeremylt const CeedInt *offsets, 6194ce2993fSjeremylt CeedElemRestriction *rstr) { 620d7b241e6Sjeremylt int ierr; 621d1d35e2fSjeremylt CeedInt *blk_offsets; 622d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 623d7b241e6Sjeremylt 6245fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6255fe0d4faSjeremylt Ceed delegate; 626aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 627aefd8378Sjeremylt CeedChk(ierr); 6285fe0d4faSjeremylt 6295fe0d4faSjeremylt if (!delegate) 630c042f62fSJeremy L Thompson // LCOV_EXCL_START 631e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 6321d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 633c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6345fe0d4faSjeremylt 635d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, 636d1d35e2fSjeremylt num_comp, comp_stride, l_size, mem_type, 637d1d35e2fSjeremylt copy_mode, offsets, rstr); 638d979a051Sjeremylt CeedChk(ierr); 639e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6405fe0d4faSjeremylt } 641d7b241e6Sjeremylt 642e022e1f8SJeremy L Thompson if (elem_size < 1) 643e022e1f8SJeremy L Thompson // LCOV_EXCL_START 644e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 645e022e1f8SJeremy L Thompson "Element size must be at least 1"); 646e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 647e022e1f8SJeremy L Thompson 648e022e1f8SJeremy L Thompson if (blk_size < 1) 649e022e1f8SJeremy L Thompson // LCOV_EXCL_START 650e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 651e022e1f8SJeremy L Thompson "Block size must be at least 1"); 652e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 653e022e1f8SJeremy L Thompson 654e022e1f8SJeremy L Thompson if (num_comp < 1) 655e022e1f8SJeremy L Thompson // LCOV_EXCL_START 656e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 657e022e1f8SJeremy L Thompson "ElemRestriction must have at least 1 component"); 658e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 659e022e1f8SJeremy L Thompson 6606838cee0SJeremy L Thompson if (num_comp > 1 && comp_stride < 1) 661e022e1f8SJeremy L Thompson // LCOV_EXCL_START 662e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 663e022e1f8SJeremy L Thompson "ElemRestriction component stride must be at least 1"); 664e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 665e022e1f8SJeremy L Thompson 6664ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 667d7b241e6Sjeremylt 668d1d35e2fSjeremylt ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr); 669d1d35e2fSjeremylt ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, 670d1d35e2fSjeremylt elem_size); CeedChk(ierr); 671d7b241e6Sjeremylt 6724ce2993fSjeremylt (*rstr)->ceed = ceed; 6739560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 674d1d35e2fSjeremylt (*rstr)->ref_count = 1; 675d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 676d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 677d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 678d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 679d1d35e2fSjeremylt (*rstr)->l_size = l_size; 680d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 681d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 682b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 683667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 684d1d35e2fSjeremylt (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr); 685d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 686d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 6871d102b48SJeremy L Thompson } 688e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 689d7b241e6Sjeremylt } 690d7b241e6Sjeremylt 691b11c1e72Sjeremylt /** 6927509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 6937509a596Sjeremylt 6947509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 695d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 696d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 697d1d35e2fSjeremylt @param blk_size Number of elements in a block 698d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 6997509a596Sjeremylt (1 for scalar fields) 700d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 701d979a051Sjeremylt the elements and fields given by this restriction. 7027509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 70395e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 70495e93d34SJeremy L Thompson the L-vector at index 70595e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 70695e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 70795e93d34SJeremy L Thompson by a Ceed backend. 7087509a596Sjeremylt @param rstr Address of the variable where the newly created 7097509a596Sjeremylt CeedElemRestriction will be stored 7107509a596Sjeremylt 7117509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 7127509a596Sjeremylt 7137a982d89SJeremy L. Thompson @ref User 7147509a596Sjeremylt **/ 715d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, 716e79b91d9SJeremy L Thompson CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 7178621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 7187509a596Sjeremylt int ierr; 719d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 7207509a596Sjeremylt 7217509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 7227509a596Sjeremylt Ceed delegate; 7237509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 7247509a596Sjeremylt CeedChk(ierr); 7257509a596Sjeremylt 7267509a596Sjeremylt if (!delegate) 7277509a596Sjeremylt // LCOV_EXCL_START 728e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 7297509a596Sjeremylt "ElemRestrictionCreateBlocked"); 7307509a596Sjeremylt // LCOV_EXCL_STOP 7317509a596Sjeremylt 732d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, 733d1d35e2fSjeremylt blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr); 734e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7357509a596Sjeremylt } 7367509a596Sjeremylt 737e022e1f8SJeremy L Thompson if (elem_size < 1) 738e022e1f8SJeremy L Thompson // LCOV_EXCL_START 739e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 740e022e1f8SJeremy L Thompson "Element size must be at least 1"); 741e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 742e022e1f8SJeremy L Thompson 743e022e1f8SJeremy L Thompson if (blk_size < 1) 744e022e1f8SJeremy L Thompson // LCOV_EXCL_START 745e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 746e022e1f8SJeremy L Thompson "Block size must be at least 1"); 747e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 748e022e1f8SJeremy L Thompson 749e022e1f8SJeremy L Thompson if (num_comp < 1) 750e022e1f8SJeremy L Thompson // LCOV_EXCL_START 751e022e1f8SJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, 752e022e1f8SJeremy L Thompson "ElemRestriction must have at least 1 component"); 753e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 754e022e1f8SJeremy L Thompson 7557509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 7567509a596Sjeremylt 7577509a596Sjeremylt (*rstr)->ceed = ceed; 7589560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 759d1d35e2fSjeremylt (*rstr)->ref_count = 1; 760d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 761d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 762d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 763d1d35e2fSjeremylt (*rstr)->l_size = l_size; 764d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 765d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 766b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 7677509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 76892ae7e47SJeremy L Thompson for (CeedInt i=0; i<3; i++) 7697509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 7707509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 7717509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 772e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7737509a596Sjeremylt } 7747509a596Sjeremylt 7757509a596Sjeremylt /** 7769560d06aSjeremylt @brief Copy the pointer to a CeedElemRestriction. Both pointers should 7779560d06aSjeremylt be destroyed with `CeedElemRestrictionDestroy()`; 7789560d06aSjeremylt Note: If `*rstr_copy` is non-NULL, then it is assumed that 7799560d06aSjeremylt `*rstr_copy` is a pointer to a CeedElemRestriction. This 7809560d06aSjeremylt CeedElemRestriction will be destroyed if `*rstr_copy` is the 7819560d06aSjeremylt only reference to this CeedElemRestriction. 7829560d06aSjeremylt 7839560d06aSjeremylt @param rstr CeedElemRestriction to copy reference to 7849560d06aSjeremylt @param[out] rstr_copy Variable to store copied reference 7859560d06aSjeremylt 7869560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7879560d06aSjeremylt 7889560d06aSjeremylt @ref User 7899560d06aSjeremylt **/ 7909560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, 7919560d06aSjeremylt CeedElemRestriction *rstr_copy) { 7929560d06aSjeremylt int ierr; 7939560d06aSjeremylt 7949560d06aSjeremylt ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr); 7959560d06aSjeremylt ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr); 7969560d06aSjeremylt *rstr_copy = rstr; 7979560d06aSjeremylt return CEED_ERROR_SUCCESS; 7989560d06aSjeremylt } 7999560d06aSjeremylt 8009560d06aSjeremylt /** 801b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 802b11c1e72Sjeremylt 8034ce2993fSjeremylt @param rstr CeedElemRestriction 804d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 805d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 806b11c1e72Sjeremylt 807b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 808dfdf5a53Sjeremylt 8097a982d89SJeremy L. Thompson @ref User 810b11c1e72Sjeremylt **/ 811d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, 812d1d35e2fSjeremylt CeedVector *e_vec) { 813d7b241e6Sjeremylt int ierr; 814d2643443SJeremy L Thompson CeedSize e_size, l_size; 815d1d35e2fSjeremylt l_size = rstr->l_size; 816d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 817d1d35e2fSjeremylt if (l_vec) { 818d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr); 819d7b241e6Sjeremylt } 820d1d35e2fSjeremylt if (e_vec) { 821d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr); 822d7b241e6Sjeremylt } 823e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 824d7b241e6Sjeremylt } 825d7b241e6Sjeremylt 826d7b241e6Sjeremylt /** 827d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 828d7b241e6Sjeremylt 8294ce2993fSjeremylt @param rstr CeedElemRestriction 830d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 831d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 832d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 833d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 8347aaeacdcSjeremylt by the backend. 8354cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 836b11c1e72Sjeremylt 837b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 838dfdf5a53Sjeremylt 8397a982d89SJeremy L. Thompson @ref User 840b11c1e72Sjeremylt **/ 841d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, 842a8d32208Sjeremylt CeedVector u, CeedVector ru, 843a8d32208Sjeremylt CeedRequest *request) { 844d7b241e6Sjeremylt CeedInt m, n; 845d7b241e6Sjeremylt int ierr; 846d7b241e6Sjeremylt 847d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 848d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 849d1d35e2fSjeremylt n = rstr->l_size; 850d7b241e6Sjeremylt } else { 851d1d35e2fSjeremylt m = rstr->l_size; 852d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 853d7b241e6Sjeremylt } 854d7b241e6Sjeremylt if (n != u->length) 855c042f62fSJeremy L Thompson // LCOV_EXCL_START 856e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 857e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 8581d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 859c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 860a8d32208Sjeremylt if (m != ru->length) 861c042f62fSJeremy L Thompson // LCOV_EXCL_START 862e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 863e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 864a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 865c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 866*52b3e6a7SJed Brown if (rstr->num_elem > 0) { 867d1d35e2fSjeremylt ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr); 868*52b3e6a7SJed Brown } 869e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 870d7b241e6Sjeremylt } 871d7b241e6Sjeremylt 872d7b241e6Sjeremylt /** 873d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 874be9261b7Sjeremylt 875be9261b7Sjeremylt @param rstr CeedElemRestriction 8761f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 877d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 878d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 879d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 880d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 881d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 882d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 8837aaeacdcSjeremylt by the backend. 8844cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 885be9261b7Sjeremylt 886be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 887be9261b7Sjeremylt 8887a982d89SJeremy L. Thompson @ref Backend 889be9261b7Sjeremylt **/ 890be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 891d1d35e2fSjeremylt CeedTransposeMode t_mode, CeedVector u, 892a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 893be9261b7Sjeremylt CeedInt m, n; 894be9261b7Sjeremylt int ierr; 895be9261b7Sjeremylt 896d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 897d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 898d1d35e2fSjeremylt n = rstr->l_size; 899be9261b7Sjeremylt } else { 900d1d35e2fSjeremylt m = rstr->l_size; 901d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 902be9261b7Sjeremylt } 903be9261b7Sjeremylt if (n != u->length) 904c042f62fSJeremy L Thompson // LCOV_EXCL_START 905e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 906e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 9071d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 908c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 909a8d32208Sjeremylt if (m != ru->length) 910c042f62fSJeremy L Thompson // LCOV_EXCL_START 911e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 912e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 913a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 914c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 915d1d35e2fSjeremylt if (rstr->blk_size*block > rstr->num_elem) 916c042f62fSJeremy L Thompson // LCOV_EXCL_START 917e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 918e15f9bd0SJeremy L Thompson "Cannot retrieve block %d, element %d > " 919d1d35e2fSjeremylt "total elements %d", block, rstr->blk_size*block, 920d1d35e2fSjeremylt rstr->num_elem); 921c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 922d1d35e2fSjeremylt ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request); 923be9261b7Sjeremylt CeedChk(ierr); 924e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 925be9261b7Sjeremylt } 926be9261b7Sjeremylt 927be9261b7Sjeremylt /** 928b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 929b7c9bbdaSJeremy L Thompson 930b7c9bbdaSJeremy L Thompson @param rstr CeedElemRestriction 931b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 932b7c9bbdaSJeremy L Thompson 933b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 934b7c9bbdaSJeremy L Thompson 935b7c9bbdaSJeremy L Thompson @ref Advanced 936b7c9bbdaSJeremy L Thompson **/ 937b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 938b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 939b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 940b7c9bbdaSJeremy L Thompson } 941b7c9bbdaSJeremy L Thompson 942b7c9bbdaSJeremy L Thompson /** 943d979a051Sjeremylt @brief Get the L-vector component stride 944a681ae63Sjeremylt 945a681ae63Sjeremylt @param rstr CeedElemRestriction 946d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 947a681ae63Sjeremylt 948a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 949a681ae63Sjeremylt 950b7c9bbdaSJeremy L Thompson @ref Advanced 951a681ae63Sjeremylt **/ 952d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 953d1d35e2fSjeremylt CeedInt *comp_stride) { 954d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 955e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 956a681ae63Sjeremylt } 957a681ae63Sjeremylt 958a681ae63Sjeremylt /** 959a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 960a681ae63Sjeremylt 961a681ae63Sjeremylt @param rstr CeedElemRestriction 962d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 963a681ae63Sjeremylt 964a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 965a681ae63Sjeremylt 966b7c9bbdaSJeremy L Thompson @ref Advanced 967a681ae63Sjeremylt **/ 968a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 969d1d35e2fSjeremylt CeedInt *num_elem) { 970d1d35e2fSjeremylt *num_elem = rstr->num_elem; 971e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 972a681ae63Sjeremylt } 973a681ae63Sjeremylt 974a681ae63Sjeremylt /** 975a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 976a681ae63Sjeremylt 977a681ae63Sjeremylt @param rstr CeedElemRestriction 978d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 979a681ae63Sjeremylt 980a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 981a681ae63Sjeremylt 982b7c9bbdaSJeremy L Thompson @ref Advanced 983a681ae63Sjeremylt **/ 984a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 985d1d35e2fSjeremylt CeedInt *elem_size) { 986d1d35e2fSjeremylt *elem_size = rstr->elem_size; 987e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 988a681ae63Sjeremylt } 989a681ae63Sjeremylt 990a681ae63Sjeremylt /** 991d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 992a681ae63Sjeremylt 993a681ae63Sjeremylt @param rstr CeedElemRestriction 994d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 995a681ae63Sjeremylt 996a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 997a681ae63Sjeremylt 998b7c9bbdaSJeremy L Thompson @ref Advanced 999a681ae63Sjeremylt **/ 1000d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 1001e79b91d9SJeremy L Thompson CeedSize *l_size) { 1002d1d35e2fSjeremylt *l_size = rstr->l_size; 1003e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1004a681ae63Sjeremylt } 1005a681ae63Sjeremylt 1006a681ae63Sjeremylt /** 1007a681ae63Sjeremylt @brief Get the number of components in the elements of a 1008a681ae63Sjeremylt CeedElemRestriction 1009a681ae63Sjeremylt 1010a681ae63Sjeremylt @param rstr CeedElemRestriction 1011d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1012a681ae63Sjeremylt 1013a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1014a681ae63Sjeremylt 1015b7c9bbdaSJeremy L Thompson @ref Advanced 1016a681ae63Sjeremylt **/ 1017a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 1018d1d35e2fSjeremylt CeedInt *num_comp) { 1019d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1020e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1021a681ae63Sjeremylt } 1022a681ae63Sjeremylt 1023a681ae63Sjeremylt /** 1024a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1025a681ae63Sjeremylt 1026a681ae63Sjeremylt @param rstr CeedElemRestriction 1027d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1028a681ae63Sjeremylt 1029a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1030a681ae63Sjeremylt 1031b7c9bbdaSJeremy L Thompson @ref Advanced 1032a681ae63Sjeremylt **/ 1033a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 1034d1d35e2fSjeremylt CeedInt *num_block) { 1035d1d35e2fSjeremylt *num_block = rstr->num_blk; 1036e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1037a681ae63Sjeremylt } 1038a681ae63Sjeremylt 1039a681ae63Sjeremylt /** 1040a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1041a681ae63Sjeremylt 1042a681ae63Sjeremylt @param rstr CeedElemRestriction 1043d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 1044a681ae63Sjeremylt 1045a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1046a681ae63Sjeremylt 1047b7c9bbdaSJeremy L Thompson @ref Advanced 1048a681ae63Sjeremylt **/ 1049a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 1050d1d35e2fSjeremylt CeedInt *blk_size) { 1051d1d35e2fSjeremylt *blk_size = rstr->blk_size; 1052e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1053a681ae63Sjeremylt } 1054a681ae63Sjeremylt 1055a681ae63Sjeremylt /** 1056d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 10571469ee4dSjeremylt 10581469ee4dSjeremylt @param rstr CeedElemRestriction 1059d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 10601469ee4dSjeremylt 10611469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 10621469ee4dSjeremylt 10637a982d89SJeremy L. Thompson @ref User 10641469ee4dSjeremylt **/ 10651469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 10661469ee4dSjeremylt CeedVector mult) { 10671469ee4dSjeremylt int ierr; 1068d1d35e2fSjeremylt CeedVector e_vec; 10691469ee4dSjeremylt 107025509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 1071d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr); 10721469ee4dSjeremylt 107325509ebbSRezgar Shakeri // Compute e_vec = E * 1 107425509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 1.0); CeedChk(ierr); 107525509ebbSRezgar Shakeri ierr = CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, 107625509ebbSRezgar Shakeri CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 107725509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 107825509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 1079d1d35e2fSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, 1080efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 10811469ee4dSjeremylt // Cleanup 1082d1d35e2fSjeremylt ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr); 1083e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10841469ee4dSjeremylt } 10851469ee4dSjeremylt 10861469ee4dSjeremylt /** 1087f02ca4a2SJed Brown @brief View a CeedElemRestriction 1088f02ca4a2SJed Brown 1089f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1090f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1091f02ca4a2SJed Brown 1092f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1093f02ca4a2SJed Brown 10947a982d89SJeremy L. Thompson @ref User 1095f02ca4a2SJed Brown **/ 1096f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 10977509a596Sjeremylt char stridesstr[500]; 10987509a596Sjeremylt if (rstr->strides) 10997509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 11007509a596Sjeremylt rstr->strides[2]); 1101d979a051Sjeremylt else 1102d1d35e2fSjeremylt sprintf(stridesstr, "%d", rstr->comp_stride); 11037509a596Sjeremylt 11045b76854bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %d) to %d elements with %d " 1105d1d35e2fSjeremylt "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "", 1106d1d35e2fSjeremylt rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1107d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1108e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1109f02ca4a2SJed Brown } 1110f02ca4a2SJed Brown 1111f02ca4a2SJed Brown /** 1112b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1113b11c1e72Sjeremylt 11144ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 1115b11c1e72Sjeremylt 1116b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1117dfdf5a53Sjeremylt 11187a982d89SJeremy L. Thompson @ref User 1119b11c1e72Sjeremylt **/ 11204ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1121d7b241e6Sjeremylt int ierr; 1122d7b241e6Sjeremylt 1123d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 1124d1d35e2fSjeremylt if ((*rstr)->num_readers) 11258229195eSjeremylt // LCOV_EXCL_START 1126e15f9bd0SJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, 1127e15f9bd0SJeremy L Thompson "Cannot destroy CeedElemRestriction, " 1128430758c8SJeremy L Thompson "a process has read access to the offset data"); 11298229195eSjeremylt // LCOV_EXCL_STOP 11304ce2993fSjeremylt if ((*rstr)->Destroy) { 11314ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 1132d7b241e6Sjeremylt } 11337509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 11344ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 11354ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 1136e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1137d7b241e6Sjeremylt } 1138d7b241e6Sjeremylt 1139d7b241e6Sjeremylt /// @} 1140