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 27fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 28*0c73c039SSebastian Grimberg @param[out] blk_offsets Array of permuted and padded array values of shape [@a num_blk, @a elem_size, @a blk_size]. 29ea61e9acSJeremy L Thompson @param[in] num_blk Number of blocks 30ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 31ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 32ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 337a982d89SJeremy L. Thompson 347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 357a982d89SJeremy L. Thompson 367a982d89SJeremy L. Thompson @ref Utility 377a982d89SJeremy L. Thompson **/ 382b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 392b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 402b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 412b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 422b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 432b730f8bSJeremy L Thompson } 442b730f8bSJeremy L Thompson } 452b730f8bSJeremy L Thompson } 46e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 477a982d89SJeremy L. Thompson } 487a982d89SJeremy L. Thompson 4977d1c127SSebastian Grimberg /** 5077d1c127SSebastian Grimberg @brief Permute and pad orientations for a blocked restriction 5177d1c127SSebastian Grimberg 52fcbe8c06SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size]. 53*0c73c039SSebastian Grimberg @param[out] blk_orients Array of permuted and padded array values of shape [@a num_blk, @a elem_size, @a blk_size]. 5477d1c127SSebastian Grimberg @param[in] num_blk Number of blocks 5577d1c127SSebastian Grimberg @param[in] num_elem Number of elements 5677d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 5777d1c127SSebastian Grimberg @param[in] elem_size Size of each element 5877d1c127SSebastian Grimberg 5977d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 6077d1c127SSebastian Grimberg 6177d1c127SSebastian Grimberg @ref Utility 6277d1c127SSebastian Grimberg **/ 63*0c73c039SSebastian Grimberg int CeedPermutePadOrients(const bool *orients, bool *blk_orients, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 6477d1c127SSebastian Grimberg for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 6577d1c127SSebastian Grimberg for (CeedInt j = 0; j < blk_size; j++) { 6677d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 6777d1c127SSebastian Grimberg blk_orients[e * elem_size + k * blk_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 6877d1c127SSebastian Grimberg } 6977d1c127SSebastian Grimberg } 7077d1c127SSebastian Grimberg } 7177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 7277d1c127SSebastian Grimberg } 7377d1c127SSebastian Grimberg 74*0c73c039SSebastian Grimberg /** 75*0c73c039SSebastian Grimberg @brief Permute and pad curl-conforming orientations for a blocked restriction 76*0c73c039SSebastian Grimberg 77*0c73c039SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size]. 78*0c73c039SSebastian Grimberg @param[out] blk_curl_orients Array of permuted and padded array values of shape [@a num_blk, @a elem_size, @a blk_size]. 79*0c73c039SSebastian Grimberg @param[in] num_blk Number of blocks 80*0c73c039SSebastian Grimberg @param[in] num_elem Number of elements 81*0c73c039SSebastian Grimberg @param[in] blk_size Number of elements in a block 82*0c73c039SSebastian Grimberg @param[in] elem_size Size of each element 83*0c73c039SSebastian Grimberg 84*0c73c039SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 85*0c73c039SSebastian Grimberg 86*0c73c039SSebastian Grimberg @ref Utility 87*0c73c039SSebastian Grimberg **/ 88*0c73c039SSebastian Grimberg int CeedPermutePadCurlOrients(const CeedInt8 *curl_orients, CeedInt8 *blk_curl_orients, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, 89*0c73c039SSebastian Grimberg CeedInt elem_size) { 90*0c73c039SSebastian Grimberg for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 91*0c73c039SSebastian Grimberg for (CeedInt j = 0; j < blk_size; j++) { 92*0c73c039SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 93*0c73c039SSebastian Grimberg blk_curl_orients[e * elem_size + k * blk_size + j] = curl_orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 94*0c73c039SSebastian Grimberg } 95*0c73c039SSebastian Grimberg } 96*0c73c039SSebastian Grimberg } 97*0c73c039SSebastian Grimberg return CEED_ERROR_SUCCESS; 98*0c73c039SSebastian Grimberg } 99*0c73c039SSebastian Grimberg 1007a982d89SJeremy L. Thompson /// @} 1017a982d89SJeremy L. Thompson 1027a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1037a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 1047a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1057a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 1067a982d89SJeremy L. Thompson /// @{ 1077a982d89SJeremy L. Thompson 1087a982d89SJeremy L. Thompson /** 10978b2e752SJeremy L Thompson @brief Restrict an L-vector to an E-vector or apply its transpose ignoring any 11078b2e752SJeremy L Thompson provided orientations 11178b2e752SJeremy L Thompson 11278b2e752SJeremy L Thompson @param[in] rstr CeedElemRestriction 11378b2e752SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 11478b2e752SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 11578b2e752SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 11678b2e752SJeremy L Thompson Ordering of the e-vector is decided by the backend. 11778b2e752SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 11878b2e752SJeremy L Thompson 11978b2e752SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 12078b2e752SJeremy L Thompson 12178b2e752SJeremy L Thompson @ref User 12278b2e752SJeremy L Thompson **/ 12378b2e752SJeremy L Thompson int CeedElemRestrictionApplyUnsigned(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 12478b2e752SJeremy L Thompson CeedInt m, n; 12578b2e752SJeremy L Thompson 12678b2e752SJeremy L Thompson CeedCheck(rstr->ApplyUnsigned, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionApplyUnsigned"); 12778b2e752SJeremy L Thompson 12878b2e752SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 12978b2e752SJeremy L Thompson m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 13078b2e752SJeremy L Thompson n = rstr->l_size; 13178b2e752SJeremy L Thompson } else { 13278b2e752SJeremy L Thompson m = rstr->l_size; 13378b2e752SJeremy L Thompson n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 13478b2e752SJeremy L Thompson } 13578b2e752SJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 13678b2e752SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 13778b2e752SJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 13878b2e752SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 13978b2e752SJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyUnsigned(rstr, t_mode, u, ru, request)); 14077d1c127SSebastian Grimberg 14178b2e752SJeremy L Thompson return CEED_ERROR_SUCCESS; 14278b2e752SJeremy L Thompson } 14378b2e752SJeremy L Thompson 14478b2e752SJeremy L Thompson /** 145fcbe8c06SSebastian Grimberg @brief Get the type of a CeedElemRestriction 146a681ae63Sjeremylt 147fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 148fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 149fcbe8c06SSebastian Grimberg 150fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 151fcbe8c06SSebastian Grimberg 152fcbe8c06SSebastian Grimberg @ref Backend 153fcbe8c06SSebastian Grimberg **/ 154fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 155fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 156fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 157fcbe8c06SSebastian Grimberg } 158fcbe8c06SSebastian Grimberg 159fcbe8c06SSebastian Grimberg /** 160fcbe8c06SSebastian Grimberg @brief Get the strided status of a CeedElemRestriction 161fcbe8c06SSebastian Grimberg 162fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 163fcbe8c06SSebastian Grimberg @param[out] is_strided Variable to store strided status, 1 if strided else 0 164fcbe8c06SSebastian Grimberg **/ 165fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 166fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 167fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 168fcbe8c06SSebastian Grimberg } 169fcbe8c06SSebastian Grimberg 170fcbe8c06SSebastian Grimberg /** 171a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 1727a982d89SJeremy L. Thompson 173ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 174a681ae63Sjeremylt @param[out] strides Variable to store strides array 1757a982d89SJeremy L. Thompson 1767a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1777a982d89SJeremy L. Thompson 1787a982d89SJeremy L. Thompson @ref Backend 1797a982d89SJeremy L. Thompson **/ 1802b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1816574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1822b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 183e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1847a982d89SJeremy L. Thompson } 1857a982d89SJeremy L. Thompson 1867a982d89SJeremy L. Thompson /** 18777d1c127SSebastian Grimberg @brief Get the backend stride status of a CeedElemRestriction 18877d1c127SSebastian Grimberg 18977d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction 19077d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 19177d1c127SSebastian Grimberg 19277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 19377d1c127SSebastian Grimberg 19477d1c127SSebastian Grimberg @ref Backend 19577d1c127SSebastian Grimberg **/ 19677d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 19777d1c127SSebastian Grimberg CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 19877d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 19977d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 20077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 20177d1c127SSebastian Grimberg } 20277d1c127SSebastian Grimberg 20377d1c127SSebastian Grimberg /** 204bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 205bd33150aSjeremylt 206ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 207fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 208fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 209d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 210bd33150aSjeremylt 211bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 212bd33150aSjeremylt 213bd33150aSjeremylt @ref User 214bd33150aSjeremylt **/ 2152b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 216c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 217c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_signed, mem_type, offsets)); 218c17ec2beSJeremy L Thompson } else { 2196574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 2202b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 221d1d35e2fSjeremylt rstr->num_readers++; 222c17ec2beSJeremy L Thompson } 223e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 224430758c8SJeremy L Thompson } 225430758c8SJeremy L Thompson 226430758c8SJeremy L Thompson /** 227430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 228430758c8SJeremy L Thompson 229ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 230ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 231430758c8SJeremy L Thompson 232430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 233430758c8SJeremy L Thompson 234430758c8SJeremy L Thompson @ref User 235430758c8SJeremy L Thompson **/ 2362b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 237c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 238c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_signed, offsets)); 239c17ec2beSJeremy L Thompson } else { 240430758c8SJeremy L Thompson *offsets = NULL; 241d1d35e2fSjeremylt rstr->num_readers--; 242c17ec2beSJeremy L Thompson } 243e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 244bd33150aSjeremylt } 245bd33150aSjeremylt 246bd33150aSjeremylt /** 24777d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction orientations array by memtype 2483ac43b2cSJeremy L Thompson 24977d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve orientations 250fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 251fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 25277d1c127SSebastian Grimberg @param[out] orients Array on memory type mem_type 2533ac43b2cSJeremy L Thompson 2543ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2553ac43b2cSJeremy L Thompson 25677d1c127SSebastian Grimberg @ref User 2573ac43b2cSJeremy L Thompson **/ 25877d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 259fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOrientations"); 26077d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 26177d1c127SSebastian Grimberg rstr->num_readers++; 262e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2633ac43b2cSJeremy L Thompson } 2643ac43b2cSJeremy L Thompson 2653ac43b2cSJeremy L Thompson /** 26677d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetOrientations() 267b435c5a6Srezgarshakeri 26877d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 26977d1c127SSebastian Grimberg @param[in] orients Array of orientation data 270b435c5a6Srezgarshakeri 271b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 272b435c5a6Srezgarshakeri 27377d1c127SSebastian Grimberg @ref User 274b435c5a6Srezgarshakeri **/ 27577d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 27677d1c127SSebastian Grimberg *orients = NULL; 27777d1c127SSebastian Grimberg rstr->num_readers--; 278b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 279b435c5a6Srezgarshakeri } 280b435c5a6Srezgarshakeri 281b435c5a6Srezgarshakeri /** 28277d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction curl-conforming orientations array by memtype 2837a982d89SJeremy L. Thompson 28477d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve curl-conforming orientations 285fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 286fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 28777d1c127SSebastian Grimberg @param[out] curl_orients Array on memory type mem_type 2887a982d89SJeremy L. Thompson 2897a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2907a982d89SJeremy L. Thompson 29177d1c127SSebastian Grimberg @ref User 2927a982d89SJeremy L. Thompson **/ 293*0c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 294fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetCurlOrientations"); 29577d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 29677d1c127SSebastian Grimberg rstr->num_readers++; 29777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 29877d1c127SSebastian Grimberg } 29977d1c127SSebastian Grimberg 30077d1c127SSebastian Grimberg /** 30177d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetCurlOrientations() 30277d1c127SSebastian Grimberg 30377d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 30477d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 30577d1c127SSebastian Grimberg 30677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 30777d1c127SSebastian Grimberg 30877d1c127SSebastian Grimberg @ref User 30977d1c127SSebastian Grimberg **/ 310*0c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 31177d1c127SSebastian Grimberg *curl_orients = NULL; 31277d1c127SSebastian Grimberg rstr->num_readers--; 313e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3147a982d89SJeremy L. Thompson } 3157a982d89SJeremy L. Thompson 3167a982d89SJeremy L. Thompson /** 31749fd234cSJeremy L Thompson 31849fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 31949fd234cSJeremy L Thompson 320ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 321fcbe8c06SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 322fcbe8c06SSebastian Grimberg 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] 32349fd234cSJeremy L Thompson 32449fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 32549fd234cSJeremy L Thompson 32649fd234cSJeremy L Thompson @ref Backend 32749fd234cSJeremy L Thompson **/ 3282b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 3296574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 3302b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 331e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 33249fd234cSJeremy L Thompson } 33349fd234cSJeremy L Thompson 33449fd234cSJeremy L Thompson /** 33549fd234cSJeremy L Thompson 33649fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 33749fd234cSJeremy L Thompson 338ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 339ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 340ea61e9acSJeremy 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] 34149fd234cSJeremy L Thompson 34249fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 34349fd234cSJeremy L Thompson 34449fd234cSJeremy L Thompson @ref Backend 34549fd234cSJeremy L Thompson **/ 3462b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 3472b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 348e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 34949fd234cSJeremy L Thompson } 35049fd234cSJeremy L Thompson 35149fd234cSJeremy L Thompson /** 3527a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3537a982d89SJeremy L. Thompson 354ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3557a982d89SJeremy L. Thompson @param[out] data Variable to store data 3567a982d89SJeremy L. Thompson 3577a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3587a982d89SJeremy L. Thompson 3597a982d89SJeremy L. Thompson @ref Backend 3607a982d89SJeremy L. Thompson **/ 361777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 362777ff853SJeremy L Thompson *(void **)data = rstr->data; 363e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3647a982d89SJeremy L. Thompson } 3657a982d89SJeremy L. Thompson 3667a982d89SJeremy L. Thompson /** 3677a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3687a982d89SJeremy L. Thompson 369ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 370ea61e9acSJeremy L Thompson @param[in] data Data to set 3717a982d89SJeremy L. Thompson 3727a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3737a982d89SJeremy L. Thompson 3747a982d89SJeremy L. Thompson @ref Backend 3757a982d89SJeremy L. Thompson **/ 376777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 377777ff853SJeremy L Thompson rstr->data = data; 378e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3797a982d89SJeremy L. Thompson } 3807a982d89SJeremy L. Thompson 38134359f16Sjeremylt /** 38234359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 38334359f16Sjeremylt 384ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 38534359f16Sjeremylt 38634359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 38734359f16Sjeremylt 38834359f16Sjeremylt @ref Backend 38934359f16Sjeremylt **/ 3909560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 39134359f16Sjeremylt rstr->ref_count++; 39234359f16Sjeremylt return CEED_ERROR_SUCCESS; 39334359f16Sjeremylt } 39434359f16Sjeremylt 3956e15d496SJeremy L Thompson /** 3966e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 3976e15d496SJeremy L Thompson 398ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 399ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 400ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 4016e15d496SJeremy L Thompson 4026e15d496SJeremy L Thompson @ref Backend 4036e15d496SJeremy L Thompson **/ 4042b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 40577d1c127SSebastian Grimberg const bool *orients = NULL; 406*0c73c039SSebastian Grimberg const CeedInt8 *curl_orients = NULL; 4072b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 4086e15d496SJeremy L Thompson 40977d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetOrientations(rstr, CEED_MEM_HOST, &orients)); 41077d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetCurlOrientations(rstr, CEED_MEM_HOST, &curl_orients)); 41177d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 41277d1c127SSebastian Grimberg if (!orients && !curl_orients) { 41377d1c127SSebastian Grimberg scale = 1; 41477d1c127SSebastian Grimberg } else if (!curl_orients) { 41577d1c127SSebastian Grimberg scale = 2; 41677d1c127SSebastian Grimberg } else { 41777d1c127SSebastian Grimberg scale = 6; 4186e15d496SJeremy L Thompson } 41977d1c127SSebastian Grimberg } else { 42077d1c127SSebastian Grimberg if (!orients && !curl_orients) { 42177d1c127SSebastian Grimberg scale = 0; 42277d1c127SSebastian Grimberg } else if (!curl_orients) { 42377d1c127SSebastian Grimberg scale = 1; 42477d1c127SSebastian Grimberg } else { 42577d1c127SSebastian Grimberg scale = 5; 42677d1c127SSebastian Grimberg } 42777d1c127SSebastian Grimberg } 42877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOrientations(rstr, &orients)); 42977d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreCurlOrientations(rstr, &curl_orients)); 4306e15d496SJeremy L Thompson *flops = e_size * scale; 4316e15d496SJeremy L Thompson 4326e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 4336e15d496SJeremy L Thompson } 4346e15d496SJeremy L Thompson 4357a982d89SJeremy L. Thompson /// @} 4367a982d89SJeremy L. Thompson 43715910d16Sjeremylt /// @cond DOXYGEN_SKIP 43815910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 43915910d16Sjeremylt /// @endcond 44015910d16Sjeremylt 4417a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4427a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4437a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4447a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 445d7b241e6Sjeremylt /// @{ 446d7b241e6Sjeremylt 4477a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 44845f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4497a982d89SJeremy L. Thompson 4504cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 4512b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4527a982d89SJeremy L. Thompson 453d7b241e6Sjeremylt /** 454b11c1e72Sjeremylt @brief Create a CeedElemRestriction 455d7b241e6Sjeremylt 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) 460fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 461fcbe8c06SSebastian Grimberg 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. 462fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 463fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 464ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 465ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 466fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 467fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 468fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 469ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 470d7b241e6Sjeremylt 471b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 472dfdf5a53Sjeremylt 4737a982d89SJeremy L. Thompson @ref User 474b11c1e72Sjeremylt **/ 4752b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4762b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4775fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4785fe0d4faSjeremylt Ceed delegate; 4796574a04fSJeremy L Thompson 4802b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 48177d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4822b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 483e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4845fe0d4faSjeremylt } 4855fe0d4faSjeremylt 4866574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4876574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4886574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 489e022e1f8SJeremy L Thompson 4902b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 491db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 492d1d35e2fSjeremylt (*rstr)->ref_count = 1; 493d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 494d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 495d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 496d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 497d1d35e2fSjeremylt (*rstr)->l_size = l_size; 498d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 499d1d35e2fSjeremylt (*rstr)->blk_size = 1; 500fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_DEFAULT; 501fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 502e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 503d7b241e6Sjeremylt } 504d7b241e6Sjeremylt 505d7b241e6Sjeremylt /** 50677d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 507fc0567d9Srezgarshakeri 508ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 509ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 510ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 511ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 512fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 513fcbe8c06SSebastian Grimberg 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. 514fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 515fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 516ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 517ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 518fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 519fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 520fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 52177d1c127SSebastian 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. 522ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 523fc0567d9Srezgarshakeri 524fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 525fc0567d9Srezgarshakeri 526fc0567d9Srezgarshakeri @ref User 527fc0567d9Srezgarshakeri **/ 5282b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 52977d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 530fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 531fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 532fc0567d9Srezgarshakeri Ceed delegate; 5336574a04fSJeremy L Thompson 5342b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 535fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5362b730f8bSJeremy L Thompson CeedCall( 53777d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 538fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 539fc0567d9Srezgarshakeri } 540fc0567d9Srezgarshakeri 5416574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5426574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5436574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 544e022e1f8SJeremy L Thompson 5452b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 546db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 547fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 548fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 549fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 550fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 551fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 552fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 553fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 554fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 555fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 556fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 55777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 55877d1c127SSebastian Grimberg } 55977d1c127SSebastian Grimberg 56077d1c127SSebastian Grimberg /** 56177d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 56277d1c127SSebastian Grimberg 56377d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 56477d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 56577d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 56677d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 567fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 568fcbe8c06SSebastian Grimberg 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. 569fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 570fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 57177d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 57277d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 573fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 574fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 575fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 57677d1c127SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[0] = 57777d1c127SSebastian 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 57877d1c127SSebastian 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 57977d1c127SSebastian Grimberg to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 58077d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 58177d1c127SSebastian Grimberg 58277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 58377d1c127SSebastian Grimberg 58477d1c127SSebastian Grimberg @ref User 58577d1c127SSebastian Grimberg **/ 58677d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 587*0c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 58877d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 589fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 59077d1c127SSebastian Grimberg Ceed delegate; 59177d1c127SSebastian Grimberg 59277d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 593fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 59477d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 59577d1c127SSebastian Grimberg curl_orients, rstr)); 59677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 59777d1c127SSebastian Grimberg } 59877d1c127SSebastian Grimberg 59977d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 60077d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 60177d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 60277d1c127SSebastian Grimberg 60377d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 604fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 60577d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 60677d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 60777d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 60877d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 60977d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 61077d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 61177d1c127SSebastian Grimberg (*rstr)->num_blk = num_elem; 61277d1c127SSebastian Grimberg (*rstr)->blk_size = 1; 613fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 614fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 615fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 616fc0567d9Srezgarshakeri } 617fc0567d9Srezgarshakeri 618fc0567d9Srezgarshakeri /** 6197509a596Sjeremylt @brief Create a strided CeedElemRestriction 620d7b241e6Sjeremylt 621ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 622ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 623ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 624ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 625fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 626fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 627fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 628fcbe8c06SSebastian Grimberg 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]. 629fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 630ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 631d7b241e6Sjeremylt 632b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 633dfdf5a53Sjeremylt 6347a982d89SJeremy L. Thompson @ref User 635b11c1e72Sjeremylt **/ 6362b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 637f90c8643Sjeremylt CeedElemRestriction *rstr) { 6385fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6395fe0d4faSjeremylt Ceed delegate; 640b04eb3d9SSebastian Grimberg 6412b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 642fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6432b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 644e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6455fe0d4faSjeremylt } 6465fe0d4faSjeremylt 6476574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6486574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 649e022e1f8SJeremy L Thompson 6502b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 651db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 652d1d35e2fSjeremylt (*rstr)->ref_count = 1; 653d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 654d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 655d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 656d1d35e2fSjeremylt (*rstr)->l_size = l_size; 657d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 658d1d35e2fSjeremylt (*rstr)->blk_size = 1; 659fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6602b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6612b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 662fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 663e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 664d7b241e6Sjeremylt } 665d7b241e6Sjeremylt 666d7b241e6Sjeremylt /** 667b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 668d7b241e6Sjeremylt 669ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 670ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 671ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 672ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 673ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 674fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 675fcbe8c06SSebastian Grimberg 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. 676fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 677fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 678ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 679ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 680fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 681fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 682fcbe8c06SSebastian Grimberg 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 683fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 684ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 685d7b241e6Sjeremylt 686b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 687dfdf5a53Sjeremylt 6887a982d89SJeremy L. Thompson @ref Backend 689b11c1e72Sjeremylt **/ 6902b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 6912b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 6924ce2993fSjeremylt CeedElemRestriction *rstr) { 693d1d35e2fSjeremylt CeedInt *blk_offsets; 694d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 695d7b241e6Sjeremylt 6965fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6975fe0d4faSjeremylt Ceed delegate; 6986574a04fSJeremy L Thompson 6992b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 7006402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 7012b730f8bSJeremy L Thompson CeedCall( 7022b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 703e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7045fe0d4faSjeremylt } 705d7b241e6Sjeremylt 7066574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 7076574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 7086574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 7096574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 710e022e1f8SJeremy L Thompson 7112b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 7122b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 713d7b241e6Sjeremylt 714db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 715db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 716d1d35e2fSjeremylt (*rstr)->ref_count = 1; 717d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 718d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 719d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 720d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 721d1d35e2fSjeremylt (*rstr)->l_size = l_size; 722d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 723d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 724fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_DEFAULT; 725fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, NULL, *rstr)); 726d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 7272b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 7281d102b48SJeremy L Thompson } 729e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 730d7b241e6Sjeremylt } 731d7b241e6Sjeremylt 732b11c1e72Sjeremylt /** 73377d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 73477d1c127SSebastian Grimberg 73577d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 73677d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 73777d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 73877d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 73977d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 740fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 741fcbe8c06SSebastian Grimberg 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. 742fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 743fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 74477d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 74577d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 746fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 747fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 748fcbe8c06SSebastian Grimberg 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 749fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 750fcbe8c06SSebastian 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. 751fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 75277d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 75377d1c127SSebastian Grimberg 75477d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 75577d1c127SSebastian Grimberg 75677d1c127SSebastian Grimberg @ref Backend 75777d1c127SSebastian Grimberg **/ 75877d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 75977d1c127SSebastian Grimberg CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 76077d1c127SSebastian Grimberg const bool *orients, CeedElemRestriction *rstr) { 76177d1c127SSebastian Grimberg CeedInt *blk_offsets; 76277d1c127SSebastian Grimberg bool *blk_orients; 76377d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 76477d1c127SSebastian Grimberg 765fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 76677d1c127SSebastian Grimberg Ceed delegate; 76777d1c127SSebastian Grimberg 76877d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 769fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 77077d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 77177d1c127SSebastian Grimberg offsets, orients, rstr)); 77277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 77377d1c127SSebastian Grimberg } 77477d1c127SSebastian Grimberg 77577d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 77677d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 77777d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 77877d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 77977d1c127SSebastian Grimberg 78077d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 78177d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_orients)); 78277d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 783*0c73c039SSebastian Grimberg CeedCall(CeedPermutePadOrients(orients, blk_orients, num_blk, num_elem, blk_size, elem_size)); 78477d1c127SSebastian Grimberg 785fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 786fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 78777d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 78877d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 78977d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 79077d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 79177d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 79277d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 79377d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 79477d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 795fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 796fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, (const bool *)blk_orients, NULL, *rstr)); 79777d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 79877d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 79977d1c127SSebastian Grimberg } 80077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 80177d1c127SSebastian Grimberg } 80277d1c127SSebastian Grimberg 80377d1c127SSebastian Grimberg /** 80477d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 80577d1c127SSebastian Grimberg 80677d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 80777d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 80877d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 80977d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 81077d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 811fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 812fcbe8c06SSebastian Grimberg 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. 813fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 814fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 81577d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 81677d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 817fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 818fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 819fcbe8c06SSebastian Grimberg where 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 820fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 82177d1c127SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[0] = 822fcbe8c06SSebastian 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. 823fcbe8c06SSebastian Grimberg This orientation matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the 824fcbe8c06SSebastian Grimberg element restriction operation, which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). Will also 825fcbe8c06SSebastian Grimberg be permuted and padded similarly to @a offsets. 82677d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 82777d1c127SSebastian Grimberg 82877d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 82977d1c127SSebastian Grimberg 83077d1c127SSebastian Grimberg @ref Backend 83177d1c127SSebastian Grimberg **/ 83277d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, 83377d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 834*0c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 83577d1c127SSebastian Grimberg CeedInt *blk_offsets; 836*0c73c039SSebastian Grimberg CeedInt8 *blk_curl_orients; 83777d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 83877d1c127SSebastian Grimberg 839fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 84077d1c127SSebastian Grimberg Ceed delegate; 84177d1c127SSebastian Grimberg 84277d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 843fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 84477d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 84577d1c127SSebastian Grimberg offsets, curl_orients, rstr)); 84677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 84777d1c127SSebastian Grimberg } 84877d1c127SSebastian Grimberg 84977d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 85077d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 85177d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 85277d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 85377d1c127SSebastian Grimberg 85477d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 85577d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * 3 * elem_size, &blk_curl_orients)); 85677d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 857*0c73c039SSebastian Grimberg CeedCall(CeedPermutePadCurlOrients(curl_orients, blk_curl_orients, num_blk, num_elem, blk_size, 3 * elem_size)); 85877d1c127SSebastian Grimberg 859fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 860fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 86177d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 86277d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 86377d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 86477d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 86577d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 86677d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 86777d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 86877d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 869fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 870*0c73c039SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, (const CeedInt8 *)blk_curl_orients, 871fcbe8c06SSebastian Grimberg *rstr)); 87277d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 87377d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 87477d1c127SSebastian Grimberg } 87577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 87677d1c127SSebastian Grimberg } 87777d1c127SSebastian Grimberg 87877d1c127SSebastian Grimberg /** 87977d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 8807509a596Sjeremylt 881ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 882ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 883ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 884ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 885ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 886fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 887fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 888fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 889fcbe8c06SSebastian Grimberg 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]. 890fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 891ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 8927509a596Sjeremylt 8937509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 8947509a596Sjeremylt 8957a982d89SJeremy L. Thompson @ref User 8967509a596Sjeremylt **/ 8972b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 8988621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 899d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 9007509a596Sjeremylt 9017509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 9027509a596Sjeremylt Ceed delegate; 9036574a04fSJeremy L Thompson 9042b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 905fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 9062b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 907e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9087509a596Sjeremylt } 9097509a596Sjeremylt 9106574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 9116574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 9126574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 913e022e1f8SJeremy L Thompson 9142b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 915db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 916d1d35e2fSjeremylt (*rstr)->ref_count = 1; 917d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 918d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 919d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 920d1d35e2fSjeremylt (*rstr)->l_size = l_size; 921d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 922d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 923fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 9242b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 9252b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 926fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 927e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9287509a596Sjeremylt } 9297509a596Sjeremylt 9307509a596Sjeremylt /** 931c17ec2beSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to `CeedElemRestrictionApplyUnsigned()`. 932c17ec2beSJeremy L Thompson 933c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 934c17ec2beSJeremy L Thompson 935c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 936c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 937c17ec2beSJeremy L Thompson 938c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 939c17ec2beSJeremy L Thompson 940c17ec2beSJeremy L Thompson @ref User 941c17ec2beSJeremy L Thompson **/ 942c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 943c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 944c17ec2beSJeremy L Thompson 945c17ec2beSJeremy L Thompson // Copy old rstr 946c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 947c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 948c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 949c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 950c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 951c17ec2beSJeremy L Thompson if (rstr->strides) { 952c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 953c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 954c17ec2beSJeremy L Thompson } 955c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_signed)); 956c17ec2beSJeremy L Thompson 957c17ec2beSJeremy L Thompson // Override Apply 958c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 959c17ec2beSJeremy L Thompson 960c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 961c17ec2beSJeremy L Thompson } 962c17ec2beSJeremy L Thompson 963c17ec2beSJeremy L Thompson /** 964ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 9659fd66db6SSebastian Grimberg 966ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 9679560d06aSjeremylt 9689fd66db6SSebastian 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. 9699fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 970ea61e9acSJeremy L Thompson 971ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 972ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 9739560d06aSjeremylt 9749560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 9759560d06aSjeremylt 9769560d06aSjeremylt @ref User 9779560d06aSjeremylt **/ 9782b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 979393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 9802b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 9819560d06aSjeremylt *rstr_copy = rstr; 9829560d06aSjeremylt return CEED_ERROR_SUCCESS; 9839560d06aSjeremylt } 9849560d06aSjeremylt 9859560d06aSjeremylt /** 986b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 987b11c1e72Sjeremylt 988ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 989ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 990ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 991b11c1e72Sjeremylt 992b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 993dfdf5a53Sjeremylt 9947a982d89SJeremy L. Thompson @ref User 995b11c1e72Sjeremylt **/ 9962b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 997d2643443SJeremy L Thompson CeedSize e_size, l_size; 998d1d35e2fSjeremylt l_size = rstr->l_size; 999d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 10002b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 10012b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 1002e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1003d7b241e6Sjeremylt } 1004d7b241e6Sjeremylt 1005d7b241e6Sjeremylt /** 1006d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1007d7b241e6Sjeremylt 1008ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1009ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1010ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1011fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1012fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1013ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1014b11c1e72Sjeremylt 1015b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1016dfdf5a53Sjeremylt 10177a982d89SJeremy L. Thompson @ref User 1018b11c1e72Sjeremylt **/ 10192b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1020d7b241e6Sjeremylt CeedInt m, n; 1021d7b241e6Sjeremylt 1022d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1023d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1024d1d35e2fSjeremylt n = rstr->l_size; 1025d7b241e6Sjeremylt } else { 1026d1d35e2fSjeremylt m = rstr->l_size; 1027d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1028d7b241e6Sjeremylt } 10296574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10306574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10316574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10326574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10332b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1034e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1035d7b241e6Sjeremylt } 1036d7b241e6Sjeremylt 1037d7b241e6Sjeremylt /** 1038d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1039be9261b7Sjeremylt 1040ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1041ea61e9acSJeremy 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 1042ea61e9acSJeremy L Thompson : 4*blk_size] 1043ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1044ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1045fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1046fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1047ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1048be9261b7Sjeremylt 1049be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1050be9261b7Sjeremylt 10517a982d89SJeremy L. Thompson @ref Backend 1052be9261b7Sjeremylt **/ 10532b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 10542b730f8bSJeremy L Thompson CeedRequest *request) { 1055be9261b7Sjeremylt CeedInt m, n; 1056be9261b7Sjeremylt 10576402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 10586402da51SJeremy L Thompson 1059d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1060d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1061d1d35e2fSjeremylt n = rstr->l_size; 1062be9261b7Sjeremylt } else { 1063d1d35e2fSjeremylt m = rstr->l_size; 1064d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1065be9261b7Sjeremylt } 10666574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10676574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10686574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10696574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10706574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 10716574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 10726574a04fSJeremy L Thompson rstr->num_elem); 10732b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1074e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1075be9261b7Sjeremylt } 1076be9261b7Sjeremylt 1077be9261b7Sjeremylt /** 1078b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1079b7c9bbdaSJeremy L Thompson 1080ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1081b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1082b7c9bbdaSJeremy L Thompson 1083b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1084b7c9bbdaSJeremy L Thompson 1085b7c9bbdaSJeremy L Thompson @ref Advanced 1086b7c9bbdaSJeremy L Thompson **/ 1087b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1088b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1089b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1090b7c9bbdaSJeremy L Thompson } 1091b7c9bbdaSJeremy L Thompson 1092b7c9bbdaSJeremy L Thompson /** 1093d979a051Sjeremylt @brief Get the L-vector component stride 1094a681ae63Sjeremylt 1095ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1096d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1097a681ae63Sjeremylt 1098a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1099a681ae63Sjeremylt 1100b7c9bbdaSJeremy L Thompson @ref Advanced 1101a681ae63Sjeremylt **/ 11022b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1103d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1104e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1105a681ae63Sjeremylt } 1106a681ae63Sjeremylt 1107a681ae63Sjeremylt /** 1108a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1109a681ae63Sjeremylt 1110ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1111d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1112a681ae63Sjeremylt 1113a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1114a681ae63Sjeremylt 1115b7c9bbdaSJeremy L Thompson @ref Advanced 1116a681ae63Sjeremylt **/ 11172b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1118d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1119e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1120a681ae63Sjeremylt } 1121a681ae63Sjeremylt 1122a681ae63Sjeremylt /** 1123a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1124a681ae63Sjeremylt 1125ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1126d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1127a681ae63Sjeremylt 1128a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1129a681ae63Sjeremylt 1130b7c9bbdaSJeremy L Thompson @ref Advanced 1131a681ae63Sjeremylt **/ 11322b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1133d1d35e2fSjeremylt *elem_size = rstr->elem_size; 1134e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1135a681ae63Sjeremylt } 1136a681ae63Sjeremylt 1137a681ae63Sjeremylt /** 1138d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1139a681ae63Sjeremylt 1140ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1141d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1142a681ae63Sjeremylt 1143a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1144a681ae63Sjeremylt 1145b7c9bbdaSJeremy L Thompson @ref Advanced 1146a681ae63Sjeremylt **/ 11472b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1148d1d35e2fSjeremylt *l_size = rstr->l_size; 1149e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1150a681ae63Sjeremylt } 1151a681ae63Sjeremylt 1152a681ae63Sjeremylt /** 1153ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1154a681ae63Sjeremylt 1155ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1156d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1157a681ae63Sjeremylt 1158a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1159a681ae63Sjeremylt 1160b7c9bbdaSJeremy L Thompson @ref Advanced 1161a681ae63Sjeremylt **/ 11622b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1163d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1164e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1165a681ae63Sjeremylt } 1166a681ae63Sjeremylt 1167a681ae63Sjeremylt /** 1168a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1169a681ae63Sjeremylt 1170ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1171d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1172a681ae63Sjeremylt 1173a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1174a681ae63Sjeremylt 1175b7c9bbdaSJeremy L Thompson @ref Advanced 1176a681ae63Sjeremylt **/ 11772b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1178d1d35e2fSjeremylt *num_block = rstr->num_blk; 1179e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1180a681ae63Sjeremylt } 1181a681ae63Sjeremylt 1182a681ae63Sjeremylt /** 1183a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1184a681ae63Sjeremylt 1185ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1186d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 1187a681ae63Sjeremylt 1188a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1189a681ae63Sjeremylt 1190b7c9bbdaSJeremy L Thompson @ref Advanced 1191a681ae63Sjeremylt **/ 11922b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 1193d1d35e2fSjeremylt *blk_size = rstr->blk_size; 1194e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1195a681ae63Sjeremylt } 1196a681ae63Sjeremylt 1197a681ae63Sjeremylt /** 1198d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 11991469ee4dSjeremylt 1200ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1201d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 12021469ee4dSjeremylt 12031469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 12041469ee4dSjeremylt 12057a982d89SJeremy L. Thompson @ref User 12061469ee4dSjeremylt **/ 12072b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1208d1d35e2fSjeremylt CeedVector e_vec; 12091469ee4dSjeremylt 121025509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 12112b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 12121469ee4dSjeremylt 121325509ebbSRezgar Shakeri // Compute e_vec = E * 1 12142b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 12152b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 121625509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 12172b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 12182b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 12191469ee4dSjeremylt // Cleanup 12202b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1221e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12221469ee4dSjeremylt } 12231469ee4dSjeremylt 12241469ee4dSjeremylt /** 1225f02ca4a2SJed Brown @brief View a CeedElemRestriction 1226f02ca4a2SJed Brown 1227f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1228f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1229f02ca4a2SJed Brown 1230f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1231f02ca4a2SJed Brown 12327a982d89SJeremy L. Thompson @ref User 1233f02ca4a2SJed Brown **/ 1234f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 12357509a596Sjeremylt char stridesstr[500]; 12362b730f8bSJeremy L Thompson if (rstr->strides) { 12372b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 12382b730f8bSJeremy L Thompson } else { 1239990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 12402b730f8bSJeremy L Thompson } 12417509a596Sjeremylt 12422b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 12432b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1244d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1245e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1246f02ca4a2SJed Brown } 1247f02ca4a2SJed Brown 1248f02ca4a2SJed Brown /** 1249b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1250b11c1e72Sjeremylt 1251ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1252b11c1e72Sjeremylt 1253b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1254dfdf5a53Sjeremylt 12557a982d89SJeremy L. Thompson @ref User 1256b11c1e72Sjeremylt **/ 12574ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1258393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1259ad6481ceSJeremy L Thompson *rstr = NULL; 1260ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1261ad6481ceSJeremy L Thompson } 12626574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 12636574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1264c17ec2beSJeremy L Thompson 1265c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 1266c17ec2beSJeremy L Thompson if ((*rstr)->rstr_signed) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_signed)); 1267c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1268c17ec2beSJeremy L Thompson 12692b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 12702b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 12712b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1272e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1273d7b241e6Sjeremylt } 1274d7b241e6Sjeremylt 1275d7b241e6Sjeremylt /// @} 1276