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 /** 6078b2e752SJeremy L Thompson @brief Restrict an L-vector to an E-vector or apply its transpose ignoring any 6178b2e752SJeremy L Thompson provided orientations 6278b2e752SJeremy L Thompson 6378b2e752SJeremy L Thompson @param[in] rstr CeedElemRestriction 6478b2e752SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 6578b2e752SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 6678b2e752SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 6778b2e752SJeremy L Thompson Ordering of the e-vector is decided by the backend. 6878b2e752SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 6978b2e752SJeremy L Thompson 7078b2e752SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7178b2e752SJeremy L Thompson 7278b2e752SJeremy L Thompson @ref User 7378b2e752SJeremy L Thompson **/ 7478b2e752SJeremy L Thompson int CeedElemRestrictionApplyUnsigned(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 7578b2e752SJeremy L Thompson CeedInt m, n; 7678b2e752SJeremy L Thompson 7778b2e752SJeremy L Thompson CeedCheck(rstr->ApplyUnsigned, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionApplyUnsigned"); 7878b2e752SJeremy L Thompson 7978b2e752SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 8078b2e752SJeremy L Thompson m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 8178b2e752SJeremy L Thompson n = rstr->l_size; 8278b2e752SJeremy L Thompson } else { 8378b2e752SJeremy L Thompson m = rstr->l_size; 8478b2e752SJeremy L Thompson n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 8578b2e752SJeremy L Thompson } 8678b2e752SJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 8778b2e752SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 8878b2e752SJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 8978b2e752SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 9078b2e752SJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyUnsigned(rstr, t_mode, u, ru, request)); 9178b2e752SJeremy L Thompson return CEED_ERROR_SUCCESS; 9278b2e752SJeremy L Thompson } 9378b2e752SJeremy L Thompson 9478b2e752SJeremy 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)); 363*db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 364d1d35e2fSjeremylt (*rstr)->ref_count = 1; 365d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 366d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 367d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 368d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 369d1d35e2fSjeremylt (*rstr)->l_size = l_size; 370d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 371d1d35e2fSjeremylt (*rstr)->blk_size = 1; 3726402da51SJeremy L Thompson (*rstr)->is_oriented = false; 3732b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr)); 374e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 375d7b241e6Sjeremylt } 376d7b241e6Sjeremylt 377d7b241e6Sjeremylt /** 378fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 379fc0567d9Srezgarshakeri 380ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 381ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 382ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 383ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 384ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 385ea61e9acSJeremy 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. 386ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 387ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 388ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 389ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 390ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 391ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 392ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 393ea61e9acSJeremy 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. 394ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 395fc0567d9Srezgarshakeri 396fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 397fc0567d9Srezgarshakeri 398fc0567d9Srezgarshakeri @ref User 399fc0567d9Srezgarshakeri **/ 4002b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4012b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orient, 402fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 403c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 404fc0567d9Srezgarshakeri Ceed delegate; 4056574a04fSJeremy L Thompson 4062b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4076574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateOriented"); 4082b730f8bSJeremy L Thompson CeedCall( 4092b730f8bSJeremy L Thompson CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orient, rstr)); 410fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 411fc0567d9Srezgarshakeri } 412fc0567d9Srezgarshakeri 4136574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4146574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4156574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 416e022e1f8SJeremy L Thompson 4172b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 418*db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 419fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 420fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 421fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 422fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 423fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 424fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 425fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 426fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 4276402da51SJeremy L Thompson (*rstr)->is_oriented = true; 4282b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient, *rstr)); 429fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 430fc0567d9Srezgarshakeri } 431fc0567d9Srezgarshakeri 432fc0567d9Srezgarshakeri /** 4337509a596Sjeremylt @brief Create a strided CeedElemRestriction 434d7b241e6Sjeremylt 435ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 436ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 437ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 438ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 439ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 440ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 441ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 442ea61e9acSJeremy 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]. 443ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 444ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 445d7b241e6Sjeremylt 446b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 447dfdf5a53Sjeremylt 4487a982d89SJeremy L. Thompson @ref User 449b11c1e72Sjeremylt **/ 4502b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 451f90c8643Sjeremylt CeedElemRestriction *rstr) { 4525fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4535fe0d4faSjeremylt Ceed delegate; 454b04eb3d9SSebastian Grimberg 4552b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4566402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateStrided"); 4572b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 458e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4595fe0d4faSjeremylt } 4605fe0d4faSjeremylt 4616574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4626574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 463e022e1f8SJeremy L Thompson 4642b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 465*db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 466d1d35e2fSjeremylt (*rstr)->ref_count = 1; 467d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 468d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 469d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 470d1d35e2fSjeremylt (*rstr)->l_size = l_size; 471d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 472d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4736402da51SJeremy L Thompson (*rstr)->is_oriented = false; 4742b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 4752b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 4762b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 477e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 478d7b241e6Sjeremylt } 479d7b241e6Sjeremylt 480d7b241e6Sjeremylt /** 481b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 482d7b241e6Sjeremylt 483ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 484ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 485ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 486ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 487ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 488ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 489ea61e9acSJeremy 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. 490ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 491ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 492ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 493ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 494ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 495ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 496ea61e9acSJeremy 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 497ea61e9acSJeremy L Thompson the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 498ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 499d7b241e6Sjeremylt 500b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 501dfdf5a53Sjeremylt 5027a982d89SJeremy L. Thompson @ref Backend 503b11c1e72Sjeremylt **/ 5042b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 5052b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 5064ce2993fSjeremylt CeedElemRestriction *rstr) { 507d1d35e2fSjeremylt CeedInt *blk_offsets; 508d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 509d7b241e6Sjeremylt 5105fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5115fe0d4faSjeremylt Ceed delegate; 5126574a04fSJeremy L Thompson 5132b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5146402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 5152b730f8bSJeremy L Thompson CeedCall( 5162b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 517e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5185fe0d4faSjeremylt } 519d7b241e6Sjeremylt 5206574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5216574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 5226574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5236574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 524e022e1f8SJeremy L Thompson 5252b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 5262b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 527d7b241e6Sjeremylt 528*db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 529*db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 530d1d35e2fSjeremylt (*rstr)->ref_count = 1; 531d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 532d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 533d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 534d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 535d1d35e2fSjeremylt (*rstr)->l_size = l_size; 536d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 537d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5386402da51SJeremy L Thompson (*rstr)->is_oriented = false; 5392b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, *rstr)); 540d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 5412b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 5421d102b48SJeremy L Thompson } 543e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 544d7b241e6Sjeremylt } 545d7b241e6Sjeremylt 546b11c1e72Sjeremylt /** 5477509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5487509a596Sjeremylt 549ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 550ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 551ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 552ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 553ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 554ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 555ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 556ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 557ea61e9acSJeremy 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]. 558ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 559ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 5607509a596Sjeremylt 5617509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 5627509a596Sjeremylt 5637a982d89SJeremy L. Thompson @ref User 5647509a596Sjeremylt **/ 5652b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 5668621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 567d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 5687509a596Sjeremylt 5697509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5707509a596Sjeremylt Ceed delegate; 5716574a04fSJeremy L Thompson 5722b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5736402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlockedStrided"); 5742b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 575e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5767509a596Sjeremylt } 5777509a596Sjeremylt 5786574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5796574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 5806574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 581e022e1f8SJeremy L Thompson 5822b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 583*db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 584d1d35e2fSjeremylt (*rstr)->ref_count = 1; 585d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 586d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 587d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 588d1d35e2fSjeremylt (*rstr)->l_size = l_size; 589d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 590d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5916402da51SJeremy L Thompson (*rstr)->is_oriented = false; 5922b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 5932b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 5942b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 595e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5967509a596Sjeremylt } 5977509a596Sjeremylt 5987509a596Sjeremylt /** 599c17ec2beSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to `CeedElemRestrictionApplyUnsigned()`. 600c17ec2beSJeremy L Thompson 601c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 602c17ec2beSJeremy L Thompson 603c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 604c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 605c17ec2beSJeremy L Thompson 606c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 607c17ec2beSJeremy L Thompson 608c17ec2beSJeremy L Thompson @ref User 609c17ec2beSJeremy L Thompson **/ 610c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 611c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 612c17ec2beSJeremy L Thompson 613c17ec2beSJeremy L Thompson // Copy old rstr 614c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 615c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 616c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 617c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 618c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 619c17ec2beSJeremy L Thompson if (rstr->strides) { 620c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 621c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 622c17ec2beSJeremy L Thompson } 623c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_signed)); 624c17ec2beSJeremy L Thompson 625c17ec2beSJeremy L Thompson // Override Apply 626c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 627c17ec2beSJeremy L Thompson 628c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 629c17ec2beSJeremy L Thompson } 630c17ec2beSJeremy L Thompson 631c17ec2beSJeremy L Thompson /** 632ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 6339fd66db6SSebastian Grimberg 634ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 6359560d06aSjeremylt 6369fd66db6SSebastian 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. 6379fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 638ea61e9acSJeremy L Thompson 639ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 640ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 6419560d06aSjeremylt 6429560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6439560d06aSjeremylt 6449560d06aSjeremylt @ref User 6459560d06aSjeremylt **/ 6462b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 647393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 6482b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 6499560d06aSjeremylt *rstr_copy = rstr; 6509560d06aSjeremylt return CEED_ERROR_SUCCESS; 6519560d06aSjeremylt } 6529560d06aSjeremylt 6539560d06aSjeremylt /** 654b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 655b11c1e72Sjeremylt 656ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 657ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 658ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 659b11c1e72Sjeremylt 660b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 661dfdf5a53Sjeremylt 6627a982d89SJeremy L. Thompson @ref User 663b11c1e72Sjeremylt **/ 6642b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 665d2643443SJeremy L Thompson CeedSize e_size, l_size; 666d1d35e2fSjeremylt l_size = rstr->l_size; 667d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 6682b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 6692b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 670e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 671d7b241e6Sjeremylt } 672d7b241e6Sjeremylt 673d7b241e6Sjeremylt /** 674d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 675d7b241e6Sjeremylt 676ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 677ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 678ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 679ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 680ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 681ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 682b11c1e72Sjeremylt 683b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 684dfdf5a53Sjeremylt 6857a982d89SJeremy L. Thompson @ref User 686b11c1e72Sjeremylt **/ 6872b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 688d7b241e6Sjeremylt CeedInt m, n; 689d7b241e6Sjeremylt 690d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 691d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 692d1d35e2fSjeremylt n = rstr->l_size; 693d7b241e6Sjeremylt } else { 694d1d35e2fSjeremylt m = rstr->l_size; 695d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 696d7b241e6Sjeremylt } 6976574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 6986574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 6996574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 7006574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 7012b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 702e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 703d7b241e6Sjeremylt } 704d7b241e6Sjeremylt 705d7b241e6Sjeremylt /** 706d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 707be9261b7Sjeremylt 708ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 709ea61e9acSJeremy 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 710ea61e9acSJeremy L Thompson : 4*blk_size] 711ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 712ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 713ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 714ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 715ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 716be9261b7Sjeremylt 717be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 718be9261b7Sjeremylt 7197a982d89SJeremy L. Thompson @ref Backend 720be9261b7Sjeremylt **/ 7212b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 7222b730f8bSJeremy L Thompson CeedRequest *request) { 723be9261b7Sjeremylt CeedInt m, n; 724be9261b7Sjeremylt 7256402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 7266402da51SJeremy L Thompson 727d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 728d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 729d1d35e2fSjeremylt n = rstr->l_size; 730be9261b7Sjeremylt } else { 731d1d35e2fSjeremylt m = rstr->l_size; 732d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 733be9261b7Sjeremylt } 7346574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 7356574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 7366574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 7376574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 7386574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 7396574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 7406574a04fSJeremy L Thompson rstr->num_elem); 7412b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 742e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 743be9261b7Sjeremylt } 744be9261b7Sjeremylt 745be9261b7Sjeremylt /** 746b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 747b7c9bbdaSJeremy L Thompson 748ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 749b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 750b7c9bbdaSJeremy L Thompson 751b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 752b7c9bbdaSJeremy L Thompson 753b7c9bbdaSJeremy L Thompson @ref Advanced 754b7c9bbdaSJeremy L Thompson **/ 755b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 756b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 757b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 758b7c9bbdaSJeremy L Thompson } 759b7c9bbdaSJeremy L Thompson 760b7c9bbdaSJeremy L Thompson /** 761d979a051Sjeremylt @brief Get the L-vector component stride 762a681ae63Sjeremylt 763ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 764d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 765a681ae63Sjeremylt 766a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 767a681ae63Sjeremylt 768b7c9bbdaSJeremy L Thompson @ref Advanced 769a681ae63Sjeremylt **/ 7702b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 771d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 772e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 773a681ae63Sjeremylt } 774a681ae63Sjeremylt 775a681ae63Sjeremylt /** 776a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 777a681ae63Sjeremylt 778ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 779d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 780a681ae63Sjeremylt 781a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 782a681ae63Sjeremylt 783b7c9bbdaSJeremy L Thompson @ref Advanced 784a681ae63Sjeremylt **/ 7852b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 786d1d35e2fSjeremylt *num_elem = rstr->num_elem; 787e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 788a681ae63Sjeremylt } 789a681ae63Sjeremylt 790a681ae63Sjeremylt /** 791a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 792a681ae63Sjeremylt 793ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 794d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 795a681ae63Sjeremylt 796a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 797a681ae63Sjeremylt 798b7c9bbdaSJeremy L Thompson @ref Advanced 799a681ae63Sjeremylt **/ 8002b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 801d1d35e2fSjeremylt *elem_size = rstr->elem_size; 802e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 803a681ae63Sjeremylt } 804a681ae63Sjeremylt 805a681ae63Sjeremylt /** 806d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 807a681ae63Sjeremylt 808ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 809d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 810a681ae63Sjeremylt 811a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 812a681ae63Sjeremylt 813b7c9bbdaSJeremy L Thompson @ref Advanced 814a681ae63Sjeremylt **/ 8152b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 816d1d35e2fSjeremylt *l_size = rstr->l_size; 817e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 818a681ae63Sjeremylt } 819a681ae63Sjeremylt 820a681ae63Sjeremylt /** 821ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 822a681ae63Sjeremylt 823ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 824d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 825a681ae63Sjeremylt 826a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 827a681ae63Sjeremylt 828b7c9bbdaSJeremy L Thompson @ref Advanced 829a681ae63Sjeremylt **/ 8302b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 831d1d35e2fSjeremylt *num_comp = rstr->num_comp; 832e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 833a681ae63Sjeremylt } 834a681ae63Sjeremylt 835a681ae63Sjeremylt /** 836a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 837a681ae63Sjeremylt 838ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 839d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 840a681ae63Sjeremylt 841a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 842a681ae63Sjeremylt 843b7c9bbdaSJeremy L Thompson @ref Advanced 844a681ae63Sjeremylt **/ 8452b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 846d1d35e2fSjeremylt *num_block = rstr->num_blk; 847e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 848a681ae63Sjeremylt } 849a681ae63Sjeremylt 850a681ae63Sjeremylt /** 851a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 852a681ae63Sjeremylt 853ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 854d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 855a681ae63Sjeremylt 856a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 857a681ae63Sjeremylt 858b7c9bbdaSJeremy L Thompson @ref Advanced 859a681ae63Sjeremylt **/ 8602b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 861d1d35e2fSjeremylt *blk_size = rstr->blk_size; 862e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 863a681ae63Sjeremylt } 864a681ae63Sjeremylt 865a681ae63Sjeremylt /** 866d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 8671469ee4dSjeremylt 868ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 869d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 8701469ee4dSjeremylt 8711469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 8721469ee4dSjeremylt 8737a982d89SJeremy L. Thompson @ref User 8741469ee4dSjeremylt **/ 8752b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 876d1d35e2fSjeremylt CeedVector e_vec; 8771469ee4dSjeremylt 87825509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 8792b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 8801469ee4dSjeremylt 88125509ebbSRezgar Shakeri // Compute e_vec = E * 1 8822b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 8832b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 88425509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 8852b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 8862b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 8871469ee4dSjeremylt // Cleanup 8882b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 889e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8901469ee4dSjeremylt } 8911469ee4dSjeremylt 8921469ee4dSjeremylt /** 893f02ca4a2SJed Brown @brief View a CeedElemRestriction 894f02ca4a2SJed Brown 895f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 896f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 897f02ca4a2SJed Brown 898f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 899f02ca4a2SJed Brown 9007a982d89SJeremy L. Thompson @ref User 901f02ca4a2SJed Brown **/ 902f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 9037509a596Sjeremylt char stridesstr[500]; 9042b730f8bSJeremy L Thompson if (rstr->strides) { 9052b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 9062b730f8bSJeremy L Thompson } else { 907990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 9082b730f8bSJeremy L Thompson } 9097509a596Sjeremylt 9102b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 9112b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 912d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 913e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 914f02ca4a2SJed Brown } 915f02ca4a2SJed Brown 916f02ca4a2SJed Brown /** 917b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 918b11c1e72Sjeremylt 919ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 920b11c1e72Sjeremylt 921b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 922dfdf5a53Sjeremylt 9237a982d89SJeremy L. Thompson @ref User 924b11c1e72Sjeremylt **/ 9254ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 926393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 927ad6481ceSJeremy L Thompson *rstr = NULL; 928ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 929ad6481ceSJeremy L Thompson } 9306574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 9316574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 932c17ec2beSJeremy L Thompson 933c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 934c17ec2beSJeremy L Thompson if ((*rstr)->rstr_signed) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_signed)); 935c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 936c17ec2beSJeremy L Thompson 9372b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 9382b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 9392b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 940e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 941d7b241e6Sjeremylt } 942d7b241e6Sjeremylt 943d7b241e6Sjeremylt /// @} 944