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*e7f679fcSJeremy L Thompson @param[out] block_offsets Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 29*e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 30ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 31*e7f679fcSJeremy L Thompson @param[in] block_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 **/ 38*e7f679fcSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *block_offsets, CeedInt num_block, CeedInt num_elem, CeedInt block_size, 39*e7f679fcSJeremy L Thompson CeedInt elem_size) { 40*e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 41*e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 422b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 43*e7f679fcSJeremy L Thompson block_offsets[e * elem_size + k * block_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 442b730f8bSJeremy L Thompson } 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 47e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 487a982d89SJeremy L. Thompson } 497a982d89SJeremy L. Thompson 5077d1c127SSebastian Grimberg /** 5177d1c127SSebastian Grimberg @brief Permute and pad orientations for a blocked restriction 5277d1c127SSebastian Grimberg 53fcbe8c06SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size]. 54*e7f679fcSJeremy L Thompson @param[out] block_orients Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 55*e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 5677d1c127SSebastian Grimberg @param[in] num_elem Number of elements 57*e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 5877d1c127SSebastian Grimberg @param[in] elem_size Size of each element 5977d1c127SSebastian Grimberg 6077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 6177d1c127SSebastian Grimberg 6277d1c127SSebastian Grimberg @ref Utility 6377d1c127SSebastian Grimberg **/ 64*e7f679fcSJeremy L Thompson int CeedPermutePadOrients(const bool *orients, bool *block_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, CeedInt elem_size) { 65*e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 66*e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 6777d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 68*e7f679fcSJeremy L Thompson block_orients[e * elem_size + k * block_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 6977d1c127SSebastian Grimberg } 7077d1c127SSebastian Grimberg } 7177d1c127SSebastian Grimberg } 7277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 7377d1c127SSebastian Grimberg } 7477d1c127SSebastian Grimberg 750c73c039SSebastian Grimberg /** 760c73c039SSebastian Grimberg @brief Permute and pad curl-conforming orientations for a blocked restriction 770c73c039SSebastian Grimberg 780c73c039SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size]. 79*e7f679fcSJeremy L Thompson @param[out] block_curl_orients Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 80*e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 810c73c039SSebastian Grimberg @param[in] num_elem Number of elements 82*e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 830c73c039SSebastian Grimberg @param[in] elem_size Size of each element 840c73c039SSebastian Grimberg 850c73c039SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 860c73c039SSebastian Grimberg 870c73c039SSebastian Grimberg @ref Utility 880c73c039SSebastian Grimberg **/ 89*e7f679fcSJeremy L Thompson int CeedPermutePadCurlOrients(const CeedInt8 *curl_orients, CeedInt8 *block_curl_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, 900c73c039SSebastian Grimberg CeedInt elem_size) { 91*e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 92*e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 930c73c039SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 94*e7f679fcSJeremy L Thompson block_curl_orients[e * elem_size + k * block_size + j] = curl_orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 950c73c039SSebastian Grimberg } 960c73c039SSebastian Grimberg } 970c73c039SSebastian Grimberg } 980c73c039SSebastian Grimberg return CEED_ERROR_SUCCESS; 990c73c039SSebastian Grimberg } 1000c73c039SSebastian Grimberg 1017a982d89SJeremy L. Thompson /// @} 1027a982d89SJeremy L. Thompson 1037a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1047a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 1057a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1067a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 1077a982d89SJeremy L. Thompson /// @{ 1087a982d89SJeremy L. Thompson 1097a982d89SJeremy L. Thompson /** 110fcbe8c06SSebastian Grimberg @brief Get the type of a CeedElemRestriction 111a681ae63Sjeremylt 112fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 113fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 114fcbe8c06SSebastian Grimberg 115fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 116fcbe8c06SSebastian Grimberg 117fcbe8c06SSebastian Grimberg @ref Backend 118fcbe8c06SSebastian Grimberg **/ 119fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 120fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 121fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 122fcbe8c06SSebastian Grimberg } 123fcbe8c06SSebastian Grimberg 124fcbe8c06SSebastian Grimberg /** 125fcbe8c06SSebastian Grimberg @brief Get the strided status of a CeedElemRestriction 126fcbe8c06SSebastian Grimberg 127fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 128fcbe8c06SSebastian Grimberg @param[out] is_strided Variable to store strided status, 1 if strided else 0 129fcbe8c06SSebastian Grimberg **/ 130fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 131fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 132fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 133fcbe8c06SSebastian Grimberg } 134fcbe8c06SSebastian Grimberg 135fcbe8c06SSebastian Grimberg /** 136a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 1377a982d89SJeremy L. Thompson 138ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 139a681ae63Sjeremylt @param[out] strides Variable to store strides array 1407a982d89SJeremy L. Thompson 1417a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1427a982d89SJeremy L. Thompson 1437a982d89SJeremy L. Thompson @ref Backend 1447a982d89SJeremy L. Thompson **/ 1452b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1466574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1472b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 148e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1497a982d89SJeremy L. Thompson } 1507a982d89SJeremy L. Thompson 1517a982d89SJeremy L. Thompson /** 15277d1c127SSebastian Grimberg @brief Get the backend stride status of a CeedElemRestriction 15377d1c127SSebastian Grimberg 15477d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction 15577d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 15677d1c127SSebastian Grimberg 15777d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 15877d1c127SSebastian Grimberg 15977d1c127SSebastian Grimberg @ref Backend 16077d1c127SSebastian Grimberg **/ 16177d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 16277d1c127SSebastian Grimberg CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 16377d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 16477d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 16577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 16677d1c127SSebastian Grimberg } 16777d1c127SSebastian Grimberg 16877d1c127SSebastian Grimberg /** 169bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 170bd33150aSjeremylt 171ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 172fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 173fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 174d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 175bd33150aSjeremylt 176bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 177bd33150aSjeremylt 178bd33150aSjeremylt @ref User 179bd33150aSjeremylt **/ 1802b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 1817c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 1827c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 183c17ec2beSJeremy L Thompson } else { 1846574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 1852b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 186d1d35e2fSjeremylt rstr->num_readers++; 187c17ec2beSJeremy L Thompson } 188e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 189430758c8SJeremy L Thompson } 190430758c8SJeremy L Thompson 191430758c8SJeremy L Thompson /** 192430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 193430758c8SJeremy L Thompson 194ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 195ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 196430758c8SJeremy L Thompson 197430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 198430758c8SJeremy L Thompson 199430758c8SJeremy L Thompson @ref User 200430758c8SJeremy L Thompson **/ 2012b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2027c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2037c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 204c17ec2beSJeremy L Thompson } else { 205430758c8SJeremy L Thompson *offsets = NULL; 206d1d35e2fSjeremylt rstr->num_readers--; 207c17ec2beSJeremy L Thompson } 208e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 209bd33150aSjeremylt } 210bd33150aSjeremylt 211bd33150aSjeremylt /** 21277d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction orientations array by memtype 2133ac43b2cSJeremy L Thompson 21477d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve orientations 215fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 216fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 21777d1c127SSebastian Grimberg @param[out] orients Array on memory type mem_type 2183ac43b2cSJeremy L Thompson 2193ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2203ac43b2cSJeremy L Thompson 22177d1c127SSebastian Grimberg @ref User 2223ac43b2cSJeremy L Thompson **/ 22377d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 224fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOrientations"); 22577d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 22677d1c127SSebastian Grimberg rstr->num_readers++; 227e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2283ac43b2cSJeremy L Thompson } 2293ac43b2cSJeremy L Thompson 2303ac43b2cSJeremy L Thompson /** 23177d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetOrientations() 232b435c5a6Srezgarshakeri 23377d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 23477d1c127SSebastian Grimberg @param[in] orients Array of orientation data 235b435c5a6Srezgarshakeri 236b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 237b435c5a6Srezgarshakeri 23877d1c127SSebastian Grimberg @ref User 239b435c5a6Srezgarshakeri **/ 24077d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 24177d1c127SSebastian Grimberg *orients = NULL; 24277d1c127SSebastian Grimberg rstr->num_readers--; 243b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 244b435c5a6Srezgarshakeri } 245b435c5a6Srezgarshakeri 246b435c5a6Srezgarshakeri /** 24777d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction curl-conforming orientations array by memtype 2487a982d89SJeremy L. Thompson 24977d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve curl-conforming 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] curl_orients Array on memory type mem_type 2537a982d89SJeremy L. Thompson 2547a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2557a982d89SJeremy L. Thompson 25677d1c127SSebastian Grimberg @ref User 2577a982d89SJeremy L. Thompson **/ 2580c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 259fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetCurlOrientations"); 26077d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 26177d1c127SSebastian Grimberg rstr->num_readers++; 26277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 26377d1c127SSebastian Grimberg } 26477d1c127SSebastian Grimberg 26577d1c127SSebastian Grimberg /** 26677d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetCurlOrientations() 26777d1c127SSebastian Grimberg 26877d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 26977d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 27077d1c127SSebastian Grimberg 27177d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 27277d1c127SSebastian Grimberg 27377d1c127SSebastian Grimberg @ref User 27477d1c127SSebastian Grimberg **/ 2750c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 27677d1c127SSebastian Grimberg *curl_orients = NULL; 27777d1c127SSebastian Grimberg rstr->num_readers--; 278e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2797a982d89SJeremy L. Thompson } 2807a982d89SJeremy L. Thompson 2817a982d89SJeremy L. Thompson /** 28249fd234cSJeremy L Thompson 28349fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 28449fd234cSJeremy L Thompson 285ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 286fcbe8c06SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 287fcbe8c06SSebastian 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] 28849fd234cSJeremy L Thompson 28949fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 29049fd234cSJeremy L Thompson 29149fd234cSJeremy L Thompson @ref Backend 29249fd234cSJeremy L Thompson **/ 2932b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 2946574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 2952b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 296e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 29749fd234cSJeremy L Thompson } 29849fd234cSJeremy L Thompson 29949fd234cSJeremy L Thompson /** 30049fd234cSJeremy L Thompson 30149fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 30249fd234cSJeremy L Thompson 303ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 304ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 305ea61e9acSJeremy 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] 30649fd234cSJeremy L Thompson 30749fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 30849fd234cSJeremy L Thompson 30949fd234cSJeremy L Thompson @ref Backend 31049fd234cSJeremy L Thompson **/ 3112b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 3122b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 313e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 31449fd234cSJeremy L Thompson } 31549fd234cSJeremy L Thompson 31649fd234cSJeremy L Thompson /** 3177a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3187a982d89SJeremy L. Thompson 319ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3207a982d89SJeremy L. Thompson @param[out] data Variable to store data 3217a982d89SJeremy L. Thompson 3227a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3237a982d89SJeremy L. Thompson 3247a982d89SJeremy L. Thompson @ref Backend 3257a982d89SJeremy L. Thompson **/ 326777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 327777ff853SJeremy L Thompson *(void **)data = rstr->data; 328e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3297a982d89SJeremy L. Thompson } 3307a982d89SJeremy L. Thompson 3317a982d89SJeremy L. Thompson /** 3327a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3337a982d89SJeremy L. Thompson 334ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 335ea61e9acSJeremy L Thompson @param[in] data Data to set 3367a982d89SJeremy L. Thompson 3377a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3387a982d89SJeremy L. Thompson 3397a982d89SJeremy L. Thompson @ref Backend 3407a982d89SJeremy L. Thompson **/ 341777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 342777ff853SJeremy L Thompson rstr->data = data; 343e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3447a982d89SJeremy L. Thompson } 3457a982d89SJeremy L. Thompson 34634359f16Sjeremylt /** 34734359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 34834359f16Sjeremylt 349ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 35034359f16Sjeremylt 35134359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 35234359f16Sjeremylt 35334359f16Sjeremylt @ref Backend 35434359f16Sjeremylt **/ 3559560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 35634359f16Sjeremylt rstr->ref_count++; 35734359f16Sjeremylt return CEED_ERROR_SUCCESS; 35834359f16Sjeremylt } 35934359f16Sjeremylt 3606e15d496SJeremy L Thompson /** 3616e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 3626e15d496SJeremy L Thompson 363ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 364ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 365ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 3666e15d496SJeremy L Thompson 3676e15d496SJeremy L Thompson @ref Backend 3686e15d496SJeremy L Thompson **/ 3692b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 370*e7f679fcSJeremy L Thompson CeedInt e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp, scale = 0; 37189edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 37289edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 37377d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 37489edb9e3SSebastian Grimberg switch (rstr_type) { 37589edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 37689edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 37777d1c127SSebastian Grimberg scale = 1; 37889edb9e3SSebastian Grimberg break; 37989edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 38077d1c127SSebastian Grimberg scale = 2; 38189edb9e3SSebastian Grimberg break; 38289edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 38377d1c127SSebastian Grimberg scale = 6; 38489edb9e3SSebastian Grimberg break; 3856e15d496SJeremy L Thompson } 38677d1c127SSebastian Grimberg } else { 38789edb9e3SSebastian Grimberg switch (rstr_type) { 38889edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 38989edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 39077d1c127SSebastian Grimberg scale = 0; 39189edb9e3SSebastian Grimberg break; 39289edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 39377d1c127SSebastian Grimberg scale = 1; 39489edb9e3SSebastian Grimberg break; 39589edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 39677d1c127SSebastian Grimberg scale = 5; 39789edb9e3SSebastian Grimberg break; 39877d1c127SSebastian Grimberg } 39977d1c127SSebastian Grimberg } 4006e15d496SJeremy L Thompson *flops = e_size * scale; 4016e15d496SJeremy L Thompson 4026e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 4036e15d496SJeremy L Thompson } 4046e15d496SJeremy L Thompson 4057a982d89SJeremy L. Thompson /// @} 4067a982d89SJeremy L. Thompson 40715910d16Sjeremylt /// @cond DOXYGEN_SKIP 40815910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 40915910d16Sjeremylt /// @endcond 41015910d16Sjeremylt 4117a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4127a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4137a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4147a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 415d7b241e6Sjeremylt /// @{ 416d7b241e6Sjeremylt 4177a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 41845f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4197a982d89SJeremy L. Thompson 4204cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 4212b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4227a982d89SJeremy L. Thompson 423d7b241e6Sjeremylt /** 424b11c1e72Sjeremylt @brief Create a CeedElemRestriction 425d7b241e6Sjeremylt 426ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 427ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 428ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 429ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 430fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 431fcbe8c06SSebastian 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. 432fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 433fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 434ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 435ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 436fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 437fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 438fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 439ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 440d7b241e6Sjeremylt 441b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 442dfdf5a53Sjeremylt 4437a982d89SJeremy L. Thompson @ref User 444b11c1e72Sjeremylt **/ 4452b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4462b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4475fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4485fe0d4faSjeremylt Ceed delegate; 4496574a04fSJeremy L Thompson 4502b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 45177d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4522b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 453e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4545fe0d4faSjeremylt } 4555fe0d4faSjeremylt 456*e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 4576574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4586574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4596574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 460e022e1f8SJeremy L Thompson 4612b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 462db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 463d1d35e2fSjeremylt (*rstr)->ref_count = 1; 464d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 465d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 466d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 467d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 468d1d35e2fSjeremylt (*rstr)->l_size = l_size; 469*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 470*e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 47161a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 472fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 473e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 474d7b241e6Sjeremylt } 475d7b241e6Sjeremylt 476d7b241e6Sjeremylt /** 47777d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 478fc0567d9Srezgarshakeri 479ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 480ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 481ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 482ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 483fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 484fcbe8c06SSebastian 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. 485fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 486fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 487ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 488ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 489fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 490fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 491fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 49277d1c127SSebastian 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. 493ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 494fc0567d9Srezgarshakeri 495fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 496fc0567d9Srezgarshakeri 497fc0567d9Srezgarshakeri @ref User 498fc0567d9Srezgarshakeri **/ 4992b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 50077d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 501fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 502fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 503fc0567d9Srezgarshakeri Ceed delegate; 5046574a04fSJeremy L Thompson 5052b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 506fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5072b730f8bSJeremy L Thompson CeedCall( 50877d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 509fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 510fc0567d9Srezgarshakeri } 511fc0567d9Srezgarshakeri 512*e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 5136574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5146574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5156574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 516e022e1f8SJeremy L Thompson 5172b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 518db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 519fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 520fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 521fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 522fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 523fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 524fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 525*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 526*e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 527fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 528fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 52977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 53077d1c127SSebastian Grimberg } 53177d1c127SSebastian Grimberg 53277d1c127SSebastian Grimberg /** 53377d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 53477d1c127SSebastian Grimberg 53577d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 53677d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 53777d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 53877d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 539fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 540fcbe8c06SSebastian 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. 541fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 542fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 54377d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 54477d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 545fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 546fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 547fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 5487c1dbaffSSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[i * 3 * elem_size] 5497c1dbaffSSebastian 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 5507c1dbaffSSebastian Grimberg orientation matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the element restriction operation, 5517c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 55277d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 55377d1c127SSebastian Grimberg 55477d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 55577d1c127SSebastian Grimberg 55677d1c127SSebastian Grimberg @ref User 55777d1c127SSebastian Grimberg **/ 55877d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 5590c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 56077d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 561fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 56277d1c127SSebastian Grimberg Ceed delegate; 56377d1c127SSebastian Grimberg 56477d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 565fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 56677d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 56777d1c127SSebastian Grimberg curl_orients, rstr)); 56877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 56977d1c127SSebastian Grimberg } 57077d1c127SSebastian Grimberg 571*e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 57277d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 57377d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 57477d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 57577d1c127SSebastian Grimberg 57677d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 577fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 57877d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 57977d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 58077d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 58177d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 58277d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 58377d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 584*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 585*e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 586fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 587fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 588fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 589fc0567d9Srezgarshakeri } 590fc0567d9Srezgarshakeri 591fc0567d9Srezgarshakeri /** 5927509a596Sjeremylt @brief Create a strided CeedElemRestriction 593d7b241e6Sjeremylt 594ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 595ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 596ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 597ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 598fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 599fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 600fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 601fcbe8c06SSebastian 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]. 602fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 603ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 604d7b241e6Sjeremylt 605b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 606dfdf5a53Sjeremylt 6077a982d89SJeremy L. Thompson @ref User 608b11c1e72Sjeremylt **/ 6092b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 610f90c8643Sjeremylt CeedElemRestriction *rstr) { 6115fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6125fe0d4faSjeremylt Ceed delegate; 613b04eb3d9SSebastian Grimberg 6142b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 615fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6162b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 617e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6185fe0d4faSjeremylt } 6195fe0d4faSjeremylt 620*e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6216574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6226574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 623*e7f679fcSJeremy L Thompson CeedCheck(l_size >= num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector size must be at least num_elem * elem_size * num_comp"); 624e022e1f8SJeremy L Thompson 6252b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 626db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 627d1d35e2fSjeremylt (*rstr)->ref_count = 1; 628d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 629d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 630d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 631d1d35e2fSjeremylt (*rstr)->l_size = l_size; 632*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 633*e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 634fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6352b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6362b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 637fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 638e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 639d7b241e6Sjeremylt } 640d7b241e6Sjeremylt 641d7b241e6Sjeremylt /** 642b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 643d7b241e6Sjeremylt 644ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 645ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 646ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 647*e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 648ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 649fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 650fcbe8c06SSebastian 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. 651fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 652fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 653ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 654ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 655fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 656*e7f679fcSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 657*e7f679fcSJeremy L Thompson 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 658*e7f679fcSJeremy L Thompson for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 659ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 660d7b241e6Sjeremylt 661b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 662dfdf5a53Sjeremylt 6637a982d89SJeremy L. Thompson @ref Backend 664b11c1e72Sjeremylt **/ 665*e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 6662b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 6674ce2993fSjeremylt CeedElemRestriction *rstr) { 668*e7f679fcSJeremy L Thompson CeedInt *block_offsets; 669*e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 670d7b241e6Sjeremylt 6715fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6725fe0d4faSjeremylt Ceed delegate; 6736574a04fSJeremy L Thompson 6742b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 6756402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 676*e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 677*e7f679fcSJeremy L Thompson rstr)); 678e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6795fe0d4faSjeremylt } 680d7b241e6Sjeremylt 681*e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6826574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 683*e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 6846574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 6856574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 686e022e1f8SJeremy L Thompson 687*e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 688*e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 689d7b241e6Sjeremylt 690db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 691db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 692d1d35e2fSjeremylt (*rstr)->ref_count = 1; 693d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 694d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 695d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 696d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 697d1d35e2fSjeremylt (*rstr)->l_size = l_size; 698*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 699*e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 70061a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 701*e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 702d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 7032b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 7041d102b48SJeremy L Thompson } 705e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 706d7b241e6Sjeremylt } 707d7b241e6Sjeremylt 708b11c1e72Sjeremylt /** 70977d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 71077d1c127SSebastian Grimberg 71177d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 71277d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 71377d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 714*e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 71577d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 716fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 717fcbe8c06SSebastian 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. 718fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 719fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 72077d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 72177d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 722fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 723fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 724fcbe8c06SSebastian 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 725fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 726fcbe8c06SSebastian 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. 727fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 72877d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 72977d1c127SSebastian Grimberg 73077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 73177d1c127SSebastian Grimberg 73277d1c127SSebastian Grimberg @ref Backend 73377d1c127SSebastian Grimberg **/ 734*e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 735*e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 736*e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 737*e7f679fcSJeremy L Thompson CeedInt *block_offsets; 738*e7f679fcSJeremy L Thompson bool *block_orients; 739*e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 74077d1c127SSebastian Grimberg 741fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 74277d1c127SSebastian Grimberg Ceed delegate; 74377d1c127SSebastian Grimberg 74477d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 745fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 746*e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 74777d1c127SSebastian Grimberg offsets, orients, rstr)); 74877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 74977d1c127SSebastian Grimberg } 75077d1c127SSebastian Grimberg 75177d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 752*e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 75377d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 75477d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 75577d1c127SSebastian Grimberg 756*e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 757*e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 758*e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 759*e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 76077d1c127SSebastian Grimberg 761fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 762fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 76377d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 76477d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 76577d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 76677d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 76777d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 76877d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 769*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 770*e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 771fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 772*e7f679fcSJeremy L Thompson CeedCall( 773*e7f679fcSJeremy L Thompson ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, *rstr)); 77477d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 77577d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 77677d1c127SSebastian Grimberg } 77777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 77877d1c127SSebastian Grimberg } 77977d1c127SSebastian Grimberg 78077d1c127SSebastian Grimberg /** 78177d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 78277d1c127SSebastian Grimberg 78377d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 78477d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 78577d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 786*e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 78777d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 788fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 789fcbe8c06SSebastian 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. 790fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 791fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 79277d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 79377d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 794fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 795fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 796fcbe8c06SSebastian 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 797fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 7987c1dbaffSSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[i * 3 * elem_size] 7997c1dbaffSSebastian 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 8007c1dbaffSSebastian Grimberg orientation matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the element restriction operation, 8017c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). Will also be permuted and padded 8027c1dbaffSSebastian Grimberg similarly to @a offsets. 80377d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 80477d1c127SSebastian Grimberg 80577d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 80677d1c127SSebastian Grimberg 80777d1c127SSebastian Grimberg @ref Backend 80877d1c127SSebastian Grimberg **/ 809*e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 81077d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 8110c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 812*e7f679fcSJeremy L Thompson CeedInt *block_offsets; 813*e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 814*e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 81577d1c127SSebastian Grimberg 816fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 81777d1c127SSebastian Grimberg Ceed delegate; 81877d1c127SSebastian Grimberg 81977d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 820fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 821*e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 822*e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 82377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 82477d1c127SSebastian Grimberg } 82577d1c127SSebastian Grimberg 826*e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 82777d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 828*e7f679fcSJeremy L Thompson CeedCheck(block_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 832*e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 833*e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 834*e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 835*e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 83677d1c127SSebastian Grimberg 837fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 838fcbe8c06SSebastian 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; 845*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 846*e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 847fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 848*e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 849*e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *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 862*e7f679fcSJeremy L Thompson @param[in] block_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) 864fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 865fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 866fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 867fcbe8c06SSebastian 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]. 868fcbe8c06SSebastian 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 **/ 875*e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 8768621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 877*e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 8787509a596Sjeremylt 8797509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 8807509a596Sjeremylt Ceed delegate; 8816574a04fSJeremy L Thompson 8822b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 883fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 884*e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 885e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8867509a596Sjeremylt } 8877509a596Sjeremylt 888*e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8896574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 890*e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 8916574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 892*e7f679fcSJeremy L Thompson CeedCheck(l_size >= num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector size must be at least num_elem * elem_size * num_comp"); 893e022e1f8SJeremy L Thompson 8942b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 895db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 896d1d35e2fSjeremylt (*rstr)->ref_count = 1; 897d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 898d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 899d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 900d1d35e2fSjeremylt (*rstr)->l_size = l_size; 901*e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 902*e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 903fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 9042b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 9052b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 906fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 907e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9087509a596Sjeremylt } 9097509a596Sjeremylt 9107509a596Sjeremylt /** 9117c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unsigned version. 912c17ec2beSJeremy L Thompson 913c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 914c17ec2beSJeremy L Thompson 915c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 916c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 917c17ec2beSJeremy L Thompson 918c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 919c17ec2beSJeremy L Thompson 920c17ec2beSJeremy L Thompson @ref User 921c17ec2beSJeremy L Thompson **/ 922c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 923c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 924c17ec2beSJeremy L Thompson 925c17ec2beSJeremy L Thompson // Copy old rstr 926c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 927c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 928c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 929c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 930c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 931c17ec2beSJeremy L Thompson if (rstr->strides) { 932c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 933c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 934c17ec2beSJeremy L Thompson } 9357c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 936c17ec2beSJeremy L Thompson 937c17ec2beSJeremy L Thompson // Override Apply 938c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 939c17ec2beSJeremy L Thompson 940c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 941c17ec2beSJeremy L Thompson } 942c17ec2beSJeremy L Thompson 943c17ec2beSJeremy L Thompson /** 9447c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unoriented version. 9457c1dbaffSSebastian Grimberg 9467c1dbaffSSebastian Grimberg Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 9477c1dbaffSSebastian Grimberg 9487c1dbaffSSebastian Grimberg @param[in] rstr CeedElemRestriction to create unoriented reference to 9497c1dbaffSSebastian Grimberg @param[in,out] rstr_unoriented Variable to store unoriented CeedElemRestriction 9507c1dbaffSSebastian Grimberg 9517c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 9527c1dbaffSSebastian Grimberg 9537c1dbaffSSebastian Grimberg @ref User 9547c1dbaffSSebastian Grimberg **/ 9557c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 9567c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 9577c1dbaffSSebastian Grimberg 9587c1dbaffSSebastian Grimberg // Copy old rstr 9597c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 9607c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 9617c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 9627c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 9637c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 9647c1dbaffSSebastian Grimberg if (rstr->strides) { 9657c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 9667c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 9677c1dbaffSSebastian Grimberg } 9687c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 9697c1dbaffSSebastian Grimberg 9707c1dbaffSSebastian Grimberg // Override Apply 9717c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 9727c1dbaffSSebastian Grimberg 9737c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 9747c1dbaffSSebastian Grimberg } 9757c1dbaffSSebastian Grimberg 9767c1dbaffSSebastian Grimberg /** 977ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 9789fd66db6SSebastian Grimberg 979ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 9809560d06aSjeremylt 9819fd66db6SSebastian 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. 9829fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 983ea61e9acSJeremy L Thompson 984ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 985ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 9869560d06aSjeremylt 9879560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 9889560d06aSjeremylt 9899560d06aSjeremylt @ref User 9909560d06aSjeremylt **/ 9912b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 992393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 9932b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 9949560d06aSjeremylt *rstr_copy = rstr; 9959560d06aSjeremylt return CEED_ERROR_SUCCESS; 9969560d06aSjeremylt } 9979560d06aSjeremylt 9989560d06aSjeremylt /** 999b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 1000b11c1e72Sjeremylt 1001ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1002ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 1003ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 1004b11c1e72Sjeremylt 1005b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1006dfdf5a53Sjeremylt 10077a982d89SJeremy L. Thompson @ref User 1008b11c1e72Sjeremylt **/ 10092b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1010d2643443SJeremy L Thompson CeedSize e_size, l_size; 1011d1d35e2fSjeremylt l_size = rstr->l_size; 1012*e7f679fcSJeremy L Thompson e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp; 10132b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 10142b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 1015e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1016d7b241e6Sjeremylt } 1017d7b241e6Sjeremylt 1018d7b241e6Sjeremylt /** 1019d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1020d7b241e6Sjeremylt 1021ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1022ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1023ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1024fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1025fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1026ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1027b11c1e72Sjeremylt 1028b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1029dfdf5a53Sjeremylt 10307a982d89SJeremy L. Thompson @ref User 1031b11c1e72Sjeremylt **/ 10322b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1033d7b241e6Sjeremylt CeedInt m, n; 1034d7b241e6Sjeremylt 1035d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1036*e7f679fcSJeremy L Thompson m = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp; 1037d1d35e2fSjeremylt n = rstr->l_size; 1038d7b241e6Sjeremylt } else { 1039d1d35e2fSjeremylt m = rstr->l_size; 1040*e7f679fcSJeremy L Thompson n = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp; 1041d7b241e6Sjeremylt } 10426574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10436574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10446574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10456574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10462b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1047e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1048d7b241e6Sjeremylt } 1049d7b241e6Sjeremylt 1050d7b241e6Sjeremylt /** 1051d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1052be9261b7Sjeremylt 1053ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1054*e7f679fcSJeremy L Thompson @param[in] block Block number to restrict to/from, i.e. block=0 will handle elements [0 : block_size] and block=3 will handle elements 1055*e7f679fcSJeremy L Thompson [3*block_size : 4*block_size] 1056ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1057ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1058*e7f679fcSJeremy L Thompson @param[out] ru Output vector (of shape [@a block_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1059fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1060ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1061be9261b7Sjeremylt 1062be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1063be9261b7Sjeremylt 10647a982d89SJeremy L. Thompson @ref Backend 1065be9261b7Sjeremylt **/ 10662b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 10672b730f8bSJeremy L Thompson CeedRequest *request) { 1068be9261b7Sjeremylt CeedInt m, n; 1069be9261b7Sjeremylt 10706402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 10716402da51SJeremy L Thompson 1072d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1073*e7f679fcSJeremy L Thompson m = rstr->block_size * rstr->elem_size * rstr->num_comp; 1074d1d35e2fSjeremylt n = rstr->l_size; 1075be9261b7Sjeremylt } else { 1076d1d35e2fSjeremylt m = rstr->l_size; 1077*e7f679fcSJeremy L Thompson n = rstr->block_size * rstr->elem_size * rstr->num_comp; 1078be9261b7Sjeremylt } 10796574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10806574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10816574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10826574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 1083*e7f679fcSJeremy L Thompson CeedCheck(rstr->block_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 1084*e7f679fcSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->block_size * block, 10856574a04fSJeremy L Thompson rstr->num_elem); 10862b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1087e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1088be9261b7Sjeremylt } 1089be9261b7Sjeremylt 1090be9261b7Sjeremylt /** 1091b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1092b7c9bbdaSJeremy L Thompson 1093ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1094b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1095b7c9bbdaSJeremy L Thompson 1096b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1097b7c9bbdaSJeremy L Thompson 1098b7c9bbdaSJeremy L Thompson @ref Advanced 1099b7c9bbdaSJeremy L Thompson **/ 1100b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1101b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1102b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1103b7c9bbdaSJeremy L Thompson } 1104b7c9bbdaSJeremy L Thompson 1105b7c9bbdaSJeremy L Thompson /** 1106d979a051Sjeremylt @brief Get the L-vector component stride 1107a681ae63Sjeremylt 1108ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1109d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1110a681ae63Sjeremylt 1111a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1112a681ae63Sjeremylt 1113b7c9bbdaSJeremy L Thompson @ref Advanced 1114a681ae63Sjeremylt **/ 11152b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1116d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1117e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1118a681ae63Sjeremylt } 1119a681ae63Sjeremylt 1120a681ae63Sjeremylt /** 1121a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1122a681ae63Sjeremylt 1123ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1124d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1125a681ae63Sjeremylt 1126a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1127a681ae63Sjeremylt 1128b7c9bbdaSJeremy L Thompson @ref Advanced 1129a681ae63Sjeremylt **/ 11302b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1131d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1132e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1133a681ae63Sjeremylt } 1134a681ae63Sjeremylt 1135a681ae63Sjeremylt /** 1136a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1137a681ae63Sjeremylt 1138ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1139d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1140a681ae63Sjeremylt 1141a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1142a681ae63Sjeremylt 1143b7c9bbdaSJeremy L Thompson @ref Advanced 1144a681ae63Sjeremylt **/ 11452b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1146d1d35e2fSjeremylt *elem_size = rstr->elem_size; 1147e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1148a681ae63Sjeremylt } 1149a681ae63Sjeremylt 1150a681ae63Sjeremylt /** 1151d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1152a681ae63Sjeremylt 1153ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1154d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1155a681ae63Sjeremylt 1156a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1157a681ae63Sjeremylt 1158b7c9bbdaSJeremy L Thompson @ref Advanced 1159a681ae63Sjeremylt **/ 11602b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1161d1d35e2fSjeremylt *l_size = rstr->l_size; 1162e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1163a681ae63Sjeremylt } 1164a681ae63Sjeremylt 1165a681ae63Sjeremylt /** 1166ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1167a681ae63Sjeremylt 1168ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1169d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1170a681ae63Sjeremylt 1171a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1172a681ae63Sjeremylt 1173b7c9bbdaSJeremy L Thompson @ref Advanced 1174a681ae63Sjeremylt **/ 11752b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1176d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1177e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1178a681ae63Sjeremylt } 1179a681ae63Sjeremylt 1180a681ae63Sjeremylt /** 1181a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1182a681ae63Sjeremylt 1183ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1184d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1185a681ae63Sjeremylt 1186a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1187a681ae63Sjeremylt 1188b7c9bbdaSJeremy L Thompson @ref Advanced 1189a681ae63Sjeremylt **/ 11902b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1191*e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1192e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1193a681ae63Sjeremylt } 1194a681ae63Sjeremylt 1195a681ae63Sjeremylt /** 1196a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1197a681ae63Sjeremylt 1198ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1199*e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1200a681ae63Sjeremylt 1201a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1202a681ae63Sjeremylt 1203b7c9bbdaSJeremy L Thompson @ref Advanced 1204a681ae63Sjeremylt **/ 1205*e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1206*e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1207e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1208a681ae63Sjeremylt } 1209a681ae63Sjeremylt 1210a681ae63Sjeremylt /** 1211d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 12121469ee4dSjeremylt 1213ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1214d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 12151469ee4dSjeremylt 12161469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 12171469ee4dSjeremylt 12187a982d89SJeremy L. Thompson @ref User 12191469ee4dSjeremylt **/ 12202b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1221d1d35e2fSjeremylt CeedVector e_vec; 12221469ee4dSjeremylt 122325509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 12242b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 12251469ee4dSjeremylt 122625509ebbSRezgar Shakeri // Compute e_vec = E * 1 12272b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 12282b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 122925509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 12302b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 12312b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 12321469ee4dSjeremylt // Cleanup 12332b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1234e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12351469ee4dSjeremylt } 12361469ee4dSjeremylt 12371469ee4dSjeremylt /** 1238f02ca4a2SJed Brown @brief View a CeedElemRestriction 1239f02ca4a2SJed Brown 1240f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1241f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1242f02ca4a2SJed Brown 1243f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1244f02ca4a2SJed Brown 12457a982d89SJeremy L. Thompson @ref User 1246f02ca4a2SJed Brown **/ 1247f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 12487509a596Sjeremylt char stridesstr[500]; 12492b730f8bSJeremy L Thompson if (rstr->strides) { 12502b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 12512b730f8bSJeremy L Thompson } else { 1252990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 12532b730f8bSJeremy L Thompson } 12547509a596Sjeremylt 12552b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 1256*e7f679fcSJeremy L Thompson rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1257d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1258e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1259f02ca4a2SJed Brown } 1260f02ca4a2SJed Brown 1261f02ca4a2SJed Brown /** 1262b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1263b11c1e72Sjeremylt 1264ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1265b11c1e72Sjeremylt 1266b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1267dfdf5a53Sjeremylt 12687a982d89SJeremy L. Thompson @ref User 1269b11c1e72Sjeremylt **/ 12704ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1271393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1272ad6481ceSJeremy L Thompson *rstr = NULL; 1273ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1274ad6481ceSJeremy L Thompson } 12756574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 12766574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1277c17ec2beSJeremy L Thompson 1278c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 12797c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1280c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1281c17ec2beSJeremy L Thompson 12822b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 12832b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 12842b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1285e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1286d7b241e6Sjeremylt } 1287d7b241e6Sjeremylt 1288d7b241e6Sjeremylt /// @} 1289