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> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.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]) { 706574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 712b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 72e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 737a982d89SJeremy L. Thompson } 747a982d89SJeremy L. Thompson 757a982d89SJeremy L. Thompson /** 76bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 77bd33150aSjeremylt 78ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 79ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the array. 80ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy (possibly cached). 81d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 82bd33150aSjeremylt 83bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 84bd33150aSjeremylt 85bd33150aSjeremylt @ref User 86bd33150aSjeremylt **/ 872b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 886574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 892b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 90d1d35e2fSjeremylt rstr->num_readers++; 91e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 92430758c8SJeremy L Thompson } 93430758c8SJeremy L Thompson 94430758c8SJeremy L Thompson /** 95430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 96430758c8SJeremy L Thompson 97ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 98ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 99430758c8SJeremy L Thompson 100430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 101430758c8SJeremy L Thompson 102430758c8SJeremy L Thompson @ref User 103430758c8SJeremy L Thompson **/ 1042b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 105430758c8SJeremy L Thompson *offsets = NULL; 106d1d35e2fSjeremylt rstr->num_readers--; 107e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 108bd33150aSjeremylt } 109bd33150aSjeremylt 110bd33150aSjeremylt /** 1113ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1123ac43b2cSJeremy L Thompson 113ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 114d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1153ac43b2cSJeremy L Thompson 1163ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1173ac43b2cSJeremy L Thompson 1183ac43b2cSJeremy L Thompson @ref Backend 1193ac43b2cSJeremy L Thompson **/ 120d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 121d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 122e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1233ac43b2cSJeremy L Thompson } 1243ac43b2cSJeremy L Thompson 1253ac43b2cSJeremy L Thompson /** 126b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 127b435c5a6Srezgarshakeri 128ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 129b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 130b435c5a6Srezgarshakeri 131b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 132b435c5a6Srezgarshakeri 133b435c5a6Srezgarshakeri @ref Backend 134b435c5a6Srezgarshakeri **/ 135b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 136b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 137b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 138b435c5a6Srezgarshakeri } 139b435c5a6Srezgarshakeri 140b435c5a6Srezgarshakeri /** 141a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1427a982d89SJeremy L. Thompson 143ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 14496b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1457a982d89SJeremy L. Thompson 1467a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1477a982d89SJeremy L. Thompson 1487a982d89SJeremy L. Thompson @ref Backend 1497a982d89SJeremy L. Thompson **/ 1502b730f8bSJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 1516574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1522b730f8bSJeremy L Thompson *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 153a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 154e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1557a982d89SJeremy L. Thompson } 1567a982d89SJeremy L. Thompson 1577a982d89SJeremy L. Thompson /** 15849fd234cSJeremy L Thompson 15949fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 16049fd234cSJeremy L Thompson 161ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 162ea61e9acSJeremy L Thompson @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 163ea61e9acSJeremy 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] 16449fd234cSJeremy L Thompson 16549fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 16649fd234cSJeremy L Thompson 16749fd234cSJeremy L Thompson @ref Backend 16849fd234cSJeremy L Thompson **/ 1692b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 1706574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 1712b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 172e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 17349fd234cSJeremy L Thompson } 17449fd234cSJeremy L Thompson 17549fd234cSJeremy L Thompson /** 17649fd234cSJeremy L Thompson 17749fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 17849fd234cSJeremy L Thompson 179ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 180ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 181ea61e9acSJeremy 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] 18249fd234cSJeremy L Thompson 18349fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 18449fd234cSJeremy L Thompson 18549fd234cSJeremy L Thompson @ref Backend 18649fd234cSJeremy L Thompson **/ 1872b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 1882b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 189e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 19049fd234cSJeremy L Thompson } 19149fd234cSJeremy L Thompson 19249fd234cSJeremy L Thompson /** 1937a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 1947a982d89SJeremy L. Thompson 195ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1967a982d89SJeremy L. Thompson @param[out] data Variable to store data 1977a982d89SJeremy L. Thompson 1987a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1997a982d89SJeremy L. Thompson 2007a982d89SJeremy L. Thompson @ref Backend 2017a982d89SJeremy L. Thompson **/ 202777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 203777ff853SJeremy L Thompson *(void **)data = rstr->data; 204e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2057a982d89SJeremy L. Thompson } 2067a982d89SJeremy L. Thompson 2077a982d89SJeremy L. Thompson /** 2087a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2097a982d89SJeremy L. Thompson 210ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 211ea61e9acSJeremy L Thompson @param[in] data Data to set 2127a982d89SJeremy L. Thompson 2137a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2147a982d89SJeremy L. Thompson 2157a982d89SJeremy L. Thompson @ref Backend 2167a982d89SJeremy L. Thompson **/ 217777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 218777ff853SJeremy L Thompson rstr->data = data; 219e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2207a982d89SJeremy L. Thompson } 2217a982d89SJeremy L. Thompson 22234359f16Sjeremylt /** 22334359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 22434359f16Sjeremylt 225ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 22634359f16Sjeremylt 22734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 22834359f16Sjeremylt 22934359f16Sjeremylt @ref Backend 23034359f16Sjeremylt **/ 2319560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 23234359f16Sjeremylt rstr->ref_count++; 23334359f16Sjeremylt return CEED_ERROR_SUCCESS; 23434359f16Sjeremylt } 23534359f16Sjeremylt 2366e15d496SJeremy L Thompson /** 2376e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 2386e15d496SJeremy L Thompson 239ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 240ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 241ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 2426e15d496SJeremy L Thompson 2436e15d496SJeremy L Thompson @ref Backend 2446e15d496SJeremy L Thompson **/ 2452b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 2466e15d496SJeremy L Thompson bool is_oriented; 2472b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 2486e15d496SJeremy L Thompson 2492b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionIsOriented(rstr, &is_oriented)); 2506e15d496SJeremy L Thompson switch (t_mode) { 2512b730f8bSJeremy L Thompson case CEED_NOTRANSPOSE: 2522b730f8bSJeremy L Thompson scale = is_oriented ? 1 : 0; 2532b730f8bSJeremy L Thompson break; 2542b730f8bSJeremy L Thompson case CEED_TRANSPOSE: 2552b730f8bSJeremy L Thompson scale = is_oriented ? 2 : 1; 2562b730f8bSJeremy L Thompson break; 2576e15d496SJeremy L Thompson } 2586e15d496SJeremy L Thompson *flops = e_size * scale; 2596e15d496SJeremy L Thompson 2606e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 2616e15d496SJeremy L Thompson } 2626e15d496SJeremy L Thompson 2637a982d89SJeremy L. Thompson /// @} 2647a982d89SJeremy L. Thompson 26515910d16Sjeremylt /// @cond DOXYGEN_SKIP 26615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 26715910d16Sjeremylt /// @endcond 26815910d16Sjeremylt 2697a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2707a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2717a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2727a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 273d7b241e6Sjeremylt /// @{ 274d7b241e6Sjeremylt 2757a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 27645f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 2777a982d89SJeremy L. Thompson 2784cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 2792b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 2807a982d89SJeremy L. Thompson 281d7b241e6Sjeremylt /** 282b11c1e72Sjeremylt @brief Create a CeedElemRestriction 283d7b241e6Sjeremylt 284ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 285ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 286ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 287ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 288ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 289ea61e9acSJeremy 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. 290ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 291ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 292ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 293ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 294ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 295ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 296ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 297ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 298d7b241e6Sjeremylt 299b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 300dfdf5a53Sjeremylt 3017a982d89SJeremy L. Thompson @ref User 302b11c1e72Sjeremylt **/ 3032b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 3042b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 3055fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3065fe0d4faSjeremylt Ceed delegate; 3076574a04fSJeremy L Thompson 3082b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 3096574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreate"); 3102b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 311e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3125fe0d4faSjeremylt } 3135fe0d4faSjeremylt 3146574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 3156574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 3166574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 317e022e1f8SJeremy L Thompson 3182b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 3194ce2993fSjeremylt (*rstr)->ceed = ceed; 3202b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 321d1d35e2fSjeremylt (*rstr)->ref_count = 1; 322d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 323d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 324d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 325d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 326d1d35e2fSjeremylt (*rstr)->l_size = l_size; 327d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 328d1d35e2fSjeremylt (*rstr)->blk_size = 1; 3296402da51SJeremy L Thompson (*rstr)->is_oriented = false; 3302b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr)); 331e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 332d7b241e6Sjeremylt } 333d7b241e6Sjeremylt 334d7b241e6Sjeremylt /** 335fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 336fc0567d9Srezgarshakeri 337ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 338ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 339ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 340ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 341ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 342ea61e9acSJeremy 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. 343ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 344ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 345ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 346ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 347ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 348ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 349ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 350ea61e9acSJeremy 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. 351ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 352fc0567d9Srezgarshakeri 353fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 354fc0567d9Srezgarshakeri 355fc0567d9Srezgarshakeri @ref User 356fc0567d9Srezgarshakeri **/ 3572b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 3582b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orient, 359fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 360c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 361fc0567d9Srezgarshakeri Ceed delegate; 3626574a04fSJeremy L Thompson 3632b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 3646574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateOriented"); 3652b730f8bSJeremy L Thompson CeedCall( 3662b730f8bSJeremy L Thompson CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orient, rstr)); 367fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 368fc0567d9Srezgarshakeri } 369fc0567d9Srezgarshakeri 3706574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 3716574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 3726574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 373e022e1f8SJeremy L Thompson 3742b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 375fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 3762b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 377fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 378fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 379fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 380fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 381fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 382fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 383fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 384fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 3856402da51SJeremy L Thompson (*rstr)->is_oriented = true; 3862b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient, *rstr)); 387fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 388fc0567d9Srezgarshakeri } 389fc0567d9Srezgarshakeri 390fc0567d9Srezgarshakeri /** 3917509a596Sjeremylt @brief Create a strided CeedElemRestriction 392d7b241e6Sjeremylt 393ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 394ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 395ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 396ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 397ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 398ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 399ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 400ea61e9acSJeremy 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]. 401ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 402ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 403d7b241e6Sjeremylt 404b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 405dfdf5a53Sjeremylt 4067a982d89SJeremy L. Thompson @ref User 407b11c1e72Sjeremylt **/ 4082b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 409f90c8643Sjeremylt CeedElemRestriction *rstr) { 4105fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4115fe0d4faSjeremylt Ceed delegate; 4122b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4136402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateStrided"); 4142b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 415e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4165fe0d4faSjeremylt } 4175fe0d4faSjeremylt 4186574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4196574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 420e022e1f8SJeremy L Thompson 4212b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 4224ce2993fSjeremylt (*rstr)->ceed = ceed; 4232b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 424d1d35e2fSjeremylt (*rstr)->ref_count = 1; 425d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 426d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 427d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 428d1d35e2fSjeremylt (*rstr)->l_size = l_size; 429d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 430d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4316402da51SJeremy L Thompson (*rstr)->is_oriented = false; 4322b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 4332b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 4342b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 435e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 436d7b241e6Sjeremylt } 437d7b241e6Sjeremylt 438d7b241e6Sjeremylt /** 439b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 440d7b241e6Sjeremylt 441ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 442ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 443ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 444ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 445ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 446ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 447ea61e9acSJeremy 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. 448ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 449ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 450ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 451ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 452ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 453ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 454ea61e9acSJeremy 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 455ea61e9acSJeremy L Thompson the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 456ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 457d7b241e6Sjeremylt 458b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 459dfdf5a53Sjeremylt 4607a982d89SJeremy L. Thompson @ref Backend 461b11c1e72Sjeremylt **/ 4622b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 4632b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 4644ce2993fSjeremylt CeedElemRestriction *rstr) { 465d1d35e2fSjeremylt CeedInt *blk_offsets; 466d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 467d7b241e6Sjeremylt 4685fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 4695fe0d4faSjeremylt Ceed delegate; 4706574a04fSJeremy L Thompson 4712b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4726402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 4732b730f8bSJeremy L Thompson CeedCall( 4742b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 475e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4765fe0d4faSjeremylt } 477d7b241e6Sjeremylt 4786574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4796574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 4806574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4816574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 482e022e1f8SJeremy L Thompson 4832b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 484d7b241e6Sjeremylt 4852b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 4862b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 487d7b241e6Sjeremylt 4884ce2993fSjeremylt (*rstr)->ceed = ceed; 4892b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 490d1d35e2fSjeremylt (*rstr)->ref_count = 1; 491d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 492d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 493d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 494d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 495d1d35e2fSjeremylt (*rstr)->l_size = l_size; 496d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 497d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 4986402da51SJeremy L Thompson (*rstr)->is_oriented = false; 4992b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, *rstr)); 500d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 5012b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 5021d102b48SJeremy L Thompson } 503e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 504d7b241e6Sjeremylt } 505d7b241e6Sjeremylt 506b11c1e72Sjeremylt /** 5077509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5087509a596Sjeremylt 509ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 510ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 511ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 512ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 513ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 514ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 515ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 516ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 517ea61e9acSJeremy 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]. 518ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 519ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 5207509a596Sjeremylt 5217509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 5227509a596Sjeremylt 5237a982d89SJeremy L. Thompson @ref User 5247509a596Sjeremylt **/ 5252b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 5268621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 527d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 5287509a596Sjeremylt 5297509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5307509a596Sjeremylt Ceed delegate; 5316574a04fSJeremy L Thompson 5322b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5336402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlockedStrided"); 5342b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 535e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5367509a596Sjeremylt } 5377509a596Sjeremylt 5386574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5396574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 5406574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 541e022e1f8SJeremy L Thompson 5422b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 5437509a596Sjeremylt 5447509a596Sjeremylt (*rstr)->ceed = ceed; 5452b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 546d1d35e2fSjeremylt (*rstr)->ref_count = 1; 547d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 548d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 549d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 550d1d35e2fSjeremylt (*rstr)->l_size = l_size; 551d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 552d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5536402da51SJeremy L Thompson (*rstr)->is_oriented = false; 5542b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 5552b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 5562b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 557e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5587509a596Sjeremylt } 5597509a596Sjeremylt 5607509a596Sjeremylt /** 561ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 5629fd66db6SSebastian Grimberg 563ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 5649560d06aSjeremylt 5659fd66db6SSebastian Grimberg Note: If the value of `rstr_copy` passed into this function is non-NULL, then it is assumed that `rstr_copy` is a pointer to a CeedElemRestriction. 5669fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 567ea61e9acSJeremy L Thompson 568ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 569ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 5709560d06aSjeremylt 5719560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5729560d06aSjeremylt 5739560d06aSjeremylt @ref User 5749560d06aSjeremylt **/ 5752b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 576393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 5772b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 5789560d06aSjeremylt *rstr_copy = rstr; 5799560d06aSjeremylt return CEED_ERROR_SUCCESS; 5809560d06aSjeremylt } 5819560d06aSjeremylt 5829560d06aSjeremylt /** 583b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 584b11c1e72Sjeremylt 585ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 586ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 587ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 588b11c1e72Sjeremylt 589b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 590dfdf5a53Sjeremylt 5917a982d89SJeremy L. Thompson @ref User 592b11c1e72Sjeremylt **/ 5932b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 594d2643443SJeremy L Thompson CeedSize e_size, l_size; 595d1d35e2fSjeremylt l_size = rstr->l_size; 596d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 5972b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 5982b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 599e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 600d7b241e6Sjeremylt } 601d7b241e6Sjeremylt 602d7b241e6Sjeremylt /** 603d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 604d7b241e6Sjeremylt 605ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 606ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 607ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 608ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 609ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 610ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 611b11c1e72Sjeremylt 612b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 613dfdf5a53Sjeremylt 6147a982d89SJeremy L. Thompson @ref User 615b11c1e72Sjeremylt **/ 6162b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 617d7b241e6Sjeremylt CeedInt m, n; 618d7b241e6Sjeremylt 619d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 620d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 621d1d35e2fSjeremylt n = rstr->l_size; 622d7b241e6Sjeremylt } else { 623d1d35e2fSjeremylt m = rstr->l_size; 624d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 625d7b241e6Sjeremylt } 6266574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 6276574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 6286574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 6296574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 6302b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 631e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 632d7b241e6Sjeremylt } 633d7b241e6Sjeremylt 634d7b241e6Sjeremylt /** 635*f30b1135SSebastian Grimberg @brief Restrict an L-vector to an E-vector or apply its transpose ignoring any 636*f30b1135SSebastian Grimberg provided orientations 637*f30b1135SSebastian Grimberg 638*f30b1135SSebastian Grimberg @param[in] rstr CeedElemRestriction 639*f30b1135SSebastian Grimberg @param[in] t_mode Apply restriction or transpose 640*f30b1135SSebastian Grimberg @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 641*f30b1135SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 642*f30b1135SSebastian Grimberg Ordering of the e-vector is decided by the backend. 643*f30b1135SSebastian Grimberg @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 644*f30b1135SSebastian Grimberg 645*f30b1135SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 646*f30b1135SSebastian Grimberg 647*f30b1135SSebastian Grimberg @ref User 648*f30b1135SSebastian Grimberg **/ 649*f30b1135SSebastian Grimberg int CeedElemRestrictionApplyUnsigned(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 650*f30b1135SSebastian Grimberg CeedInt m, n; 651*f30b1135SSebastian Grimberg 652*f30b1135SSebastian Grimberg if (t_mode == CEED_NOTRANSPOSE) { 653*f30b1135SSebastian Grimberg m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 654*f30b1135SSebastian Grimberg n = rstr->l_size; 655*f30b1135SSebastian Grimberg } else { 656*f30b1135SSebastian Grimberg m = rstr->l_size; 657*f30b1135SSebastian Grimberg n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 658*f30b1135SSebastian Grimberg } 659*f30b1135SSebastian Grimberg if (n != u->length) { 660*f30b1135SSebastian Grimberg // LCOV_EXCL_START 661*f30b1135SSebastian Grimberg return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 662*f30b1135SSebastian Grimberg "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, 663*f30b1135SSebastian Grimberg n); 664*f30b1135SSebastian Grimberg // LCOV_EXCL_STOP 665*f30b1135SSebastian Grimberg } 666*f30b1135SSebastian Grimberg if (m != ru->length) { 667*f30b1135SSebastian Grimberg // LCOV_EXCL_START 668*f30b1135SSebastian Grimberg return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 669*f30b1135SSebastian Grimberg "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, 670*f30b1135SSebastian Grimberg m, n); 671*f30b1135SSebastian Grimberg // LCOV_EXCL_STOP 672*f30b1135SSebastian Grimberg } 673*f30b1135SSebastian Grimberg if (rstr->num_elem > 0) { 674*f30b1135SSebastian Grimberg if (rstr->ApplyUnsigned) CeedCall(rstr->ApplyUnsigned(rstr, t_mode, u, ru, request)); 675*f30b1135SSebastian Grimberg else CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 676*f30b1135SSebastian Grimberg } 677*f30b1135SSebastian Grimberg return CEED_ERROR_SUCCESS; 678*f30b1135SSebastian Grimberg } 679*f30b1135SSebastian Grimberg 680*f30b1135SSebastian Grimberg /** 681d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 682be9261b7Sjeremylt 683ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 684ea61e9acSJeremy 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 685ea61e9acSJeremy L Thompson : 4*blk_size] 686ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 687ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 688ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 689ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 690ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 691be9261b7Sjeremylt 692be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 693be9261b7Sjeremylt 6947a982d89SJeremy L. Thompson @ref Backend 695be9261b7Sjeremylt **/ 6962b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 6972b730f8bSJeremy L Thompson CeedRequest *request) { 698be9261b7Sjeremylt CeedInt m, n; 699be9261b7Sjeremylt 7006402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 7016402da51SJeremy L Thompson 702d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 703d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 704d1d35e2fSjeremylt n = rstr->l_size; 705be9261b7Sjeremylt } else { 706d1d35e2fSjeremylt m = rstr->l_size; 707d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 708be9261b7Sjeremylt } 7096574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 7106574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 7116574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 7126574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 7136574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 7146574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 7156574a04fSJeremy L Thompson rstr->num_elem); 7162b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 717e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 718be9261b7Sjeremylt } 719be9261b7Sjeremylt 720be9261b7Sjeremylt /** 721b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 722b7c9bbdaSJeremy L Thompson 723ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 724b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 725b7c9bbdaSJeremy L Thompson 726b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 727b7c9bbdaSJeremy L Thompson 728b7c9bbdaSJeremy L Thompson @ref Advanced 729b7c9bbdaSJeremy L Thompson **/ 730b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 731b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 732b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 733b7c9bbdaSJeremy L Thompson } 734b7c9bbdaSJeremy L Thompson 735b7c9bbdaSJeremy L Thompson /** 736d979a051Sjeremylt @brief Get the L-vector component stride 737a681ae63Sjeremylt 738ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 739d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 740a681ae63Sjeremylt 741a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 742a681ae63Sjeremylt 743b7c9bbdaSJeremy L Thompson @ref Advanced 744a681ae63Sjeremylt **/ 7452b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 746d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 747e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 748a681ae63Sjeremylt } 749a681ae63Sjeremylt 750a681ae63Sjeremylt /** 751a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 752a681ae63Sjeremylt 753ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 754d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 755a681ae63Sjeremylt 756a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 757a681ae63Sjeremylt 758b7c9bbdaSJeremy L Thompson @ref Advanced 759a681ae63Sjeremylt **/ 7602b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 761d1d35e2fSjeremylt *num_elem = rstr->num_elem; 762e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 763a681ae63Sjeremylt } 764a681ae63Sjeremylt 765a681ae63Sjeremylt /** 766a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 767a681ae63Sjeremylt 768ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 769d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 770a681ae63Sjeremylt 771a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 772a681ae63Sjeremylt 773b7c9bbdaSJeremy L Thompson @ref Advanced 774a681ae63Sjeremylt **/ 7752b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 776d1d35e2fSjeremylt *elem_size = rstr->elem_size; 777e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 778a681ae63Sjeremylt } 779a681ae63Sjeremylt 780a681ae63Sjeremylt /** 781d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 782a681ae63Sjeremylt 783ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 784d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 785a681ae63Sjeremylt 786a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 787a681ae63Sjeremylt 788b7c9bbdaSJeremy L Thompson @ref Advanced 789a681ae63Sjeremylt **/ 7902b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 791d1d35e2fSjeremylt *l_size = rstr->l_size; 792e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 793a681ae63Sjeremylt } 794a681ae63Sjeremylt 795a681ae63Sjeremylt /** 796ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 797a681ae63Sjeremylt 798ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 799d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 800a681ae63Sjeremylt 801a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 802a681ae63Sjeremylt 803b7c9bbdaSJeremy L Thompson @ref Advanced 804a681ae63Sjeremylt **/ 8052b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 806d1d35e2fSjeremylt *num_comp = rstr->num_comp; 807e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 808a681ae63Sjeremylt } 809a681ae63Sjeremylt 810a681ae63Sjeremylt /** 811a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 812a681ae63Sjeremylt 813ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 814d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 815a681ae63Sjeremylt 816a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 817a681ae63Sjeremylt 818b7c9bbdaSJeremy L Thompson @ref Advanced 819a681ae63Sjeremylt **/ 8202b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 821d1d35e2fSjeremylt *num_block = rstr->num_blk; 822e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 823a681ae63Sjeremylt } 824a681ae63Sjeremylt 825a681ae63Sjeremylt /** 826a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 827a681ae63Sjeremylt 828ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 829d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 830a681ae63Sjeremylt 831a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 832a681ae63Sjeremylt 833b7c9bbdaSJeremy L Thompson @ref Advanced 834a681ae63Sjeremylt **/ 8352b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 836d1d35e2fSjeremylt *blk_size = rstr->blk_size; 837e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 838a681ae63Sjeremylt } 839a681ae63Sjeremylt 840a681ae63Sjeremylt /** 841d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 8421469ee4dSjeremylt 843ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 844d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 8451469ee4dSjeremylt 8461469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 8471469ee4dSjeremylt 8487a982d89SJeremy L. Thompson @ref User 8491469ee4dSjeremylt **/ 8502b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 851d1d35e2fSjeremylt CeedVector e_vec; 8521469ee4dSjeremylt 85325509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 8542b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 8551469ee4dSjeremylt 85625509ebbSRezgar Shakeri // Compute e_vec = E * 1 8572b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 8582b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 85925509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 8602b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 8612b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 8621469ee4dSjeremylt // Cleanup 8632b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 864e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8651469ee4dSjeremylt } 8661469ee4dSjeremylt 8671469ee4dSjeremylt /** 868f02ca4a2SJed Brown @brief View a CeedElemRestriction 869f02ca4a2SJed Brown 870f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 871f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 872f02ca4a2SJed Brown 873f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 874f02ca4a2SJed Brown 8757a982d89SJeremy L. Thompson @ref User 876f02ca4a2SJed Brown **/ 877f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 8787509a596Sjeremylt char stridesstr[500]; 8792b730f8bSJeremy L Thompson if (rstr->strides) { 8802b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 8812b730f8bSJeremy L Thompson } else { 882990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 8832b730f8bSJeremy L Thompson } 8847509a596Sjeremylt 8852b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 8862b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 887d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 888e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 889f02ca4a2SJed Brown } 890f02ca4a2SJed Brown 891f02ca4a2SJed Brown /** 892b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 893b11c1e72Sjeremylt 894ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 895b11c1e72Sjeremylt 896b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 897dfdf5a53Sjeremylt 8987a982d89SJeremy L. Thompson @ref User 899b11c1e72Sjeremylt **/ 9004ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 901393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 902ad6481ceSJeremy L Thompson *rstr = NULL; 903ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 904ad6481ceSJeremy L Thompson } 9056574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 9066574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 9072b730f8bSJeremy L Thompson if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 9082b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 9092b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 9102b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 911e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 912d7b241e6Sjeremylt } 913d7b241e6Sjeremylt 914d7b241e6Sjeremylt /// @} 915