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> 13c17ec2beSJeremy L Thompson #include <string.h> 14d7b241e6Sjeremylt 157a982d89SJeremy L. Thompson /// @file 167a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces 177a982d89SJeremy L. Thompson 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions 207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 217a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper 227a982d89SJeremy L. Thompson /// @{ 237a982d89SJeremy L. Thompson 247a982d89SJeremy L. Thompson /** 25d979a051Sjeremylt @brief Permute and pad offsets for a blocked restriction 267a982d89SJeremy L. Thompson 27ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 28ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 29ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 30ea61e9acSJeremy L Thompson @param[out] blk_offsets Array of permuted and padded offsets of shape [@a num_blk, @a elem_size, @a blk_size]. 31ea61e9acSJeremy L Thompson @param[in] num_blk Number of blocks 32ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 33ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 34ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 357a982d89SJeremy L. Thompson 367a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 377a982d89SJeremy L. Thompson 387a982d89SJeremy L. Thompson @ref Utility 397a982d89SJeremy L. Thompson **/ 402b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 412b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 422b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 432b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 442b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 472b730f8bSJeremy L Thompson } 48e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 497a982d89SJeremy L. Thompson } 507a982d89SJeremy L. Thompson 517a982d89SJeremy L. Thompson /// @} 527a982d89SJeremy L. Thompson 537a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 547a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 557a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 567a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 577a982d89SJeremy L. Thompson /// @{ 587a982d89SJeremy L. Thompson 597a982d89SJeremy L. Thompson /** 60*78b2e752SJeremy L Thompson @brief Restrict an L-vector to an E-vector or apply its transpose ignoring any 61*78b2e752SJeremy L Thompson provided orientations 62*78b2e752SJeremy L Thompson 63*78b2e752SJeremy L Thompson @param[in] rstr CeedElemRestriction 64*78b2e752SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 65*78b2e752SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 66*78b2e752SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 67*78b2e752SJeremy L Thompson Ordering of the e-vector is decided by the backend. 68*78b2e752SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 69*78b2e752SJeremy L Thompson 70*78b2e752SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 71*78b2e752SJeremy L Thompson 72*78b2e752SJeremy L Thompson @ref User 73*78b2e752SJeremy L Thompson **/ 74*78b2e752SJeremy L Thompson int CeedElemRestrictionApplyUnsigned(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 75*78b2e752SJeremy L Thompson CeedInt m, n; 76*78b2e752SJeremy L Thompson 77*78b2e752SJeremy L Thompson CeedCheck(rstr->ApplyUnsigned, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionApplyUnsigned"); 78*78b2e752SJeremy L Thompson 79*78b2e752SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 80*78b2e752SJeremy L Thompson m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 81*78b2e752SJeremy L Thompson n = rstr->l_size; 82*78b2e752SJeremy L Thompson } else { 83*78b2e752SJeremy L Thompson m = rstr->l_size; 84*78b2e752SJeremy L Thompson n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 85*78b2e752SJeremy L Thompson } 86*78b2e752SJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 87*78b2e752SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 88*78b2e752SJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 89*78b2e752SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 90*78b2e752SJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyUnsigned(rstr, t_mode, u, ru, request)); 91*78b2e752SJeremy L Thompson return CEED_ERROR_SUCCESS; 92*78b2e752SJeremy L Thompson } 93*78b2e752SJeremy L Thompson 94*78b2e752SJeremy L Thompson /** 95a681ae63Sjeremylt 96a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 977a982d89SJeremy L. Thompson 98ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 99a681ae63Sjeremylt @param[out] strides Variable to store strides array 1007a982d89SJeremy L. Thompson 1017a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1027a982d89SJeremy L. Thompson 1037a982d89SJeremy L. Thompson @ref Backend 1047a982d89SJeremy L. Thompson **/ 1052b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1066574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1072b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 108e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1097a982d89SJeremy L. Thompson } 1107a982d89SJeremy L. Thompson 1117a982d89SJeremy L. Thompson /** 112bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 113bd33150aSjeremylt 114ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 115ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the array. 116ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy (possibly cached). 117d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 118bd33150aSjeremylt 119bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 120bd33150aSjeremylt 121bd33150aSjeremylt @ref User 122bd33150aSjeremylt **/ 1232b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 124c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 125c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_signed, mem_type, offsets)); 126c17ec2beSJeremy L Thompson } else { 1276574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 1282b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 129d1d35e2fSjeremylt rstr->num_readers++; 130c17ec2beSJeremy L Thompson } 131e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 132430758c8SJeremy L Thompson } 133430758c8SJeremy L Thompson 134430758c8SJeremy L Thompson /** 135430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 136430758c8SJeremy L Thompson 137ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 138ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 139430758c8SJeremy L Thompson 140430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 141430758c8SJeremy L Thompson 142430758c8SJeremy L Thompson @ref User 143430758c8SJeremy L Thompson **/ 1442b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 145c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 146c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_signed, offsets)); 147c17ec2beSJeremy L Thompson } else { 148430758c8SJeremy L Thompson *offsets = NULL; 149d1d35e2fSjeremylt rstr->num_readers--; 150c17ec2beSJeremy L Thompson } 151e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 152bd33150aSjeremylt } 153bd33150aSjeremylt 154bd33150aSjeremylt /** 1553ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1563ac43b2cSJeremy L Thompson 157ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 158d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1593ac43b2cSJeremy L Thompson 1603ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1613ac43b2cSJeremy L Thompson 1623ac43b2cSJeremy L Thompson @ref Backend 1633ac43b2cSJeremy L Thompson **/ 164d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 165d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 166e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1673ac43b2cSJeremy L Thompson } 1683ac43b2cSJeremy L Thompson 1693ac43b2cSJeremy L Thompson /** 170b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 171b435c5a6Srezgarshakeri 172ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 173b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 174b435c5a6Srezgarshakeri 175b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 176b435c5a6Srezgarshakeri 177b435c5a6Srezgarshakeri @ref Backend 178b435c5a6Srezgarshakeri **/ 179b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 180b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 181b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 182b435c5a6Srezgarshakeri } 183b435c5a6Srezgarshakeri 184b435c5a6Srezgarshakeri /** 185a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1867a982d89SJeremy L. Thompson 187ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 18896b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1897a982d89SJeremy L. Thompson 1907a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1917a982d89SJeremy L. Thompson 1927a982d89SJeremy L. Thompson @ref Backend 1937a982d89SJeremy L. Thompson **/ 1942b730f8bSJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 1956574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1962b730f8bSJeremy L Thompson *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 197a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 198e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1997a982d89SJeremy L. Thompson } 2007a982d89SJeremy L. Thompson 2017a982d89SJeremy L. Thompson /** 20249fd234cSJeremy L Thompson 20349fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 20449fd234cSJeremy L Thompson 205ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 206ea61e9acSJeremy L Thompson @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 207ea61e9acSJeremy 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] 20849fd234cSJeremy L Thompson 20949fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21049fd234cSJeremy L Thompson 21149fd234cSJeremy L Thompson @ref Backend 21249fd234cSJeremy L Thompson **/ 2132b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 2146574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 2152b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 216e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 21749fd234cSJeremy L Thompson } 21849fd234cSJeremy L Thompson 21949fd234cSJeremy L Thompson /** 22049fd234cSJeremy L Thompson 22149fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 22249fd234cSJeremy L Thompson 223ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 224ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 225ea61e9acSJeremy 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] 22649fd234cSJeremy L Thompson 22749fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 22849fd234cSJeremy L Thompson 22949fd234cSJeremy L Thompson @ref Backend 23049fd234cSJeremy L Thompson **/ 2312b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 2322b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 233e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 23449fd234cSJeremy L Thompson } 23549fd234cSJeremy L Thompson 23649fd234cSJeremy L Thompson /** 2377a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2387a982d89SJeremy L. Thompson 239ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 2407a982d89SJeremy L. Thompson @param[out] data Variable to store data 2417a982d89SJeremy L. Thompson 2427a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2437a982d89SJeremy L. Thompson 2447a982d89SJeremy L. Thompson @ref Backend 2457a982d89SJeremy L. Thompson **/ 246777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 247777ff853SJeremy L Thompson *(void **)data = rstr->data; 248e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2497a982d89SJeremy L. Thompson } 2507a982d89SJeremy L. Thompson 2517a982d89SJeremy L. Thompson /** 2527a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2537a982d89SJeremy L. Thompson 254ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 255ea61e9acSJeremy L Thompson @param[in] data Data to set 2567a982d89SJeremy L. Thompson 2577a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2587a982d89SJeremy L. Thompson 2597a982d89SJeremy L. Thompson @ref Backend 2607a982d89SJeremy L. Thompson **/ 261777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 262777ff853SJeremy L Thompson rstr->data = data; 263e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2647a982d89SJeremy L. Thompson } 2657a982d89SJeremy L. Thompson 26634359f16Sjeremylt /** 26734359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 26834359f16Sjeremylt 269ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 27034359f16Sjeremylt 27134359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 27234359f16Sjeremylt 27334359f16Sjeremylt @ref Backend 27434359f16Sjeremylt **/ 2759560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 27634359f16Sjeremylt rstr->ref_count++; 27734359f16Sjeremylt return CEED_ERROR_SUCCESS; 27834359f16Sjeremylt } 27934359f16Sjeremylt 2806e15d496SJeremy L Thompson /** 2816e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 2826e15d496SJeremy L Thompson 283ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 284ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 285ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 2866e15d496SJeremy L Thompson 2876e15d496SJeremy L Thompson @ref Backend 2886e15d496SJeremy L Thompson **/ 2892b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 2906e15d496SJeremy L Thompson bool is_oriented; 2912b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 2926e15d496SJeremy L Thompson 2932b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionIsOriented(rstr, &is_oriented)); 2946e15d496SJeremy L Thompson switch (t_mode) { 2952b730f8bSJeremy L Thompson case CEED_NOTRANSPOSE: 2962b730f8bSJeremy L Thompson scale = is_oriented ? 1 : 0; 2972b730f8bSJeremy L Thompson break; 2982b730f8bSJeremy L Thompson case CEED_TRANSPOSE: 2992b730f8bSJeremy L Thompson scale = is_oriented ? 2 : 1; 3002b730f8bSJeremy L Thompson break; 3016e15d496SJeremy L Thompson } 3026e15d496SJeremy L Thompson *flops = e_size * scale; 3036e15d496SJeremy L Thompson 3046e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 3056e15d496SJeremy L Thompson } 3066e15d496SJeremy L Thompson 3077a982d89SJeremy L. Thompson /// @} 3087a982d89SJeremy L. Thompson 30915910d16Sjeremylt /// @cond DOXYGEN_SKIP 31015910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 31115910d16Sjeremylt /// @endcond 31215910d16Sjeremylt 3137a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3147a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 3157a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3167a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 317d7b241e6Sjeremylt /// @{ 318d7b241e6Sjeremylt 3197a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 32045f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 3217a982d89SJeremy L. Thompson 3224cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 3232b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 3247a982d89SJeremy L. Thompson 325d7b241e6Sjeremylt /** 326b11c1e72Sjeremylt @brief Create a CeedElemRestriction 327d7b241e6Sjeremylt 328ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 329ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 330ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 331ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 332ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 333ea61e9acSJeremy 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. 334ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 335ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 336ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 337ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 338ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 339ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 340ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 341ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 342d7b241e6Sjeremylt 343b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 344dfdf5a53Sjeremylt 3457a982d89SJeremy L. Thompson @ref User 346b11c1e72Sjeremylt **/ 3472b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 3482b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 3495fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3505fe0d4faSjeremylt Ceed delegate; 3516574a04fSJeremy L Thompson 3522b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 3536574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreate"); 3542b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 355e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3565fe0d4faSjeremylt } 3575fe0d4faSjeremylt 3586574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 3596574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 3606574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 361e022e1f8SJeremy L Thompson 3622b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 3634ce2993fSjeremylt (*rstr)->ceed = ceed; 3642b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 365d1d35e2fSjeremylt (*rstr)->ref_count = 1; 366d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 367d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 368d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 369d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 370d1d35e2fSjeremylt (*rstr)->l_size = l_size; 371d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 372d1d35e2fSjeremylt (*rstr)->blk_size = 1; 3736402da51SJeremy L Thompson (*rstr)->is_oriented = false; 3742b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr)); 375e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 376d7b241e6Sjeremylt } 377d7b241e6Sjeremylt 378d7b241e6Sjeremylt /** 379fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 380fc0567d9Srezgarshakeri 381ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 382ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 383ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 384ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 385ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 386ea61e9acSJeremy 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. 387ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 388ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 389ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 390ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 391ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 392ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 393ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 394ea61e9acSJeremy 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. 395ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 396fc0567d9Srezgarshakeri 397fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 398fc0567d9Srezgarshakeri 399fc0567d9Srezgarshakeri @ref User 400fc0567d9Srezgarshakeri **/ 4012b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4022b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orient, 403fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 404c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 405fc0567d9Srezgarshakeri Ceed delegate; 4066574a04fSJeremy L Thompson 4072b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4086574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateOriented"); 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 4146574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4156574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4166574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 417e022e1f8SJeremy L Thompson 4182b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 419fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 4202b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 421fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 422fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 423fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 424fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 425fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 426fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 427fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 428fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 4296402da51SJeremy L Thompson (*rstr)->is_oriented = true; 4302b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient, *rstr)); 431fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 432fc0567d9Srezgarshakeri } 433fc0567d9Srezgarshakeri 434fc0567d9Srezgarshakeri /** 4357509a596Sjeremylt @brief Create a strided CeedElemRestriction 436d7b241e6Sjeremylt 437ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 438ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 439ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 440ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 441ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 442ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 443ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 444ea61e9acSJeremy 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]. 445ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 446ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 447d7b241e6Sjeremylt 448b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 449dfdf5a53Sjeremylt 4507a982d89SJeremy L. Thompson @ref User 451b11c1e72Sjeremylt **/ 4522b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 453f90c8643Sjeremylt CeedElemRestriction *rstr) { 4545fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4555fe0d4faSjeremylt Ceed delegate; 456b04eb3d9SSebastian Grimberg 4572b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4586402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateStrided"); 4592b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 460e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4615fe0d4faSjeremylt } 4625fe0d4faSjeremylt 4636574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4646574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 465e022e1f8SJeremy L Thompson 4662b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 4674ce2993fSjeremylt (*rstr)->ceed = ceed; 4682b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 469d1d35e2fSjeremylt (*rstr)->ref_count = 1; 470d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 471d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 472d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 473d1d35e2fSjeremylt (*rstr)->l_size = l_size; 474d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 475d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4766402da51SJeremy L Thompson (*rstr)->is_oriented = false; 4772b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 4782b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 4792b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 480e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 481d7b241e6Sjeremylt } 482d7b241e6Sjeremylt 483d7b241e6Sjeremylt /** 484b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 485d7b241e6Sjeremylt 486ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 487ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 488ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 489ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 490ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 491ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 492ea61e9acSJeremy 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. 493ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 494ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 495ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 496ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 497ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 498ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 499ea61e9acSJeremy 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 500ea61e9acSJeremy L Thompson the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 501ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 502d7b241e6Sjeremylt 503b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 504dfdf5a53Sjeremylt 5057a982d89SJeremy L. Thompson @ref Backend 506b11c1e72Sjeremylt **/ 5072b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 5082b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 5094ce2993fSjeremylt CeedElemRestriction *rstr) { 510d1d35e2fSjeremylt CeedInt *blk_offsets; 511d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 512d7b241e6Sjeremylt 5135fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5145fe0d4faSjeremylt Ceed delegate; 5156574a04fSJeremy L Thompson 5162b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5176402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 5182b730f8bSJeremy L Thompson CeedCall( 5192b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 520e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5215fe0d4faSjeremylt } 522d7b241e6Sjeremylt 5236574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5246574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 5256574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5266574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 527e022e1f8SJeremy L Thompson 5282b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 529d7b241e6Sjeremylt 5302b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 5312b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 532d7b241e6Sjeremylt 5334ce2993fSjeremylt (*rstr)->ceed = ceed; 5342b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 535d1d35e2fSjeremylt (*rstr)->ref_count = 1; 536d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 537d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 538d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 539d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 540d1d35e2fSjeremylt (*rstr)->l_size = l_size; 541d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 542d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5436402da51SJeremy L Thompson (*rstr)->is_oriented = false; 5442b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, *rstr)); 545d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 5462b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 5471d102b48SJeremy L Thompson } 548e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 549d7b241e6Sjeremylt } 550d7b241e6Sjeremylt 551b11c1e72Sjeremylt /** 5527509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5537509a596Sjeremylt 554ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 555ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 556ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 557ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 558ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 559ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 560ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 561ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 562ea61e9acSJeremy 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]. 563ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 564ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 5657509a596Sjeremylt 5667509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 5677509a596Sjeremylt 5687a982d89SJeremy L. Thompson @ref User 5697509a596Sjeremylt **/ 5702b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 5718621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 572d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 5737509a596Sjeremylt 5747509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5757509a596Sjeremylt Ceed delegate; 5766574a04fSJeremy L Thompson 5772b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5786402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlockedStrided"); 5792b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 580e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5817509a596Sjeremylt } 5827509a596Sjeremylt 5836574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5846574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 5856574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 586e022e1f8SJeremy L Thompson 5872b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 5887509a596Sjeremylt 5897509a596Sjeremylt (*rstr)->ceed = ceed; 5902b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 591d1d35e2fSjeremylt (*rstr)->ref_count = 1; 592d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 593d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 594d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 595d1d35e2fSjeremylt (*rstr)->l_size = l_size; 596d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 597d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5986402da51SJeremy L Thompson (*rstr)->is_oriented = false; 5992b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6002b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 6012b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 602e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6037509a596Sjeremylt } 6047509a596Sjeremylt 6057509a596Sjeremylt /** 606c17ec2beSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to `CeedElemRestrictionApplyUnsigned()`. 607c17ec2beSJeremy L Thompson 608c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 609c17ec2beSJeremy L Thompson 610c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 611c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 612c17ec2beSJeremy L Thompson 613c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 614c17ec2beSJeremy L Thompson 615c17ec2beSJeremy L Thompson @ref User 616c17ec2beSJeremy L Thompson **/ 617c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 618c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 619c17ec2beSJeremy L Thompson 620c17ec2beSJeremy L Thompson // Copy old rstr 621c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 622c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 623c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 624c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 625c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 626c17ec2beSJeremy L Thompson if (rstr->strides) { 627c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 628c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 629c17ec2beSJeremy L Thompson } 630c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_signed)); 631c17ec2beSJeremy L Thompson 632c17ec2beSJeremy L Thompson // Override Apply 633c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 634c17ec2beSJeremy L Thompson 635c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 636c17ec2beSJeremy L Thompson } 637c17ec2beSJeremy L Thompson 638c17ec2beSJeremy L Thompson /** 639ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 6409fd66db6SSebastian Grimberg 641ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 6429560d06aSjeremylt 6439fd66db6SSebastian 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. 6449fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 645ea61e9acSJeremy L Thompson 646ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 647ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 6489560d06aSjeremylt 6499560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6509560d06aSjeremylt 6519560d06aSjeremylt @ref User 6529560d06aSjeremylt **/ 6532b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 654393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 6552b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 6569560d06aSjeremylt *rstr_copy = rstr; 6579560d06aSjeremylt return CEED_ERROR_SUCCESS; 6589560d06aSjeremylt } 6599560d06aSjeremylt 6609560d06aSjeremylt /** 661b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 662b11c1e72Sjeremylt 663ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 664ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 665ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 666b11c1e72Sjeremylt 667b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 668dfdf5a53Sjeremylt 6697a982d89SJeremy L. Thompson @ref User 670b11c1e72Sjeremylt **/ 6712b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 672d2643443SJeremy L Thompson CeedSize e_size, l_size; 673d1d35e2fSjeremylt l_size = rstr->l_size; 674d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 6752b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 6762b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 677e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 678d7b241e6Sjeremylt } 679d7b241e6Sjeremylt 680d7b241e6Sjeremylt /** 681d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 682d7b241e6Sjeremylt 683ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 684ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 685ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 686ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 687ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 688ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 689b11c1e72Sjeremylt 690b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 691dfdf5a53Sjeremylt 6927a982d89SJeremy L. Thompson @ref User 693b11c1e72Sjeremylt **/ 6942b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 695d7b241e6Sjeremylt CeedInt m, n; 696d7b241e6Sjeremylt 697d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 698d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 699d1d35e2fSjeremylt n = rstr->l_size; 700d7b241e6Sjeremylt } else { 701d1d35e2fSjeremylt m = rstr->l_size; 702d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 703d7b241e6Sjeremylt } 7046574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 7056574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 7066574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 7076574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 7082b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 709e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 710d7b241e6Sjeremylt } 711d7b241e6Sjeremylt 712d7b241e6Sjeremylt /** 713d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 714be9261b7Sjeremylt 715ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 716ea61e9acSJeremy 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 717ea61e9acSJeremy L Thompson : 4*blk_size] 718ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 719ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 720ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 721ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 722ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 723be9261b7Sjeremylt 724be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 725be9261b7Sjeremylt 7267a982d89SJeremy L. Thompson @ref Backend 727be9261b7Sjeremylt **/ 7282b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 7292b730f8bSJeremy L Thompson CeedRequest *request) { 730be9261b7Sjeremylt CeedInt m, n; 731be9261b7Sjeremylt 7326402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 7336402da51SJeremy L Thompson 734d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 735d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 736d1d35e2fSjeremylt n = rstr->l_size; 737be9261b7Sjeremylt } else { 738d1d35e2fSjeremylt m = rstr->l_size; 739d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 740be9261b7Sjeremylt } 7416574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 7426574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 7436574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 7446574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 7456574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 7466574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 7476574a04fSJeremy L Thompson rstr->num_elem); 7482b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 749e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 750be9261b7Sjeremylt } 751be9261b7Sjeremylt 752be9261b7Sjeremylt /** 753b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 754b7c9bbdaSJeremy L Thompson 755ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 756b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 757b7c9bbdaSJeremy L Thompson 758b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 759b7c9bbdaSJeremy L Thompson 760b7c9bbdaSJeremy L Thompson @ref Advanced 761b7c9bbdaSJeremy L Thompson **/ 762b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 763b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 764b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 765b7c9bbdaSJeremy L Thompson } 766b7c9bbdaSJeremy L Thompson 767b7c9bbdaSJeremy L Thompson /** 768d979a051Sjeremylt @brief Get the L-vector component stride 769a681ae63Sjeremylt 770ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 771d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 772a681ae63Sjeremylt 773a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 774a681ae63Sjeremylt 775b7c9bbdaSJeremy L Thompson @ref Advanced 776a681ae63Sjeremylt **/ 7772b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 778d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 779e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 780a681ae63Sjeremylt } 781a681ae63Sjeremylt 782a681ae63Sjeremylt /** 783a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 784a681ae63Sjeremylt 785ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 786d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 787a681ae63Sjeremylt 788a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 789a681ae63Sjeremylt 790b7c9bbdaSJeremy L Thompson @ref Advanced 791a681ae63Sjeremylt **/ 7922b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 793d1d35e2fSjeremylt *num_elem = rstr->num_elem; 794e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 795a681ae63Sjeremylt } 796a681ae63Sjeremylt 797a681ae63Sjeremylt /** 798a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 799a681ae63Sjeremylt 800ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 801d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 802a681ae63Sjeremylt 803a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 804a681ae63Sjeremylt 805b7c9bbdaSJeremy L Thompson @ref Advanced 806a681ae63Sjeremylt **/ 8072b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 808d1d35e2fSjeremylt *elem_size = rstr->elem_size; 809e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 810a681ae63Sjeremylt } 811a681ae63Sjeremylt 812a681ae63Sjeremylt /** 813d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 814a681ae63Sjeremylt 815ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 816d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 817a681ae63Sjeremylt 818a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 819a681ae63Sjeremylt 820b7c9bbdaSJeremy L Thompson @ref Advanced 821a681ae63Sjeremylt **/ 8222b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 823d1d35e2fSjeremylt *l_size = rstr->l_size; 824e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 825a681ae63Sjeremylt } 826a681ae63Sjeremylt 827a681ae63Sjeremylt /** 828ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 829a681ae63Sjeremylt 830ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 831d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 832a681ae63Sjeremylt 833a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 834a681ae63Sjeremylt 835b7c9bbdaSJeremy L Thompson @ref Advanced 836a681ae63Sjeremylt **/ 8372b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 838d1d35e2fSjeremylt *num_comp = rstr->num_comp; 839e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 840a681ae63Sjeremylt } 841a681ae63Sjeremylt 842a681ae63Sjeremylt /** 843a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 844a681ae63Sjeremylt 845ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 846d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 847a681ae63Sjeremylt 848a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 849a681ae63Sjeremylt 850b7c9bbdaSJeremy L Thompson @ref Advanced 851a681ae63Sjeremylt **/ 8522b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 853d1d35e2fSjeremylt *num_block = rstr->num_blk; 854e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 855a681ae63Sjeremylt } 856a681ae63Sjeremylt 857a681ae63Sjeremylt /** 858a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 859a681ae63Sjeremylt 860ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 861d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 862a681ae63Sjeremylt 863a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 864a681ae63Sjeremylt 865b7c9bbdaSJeremy L Thompson @ref Advanced 866a681ae63Sjeremylt **/ 8672b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 868d1d35e2fSjeremylt *blk_size = rstr->blk_size; 869e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 870a681ae63Sjeremylt } 871a681ae63Sjeremylt 872a681ae63Sjeremylt /** 873d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 8741469ee4dSjeremylt 875ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 876d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 8771469ee4dSjeremylt 8781469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 8791469ee4dSjeremylt 8807a982d89SJeremy L. Thompson @ref User 8811469ee4dSjeremylt **/ 8822b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 883d1d35e2fSjeremylt CeedVector e_vec; 8841469ee4dSjeremylt 88525509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 8862b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 8871469ee4dSjeremylt 88825509ebbSRezgar Shakeri // Compute e_vec = E * 1 8892b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 8902b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 89125509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 8922b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 8932b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 8941469ee4dSjeremylt // Cleanup 8952b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 896e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8971469ee4dSjeremylt } 8981469ee4dSjeremylt 8991469ee4dSjeremylt /** 900f02ca4a2SJed Brown @brief View a CeedElemRestriction 901f02ca4a2SJed Brown 902f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 903f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 904f02ca4a2SJed Brown 905f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 906f02ca4a2SJed Brown 9077a982d89SJeremy L. Thompson @ref User 908f02ca4a2SJed Brown **/ 909f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 9107509a596Sjeremylt char stridesstr[500]; 9112b730f8bSJeremy L Thompson if (rstr->strides) { 9122b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 9132b730f8bSJeremy L Thompson } else { 914990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 9152b730f8bSJeremy L Thompson } 9167509a596Sjeremylt 9172b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 9182b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 919d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 920e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 921f02ca4a2SJed Brown } 922f02ca4a2SJed Brown 923f02ca4a2SJed Brown /** 924b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 925b11c1e72Sjeremylt 926ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 927b11c1e72Sjeremylt 928b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 929dfdf5a53Sjeremylt 9307a982d89SJeremy L. Thompson @ref User 931b11c1e72Sjeremylt **/ 9324ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 933393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 934ad6481ceSJeremy L Thompson *rstr = NULL; 935ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 936ad6481ceSJeremy L Thompson } 9376574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 9386574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 939c17ec2beSJeremy L Thompson 940c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 941c17ec2beSJeremy L Thompson if ((*rstr)->rstr_signed) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_signed)); 942c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 943c17ec2beSJeremy L Thompson 9442b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 9452b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 9462b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 947e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 948d7b241e6Sjeremylt } 949d7b241e6Sjeremylt 950d7b241e6Sjeremylt /// @} 951