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]. 28e7f679fcSJeremy L Thompson @param[out] block_offsets Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 29e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 30ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 31e7f679fcSJeremy 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 **/ 38e7f679fcSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *block_offsets, CeedInt num_block, CeedInt num_elem, CeedInt block_size, 39e7f679fcSJeremy L Thompson CeedInt elem_size) { 40e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 41e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 422b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 43e7f679fcSJeremy 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]. 54e7f679fcSJeremy L Thompson @param[out] block_orients Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 55e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 5677d1c127SSebastian Grimberg @param[in] num_elem Number of elements 57e7f679fcSJeremy 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 **/ 64e7f679fcSJeremy L Thompson int CeedPermutePadOrients(const bool *orients, bool *block_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, CeedInt elem_size) { 65e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 66e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 6777d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 68e7f679fcSJeremy 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]. 79e7f679fcSJeremy 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]. 80e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 810c73c039SSebastian Grimberg @param[in] num_elem Number of elements 82e7f679fcSJeremy 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 **/ 89e7f679fcSJeremy 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) { 91e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 92e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 930c73c039SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 94e7f679fcSJeremy 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 /** 1363ac8f562SJeremy L Thompson @brief Get the points status of a CeedElemRestriction 1373ac8f562SJeremy L Thompson 1383ac8f562SJeremy L Thompson @param[in] rstr CeedElemRestriction 1393ac8f562SJeremy L Thompson @param[out] is_points Variable to store points status, 1 if points else 0 1403ac8f562SJeremy L Thompson **/ 1413ac8f562SJeremy L Thompson int CeedElemRestrictionIsPoints(CeedElemRestriction rstr, bool *is_points) { 1423ac8f562SJeremy L Thompson *is_points = (rstr->rstr_type == CEED_RESTRICTION_POINTS); 1433ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 1443ac8f562SJeremy L Thompson } 1453ac8f562SJeremy L Thompson 1463ac8f562SJeremy L Thompson /** 147*48acf710SJeremy L Thompson @brief Check if two CeedElemRestrictionAtPoints use the same points per element 148*48acf710SJeremy L Thompson 149*48acf710SJeremy L Thompson @param[in] rstr_a First CeedElemRestriction 150*48acf710SJeremy L Thompson @param[in] rstr_b Second CeedElemRestriction 151*48acf710SJeremy L Thompson @param[out] are_compatible Variable to store compatibility status 152*48acf710SJeremy L Thompson **/ 153*48acf710SJeremy L Thompson int CeedElemRestrictionAtPointsAreCompatible(CeedElemRestriction rstr_a, CeedElemRestriction rstr_b, bool *are_compatible) { 154*48acf710SJeremy L Thompson CeedInt num_elem_a, num_elem_b, num_points_a, num_points_b; 155*48acf710SJeremy L Thompson 156*48acf710SJeremy L Thompson // Cannot compare non-points restrictions 157*48acf710SJeremy L Thompson CeedCheck(rstr_a->rstr_type == CEED_RESTRICTION_POINTS, rstr_a->ceed, CEED_ERROR_UNSUPPORTED, "First ElemRestriction must be AtPoints"); 158*48acf710SJeremy L Thompson CeedCheck(rstr_b->rstr_type == CEED_RESTRICTION_POINTS, rstr_b->ceed, CEED_ERROR_UNSUPPORTED, "Second ElemRestriction must be AtPoints"); 159*48acf710SJeremy L Thompson 160*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_a, &num_elem_a)); 161*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_b, &num_elem_b)); 162*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_a, &num_points_a)); 163*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_b, &num_points_b)); 164*48acf710SJeremy L Thompson 165*48acf710SJeremy L Thompson // Check size and contents of offsets arrays 166*48acf710SJeremy L Thompson *are_compatible = true; 167*48acf710SJeremy L Thompson if (num_elem_a != num_elem_b) *are_compatible = false; 168*48acf710SJeremy L Thompson if (num_points_a != num_points_b) *are_compatible = false; 169*48acf710SJeremy L Thompson if (*are_compatible) { 170*48acf710SJeremy L Thompson const CeedInt *offsets_a, *offsets_b; 171*48acf710SJeremy L Thompson 172*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_a, CEED_MEM_HOST, &offsets_a)); 173*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_b, CEED_MEM_HOST, &offsets_b)); 174*48acf710SJeremy L Thompson for (CeedInt i = 0; i < num_elem_a + 1 + num_points_a; i++) *are_compatible &= offsets_a[i] == offsets_b[i]; 175*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_a, &offsets_a)); 176*48acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_b, &offsets_b)); 177*48acf710SJeremy L Thompson } 178*48acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 179*48acf710SJeremy L Thompson } 180*48acf710SJeremy L Thompson 181*48acf710SJeremy L Thompson /** 182a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 1837a982d89SJeremy L. Thompson 184ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 185a681ae63Sjeremylt @param[out] strides Variable to store strides array 1867a982d89SJeremy L. Thompson 1877a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1887a982d89SJeremy L. Thompson 1897a982d89SJeremy L. Thompson @ref Backend 1907a982d89SJeremy L. Thompson **/ 1912b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1926574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1932b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 194e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1957a982d89SJeremy L. Thompson } 1967a982d89SJeremy L. Thompson 1977a982d89SJeremy L. Thompson /** 19877d1c127SSebastian Grimberg @brief Get the backend stride status of a CeedElemRestriction 19977d1c127SSebastian Grimberg 20077d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction 20177d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 20277d1c127SSebastian Grimberg 20377d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 20477d1c127SSebastian Grimberg 20577d1c127SSebastian Grimberg @ref Backend 20677d1c127SSebastian Grimberg **/ 20777d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 20877d1c127SSebastian Grimberg CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 20977d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 21077d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 21177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 21277d1c127SSebastian Grimberg } 21377d1c127SSebastian Grimberg 21477d1c127SSebastian Grimberg /** 215bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 216bd33150aSjeremylt 217ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 218fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 219fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 220d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 221bd33150aSjeremylt 222bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 223bd33150aSjeremylt 224bd33150aSjeremylt @ref User 225bd33150aSjeremylt **/ 2262b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 2277c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2287c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 229c17ec2beSJeremy L Thompson } else { 2306574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 2312b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 232d1d35e2fSjeremylt rstr->num_readers++; 233c17ec2beSJeremy L Thompson } 234e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 235430758c8SJeremy L Thompson } 236430758c8SJeremy L Thompson 237430758c8SJeremy L Thompson /** 238430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 239430758c8SJeremy L Thompson 240ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 241ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 242430758c8SJeremy L Thompson 243430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 244430758c8SJeremy L Thompson 245430758c8SJeremy L Thompson @ref User 246430758c8SJeremy L Thompson **/ 2472b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2487c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2497c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 250c17ec2beSJeremy L Thompson } else { 251430758c8SJeremy L Thompson *offsets = NULL; 252d1d35e2fSjeremylt rstr->num_readers--; 253c17ec2beSJeremy L Thompson } 254e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 255bd33150aSjeremylt } 256bd33150aSjeremylt 257bd33150aSjeremylt /** 25877d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction orientations array by memtype 2593ac43b2cSJeremy L Thompson 26077d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve orientations 261fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 262fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 26377d1c127SSebastian Grimberg @param[out] orients Array on memory type mem_type 2643ac43b2cSJeremy L Thompson 2653ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2663ac43b2cSJeremy L Thompson 26777d1c127SSebastian Grimberg @ref User 2683ac43b2cSJeremy L Thompson **/ 26977d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 270fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOrientations"); 27177d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 27277d1c127SSebastian Grimberg rstr->num_readers++; 273e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2743ac43b2cSJeremy L Thompson } 2753ac43b2cSJeremy L Thompson 2763ac43b2cSJeremy L Thompson /** 27777d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetOrientations() 278b435c5a6Srezgarshakeri 27977d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 28077d1c127SSebastian Grimberg @param[in] orients Array of orientation data 281b435c5a6Srezgarshakeri 282b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 283b435c5a6Srezgarshakeri 28477d1c127SSebastian Grimberg @ref User 285b435c5a6Srezgarshakeri **/ 28677d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 28777d1c127SSebastian Grimberg *orients = NULL; 28877d1c127SSebastian Grimberg rstr->num_readers--; 289b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 290b435c5a6Srezgarshakeri } 291b435c5a6Srezgarshakeri 292b435c5a6Srezgarshakeri /** 29377d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction curl-conforming orientations array by memtype 2947a982d89SJeremy L. Thompson 29577d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve curl-conforming orientations 296fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 297fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 29877d1c127SSebastian Grimberg @param[out] curl_orients Array on memory type mem_type 2997a982d89SJeremy L. Thompson 3007a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3017a982d89SJeremy L. Thompson 30277d1c127SSebastian Grimberg @ref User 3037a982d89SJeremy L. Thompson **/ 3040c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 305fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetCurlOrientations"); 30677d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 30777d1c127SSebastian Grimberg rstr->num_readers++; 30877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 30977d1c127SSebastian Grimberg } 31077d1c127SSebastian Grimberg 31177d1c127SSebastian Grimberg /** 31277d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetCurlOrientations() 31377d1c127SSebastian Grimberg 31477d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 31577d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 31677d1c127SSebastian Grimberg 31777d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 31877d1c127SSebastian Grimberg 31977d1c127SSebastian Grimberg @ref User 32077d1c127SSebastian Grimberg **/ 3210c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 32277d1c127SSebastian Grimberg *curl_orients = NULL; 32377d1c127SSebastian Grimberg rstr->num_readers--; 324e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3257a982d89SJeremy L. Thompson } 3267a982d89SJeremy L. Thompson 3277a982d89SJeremy L. Thompson /** 32849fd234cSJeremy L Thompson 32949fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 33049fd234cSJeremy L Thompson 331ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 332fcbe8c06SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 333fcbe8c06SSebastian 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] 33449fd234cSJeremy L Thompson 33549fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 33649fd234cSJeremy L Thompson 33749fd234cSJeremy L Thompson @ref Backend 33849fd234cSJeremy L Thompson **/ 3392b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 3406574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 3412b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 342e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 34349fd234cSJeremy L Thompson } 34449fd234cSJeremy L Thompson 34549fd234cSJeremy L Thompson /** 34649fd234cSJeremy L Thompson 34749fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 34849fd234cSJeremy L Thompson 349ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 350ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 351ea61e9acSJeremy 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] 35249fd234cSJeremy L Thompson 35349fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 35449fd234cSJeremy L Thompson 35549fd234cSJeremy L Thompson @ref Backend 35649fd234cSJeremy L Thompson **/ 3572b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 3582b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 359e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 36049fd234cSJeremy L Thompson } 36149fd234cSJeremy L Thompson 36249fd234cSJeremy L Thompson /** 3637a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3647a982d89SJeremy L. Thompson 365ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3667a982d89SJeremy L. Thompson @param[out] data Variable to store data 3677a982d89SJeremy L. Thompson 3687a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3697a982d89SJeremy L. Thompson 3707a982d89SJeremy L. Thompson @ref Backend 3717a982d89SJeremy L. Thompson **/ 372777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 373777ff853SJeremy L Thompson *(void **)data = rstr->data; 374e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3757a982d89SJeremy L. Thompson } 3767a982d89SJeremy L. Thompson 3777a982d89SJeremy L. Thompson /** 3787a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3797a982d89SJeremy L. Thompson 380ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 381ea61e9acSJeremy L Thompson @param[in] data Data to set 3827a982d89SJeremy L. Thompson 3837a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3847a982d89SJeremy L. Thompson 3857a982d89SJeremy L. Thompson @ref Backend 3867a982d89SJeremy L. Thompson **/ 387777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 388777ff853SJeremy L Thompson rstr->data = data; 389e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3907a982d89SJeremy L. Thompson } 3917a982d89SJeremy L. Thompson 39234359f16Sjeremylt /** 39334359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 39434359f16Sjeremylt 395ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 39634359f16Sjeremylt 39734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 39834359f16Sjeremylt 39934359f16Sjeremylt @ref Backend 40034359f16Sjeremylt **/ 4019560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 40234359f16Sjeremylt rstr->ref_count++; 40334359f16Sjeremylt return CEED_ERROR_SUCCESS; 40434359f16Sjeremylt } 40534359f16Sjeremylt 4066e15d496SJeremy L Thompson /** 4076e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 4086e15d496SJeremy L Thompson 409ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 410ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 411ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 4126e15d496SJeremy L Thompson 4136e15d496SJeremy L Thompson @ref Backend 4146e15d496SJeremy L Thompson **/ 4152b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 416e7f679fcSJeremy L Thompson CeedInt e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp, scale = 0; 41789edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 4181c66c397SJeremy L Thompson 41989edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 4203ac8f562SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) e_size = rstr->num_points * rstr->num_comp; 42177d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 42289edb9e3SSebastian Grimberg switch (rstr_type) { 4233ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 4243ac8f562SJeremy L Thompson scale = 0; 4253ac8f562SJeremy L Thompson break; 42689edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 42789edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 42877d1c127SSebastian Grimberg scale = 1; 42989edb9e3SSebastian Grimberg break; 43089edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 43177d1c127SSebastian Grimberg scale = 2; 43289edb9e3SSebastian Grimberg break; 43389edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 43477d1c127SSebastian Grimberg scale = 6; 43589edb9e3SSebastian Grimberg break; 4366e15d496SJeremy L Thompson } 43777d1c127SSebastian Grimberg } else { 43889edb9e3SSebastian Grimberg switch (rstr_type) { 43989edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 44089edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 4413ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 44277d1c127SSebastian Grimberg scale = 0; 44389edb9e3SSebastian Grimberg break; 44489edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 44577d1c127SSebastian Grimberg scale = 1; 44689edb9e3SSebastian Grimberg break; 44789edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 44877d1c127SSebastian Grimberg scale = 5; 44989edb9e3SSebastian Grimberg break; 45077d1c127SSebastian Grimberg } 45177d1c127SSebastian Grimberg } 4526e15d496SJeremy L Thompson *flops = e_size * scale; 4536e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 4546e15d496SJeremy L Thompson } 4556e15d496SJeremy L Thompson 4567a982d89SJeremy L. Thompson /// @} 4577a982d89SJeremy L. Thompson 45815910d16Sjeremylt /// @cond DOXYGEN_SKIP 45915910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 46015910d16Sjeremylt /// @endcond 46115910d16Sjeremylt 4627a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4637a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4647a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4657a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 466d7b241e6Sjeremylt /// @{ 467d7b241e6Sjeremylt 4687a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 46945f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4707a982d89SJeremy L. Thompson 471356036faSJeremy L Thompson /// Argument for CeedOperatorSetField indicating that the field does not requre a CeedElemRestriction 4722b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4737a982d89SJeremy L. Thompson 474d7b241e6Sjeremylt /** 475b11c1e72Sjeremylt @brief Create a CeedElemRestriction 476d7b241e6Sjeremylt 477ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 478ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 479ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 480ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 481fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 482fcbe8c06SSebastian 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. 483fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 484fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 485ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 486ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 487fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 488fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 489fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 490ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 491d7b241e6Sjeremylt 492b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 493dfdf5a53Sjeremylt 4947a982d89SJeremy L. Thompson @ref User 495b11c1e72Sjeremylt **/ 4962b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4972b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4985fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4995fe0d4faSjeremylt Ceed delegate; 5006574a04fSJeremy L Thompson 5012b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 50277d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5032b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 504e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5055fe0d4faSjeremylt } 5065fe0d4faSjeremylt 507e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 5086574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5096574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5106574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 511e022e1f8SJeremy L Thompson 5122b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 513db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 514d1d35e2fSjeremylt (*rstr)->ref_count = 1; 515d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 516d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 517d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 518d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 519d1d35e2fSjeremylt (*rstr)->l_size = l_size; 52005fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 521e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 522e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 52361a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 524fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 525e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 526d7b241e6Sjeremylt } 527d7b241e6Sjeremylt 528d7b241e6Sjeremylt /** 52977d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 530fc0567d9Srezgarshakeri 531ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 532ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 533ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 534ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 535fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 536fcbe8c06SSebastian 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. 537fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 538fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 539ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 540ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 541fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 542fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 543fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 54477d1c127SSebastian 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. 545ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 546fc0567d9Srezgarshakeri 547fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 548fc0567d9Srezgarshakeri 549fc0567d9Srezgarshakeri @ref User 550fc0567d9Srezgarshakeri **/ 5512b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 55277d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 553fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 554fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 555fc0567d9Srezgarshakeri Ceed delegate; 5566574a04fSJeremy L Thompson 5572b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 558fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5592b730f8bSJeremy L Thompson CeedCall( 56077d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 561fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 562fc0567d9Srezgarshakeri } 563fc0567d9Srezgarshakeri 564e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 5656574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5666574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5676574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 568e022e1f8SJeremy L Thompson 5692b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 570db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 571fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 572fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 573fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 574fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 575fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 576fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 57705fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 578e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 579e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 580fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 581fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 58277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 58377d1c127SSebastian Grimberg } 58477d1c127SSebastian Grimberg 58577d1c127SSebastian Grimberg /** 58677d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 58777d1c127SSebastian Grimberg 58877d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 58977d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 59077d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 59177d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 592fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 593fcbe8c06SSebastian 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. 594fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 595fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 59677d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 59777d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 598fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 599fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 600fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 6017c1dbaffSSebastian 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] 6027c1dbaffSSebastian 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 6037c1dbaffSSebastian 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, 6047c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 60577d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 60677d1c127SSebastian Grimberg 60777d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 60877d1c127SSebastian Grimberg 60977d1c127SSebastian Grimberg @ref User 61077d1c127SSebastian Grimberg **/ 61177d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 6120c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 61377d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 614fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 61577d1c127SSebastian Grimberg Ceed delegate; 61677d1c127SSebastian Grimberg 61777d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 618fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 61977d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 62077d1c127SSebastian Grimberg curl_orients, rstr)); 62177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 62277d1c127SSebastian Grimberg } 62377d1c127SSebastian Grimberg 624e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 62577d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 62677d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 62777d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 62877d1c127SSebastian Grimberg 62977d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 630fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 63177d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 63277d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 63377d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 63477d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 63577d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 63677d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 63705fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 638e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 639e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 640fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 641fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 642fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 643fc0567d9Srezgarshakeri } 644fc0567d9Srezgarshakeri 645fc0567d9Srezgarshakeri /** 6467509a596Sjeremylt @brief Create a strided CeedElemRestriction 647d7b241e6Sjeremylt 648ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 649ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 650ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 651ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 652fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 653fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 654fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 655fcbe8c06SSebastian 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]. 656fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 657ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 658d7b241e6Sjeremylt 659b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 660dfdf5a53Sjeremylt 6617a982d89SJeremy L. Thompson @ref User 662b11c1e72Sjeremylt **/ 6632b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 664f90c8643Sjeremylt CeedElemRestriction *rstr) { 6655fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6665fe0d4faSjeremylt Ceed delegate; 667b04eb3d9SSebastian Grimberg 6682b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 669fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6702b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 671e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6725fe0d4faSjeremylt } 6735fe0d4faSjeremylt 674e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6756574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6766574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 677e7f679fcSJeremy 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"); 678e022e1f8SJeremy L Thompson 6792b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 680db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 681d1d35e2fSjeremylt (*rstr)->ref_count = 1; 682d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 683d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 684d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 685d1d35e2fSjeremylt (*rstr)->l_size = l_size; 68605fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 687e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 688e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 689fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6902b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6912b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 692fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 693e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 694d7b241e6Sjeremylt } 695d7b241e6Sjeremylt 696d7b241e6Sjeremylt /** 6973ac8f562SJeremy L Thompson @brief Create a points CeedElemRestriction, for restricting for restricting from a all local points to the current element in which they are 6983ac8f562SJeremy L Thompson located. 6993ac8f562SJeremy L Thompson 7003ac8f562SJeremy L Thompson The offsets array is arranged as 7013ac8f562SJeremy L Thompson 7023ac8f562SJeremy L Thompson element_0_start_index 7033ac8f562SJeremy L Thompson element_1_start_index 7043ac8f562SJeremy L Thompson ... 7053ac8f562SJeremy L Thompson element_n_start_index 7063ac8f562SJeremy L Thompson element_n_stop_index 7073ac8f562SJeremy L Thompson element_0_point_0 7083ac8f562SJeremy L Thompson element_0_point_1 7093ac8f562SJeremy L Thompson ... 7103ac8f562SJeremy L Thompson 7113ac8f562SJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 7123ac8f562SJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 7133ac8f562SJeremy L Thompson @param[in] num_points Number of points described in the @a offsets array 7143ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 7153ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 7163ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 7173ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 7183ac8f562SJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 7193ac8f562SJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 7203ac8f562SJeremy L Thompson @param[in] offsets Array of size num_elem + 1 + num_points. 7213ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 7223ac8f562SJeremy L Thompson The second portion holds the indices for each element. 7233ac8f562SJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 7243ac8f562SJeremy L Thompson 7253ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7263ac8f562SJeremy L Thompson 7273ac8f562SJeremy L Thompson @ref Backend 7283ac8f562SJeremy L Thompson **/ 7293ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 7303ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 7313ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 7323ac8f562SJeremy L Thompson Ceed delegate; 7333ac8f562SJeremy L Thompson 7343ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 7353ac8f562SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateAtPoints"); 7363ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 7373ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 7383ac8f562SJeremy L Thompson } 7393ac8f562SJeremy L Thompson 7403ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7413ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 7423ac8f562SJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 7433ac8f562SJeremy L Thompson CeedCheck(l_size >= num_points * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector must be at least num_points * num_comp"); 7443ac8f562SJeremy L Thompson 7453ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 7463ac8f562SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 7473ac8f562SJeremy L Thompson (*rstr)->ref_count = 1; 7483ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 7493ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 7503ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 7513ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 75205fa913cSJeremy L Thompson (*rstr)->e_size = num_points * num_comp; 75305fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 7543ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 7553ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 7563ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 7573ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 7583ac8f562SJeremy L Thompson } 7593ac8f562SJeremy L Thompson 7603ac8f562SJeremy L Thompson /** 761b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 762d7b241e6Sjeremylt 7633ac8f562SJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 7643ac8f562SJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 765ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 766e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 767ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 768fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 769fcbe8c06SSebastian 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. 770fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 771fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 772ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 773ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 774fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 775e7f679fcSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 776e7f679fcSJeremy 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 777e7f679fcSJeremy L Thompson for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 778ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 779d7b241e6Sjeremylt 780b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 781dfdf5a53Sjeremylt 7827a982d89SJeremy L. Thompson @ref Backend 783b11c1e72Sjeremylt **/ 784e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 7852b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 7864ce2993fSjeremylt CeedElemRestriction *rstr) { 7871c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 788d7b241e6Sjeremylt 7895fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 7905fe0d4faSjeremylt Ceed delegate; 7916574a04fSJeremy L Thompson 7922b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 7936402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 794e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 795e7f679fcSJeremy L Thompson rstr)); 796e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7975fe0d4faSjeremylt } 798d7b241e6Sjeremylt 799e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8006574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 801e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 8026574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 8036574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 804e022e1f8SJeremy L Thompson 805e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 806e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 807d7b241e6Sjeremylt 808db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 809db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 810d1d35e2fSjeremylt (*rstr)->ref_count = 1; 811d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 812d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 813d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 814d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 815d1d35e2fSjeremylt (*rstr)->l_size = l_size; 81605fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 817e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 818e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 81961a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 820e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 8211c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 822e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 823d7b241e6Sjeremylt } 824d7b241e6Sjeremylt 825b11c1e72Sjeremylt /** 82677d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 82777d1c127SSebastian Grimberg 82877d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 82977d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 83077d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 831e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 83277d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 833fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 834fcbe8c06SSebastian 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. 835fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 836fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 83777d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 83877d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 839fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 840fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 841fcbe8c06SSebastian 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 842fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 843fcbe8c06SSebastian 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. 844fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 84577d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 84677d1c127SSebastian Grimberg 84777d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 84877d1c127SSebastian Grimberg 84977d1c127SSebastian Grimberg @ref Backend 85077d1c127SSebastian Grimberg **/ 851e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 852e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 853e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 854e7f679fcSJeremy L Thompson bool *block_orients; 8551c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 85677d1c127SSebastian Grimberg 857fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 85877d1c127SSebastian Grimberg Ceed delegate; 85977d1c127SSebastian Grimberg 86077d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 861fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 862e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 86377d1c127SSebastian Grimberg offsets, orients, rstr)); 86477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 86577d1c127SSebastian Grimberg } 86677d1c127SSebastian Grimberg 86777d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 868e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 86977d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 87077d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 87177d1c127SSebastian Grimberg 872e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 873e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 874e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 875e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 87677d1c127SSebastian Grimberg 877fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 878fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 87977d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 88077d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 88177d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 88277d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 88377d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 88477d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 88505fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 886e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 887e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 888fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 889e7f679fcSJeremy L Thompson CeedCall( 890e7f679fcSJeremy L Thompson ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, *rstr)); 8911c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 89277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 89377d1c127SSebastian Grimberg } 89477d1c127SSebastian Grimberg 89577d1c127SSebastian Grimberg /** 89677d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 89777d1c127SSebastian Grimberg 89877d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 89977d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 90077d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 901e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 90277d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 903fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 904fcbe8c06SSebastian 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. 905fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 906fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 90777d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 90877d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 909fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 910fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 911fcbe8c06SSebastian 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 912fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 9137c1dbaffSSebastian 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] 9147c1dbaffSSebastian 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 9157c1dbaffSSebastian 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, 9167c1dbaffSSebastian 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 9177c1dbaffSSebastian Grimberg similarly to @a offsets. 91877d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 91977d1c127SSebastian Grimberg 92077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 92177d1c127SSebastian Grimberg 92277d1c127SSebastian Grimberg @ref Backend 92377d1c127SSebastian Grimberg **/ 924e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 92577d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 9260c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 927e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 9281c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 92977d1c127SSebastian Grimberg 930fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 93177d1c127SSebastian Grimberg Ceed delegate; 93277d1c127SSebastian Grimberg 93377d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 934fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 935e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 936e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 93777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 93877d1c127SSebastian Grimberg } 93977d1c127SSebastian Grimberg 940e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 94177d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 942e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 94377d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 94477d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 94577d1c127SSebastian Grimberg 946e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 947e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 948e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 949e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 95077d1c127SSebastian Grimberg 951fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 952fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 95377d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 95477d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 95577d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 95677d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 95777d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 95877d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 95905fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 960e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 961e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 962fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 963e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 964e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 9651c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 96677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 96777d1c127SSebastian Grimberg } 96877d1c127SSebastian Grimberg 96977d1c127SSebastian Grimberg /** 97077d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 9717509a596Sjeremylt 972ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 973ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 974ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 975e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 976ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 977fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 978fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 979fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 980fcbe8c06SSebastian 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]. 981fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 982ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 9837509a596Sjeremylt 9847509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 9857509a596Sjeremylt 9867a982d89SJeremy L. Thompson @ref User 9877509a596Sjeremylt **/ 988e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 9898621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 990e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 9917509a596Sjeremylt 9927509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 9937509a596Sjeremylt Ceed delegate; 9946574a04fSJeremy L Thompson 9952b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 996fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 997e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 998e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9997509a596Sjeremylt } 10007509a596Sjeremylt 1001e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 10026574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1003e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 10046574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 1005e7f679fcSJeremy 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"); 1006e022e1f8SJeremy L Thompson 10072b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 1008db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 1009d1d35e2fSjeremylt (*rstr)->ref_count = 1; 1010d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 1011d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 1012d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 1013d1d35e2fSjeremylt (*rstr)->l_size = l_size; 101405fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 1015e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1016e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1017fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 10182b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 10192b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 1020fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 1021e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10227509a596Sjeremylt } 10237509a596Sjeremylt 10247509a596Sjeremylt /** 10257c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unsigned version. 1026c17ec2beSJeremy L Thompson 1027c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 1028c17ec2beSJeremy L Thompson 1029c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 1030c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 1031c17ec2beSJeremy L Thompson 1032c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1033c17ec2beSJeremy L Thompson 1034c17ec2beSJeremy L Thompson @ref User 1035c17ec2beSJeremy L Thompson **/ 1036c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1037c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1038c17ec2beSJeremy L Thompson 1039c17ec2beSJeremy L Thompson // Copy old rstr 1040c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1041c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 1042c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 1043c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 1044c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1045c17ec2beSJeremy L Thompson if (rstr->strides) { 1046c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1047c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1048c17ec2beSJeremy L Thompson } 10497c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1050c17ec2beSJeremy L Thompson 1051c17ec2beSJeremy L Thompson // Override Apply 1052c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1053c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1054c17ec2beSJeremy L Thompson } 1055c17ec2beSJeremy L Thompson 1056c17ec2beSJeremy L Thompson /** 10577c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unoriented version. 10587c1dbaffSSebastian Grimberg 10597c1dbaffSSebastian Grimberg Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 10607c1dbaffSSebastian Grimberg 10617c1dbaffSSebastian Grimberg @param[in] rstr CeedElemRestriction to create unoriented reference to 10627c1dbaffSSebastian Grimberg @param[in,out] rstr_unoriented Variable to store unoriented CeedElemRestriction 10637c1dbaffSSebastian Grimberg 10647c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 10657c1dbaffSSebastian Grimberg 10667c1dbaffSSebastian Grimberg @ref User 10677c1dbaffSSebastian Grimberg **/ 10687c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 10697c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 10707c1dbaffSSebastian Grimberg 10717c1dbaffSSebastian Grimberg // Copy old rstr 10727c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 10737c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 10747c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 10757c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 10767c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 10777c1dbaffSSebastian Grimberg if (rstr->strides) { 10787c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 10797c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 10807c1dbaffSSebastian Grimberg } 10817c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 10827c1dbaffSSebastian Grimberg 10837c1dbaffSSebastian Grimberg // Override Apply 10847c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 10857c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 10867c1dbaffSSebastian Grimberg } 10877c1dbaffSSebastian Grimberg 10887c1dbaffSSebastian Grimberg /** 1089ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 10909fd66db6SSebastian Grimberg 1091ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 10929560d06aSjeremylt 10939fd66db6SSebastian 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. 10949fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 1095ea61e9acSJeremy L Thompson 1096ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 1097ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 10989560d06aSjeremylt 10999560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 11009560d06aSjeremylt 11019560d06aSjeremylt @ref User 11029560d06aSjeremylt **/ 11032b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1104393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 11052b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 11069560d06aSjeremylt *rstr_copy = rstr; 11079560d06aSjeremylt return CEED_ERROR_SUCCESS; 11089560d06aSjeremylt } 11099560d06aSjeremylt 11109560d06aSjeremylt /** 1111b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 1112b11c1e72Sjeremylt 1113ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1114ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 1115ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 1116b11c1e72Sjeremylt 1117b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1118dfdf5a53Sjeremylt 11197a982d89SJeremy L. Thompson @ref User 1120b11c1e72Sjeremylt **/ 11212b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1122d2643443SJeremy L Thompson CeedSize e_size, l_size; 1123*48acf710SJeremy L Thompson 1124d1d35e2fSjeremylt l_size = rstr->l_size; 1125*48acf710SJeremy L Thompson if (rstr->rstr_type == CEED_RESTRICTION_POINTS) { 1126*48acf710SJeremy L Thompson e_size = rstr->num_points * rstr->num_comp; 1127*48acf710SJeremy L Thompson } else { 1128e7f679fcSJeremy L Thompson e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp; 1129*48acf710SJeremy L Thompson } 11302b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 11312b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 1132e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1133d7b241e6Sjeremylt } 1134d7b241e6Sjeremylt 1135d7b241e6Sjeremylt /** 1136d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1137d7b241e6Sjeremylt 1138ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1139ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1140ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1141fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1142fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1143ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1144b11c1e72Sjeremylt 1145b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1146dfdf5a53Sjeremylt 11477a982d89SJeremy L. Thompson @ref User 1148b11c1e72Sjeremylt **/ 11492b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1150d7b241e6Sjeremylt CeedInt m, n; 1151d7b241e6Sjeremylt 1152d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 115305fa913cSJeremy L Thompson m = rstr->e_size; 1154d1d35e2fSjeremylt n = rstr->l_size; 1155d7b241e6Sjeremylt } else { 1156d1d35e2fSjeremylt m = rstr->l_size; 115705fa913cSJeremy L Thompson n = rstr->e_size; 1158d7b241e6Sjeremylt } 115905fa913cSJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11606574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 116105fa913cSJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11626574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 11632b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1164e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1165d7b241e6Sjeremylt } 1166d7b241e6Sjeremylt 1167d7b241e6Sjeremylt /** 11683ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 11693ac8f562SJeremy L Thompson 11703ac8f562SJeremy L Thompson @param[in] rstr CeedElemRestriction 11716cec60aaSJed Brown @param[in] elem Element number in range 0..@a num_elem 11723ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 11733ac8f562SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 11746595d053SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_points * @a num_comp] when t_mode=@ref CEED_NOTRANSPOSE). 11753ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 11763ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 11773ac8f562SJeremy L Thompson 11783ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11793ac8f562SJeremy L Thompson 11803ac8f562SJeremy L Thompson @ref User 11813ac8f562SJeremy L Thompson **/ 118205fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 11833ac8f562SJeremy L Thompson CeedRequest *request) { 11843ac8f562SJeremy L Thompson CeedInt m, n; 11853ac8f562SJeremy L Thompson 11863ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 11873ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &m)); 11883ac8f562SJeremy L Thompson n = rstr->l_size; 11893ac8f562SJeremy L Thompson } else { 11903ac8f562SJeremy L Thompson m = rstr->l_size; 11913ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &n)); 11923ac8f562SJeremy L Thompson } 11933ac8f562SJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11943ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 11953ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 11963ac8f562SJeremy L Thompson u->length, m, n, elem); 11973ac8f562SJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11983ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 11993ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 12003ac8f562SJeremy L Thompson ru->length, m, n, elem); 12010930e4e7SJeremy L Thompson CeedCheck(elem < rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 12023ac8f562SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, rstr->num_elem); 120305fa913cSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 12043ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 12053ac8f562SJeremy L Thompson } 12063ac8f562SJeremy L Thompson 12073ac8f562SJeremy L Thompson /** 1208d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1209be9261b7Sjeremylt 1210ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1211e7f679fcSJeremy 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 1212e7f679fcSJeremy L Thompson [3*block_size : 4*block_size] 1213ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1214ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1215e7f679fcSJeremy L Thompson @param[out] ru Output vector (of shape [@a block_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1216fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1217ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1218be9261b7Sjeremylt 1219be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1220be9261b7Sjeremylt 12217a982d89SJeremy L. Thompson @ref Backend 1222be9261b7Sjeremylt **/ 12232b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 12242b730f8bSJeremy L Thompson CeedRequest *request) { 1225be9261b7Sjeremylt CeedInt m, n; 1226be9261b7Sjeremylt 12276402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 12286402da51SJeremy L Thompson 1229d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1230e7f679fcSJeremy L Thompson m = rstr->block_size * rstr->elem_size * rstr->num_comp; 1231d1d35e2fSjeremylt n = rstr->l_size; 1232be9261b7Sjeremylt } else { 1233d1d35e2fSjeremylt m = rstr->l_size; 1234e7f679fcSJeremy L Thompson n = rstr->block_size * rstr->elem_size * rstr->num_comp; 1235be9261b7Sjeremylt } 12366574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 12376574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 12386574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 12396574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 1240e7f679fcSJeremy L Thompson CeedCheck(rstr->block_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 1241e7f679fcSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->block_size * block, 12426574a04fSJeremy L Thompson rstr->num_elem); 12432b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1244e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1245be9261b7Sjeremylt } 1246be9261b7Sjeremylt 1247be9261b7Sjeremylt /** 1248b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1249b7c9bbdaSJeremy L Thompson 1250ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1251b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1252b7c9bbdaSJeremy L Thompson 1253b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1254b7c9bbdaSJeremy L Thompson 1255b7c9bbdaSJeremy L Thompson @ref Advanced 1256b7c9bbdaSJeremy L Thompson **/ 1257b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1258b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1259b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1260b7c9bbdaSJeremy L Thompson } 1261b7c9bbdaSJeremy L Thompson 1262b7c9bbdaSJeremy L Thompson /** 1263d979a051Sjeremylt @brief Get the L-vector component stride 1264a681ae63Sjeremylt 1265ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1266d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1267a681ae63Sjeremylt 1268a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1269a681ae63Sjeremylt 1270b7c9bbdaSJeremy L Thompson @ref Advanced 1271a681ae63Sjeremylt **/ 12722b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1273d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1274e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1275a681ae63Sjeremylt } 1276a681ae63Sjeremylt 1277a681ae63Sjeremylt /** 1278a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1279a681ae63Sjeremylt 1280ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1281d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1282a681ae63Sjeremylt 1283a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1284a681ae63Sjeremylt 1285b7c9bbdaSJeremy L Thompson @ref Advanced 1286a681ae63Sjeremylt **/ 12872b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1288d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1289e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1290a681ae63Sjeremylt } 1291a681ae63Sjeremylt 1292a681ae63Sjeremylt /** 1293a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1294a681ae63Sjeremylt 1295ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1296d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1297a681ae63Sjeremylt 1298a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1299a681ae63Sjeremylt 1300b7c9bbdaSJeremy L Thompson @ref Advanced 1301a681ae63Sjeremylt **/ 13022b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1303d1d35e2fSjeremylt *elem_size = rstr->elem_size; 13042c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 13052c7e7413SJeremy L Thompson } 13062c7e7413SJeremy L Thompson 13072c7e7413SJeremy L Thompson /** 130807d5dec1SJeremy L Thompson 130907d5dec1SJeremy L Thompson @brief Get the number of points in the l-vector for a points CeedElemRestriction 131007d5dec1SJeremy L Thompson 131107d5dec1SJeremy L Thompson @param[in] rstr CeedElemRestriction 131207d5dec1SJeremy L Thompson @param[out] num_points The number of points in the l-vector 131307d5dec1SJeremy L Thompson 131407d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 131507d5dec1SJeremy L Thompson 1316c63574e3SJeremy L Thompson @ref User 131707d5dec1SJeremy L Thompson **/ 131807d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) { 131907d5dec1SJeremy L Thompson Ceed ceed; 132007d5dec1SJeremy L Thompson 132107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 132207d5dec1SJeremy L Thompson CeedCheck(rstr->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 132307d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 132407d5dec1SJeremy L Thompson 132507d5dec1SJeremy L Thompson *num_points = rstr->num_points; 132607d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 132707d5dec1SJeremy L Thompson } 132807d5dec1SJeremy L Thompson 132907d5dec1SJeremy L Thompson /** 133007d5dec1SJeremy L Thompson 133107d5dec1SJeremy L Thompson @brief Get the number of points in an element of a points CeedElemRestriction 133207d5dec1SJeremy L Thompson 133307d5dec1SJeremy L Thompson @param[in] rstr CeedElemRestriction 133407d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 133507d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 133607d5dec1SJeremy L Thompson 133707d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 133807d5dec1SJeremy L Thompson 1339c63574e3SJeremy L Thompson @ref User 134007d5dec1SJeremy L Thompson **/ 134107d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 134207d5dec1SJeremy L Thompson Ceed ceed; 134307d5dec1SJeremy L Thompson const CeedInt *offsets; 134407d5dec1SJeremy L Thompson 134507d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 134607d5dec1SJeremy L Thompson CeedCheck(rstr->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 134707d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 134807d5dec1SJeremy L Thompson 134907d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 135007d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem]; 135107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 135207d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 135307d5dec1SJeremy L Thompson } 135407d5dec1SJeremy L Thompson 135507d5dec1SJeremy L Thompson /** 13562c7e7413SJeremy L Thompson @brief Get the maximum number of points in an element for a CeedElemRestriction at points 13572c7e7413SJeremy L Thompson 13582c7e7413SJeremy L Thompson @param[in] rstr CeedElemRestriction 13592c7e7413SJeremy L Thompson @param[out] max_points Variable to store size of elements 13602c7e7413SJeremy L Thompson 13612c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13622c7e7413SJeremy L Thompson 13632c7e7413SJeremy L Thompson @ref Advanced 13642c7e7413SJeremy L Thompson **/ 13652c7e7413SJeremy L Thompson int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 13662c7e7413SJeremy L Thompson Ceed ceed; 13672c7e7413SJeremy L Thompson CeedInt num_elem; 13682c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 13692c7e7413SJeremy L Thompson 13702c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 13712c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 13722c7e7413SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 13732c7e7413SJeremy L Thompson "Cannot compute max points for a CeedElemRestriction that does not use points"); 13742c7e7413SJeremy L Thompson 13752c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 13762c7e7413SJeremy L Thompson *max_points = 0; 13772c7e7413SJeremy L Thompson for (CeedInt e = 0; e < num_elem; e++) { 13782c7e7413SJeremy L Thompson CeedInt num_points; 13792c7e7413SJeremy L Thompson 13802c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 13812c7e7413SJeremy L Thompson *max_points = CeedIntMax(num_points, *max_points); 13822c7e7413SJeremy L Thompson } 1383e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1384a681ae63Sjeremylt } 1385a681ae63Sjeremylt 1386a681ae63Sjeremylt /** 1387d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1388a681ae63Sjeremylt 1389ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1390d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1391a681ae63Sjeremylt 1392a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1393a681ae63Sjeremylt 1394b7c9bbdaSJeremy L Thompson @ref Advanced 1395a681ae63Sjeremylt **/ 13962b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1397d1d35e2fSjeremylt *l_size = rstr->l_size; 1398e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1399a681ae63Sjeremylt } 1400a681ae63Sjeremylt 1401a681ae63Sjeremylt /** 1402ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1403a681ae63Sjeremylt 1404ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1405d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1406a681ae63Sjeremylt 1407a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1408a681ae63Sjeremylt 1409b7c9bbdaSJeremy L Thompson @ref Advanced 1410a681ae63Sjeremylt **/ 14112b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1412d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1413e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1414a681ae63Sjeremylt } 1415a681ae63Sjeremylt 1416a681ae63Sjeremylt /** 1417a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1418a681ae63Sjeremylt 1419ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1420d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1421a681ae63Sjeremylt 1422a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1423a681ae63Sjeremylt 1424b7c9bbdaSJeremy L Thompson @ref Advanced 1425a681ae63Sjeremylt **/ 14262b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1427e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1428e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1429a681ae63Sjeremylt } 1430a681ae63Sjeremylt 1431a681ae63Sjeremylt /** 1432a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1433a681ae63Sjeremylt 1434ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1435e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1436a681ae63Sjeremylt 1437a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1438a681ae63Sjeremylt 1439b7c9bbdaSJeremy L Thompson @ref Advanced 1440a681ae63Sjeremylt **/ 1441e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1442e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1443e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1444a681ae63Sjeremylt } 1445a681ae63Sjeremylt 1446a681ae63Sjeremylt /** 1447d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 14481469ee4dSjeremylt 1449ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1450d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 14511469ee4dSjeremylt 14521469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 14531469ee4dSjeremylt 14547a982d89SJeremy L. Thompson @ref User 14551469ee4dSjeremylt **/ 14562b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1457d1d35e2fSjeremylt CeedVector e_vec; 14581469ee4dSjeremylt 145925509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 14602b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 14611469ee4dSjeremylt 146225509ebbSRezgar Shakeri // Compute e_vec = E * 1 14632b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 14642b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 146525509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 14662b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 14672b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 14681469ee4dSjeremylt // Cleanup 14692b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1470e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 14711469ee4dSjeremylt } 14721469ee4dSjeremylt 14731469ee4dSjeremylt /** 1474f02ca4a2SJed Brown @brief View a CeedElemRestriction 1475f02ca4a2SJed Brown 1476f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1477f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1478f02ca4a2SJed Brown 1479f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1480f02ca4a2SJed Brown 14817a982d89SJeremy L. Thompson @ref User 1482f02ca4a2SJed Brown **/ 1483f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 14840930e4e7SJeremy L Thompson CeedRestrictionType rstr_type; 14850930e4e7SJeremy L Thompson 14860930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 14870930e4e7SJeremy L Thompson 14880930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 14890930e4e7SJeremy L Thompson CeedInt max_points; 14900930e4e7SJeremy L Thompson 14910930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points)); 14920930e4e7SJeremy L Thompson fprintf(stream, 14930930e4e7SJeremy L Thompson "CeedElemRestriction at points from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT 14940930e4e7SJeremy L Thompson " points on an element\n", 14950930e4e7SJeremy L Thompson rstr->l_size, rstr->num_comp, rstr->num_elem, max_points); 14960930e4e7SJeremy L Thompson } else { 14977509a596Sjeremylt char stridesstr[500]; 14981c66c397SJeremy L Thompson 14992b730f8bSJeremy L Thompson if (rstr->strides) { 15002b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 15012b730f8bSJeremy L Thompson } else { 1502990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 15032b730f8bSJeremy L Thompson } 15042b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 1505e7f679fcSJeremy L Thompson rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1506d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 15070930e4e7SJeremy L Thompson } 1508e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1509f02ca4a2SJed Brown } 1510f02ca4a2SJed Brown 1511f02ca4a2SJed Brown /** 1512b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1513b11c1e72Sjeremylt 1514ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1515b11c1e72Sjeremylt 1516b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1517dfdf5a53Sjeremylt 15187a982d89SJeremy L. Thompson @ref User 1519b11c1e72Sjeremylt **/ 15204ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1521393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1522ad6481ceSJeremy L Thompson *rstr = NULL; 1523ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1524ad6481ceSJeremy L Thompson } 15256574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 15266574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1527c17ec2beSJeremy L Thompson 1528c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 15297c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1530c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1531c17ec2beSJeremy L Thompson 15322b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 15332b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 15342b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1535e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1536d7b241e6Sjeremylt } 1537d7b241e6Sjeremylt 1538d7b241e6Sjeremylt /// @} 1539