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*fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 28*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 29*fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 30ea61e9acSJeremy L Thompson @param[out] blk_offsets Array of permuted and padded offsets of shape [@a num_blk, @a elem_size, @a blk_size]. 31ea61e9acSJeremy L Thompson @param[in] num_blk Number of blocks 32ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 33ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 34ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 357a982d89SJeremy L. Thompson 367a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 377a982d89SJeremy L. Thompson 387a982d89SJeremy L. Thompson @ref Utility 397a982d89SJeremy L. Thompson **/ 402b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 412b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 422b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 432b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 442b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 472b730f8bSJeremy L Thompson } 48e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 497a982d89SJeremy L. Thompson } 507a982d89SJeremy L. Thompson 5177d1c127SSebastian Grimberg /** 5277d1c127SSebastian Grimberg @brief Permute and pad orientations for a blocked restriction 5377d1c127SSebastian Grimberg 54*fcbe8c06SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size]. 55*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the orientations (into the input CeedVector) for 5677d1c127SSebastian Grimberg the unknowns corresponding to element i, where 0 <= i < @a num_elem. 5777d1c127SSebastian Grimberg @param[out] blk_orients Array of permuted and padded orientations of shape [@a num_blk, @a elem_size, @a blk_size]. 5877d1c127SSebastian Grimberg @param[in] num_blk Number of blocks 5977d1c127SSebastian Grimberg @param[in] num_elem Number of elements 6077d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 6177d1c127SSebastian Grimberg @param[in] elem_size Size of each element 6277d1c127SSebastian Grimberg 6377d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 6477d1c127SSebastian Grimberg 6577d1c127SSebastian Grimberg @ref Utility 6677d1c127SSebastian Grimberg **/ 6777d1c127SSebastian Grimberg int CeedPermutePadOrientations(const bool *orients, bool *blk_orients, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 6877d1c127SSebastian Grimberg for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 6977d1c127SSebastian Grimberg for (CeedInt j = 0; j < blk_size; j++) { 7077d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 7177d1c127SSebastian Grimberg blk_orients[e * elem_size + k * blk_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 7277d1c127SSebastian Grimberg } 7377d1c127SSebastian Grimberg } 7477d1c127SSebastian Grimberg } 7577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 7677d1c127SSebastian Grimberg } 7777d1c127SSebastian Grimberg 787a982d89SJeremy L. Thompson /// @} 797a982d89SJeremy L. Thompson 807a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 817a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 827a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 837a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 847a982d89SJeremy L. Thompson /// @{ 857a982d89SJeremy L. Thompson 867a982d89SJeremy L. Thompson /** 8778b2e752SJeremy L Thompson @brief Restrict an L-vector to an E-vector or apply its transpose ignoring any 8878b2e752SJeremy L Thompson provided orientations 8978b2e752SJeremy L Thompson 9078b2e752SJeremy L Thompson @param[in] rstr CeedElemRestriction 9178b2e752SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 9278b2e752SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 9378b2e752SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 9478b2e752SJeremy L Thompson Ordering of the e-vector is decided by the backend. 9578b2e752SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 9678b2e752SJeremy L Thompson 9778b2e752SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9878b2e752SJeremy L Thompson 9978b2e752SJeremy L Thompson @ref User 10078b2e752SJeremy L Thompson **/ 10178b2e752SJeremy L Thompson int CeedElemRestrictionApplyUnsigned(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 10278b2e752SJeremy L Thompson CeedInt m, n; 10378b2e752SJeremy L Thompson 10478b2e752SJeremy L Thompson CeedCheck(rstr->ApplyUnsigned, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionApplyUnsigned"); 10578b2e752SJeremy L Thompson 10678b2e752SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 10778b2e752SJeremy L Thompson m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 10878b2e752SJeremy L Thompson n = rstr->l_size; 10978b2e752SJeremy L Thompson } else { 11078b2e752SJeremy L Thompson m = rstr->l_size; 11178b2e752SJeremy L Thompson n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 11278b2e752SJeremy L Thompson } 11378b2e752SJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11478b2e752SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 11578b2e752SJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11678b2e752SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 11778b2e752SJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyUnsigned(rstr, t_mode, u, ru, request)); 11877d1c127SSebastian Grimberg 11978b2e752SJeremy L Thompson return CEED_ERROR_SUCCESS; 12078b2e752SJeremy L Thompson } 12178b2e752SJeremy L Thompson 12278b2e752SJeremy L Thompson /** 123*fcbe8c06SSebastian Grimberg @brief Get the type of a CeedElemRestriction 124a681ae63Sjeremylt 125*fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 126*fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 127*fcbe8c06SSebastian Grimberg 128*fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 129*fcbe8c06SSebastian Grimberg 130*fcbe8c06SSebastian Grimberg @ref Backend 131*fcbe8c06SSebastian Grimberg **/ 132*fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 133*fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 134*fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 135*fcbe8c06SSebastian Grimberg } 136*fcbe8c06SSebastian Grimberg 137*fcbe8c06SSebastian Grimberg /** 138*fcbe8c06SSebastian Grimberg @brief Get the strided status of a CeedElemRestriction 139*fcbe8c06SSebastian Grimberg 140*fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 141*fcbe8c06SSebastian Grimberg @param[out] is_strided Variable to store strided status, 1 if strided else 0 142*fcbe8c06SSebastian Grimberg **/ 143*fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 144*fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 145*fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 146*fcbe8c06SSebastian Grimberg } 147*fcbe8c06SSebastian Grimberg 148*fcbe8c06SSebastian Grimberg /** 149a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 1507a982d89SJeremy L. Thompson 151ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 152a681ae63Sjeremylt @param[out] strides Variable to store strides array 1537a982d89SJeremy L. Thompson 1547a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1557a982d89SJeremy L. Thompson 1567a982d89SJeremy L. Thompson @ref Backend 1577a982d89SJeremy L. Thompson **/ 1582b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1596574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1602b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 161e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1627a982d89SJeremy L. Thompson } 1637a982d89SJeremy L. Thompson 1647a982d89SJeremy L. Thompson /** 16577d1c127SSebastian Grimberg @brief Get the backend stride status of a CeedElemRestriction 16677d1c127SSebastian Grimberg 16777d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction 16877d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 16977d1c127SSebastian Grimberg 17077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 17177d1c127SSebastian Grimberg 17277d1c127SSebastian Grimberg @ref Backend 17377d1c127SSebastian Grimberg **/ 17477d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 17577d1c127SSebastian Grimberg CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 17677d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 17777d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 17877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 17977d1c127SSebastian Grimberg } 18077d1c127SSebastian Grimberg 18177d1c127SSebastian Grimberg /** 182bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 183bd33150aSjeremylt 184ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 185*fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 186*fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 187d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 188bd33150aSjeremylt 189bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 190bd33150aSjeremylt 191bd33150aSjeremylt @ref User 192bd33150aSjeremylt **/ 1932b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 194c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 195c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_signed, mem_type, offsets)); 196c17ec2beSJeremy L Thompson } else { 1976574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 1982b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 199d1d35e2fSjeremylt rstr->num_readers++; 200c17ec2beSJeremy L Thompson } 201e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 202430758c8SJeremy L Thompson } 203430758c8SJeremy L Thompson 204430758c8SJeremy L Thompson /** 205430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 206430758c8SJeremy L Thompson 207ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 208ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 209430758c8SJeremy L Thompson 210430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 211430758c8SJeremy L Thompson 212430758c8SJeremy L Thompson @ref User 213430758c8SJeremy L Thompson **/ 2142b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 215c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 216c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_signed, offsets)); 217c17ec2beSJeremy L Thompson } else { 218430758c8SJeremy L Thompson *offsets = NULL; 219d1d35e2fSjeremylt rstr->num_readers--; 220c17ec2beSJeremy L Thompson } 221e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 222bd33150aSjeremylt } 223bd33150aSjeremylt 224bd33150aSjeremylt /** 22577d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction orientations array by memtype 2263ac43b2cSJeremy L Thompson 22777d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve orientations 228*fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 229*fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 23077d1c127SSebastian Grimberg @param[out] orients Array on memory type mem_type 2313ac43b2cSJeremy L Thompson 2323ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2333ac43b2cSJeremy L Thompson 23477d1c127SSebastian Grimberg @ref User 2353ac43b2cSJeremy L Thompson **/ 23677d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 237*fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOrientations"); 23877d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 23977d1c127SSebastian Grimberg rstr->num_readers++; 240e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2413ac43b2cSJeremy L Thompson } 2423ac43b2cSJeremy L Thompson 2433ac43b2cSJeremy L Thompson /** 24477d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetOrientations() 245b435c5a6Srezgarshakeri 24677d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 24777d1c127SSebastian Grimberg @param[in] orients Array of orientation data 248b435c5a6Srezgarshakeri 249b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 250b435c5a6Srezgarshakeri 25177d1c127SSebastian Grimberg @ref User 252b435c5a6Srezgarshakeri **/ 25377d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 25477d1c127SSebastian Grimberg *orients = NULL; 25577d1c127SSebastian Grimberg rstr->num_readers--; 256b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 257b435c5a6Srezgarshakeri } 258b435c5a6Srezgarshakeri 259b435c5a6Srezgarshakeri /** 26077d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction curl-conforming orientations array by memtype 2617a982d89SJeremy L. Thompson 26277d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve curl-conforming orientations 263*fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 264*fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 26577d1c127SSebastian Grimberg @param[out] curl_orients Array on memory type mem_type 2667a982d89SJeremy L. Thompson 2677a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2687a982d89SJeremy L. Thompson 26977d1c127SSebastian Grimberg @ref User 2707a982d89SJeremy L. Thompson **/ 27177d1c127SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **curl_orients) { 272*fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetCurlOrientations"); 27377d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 27477d1c127SSebastian Grimberg rstr->num_readers++; 27577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 27677d1c127SSebastian Grimberg } 27777d1c127SSebastian Grimberg 27877d1c127SSebastian Grimberg /** 27977d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetCurlOrientations() 28077d1c127SSebastian Grimberg 28177d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 28277d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 28377d1c127SSebastian Grimberg 28477d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 28577d1c127SSebastian Grimberg 28677d1c127SSebastian Grimberg @ref User 28777d1c127SSebastian Grimberg **/ 28877d1c127SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt **curl_orients) { 28977d1c127SSebastian Grimberg *curl_orients = NULL; 29077d1c127SSebastian Grimberg rstr->num_readers--; 291e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2927a982d89SJeremy L. Thompson } 2937a982d89SJeremy L. Thompson 2947a982d89SJeremy L. Thompson /** 29549fd234cSJeremy L Thompson 29649fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 29749fd234cSJeremy L Thompson 298ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 299*fcbe8c06SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 300*fcbe8c06SSebastian 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] 30149fd234cSJeremy L Thompson 30249fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 30349fd234cSJeremy L Thompson 30449fd234cSJeremy L Thompson @ref Backend 30549fd234cSJeremy L Thompson **/ 3062b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 3076574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 3082b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 309e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 31049fd234cSJeremy L Thompson } 31149fd234cSJeremy L Thompson 31249fd234cSJeremy L Thompson /** 31349fd234cSJeremy L Thompson 31449fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 31549fd234cSJeremy L Thompson 316ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 317ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 318ea61e9acSJeremy 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] 31949fd234cSJeremy L Thompson 32049fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 32149fd234cSJeremy L Thompson 32249fd234cSJeremy L Thompson @ref Backend 32349fd234cSJeremy L Thompson **/ 3242b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 3252b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 326e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 32749fd234cSJeremy L Thompson } 32849fd234cSJeremy L Thompson 32949fd234cSJeremy L Thompson /** 3307a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3317a982d89SJeremy L. Thompson 332ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3337a982d89SJeremy L. Thompson @param[out] data Variable to store data 3347a982d89SJeremy L. Thompson 3357a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3367a982d89SJeremy L. Thompson 3377a982d89SJeremy L. Thompson @ref Backend 3387a982d89SJeremy L. Thompson **/ 339777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 340777ff853SJeremy L Thompson *(void **)data = rstr->data; 341e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3427a982d89SJeremy L. Thompson } 3437a982d89SJeremy L. Thompson 3447a982d89SJeremy L. Thompson /** 3457a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3467a982d89SJeremy L. Thompson 347ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 348ea61e9acSJeremy L Thompson @param[in] data Data to set 3497a982d89SJeremy L. Thompson 3507a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3517a982d89SJeremy L. Thompson 3527a982d89SJeremy L. Thompson @ref Backend 3537a982d89SJeremy L. Thompson **/ 354777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 355777ff853SJeremy L Thompson rstr->data = data; 356e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3577a982d89SJeremy L. Thompson } 3587a982d89SJeremy L. Thompson 35934359f16Sjeremylt /** 36034359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 36134359f16Sjeremylt 362ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 36334359f16Sjeremylt 36434359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 36534359f16Sjeremylt 36634359f16Sjeremylt @ref Backend 36734359f16Sjeremylt **/ 3689560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 36934359f16Sjeremylt rstr->ref_count++; 37034359f16Sjeremylt return CEED_ERROR_SUCCESS; 37134359f16Sjeremylt } 37234359f16Sjeremylt 3736e15d496SJeremy L Thompson /** 3746e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 3756e15d496SJeremy L Thompson 376ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 377ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 378ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 3796e15d496SJeremy L Thompson 3806e15d496SJeremy L Thompson @ref Backend 3816e15d496SJeremy L Thompson **/ 3822b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 38377d1c127SSebastian Grimberg const bool *orients = NULL; 38477d1c127SSebastian Grimberg const CeedInt *curl_orients = NULL; 3852b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 3866e15d496SJeremy L Thompson 38777d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetOrientations(rstr, CEED_MEM_HOST, &orients)); 38877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetCurlOrientations(rstr, CEED_MEM_HOST, &curl_orients)); 38977d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 39077d1c127SSebastian Grimberg if (!orients && !curl_orients) { 39177d1c127SSebastian Grimberg scale = 1; 39277d1c127SSebastian Grimberg } else if (!curl_orients) { 39377d1c127SSebastian Grimberg scale = 2; 39477d1c127SSebastian Grimberg } else { 39577d1c127SSebastian Grimberg scale = 6; 3966e15d496SJeremy L Thompson } 39777d1c127SSebastian Grimberg } else { 39877d1c127SSebastian Grimberg if (!orients && !curl_orients) { 39977d1c127SSebastian Grimberg scale = 0; 40077d1c127SSebastian Grimberg } else if (!curl_orients) { 40177d1c127SSebastian Grimberg scale = 1; 40277d1c127SSebastian Grimberg } else { 40377d1c127SSebastian Grimberg scale = 5; 40477d1c127SSebastian Grimberg } 40577d1c127SSebastian Grimberg } 40677d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOrientations(rstr, &orients)); 40777d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreCurlOrientations(rstr, &curl_orients)); 4086e15d496SJeremy L Thompson *flops = e_size * scale; 4096e15d496SJeremy L Thompson 4106e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 4116e15d496SJeremy L Thompson } 4126e15d496SJeremy L Thompson 4137a982d89SJeremy L. Thompson /// @} 4147a982d89SJeremy L. Thompson 41515910d16Sjeremylt /// @cond DOXYGEN_SKIP 41615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 41715910d16Sjeremylt /// @endcond 41815910d16Sjeremylt 4197a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4207a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4217a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4227a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 423d7b241e6Sjeremylt /// @{ 424d7b241e6Sjeremylt 4257a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 42645f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4277a982d89SJeremy L. Thompson 4284cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 4292b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4307a982d89SJeremy L. Thompson 431d7b241e6Sjeremylt /** 432b11c1e72Sjeremylt @brief Create a CeedElemRestriction 433d7b241e6Sjeremylt 434ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 435ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 436ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 437ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 438*fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 439*fcbe8c06SSebastian 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. 440*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 441*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 442ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 443ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 444*fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 445*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 446*fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 447ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 448d7b241e6Sjeremylt 449b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 450dfdf5a53Sjeremylt 4517a982d89SJeremy L. Thompson @ref User 452b11c1e72Sjeremylt **/ 4532b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4542b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4555fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4565fe0d4faSjeremylt Ceed delegate; 4576574a04fSJeremy L Thompson 4582b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 45977d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4602b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 461e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4625fe0d4faSjeremylt } 4635fe0d4faSjeremylt 4646574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4656574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4666574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 467e022e1f8SJeremy L Thompson 4682b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 469db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 470d1d35e2fSjeremylt (*rstr)->ref_count = 1; 471d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 472d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 473d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 474d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 475d1d35e2fSjeremylt (*rstr)->l_size = l_size; 476d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 477d1d35e2fSjeremylt (*rstr)->blk_size = 1; 478*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_DEFAULT; 479*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 480e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 481d7b241e6Sjeremylt } 482d7b241e6Sjeremylt 483d7b241e6Sjeremylt /** 48477d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 485fc0567d9Srezgarshakeri 486ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 487ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 488ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 489ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 490*fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 491*fcbe8c06SSebastian 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. 492*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 493*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 494ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 495ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 496*fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 497*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 498*fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 49977d1c127SSebastian 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. 500ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 501fc0567d9Srezgarshakeri 502fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 503fc0567d9Srezgarshakeri 504fc0567d9Srezgarshakeri @ref User 505fc0567d9Srezgarshakeri **/ 5062b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 50777d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 508fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 509*fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 510fc0567d9Srezgarshakeri Ceed delegate; 5116574a04fSJeremy L Thompson 5122b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 513*fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5142b730f8bSJeremy L Thompson CeedCall( 51577d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 516fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 517fc0567d9Srezgarshakeri } 518fc0567d9Srezgarshakeri 5196574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5206574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5216574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 522e022e1f8SJeremy L Thompson 5232b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 524db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 525fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 526fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 527fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 528fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 529fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 530fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 531fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 532fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 533*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 534*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 53577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 53677d1c127SSebastian Grimberg } 53777d1c127SSebastian Grimberg 53877d1c127SSebastian Grimberg /** 53977d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 54077d1c127SSebastian Grimberg 54177d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 54277d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 54377d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 54477d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 545*fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 546*fcbe8c06SSebastian 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. 547*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 548*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 54977d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 55077d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 551*fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 552*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 553*fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 55477d1c127SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[0] = 55577d1c127SSebastian 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 55677d1c127SSebastian 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 55777d1c127SSebastian Grimberg to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 55877d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 55977d1c127SSebastian Grimberg 56077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 56177d1c127SSebastian Grimberg 56277d1c127SSebastian Grimberg @ref User 56377d1c127SSebastian Grimberg **/ 56477d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 56577d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt *curl_orients, 56677d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 567*fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 56877d1c127SSebastian Grimberg Ceed delegate; 56977d1c127SSebastian Grimberg 57077d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 571*fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 57277d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 57377d1c127SSebastian Grimberg curl_orients, rstr)); 57477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 57577d1c127SSebastian Grimberg } 57677d1c127SSebastian Grimberg 57777d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 57877d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 57977d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 58077d1c127SSebastian Grimberg 58177d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 582*fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 58377d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 58477d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 58577d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 58677d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 58777d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 58877d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 58977d1c127SSebastian Grimberg (*rstr)->num_blk = num_elem; 59077d1c127SSebastian Grimberg (*rstr)->blk_size = 1; 591*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 592*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 593fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 594fc0567d9Srezgarshakeri } 595fc0567d9Srezgarshakeri 596fc0567d9Srezgarshakeri /** 5977509a596Sjeremylt @brief Create a strided CeedElemRestriction 598d7b241e6Sjeremylt 599ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 600ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 601ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 602ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 603*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 604*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 605*fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 606*fcbe8c06SSebastian 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]. 607*fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 608ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 609d7b241e6Sjeremylt 610b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 611dfdf5a53Sjeremylt 6127a982d89SJeremy L. Thompson @ref User 613b11c1e72Sjeremylt **/ 6142b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 615f90c8643Sjeremylt CeedElemRestriction *rstr) { 6165fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6175fe0d4faSjeremylt Ceed delegate; 618b04eb3d9SSebastian Grimberg 6192b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 620*fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6212b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 622e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6235fe0d4faSjeremylt } 6245fe0d4faSjeremylt 6256574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6266574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 627e022e1f8SJeremy L Thompson 6282b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 629db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 630d1d35e2fSjeremylt (*rstr)->ref_count = 1; 631d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 632d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 633d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 634d1d35e2fSjeremylt (*rstr)->l_size = l_size; 635d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 636d1d35e2fSjeremylt (*rstr)->blk_size = 1; 637*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6382b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6392b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 640*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 641e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 642d7b241e6Sjeremylt } 643d7b241e6Sjeremylt 644d7b241e6Sjeremylt /** 645b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 646d7b241e6Sjeremylt 647ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 648ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 649ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 650ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 651ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 652*fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 653*fcbe8c06SSebastian 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. 654*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 655*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 656ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 657ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 658*fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 659*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 660*fcbe8c06SSebastian 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 661*fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 662ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 663d7b241e6Sjeremylt 664b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 665dfdf5a53Sjeremylt 6667a982d89SJeremy L. Thompson @ref Backend 667b11c1e72Sjeremylt **/ 6682b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 6692b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 6704ce2993fSjeremylt CeedElemRestriction *rstr) { 671d1d35e2fSjeremylt CeedInt *blk_offsets; 672d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 673d7b241e6Sjeremylt 6745fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6755fe0d4faSjeremylt Ceed delegate; 6766574a04fSJeremy L Thompson 6772b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 6786402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 6792b730f8bSJeremy L Thompson CeedCall( 6802b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 681e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6825fe0d4faSjeremylt } 683d7b241e6Sjeremylt 6846574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6856574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 6866574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 6876574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 688e022e1f8SJeremy L Thompson 6892b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 6902b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 691d7b241e6Sjeremylt 692db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 693db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 694d1d35e2fSjeremylt (*rstr)->ref_count = 1; 695d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 696d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 697d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 698d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 699d1d35e2fSjeremylt (*rstr)->l_size = l_size; 700d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 701d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 702*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_DEFAULT; 703*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, NULL, *rstr)); 704d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 7052b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 7061d102b48SJeremy L Thompson } 707e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 708d7b241e6Sjeremylt } 709d7b241e6Sjeremylt 710b11c1e72Sjeremylt /** 71177d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 71277d1c127SSebastian Grimberg 71377d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 71477d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 71577d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 71677d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 71777d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 718*fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 719*fcbe8c06SSebastian 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. 720*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 721*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 72277d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 72377d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 724*fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 725*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 726*fcbe8c06SSebastian 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 727*fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 728*fcbe8c06SSebastian 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. 729*fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 73077d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 73177d1c127SSebastian Grimberg 73277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 73377d1c127SSebastian Grimberg 73477d1c127SSebastian Grimberg @ref Backend 73577d1c127SSebastian Grimberg **/ 73677d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 73777d1c127SSebastian Grimberg CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 73877d1c127SSebastian Grimberg const bool *orients, CeedElemRestriction *rstr) { 73977d1c127SSebastian Grimberg CeedInt *blk_offsets; 74077d1c127SSebastian Grimberg bool *blk_orients; 74177d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 74277d1c127SSebastian Grimberg 743*fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 74477d1c127SSebastian Grimberg Ceed delegate; 74577d1c127SSebastian Grimberg 74677d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 747*fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 74877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 74977d1c127SSebastian Grimberg offsets, orients, rstr)); 75077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 75177d1c127SSebastian Grimberg } 75277d1c127SSebastian Grimberg 75377d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 75477d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 75577d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 75677d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 75777d1c127SSebastian Grimberg 75877d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 75977d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_orients)); 76077d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 76177d1c127SSebastian Grimberg CeedCall(CeedPermutePadOrientations(orients, blk_orients, num_blk, num_elem, blk_size, elem_size)); 76277d1c127SSebastian Grimberg 763*fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 764*fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 76577d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 76677d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 76777d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 76877d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 76977d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 77077d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 77177d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 77277d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 773*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 774*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, (const bool *)blk_orients, NULL, *rstr)); 77577d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 77677d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 77777d1c127SSebastian Grimberg } 77877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 77977d1c127SSebastian Grimberg } 78077d1c127SSebastian Grimberg 78177d1c127SSebastian Grimberg /** 78277d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 78377d1c127SSebastian Grimberg 78477d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 78577d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 78677d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 78777d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 78877d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 789*fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 790*fcbe8c06SSebastian 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. 791*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 792*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 79377d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 79477d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 795*fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 796*fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 797*fcbe8c06SSebastian 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 798*fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 79977d1c127SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[0] = 800*fcbe8c06SSebastian 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. 801*fcbe8c06SSebastian Grimberg This orientation matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the 802*fcbe8c06SSebastian 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 803*fcbe8c06SSebastian Grimberg be permuted and padded similarly to @a offsets. 80477d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 80577d1c127SSebastian Grimberg 80677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 80777d1c127SSebastian Grimberg 80877d1c127SSebastian Grimberg @ref Backend 80977d1c127SSebastian Grimberg **/ 81077d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, 81177d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 81277d1c127SSebastian Grimberg const CeedInt *offsets, const CeedInt *curl_orients, CeedElemRestriction *rstr) { 81377d1c127SSebastian Grimberg CeedInt *blk_offsets; 81477d1c127SSebastian Grimberg CeedInt *blk_curl_orients; 81577d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 81677d1c127SSebastian Grimberg 817*fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 81877d1c127SSebastian Grimberg Ceed delegate; 81977d1c127SSebastian Grimberg 82077d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 821*fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 82277d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 82377d1c127SSebastian Grimberg offsets, curl_orients, rstr)); 82477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 82577d1c127SSebastian Grimberg } 82677d1c127SSebastian Grimberg 82777d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 82877d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 82977d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 83077d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 83177d1c127SSebastian Grimberg 83277d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 83377d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * 3 * elem_size, &blk_curl_orients)); 83477d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 83577d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(curl_orients, blk_curl_orients, num_blk, num_elem, blk_size, 3 * elem_size)); 83677d1c127SSebastian Grimberg 837*fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 838*fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 83977d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 84077d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 84177d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 84277d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 84377d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 84477d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 84577d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 84677d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 847*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 848*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, (const CeedInt *)blk_curl_orients, 849*fcbe8c06SSebastian Grimberg *rstr)); 85077d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 85177d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 85277d1c127SSebastian Grimberg } 85377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 85477d1c127SSebastian Grimberg } 85577d1c127SSebastian Grimberg 85677d1c127SSebastian Grimberg /** 85777d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 8587509a596Sjeremylt 859ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 860ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 861ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 862ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 863ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 864*fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 865*fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 866*fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 867*fcbe8c06SSebastian 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]. 868*fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 869ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 8707509a596Sjeremylt 8717509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 8727509a596Sjeremylt 8737a982d89SJeremy L. Thompson @ref User 8747509a596Sjeremylt **/ 8752b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 8768621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 877d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 8787509a596Sjeremylt 8797509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 8807509a596Sjeremylt Ceed delegate; 8816574a04fSJeremy L Thompson 8822b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 883*fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 8842b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 885e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8867509a596Sjeremylt } 8877509a596Sjeremylt 8886574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 8896574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 8906574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 891e022e1f8SJeremy L Thompson 8922b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 893db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 894d1d35e2fSjeremylt (*rstr)->ref_count = 1; 895d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 896d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 897d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 898d1d35e2fSjeremylt (*rstr)->l_size = l_size; 899d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 900d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 901*fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 9022b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 9032b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 904*fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 905e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9067509a596Sjeremylt } 9077509a596Sjeremylt 9087509a596Sjeremylt /** 909c17ec2beSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to `CeedElemRestrictionApplyUnsigned()`. 910c17ec2beSJeremy L Thompson 911c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 912c17ec2beSJeremy L Thompson 913c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 914c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 915c17ec2beSJeremy L Thompson 916c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 917c17ec2beSJeremy L Thompson 918c17ec2beSJeremy L Thompson @ref User 919c17ec2beSJeremy L Thompson **/ 920c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 921c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 922c17ec2beSJeremy L Thompson 923c17ec2beSJeremy L Thompson // Copy old rstr 924c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 925c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 926c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 927c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 928c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 929c17ec2beSJeremy L Thompson if (rstr->strides) { 930c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 931c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 932c17ec2beSJeremy L Thompson } 933c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_signed)); 934c17ec2beSJeremy L Thompson 935c17ec2beSJeremy L Thompson // Override Apply 936c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 937c17ec2beSJeremy L Thompson 938c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 939c17ec2beSJeremy L Thompson } 940c17ec2beSJeremy L Thompson 941c17ec2beSJeremy L Thompson /** 942ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 9439fd66db6SSebastian Grimberg 944ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 9459560d06aSjeremylt 9469fd66db6SSebastian 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. 9479fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 948ea61e9acSJeremy L Thompson 949ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 950ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 9519560d06aSjeremylt 9529560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 9539560d06aSjeremylt 9549560d06aSjeremylt @ref User 9559560d06aSjeremylt **/ 9562b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 957393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 9582b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 9599560d06aSjeremylt *rstr_copy = rstr; 9609560d06aSjeremylt return CEED_ERROR_SUCCESS; 9619560d06aSjeremylt } 9629560d06aSjeremylt 9639560d06aSjeremylt /** 964b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 965b11c1e72Sjeremylt 966ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 967ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 968ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 969b11c1e72Sjeremylt 970b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 971dfdf5a53Sjeremylt 9727a982d89SJeremy L. Thompson @ref User 973b11c1e72Sjeremylt **/ 9742b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 975d2643443SJeremy L Thompson CeedSize e_size, l_size; 976d1d35e2fSjeremylt l_size = rstr->l_size; 977d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 9782b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 9792b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 980e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 981d7b241e6Sjeremylt } 982d7b241e6Sjeremylt 983d7b241e6Sjeremylt /** 984d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 985d7b241e6Sjeremylt 986ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 987ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 988ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 989*fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 990*fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 991ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 992b11c1e72Sjeremylt 993b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 994dfdf5a53Sjeremylt 9957a982d89SJeremy L. Thompson @ref User 996b11c1e72Sjeremylt **/ 9972b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 998d7b241e6Sjeremylt CeedInt m, n; 999d7b241e6Sjeremylt 1000d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1001d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1002d1d35e2fSjeremylt n = rstr->l_size; 1003d7b241e6Sjeremylt } else { 1004d1d35e2fSjeremylt m = rstr->l_size; 1005d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1006d7b241e6Sjeremylt } 10076574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10086574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10096574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10106574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10112b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1012e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1013d7b241e6Sjeremylt } 1014d7b241e6Sjeremylt 1015d7b241e6Sjeremylt /** 1016d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1017be9261b7Sjeremylt 1018ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1019ea61e9acSJeremy 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 1020ea61e9acSJeremy L Thompson : 4*blk_size] 1021ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1022ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1023*fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1024*fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1025ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1026be9261b7Sjeremylt 1027be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1028be9261b7Sjeremylt 10297a982d89SJeremy L. Thompson @ref Backend 1030be9261b7Sjeremylt **/ 10312b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 10322b730f8bSJeremy L Thompson CeedRequest *request) { 1033be9261b7Sjeremylt CeedInt m, n; 1034be9261b7Sjeremylt 10356402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 10366402da51SJeremy L Thompson 1037d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1038d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1039d1d35e2fSjeremylt n = rstr->l_size; 1040be9261b7Sjeremylt } else { 1041d1d35e2fSjeremylt m = rstr->l_size; 1042d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1043be9261b7Sjeremylt } 10446574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10456574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10466574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10476574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10486574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 10496574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 10506574a04fSJeremy L Thompson rstr->num_elem); 10512b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1052e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1053be9261b7Sjeremylt } 1054be9261b7Sjeremylt 1055be9261b7Sjeremylt /** 1056b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1057b7c9bbdaSJeremy L Thompson 1058ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1059b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1060b7c9bbdaSJeremy L Thompson 1061b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1062b7c9bbdaSJeremy L Thompson 1063b7c9bbdaSJeremy L Thompson @ref Advanced 1064b7c9bbdaSJeremy L Thompson **/ 1065b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1066b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1067b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1068b7c9bbdaSJeremy L Thompson } 1069b7c9bbdaSJeremy L Thompson 1070b7c9bbdaSJeremy L Thompson /** 1071d979a051Sjeremylt @brief Get the L-vector component stride 1072a681ae63Sjeremylt 1073ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1074d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1075a681ae63Sjeremylt 1076a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1077a681ae63Sjeremylt 1078b7c9bbdaSJeremy L Thompson @ref Advanced 1079a681ae63Sjeremylt **/ 10802b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1081d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1082e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1083a681ae63Sjeremylt } 1084a681ae63Sjeremylt 1085a681ae63Sjeremylt /** 1086a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1087a681ae63Sjeremylt 1088ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1089d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1090a681ae63Sjeremylt 1091a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1092a681ae63Sjeremylt 1093b7c9bbdaSJeremy L Thompson @ref Advanced 1094a681ae63Sjeremylt **/ 10952b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1096d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1097e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1098a681ae63Sjeremylt } 1099a681ae63Sjeremylt 1100a681ae63Sjeremylt /** 1101a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1102a681ae63Sjeremylt 1103ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1104d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1105a681ae63Sjeremylt 1106a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1107a681ae63Sjeremylt 1108b7c9bbdaSJeremy L Thompson @ref Advanced 1109a681ae63Sjeremylt **/ 11102b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1111d1d35e2fSjeremylt *elem_size = rstr->elem_size; 1112e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1113a681ae63Sjeremylt } 1114a681ae63Sjeremylt 1115a681ae63Sjeremylt /** 1116d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1117a681ae63Sjeremylt 1118ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1119d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1120a681ae63Sjeremylt 1121a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1122a681ae63Sjeremylt 1123b7c9bbdaSJeremy L Thompson @ref Advanced 1124a681ae63Sjeremylt **/ 11252b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1126d1d35e2fSjeremylt *l_size = rstr->l_size; 1127e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1128a681ae63Sjeremylt } 1129a681ae63Sjeremylt 1130a681ae63Sjeremylt /** 1131ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1132a681ae63Sjeremylt 1133ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1134d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1135a681ae63Sjeremylt 1136a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1137a681ae63Sjeremylt 1138b7c9bbdaSJeremy L Thompson @ref Advanced 1139a681ae63Sjeremylt **/ 11402b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1141d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1142e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1143a681ae63Sjeremylt } 1144a681ae63Sjeremylt 1145a681ae63Sjeremylt /** 1146a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1147a681ae63Sjeremylt 1148ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1149d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1150a681ae63Sjeremylt 1151a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1152a681ae63Sjeremylt 1153b7c9bbdaSJeremy L Thompson @ref Advanced 1154a681ae63Sjeremylt **/ 11552b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1156d1d35e2fSjeremylt *num_block = rstr->num_blk; 1157e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1158a681ae63Sjeremylt } 1159a681ae63Sjeremylt 1160a681ae63Sjeremylt /** 1161a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1162a681ae63Sjeremylt 1163ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1164d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 1165a681ae63Sjeremylt 1166a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1167a681ae63Sjeremylt 1168b7c9bbdaSJeremy L Thompson @ref Advanced 1169a681ae63Sjeremylt **/ 11702b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 1171d1d35e2fSjeremylt *blk_size = rstr->blk_size; 1172e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1173a681ae63Sjeremylt } 1174a681ae63Sjeremylt 1175a681ae63Sjeremylt /** 1176d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 11771469ee4dSjeremylt 1178ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1179d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 11801469ee4dSjeremylt 11811469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 11821469ee4dSjeremylt 11837a982d89SJeremy L. Thompson @ref User 11841469ee4dSjeremylt **/ 11852b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1186d1d35e2fSjeremylt CeedVector e_vec; 11871469ee4dSjeremylt 118825509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 11892b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 11901469ee4dSjeremylt 119125509ebbSRezgar Shakeri // Compute e_vec = E * 1 11922b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 11932b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 119425509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 11952b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 11962b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 11971469ee4dSjeremylt // Cleanup 11982b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1199e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12001469ee4dSjeremylt } 12011469ee4dSjeremylt 12021469ee4dSjeremylt /** 1203f02ca4a2SJed Brown @brief View a CeedElemRestriction 1204f02ca4a2SJed Brown 1205f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1206f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1207f02ca4a2SJed Brown 1208f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1209f02ca4a2SJed Brown 12107a982d89SJeremy L. Thompson @ref User 1211f02ca4a2SJed Brown **/ 1212f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 12137509a596Sjeremylt char stridesstr[500]; 12142b730f8bSJeremy L Thompson if (rstr->strides) { 12152b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 12162b730f8bSJeremy L Thompson } else { 1217990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 12182b730f8bSJeremy L Thompson } 12197509a596Sjeremylt 12202b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 12212b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1222d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1223e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1224f02ca4a2SJed Brown } 1225f02ca4a2SJed Brown 1226f02ca4a2SJed Brown /** 1227b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1228b11c1e72Sjeremylt 1229ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1230b11c1e72Sjeremylt 1231b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1232dfdf5a53Sjeremylt 12337a982d89SJeremy L. Thompson @ref User 1234b11c1e72Sjeremylt **/ 12354ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1236393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1237ad6481ceSJeremy L Thompson *rstr = NULL; 1238ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1239ad6481ceSJeremy L Thompson } 12406574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 12416574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1242c17ec2beSJeremy L Thompson 1243c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 1244c17ec2beSJeremy L Thompson if ((*rstr)->rstr_signed) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_signed)); 1245c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1246c17ec2beSJeremy L Thompson 12472b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 12482b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 12492b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1250e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1251d7b241e6Sjeremylt } 1252d7b241e6Sjeremylt 1253d7b241e6Sjeremylt /// @} 1254