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 27*77d1c127SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the offsets (into the input CeedVector) for the 28*77d1c127SSebastian Grimberg unknowns corresponding to element i, where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 29ea61e9acSJeremy L Thompson @param[out] blk_offsets Array of permuted and padded offsets of shape [@a num_blk, @a elem_size, @a blk_size]. 30ea61e9acSJeremy L Thompson @param[in] num_blk Number of blocks 31ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 32ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 33ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 347a982d89SJeremy L. Thompson 357a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 367a982d89SJeremy L. Thompson 377a982d89SJeremy L. Thompson @ref Utility 387a982d89SJeremy L. Thompson **/ 392b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 402b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 412b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 422b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 432b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 442b730f8bSJeremy L Thompson } 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 47e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 487a982d89SJeremy L. Thompson } 497a982d89SJeremy L. Thompson 50*77d1c127SSebastian Grimberg /** 51*77d1c127SSebastian Grimberg @brief Permute and pad orientations for a blocked restriction 52*77d1c127SSebastian Grimberg 53*77d1c127SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the orientations (into the input CeedVector) for 54*77d1c127SSebastian Grimberg the unknowns corresponding to element i, where 0 <= i < @a num_elem. 55*77d1c127SSebastian Grimberg @param[out] blk_orients Array of permuted and padded orientations of shape [@a num_blk, @a elem_size, @a blk_size]. 56*77d1c127SSebastian Grimberg @param[in] num_blk Number of blocks 57*77d1c127SSebastian Grimberg @param[in] num_elem Number of elements 58*77d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 59*77d1c127SSebastian Grimberg @param[in] elem_size Size of each element 60*77d1c127SSebastian Grimberg 61*77d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 62*77d1c127SSebastian Grimberg 63*77d1c127SSebastian Grimberg @ref Utility 64*77d1c127SSebastian Grimberg **/ 65*77d1c127SSebastian Grimberg int CeedPermutePadOrientations(const bool *orients, bool *blk_orients, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 66*77d1c127SSebastian Grimberg for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 67*77d1c127SSebastian Grimberg for (CeedInt j = 0; j < blk_size; j++) { 68*77d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 69*77d1c127SSebastian Grimberg blk_orients[e * elem_size + k * blk_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 70*77d1c127SSebastian Grimberg } 71*77d1c127SSebastian Grimberg } 72*77d1c127SSebastian Grimberg } 73*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 74*77d1c127SSebastian Grimberg } 75*77d1c127SSebastian Grimberg 767a982d89SJeremy L. Thompson /// @} 777a982d89SJeremy L. Thompson 787a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 797a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 807a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 817a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 827a982d89SJeremy L. Thompson /// @{ 837a982d89SJeremy L. Thompson 847a982d89SJeremy L. Thompson /** 8578b2e752SJeremy L Thompson @brief Restrict an L-vector to an E-vector or apply its transpose ignoring any 8678b2e752SJeremy L Thompson provided orientations 8778b2e752SJeremy L Thompson 8878b2e752SJeremy L Thompson @param[in] rstr CeedElemRestriction 8978b2e752SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 9078b2e752SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 9178b2e752SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 9278b2e752SJeremy L Thompson Ordering of the e-vector is decided by the backend. 9378b2e752SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 9478b2e752SJeremy L Thompson 9578b2e752SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9678b2e752SJeremy L Thompson 9778b2e752SJeremy L Thompson @ref User 9878b2e752SJeremy L Thompson **/ 9978b2e752SJeremy L Thompson int CeedElemRestrictionApplyUnsigned(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 10078b2e752SJeremy L Thompson CeedInt m, n; 10178b2e752SJeremy L Thompson 10278b2e752SJeremy L Thompson CeedCheck(rstr->ApplyUnsigned, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionApplyUnsigned"); 10378b2e752SJeremy L Thompson 10478b2e752SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 10578b2e752SJeremy L Thompson m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 10678b2e752SJeremy L Thompson n = rstr->l_size; 10778b2e752SJeremy L Thompson } else { 10878b2e752SJeremy L Thompson m = rstr->l_size; 10978b2e752SJeremy L Thompson n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 11078b2e752SJeremy L Thompson } 11178b2e752SJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11278b2e752SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 11378b2e752SJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11478b2e752SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 11578b2e752SJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyUnsigned(rstr, t_mode, u, ru, request)); 116*77d1c127SSebastian Grimberg 11778b2e752SJeremy L Thompson return CEED_ERROR_SUCCESS; 11878b2e752SJeremy L Thompson } 11978b2e752SJeremy L Thompson 12078b2e752SJeremy L Thompson /** 121a681ae63Sjeremylt 122a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 1237a982d89SJeremy L. Thompson 124ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 125a681ae63Sjeremylt @param[out] strides Variable to store strides array 1267a982d89SJeremy L. Thompson 1277a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1287a982d89SJeremy L. Thompson 1297a982d89SJeremy L. Thompson @ref Backend 1307a982d89SJeremy L. Thompson **/ 1312b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1326574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1332b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 134e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1357a982d89SJeremy L. Thompson } 1367a982d89SJeremy L. Thompson 1377a982d89SJeremy L. Thompson /** 138*77d1c127SSebastian Grimberg @brief Get the backend stride status of a CeedElemRestriction 139*77d1c127SSebastian Grimberg 140*77d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction 141*77d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 142*77d1c127SSebastian Grimberg 143*77d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 144*77d1c127SSebastian Grimberg 145*77d1c127SSebastian Grimberg @ref Backend 146*77d1c127SSebastian Grimberg **/ 147*77d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 148*77d1c127SSebastian Grimberg CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 149*77d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 150*77d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 151*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 152*77d1c127SSebastian Grimberg } 153*77d1c127SSebastian Grimberg 154*77d1c127SSebastian Grimberg /** 155bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 156bd33150aSjeremylt 157ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 158*77d1c127SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. If the backend uses a different memory type, this will perform a copy (possibly 159*77d1c127SSebastian Grimberg cached). 160d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 161bd33150aSjeremylt 162bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 163bd33150aSjeremylt 164bd33150aSjeremylt @ref User 165bd33150aSjeremylt **/ 1662b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 167c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 168c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_signed, mem_type, offsets)); 169c17ec2beSJeremy L Thompson } else { 1706574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 1712b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 172d1d35e2fSjeremylt rstr->num_readers++; 173c17ec2beSJeremy L Thompson } 174e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 175430758c8SJeremy L Thompson } 176430758c8SJeremy L Thompson 177430758c8SJeremy L Thompson /** 178430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 179430758c8SJeremy L Thompson 180ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 181ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 182430758c8SJeremy L Thompson 183430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 184430758c8SJeremy L Thompson 185430758c8SJeremy L Thompson @ref User 186430758c8SJeremy L Thompson **/ 1872b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 188c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 189c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_signed, offsets)); 190c17ec2beSJeremy L Thompson } else { 191430758c8SJeremy L Thompson *offsets = NULL; 192d1d35e2fSjeremylt rstr->num_readers--; 193c17ec2beSJeremy L Thompson } 194e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 195bd33150aSjeremylt } 196bd33150aSjeremylt 197bd33150aSjeremylt /** 198*77d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction orientations array by memtype 1993ac43b2cSJeremy L Thompson 200*77d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve orientations 201*77d1c127SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. If the backend uses a different memory type, this will perform a copy (possibly 202*77d1c127SSebastian Grimberg cached). 203*77d1c127SSebastian Grimberg @param[out] orients Array on memory type mem_type 2043ac43b2cSJeremy L Thompson 2053ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2063ac43b2cSJeremy L Thompson 207*77d1c127SSebastian Grimberg @ref User 2083ac43b2cSJeremy L Thompson **/ 209*77d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 210*77d1c127SSebastian Grimberg CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement GetOrientations"); 211*77d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 212*77d1c127SSebastian Grimberg rstr->num_readers++; 213e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2143ac43b2cSJeremy L Thompson } 2153ac43b2cSJeremy L Thompson 2163ac43b2cSJeremy L Thompson /** 217*77d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetOrientations() 218b435c5a6Srezgarshakeri 219*77d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 220*77d1c127SSebastian Grimberg @param[in] orients Array of orientation data 221b435c5a6Srezgarshakeri 222b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 223b435c5a6Srezgarshakeri 224*77d1c127SSebastian Grimberg @ref User 225b435c5a6Srezgarshakeri **/ 226*77d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 227*77d1c127SSebastian Grimberg *orients = NULL; 228*77d1c127SSebastian Grimberg rstr->num_readers--; 229b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 230b435c5a6Srezgarshakeri } 231b435c5a6Srezgarshakeri 232b435c5a6Srezgarshakeri /** 233*77d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction curl-conforming orientations array by memtype 2347a982d89SJeremy L. Thompson 235*77d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve curl-conforming orientations 236*77d1c127SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. If the backend uses a different memory type, this will perform a copy (possibly 237*77d1c127SSebastian Grimberg cached). 238*77d1c127SSebastian Grimberg @param[out] curl_orients Array on memory type mem_type 2397a982d89SJeremy L. Thompson 2407a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2417a982d89SJeremy L. Thompson 242*77d1c127SSebastian Grimberg @ref User 2437a982d89SJeremy L. Thompson **/ 244*77d1c127SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **curl_orients) { 245*77d1c127SSebastian Grimberg CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement GetCurlOrientations"); 246*77d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 247*77d1c127SSebastian Grimberg rstr->num_readers++; 248*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 249*77d1c127SSebastian Grimberg } 250*77d1c127SSebastian Grimberg 251*77d1c127SSebastian Grimberg /** 252*77d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetCurlOrientations() 253*77d1c127SSebastian Grimberg 254*77d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 255*77d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 256*77d1c127SSebastian Grimberg 257*77d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 258*77d1c127SSebastian Grimberg 259*77d1c127SSebastian Grimberg @ref User 260*77d1c127SSebastian Grimberg **/ 261*77d1c127SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt **curl_orients) { 262*77d1c127SSebastian Grimberg *curl_orients = NULL; 263*77d1c127SSebastian Grimberg rstr->num_readers--; 264e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2657a982d89SJeremy L. Thompson } 2667a982d89SJeremy L. Thompson 2677a982d89SJeremy L. Thompson /** 26849fd234cSJeremy L Thompson 26949fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 27049fd234cSJeremy L Thompson 271ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 272*77d1c127SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. The data for node i, component j, element k in the 273*77d1c127SSebastian Grimberg E-vector is given by i*layout[0] + j*layout[1] + k*layout[2] 27449fd234cSJeremy L Thompson 27549fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 27649fd234cSJeremy L Thompson 27749fd234cSJeremy L Thompson @ref Backend 27849fd234cSJeremy L Thompson **/ 2792b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 2806574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 2812b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 282e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 28349fd234cSJeremy L Thompson } 28449fd234cSJeremy L Thompson 28549fd234cSJeremy L Thompson /** 28649fd234cSJeremy L Thompson 28749fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 28849fd234cSJeremy L Thompson 289ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 290ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 291ea61e9acSJeremy 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] 29249fd234cSJeremy L Thompson 29349fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 29449fd234cSJeremy L Thompson 29549fd234cSJeremy L Thompson @ref Backend 29649fd234cSJeremy L Thompson **/ 2972b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 2982b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 299e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 30049fd234cSJeremy L Thompson } 30149fd234cSJeremy L Thompson 30249fd234cSJeremy L Thompson /** 3037a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3047a982d89SJeremy L. Thompson 305ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3067a982d89SJeremy L. Thompson @param[out] data Variable to store data 3077a982d89SJeremy L. Thompson 3087a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3097a982d89SJeremy L. Thompson 3107a982d89SJeremy L. Thompson @ref Backend 3117a982d89SJeremy L. Thompson **/ 312777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 313777ff853SJeremy L Thompson *(void **)data = rstr->data; 314e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3157a982d89SJeremy L. Thompson } 3167a982d89SJeremy L. Thompson 3177a982d89SJeremy L. Thompson /** 3187a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3197a982d89SJeremy L. Thompson 320ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 321ea61e9acSJeremy L Thompson @param[in] data Data to set 3227a982d89SJeremy L. Thompson 3237a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3247a982d89SJeremy L. Thompson 3257a982d89SJeremy L. Thompson @ref Backend 3267a982d89SJeremy L. Thompson **/ 327777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 328777ff853SJeremy L Thompson rstr->data = data; 329e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3307a982d89SJeremy L. Thompson } 3317a982d89SJeremy L. Thompson 33234359f16Sjeremylt /** 33334359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 33434359f16Sjeremylt 335ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 33634359f16Sjeremylt 33734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 33834359f16Sjeremylt 33934359f16Sjeremylt @ref Backend 34034359f16Sjeremylt **/ 3419560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 34234359f16Sjeremylt rstr->ref_count++; 34334359f16Sjeremylt return CEED_ERROR_SUCCESS; 34434359f16Sjeremylt } 34534359f16Sjeremylt 3466e15d496SJeremy L Thompson /** 3476e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 3486e15d496SJeremy L Thompson 349ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 350ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 351ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 3526e15d496SJeremy L Thompson 3536e15d496SJeremy L Thompson @ref Backend 3546e15d496SJeremy L Thompson **/ 3552b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 356*77d1c127SSebastian Grimberg const bool *orients = NULL; 357*77d1c127SSebastian Grimberg const CeedInt *curl_orients = NULL; 3582b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 3596e15d496SJeremy L Thompson 360*77d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetOrientations(rstr, CEED_MEM_HOST, &orients)); 361*77d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetCurlOrientations(rstr, CEED_MEM_HOST, &curl_orients)); 362*77d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 363*77d1c127SSebastian Grimberg if (!orients && !curl_orients) { 364*77d1c127SSebastian Grimberg scale = 1; 365*77d1c127SSebastian Grimberg } else if (!curl_orients) { 366*77d1c127SSebastian Grimberg scale = 2; 367*77d1c127SSebastian Grimberg } else { 368*77d1c127SSebastian Grimberg scale = 6; 3696e15d496SJeremy L Thompson } 370*77d1c127SSebastian Grimberg } else { 371*77d1c127SSebastian Grimberg if (!orients && !curl_orients) { 372*77d1c127SSebastian Grimberg scale = 0; 373*77d1c127SSebastian Grimberg } else if (!curl_orients) { 374*77d1c127SSebastian Grimberg scale = 1; 375*77d1c127SSebastian Grimberg } else { 376*77d1c127SSebastian Grimberg scale = 5; 377*77d1c127SSebastian Grimberg } 378*77d1c127SSebastian Grimberg } 379*77d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOrientations(rstr, &orients)); 380*77d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreCurlOrientations(rstr, &curl_orients)); 3816e15d496SJeremy L Thompson *flops = e_size * scale; 3826e15d496SJeremy L Thompson 3836e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 3846e15d496SJeremy L Thompson } 3856e15d496SJeremy L Thompson 3867a982d89SJeremy L. Thompson /// @} 3877a982d89SJeremy L. Thompson 38815910d16Sjeremylt /// @cond DOXYGEN_SKIP 38915910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 39015910d16Sjeremylt /// @endcond 39115910d16Sjeremylt 3927a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3937a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 3947a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3957a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 396d7b241e6Sjeremylt /// @{ 397d7b241e6Sjeremylt 3987a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 39945f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4007a982d89SJeremy L. Thompson 4014cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 4022b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4037a982d89SJeremy L. Thompson 404d7b241e6Sjeremylt /** 405b11c1e72Sjeremylt @brief Create a CeedElemRestriction 406d7b241e6Sjeremylt 407ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 408ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 409ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 410ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 411*77d1c127SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". Data for node i, component j, element k can be found in the L-vector 412*77d1c127SSebastian Grimberg at index offsets[i + k*elem_size] + j*comp_stride. 413*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 414ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 415ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 416*77d1c127SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the offsets (into the input CeedVector) for the 417*77d1c127SSebastian Grimberg unknowns corresponding to element i, where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 418ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 419d7b241e6Sjeremylt 420b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 421dfdf5a53Sjeremylt 4227a982d89SJeremy L. Thompson @ref User 423b11c1e72Sjeremylt **/ 4242b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4252b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4265fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4275fe0d4faSjeremylt Ceed delegate; 4286574a04fSJeremy L Thompson 4292b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 430*77d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4312b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 432e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4335fe0d4faSjeremylt } 4345fe0d4faSjeremylt 4356574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4366574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4376574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 438e022e1f8SJeremy L Thompson 4392b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 440db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 441d1d35e2fSjeremylt (*rstr)->ref_count = 1; 442d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 443d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 444d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 445d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 446d1d35e2fSjeremylt (*rstr)->l_size = l_size; 447d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 448d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4492b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr)); 450e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 451d7b241e6Sjeremylt } 452d7b241e6Sjeremylt 453d7b241e6Sjeremylt /** 454*77d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 455fc0567d9Srezgarshakeri 456ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 457ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 458ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 459ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 460*77d1c127SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". Data for node i, component j, element k can be found in the L-vector 461*77d1c127SSebastian Grimberg at index offsets[i + k*elem_size] + j*comp_stride. 462*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 463ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 464ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 465*77d1c127SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the offsets (into the input CeedVector) for the 466*77d1c127SSebastian Grimberg unknowns corresponding to element i, where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 467*77d1c127SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size] with bool false for positively oriented and true to flip the orientation. 468ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 469fc0567d9Srezgarshakeri 470fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 471fc0567d9Srezgarshakeri 472fc0567d9Srezgarshakeri @ref User 473fc0567d9Srezgarshakeri **/ 4742b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 475*77d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 476fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 477c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 478fc0567d9Srezgarshakeri Ceed delegate; 4796574a04fSJeremy L Thompson 4802b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4816574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateOriented"); 4822b730f8bSJeremy L Thompson CeedCall( 483*77d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 484fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 485fc0567d9Srezgarshakeri } 486fc0567d9Srezgarshakeri 4876574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4886574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4896574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 490e022e1f8SJeremy L Thompson 4912b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 492db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 493fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 494fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 495fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 496fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 497fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 498fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 499fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 500fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 501*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 502*77d1c127SSebastian Grimberg } 503*77d1c127SSebastian Grimberg 504*77d1c127SSebastian Grimberg /** 505*77d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 506*77d1c127SSebastian Grimberg 507*77d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 508*77d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 509*77d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 510*77d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 511*77d1c127SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". Data for node i, component j, element k can be found in the 512*77d1c127SSebastian Grimberg L-vector at index offsets[i + k*elem_size] + j*comp_stride. 513*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 514*77d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 515*77d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 516*77d1c127SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the offsets (into the input CeedVector) for the 517*77d1c127SSebastian Grimberg unknowns corresponding to element i, where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 518*77d1c127SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[0] = 519*77d1c127SSebastian Grimberg curl_orients[(i + 1) * 3 * elem_size - 1] = 0, where 0 <= i < @a num_elem) which is applied to the element unknowns upon restriction. This orientation 520*77d1c127SSebastian Grimberg matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the element restriction operation, which is a way 521*77d1c127SSebastian Grimberg to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 522*77d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 523*77d1c127SSebastian Grimberg 524*77d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 525*77d1c127SSebastian Grimberg 526*77d1c127SSebastian Grimberg @ref User 527*77d1c127SSebastian Grimberg **/ 528*77d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 529*77d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt *curl_orients, 530*77d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 531*77d1c127SSebastian Grimberg if (!ceed->ElemRestrictionCreateCurlOriented) { 532*77d1c127SSebastian Grimberg Ceed delegate; 533*77d1c127SSebastian Grimberg 534*77d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 535*77d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateCurlOriented"); 536*77d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 537*77d1c127SSebastian Grimberg curl_orients, rstr)); 538*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 539*77d1c127SSebastian Grimberg } 540*77d1c127SSebastian Grimberg 541*77d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 542*77d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 543*77d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 544*77d1c127SSebastian Grimberg 545*77d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 546*77d1c127SSebastian Grimberg (*rstr)->ceed = ceed; 547*77d1c127SSebastian Grimberg CeedCall(CeedReference(ceed)); 548*77d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 549*77d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 550*77d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 551*77d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 552*77d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 553*77d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 554*77d1c127SSebastian Grimberg (*rstr)->num_blk = num_elem; 555*77d1c127SSebastian Grimberg (*rstr)->blk_size = 1; 556*77d1c127SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateCurlOriented(mem_type, copy_mode, offsets, curl_orients, *rstr)); 557fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 558fc0567d9Srezgarshakeri } 559fc0567d9Srezgarshakeri 560fc0567d9Srezgarshakeri /** 5617509a596Sjeremylt @brief Create a strided CeedElemRestriction 562d7b241e6Sjeremylt 563ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 564ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 565ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 566ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 567*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 568*77d1c127SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. Data for node i, component j, element k can be found in the L-vector 569*77d1c127SSebastian Grimberg at index i*strides[0] + j*strides[1] + k*strides[2]. @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 570ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 571d7b241e6Sjeremylt 572b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 573dfdf5a53Sjeremylt 5747a982d89SJeremy L. Thompson @ref User 575b11c1e72Sjeremylt **/ 5762b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 577f90c8643Sjeremylt CeedElemRestriction *rstr) { 5785fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 5795fe0d4faSjeremylt Ceed delegate; 580b04eb3d9SSebastian Grimberg 5812b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 582*77d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateStrided"); 5832b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 584e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5855fe0d4faSjeremylt } 5865fe0d4faSjeremylt 5876574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5886574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 589e022e1f8SJeremy L Thompson 5902b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 591db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 592d1d35e2fSjeremylt (*rstr)->ref_count = 1; 593d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 594d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 595d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 596d1d35e2fSjeremylt (*rstr)->l_size = l_size; 597d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 598d1d35e2fSjeremylt (*rstr)->blk_size = 1; 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->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 602e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 603d7b241e6Sjeremylt } 604d7b241e6Sjeremylt 605d7b241e6Sjeremylt /** 606b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 607d7b241e6Sjeremylt 608ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 609ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 610ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 611ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 612ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 613*77d1c127SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". Data for node i, component j, element k can be found in the L-vector 614*77d1c127SSebastian Grimberg at index offsets[i + k*elem_size] + j*comp_stride. 615*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 616ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 617ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 618*77d1c127SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the offsets (into the input CeedVector) for the 619*77d1c127SSebastian Grimberg unknowns corresponding to element i, where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. The backend will permute and 620*77d1c127SSebastian Grimberg pad this array to the desired ordering for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 621ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 622d7b241e6Sjeremylt 623b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 624dfdf5a53Sjeremylt 6257a982d89SJeremy L. Thompson @ref Backend 626b11c1e72Sjeremylt **/ 6272b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 6282b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 6294ce2993fSjeremylt CeedElemRestriction *rstr) { 630d1d35e2fSjeremylt CeedInt *blk_offsets; 631d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 632d7b241e6Sjeremylt 6335fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6345fe0d4faSjeremylt Ceed delegate; 6356574a04fSJeremy L Thompson 6362b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 6376402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 6382b730f8bSJeremy L Thompson CeedCall( 6392b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 640e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6415fe0d4faSjeremylt } 642d7b241e6Sjeremylt 6436574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6446574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 6456574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 6466574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 647e022e1f8SJeremy L Thompson 6482b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 6492b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 650d7b241e6Sjeremylt 651db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 652db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 653d1d35e2fSjeremylt (*rstr)->ref_count = 1; 654d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 655d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 656d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 657d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 658d1d35e2fSjeremylt (*rstr)->l_size = l_size; 659d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 660d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 6612b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, *rstr)); 662d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 6632b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 6641d102b48SJeremy L Thompson } 665e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 666d7b241e6Sjeremylt } 667d7b241e6Sjeremylt 668b11c1e72Sjeremylt /** 669*77d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 670*77d1c127SSebastian Grimberg 671*77d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 672*77d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 673*77d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 674*77d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 675*77d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 676*77d1c127SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". Data for node i, component j, element k can be found in the L-vector 677*77d1c127SSebastian Grimberg at index offsets[i + k*elem_size] + j*comp_stride. 678*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 679*77d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 680*77d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 681*77d1c127SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the offsets (into the input CeedVector) for the 682*77d1c127SSebastian Grimberg unknowns corresponding to element i, where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. The backend will permute and 683*77d1c127SSebastian Grimberg pad this array to the desired ordering for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 684*77d1c127SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size] with bool false for positively oriented and true to flip the orientation. Will 685*77d1c127SSebastian Grimberg also be permuted and padded similarly to offsets. 686*77d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 687*77d1c127SSebastian Grimberg 688*77d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 689*77d1c127SSebastian Grimberg 690*77d1c127SSebastian Grimberg @ref Backend 691*77d1c127SSebastian Grimberg **/ 692*77d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 693*77d1c127SSebastian Grimberg CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 694*77d1c127SSebastian Grimberg const bool *orients, CeedElemRestriction *rstr) { 695*77d1c127SSebastian Grimberg CeedInt *blk_offsets; 696*77d1c127SSebastian Grimberg bool *blk_orients; 697*77d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 698*77d1c127SSebastian Grimberg 699*77d1c127SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlockedOriented) { 700*77d1c127SSebastian Grimberg Ceed delegate; 701*77d1c127SSebastian Grimberg 702*77d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 703*77d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlockedOriented"); 704*77d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 705*77d1c127SSebastian Grimberg offsets, orients, rstr)); 706*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 707*77d1c127SSebastian Grimberg } 708*77d1c127SSebastian Grimberg 709*77d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 710*77d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 711*77d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 712*77d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 713*77d1c127SSebastian Grimberg 714*77d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 715*77d1c127SSebastian Grimberg 716*77d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 717*77d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_orients)); 718*77d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 719*77d1c127SSebastian Grimberg CeedCall(CeedPermutePadOrientations(orients, blk_orients, num_blk, num_elem, blk_size, elem_size)); 720*77d1c127SSebastian Grimberg 721*77d1c127SSebastian Grimberg (*rstr)->ceed = ceed; 722*77d1c127SSebastian Grimberg CeedCall(CeedReference(ceed)); 723*77d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 724*77d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 725*77d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 726*77d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 727*77d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 728*77d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 729*77d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 730*77d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 731*77d1c127SSebastian Grimberg CeedCall( 732*77d1c127SSebastian Grimberg ceed->ElemRestrictionCreateBlockedOriented(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, (const bool *)blk_orients, *rstr)); 733*77d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 734*77d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 735*77d1c127SSebastian Grimberg } 736*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 737*77d1c127SSebastian Grimberg } 738*77d1c127SSebastian Grimberg 739*77d1c127SSebastian Grimberg /** 740*77d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 741*77d1c127SSebastian Grimberg 742*77d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 743*77d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 744*77d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 745*77d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 746*77d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 747*77d1c127SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". Data for node i, component j, element k can be found in the 748*77d1c127SSebastian Grimberg L-vector at index offsets[i + k*elem_size] + j*comp_stride. 749*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 750*77d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 751*77d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 752*77d1c127SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the ordered list of the offsets (into the input CeedVector) for the 753*77d1c127SSebastian Grimberg unknowns corresponding to element i, where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. The backend will permute and 754*77d1c127SSebastian Grimberg pad this array to the desired ordering for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 755*77d1c127SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[0] = 756*77d1c127SSebastian Grimberg curl_orients[(i + 1) * 3 * elem_size - 1] = 0, where 0 <= i < @a num_elem) which is applied to the element unknowns upon restriction. This orientation 757*77d1c127SSebastian Grimberg matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the element restriction operation, which is a way 758*77d1c127SSebastian Grimberg to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). Will also be permuted and padded similarly to 759*77d1c127SSebastian Grimberg offsets. 760*77d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 761*77d1c127SSebastian Grimberg 762*77d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 763*77d1c127SSebastian Grimberg 764*77d1c127SSebastian Grimberg @ref Backend 765*77d1c127SSebastian Grimberg **/ 766*77d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, 767*77d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 768*77d1c127SSebastian Grimberg const CeedInt *offsets, const CeedInt *curl_orients, CeedElemRestriction *rstr) { 769*77d1c127SSebastian Grimberg CeedInt *blk_offsets; 770*77d1c127SSebastian Grimberg CeedInt *blk_curl_orients; 771*77d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 772*77d1c127SSebastian Grimberg 773*77d1c127SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlockedCurlOriented) { 774*77d1c127SSebastian Grimberg Ceed delegate; 775*77d1c127SSebastian Grimberg 776*77d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 777*77d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlockedCurlOriented"); 778*77d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 779*77d1c127SSebastian Grimberg offsets, curl_orients, rstr)); 780*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 781*77d1c127SSebastian Grimberg } 782*77d1c127SSebastian Grimberg 783*77d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 784*77d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 785*77d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 786*77d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 787*77d1c127SSebastian Grimberg 788*77d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 789*77d1c127SSebastian Grimberg 790*77d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 791*77d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * 3 * elem_size, &blk_curl_orients)); 792*77d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 793*77d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(curl_orients, blk_curl_orients, num_blk, num_elem, blk_size, 3 * elem_size)); 794*77d1c127SSebastian Grimberg 795*77d1c127SSebastian Grimberg (*rstr)->ceed = ceed; 796*77d1c127SSebastian Grimberg CeedCall(CeedReference(ceed)); 797*77d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 798*77d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 799*77d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 800*77d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 801*77d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 802*77d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 803*77d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 804*77d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 805*77d1c127SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlockedCurlOriented(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, 806*77d1c127SSebastian Grimberg (const CeedInt *)blk_curl_orients, *rstr)); 807*77d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 808*77d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 809*77d1c127SSebastian Grimberg } 810*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 811*77d1c127SSebastian Grimberg } 812*77d1c127SSebastian Grimberg 813*77d1c127SSebastian Grimberg /** 814*77d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 8157509a596Sjeremylt 816ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 817ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 818ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 819ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 820ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 821*77d1c127SSebastian Grimberg @param[in] l_size The size of the L-vector. This vector may be larger than the elements and fields given by this restriction. 822*77d1c127SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. Data for node i, component j, element k can be found in the L-vector 823*77d1c127SSebastian Grimberg at index i*strides[0] + j*strides[1] + k*strides[2]. @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 824ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 8257509a596Sjeremylt 8267509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 8277509a596Sjeremylt 8287a982d89SJeremy L. Thompson @ref User 8297509a596Sjeremylt **/ 8302b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 8318621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 832d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 8337509a596Sjeremylt 8347509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 8357509a596Sjeremylt Ceed delegate; 8366574a04fSJeremy L Thompson 8372b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 8386402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlockedStrided"); 8392b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 840e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8417509a596Sjeremylt } 8427509a596Sjeremylt 8436574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 8446574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 8456574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 846e022e1f8SJeremy L Thompson 8472b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 848db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 849d1d35e2fSjeremylt (*rstr)->ref_count = 1; 850d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 851d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 852d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 853d1d35e2fSjeremylt (*rstr)->l_size = l_size; 854d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 855d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 8562b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 8572b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 8582b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 859e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8607509a596Sjeremylt } 8617509a596Sjeremylt 8627509a596Sjeremylt /** 863c17ec2beSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to `CeedElemRestrictionApplyUnsigned()`. 864c17ec2beSJeremy L Thompson 865c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 866c17ec2beSJeremy L Thompson 867c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 868c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 869c17ec2beSJeremy L Thompson 870c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 871c17ec2beSJeremy L Thompson 872c17ec2beSJeremy L Thompson @ref User 873c17ec2beSJeremy L Thompson **/ 874c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 875c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 876c17ec2beSJeremy L Thompson 877c17ec2beSJeremy L Thompson // Copy old rstr 878c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 879c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 880c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 881c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 882c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 883c17ec2beSJeremy L Thompson if (rstr->strides) { 884c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 885c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 886c17ec2beSJeremy L Thompson } 887c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_signed)); 888c17ec2beSJeremy L Thompson 889c17ec2beSJeremy L Thompson // Override Apply 890c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 891c17ec2beSJeremy L Thompson 892c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 893c17ec2beSJeremy L Thompson } 894c17ec2beSJeremy L Thompson 895c17ec2beSJeremy L Thompson /** 896ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 8979fd66db6SSebastian Grimberg 898ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 8999560d06aSjeremylt 9009fd66db6SSebastian 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. 9019fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 902ea61e9acSJeremy L Thompson 903ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 904ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 9059560d06aSjeremylt 9069560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 9079560d06aSjeremylt 9089560d06aSjeremylt @ref User 9099560d06aSjeremylt **/ 9102b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 911393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 9122b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 9139560d06aSjeremylt *rstr_copy = rstr; 9149560d06aSjeremylt return CEED_ERROR_SUCCESS; 9159560d06aSjeremylt } 9169560d06aSjeremylt 9179560d06aSjeremylt /** 918b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 919b11c1e72Sjeremylt 920ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 921ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 922ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 923b11c1e72Sjeremylt 924b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 925dfdf5a53Sjeremylt 9267a982d89SJeremy L. Thompson @ref User 927b11c1e72Sjeremylt **/ 9282b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 929d2643443SJeremy L Thompson CeedSize e_size, l_size; 930d1d35e2fSjeremylt l_size = rstr->l_size; 931d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 9322b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 9332b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 934e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 935d7b241e6Sjeremylt } 936d7b241e6Sjeremylt 937d7b241e6Sjeremylt /** 938d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 939d7b241e6Sjeremylt 940ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 941ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 942ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 943*77d1c127SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided by 944*77d1c127SSebastian Grimberg the backend. 945ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 946b11c1e72Sjeremylt 947b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 948dfdf5a53Sjeremylt 9497a982d89SJeremy L. Thompson @ref User 950b11c1e72Sjeremylt **/ 9512b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 952d7b241e6Sjeremylt CeedInt m, n; 953d7b241e6Sjeremylt 954d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 955d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 956d1d35e2fSjeremylt n = rstr->l_size; 957d7b241e6Sjeremylt } else { 958d1d35e2fSjeremylt m = rstr->l_size; 959d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 960d7b241e6Sjeremylt } 9616574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 9626574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 9636574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 9646574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 9652b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 966e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 967d7b241e6Sjeremylt } 968d7b241e6Sjeremylt 969d7b241e6Sjeremylt /** 970d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 971be9261b7Sjeremylt 972ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 973ea61e9acSJeremy 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 974ea61e9acSJeremy L Thompson : 4*blk_size] 975ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 976ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 977*77d1c127SSebastian Grimberg @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided by 978*77d1c127SSebastian Grimberg the backend. 979ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 980be9261b7Sjeremylt 981be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 982be9261b7Sjeremylt 9837a982d89SJeremy L. Thompson @ref Backend 984be9261b7Sjeremylt **/ 9852b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 9862b730f8bSJeremy L Thompson CeedRequest *request) { 987be9261b7Sjeremylt CeedInt m, n; 988be9261b7Sjeremylt 9896402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 9906402da51SJeremy L Thompson 991d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 992d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 993d1d35e2fSjeremylt n = rstr->l_size; 994be9261b7Sjeremylt } else { 995d1d35e2fSjeremylt m = rstr->l_size; 996d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 997be9261b7Sjeremylt } 9986574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 9996574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10006574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10016574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10026574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 10036574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 10046574a04fSJeremy L Thompson rstr->num_elem); 10052b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1006e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1007be9261b7Sjeremylt } 1008be9261b7Sjeremylt 1009be9261b7Sjeremylt /** 1010b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1011b7c9bbdaSJeremy L Thompson 1012ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1013b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1014b7c9bbdaSJeremy L Thompson 1015b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1016b7c9bbdaSJeremy L Thompson 1017b7c9bbdaSJeremy L Thompson @ref Advanced 1018b7c9bbdaSJeremy L Thompson **/ 1019b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1020b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1021b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1022b7c9bbdaSJeremy L Thompson } 1023b7c9bbdaSJeremy L Thompson 1024b7c9bbdaSJeremy L Thompson /** 1025d979a051Sjeremylt @brief Get the L-vector component stride 1026a681ae63Sjeremylt 1027ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1028d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1029a681ae63Sjeremylt 1030a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1031a681ae63Sjeremylt 1032b7c9bbdaSJeremy L Thompson @ref Advanced 1033a681ae63Sjeremylt **/ 10342b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1035d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1036e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1037a681ae63Sjeremylt } 1038a681ae63Sjeremylt 1039a681ae63Sjeremylt /** 1040a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1041a681ae63Sjeremylt 1042ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1043d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1044a681ae63Sjeremylt 1045a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1046a681ae63Sjeremylt 1047b7c9bbdaSJeremy L Thompson @ref Advanced 1048a681ae63Sjeremylt **/ 10492b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1050d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1051e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1052a681ae63Sjeremylt } 1053a681ae63Sjeremylt 1054a681ae63Sjeremylt /** 1055a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1056a681ae63Sjeremylt 1057ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1058d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1059a681ae63Sjeremylt 1060a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1061a681ae63Sjeremylt 1062b7c9bbdaSJeremy L Thompson @ref Advanced 1063a681ae63Sjeremylt **/ 10642b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1065d1d35e2fSjeremylt *elem_size = rstr->elem_size; 1066e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1067a681ae63Sjeremylt } 1068a681ae63Sjeremylt 1069a681ae63Sjeremylt /** 1070d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1071a681ae63Sjeremylt 1072ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1073d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1074a681ae63Sjeremylt 1075a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1076a681ae63Sjeremylt 1077b7c9bbdaSJeremy L Thompson @ref Advanced 1078a681ae63Sjeremylt **/ 10792b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1080d1d35e2fSjeremylt *l_size = rstr->l_size; 1081e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1082a681ae63Sjeremylt } 1083a681ae63Sjeremylt 1084a681ae63Sjeremylt /** 1085ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1086a681ae63Sjeremylt 1087ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1088d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1089a681ae63Sjeremylt 1090a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1091a681ae63Sjeremylt 1092b7c9bbdaSJeremy L Thompson @ref Advanced 1093a681ae63Sjeremylt **/ 10942b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1095d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1096e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1097a681ae63Sjeremylt } 1098a681ae63Sjeremylt 1099a681ae63Sjeremylt /** 1100a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1101a681ae63Sjeremylt 1102ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1103d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1104a681ae63Sjeremylt 1105a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1106a681ae63Sjeremylt 1107b7c9bbdaSJeremy L Thompson @ref Advanced 1108a681ae63Sjeremylt **/ 11092b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1110d1d35e2fSjeremylt *num_block = rstr->num_blk; 1111e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1112a681ae63Sjeremylt } 1113a681ae63Sjeremylt 1114a681ae63Sjeremylt /** 1115a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1116a681ae63Sjeremylt 1117ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1118d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 1119a681ae63Sjeremylt 1120a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1121a681ae63Sjeremylt 1122b7c9bbdaSJeremy L Thompson @ref Advanced 1123a681ae63Sjeremylt **/ 11242b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 1125d1d35e2fSjeremylt *blk_size = rstr->blk_size; 1126e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1127a681ae63Sjeremylt } 1128a681ae63Sjeremylt 1129a681ae63Sjeremylt /** 1130d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 11311469ee4dSjeremylt 1132ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1133d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 11341469ee4dSjeremylt 11351469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 11361469ee4dSjeremylt 11377a982d89SJeremy L. Thompson @ref User 11381469ee4dSjeremylt **/ 11392b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1140d1d35e2fSjeremylt CeedVector e_vec; 11411469ee4dSjeremylt 114225509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 11432b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 11441469ee4dSjeremylt 114525509ebbSRezgar Shakeri // Compute e_vec = E * 1 11462b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 11472b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 114825509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 11492b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 11502b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 11511469ee4dSjeremylt // Cleanup 11522b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1153e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11541469ee4dSjeremylt } 11551469ee4dSjeremylt 11561469ee4dSjeremylt /** 1157f02ca4a2SJed Brown @brief View a CeedElemRestriction 1158f02ca4a2SJed Brown 1159f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1160f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1161f02ca4a2SJed Brown 1162f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1163f02ca4a2SJed Brown 11647a982d89SJeremy L. Thompson @ref User 1165f02ca4a2SJed Brown **/ 1166f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 11677509a596Sjeremylt char stridesstr[500]; 11682b730f8bSJeremy L Thompson if (rstr->strides) { 11692b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 11702b730f8bSJeremy L Thompson } else { 1171990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 11722b730f8bSJeremy L Thompson } 11737509a596Sjeremylt 11742b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 11752b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1176d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1177e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1178f02ca4a2SJed Brown } 1179f02ca4a2SJed Brown 1180f02ca4a2SJed Brown /** 1181b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1182b11c1e72Sjeremylt 1183ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1184b11c1e72Sjeremylt 1185b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1186dfdf5a53Sjeremylt 11877a982d89SJeremy L. Thompson @ref User 1188b11c1e72Sjeremylt **/ 11894ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1190393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1191ad6481ceSJeremy L Thompson *rstr = NULL; 1192ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1193ad6481ceSJeremy L Thompson } 11946574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 11956574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1196c17ec2beSJeremy L Thompson 1197c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 1198c17ec2beSJeremy L Thompson if ((*rstr)->rstr_signed) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_signed)); 1199c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1200c17ec2beSJeremy L Thompson 12012b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 12022b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 12032b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1204e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1205d7b241e6Sjeremylt } 1206d7b241e6Sjeremylt 1207d7b241e6Sjeremylt /// @} 1208