15aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, 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; 1671203703bSJeremy L Thompson Ceed ceed; 1681203703bSJeremy L Thompson 1691203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr_a, &ceed)); 17048acf710SJeremy L Thompson 17148acf710SJeremy L Thompson // Cannot compare non-points restrictions 1721203703bSJeremy L Thompson CeedCheck(rstr_a->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_UNSUPPORTED, "First CeedElemRestriction must be AtPoints"); 1731203703bSJeremy L Thompson CeedCheck(rstr_b->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_UNSUPPORTED, "Second CeedElemRestriction must be AtPoints"); 17448acf710SJeremy L Thompson 17548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_a, &num_elem_a)); 17648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_b, &num_elem_b)); 17748acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_a, &num_points_a)); 17848acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_b, &num_points_b)); 17948acf710SJeremy L Thompson 18048acf710SJeremy L Thompson // Check size and contents of offsets arrays 18148acf710SJeremy L Thompson *are_compatible = true; 18248acf710SJeremy L Thompson if (num_elem_a != num_elem_b) *are_compatible = false; 18348acf710SJeremy L Thompson if (num_points_a != num_points_b) *are_compatible = false; 18448acf710SJeremy L Thompson if (*are_compatible) { 18548acf710SJeremy L Thompson const CeedInt *offsets_a, *offsets_b; 18648acf710SJeremy L Thompson 18748acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_a, CEED_MEM_HOST, &offsets_a)); 18848acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_b, CEED_MEM_HOST, &offsets_b)); 18948acf710SJeremy L Thompson for (CeedInt i = 0; i < num_elem_a + 1 + num_points_a; i++) *are_compatible &= offsets_a[i] == offsets_b[i]; 19048acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_a, &offsets_a)); 19148acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_b, &offsets_b)); 19248acf710SJeremy L Thompson } 19348acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 19448acf710SJeremy L Thompson } 19548acf710SJeremy L Thompson 19648acf710SJeremy L Thompson /** 197ca94c3ddSJeremy L Thompson @brief Get the strides of a strided `CeedElemRestriction` 1987a982d89SJeremy L. Thompson 199ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 200a681ae63Sjeremylt @param[out] strides Variable to store strides array 2017a982d89SJeremy L. Thompson 2027a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2037a982d89SJeremy L. Thompson 2047a982d89SJeremy L. Thompson @ref Backend 2057a982d89SJeremy L. Thompson **/ 20656c48462SJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt strides[3]) { 2076e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 20856c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) strides[i] = rstr->strides[i]; 209e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2107a982d89SJeremy L. Thompson } 2117a982d89SJeremy L. Thompson 2127a982d89SJeremy L. Thompson /** 213ca94c3ddSJeremy L Thompson @brief Get the backend stride status of a `CeedElemRestriction` 21477d1c127SSebastian Grimberg 215ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 21677d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 21777d1c127SSebastian Grimberg 21877d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 21977d1c127SSebastian Grimberg 22077d1c127SSebastian Grimberg @ref Backend 22177d1c127SSebastian Grimberg **/ 22277d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 2236e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 22477d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 22577d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 22677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 22777d1c127SSebastian Grimberg } 22877d1c127SSebastian Grimberg 22977d1c127SSebastian Grimberg /** 230ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` offsets array by @ref CeedMemType 231bd33150aSjeremylt 232ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve offsets 233fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 234fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 235ca94c3ddSJeremy L Thompson @param[out] offsets Array on memory type `mem_type` 236bd33150aSjeremylt 237bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 238bd33150aSjeremylt 239bd33150aSjeremylt @ref User 240bd33150aSjeremylt **/ 2412b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 2427c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2437c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 244c17ec2beSJeremy L Thompson } else { 2456e536b99SJeremy L Thompson CeedCheck(rstr->GetOffsets, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 2466e536b99SJeremy L Thompson "Backend does not support CeedElemRestrictionGetOffsets"); 2472b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 248d1d35e2fSjeremylt rstr->num_readers++; 249c17ec2beSJeremy L Thompson } 250e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 251430758c8SJeremy L Thompson } 252430758c8SJeremy L Thompson 253430758c8SJeremy L Thompson /** 254ca94c3ddSJeremy L Thompson @brief Restore an offsets array obtained using @ref CeedElemRestrictionGetOffsets() 255430758c8SJeremy L Thompson 256ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 257ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 258430758c8SJeremy L Thompson 259430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 260430758c8SJeremy L Thompson 261430758c8SJeremy L Thompson @ref User 262430758c8SJeremy L Thompson **/ 2632b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2647c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2657c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 266c17ec2beSJeremy L Thompson } else { 267430758c8SJeremy L Thompson *offsets = NULL; 268d1d35e2fSjeremylt rstr->num_readers--; 269c17ec2beSJeremy L Thompson } 270e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 271bd33150aSjeremylt } 272bd33150aSjeremylt 273bd33150aSjeremylt /** 274ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` orientations array by @ref CeedMemType 2753ac43b2cSJeremy L Thompson 276ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve orientations 277fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 278fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 279ca94c3ddSJeremy L Thompson @param[out] orients Array on memory type `mem_type` 2803ac43b2cSJeremy L Thompson 2813ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2823ac43b2cSJeremy L Thompson 28377d1c127SSebastian Grimberg @ref User 2843ac43b2cSJeremy L Thompson **/ 28577d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 2866e536b99SJeremy L Thompson CeedCheck(rstr->GetOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 2876e536b99SJeremy L Thompson "Backend does not support CeedElemRestrictionGetOrientations"); 28877d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 28977d1c127SSebastian Grimberg rstr->num_readers++; 290e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2913ac43b2cSJeremy L Thompson } 2923ac43b2cSJeremy L Thompson 2933ac43b2cSJeremy L Thompson /** 294ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetOrientations() 295b435c5a6Srezgarshakeri 296ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 29777d1c127SSebastian Grimberg @param[in] orients Array of orientation data 298b435c5a6Srezgarshakeri 299b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 300b435c5a6Srezgarshakeri 30177d1c127SSebastian Grimberg @ref User 302b435c5a6Srezgarshakeri **/ 30377d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 30477d1c127SSebastian Grimberg *orients = NULL; 30577d1c127SSebastian Grimberg rstr->num_readers--; 306b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 307b435c5a6Srezgarshakeri } 308b435c5a6Srezgarshakeri 309b435c5a6Srezgarshakeri /** 310ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` curl-conforming orientations array by @ref CeedMemType 3117a982d89SJeremy L. Thompson 312ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve curl-conforming orientations 313fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 314fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 315ca94c3ddSJeremy L Thompson @param[out] curl_orients Array on memory type `mem_type` 3167a982d89SJeremy L. Thompson 3177a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3187a982d89SJeremy L. Thompson 31977d1c127SSebastian Grimberg @ref User 3207a982d89SJeremy L. Thompson **/ 3210c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 3226e536b99SJeremy L Thompson CeedCheck(rstr->GetCurlOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 3236e536b99SJeremy L Thompson "Backend does not support CeedElemRestrictionGetCurlOrientations"); 32477d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 32577d1c127SSebastian Grimberg rstr->num_readers++; 32677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 32777d1c127SSebastian Grimberg } 32877d1c127SSebastian Grimberg 32977d1c127SSebastian Grimberg /** 330ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetCurlOrientations() 33177d1c127SSebastian Grimberg 332ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 33377d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 33477d1c127SSebastian Grimberg 33577d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 33677d1c127SSebastian Grimberg 33777d1c127SSebastian Grimberg @ref User 33877d1c127SSebastian Grimberg **/ 3390c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 34077d1c127SSebastian Grimberg *curl_orients = NULL; 34177d1c127SSebastian Grimberg rstr->num_readers--; 342e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3437a982d89SJeremy L. Thompson } 3447a982d89SJeremy L. Thompson 3457a982d89SJeremy L. Thompson /** 34649fd234cSJeremy L Thompson 34722eb1385SJeremy L Thompson @brief Get the L-vector layout of a strided `CeedElemRestriction` 34822eb1385SJeremy L Thompson 34922eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 35022eb1385SJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 35122eb1385SJeremy 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]`. 35222eb1385SJeremy L Thompson 35322eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 35422eb1385SJeremy L Thompson 35522eb1385SJeremy L Thompson @ref Backend 35622eb1385SJeremy L Thompson **/ 35756c48462SJeremy L Thompson int CeedElemRestrictionGetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 35822eb1385SJeremy L Thompson bool has_backend_strides; 35922eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 3601203703bSJeremy L Thompson Ceed ceed; 36122eb1385SJeremy L Thompson 3621203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 36322eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 3641203703bSJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, ceed, CEED_ERROR_MINOR, "Only strided CeedElemRestriction have strided L-vector layout"); 36522eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 36622eb1385SJeremy L Thompson if (has_backend_strides) { 3671203703bSJeremy L Thompson CeedCheck(rstr->l_layout[0], ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no L-vector layout data"); 36856c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->l_layout[i]; 36922eb1385SJeremy L Thompson } else { 37022eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetStrides(rstr, layout)); 37122eb1385SJeremy L Thompson } 37222eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 37322eb1385SJeremy L Thompson } 37422eb1385SJeremy L Thompson 37522eb1385SJeremy L Thompson /** 37622eb1385SJeremy L Thompson 37722eb1385SJeremy L Thompson @brief Set the L-vector layout of a strided `CeedElemRestriction` 37822eb1385SJeremy L Thompson 37922eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 38022eb1385SJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 38122eb1385SJeremy 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]`. 38222eb1385SJeremy L Thompson 38322eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 38422eb1385SJeremy L Thompson 38522eb1385SJeremy L Thompson @ref Backend 38622eb1385SJeremy L Thompson **/ 38722eb1385SJeremy L Thompson int CeedElemRestrictionSetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 38822eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 38922eb1385SJeremy L Thompson 39022eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 3916e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, 3926e536b99SJeremy L Thompson "Only strided CeedElemRestriction have strided L-vector layout"); 39322eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->l_layout[i] = layout[i]; 39422eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 39522eb1385SJeremy L Thompson } 39622eb1385SJeremy L Thompson 39722eb1385SJeremy L Thompson /** 39822eb1385SJeremy L Thompson 399ca94c3ddSJeremy L Thompson @brief Get the E-vector layout of a `CeedElemRestriction` 40049fd234cSJeremy L Thompson 401ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 402ca94c3ddSJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 403ca94c3ddSJeremy 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]`. 40449fd234cSJeremy L Thompson 40549fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 40649fd234cSJeremy L Thompson 40749fd234cSJeremy L Thompson @ref Backend 40849fd234cSJeremy L Thompson **/ 40956c48462SJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 4106e536b99SJeremy L Thompson CeedCheck(rstr->e_layout[0], CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no E-vector layout data"); 41156c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->e_layout[i]; 412e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 41349fd234cSJeremy L Thompson } 41449fd234cSJeremy L Thompson 41549fd234cSJeremy L Thompson /** 41649fd234cSJeremy L Thompson 417ca94c3ddSJeremy L Thompson @brief Set the E-vector layout of a `CeedElemRestriction` 41849fd234cSJeremy L Thompson 419ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 420ca94c3ddSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 421ca94c3ddSJeremy 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]`. 42249fd234cSJeremy L Thompson 42349fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 42449fd234cSJeremy L Thompson 42549fd234cSJeremy L Thompson @ref Backend 42649fd234cSJeremy L Thompson **/ 4272b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 42822eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->e_layout[i] = layout[i]; 429e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 43049fd234cSJeremy L Thompson } 43149fd234cSJeremy L Thompson 43249fd234cSJeremy L Thompson /** 43319605835SJeremy L Thompson 43419605835SJeremy L Thompson @brief Get the E-vector element offset of a `CeedElemRestriction` at points 43519605835SJeremy L Thompson 43619605835SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 43719605835SJeremy L Thompson @param[in] elem Element number index into E-vector for 43819605835SJeremy L Thompson @param[out] elem_offset Offset for element `elem` in the E-vector. 43919605835SJeremy L Thompson The data for point `i`, component `j`, element `elem` in the E-vector is given by `i*e_layout[0] + j*e_layout[1] + elem_offset`. 44019605835SJeremy L Thompson 44119605835SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 44219605835SJeremy L Thompson 44319605835SJeremy L Thompson @ref Backend 44419605835SJeremy L Thompson **/ 44519605835SJeremy L Thompson int CeedElemRestrictionGetAtPointsElementOffset(CeedElemRestriction rstr, CeedInt elem, CeedSize *elem_offset) { 44619605835SJeremy L Thompson CeedInt num_comp; 44719605835SJeremy L Thompson CeedRestrictionType rstr_type; 44819605835SJeremy L Thompson 44919605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 45019605835SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 45119605835SJeremy L Thompson "Can only compute offset for a points CeedElemRestriction"); 45219605835SJeremy L Thompson 45319605835SJeremy L Thompson // Backend method 45419605835SJeremy L Thompson if (rstr->GetAtPointsElementOffset) { 45519605835SJeremy L Thompson CeedCall(rstr->GetAtPointsElementOffset(rstr, elem, elem_offset)); 45619605835SJeremy L Thompson return CEED_ERROR_SUCCESS; 45719605835SJeremy L Thompson } 45819605835SJeremy L Thompson 45919605835SJeremy L Thompson // Default layout (CPU) 46019605835SJeremy L Thompson *elem_offset = 0; 46119605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 46219605835SJeremy L Thompson for (CeedInt i = 0; i < elem; i++) { 46319605835SJeremy L Thompson CeedInt num_points; 46419605835SJeremy L Thompson 46519605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, i, &num_points)); 46619605835SJeremy L Thompson *elem_offset += num_points * num_comp; 46719605835SJeremy L Thompson } 46819605835SJeremy L Thompson return CEED_ERROR_SUCCESS; 46919605835SJeremy L Thompson } 47019605835SJeremy L Thompson 47119605835SJeremy L Thompson /** 472ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedElemRestriction` 4737a982d89SJeremy L. Thompson 474ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 4757a982d89SJeremy L. Thompson @param[out] data Variable to store data 4767a982d89SJeremy L. Thompson 4777a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4787a982d89SJeremy L. Thompson 4797a982d89SJeremy L. Thompson @ref Backend 4807a982d89SJeremy L. Thompson **/ 481777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 482777ff853SJeremy L Thompson *(void **)data = rstr->data; 483e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4847a982d89SJeremy L. Thompson } 4857a982d89SJeremy L. Thompson 4867a982d89SJeremy L. Thompson /** 487ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedElemRestriction` 4887a982d89SJeremy L. Thompson 489ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` 490ea61e9acSJeremy L Thompson @param[in] data Data to set 4917a982d89SJeremy L. Thompson 4927a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4937a982d89SJeremy L. Thompson 4947a982d89SJeremy L. Thompson @ref Backend 4957a982d89SJeremy L. Thompson **/ 496777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 497777ff853SJeremy L Thompson rstr->data = data; 498e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4997a982d89SJeremy L. Thompson } 5007a982d89SJeremy L. Thompson 50134359f16Sjeremylt /** 502ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedElemRestriction` 50334359f16Sjeremylt 504ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to increment the reference counter 50534359f16Sjeremylt 50634359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 50734359f16Sjeremylt 50834359f16Sjeremylt @ref Backend 50934359f16Sjeremylt **/ 5109560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 51134359f16Sjeremylt rstr->ref_count++; 51234359f16Sjeremylt return CEED_ERROR_SUCCESS; 51334359f16Sjeremylt } 51434359f16Sjeremylt 5156e15d496SJeremy L Thompson /** 516ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedElemRestriction` in `t_mode` 5176e15d496SJeremy L Thompson 518ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to estimate FLOPs for 519ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 520ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5216e15d496SJeremy L Thompson 5226e15d496SJeremy L Thompson @ref Backend 5236e15d496SJeremy L Thompson **/ 5242b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 5251203703bSJeremy L Thompson CeedSize e_size, scale = 0; 52689edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 5271c66c397SJeremy L Thompson 5281203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 52989edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 53077d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 53189edb9e3SSebastian Grimberg switch (rstr_type) { 5323ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 5333ac8f562SJeremy L Thompson scale = 0; 5343ac8f562SJeremy L Thompson break; 53589edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 53689edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 53777d1c127SSebastian Grimberg scale = 1; 53889edb9e3SSebastian Grimberg break; 53989edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 54077d1c127SSebastian Grimberg scale = 2; 54189edb9e3SSebastian Grimberg break; 54289edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 54377d1c127SSebastian Grimberg scale = 6; 54489edb9e3SSebastian Grimberg break; 5456e15d496SJeremy L Thompson } 54677d1c127SSebastian Grimberg } else { 54789edb9e3SSebastian Grimberg switch (rstr_type) { 54889edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 54989edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 5503ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 55177d1c127SSebastian Grimberg scale = 0; 55289edb9e3SSebastian Grimberg break; 55389edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 55477d1c127SSebastian Grimberg scale = 1; 55589edb9e3SSebastian Grimberg break; 55689edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 55777d1c127SSebastian Grimberg scale = 5; 55889edb9e3SSebastian Grimberg break; 55977d1c127SSebastian Grimberg } 56077d1c127SSebastian Grimberg } 5616e15d496SJeremy L Thompson *flops = e_size * scale; 5626e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5636e15d496SJeremy L Thompson } 5646e15d496SJeremy L Thompson 5657a982d89SJeremy L. Thompson /// @} 5667a982d89SJeremy L. Thompson 56715910d16Sjeremylt /// @cond DOXYGEN_SKIP 56815910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 56915910d16Sjeremylt /// @endcond 57015910d16Sjeremylt 5717a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5727a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 5737a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5747a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 575d7b241e6Sjeremylt /// @{ 576d7b241e6Sjeremylt 5777a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 57845f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 5797a982d89SJeremy L. Thompson 580ca94c3ddSJeremy L Thompson /// Argument for @ref CeedOperatorSetField() indicating that the field does not require a `CeedElemRestriction` 5812b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 5827a982d89SJeremy L. Thompson 583d7b241e6Sjeremylt /** 584ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` 585d7b241e6Sjeremylt 586ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 587ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 588ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 589ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 590fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 591ca94c3ddSJeremy 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`. 592fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 593fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 594ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 595ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 596ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 597ca94c3ddSJeremy 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. 598ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 599ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 600d7b241e6Sjeremylt 601b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 602dfdf5a53Sjeremylt 6037a982d89SJeremy L. Thompson @ref User 604b11c1e72Sjeremylt **/ 6052b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 6062b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 6075fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6085fe0d4faSjeremylt Ceed delegate; 6096574a04fSJeremy L Thompson 6102b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 611ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreate"); 6122b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 613e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6145fe0d4faSjeremylt } 6155fe0d4faSjeremylt 616e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6176574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 618ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 619ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 620e022e1f8SJeremy L Thompson 6212b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 622db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 623d1d35e2fSjeremylt (*rstr)->ref_count = 1; 624d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 625d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 626d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 627d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 628d1d35e2fSjeremylt (*rstr)->l_size = l_size; 6291203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 630e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 631e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 63261a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 633fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 634e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 635d7b241e6Sjeremylt } 636d7b241e6Sjeremylt 637d7b241e6Sjeremylt /** 638ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with orientation signs 639fc0567d9Srezgarshakeri 640ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 641ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 642ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 643ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 644fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 645ca94c3ddSJeremy 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`. 646fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 647fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 648ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 649ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 650ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 651ca94c3ddSJeremy 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`. 652ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 653ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation 654ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 655fc0567d9Srezgarshakeri 656fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 657fc0567d9Srezgarshakeri 658fc0567d9Srezgarshakeri @ref User 659fc0567d9Srezgarshakeri **/ 6602b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 66177d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 662fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 663fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 664fc0567d9Srezgarshakeri Ceed delegate; 6656574a04fSJeremy L Thompson 6662b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 667ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateOriented"); 6682b730f8bSJeremy L Thompson CeedCall( 66977d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 670fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 671fc0567d9Srezgarshakeri } 672fc0567d9Srezgarshakeri 673e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6746574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 675ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 676ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 677e022e1f8SJeremy L Thompson 6782b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 679db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 680fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 681fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 682fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 683fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 684fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 685fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 6861203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 687e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 688e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 689fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 690fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 69177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 69277d1c127SSebastian Grimberg } 69377d1c127SSebastian Grimberg 69477d1c127SSebastian Grimberg /** 695ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with a general tridiagonal transformation matrix for curl-conforming elements 69677d1c127SSebastian Grimberg 697ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 698ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 69977d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 70077d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 701fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 702ca94c3ddSJeremy 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`. 703fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 704fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 705ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 706ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 707ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 708ca94c3ddSJeremy 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`. 709ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 710ca94c3ddSJeremy 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. 711ca94c3ddSJeremy 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). 712ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 71377d1c127SSebastian Grimberg 71477d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 71577d1c127SSebastian Grimberg 71677d1c127SSebastian Grimberg @ref User 71777d1c127SSebastian Grimberg **/ 71877d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 7190c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 72077d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 721fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 72277d1c127SSebastian Grimberg Ceed delegate; 72377d1c127SSebastian Grimberg 72477d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 725ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateCurlOriented"); 72677d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 72777d1c127SSebastian Grimberg curl_orients, rstr)); 72877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 72977d1c127SSebastian Grimberg } 73077d1c127SSebastian Grimberg 731e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 73277d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 733ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 734ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 73577d1c127SSebastian Grimberg 73677d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 737fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 73877d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 73977d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 74077d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 74177d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 74277d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 74377d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 7441203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 745e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 746e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 747fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 748fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 749fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 750fc0567d9Srezgarshakeri } 751fc0567d9Srezgarshakeri 752fc0567d9Srezgarshakeri /** 753ca94c3ddSJeremy L Thompson @brief Create a strided `CeedElemRestriction` 754d7b241e6Sjeremylt 755ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 756ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 757ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 758ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 759fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 760fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 761ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 762ca94c3ddSJeremy 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]`. 763ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 764972f909dSJeremy L Thompson `CEED_STRIDES_BACKEND` should only be used pass data between `CeedOperator` created with the same `Ceed` backend. 765972f909dSJeremy L Thompson The L-vector layout will, in general, be different between `Ceed` backends. 766ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 767d7b241e6Sjeremylt 768b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 769dfdf5a53Sjeremylt 7707a982d89SJeremy L. Thompson @ref User 771b11c1e72Sjeremylt **/ 7722b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 773f90c8643Sjeremylt CeedElemRestriction *rstr) { 7745fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 7755fe0d4faSjeremylt Ceed delegate; 776b04eb3d9SSebastian Grimberg 7772b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 778ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateStrided"); 7792b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 780e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7815fe0d4faSjeremylt } 7825fe0d4faSjeremylt 783e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7846574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 785ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 78681670346SSebastian Grimberg CeedCheck(l_size >= (CeedSize)num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, 78781670346SSebastian Grimberg "L-vector size must be at least num_elem * elem_size * num_comp"); 788e022e1f8SJeremy L Thompson 7892b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 790db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 791d1d35e2fSjeremylt (*rstr)->ref_count = 1; 792d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 793d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 794d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 795d1d35e2fSjeremylt (*rstr)->l_size = l_size; 7961203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 797e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 798e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 799fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 8002b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 8012b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 802fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 803e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 804d7b241e6Sjeremylt } 805d7b241e6Sjeremylt 806d7b241e6Sjeremylt /** 807ca94c3ddSJeremy 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. 8083ac8f562SJeremy L Thompson 8093ac8f562SJeremy L Thompson The offsets array is arranged as 8103ac8f562SJeremy L Thompson 8113ac8f562SJeremy L Thompson element_0_start_index 8123ac8f562SJeremy L Thompson element_1_start_index 8133ac8f562SJeremy L Thompson ... 8143ac8f562SJeremy L Thompson element_n_start_index 8153ac8f562SJeremy L Thompson element_n_stop_index 8163ac8f562SJeremy L Thompson element_0_point_0 8173ac8f562SJeremy L Thompson element_0_point_1 8183ac8f562SJeremy L Thompson ... 8193ac8f562SJeremy L Thompson 820ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 821ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 822ca94c3ddSJeremy L Thompson @param[in] num_points Number of points described in the `offsets` array 8233ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 8243ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 8253ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 8263ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 827ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 828ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 829ca94c3ddSJeremy L Thompson @param[in] offsets Array of size `num_elem + 1 + num_points`. 8303ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 8313ac8f562SJeremy L Thompson The second portion holds the indices for each element. 832ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 8333ac8f562SJeremy L Thompson 8343ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8353ac8f562SJeremy L Thompson 8363ac8f562SJeremy L Thompson @ref Backend 8373ac8f562SJeremy L Thompson **/ 8383ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 8393ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 8403ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 8413ac8f562SJeremy L Thompson Ceed delegate; 8423ac8f562SJeremy L Thompson 8433ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 844ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateAtPoints"); 8453ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 8463ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 8473ac8f562SJeremy L Thompson } 8483ac8f562SJeremy L Thompson 8493ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8503ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 851ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 85281670346SSebastian Grimberg CeedCheck(l_size >= (CeedSize)num_points * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector must be at least num_points * num_comp"); 8533ac8f562SJeremy L Thompson 8543ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 8553ac8f562SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 8563ac8f562SJeremy L Thompson (*rstr)->ref_count = 1; 8573ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 8583ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 8593ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 860*2c2c926cSJeremy L Thompson (*rstr)->comp_stride = 1; 8613ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 8621203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_points * (CeedSize)num_comp; 86305fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 8643ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 8653ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 8663ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 8673ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 8683ac8f562SJeremy L Thompson } 8693ac8f562SJeremy L Thompson 8703ac8f562SJeremy L Thompson /** 871ca94c3ddSJeremy L Thompson @brief Create a blocked `CeedElemRestriction`, typically only used by backends 872d7b241e6Sjeremylt 873ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 874ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 875ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 876e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 877ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 878fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 879ca94c3ddSJeremy 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`. 880fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 881fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 882ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 883ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 884ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 885ca94c3ddSJeremy 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`. 886ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 887ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 888ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 889ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 890d7b241e6Sjeremylt 891b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 892dfdf5a53Sjeremylt 8937a982d89SJeremy L. Thompson @ref Backend 894b11c1e72Sjeremylt **/ 895e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 8962b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 8974ce2993fSjeremylt CeedElemRestriction *rstr) { 8981c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 899d7b241e6Sjeremylt 9005fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 9015fe0d4faSjeremylt Ceed delegate; 9026574a04fSJeremy L Thompson 9032b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 904ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlocked"); 905e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 906e7f679fcSJeremy L Thompson rstr)); 907e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9085fe0d4faSjeremylt } 909d7b241e6Sjeremylt 910e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 9116574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 912e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 913ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 914ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 915e022e1f8SJeremy L Thompson 916e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 917e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 918d7b241e6Sjeremylt 919db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 920db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 921d1d35e2fSjeremylt (*rstr)->ref_count = 1; 922d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 923d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 924d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 925d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 926d1d35e2fSjeremylt (*rstr)->l_size = l_size; 9271203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 928e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 929e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 93061a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 931e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 9321c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 933e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 934d7b241e6Sjeremylt } 935d7b241e6Sjeremylt 936b11c1e72Sjeremylt /** 937ca94c3ddSJeremy L Thompson @brief Create a blocked oriented `CeedElemRestriction`, typically only used by backends 93877d1c127SSebastian Grimberg 939ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 940ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 94177d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 942e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 94377d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 944fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 945ca94c3ddSJeremy 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`. 946fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 947fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 948ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 949ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 950ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 951ca94c3ddSJeremy 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`. 952ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 953ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 954ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 955ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation. 956ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to `offsets`. 957ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 95877d1c127SSebastian Grimberg 95977d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 96077d1c127SSebastian Grimberg 96177d1c127SSebastian Grimberg @ref Backend 96277d1c127SSebastian Grimberg **/ 963e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 964e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 965e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 966e7f679fcSJeremy L Thompson bool *block_orients; 9671c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 96877d1c127SSebastian Grimberg 969fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 97077d1c127SSebastian Grimberg Ceed delegate; 97177d1c127SSebastian Grimberg 97277d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 973ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedOriented"); 974e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 97577d1c127SSebastian Grimberg offsets, orients, rstr)); 97677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 97777d1c127SSebastian Grimberg } 97877d1c127SSebastian Grimberg 97977d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 980e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 981ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 982ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 98377d1c127SSebastian Grimberg 984e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 985e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 986e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 987e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 98877d1c127SSebastian Grimberg 989fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 990fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 99177d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 99277d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 99377d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 99477d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 99577d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 99677d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 9971203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 998e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 999e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1000fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 1001e7f679fcSJeremy L Thompson CeedCall( 1002e7f679fcSJeremy L Thompson ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, *rstr)); 10031c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 100477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 100577d1c127SSebastian Grimberg } 100677d1c127SSebastian Grimberg 100777d1c127SSebastian Grimberg /** 1008ca94c3ddSJeremy L Thompson @brief Create a blocked curl-oriented `CeedElemRestriction`, typically only used by backends 100977d1c127SSebastian Grimberg 1010ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1011ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 101277d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 1013e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 101477d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1015fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 1016ca94c3ddSJeremy 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`. 1017fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1018fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1019ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 1020ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 1021ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 1022ca94c3ddSJeremy 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`. 1023ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 1024ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 1025ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 1026ca94c3ddSJeremy 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. 1027ca94c3ddSJeremy 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). 1028ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to offsets. 1029ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 103077d1c127SSebastian Grimberg 103177d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 103277d1c127SSebastian Grimberg 103377d1c127SSebastian Grimberg @ref Backend 103477d1c127SSebastian Grimberg **/ 1035e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 103677d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 10370c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 1038e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 10391c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 104077d1c127SSebastian Grimberg 1041fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 104277d1c127SSebastian Grimberg Ceed delegate; 104377d1c127SSebastian Grimberg 104477d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1045ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedCurlOriented"); 1046e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 1047e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 104877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 104977d1c127SSebastian Grimberg } 105077d1c127SSebastian Grimberg 1051e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 105277d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1053e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1054ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1055ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 105677d1c127SSebastian Grimberg 1057e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 1058e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 1059e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 1060e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 106177d1c127SSebastian Grimberg 1062fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 1063fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 106477d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 106577d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 106677d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 106777d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 106877d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 106977d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 10701203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1071e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1072e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1073fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 1074e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 1075e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 10761c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 107777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 107877d1c127SSebastian Grimberg } 107977d1c127SSebastian Grimberg 108077d1c127SSebastian Grimberg /** 1081ca94c3ddSJeremy L Thompson @brief Create a blocked strided `CeedElemRestriction`, typically only used by backends 10827509a596Sjeremylt 1083ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1084ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 1085ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 1086e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 1087ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1088fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1089fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1090ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 1091ca94c3ddSJeremy 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]`. 1092ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 1093ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 10947509a596Sjeremylt 10957509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 10967509a596Sjeremylt 10977a982d89SJeremy L. Thompson @ref User 10987509a596Sjeremylt **/ 1099e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 11008621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 1101e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 11027509a596Sjeremylt 11037509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 11047509a596Sjeremylt Ceed delegate; 11056574a04fSJeremy L Thompson 11062b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1107ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedStrided"); 1108e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 1109e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11107509a596Sjeremylt } 11117509a596Sjeremylt 1112e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 11136574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1114e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1115ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 111681670346SSebastian Grimberg CeedCheck(l_size >= (CeedSize)num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, 111781670346SSebastian Grimberg "L-vector size must be at least num_elem * elem_size * num_comp"); 1118e022e1f8SJeremy L Thompson 11192b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 1120db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 1121d1d35e2fSjeremylt (*rstr)->ref_count = 1; 1122d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 1123d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 1124d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 1125d1d35e2fSjeremylt (*rstr)->l_size = l_size; 11261203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1127e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1128e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1129fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 11302b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 11312b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 1132fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 1133e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11347509a596Sjeremylt } 11357509a596Sjeremylt 11367509a596Sjeremylt /** 1137ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unsigned version. 1138c17ec2beSJeremy L Thompson 1139ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 1140c17ec2beSJeremy L Thompson 1141ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unsigned reference to 1142ca94c3ddSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned `CeedElemRestriction` 1143c17ec2beSJeremy L Thompson 1144c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1145c17ec2beSJeremy L Thompson 1146c17ec2beSJeremy L Thompson @ref User 1147c17ec2beSJeremy L Thompson **/ 1148c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1149c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1150c17ec2beSJeremy L Thompson 1151c17ec2beSJeremy L Thompson // Copy old rstr 1152c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1153c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 1154c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 1155c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 1156c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1157c17ec2beSJeremy L Thompson if (rstr->strides) { 1158c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1159c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1160c17ec2beSJeremy L Thompson } 11617c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1162c17ec2beSJeremy L Thompson 1163c17ec2beSJeremy L Thompson // Override Apply 1164c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1165c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1166c17ec2beSJeremy L Thompson } 1167c17ec2beSJeremy L Thompson 1168c17ec2beSJeremy L Thompson /** 1169ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unoriented version. 11707c1dbaffSSebastian Grimberg 1171ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 11727c1dbaffSSebastian Grimberg 1173ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unoriented reference to 1174ca94c3ddSJeremy L Thompson @param[in,out] rstr_unoriented Variable to store unoriented `CeedElemRestriction` 11757c1dbaffSSebastian Grimberg 11767c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 11777c1dbaffSSebastian Grimberg 11787c1dbaffSSebastian Grimberg @ref User 11797c1dbaffSSebastian Grimberg **/ 11807c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 11817c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 11827c1dbaffSSebastian Grimberg 11837c1dbaffSSebastian Grimberg // Copy old rstr 11847c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 11857c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 11867c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 11877c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 11887c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 11897c1dbaffSSebastian Grimberg if (rstr->strides) { 11907c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 11917c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 11927c1dbaffSSebastian Grimberg } 11937c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 11947c1dbaffSSebastian Grimberg 11957c1dbaffSSebastian Grimberg // Override Apply 11967c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 11977c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 11987c1dbaffSSebastian Grimberg } 11997c1dbaffSSebastian Grimberg 12007c1dbaffSSebastian Grimberg /** 1201ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction`. 12029fd66db6SSebastian Grimberg 1203ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 12049560d06aSjeremylt 1205ca94c3ddSJeremy 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`. 1206ca94c3ddSJeremy L Thompson This `CeedElemRestriction` will be destroyed if `*rstr_copy` is the only reference to this `CeedElemRestriction`. 1207ea61e9acSJeremy L Thompson 1208ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to copy reference to 1209ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 12109560d06aSjeremylt 12119560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 12129560d06aSjeremylt 12139560d06aSjeremylt @ref User 12149560d06aSjeremylt **/ 12152b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1216393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 12172b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 12189560d06aSjeremylt *rstr_copy = rstr; 12199560d06aSjeremylt return CEED_ERROR_SUCCESS; 12209560d06aSjeremylt } 12219560d06aSjeremylt 12229560d06aSjeremylt /** 1223ca94c3ddSJeremy L Thompson @brief Create `CeedVector` associated with a `CeedElemRestriction` 1224b11c1e72Sjeremylt 1225ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1226ca94c3ddSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or `NULL` 1227ca94c3ddSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or `NULL` 1228b11c1e72Sjeremylt 1229b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1230dfdf5a53Sjeremylt 12317a982d89SJeremy L. Thompson @ref User 1232b11c1e72Sjeremylt **/ 12332b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1234d2643443SJeremy L Thompson CeedSize e_size, l_size; 12351203703bSJeremy L Thompson Ceed ceed; 123648acf710SJeremy L Thompson 12371203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 12381203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 12391203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 12401203703bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(ceed, l_size, l_vec)); 12411203703bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(ceed, e_size, e_vec)); 1242e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1243d7b241e6Sjeremylt } 1244d7b241e6Sjeremylt 1245d7b241e6Sjeremylt /** 1246d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1247d7b241e6Sjeremylt 1248ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1249ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1250ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1251ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[num_elem * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1252fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1253ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1254b11c1e72Sjeremylt 1255b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1256dfdf5a53Sjeremylt 12577a982d89SJeremy L. Thompson @ref User 1258b11c1e72Sjeremylt **/ 12592b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1260701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1261701e7d35SJeremy L Thompson CeedInt num_elem; 12621203703bSJeremy L Thompson Ceed ceed; 1263d7b241e6Sjeremylt 12641203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 1265d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1266701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_ru_len)); 1267701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1268d7b241e6Sjeremylt } else { 1269701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_u_len)); 1270701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1271d7b241e6Sjeremylt } 1272701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 12731203703bSJeremy L Thompson CeedCheck(min_u_len <= len, ceed, CEED_ERROR_DIMENSION, 1274701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1275701e7d35SJeremy L Thompson min_u_len); 1276701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 12771203703bSJeremy L Thompson CeedCheck(min_ru_len <= len, ceed, CEED_ERROR_DIMENSION, 1278701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1279701e7d35SJeremy L Thompson min_ru_len); 1280701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 1281701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1282e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1283d7b241e6Sjeremylt } 1284d7b241e6Sjeremylt 1285d7b241e6Sjeremylt /** 12863ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 12873ac8f562SJeremy L Thompson 1288ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1289ca94c3ddSJeremy L Thompson @param[in] elem Element number in range `[0, num_elem)` 12903ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1291ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1292ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape [`num_points * num_comp]` when `t_mode` = @ref CEED_NOTRANSPOSE). 12933ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 12943ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 12953ac8f562SJeremy L Thompson 12963ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 12973ac8f562SJeremy L Thompson 12983ac8f562SJeremy L Thompson @ref User 12993ac8f562SJeremy L Thompson **/ 130005fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 13013ac8f562SJeremy L Thompson CeedRequest *request) { 1302701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1303701e7d35SJeremy L Thompson CeedInt num_elem; 13041203703bSJeremy L Thompson Ceed ceed; 13053ac8f562SJeremy L Thompson 13061203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 13073ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 1308701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1309701e7d35SJeremy L Thompson 1310701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1311701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1312701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1313701e7d35SJeremy L Thompson min_ru_len = (CeedSize)num_points * (CeedSize)num_comp; 13143ac8f562SJeremy L Thompson } else { 1315701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1316701e7d35SJeremy L Thompson 1317701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1318701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1319701e7d35SJeremy L Thompson min_u_len = (CeedSize)num_points * (CeedSize)num_comp; 1320701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 13213ac8f562SJeremy L Thompson } 1322701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 13231203703bSJeremy L Thompson CeedCheck(min_u_len <= len, ceed, CEED_ERROR_DIMENSION, 13243ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 13253ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1326701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1327701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 13281203703bSJeremy L Thompson CeedCheck(min_ru_len <= len, ceed, CEED_ERROR_DIMENSION, 13293ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 13303ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1331701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1332701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 13331203703bSJeremy L Thompson CeedCheck(elem < num_elem, ceed, CEED_ERROR_DIMENSION, 1334701e7d35SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, num_elem); 1335701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 13363ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 13373ac8f562SJeremy L Thompson } 13383ac8f562SJeremy L Thompson 13393ac8f562SJeremy L Thompson /** 1340d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1341be9261b7Sjeremylt 1342ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1343ca94c3ddSJeremy 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]` 1344ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1345ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1346ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[block_size * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1347fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1348ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1349be9261b7Sjeremylt 1350be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1351be9261b7Sjeremylt 13527a982d89SJeremy L. Thompson @ref Backend 1353be9261b7Sjeremylt **/ 13542b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 13552b730f8bSJeremy L Thompson CeedRequest *request) { 1356701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1357701e7d35SJeremy L Thompson CeedInt block_size, num_elem; 13581203703bSJeremy L Thompson Ceed ceed; 1359be9261b7Sjeremylt 13601203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 13611203703bSJeremy L Thompson CeedCheck(rstr->ApplyBlock, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionApplyBlock"); 13626402da51SJeremy L Thompson 1363701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetBlockSize(rstr, &block_size)); 1364d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1365701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1366701e7d35SJeremy L Thompson 1367701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1368701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1369701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1370701e7d35SJeremy L Thompson min_ru_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1371be9261b7Sjeremylt } else { 1372701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1373701e7d35SJeremy L Thompson 1374701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1375701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1376701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1377701e7d35SJeremy L Thompson min_u_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1378be9261b7Sjeremylt } 1379701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 13801203703bSJeremy L Thompson CeedCheck(min_u_len == len, ceed, CEED_ERROR_DIMENSION, 1381701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1382701e7d35SJeremy L Thompson min_ru_len); 1383701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 13841203703bSJeremy L Thompson CeedCheck(min_ru_len == len, ceed, CEED_ERROR_DIMENSION, 1385701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1386701e7d35SJeremy L Thompson min_u_len); 1387701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 13881203703bSJeremy L Thompson CeedCheck(block_size * block <= num_elem, ceed, CEED_ERROR_DIMENSION, 1389701e7d35SJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, block_size * block, 1390701e7d35SJeremy L Thompson num_elem); 13912b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1392e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1393be9261b7Sjeremylt } 1394be9261b7Sjeremylt 1395be9261b7Sjeremylt /** 1396ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedElemRestriction` 1397b7c9bbdaSJeremy L Thompson 1398ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1399ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1400b7c9bbdaSJeremy L Thompson 1401b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1402b7c9bbdaSJeremy L Thompson 1403b7c9bbdaSJeremy L Thompson @ref Advanced 1404b7c9bbdaSJeremy L Thompson **/ 1405b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 14066e536b99SJeremy L Thompson *ceed = CeedElemRestrictionReturnCeed(rstr); 1407b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1408b7c9bbdaSJeremy L Thompson } 1409b7c9bbdaSJeremy L Thompson 1410b7c9bbdaSJeremy L Thompson /** 14116e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedElemRestriction` 14126e536b99SJeremy L Thompson 14136e536b99SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 14146e536b99SJeremy L Thompson 14156e536b99SJeremy L Thompson @return `Ceed` associated with the `rstr` 14166e536b99SJeremy L Thompson 14176e536b99SJeremy L Thompson @ref Advanced 14186e536b99SJeremy L Thompson **/ 14196e536b99SJeremy L Thompson Ceed CeedElemRestrictionReturnCeed(CeedElemRestriction rstr) { return rstr->ceed; } 14206e536b99SJeremy L Thompson 14216e536b99SJeremy L Thompson /** 1422d979a051Sjeremylt @brief Get the L-vector component stride 1423a681ae63Sjeremylt 1424ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1425d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1426a681ae63Sjeremylt 1427a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1428a681ae63Sjeremylt 1429b7c9bbdaSJeremy L Thompson @ref Advanced 1430a681ae63Sjeremylt **/ 14312b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1432d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1433e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1434a681ae63Sjeremylt } 1435a681ae63Sjeremylt 1436a681ae63Sjeremylt /** 1437ca94c3ddSJeremy L Thompson @brief Get the total number of elements in the range of a `CeedElemRestriction` 1438a681ae63Sjeremylt 1439ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1440d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1441a681ae63Sjeremylt 1442a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1443a681ae63Sjeremylt 1444b7c9bbdaSJeremy L Thompson @ref Advanced 1445a681ae63Sjeremylt **/ 14462b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1447d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1448e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1449a681ae63Sjeremylt } 1450a681ae63Sjeremylt 1451a681ae63Sjeremylt /** 1452ca94c3ddSJeremy L Thompson @brief Get the size of elements in the `CeedElemRestriction` 1453a681ae63Sjeremylt 1454ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1455d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1456a681ae63Sjeremylt 1457a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1458a681ae63Sjeremylt 1459b7c9bbdaSJeremy L Thompson @ref Advanced 1460a681ae63Sjeremylt **/ 14612b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1462d1d35e2fSjeremylt *elem_size = rstr->elem_size; 14632c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 14642c7e7413SJeremy L Thompson } 14652c7e7413SJeremy L Thompson 14662c7e7413SJeremy L Thompson /** 146707d5dec1SJeremy L Thompson 1468ca94c3ddSJeremy L Thompson @brief Get the number of points in the l-vector for a points `CeedElemRestriction` 146907d5dec1SJeremy L Thompson 1470ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 147107d5dec1SJeremy L Thompson @param[out] num_points The number of points in the l-vector 147207d5dec1SJeremy L Thompson 147307d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 147407d5dec1SJeremy L Thompson 1475c63574e3SJeremy L Thompson @ref User 147607d5dec1SJeremy L Thompson **/ 147707d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) { 14781203703bSJeremy L Thompson CeedRestrictionType rstr_type; 147907d5dec1SJeremy L Thompson 14801203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 14816e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 148207d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 148307d5dec1SJeremy L Thompson 148407d5dec1SJeremy L Thompson *num_points = rstr->num_points; 148507d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 148607d5dec1SJeremy L Thompson } 148707d5dec1SJeremy L Thompson 148807d5dec1SJeremy L Thompson /** 148907d5dec1SJeremy L Thompson 1490ca94c3ddSJeremy L Thompson @brief Get the number of points in an element of a `CeedElemRestriction` at points 149107d5dec1SJeremy L Thompson 1492ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 149307d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 149407d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 149507d5dec1SJeremy L Thompson 149607d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 149707d5dec1SJeremy L Thompson 1498c63574e3SJeremy L Thompson @ref User 149907d5dec1SJeremy L Thompson **/ 150007d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 15011203703bSJeremy L Thompson CeedRestrictionType rstr_type; 150207d5dec1SJeremy L Thompson const CeedInt *offsets; 150307d5dec1SJeremy L Thompson 15041203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15056e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 150607d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 150707d5dec1SJeremy L Thompson 150807d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 150907d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem]; 151007d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 151107d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 151207d5dec1SJeremy L Thompson } 151307d5dec1SJeremy L Thompson 151407d5dec1SJeremy L Thompson /** 1515ca94c3ddSJeremy L Thompson @brief Get the maximum number of points in an element for a `CeedElemRestriction` at points 15162c7e7413SJeremy L Thompson 1517ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 15182c7e7413SJeremy L Thompson @param[out] max_points Variable to store size of elements 15192c7e7413SJeremy L Thompson 15202c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 15212c7e7413SJeremy L Thompson 15222c7e7413SJeremy L Thompson @ref Advanced 15232c7e7413SJeremy L Thompson **/ 15242c7e7413SJeremy L Thompson int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 15252c7e7413SJeremy L Thompson CeedInt num_elem; 15262c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 15272c7e7413SJeremy L Thompson 15282c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15296e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 15302c7e7413SJeremy L Thompson "Cannot compute max points for a CeedElemRestriction that does not use points"); 15312c7e7413SJeremy L Thompson 15322c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 15332c7e7413SJeremy L Thompson *max_points = 0; 15342c7e7413SJeremy L Thompson for (CeedInt e = 0; e < num_elem; e++) { 15352c7e7413SJeremy L Thompson CeedInt num_points; 15362c7e7413SJeremy L Thompson 15372c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 15382c7e7413SJeremy L Thompson *max_points = CeedIntMax(num_points, *max_points); 15392c7e7413SJeremy L Thompson } 1540e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1541a681ae63Sjeremylt } 1542a681ae63Sjeremylt 1543a681ae63Sjeremylt /** 1544ca94c3ddSJeremy L Thompson @brief Get the size of the l-vector for a `CeedElemRestriction` 1545a681ae63Sjeremylt 1546ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1547701e7d35SJeremy L Thompson @param[out] l_size Variable to store l-vector size 1548a681ae63Sjeremylt 1549a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1550a681ae63Sjeremylt 1551b7c9bbdaSJeremy L Thompson @ref Advanced 1552a681ae63Sjeremylt **/ 15532b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1554d1d35e2fSjeremylt *l_size = rstr->l_size; 1555e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1556a681ae63Sjeremylt } 1557a681ae63Sjeremylt 1558a681ae63Sjeremylt /** 1559701e7d35SJeremy L Thompson @brief Get the size of the e-vector for a `CeedElemRestriction` 1560701e7d35SJeremy L Thompson 1561701e7d35SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1562701e7d35SJeremy L Thompson @param[out] e_size Variable to store e-vector size 1563701e7d35SJeremy L Thompson 1564701e7d35SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1565701e7d35SJeremy L Thompson 1566701e7d35SJeremy L Thompson @ref Advanced 1567701e7d35SJeremy L Thompson **/ 1568701e7d35SJeremy L Thompson int CeedElemRestrictionGetEVectorSize(CeedElemRestriction rstr, CeedSize *e_size) { 1569701e7d35SJeremy L Thompson *e_size = rstr->e_size; 1570701e7d35SJeremy L Thompson return CEED_ERROR_SUCCESS; 1571701e7d35SJeremy L Thompson } 1572701e7d35SJeremy L Thompson 1573701e7d35SJeremy L Thompson /** 1574ca94c3ddSJeremy L Thompson @brief Get the number of components in the elements of a `CeedElemRestriction` 1575a681ae63Sjeremylt 1576ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1577d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1578a681ae63Sjeremylt 1579a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1580a681ae63Sjeremylt 1581b7c9bbdaSJeremy L Thompson @ref Advanced 1582a681ae63Sjeremylt **/ 15832b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1584d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1585e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1586a681ae63Sjeremylt } 1587a681ae63Sjeremylt 1588a681ae63Sjeremylt /** 1589ca94c3ddSJeremy L Thompson @brief Get the number of blocks in a `CeedElemRestriction` 1590a681ae63Sjeremylt 1591ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1592d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1593a681ae63Sjeremylt 1594a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1595a681ae63Sjeremylt 1596b7c9bbdaSJeremy L Thompson @ref Advanced 1597a681ae63Sjeremylt **/ 15982b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1599e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1600e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1601a681ae63Sjeremylt } 1602a681ae63Sjeremylt 1603a681ae63Sjeremylt /** 1604ca94c3ddSJeremy L Thompson @brief Get the size of blocks in the `CeedElemRestriction` 1605a681ae63Sjeremylt 1606ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1607e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1608a681ae63Sjeremylt 1609a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1610a681ae63Sjeremylt 1611b7c9bbdaSJeremy L Thompson @ref Advanced 1612a681ae63Sjeremylt **/ 1613e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1614e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1615e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1616a681ae63Sjeremylt } 1617a681ae63Sjeremylt 1618a681ae63Sjeremylt /** 1619ca94c3ddSJeremy L Thompson @brief Get the multiplicity of nodes in a `CeedElemRestriction` 16201469ee4dSjeremylt 1621ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1622ca94c3ddSJeremy L Thompson @param[out] mult Vector to store multiplicity (of size `l_size`) 16231469ee4dSjeremylt 16241469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 16251469ee4dSjeremylt 16267a982d89SJeremy L. Thompson @ref User 16271469ee4dSjeremylt **/ 16282b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1629d1d35e2fSjeremylt CeedVector e_vec; 16301469ee4dSjeremylt 163125509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 16322b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 16331469ee4dSjeremylt 163425509ebbSRezgar Shakeri // Compute e_vec = E * 1 16352b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 16362b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 163725509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 16382b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 16392b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 16401469ee4dSjeremylt // Cleanup 16412b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1642e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 16431469ee4dSjeremylt } 16441469ee4dSjeremylt 16451469ee4dSjeremylt /** 1646ca94c3ddSJeremy L Thompson @brief View a `CeedElemRestriction` 1647f02ca4a2SJed Brown 1648ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view 1649ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1650f02ca4a2SJed Brown 1651f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1652f02ca4a2SJed Brown 16537a982d89SJeremy L. Thompson @ref User 1654f02ca4a2SJed Brown **/ 1655f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 16560930e4e7SJeremy L Thompson CeedRestrictionType rstr_type; 16570930e4e7SJeremy L Thompson 16580930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 16590930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 16600930e4e7SJeremy L Thompson CeedInt max_points; 16610930e4e7SJeremy L Thompson 16620930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points)); 16630930e4e7SJeremy L Thompson fprintf(stream, 1664249f8407SJeremy L Thompson "CeedElemRestriction at points from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT 16650930e4e7SJeremy L Thompson " points on an element\n", 16660930e4e7SJeremy L Thompson rstr->l_size, rstr->num_comp, rstr->num_elem, max_points); 16670930e4e7SJeremy L Thompson } else { 1668249f8407SJeremy L Thompson char strides_str[500]; 16691c66c397SJeremy L Thompson 16702b730f8bSJeremy L Thompson if (rstr->strides) { 1671249f8407SJeremy L Thompson sprintf(strides_str, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 16722b730f8bSJeremy L Thompson } else { 1673249f8407SJeremy L Thompson sprintf(strides_str, "%" CeedInt_FMT, rstr->comp_stride); 16742b730f8bSJeremy L Thompson } 1675249f8407SJeremy L Thompson fprintf(stream, 1676249f8407SJeremy L Thompson "%sCeedElemRestriction from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT 1677249f8407SJeremy L Thompson " nodes each and %s %s\n", 1678e7f679fcSJeremy L Thompson rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1679249f8407SJeremy L Thompson rstr->strides ? "strides" : "component stride", strides_str); 16800930e4e7SJeremy L Thompson } 1681e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1682f02ca4a2SJed Brown } 1683f02ca4a2SJed Brown 1684f02ca4a2SJed Brown /** 1685ca94c3ddSJeremy L Thompson @brief Destroy a `CeedElemRestriction` 1686b11c1e72Sjeremylt 1687ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to destroy 1688b11c1e72Sjeremylt 1689b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1690dfdf5a53Sjeremylt 16917a982d89SJeremy L. Thompson @ref User 1692b11c1e72Sjeremylt **/ 16934ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1694393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1695ad6481ceSJeremy L Thompson *rstr = NULL; 1696ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1697ad6481ceSJeremy L Thompson } 16986574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 16996574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1700c17ec2beSJeremy L Thompson 1701c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 17027c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1703c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1704c17ec2beSJeremy L Thompson 17052b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 17062b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 17072b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1708e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1709d7b241e6Sjeremylt } 1710d7b241e6Sjeremylt 1711d7b241e6Sjeremylt /// @} 1712