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 83d576824SJeremy L Thompson #include <ceed-impl.h> 92b730f8bSJeremy L Thompson #include <ceed/backend.h> 102b730f8bSJeremy L Thompson #include <ceed/ceed.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 26ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 27ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 28ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 29ea61e9acSJeremy L Thompson @param[out] blk_offsets Array of permuted and padded offsets of shape [@a num_blk, @a elem_size, @a blk_size]. 30ea61e9acSJeremy L Thompson @param[in] num_blk Number of blocks 31ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 32ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 33ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 347a982d89SJeremy L. Thompson 357a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 367a982d89SJeremy L. Thompson 377a982d89SJeremy L. Thompson @ref Utility 387a982d89SJeremy L. Thompson **/ 392b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 402b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 412b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 422b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 432b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 442b730f8bSJeremy L Thompson } 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 47e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 487a982d89SJeremy L. Thompson } 497a982d89SJeremy L. Thompson 507a982d89SJeremy L. Thompson /// @} 517a982d89SJeremy L. Thompson 527a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 537a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 547a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 557a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 567a982d89SJeremy L. Thompson /// @{ 577a982d89SJeremy L. Thompson 587a982d89SJeremy L. Thompson /** 59a681ae63Sjeremylt 60a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 617a982d89SJeremy L. Thompson 62ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 63a681ae63Sjeremylt @param[out] strides Variable to store strides array 647a982d89SJeremy L. Thompson 657a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 667a982d89SJeremy L. Thompson 677a982d89SJeremy L. Thompson @ref Backend 687a982d89SJeremy L. Thompson **/ 692b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 702b730f8bSJeremy L Thompson if (!rstr->strides) { 71a681ae63Sjeremylt // LCOV_EXCL_START 722b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 73a681ae63Sjeremylt // LCOV_EXCL_STOP 742b730f8bSJeremy L Thompson } 75a681ae63Sjeremylt 762b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 77e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 787a982d89SJeremy L. Thompson } 797a982d89SJeremy L. Thompson 807a982d89SJeremy L. Thompson /** 81bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 82bd33150aSjeremylt 83ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 84ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the array. 85ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy (possibly cached). 86d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 87bd33150aSjeremylt 88bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 89bd33150aSjeremylt 90bd33150aSjeremylt @ref User 91bd33150aSjeremylt **/ 922b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 932b730f8bSJeremy L Thompson if (!rstr->GetOffsets) { 94bd33150aSjeremylt // LCOV_EXCL_START 952b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 96bd33150aSjeremylt // LCOV_EXCL_STOP 972b730f8bSJeremy L Thompson } 98bd33150aSjeremylt 992b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 100d1d35e2fSjeremylt rstr->num_readers++; 101e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 102430758c8SJeremy L Thompson } 103430758c8SJeremy L Thompson 104430758c8SJeremy L Thompson /** 105430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 106430758c8SJeremy L Thompson 107ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 108ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 109430758c8SJeremy L Thompson 110430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 111430758c8SJeremy L Thompson 112430758c8SJeremy L Thompson @ref User 113430758c8SJeremy L Thompson **/ 1142b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 115430758c8SJeremy L Thompson *offsets = NULL; 116d1d35e2fSjeremylt rstr->num_readers--; 117e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 118bd33150aSjeremylt } 119bd33150aSjeremylt 120bd33150aSjeremylt /** 1213ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1223ac43b2cSJeremy L Thompson 123ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 124d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1253ac43b2cSJeremy L Thompson 1263ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1273ac43b2cSJeremy L Thompson 1283ac43b2cSJeremy L Thompson @ref Backend 1293ac43b2cSJeremy L Thompson **/ 130d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 131d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 132e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1333ac43b2cSJeremy L Thompson } 1343ac43b2cSJeremy L Thompson 1353ac43b2cSJeremy L Thompson /** 136b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 137b435c5a6Srezgarshakeri 138ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 139b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 140b435c5a6Srezgarshakeri 141b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 142b435c5a6Srezgarshakeri 143b435c5a6Srezgarshakeri @ref Backend 144b435c5a6Srezgarshakeri **/ 145b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 146b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 147b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 148b435c5a6Srezgarshakeri } 149b435c5a6Srezgarshakeri 150b435c5a6Srezgarshakeri /** 151a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1527a982d89SJeremy L. Thompson 153ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 15496b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1557a982d89SJeremy L. Thompson 1567a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1577a982d89SJeremy L. Thompson 1587a982d89SJeremy L. Thompson @ref Backend 1597a982d89SJeremy L. Thompson **/ 1602b730f8bSJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 1612b730f8bSJeremy L Thompson if (!rstr->strides) { 162a681ae63Sjeremylt // LCOV_EXCL_START 1632b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 164a681ae63Sjeremylt // LCOV_EXCL_STOP 1652b730f8bSJeremy L Thompson } 1667a982d89SJeremy L. Thompson 1672b730f8bSJeremy L Thompson *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 168a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 169e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1707a982d89SJeremy L. Thompson } 1717a982d89SJeremy L. Thompson 1727a982d89SJeremy L. Thompson /** 17349fd234cSJeremy L Thompson 17449fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 17549fd234cSJeremy L Thompson 176ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 177ea61e9acSJeremy L Thompson @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 178ea61e9acSJeremy L Thompson The data for node i, component j, element k in the E-vector is given by i*layout[0] + j*layout[1] + k*layout[2] 17949fd234cSJeremy L Thompson 18049fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 18149fd234cSJeremy L Thompson 18249fd234cSJeremy L Thompson @ref Backend 18349fd234cSJeremy L Thompson **/ 1842b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 1852b730f8bSJeremy L Thompson if (!rstr->layout[0]) { 18649fd234cSJeremy L Thompson // LCOV_EXCL_START 1872b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 18849fd234cSJeremy L Thompson // LCOV_EXCL_STOP 1892b730f8bSJeremy L Thompson } 19049fd234cSJeremy L Thompson 1912b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 192e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 19349fd234cSJeremy L Thompson } 19449fd234cSJeremy L Thompson 19549fd234cSJeremy L Thompson /** 19649fd234cSJeremy L Thompson 19749fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 19849fd234cSJeremy L Thompson 199ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 200ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 201ea61e9acSJeremy L Thompson The data for node i, component j, element k in the E-vector is given by i*layout[0] + j*layout[1] + k*layout[2] 20249fd234cSJeremy L Thompson 20349fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 20449fd234cSJeremy L Thompson 20549fd234cSJeremy L Thompson @ref Backend 20649fd234cSJeremy L Thompson **/ 2072b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 2082b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 209e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 21049fd234cSJeremy L Thompson } 21149fd234cSJeremy L Thompson 21249fd234cSJeremy L Thompson /** 2137a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2147a982d89SJeremy L. Thompson 215ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 2167a982d89SJeremy L. Thompson @param[out] data Variable to store data 2177a982d89SJeremy L. Thompson 2187a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2197a982d89SJeremy L. Thompson 2207a982d89SJeremy L. Thompson @ref Backend 2217a982d89SJeremy L. Thompson **/ 222777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 223777ff853SJeremy L Thompson *(void **)data = rstr->data; 224e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2257a982d89SJeremy L. Thompson } 2267a982d89SJeremy L. Thompson 2277a982d89SJeremy L. Thompson /** 2287a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2297a982d89SJeremy L. Thompson 230ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 231ea61e9acSJeremy L Thompson @param[in] data Data to set 2327a982d89SJeremy L. Thompson 2337a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2347a982d89SJeremy L. Thompson 2357a982d89SJeremy L. Thompson @ref Backend 2367a982d89SJeremy L. Thompson **/ 237777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 238777ff853SJeremy L Thompson rstr->data = data; 239e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2407a982d89SJeremy L. Thompson } 2417a982d89SJeremy L. Thompson 24234359f16Sjeremylt /** 24334359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 24434359f16Sjeremylt 245ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 24634359f16Sjeremylt 24734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 24834359f16Sjeremylt 24934359f16Sjeremylt @ref Backend 25034359f16Sjeremylt **/ 2519560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 25234359f16Sjeremylt rstr->ref_count++; 25334359f16Sjeremylt return CEED_ERROR_SUCCESS; 25434359f16Sjeremylt } 25534359f16Sjeremylt 2566e15d496SJeremy L Thompson /** 2576e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 2586e15d496SJeremy L Thompson 259ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 260ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 261ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 2626e15d496SJeremy L Thompson 2636e15d496SJeremy L Thompson @ref Backend 2646e15d496SJeremy L Thompson **/ 2652b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 2666e15d496SJeremy L Thompson bool is_oriented; 2672b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 2686e15d496SJeremy L Thompson 2692b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionIsOriented(rstr, &is_oriented)); 2706e15d496SJeremy L Thompson switch (t_mode) { 2712b730f8bSJeremy L Thompson case CEED_NOTRANSPOSE: 2722b730f8bSJeremy L Thompson scale = is_oriented ? 1 : 0; 2732b730f8bSJeremy L Thompson break; 2742b730f8bSJeremy L Thompson case CEED_TRANSPOSE: 2752b730f8bSJeremy L Thompson scale = is_oriented ? 2 : 1; 2762b730f8bSJeremy L Thompson break; 2776e15d496SJeremy L Thompson } 2786e15d496SJeremy L Thompson *flops = e_size * scale; 2796e15d496SJeremy L Thompson 2806e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 2816e15d496SJeremy L Thompson } 2826e15d496SJeremy L Thompson 2837a982d89SJeremy L. Thompson /// @} 2847a982d89SJeremy L. Thompson 28515910d16Sjeremylt /// @cond DOXYGEN_SKIP 28615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 28715910d16Sjeremylt /// @endcond 28815910d16Sjeremylt 2897a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2907a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2917a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2927a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 293d7b241e6Sjeremylt /// @{ 294d7b241e6Sjeremylt 2957a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 29645f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 2977a982d89SJeremy L. Thompson 2984cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 2992b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 3007a982d89SJeremy L. Thompson 301d7b241e6Sjeremylt /** 302b11c1e72Sjeremylt @brief Create a CeedElemRestriction 303d7b241e6Sjeremylt 304ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 305ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 306ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 307ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 308ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 309ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index offsets[i + k*elem_size] + j*comp_stride. 310ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 311ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 312ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 313ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 314ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 315ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 316ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 317ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 318d7b241e6Sjeremylt 319b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 320dfdf5a53Sjeremylt 3217a982d89SJeremy L. Thompson @ref User 322b11c1e72Sjeremylt **/ 3232b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 3242b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 3255fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3265fe0d4faSjeremylt Ceed delegate; 3272b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 3285fe0d4faSjeremylt 3292b730f8bSJeremy L Thompson if (!delegate) { 330c042f62fSJeremy L Thompson // LCOV_EXCL_START 3312b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreate"); 332c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3332b730f8bSJeremy L Thompson } 3345fe0d4faSjeremylt 3352b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 336e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3375fe0d4faSjeremylt } 3385fe0d4faSjeremylt 3392b730f8bSJeremy L Thompson if (elem_size < 1) { 340e022e1f8SJeremy L Thompson // LCOV_EXCL_START 3412b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 342e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 3432b730f8bSJeremy L Thompson } 344e022e1f8SJeremy L Thompson 3452b730f8bSJeremy L Thompson if (num_comp < 1) { 346e022e1f8SJeremy L Thompson // LCOV_EXCL_START 3472b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 348e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 3492b730f8bSJeremy L Thompson } 350e022e1f8SJeremy L Thompson 3512b730f8bSJeremy L Thompson if (num_comp > 1 && comp_stride < 1) { 352e022e1f8SJeremy L Thompson // LCOV_EXCL_START 3532b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 354e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 3552b730f8bSJeremy L Thompson } 356e022e1f8SJeremy L Thompson 3572b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 3584ce2993fSjeremylt (*rstr)->ceed = ceed; 3592b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 360d1d35e2fSjeremylt (*rstr)->ref_count = 1; 361d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 362d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 363d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 364d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 365d1d35e2fSjeremylt (*rstr)->l_size = l_size; 366d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 367d1d35e2fSjeremylt (*rstr)->blk_size = 1; 368b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 3692b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr)); 370e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 371d7b241e6Sjeremylt } 372d7b241e6Sjeremylt 373d7b241e6Sjeremylt /** 374fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 375fc0567d9Srezgarshakeri 376ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 377ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 378ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 379ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 380ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 381ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index offsets[i + k*elem_size] + j*comp_stride. 382ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 383ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 384ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 385ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 386ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 387ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 388ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 389ea61e9acSJeremy L Thompson @param[in] orient Array of shape [@a num_elem, @a elem_size] with bool false for positively oriented and true to flip the orientation. 390ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 391fc0567d9Srezgarshakeri 392fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 393fc0567d9Srezgarshakeri 394fc0567d9Srezgarshakeri @ref User 395fc0567d9Srezgarshakeri **/ 3962b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 3972b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orient, 398fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 399c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 400fc0567d9Srezgarshakeri Ceed delegate; 4012b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 402fc0567d9Srezgarshakeri 4032b730f8bSJeremy L Thompson if (!delegate) { 404fc0567d9Srezgarshakeri // LCOV_EXCL_START 4052b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateOriented"); 406fc0567d9Srezgarshakeri // LCOV_EXCL_STOP 4072b730f8bSJeremy L Thompson } 408fc0567d9Srezgarshakeri 4092b730f8bSJeremy L Thompson CeedCall( 4102b730f8bSJeremy L Thompson CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orient, rstr)); 411fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 412fc0567d9Srezgarshakeri } 413fc0567d9Srezgarshakeri 4142b730f8bSJeremy L Thompson if (elem_size < 1) { 415e022e1f8SJeremy L Thompson // LCOV_EXCL_START 4162b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 417e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 4182b730f8bSJeremy L Thompson } 419e022e1f8SJeremy L Thompson 4202b730f8bSJeremy L Thompson if (num_comp < 1) { 421e022e1f8SJeremy L Thompson // LCOV_EXCL_START 4222b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 423e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 4242b730f8bSJeremy L Thompson } 425e022e1f8SJeremy L Thompson 4262b730f8bSJeremy L Thompson if (num_comp > 1 && comp_stride < 1) { 427e022e1f8SJeremy L Thompson // LCOV_EXCL_START 4282b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 429e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 4302b730f8bSJeremy L Thompson } 431e022e1f8SJeremy L Thompson 4322b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 433fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 4342b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 435fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 436fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 437fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 438fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 439fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 440fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 441fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 442fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 443b435c5a6Srezgarshakeri (*rstr)->is_oriented = 1; 4442b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient, *rstr)); 445fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 446fc0567d9Srezgarshakeri } 447fc0567d9Srezgarshakeri 448fc0567d9Srezgarshakeri /** 4497509a596Sjeremylt @brief Create a strided CeedElemRestriction 450d7b241e6Sjeremylt 451ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 452ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 453ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 454ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 455ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 456ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 457ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 458ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index i*strides[0] + j*strides[1] + k*strides[2]. 459ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 460ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 461d7b241e6Sjeremylt 462b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 463dfdf5a53Sjeremylt 4647a982d89SJeremy L. Thompson @ref User 465b11c1e72Sjeremylt **/ 4662b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 467f90c8643Sjeremylt CeedElemRestriction *rstr) { 4685fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4695fe0d4faSjeremylt Ceed delegate; 4702b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4715fe0d4faSjeremylt 4722b730f8bSJeremy L Thompson if (!delegate) { 473c042f62fSJeremy L Thompson // LCOV_EXCL_START 4742b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreate"); 475c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4762b730f8bSJeremy L Thompson } 4775fe0d4faSjeremylt 4782b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 479e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4805fe0d4faSjeremylt } 4815fe0d4faSjeremylt 4822b730f8bSJeremy L Thompson if (elem_size < 1) { 483e022e1f8SJeremy L Thompson // LCOV_EXCL_START 4842b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 485e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 4862b730f8bSJeremy L Thompson } 487e022e1f8SJeremy L Thompson 4882b730f8bSJeremy L Thompson if (num_comp < 1) { 489e022e1f8SJeremy L Thompson // LCOV_EXCL_START 4902b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 491e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 4922b730f8bSJeremy L Thompson } 493e022e1f8SJeremy L Thompson 4942b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 4954ce2993fSjeremylt (*rstr)->ceed = ceed; 4962b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 497d1d35e2fSjeremylt (*rstr)->ref_count = 1; 498d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 499d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 500d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 501d1d35e2fSjeremylt (*rstr)->l_size = l_size; 502d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 503d1d35e2fSjeremylt (*rstr)->blk_size = 1; 504b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 5052b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 5062b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 5072b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 508e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 509d7b241e6Sjeremylt } 510d7b241e6Sjeremylt 511d7b241e6Sjeremylt /** 512b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 513d7b241e6Sjeremylt 514ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 515ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 516ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 517ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 518ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 519ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 520ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index offsets[i + k*elem_size] + j*comp_stride. 521ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 522ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 523ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 524ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 525ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 526ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 527ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. The backend will permute and pad this array to the desired ordering for 528ea61e9acSJeremy L Thompson the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 529ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 530d7b241e6Sjeremylt 531b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 532dfdf5a53Sjeremylt 5337a982d89SJeremy L. Thompson @ref Backend 534b11c1e72Sjeremylt **/ 5352b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 5362b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 5374ce2993fSjeremylt CeedElemRestriction *rstr) { 538d1d35e2fSjeremylt CeedInt *blk_offsets; 539d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 540d7b241e6Sjeremylt 5415fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5425fe0d4faSjeremylt Ceed delegate; 5432b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5445fe0d4faSjeremylt 5452b730f8bSJeremy L Thompson if (!delegate) { 546c042f62fSJeremy L Thompson // LCOV_EXCL_START 5472b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateBlocked"); 548c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5492b730f8bSJeremy L Thompson } 5505fe0d4faSjeremylt 5512b730f8bSJeremy L Thompson CeedCall( 5522b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 553e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5545fe0d4faSjeremylt } 555d7b241e6Sjeremylt 5562b730f8bSJeremy L Thompson if (elem_size < 1) { 557e022e1f8SJeremy L Thompson // LCOV_EXCL_START 5582b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 559e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 5602b730f8bSJeremy L Thompson } 561e022e1f8SJeremy L Thompson 5622b730f8bSJeremy L Thompson if (blk_size < 1) { 563e022e1f8SJeremy L Thompson // LCOV_EXCL_START 5642b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 565e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 5662b730f8bSJeremy L Thompson } 567e022e1f8SJeremy L Thompson 5682b730f8bSJeremy L Thompson if (num_comp < 1) { 569e022e1f8SJeremy L Thompson // LCOV_EXCL_START 5702b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 571e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 5722b730f8bSJeremy L Thompson } 573e022e1f8SJeremy L Thompson 5742b730f8bSJeremy L Thompson if (num_comp > 1 && comp_stride < 1) { 575e022e1f8SJeremy L Thompson // LCOV_EXCL_START 5762b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 577e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 5782b730f8bSJeremy L Thompson } 579e022e1f8SJeremy L Thompson 5802b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 581d7b241e6Sjeremylt 5822b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 5832b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 584d7b241e6Sjeremylt 5854ce2993fSjeremylt (*rstr)->ceed = ceed; 5862b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 587d1d35e2fSjeremylt (*rstr)->ref_count = 1; 588d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 589d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 590d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 591d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 592d1d35e2fSjeremylt (*rstr)->l_size = l_size; 593d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 594d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 595b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 5962b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, *rstr)); 597d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 5982b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 5991d102b48SJeremy L Thompson } 600e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 601d7b241e6Sjeremylt } 602d7b241e6Sjeremylt 603b11c1e72Sjeremylt /** 6047509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 6057509a596Sjeremylt 606ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 607ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 608ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 609ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 610ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 611ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 612ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 613ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 614ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index i*strides[0] + j*strides[1] + k*strides[2]. 615ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 616ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 6177509a596Sjeremylt 6187509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 6197509a596Sjeremylt 6207a982d89SJeremy L. Thompson @ref User 6217509a596Sjeremylt **/ 6222b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 6238621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 624d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 6257509a596Sjeremylt 6267509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6277509a596Sjeremylt Ceed delegate; 6282b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 6297509a596Sjeremylt 6302b730f8bSJeremy L Thompson if (!delegate) { 6317509a596Sjeremylt // LCOV_EXCL_START 6322b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateBlocked"); 6337509a596Sjeremylt // LCOV_EXCL_STOP 6342b730f8bSJeremy L Thompson } 6357509a596Sjeremylt 6362b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 637e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6387509a596Sjeremylt } 6397509a596Sjeremylt 6402b730f8bSJeremy L Thompson if (elem_size < 1) { 641e022e1f8SJeremy L Thompson // LCOV_EXCL_START 6422b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 643e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 6442b730f8bSJeremy L Thompson } 645e022e1f8SJeremy L Thompson 6462b730f8bSJeremy L Thompson if (blk_size < 1) { 647e022e1f8SJeremy L Thompson // LCOV_EXCL_START 6482b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 649e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 6502b730f8bSJeremy L Thompson } 651e022e1f8SJeremy L Thompson 6522b730f8bSJeremy L Thompson if (num_comp < 1) { 653e022e1f8SJeremy L Thompson // LCOV_EXCL_START 6542b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 655e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 6562b730f8bSJeremy L Thompson } 657e022e1f8SJeremy L Thompson 6582b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 6597509a596Sjeremylt 6607509a596Sjeremylt (*rstr)->ceed = ceed; 6612b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 662d1d35e2fSjeremylt (*rstr)->ref_count = 1; 663d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 664d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 665d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 666d1d35e2fSjeremylt (*rstr)->l_size = l_size; 667d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 668d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 669b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 6702b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6712b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 6722b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 673e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6747509a596Sjeremylt } 6757509a596Sjeremylt 6767509a596Sjeremylt /** 677ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 678ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 6799560d06aSjeremylt 680ea61e9acSJeremy L Thompson Note: If `*rstr_copy` is non-NULL, then it is assumed that `*rstr_copy` is a pointer to a CeedElemRestriction. 681ea61e9acSJeremy L Thompson This CeedElemRestriction will be destroyed if `*rstr_copy` is the only reference to this CeedElemRestriction. 682ea61e9acSJeremy L Thompson 683ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 684ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 6859560d06aSjeremylt 6869560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6879560d06aSjeremylt 6889560d06aSjeremylt @ref User 6899560d06aSjeremylt **/ 6902b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 6912b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionReference(rstr)); 6922b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 6939560d06aSjeremylt *rstr_copy = rstr; 6949560d06aSjeremylt return CEED_ERROR_SUCCESS; 6959560d06aSjeremylt } 6969560d06aSjeremylt 6979560d06aSjeremylt /** 698b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 699b11c1e72Sjeremylt 700ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 701ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 702ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 703b11c1e72Sjeremylt 704b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 705dfdf5a53Sjeremylt 7067a982d89SJeremy L. Thompson @ref User 707b11c1e72Sjeremylt **/ 7082b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 709d2643443SJeremy L Thompson CeedSize e_size, l_size; 710d1d35e2fSjeremylt l_size = rstr->l_size; 711d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 7122b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 7132b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 714e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 715d7b241e6Sjeremylt } 716d7b241e6Sjeremylt 717d7b241e6Sjeremylt /** 718d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 719d7b241e6Sjeremylt 720ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 721ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 722ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 723ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 724ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 725ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 726b11c1e72Sjeremylt 727b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 728dfdf5a53Sjeremylt 7297a982d89SJeremy L. Thompson @ref User 730b11c1e72Sjeremylt **/ 7312b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 732d7b241e6Sjeremylt CeedInt m, n; 733d7b241e6Sjeremylt 734d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 735d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 736d1d35e2fSjeremylt n = rstr->l_size; 737d7b241e6Sjeremylt } else { 738d1d35e2fSjeremylt m = rstr->l_size; 739d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 740d7b241e6Sjeremylt } 7412b730f8bSJeremy L Thompson if (n != u->length) { 742c042f62fSJeremy L Thompson // LCOV_EXCL_START 743e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 7442b730f8bSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, 7452b730f8bSJeremy L Thompson n); 746c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 74752b3e6a7SJed Brown } 7482b730f8bSJeremy L Thompson if (m != ru->length) { 7492b730f8bSJeremy L Thompson // LCOV_EXCL_START 7502b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 7512b730f8bSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, 7522b730f8bSJeremy L Thompson m, n); 7532b730f8bSJeremy L Thompson // LCOV_EXCL_STOP 7542b730f8bSJeremy L Thompson } 7552b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 756e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 757d7b241e6Sjeremylt } 758d7b241e6Sjeremylt 759d7b241e6Sjeremylt /** 760d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 761be9261b7Sjeremylt 762ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 763ea61e9acSJeremy L Thompson @param[in] block Block number to restrict to/from, i.e. block=0 will handle elements [0 : blk_size] and block=3 will handle elements [3*blk_size 764ea61e9acSJeremy L Thompson : 4*blk_size] 765ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 766ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 767ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 768ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 769ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 770be9261b7Sjeremylt 771be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 772be9261b7Sjeremylt 7737a982d89SJeremy L. Thompson @ref Backend 774be9261b7Sjeremylt **/ 7752b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 7762b730f8bSJeremy L Thompson CeedRequest *request) { 777be9261b7Sjeremylt CeedInt m, n; 778be9261b7Sjeremylt 779d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 780d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 781d1d35e2fSjeremylt n = rstr->l_size; 782be9261b7Sjeremylt } else { 783d1d35e2fSjeremylt m = rstr->l_size; 784d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 785be9261b7Sjeremylt } 7862b730f8bSJeremy L Thompson if (n != u->length) { 787c042f62fSJeremy L Thompson // LCOV_EXCL_START 788e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 7892b730f8bSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, 7902b730f8bSJeremy L Thompson n); 791c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7922b730f8bSJeremy L Thompson } 7932b730f8bSJeremy L Thompson if (m != ru->length) { 794c042f62fSJeremy L Thompson // LCOV_EXCL_START 795e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 7962b730f8bSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, 7972b730f8bSJeremy L Thompson m, n); 798c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 7992b730f8bSJeremy L Thompson } 8002b730f8bSJeremy L Thompson if (rstr->blk_size * block > rstr->num_elem) { 801c042f62fSJeremy L Thompson // LCOV_EXCL_START 802e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 8032b730f8bSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, 8042b730f8bSJeremy L Thompson rstr->blk_size * block, rstr->num_elem); 805c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 8062b730f8bSJeremy L Thompson } 8072b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 808e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 809be9261b7Sjeremylt } 810be9261b7Sjeremylt 811be9261b7Sjeremylt /** 812b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 813b7c9bbdaSJeremy L Thompson 814ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 815b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 816b7c9bbdaSJeremy L Thompson 817b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 818b7c9bbdaSJeremy L Thompson 819b7c9bbdaSJeremy L Thompson @ref Advanced 820b7c9bbdaSJeremy L Thompson **/ 821b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 822b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 823b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 824b7c9bbdaSJeremy L Thompson } 825b7c9bbdaSJeremy L Thompson 826b7c9bbdaSJeremy L Thompson /** 827d979a051Sjeremylt @brief Get the L-vector component stride 828a681ae63Sjeremylt 829ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 830d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 831a681ae63Sjeremylt 832a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 833a681ae63Sjeremylt 834b7c9bbdaSJeremy L Thompson @ref Advanced 835a681ae63Sjeremylt **/ 8362b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 837d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 838e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 839a681ae63Sjeremylt } 840a681ae63Sjeremylt 841a681ae63Sjeremylt /** 842a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 843a681ae63Sjeremylt 844ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 845d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 846a681ae63Sjeremylt 847a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 848a681ae63Sjeremylt 849b7c9bbdaSJeremy L Thompson @ref Advanced 850a681ae63Sjeremylt **/ 8512b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 852d1d35e2fSjeremylt *num_elem = rstr->num_elem; 853e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 854a681ae63Sjeremylt } 855a681ae63Sjeremylt 856a681ae63Sjeremylt /** 857a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 858a681ae63Sjeremylt 859ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 860d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 861a681ae63Sjeremylt 862a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 863a681ae63Sjeremylt 864b7c9bbdaSJeremy L Thompson @ref Advanced 865a681ae63Sjeremylt **/ 8662b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 867d1d35e2fSjeremylt *elem_size = rstr->elem_size; 868e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 869a681ae63Sjeremylt } 870a681ae63Sjeremylt 871a681ae63Sjeremylt /** 872d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 873a681ae63Sjeremylt 874ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 875d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 876a681ae63Sjeremylt 877a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 878a681ae63Sjeremylt 879b7c9bbdaSJeremy L Thompson @ref Advanced 880a681ae63Sjeremylt **/ 8812b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 882d1d35e2fSjeremylt *l_size = rstr->l_size; 883e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 884a681ae63Sjeremylt } 885a681ae63Sjeremylt 886a681ae63Sjeremylt /** 887ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 888a681ae63Sjeremylt 889ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 890d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 891a681ae63Sjeremylt 892a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 893a681ae63Sjeremylt 894b7c9bbdaSJeremy L Thompson @ref Advanced 895a681ae63Sjeremylt **/ 8962b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 897d1d35e2fSjeremylt *num_comp = rstr->num_comp; 898e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 899a681ae63Sjeremylt } 900a681ae63Sjeremylt 901a681ae63Sjeremylt /** 902a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 903a681ae63Sjeremylt 904ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 905d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 906a681ae63Sjeremylt 907a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 908a681ae63Sjeremylt 909b7c9bbdaSJeremy L Thompson @ref Advanced 910a681ae63Sjeremylt **/ 9112b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 912d1d35e2fSjeremylt *num_block = rstr->num_blk; 913e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 914a681ae63Sjeremylt } 915a681ae63Sjeremylt 916a681ae63Sjeremylt /** 917a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 918a681ae63Sjeremylt 919ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 920d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 921a681ae63Sjeremylt 922a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 923a681ae63Sjeremylt 924b7c9bbdaSJeremy L Thompson @ref Advanced 925a681ae63Sjeremylt **/ 9262b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 927d1d35e2fSjeremylt *blk_size = rstr->blk_size; 928e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 929a681ae63Sjeremylt } 930a681ae63Sjeremylt 931a681ae63Sjeremylt /** 932d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 9331469ee4dSjeremylt 934ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 935d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 9361469ee4dSjeremylt 9371469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 9381469ee4dSjeremylt 9397a982d89SJeremy L. Thompson @ref User 9401469ee4dSjeremylt **/ 9412b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 942d1d35e2fSjeremylt CeedVector e_vec; 9431469ee4dSjeremylt 94425509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 9452b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 9461469ee4dSjeremylt 94725509ebbSRezgar Shakeri // Compute e_vec = E * 1 9482b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 9492b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 95025509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 9512b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 9522b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 9531469ee4dSjeremylt // Cleanup 9542b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 955e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9561469ee4dSjeremylt } 9571469ee4dSjeremylt 9581469ee4dSjeremylt /** 959f02ca4a2SJed Brown @brief View a CeedElemRestriction 960f02ca4a2SJed Brown 961f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 962f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 963f02ca4a2SJed Brown 964f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 965f02ca4a2SJed Brown 9667a982d89SJeremy L. Thompson @ref User 967f02ca4a2SJed Brown **/ 968f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 9697509a596Sjeremylt char stridesstr[500]; 9702b730f8bSJeremy L Thompson if (rstr->strides) { 9712b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 9722b730f8bSJeremy L Thompson } else { 973990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 9742b730f8bSJeremy L Thompson } 9757509a596Sjeremylt 9762b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 9772b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 978d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 979e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 980f02ca4a2SJed Brown } 981f02ca4a2SJed Brown 982f02ca4a2SJed Brown /** 983b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 984b11c1e72Sjeremylt 985ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 986b11c1e72Sjeremylt 987b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 988dfdf5a53Sjeremylt 9897a982d89SJeremy L. Thompson @ref User 990b11c1e72Sjeremylt **/ 9914ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 992*ad6481ceSJeremy L Thompson if (!*rstr || --(*rstr)->ref_count > 0) { 993*ad6481ceSJeremy L Thompson *rstr = NULL; 994*ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 995*ad6481ceSJeremy L Thompson } 9962b730f8bSJeremy L Thompson if ((*rstr)->num_readers) { 9978229195eSjeremylt // LCOV_EXCL_START 9982b730f8bSJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 9998229195eSjeremylt // LCOV_EXCL_STOP 1000d7b241e6Sjeremylt } 10012b730f8bSJeremy L Thompson if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 10022b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 10032b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 10042b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1005e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1006d7b241e6Sjeremylt } 1007d7b241e6Sjeremylt 1008d7b241e6Sjeremylt /// @} 1009