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 /** 25ca94c3ddSJeremy L Thompson @brief Permute and pad offsets for a blocked `CeedElemRestriction` 267a982d89SJeremy L. Thompson 27ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]` 28ca94c3ddSJeremy L Thompson @param[out] block_offsets Array of permuted and padded array values of shape `[num_block, elem_size, 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 /** 51ca94c3ddSJeremy L Thompson @brief Permute and pad orientations for a blocked `CeedElemRestriction` 5277d1c127SSebastian Grimberg 53ca94c3ddSJeremy L Thompson @param[in] orients Array of shape `[num_elem, elem_size]` 54ca94c3ddSJeremy L Thompson @param[out] block_orients Array of permuted and padded array values of shape `[num_block, elem_size, 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 /** 76ca94c3ddSJeremy L Thompson @brief Permute and pad curl-conforming orientations for a blocked `CeedElemRestriction` 770c73c039SSebastian Grimberg 785c7e0f51SSebastian Grimberg @param[in] curl_orients Array of shape `[num_elem, elem_size]` 79ca94c3ddSJeremy L Thompson @param[out] block_curl_orients Array of permuted and padded array values of shape `[num_block, elem_size, 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 /** 110ca94c3ddSJeremy L Thompson @brief Get the type of a `CeedElemRestriction` 111a681ae63Sjeremylt 112ca94c3ddSJeremy L Thompson @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 /** 125ca94c3ddSJeremy L Thompson @brief Get the strided status of a `CeedElemRestriction` 126fcbe8c06SSebastian Grimberg 127ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 128ca94c3ddSJeremy L Thompson @param[out] is_strided Variable to store strided status 129ca94c3ddSJeremy L Thompson 130ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 131ca94c3ddSJeremy L Thompson 132ca94c3ddSJeremy L Thompson @ref Backend 133fcbe8c06SSebastian Grimberg **/ 134fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 135fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 136fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 137fcbe8c06SSebastian Grimberg } 138fcbe8c06SSebastian Grimberg 139fcbe8c06SSebastian Grimberg /** 140ca94c3ddSJeremy L Thompson @brief Get the points status of a `CeedElemRestriction` 1413ac8f562SJeremy L Thompson 142ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 143ca94c3ddSJeremy L Thompson @param[out] is_points Variable to store points status 144ca94c3ddSJeremy L Thompson 145ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 146ca94c3ddSJeremy L Thompson 147ca94c3ddSJeremy L Thompson @ref Backend 1483ac8f562SJeremy L Thompson **/ 1493ac8f562SJeremy L Thompson int CeedElemRestrictionIsPoints(CeedElemRestriction rstr, bool *is_points) { 1503ac8f562SJeremy L Thompson *is_points = (rstr->rstr_type == CEED_RESTRICTION_POINTS); 1513ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 1523ac8f562SJeremy L Thompson } 1533ac8f562SJeremy L Thompson 1543ac8f562SJeremy L Thompson /** 155ca94c3ddSJeremy L Thompson @brief Check if two `CeedElemRestriction` created with @ref CeedElemRestrictionCreateAtPoints() and use the same points per element 15648acf710SJeremy L Thompson 157ca94c3ddSJeremy L Thompson @param[in] rstr_a First `CeedElemRestriction` 158ca94c3ddSJeremy L Thompson @param[in] rstr_b Second `CeedElemRestriction` 15948acf710SJeremy L Thompson @param[out] are_compatible Variable to store compatibility status 160ca94c3ddSJeremy L Thompson 161ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 162ca94c3ddSJeremy L Thompson 163ca94c3ddSJeremy L Thompson @ref Backend 16448acf710SJeremy L Thompson **/ 16548acf710SJeremy L Thompson int CeedElemRestrictionAtPointsAreCompatible(CeedElemRestriction rstr_a, CeedElemRestriction rstr_b, bool *are_compatible) { 16648acf710SJeremy L Thompson CeedInt num_elem_a, num_elem_b, num_points_a, num_points_b; 16748acf710SJeremy L Thompson 16848acf710SJeremy L Thompson // Cannot compare non-points restrictions 169ca94c3ddSJeremy L Thompson CeedCheck(rstr_a->rstr_type == CEED_RESTRICTION_POINTS, rstr_a->ceed, CEED_ERROR_UNSUPPORTED, "First CeedElemRestriction must be AtPoints"); 170ca94c3ddSJeremy L Thompson CeedCheck(rstr_b->rstr_type == CEED_RESTRICTION_POINTS, rstr_b->ceed, CEED_ERROR_UNSUPPORTED, "Second CeedElemRestriction must be AtPoints"); 17148acf710SJeremy L Thompson 17248acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_a, &num_elem_a)); 17348acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_b, &num_elem_b)); 17448acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_a, &num_points_a)); 17548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_b, &num_points_b)); 17648acf710SJeremy L Thompson 17748acf710SJeremy L Thompson // Check size and contents of offsets arrays 17848acf710SJeremy L Thompson *are_compatible = true; 17948acf710SJeremy L Thompson if (num_elem_a != num_elem_b) *are_compatible = false; 18048acf710SJeremy L Thompson if (num_points_a != num_points_b) *are_compatible = false; 18148acf710SJeremy L Thompson if (*are_compatible) { 18248acf710SJeremy L Thompson const CeedInt *offsets_a, *offsets_b; 18348acf710SJeremy L Thompson 18448acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_a, CEED_MEM_HOST, &offsets_a)); 18548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_b, CEED_MEM_HOST, &offsets_b)); 18648acf710SJeremy L Thompson for (CeedInt i = 0; i < num_elem_a + 1 + num_points_a; i++) *are_compatible &= offsets_a[i] == offsets_b[i]; 18748acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_a, &offsets_a)); 18848acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_b, &offsets_b)); 18948acf710SJeremy L Thompson } 19048acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 19148acf710SJeremy L Thompson } 19248acf710SJeremy L Thompson 19348acf710SJeremy L Thompson /** 194ca94c3ddSJeremy L Thompson @brief Get the strides of a strided `CeedElemRestriction` 1957a982d89SJeremy L. Thompson 196ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 197a681ae63Sjeremylt @param[out] strides Variable to store strides array 1987a982d89SJeremy L. Thompson 1997a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2007a982d89SJeremy L. Thompson 2017a982d89SJeremy L. Thompson @ref Backend 2027a982d89SJeremy L. Thompson **/ 2032b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 204ca94c3ddSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 2052b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 206e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2077a982d89SJeremy L. Thompson } 2087a982d89SJeremy L. Thompson 2097a982d89SJeremy L. Thompson /** 210ca94c3ddSJeremy L Thompson @brief Get the backend stride status of a `CeedElemRestriction` 21177d1c127SSebastian Grimberg 212ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 21377d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 21477d1c127SSebastian Grimberg 21577d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 21677d1c127SSebastian Grimberg 21777d1c127SSebastian Grimberg @ref Backend 21877d1c127SSebastian Grimberg **/ 21977d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 220ca94c3ddSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 22177d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 22277d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 22377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 22477d1c127SSebastian Grimberg } 22577d1c127SSebastian Grimberg 22677d1c127SSebastian Grimberg /** 227ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` offsets array by @ref CeedMemType 228bd33150aSjeremylt 229ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve offsets 230fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 231fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 232ca94c3ddSJeremy L Thompson @param[out] offsets Array on memory type `mem_type` 233bd33150aSjeremylt 234bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 235bd33150aSjeremylt 236bd33150aSjeremylt @ref User 237bd33150aSjeremylt **/ 2382b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 2397c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2407c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 241c17ec2beSJeremy L Thompson } else { 242ca94c3ddSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedElemRestrictionGetOffsets"); 2432b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 244d1d35e2fSjeremylt rstr->num_readers++; 245c17ec2beSJeremy L Thompson } 246e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 247430758c8SJeremy L Thompson } 248430758c8SJeremy L Thompson 249430758c8SJeremy L Thompson /** 250ca94c3ddSJeremy L Thompson @brief Restore an offsets array obtained using @ref CeedElemRestrictionGetOffsets() 251430758c8SJeremy L Thompson 252ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 253ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 254430758c8SJeremy L Thompson 255430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 256430758c8SJeremy L Thompson 257430758c8SJeremy L Thompson @ref User 258430758c8SJeremy L Thompson **/ 2592b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2607c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2617c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 262c17ec2beSJeremy L Thompson } else { 263430758c8SJeremy L Thompson *offsets = NULL; 264d1d35e2fSjeremylt rstr->num_readers--; 265c17ec2beSJeremy L Thompson } 266e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 267bd33150aSjeremylt } 268bd33150aSjeremylt 269bd33150aSjeremylt /** 270ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` orientations array by @ref CeedMemType 2713ac43b2cSJeremy L Thompson 272ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve orientations 273fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 274fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 275ca94c3ddSJeremy L Thompson @param[out] orients Array on memory type `mem_type` 2763ac43b2cSJeremy L Thompson 2773ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2783ac43b2cSJeremy L Thompson 27977d1c127SSebastian Grimberg @ref User 2803ac43b2cSJeremy L Thompson **/ 28177d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 282ca94c3ddSJeremy L Thompson CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedElemRestrictionGetOrientations"); 28377d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 28477d1c127SSebastian Grimberg rstr->num_readers++; 285e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2863ac43b2cSJeremy L Thompson } 2873ac43b2cSJeremy L Thompson 2883ac43b2cSJeremy L Thompson /** 289ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetOrientations() 290b435c5a6Srezgarshakeri 291ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 29277d1c127SSebastian Grimberg @param[in] orients Array of orientation data 293b435c5a6Srezgarshakeri 294b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 295b435c5a6Srezgarshakeri 29677d1c127SSebastian Grimberg @ref User 297b435c5a6Srezgarshakeri **/ 29877d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 29977d1c127SSebastian Grimberg *orients = NULL; 30077d1c127SSebastian Grimberg rstr->num_readers--; 301b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 302b435c5a6Srezgarshakeri } 303b435c5a6Srezgarshakeri 304b435c5a6Srezgarshakeri /** 305ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` curl-conforming orientations array by @ref CeedMemType 3067a982d89SJeremy L. Thompson 307ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve curl-conforming orientations 308fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 309fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 310ca94c3ddSJeremy L Thompson @param[out] curl_orients Array on memory type `mem_type` 3117a982d89SJeremy L. Thompson 3127a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3137a982d89SJeremy L. Thompson 31477d1c127SSebastian Grimberg @ref User 3157a982d89SJeremy L. Thompson **/ 3160c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 317ca94c3ddSJeremy L Thompson CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedElemRestrictionGetCurlOrientations"); 31877d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 31977d1c127SSebastian Grimberg rstr->num_readers++; 32077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 32177d1c127SSebastian Grimberg } 32277d1c127SSebastian Grimberg 32377d1c127SSebastian Grimberg /** 324ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetCurlOrientations() 32577d1c127SSebastian Grimberg 326ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 32777d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 32877d1c127SSebastian Grimberg 32977d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 33077d1c127SSebastian Grimberg 33177d1c127SSebastian Grimberg @ref User 33277d1c127SSebastian Grimberg **/ 3330c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 33477d1c127SSebastian Grimberg *curl_orients = NULL; 33577d1c127SSebastian Grimberg rstr->num_readers--; 336e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3377a982d89SJeremy L. Thompson } 3387a982d89SJeremy L. Thompson 3397a982d89SJeremy L. Thompson /** 34049fd234cSJeremy L Thompson 341*22eb1385SJeremy L Thompson @brief Get the L-vector layout of a strided `CeedElemRestriction` 342*22eb1385SJeremy L Thompson 343*22eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 344*22eb1385SJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 345*22eb1385SJeremy 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]`. 346*22eb1385SJeremy L Thompson 347*22eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 348*22eb1385SJeremy L Thompson 349*22eb1385SJeremy L Thompson @ref Backend 350*22eb1385SJeremy L Thompson **/ 351*22eb1385SJeremy L Thompson int CeedElemRestrictionGetLLayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 352*22eb1385SJeremy L Thompson bool has_backend_strides; 353*22eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 354*22eb1385SJeremy L Thompson 355*22eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 356*22eb1385SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, rstr->ceed, CEED_ERROR_MINOR, "Only strided CeedElemRestriction have strided L-vector layout"); 357*22eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 358*22eb1385SJeremy L Thompson if (has_backend_strides) { 359*22eb1385SJeremy L Thompson CeedCheck(rstr->l_layout[0], rstr->ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no L-vector layout data"); 360*22eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->l_layout[i]; 361*22eb1385SJeremy L Thompson } else { 362*22eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetStrides(rstr, layout)); 363*22eb1385SJeremy L Thompson } 364*22eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 365*22eb1385SJeremy L Thompson } 366*22eb1385SJeremy L Thompson 367*22eb1385SJeremy L Thompson /** 368*22eb1385SJeremy L Thompson 369*22eb1385SJeremy L Thompson @brief Set the L-vector layout of a strided `CeedElemRestriction` 370*22eb1385SJeremy L Thompson 371*22eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 372*22eb1385SJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 373*22eb1385SJeremy 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]`. 374*22eb1385SJeremy L Thompson 375*22eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 376*22eb1385SJeremy L Thompson 377*22eb1385SJeremy L Thompson @ref Backend 378*22eb1385SJeremy L Thompson **/ 379*22eb1385SJeremy L Thompson int CeedElemRestrictionSetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 380*22eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 381*22eb1385SJeremy L Thompson 382*22eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 383*22eb1385SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, rstr->ceed, CEED_ERROR_MINOR, "Only strided CeedElemRestriction have strided L-vector layout"); 384*22eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->l_layout[i] = layout[i]; 385*22eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 386*22eb1385SJeremy L Thompson } 387*22eb1385SJeremy L Thompson 388*22eb1385SJeremy L Thompson /** 389*22eb1385SJeremy L Thompson 390ca94c3ddSJeremy L Thompson @brief Get the E-vector layout of a `CeedElemRestriction` 39149fd234cSJeremy L Thompson 392ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 393ca94c3ddSJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 394ca94c3ddSJeremy 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]`. 39549fd234cSJeremy L Thompson 39649fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 39749fd234cSJeremy L Thompson 39849fd234cSJeremy L Thompson @ref Backend 39949fd234cSJeremy L Thompson **/ 4002b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 401*22eb1385SJeremy L Thompson CeedCheck(rstr->e_layout[0], rstr->ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no E-vector layout data"); 402*22eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->e_layout[i]; 403e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 40449fd234cSJeremy L Thompson } 40549fd234cSJeremy L Thompson 40649fd234cSJeremy L Thompson /** 40749fd234cSJeremy L Thompson 408ca94c3ddSJeremy L Thompson @brief Set the E-vector layout of a `CeedElemRestriction` 40949fd234cSJeremy L Thompson 410ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 411ca94c3ddSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 412ca94c3ddSJeremy 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]`. 41349fd234cSJeremy L Thompson 41449fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 41549fd234cSJeremy L Thompson 41649fd234cSJeremy L Thompson @ref Backend 41749fd234cSJeremy L Thompson **/ 4182b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 419*22eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->e_layout[i] = layout[i]; 420e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 42149fd234cSJeremy L Thompson } 42249fd234cSJeremy L Thompson 42349fd234cSJeremy L Thompson /** 424ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedElemRestriction` 4257a982d89SJeremy L. Thompson 426ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 4277a982d89SJeremy L. Thompson @param[out] data Variable to store data 4287a982d89SJeremy L. Thompson 4297a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4307a982d89SJeremy L. Thompson 4317a982d89SJeremy L. Thompson @ref Backend 4327a982d89SJeremy L. Thompson **/ 433777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 434777ff853SJeremy L Thompson *(void **)data = rstr->data; 435e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4367a982d89SJeremy L. Thompson } 4377a982d89SJeremy L. Thompson 4387a982d89SJeremy L. Thompson /** 439ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedElemRestriction` 4407a982d89SJeremy L. Thompson 441ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` 442ea61e9acSJeremy L Thompson @param[in] data Data to set 4437a982d89SJeremy L. Thompson 4447a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4457a982d89SJeremy L. Thompson 4467a982d89SJeremy L. Thompson @ref Backend 4477a982d89SJeremy L. Thompson **/ 448777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 449777ff853SJeremy L Thompson rstr->data = data; 450e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4517a982d89SJeremy L. Thompson } 4527a982d89SJeremy L. Thompson 45334359f16Sjeremylt /** 454ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedElemRestriction` 45534359f16Sjeremylt 456ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to increment the reference counter 45734359f16Sjeremylt 45834359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 45934359f16Sjeremylt 46034359f16Sjeremylt @ref Backend 46134359f16Sjeremylt **/ 4629560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 46334359f16Sjeremylt rstr->ref_count++; 46434359f16Sjeremylt return CEED_ERROR_SUCCESS; 46534359f16Sjeremylt } 46634359f16Sjeremylt 4676e15d496SJeremy L Thompson /** 468ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedElemRestriction` in `t_mode` 4696e15d496SJeremy L Thompson 470ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to estimate FLOPs for 471ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 472ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 4736e15d496SJeremy L Thompson 4746e15d496SJeremy L Thompson @ref Backend 4756e15d496SJeremy L Thompson **/ 4762b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 477e7f679fcSJeremy L Thompson CeedInt e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp, scale = 0; 47889edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 4791c66c397SJeremy L Thompson 48089edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 4813ac8f562SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) e_size = rstr->num_points * rstr->num_comp; 48277d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 48389edb9e3SSebastian Grimberg switch (rstr_type) { 4843ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 4853ac8f562SJeremy L Thompson scale = 0; 4863ac8f562SJeremy L Thompson break; 48789edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 48889edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 48977d1c127SSebastian Grimberg scale = 1; 49089edb9e3SSebastian Grimberg break; 49189edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 49277d1c127SSebastian Grimberg scale = 2; 49389edb9e3SSebastian Grimberg break; 49489edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 49577d1c127SSebastian Grimberg scale = 6; 49689edb9e3SSebastian Grimberg break; 4976e15d496SJeremy L Thompson } 49877d1c127SSebastian Grimberg } else { 49989edb9e3SSebastian Grimberg switch (rstr_type) { 50089edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 50189edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 5023ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 50377d1c127SSebastian Grimberg scale = 0; 50489edb9e3SSebastian Grimberg break; 50589edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 50677d1c127SSebastian Grimberg scale = 1; 50789edb9e3SSebastian Grimberg break; 50889edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 50977d1c127SSebastian Grimberg scale = 5; 51089edb9e3SSebastian Grimberg break; 51177d1c127SSebastian Grimberg } 51277d1c127SSebastian Grimberg } 5136e15d496SJeremy L Thompson *flops = e_size * scale; 5146e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5156e15d496SJeremy L Thompson } 5166e15d496SJeremy L Thompson 5177a982d89SJeremy L. Thompson /// @} 5187a982d89SJeremy L. Thompson 51915910d16Sjeremylt /// @cond DOXYGEN_SKIP 52015910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 52115910d16Sjeremylt /// @endcond 52215910d16Sjeremylt 5237a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5247a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 5257a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5267a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 527d7b241e6Sjeremylt /// @{ 528d7b241e6Sjeremylt 5297a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 53045f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 5317a982d89SJeremy L. Thompson 532ca94c3ddSJeremy L Thompson /// Argument for @ref CeedOperatorSetField() indicating that the field does not require a `CeedElemRestriction` 5332b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 5347a982d89SJeremy L. Thompson 535d7b241e6Sjeremylt /** 536ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` 537d7b241e6Sjeremylt 538ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 539ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 540ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 541ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 542fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 543ca94c3ddSJeremy L Thompson 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`. 544fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 545fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 546ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 547ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 548ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 549ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where 0 <= i < @a num_elem. 550ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 551ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 552d7b241e6Sjeremylt 553b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 554dfdf5a53Sjeremylt 5557a982d89SJeremy L. Thompson @ref User 556b11c1e72Sjeremylt **/ 5572b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 5582b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 5595fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 5605fe0d4faSjeremylt Ceed delegate; 5616574a04fSJeremy L Thompson 5622b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 563ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreate"); 5642b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 565e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5665fe0d4faSjeremylt } 5675fe0d4faSjeremylt 568e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 5696574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 570ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 571ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 572e022e1f8SJeremy L Thompson 5732b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 574db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 575d1d35e2fSjeremylt (*rstr)->ref_count = 1; 576d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 577d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 578d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 579d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 580d1d35e2fSjeremylt (*rstr)->l_size = l_size; 58105fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 582e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 583e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 58461a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 585fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 586e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 587d7b241e6Sjeremylt } 588d7b241e6Sjeremylt 589d7b241e6Sjeremylt /** 590ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with orientation signs 591fc0567d9Srezgarshakeri 592ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 593ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 594ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 595ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 596fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 597ca94c3ddSJeremy L Thompson 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`. 598fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 599fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 600ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 601ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 602ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 603ca94c3ddSJeremy L Thompson Row i holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`. 604ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 605ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation 606ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 607fc0567d9Srezgarshakeri 608fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 609fc0567d9Srezgarshakeri 610fc0567d9Srezgarshakeri @ref User 611fc0567d9Srezgarshakeri **/ 6122b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 61377d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 614fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 615fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 616fc0567d9Srezgarshakeri Ceed delegate; 6176574a04fSJeremy L Thompson 6182b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 619ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateOriented"); 6202b730f8bSJeremy L Thompson CeedCall( 62177d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 622fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 623fc0567d9Srezgarshakeri } 624fc0567d9Srezgarshakeri 625e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6266574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 627ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 628ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 629e022e1f8SJeremy L Thompson 6302b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 631db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 632fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 633fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 634fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 635fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 636fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 637fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 63805fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 639e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 640e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 641fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 642fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 64377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 64477d1c127SSebastian Grimberg } 64577d1c127SSebastian Grimberg 64677d1c127SSebastian Grimberg /** 647ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with a general tridiagonal transformation matrix for curl-conforming elements 64877d1c127SSebastian Grimberg 649ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 650ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 65177d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 65277d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 653fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 654ca94c3ddSJeremy L Thompson 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`. 655fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 656fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 657ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 658ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 659ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 660ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`. 661ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 662ca94c3ddSJeremy L Thompson @param[in] curl_orients Array of shape `[num_elem, 3 * elem_size]` representing a row-major tridiagonal matrix (`curl_orients[i * 3 * elem_size] = curl_orients[(i + 1) * 3 * elem_size - 1] = 0`, where `0 <= i < num_elem`) which is applied to the element unknowns upon restriction. 663ca94c3ddSJeremy L Thompson This orientation matrix allows for pairs of face degrees of freedom on elements for \f$H(\mathrm{curl})\f$ spaces to be coupled in the element restriction operation, which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 664ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 66577d1c127SSebastian Grimberg 66677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 66777d1c127SSebastian Grimberg 66877d1c127SSebastian Grimberg @ref User 66977d1c127SSebastian Grimberg **/ 67077d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 6710c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 67277d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 673fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 67477d1c127SSebastian Grimberg Ceed delegate; 67577d1c127SSebastian Grimberg 67677d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 677ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateCurlOriented"); 67877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 67977d1c127SSebastian Grimberg curl_orients, rstr)); 68077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 68177d1c127SSebastian Grimberg } 68277d1c127SSebastian Grimberg 683e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 68477d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 685ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 686ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 68777d1c127SSebastian Grimberg 68877d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 689fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 69077d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 69177d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 69277d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 69377d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 69477d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 69577d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 69605fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 697e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 698e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 699fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 700fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 701fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 702fc0567d9Srezgarshakeri } 703fc0567d9Srezgarshakeri 704fc0567d9Srezgarshakeri /** 705ca94c3ddSJeremy L Thompson @brief Create a strided `CeedElemRestriction` 706d7b241e6Sjeremylt 707ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 708ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 709ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 710ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 711fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 712fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 713ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 714ca94c3ddSJeremy L Thompson 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]`. 715ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 716972f909dSJeremy L Thompson `CEED_STRIDES_BACKEND` should only be used pass data between `CeedOperator` created with the same `Ceed` backend. 717972f909dSJeremy L Thompson The L-vector layout will, in general, be different between `Ceed` backends. 718ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 719d7b241e6Sjeremylt 720b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 721dfdf5a53Sjeremylt 7227a982d89SJeremy L. Thompson @ref User 723b11c1e72Sjeremylt **/ 7242b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 725f90c8643Sjeremylt CeedElemRestriction *rstr) { 7265fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 7275fe0d4faSjeremylt Ceed delegate; 728b04eb3d9SSebastian Grimberg 7292b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 730ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateStrided"); 7312b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 732e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7335fe0d4faSjeremylt } 7345fe0d4faSjeremylt 735e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7366574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 737ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 738e7f679fcSJeremy 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"); 739e022e1f8SJeremy L Thompson 7402b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 741db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 742d1d35e2fSjeremylt (*rstr)->ref_count = 1; 743d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 744d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 745d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 746d1d35e2fSjeremylt (*rstr)->l_size = l_size; 74705fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 748e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 749e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 750fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 7512b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 7522b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 753fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 754e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 755d7b241e6Sjeremylt } 756d7b241e6Sjeremylt 757d7b241e6Sjeremylt /** 758ca94c3ddSJeremy L Thompson @brief Create a points `CeedElemRestriction`, for restricting for restricting from a all local points to the current element in which they are located. 7593ac8f562SJeremy L Thompson 7603ac8f562SJeremy L Thompson The offsets array is arranged as 7613ac8f562SJeremy L Thompson 7623ac8f562SJeremy L Thompson element_0_start_index 7633ac8f562SJeremy L Thompson element_1_start_index 7643ac8f562SJeremy L Thompson ... 7653ac8f562SJeremy L Thompson element_n_start_index 7663ac8f562SJeremy L Thompson element_n_stop_index 7673ac8f562SJeremy L Thompson element_0_point_0 7683ac8f562SJeremy L Thompson element_0_point_1 7693ac8f562SJeremy L Thompson ... 7703ac8f562SJeremy L Thompson 771ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 772ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 773ca94c3ddSJeremy L Thompson @param[in] num_points Number of points described in the `offsets` array 7743ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 7753ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 7763ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 7773ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 778ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 779ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 780ca94c3ddSJeremy L Thompson @param[in] offsets Array of size `num_elem + 1 + num_points`. 7813ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 7823ac8f562SJeremy L Thompson The second portion holds the indices for each element. 783ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 7843ac8f562SJeremy L Thompson 7853ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7863ac8f562SJeremy L Thompson 7873ac8f562SJeremy L Thompson @ref Backend 7883ac8f562SJeremy L Thompson **/ 7893ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 7903ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 7913ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 7923ac8f562SJeremy L Thompson Ceed delegate; 7933ac8f562SJeremy L Thompson 7943ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 795ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateAtPoints"); 7963ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 7973ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 7983ac8f562SJeremy L Thompson } 7993ac8f562SJeremy L Thompson 8003ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8013ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 802ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 8033ac8f562SJeremy L Thompson CeedCheck(l_size >= num_points * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector must be at least num_points * num_comp"); 8043ac8f562SJeremy L Thompson 8053ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 8063ac8f562SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 8073ac8f562SJeremy L Thompson (*rstr)->ref_count = 1; 8083ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 8093ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 8103ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 8113ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 81205fa913cSJeremy L Thompson (*rstr)->e_size = num_points * num_comp; 81305fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 8143ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 8153ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 8163ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 8173ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 8183ac8f562SJeremy L Thompson } 8193ac8f562SJeremy L Thompson 8203ac8f562SJeremy L Thompson /** 821ca94c3ddSJeremy L Thompson @brief Create a blocked `CeedElemRestriction`, typically only used by backends 822d7b241e6Sjeremylt 823ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 824ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 825ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 826e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 827ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 828fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 829ca94c3ddSJeremy L Thompson 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`. 830fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 831fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 832ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 833ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 834ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 835ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`. 836ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 837ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 838ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 839ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 840d7b241e6Sjeremylt 841b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 842dfdf5a53Sjeremylt 8437a982d89SJeremy L. Thompson @ref Backend 844b11c1e72Sjeremylt **/ 845e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 8462b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 8474ce2993fSjeremylt CeedElemRestriction *rstr) { 8481c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 849d7b241e6Sjeremylt 8505fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 8515fe0d4faSjeremylt Ceed delegate; 8526574a04fSJeremy L Thompson 8532b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 854ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlocked"); 855e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 856e7f679fcSJeremy L Thompson rstr)); 857e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8585fe0d4faSjeremylt } 859d7b241e6Sjeremylt 860e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8616574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 862e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 863ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 864ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 865e022e1f8SJeremy L Thompson 866e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 867e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 868d7b241e6Sjeremylt 869db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 870db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 871d1d35e2fSjeremylt (*rstr)->ref_count = 1; 872d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 873d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 874d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 875d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 876d1d35e2fSjeremylt (*rstr)->l_size = l_size; 87705fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 878e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 879e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 88061a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 881e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 8821c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 883e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 884d7b241e6Sjeremylt } 885d7b241e6Sjeremylt 886b11c1e72Sjeremylt /** 887ca94c3ddSJeremy L Thompson @brief Create a blocked oriented `CeedElemRestriction`, typically only used by backends 88877d1c127SSebastian Grimberg 889ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 890ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 89177d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 892e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 89377d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 894fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 895ca94c3ddSJeremy L Thompson 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`. 896fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 897fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 898ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 899ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 900ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 901ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`. 902ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 903ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 904ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 905ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation. 906ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to `offsets`. 907ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 90877d1c127SSebastian Grimberg 90977d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 91077d1c127SSebastian Grimberg 91177d1c127SSebastian Grimberg @ref Backend 91277d1c127SSebastian Grimberg **/ 913e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 914e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 915e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 916e7f679fcSJeremy L Thompson bool *block_orients; 9171c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 91877d1c127SSebastian Grimberg 919fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 92077d1c127SSebastian Grimberg Ceed delegate; 92177d1c127SSebastian Grimberg 92277d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 923ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedOriented"); 924e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 92577d1c127SSebastian Grimberg offsets, orients, rstr)); 92677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 92777d1c127SSebastian Grimberg } 92877d1c127SSebastian Grimberg 92977d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 930e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 931ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 932ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 93377d1c127SSebastian Grimberg 934e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 935e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 936e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 937e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 93877d1c127SSebastian Grimberg 939fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 940fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 94177d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 94277d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 94377d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 94477d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 94577d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 94677d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 94705fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 948e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 949e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 950fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 951e7f679fcSJeremy L Thompson CeedCall( 952e7f679fcSJeremy L Thompson ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, *rstr)); 9531c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 95477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 95577d1c127SSebastian Grimberg } 95677d1c127SSebastian Grimberg 95777d1c127SSebastian Grimberg /** 958ca94c3ddSJeremy L Thompson @brief Create a blocked curl-oriented `CeedElemRestriction`, typically only used by backends 95977d1c127SSebastian Grimberg 960ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 961ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 96277d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 963e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 96477d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 965fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 966ca94c3ddSJeremy L Thompson 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`. 967fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 968fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 969ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 970ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 971ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 972ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`. 973ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 974ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 975ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 976ca94c3ddSJeremy L Thompson @param[in] curl_orients Array of shape `[num_elem, 3 * elem_size]` representing a row-major tridiagonal matrix (`curl_orients[i * 3 * elem_size] = curl_orients[(i + 1) * 3 * elem_size - 1] = 0`, where `0 <= i < num_elem`) which is applied to the element unknowns upon restriction. 977ca94c3ddSJeremy L Thompson This orientation matrix allows for pairs of face degrees of freedom on elements for \f$H(\mathrm{curl})\f$ spaces to be coupled in the element restriction operation, which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 978ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to offsets. 979ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 98077d1c127SSebastian Grimberg 98177d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 98277d1c127SSebastian Grimberg 98377d1c127SSebastian Grimberg @ref Backend 98477d1c127SSebastian Grimberg **/ 985e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 98677d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 9870c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 988e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 9891c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 99077d1c127SSebastian Grimberg 991fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 99277d1c127SSebastian Grimberg Ceed delegate; 99377d1c127SSebastian Grimberg 99477d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 995ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedCurlOriented"); 996e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 997e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 99877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 99977d1c127SSebastian Grimberg } 100077d1c127SSebastian Grimberg 1001e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 100277d1c127SSebastian Grimberg 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"); 1004ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1005ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 100677d1c127SSebastian Grimberg 1007e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 1008e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 1009e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 1010e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 101177d1c127SSebastian Grimberg 1012fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 1013fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 101477d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 101577d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 101677d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 101777d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 101877d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 101977d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 102005fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 1021e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1022e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1023fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 1024e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 1025e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 10261c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 102777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 102877d1c127SSebastian Grimberg } 102977d1c127SSebastian Grimberg 103077d1c127SSebastian Grimberg /** 1031ca94c3ddSJeremy L Thompson @brief Create a blocked strided `CeedElemRestriction`, typically only used by backends 10327509a596Sjeremylt 1033ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1034ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 1035ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 1036e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 1037ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1038fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1039fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1040ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 1041ca94c3ddSJeremy L Thompson 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]`. 1042ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 1043ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 10447509a596Sjeremylt 10457509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 10467509a596Sjeremylt 10477a982d89SJeremy L. Thompson @ref User 10487509a596Sjeremylt **/ 1049e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 10508621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 1051e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 10527509a596Sjeremylt 10537509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 10547509a596Sjeremylt Ceed delegate; 10556574a04fSJeremy L Thompson 10562b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1057ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedStrided"); 1058e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 1059e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10607509a596Sjeremylt } 10617509a596Sjeremylt 1062e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 10636574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1064e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1065ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1066e7f679fcSJeremy 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"); 1067e022e1f8SJeremy L Thompson 10682b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 1069db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 1070d1d35e2fSjeremylt (*rstr)->ref_count = 1; 1071d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 1072d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 1073d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 1074d1d35e2fSjeremylt (*rstr)->l_size = l_size; 107505fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 1076e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1077e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1078fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 10792b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 10802b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 1081fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 1082e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10837509a596Sjeremylt } 10847509a596Sjeremylt 10857509a596Sjeremylt /** 1086ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unsigned version. 1087c17ec2beSJeremy L Thompson 1088ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 1089c17ec2beSJeremy L Thompson 1090ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unsigned reference to 1091ca94c3ddSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned `CeedElemRestriction` 1092c17ec2beSJeremy L Thompson 1093c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1094c17ec2beSJeremy L Thompson 1095c17ec2beSJeremy L Thompson @ref User 1096c17ec2beSJeremy L Thompson **/ 1097c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1098c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1099c17ec2beSJeremy L Thompson 1100c17ec2beSJeremy L Thompson // Copy old rstr 1101c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1102c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 1103c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 1104c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 1105c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1106c17ec2beSJeremy L Thompson if (rstr->strides) { 1107c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1108c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1109c17ec2beSJeremy L Thompson } 11107c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1111c17ec2beSJeremy L Thompson 1112c17ec2beSJeremy L Thompson // Override Apply 1113c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1114c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1115c17ec2beSJeremy L Thompson } 1116c17ec2beSJeremy L Thompson 1117c17ec2beSJeremy L Thompson /** 1118ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unoriented version. 11197c1dbaffSSebastian Grimberg 1120ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 11217c1dbaffSSebastian Grimberg 1122ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unoriented reference to 1123ca94c3ddSJeremy L Thompson @param[in,out] rstr_unoriented Variable to store unoriented `CeedElemRestriction` 11247c1dbaffSSebastian Grimberg 11257c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 11267c1dbaffSSebastian Grimberg 11277c1dbaffSSebastian Grimberg @ref User 11287c1dbaffSSebastian Grimberg **/ 11297c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 11307c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 11317c1dbaffSSebastian Grimberg 11327c1dbaffSSebastian Grimberg // Copy old rstr 11337c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 11347c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 11357c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 11367c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 11377c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 11387c1dbaffSSebastian Grimberg if (rstr->strides) { 11397c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 11407c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 11417c1dbaffSSebastian Grimberg } 11427c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 11437c1dbaffSSebastian Grimberg 11447c1dbaffSSebastian Grimberg // Override Apply 11457c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 11467c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 11477c1dbaffSSebastian Grimberg } 11487c1dbaffSSebastian Grimberg 11497c1dbaffSSebastian Grimberg /** 1150ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction`. 11519fd66db6SSebastian Grimberg 1152ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 11539560d06aSjeremylt 1154ca94c3ddSJeremy L Thompson 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`. 1155ca94c3ddSJeremy L Thompson This `CeedElemRestriction` will be destroyed if `*rstr_copy` is the only reference to this `CeedElemRestriction`. 1156ea61e9acSJeremy L Thompson 1157ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to copy reference to 1158ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 11599560d06aSjeremylt 11609560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 11619560d06aSjeremylt 11629560d06aSjeremylt @ref User 11639560d06aSjeremylt **/ 11642b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1165393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 11662b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 11679560d06aSjeremylt *rstr_copy = rstr; 11689560d06aSjeremylt return CEED_ERROR_SUCCESS; 11699560d06aSjeremylt } 11709560d06aSjeremylt 11719560d06aSjeremylt /** 1172ca94c3ddSJeremy L Thompson @brief Create `CeedVector` associated with a `CeedElemRestriction` 1173b11c1e72Sjeremylt 1174ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1175ca94c3ddSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or `NULL` 1176ca94c3ddSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or `NULL` 1177b11c1e72Sjeremylt 1178b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1179dfdf5a53Sjeremylt 11807a982d89SJeremy L. Thompson @ref User 1181b11c1e72Sjeremylt **/ 11822b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1183d2643443SJeremy L Thompson CeedSize e_size, l_size; 118448acf710SJeremy L Thompson 1185d1d35e2fSjeremylt l_size = rstr->l_size; 118648acf710SJeremy L Thompson if (rstr->rstr_type == CEED_RESTRICTION_POINTS) { 118748acf710SJeremy L Thompson e_size = rstr->num_points * rstr->num_comp; 118848acf710SJeremy L Thompson } else { 1189e7f679fcSJeremy L Thompson e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp; 119048acf710SJeremy L Thompson } 11912b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 11922b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 1193e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1194d7b241e6Sjeremylt } 1195d7b241e6Sjeremylt 1196d7b241e6Sjeremylt /** 1197d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1198d7b241e6Sjeremylt 1199ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1200ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1201ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1202ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[num_elem * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1203fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1204ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1205b11c1e72Sjeremylt 1206b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1207dfdf5a53Sjeremylt 12087a982d89SJeremy L. Thompson @ref User 1209b11c1e72Sjeremylt **/ 12102b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1211d7b241e6Sjeremylt CeedInt m, n; 1212d7b241e6Sjeremylt 1213d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 121405fa913cSJeremy L Thompson m = rstr->e_size; 1215d1d35e2fSjeremylt n = rstr->l_size; 1216d7b241e6Sjeremylt } else { 1217d1d35e2fSjeremylt m = rstr->l_size; 121805fa913cSJeremy L Thompson n = rstr->e_size; 1219d7b241e6Sjeremylt } 122005fa913cSJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 12216574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 122205fa913cSJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 12236574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 12242b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1225e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1226d7b241e6Sjeremylt } 1227d7b241e6Sjeremylt 1228d7b241e6Sjeremylt /** 12293ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 12303ac8f562SJeremy L Thompson 1231ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1232ca94c3ddSJeremy L Thompson @param[in] elem Element number in range `[0, num_elem)` 12333ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1234ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1235ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape [`num_points * num_comp]` when `t_mode` = @ref CEED_NOTRANSPOSE). 12363ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 12373ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 12383ac8f562SJeremy L Thompson 12393ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 12403ac8f562SJeremy L Thompson 12413ac8f562SJeremy L Thompson @ref User 12423ac8f562SJeremy L Thompson **/ 124305fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 12443ac8f562SJeremy L Thompson CeedRequest *request) { 12453ac8f562SJeremy L Thompson CeedInt m, n; 12463ac8f562SJeremy L Thompson 12473ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 12483ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &m)); 12493ac8f562SJeremy L Thompson n = rstr->l_size; 12503ac8f562SJeremy L Thompson } else { 12513ac8f562SJeremy L Thompson m = rstr->l_size; 12523ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &n)); 12533ac8f562SJeremy L Thompson } 12543ac8f562SJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 12553ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 12563ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 12573ac8f562SJeremy L Thompson u->length, m, n, elem); 12583ac8f562SJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 12593ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 12603ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 12613ac8f562SJeremy L Thompson ru->length, m, n, elem); 12620930e4e7SJeremy L Thompson CeedCheck(elem < rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 12633ac8f562SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, rstr->num_elem); 126405fa913cSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 12653ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 12663ac8f562SJeremy L Thompson } 12673ac8f562SJeremy L Thompson 12683ac8f562SJeremy L Thompson /** 1269d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1270be9261b7Sjeremylt 1271ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1272ca94c3ddSJeremy 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 `[3*block_size : 4*block_size]` 1273ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1274ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1275ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[block_size * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1276fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1277ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1278be9261b7Sjeremylt 1279be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1280be9261b7Sjeremylt 12817a982d89SJeremy L. Thompson @ref Backend 1282be9261b7Sjeremylt **/ 12832b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 12842b730f8bSJeremy L Thompson CeedRequest *request) { 1285be9261b7Sjeremylt CeedInt m, n; 1286be9261b7Sjeremylt 1287ca94c3ddSJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionApplyBlock"); 12886402da51SJeremy L Thompson 1289d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1290e7f679fcSJeremy L Thompson m = rstr->block_size * rstr->elem_size * rstr->num_comp; 1291d1d35e2fSjeremylt n = rstr->l_size; 1292be9261b7Sjeremylt } else { 1293d1d35e2fSjeremylt m = rstr->l_size; 1294e7f679fcSJeremy L Thompson n = rstr->block_size * rstr->elem_size * rstr->num_comp; 1295be9261b7Sjeremylt } 12966574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 12976574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 12986574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 12996574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 1300e7f679fcSJeremy L Thompson CeedCheck(rstr->block_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 1301e7f679fcSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->block_size * block, 13026574a04fSJeremy L Thompson rstr->num_elem); 13032b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1304e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1305be9261b7Sjeremylt } 1306be9261b7Sjeremylt 1307be9261b7Sjeremylt /** 1308ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedElemRestriction` 1309b7c9bbdaSJeremy L Thompson 1310ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1311ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1312b7c9bbdaSJeremy L Thompson 1313b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1314b7c9bbdaSJeremy L Thompson 1315b7c9bbdaSJeremy L Thompson @ref Advanced 1316b7c9bbdaSJeremy L Thompson **/ 1317b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1318b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1319b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1320b7c9bbdaSJeremy L Thompson } 1321b7c9bbdaSJeremy L Thompson 1322b7c9bbdaSJeremy L Thompson /** 1323d979a051Sjeremylt @brief Get the L-vector component stride 1324a681ae63Sjeremylt 1325ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1326d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1327a681ae63Sjeremylt 1328a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1329a681ae63Sjeremylt 1330b7c9bbdaSJeremy L Thompson @ref Advanced 1331a681ae63Sjeremylt **/ 13322b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1333d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1334e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1335a681ae63Sjeremylt } 1336a681ae63Sjeremylt 1337a681ae63Sjeremylt /** 1338ca94c3ddSJeremy L Thompson @brief Get the total number of elements in the range of a `CeedElemRestriction` 1339a681ae63Sjeremylt 1340ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1341d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1342a681ae63Sjeremylt 1343a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1344a681ae63Sjeremylt 1345b7c9bbdaSJeremy L Thompson @ref Advanced 1346a681ae63Sjeremylt **/ 13472b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1348d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1349e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1350a681ae63Sjeremylt } 1351a681ae63Sjeremylt 1352a681ae63Sjeremylt /** 1353ca94c3ddSJeremy L Thompson @brief Get the size of elements in the `CeedElemRestriction` 1354a681ae63Sjeremylt 1355ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1356d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1357a681ae63Sjeremylt 1358a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1359a681ae63Sjeremylt 1360b7c9bbdaSJeremy L Thompson @ref Advanced 1361a681ae63Sjeremylt **/ 13622b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1363d1d35e2fSjeremylt *elem_size = rstr->elem_size; 13642c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 13652c7e7413SJeremy L Thompson } 13662c7e7413SJeremy L Thompson 13672c7e7413SJeremy L Thompson /** 136807d5dec1SJeremy L Thompson 1369ca94c3ddSJeremy L Thompson @brief Get the number of points in the l-vector for a points `CeedElemRestriction` 137007d5dec1SJeremy L Thompson 1371ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 137207d5dec1SJeremy L Thompson @param[out] num_points The number of points in the l-vector 137307d5dec1SJeremy L Thompson 137407d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 137507d5dec1SJeremy L Thompson 1376c63574e3SJeremy L Thompson @ref User 137707d5dec1SJeremy L Thompson **/ 137807d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) { 137907d5dec1SJeremy L Thompson Ceed ceed; 138007d5dec1SJeremy L Thompson 138107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 138207d5dec1SJeremy L Thompson CeedCheck(rstr->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 138307d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 138407d5dec1SJeremy L Thompson 138507d5dec1SJeremy L Thompson *num_points = rstr->num_points; 138607d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 138707d5dec1SJeremy L Thompson } 138807d5dec1SJeremy L Thompson 138907d5dec1SJeremy L Thompson /** 139007d5dec1SJeremy L Thompson 1391ca94c3ddSJeremy L Thompson @brief Get the number of points in an element of a `CeedElemRestriction` at points 139207d5dec1SJeremy L Thompson 1393ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 139407d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 139507d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 139607d5dec1SJeremy L Thompson 139707d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 139807d5dec1SJeremy L Thompson 1399c63574e3SJeremy L Thompson @ref User 140007d5dec1SJeremy L Thompson **/ 140107d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 140207d5dec1SJeremy L Thompson Ceed ceed; 140307d5dec1SJeremy L Thompson const CeedInt *offsets; 140407d5dec1SJeremy L Thompson 140507d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 140607d5dec1SJeremy L Thompson CeedCheck(rstr->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 140707d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 140807d5dec1SJeremy L Thompson 140907d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 141007d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem]; 141107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 141207d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 141307d5dec1SJeremy L Thompson } 141407d5dec1SJeremy L Thompson 141507d5dec1SJeremy L Thompson /** 1416ca94c3ddSJeremy L Thompson @brief Get the maximum number of points in an element for a `CeedElemRestriction` at points 14172c7e7413SJeremy L Thompson 1418ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 14192c7e7413SJeremy L Thompson @param[out] max_points Variable to store size of elements 14202c7e7413SJeremy L Thompson 14212c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14222c7e7413SJeremy L Thompson 14232c7e7413SJeremy L Thompson @ref Advanced 14242c7e7413SJeremy L Thompson **/ 14252c7e7413SJeremy L Thompson int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 14262c7e7413SJeremy L Thompson Ceed ceed; 14272c7e7413SJeremy L Thompson CeedInt num_elem; 14282c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 14292c7e7413SJeremy L Thompson 14302c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 14312c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 14322c7e7413SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 14332c7e7413SJeremy L Thompson "Cannot compute max points for a CeedElemRestriction that does not use points"); 14342c7e7413SJeremy L Thompson 14352c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 14362c7e7413SJeremy L Thompson *max_points = 0; 14372c7e7413SJeremy L Thompson for (CeedInt e = 0; e < num_elem; e++) { 14382c7e7413SJeremy L Thompson CeedInt num_points; 14392c7e7413SJeremy L Thompson 14402c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 14412c7e7413SJeremy L Thompson *max_points = CeedIntMax(num_points, *max_points); 14422c7e7413SJeremy L Thompson } 1443e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1444a681ae63Sjeremylt } 1445a681ae63Sjeremylt 1446a681ae63Sjeremylt /** 1447ca94c3ddSJeremy L Thompson @brief Get the size of the l-vector for a `CeedElemRestriction` 1448a681ae63Sjeremylt 1449ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1450d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1451a681ae63Sjeremylt 1452a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1453a681ae63Sjeremylt 1454b7c9bbdaSJeremy L Thompson @ref Advanced 1455a681ae63Sjeremylt **/ 14562b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1457d1d35e2fSjeremylt *l_size = rstr->l_size; 1458e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1459a681ae63Sjeremylt } 1460a681ae63Sjeremylt 1461a681ae63Sjeremylt /** 1462ca94c3ddSJeremy L Thompson @brief Get the number of components in the elements of a `CeedElemRestriction` 1463a681ae63Sjeremylt 1464ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1465d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1466a681ae63Sjeremylt 1467a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1468a681ae63Sjeremylt 1469b7c9bbdaSJeremy L Thompson @ref Advanced 1470a681ae63Sjeremylt **/ 14712b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1472d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1473e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1474a681ae63Sjeremylt } 1475a681ae63Sjeremylt 1476a681ae63Sjeremylt /** 1477ca94c3ddSJeremy L Thompson @brief Get the number of blocks in a `CeedElemRestriction` 1478a681ae63Sjeremylt 1479ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1480d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1481a681ae63Sjeremylt 1482a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1483a681ae63Sjeremylt 1484b7c9bbdaSJeremy L Thompson @ref Advanced 1485a681ae63Sjeremylt **/ 14862b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1487e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1488e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1489a681ae63Sjeremylt } 1490a681ae63Sjeremylt 1491a681ae63Sjeremylt /** 1492ca94c3ddSJeremy L Thompson @brief Get the size of blocks in the `CeedElemRestriction` 1493a681ae63Sjeremylt 1494ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1495e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1496a681ae63Sjeremylt 1497a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1498a681ae63Sjeremylt 1499b7c9bbdaSJeremy L Thompson @ref Advanced 1500a681ae63Sjeremylt **/ 1501e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1502e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1503e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1504a681ae63Sjeremylt } 1505a681ae63Sjeremylt 1506a681ae63Sjeremylt /** 1507ca94c3ddSJeremy L Thompson @brief Get the multiplicity of nodes in a `CeedElemRestriction` 15081469ee4dSjeremylt 1509ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1510ca94c3ddSJeremy L Thompson @param[out] mult Vector to store multiplicity (of size `l_size`) 15111469ee4dSjeremylt 15121469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 15131469ee4dSjeremylt 15147a982d89SJeremy L. Thompson @ref User 15151469ee4dSjeremylt **/ 15162b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1517d1d35e2fSjeremylt CeedVector e_vec; 15181469ee4dSjeremylt 151925509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 15202b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 15211469ee4dSjeremylt 152225509ebbSRezgar Shakeri // Compute e_vec = E * 1 15232b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 15242b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 152525509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 15262b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 15272b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 15281469ee4dSjeremylt // Cleanup 15292b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1530e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 15311469ee4dSjeremylt } 15321469ee4dSjeremylt 15331469ee4dSjeremylt /** 1534ca94c3ddSJeremy L Thompson @brief View a `CeedElemRestriction` 1535f02ca4a2SJed Brown 1536ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view 1537ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1538f02ca4a2SJed Brown 1539f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1540f02ca4a2SJed Brown 15417a982d89SJeremy L. Thompson @ref User 1542f02ca4a2SJed Brown **/ 1543f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 15440930e4e7SJeremy L Thompson CeedRestrictionType rstr_type; 15450930e4e7SJeremy L Thompson 15460930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15470930e4e7SJeremy L Thompson 15480930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 15490930e4e7SJeremy L Thompson CeedInt max_points; 15500930e4e7SJeremy L Thompson 15510930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points)); 15520930e4e7SJeremy L Thompson fprintf(stream, 15530930e4e7SJeremy L Thompson "CeedElemRestriction at points from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT 15540930e4e7SJeremy L Thompson " points on an element\n", 15550930e4e7SJeremy L Thompson rstr->l_size, rstr->num_comp, rstr->num_elem, max_points); 15560930e4e7SJeremy L Thompson } else { 15577509a596Sjeremylt char stridesstr[500]; 15581c66c397SJeremy L Thompson 15592b730f8bSJeremy L Thompson if (rstr->strides) { 15602b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 15612b730f8bSJeremy L Thompson } else { 1562990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 15632b730f8bSJeremy L Thompson } 15642b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 1565e7f679fcSJeremy L Thompson rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1566d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 15670930e4e7SJeremy L Thompson } 1568e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1569f02ca4a2SJed Brown } 1570f02ca4a2SJed Brown 1571f02ca4a2SJed Brown /** 1572ca94c3ddSJeremy L Thompson @brief Destroy a `CeedElemRestriction` 1573b11c1e72Sjeremylt 1574ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to destroy 1575b11c1e72Sjeremylt 1576b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1577dfdf5a53Sjeremylt 15787a982d89SJeremy L. Thompson @ref User 1579b11c1e72Sjeremylt **/ 15804ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1581393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1582ad6481ceSJeremy L Thompson *rstr = NULL; 1583ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1584ad6481ceSJeremy L Thompson } 15856574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 15866574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1587c17ec2beSJeremy L Thompson 1588c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 15897c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1590c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1591c17ec2beSJeremy L Thompson 15922b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 15932b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 15942b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1595e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1596d7b241e6Sjeremylt } 1597d7b241e6Sjeremylt 1598d7b241e6Sjeremylt /// @} 1599