13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 83d576824SJeremy L Thompson #include <ceed-impl.h> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 13c17ec2beSJeremy L Thompson #include <string.h> 14d7b241e6Sjeremylt 157a982d89SJeremy L. Thompson /// @file 167a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces 177a982d89SJeremy L. Thompson 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions 207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 217a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper 227a982d89SJeremy L. Thompson /// @{ 237a982d89SJeremy L. Thompson 247a982d89SJeremy L. Thompson /** 25ca94c3ddSJeremy L Thompson @brief Permute and pad offsets for a blocked `CeedElemRestriction` 267a982d89SJeremy L. Thompson 27ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]` 28ca94c3ddSJeremy L Thompson @param[out] block_offsets Array of permuted and padded array values of shape `[num_block, elem_size, block_size]` 29e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 30ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 31e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 32ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 337a982d89SJeremy L. Thompson 347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 357a982d89SJeremy L. Thompson 367a982d89SJeremy L. Thompson @ref Utility 377a982d89SJeremy L. Thompson **/ 38e7f679fcSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *block_offsets, CeedInt num_block, CeedInt num_elem, CeedInt block_size, 39e7f679fcSJeremy L Thompson CeedInt elem_size) { 40e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 41e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 422b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 43e7f679fcSJeremy L Thompson block_offsets[e * elem_size + k * block_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 442b730f8bSJeremy L Thompson } 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 47e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 487a982d89SJeremy L. Thompson } 497a982d89SJeremy L. Thompson 5077d1c127SSebastian Grimberg /** 51ca94c3ddSJeremy L Thompson @brief Permute and pad orientations for a blocked `CeedElemRestriction` 5277d1c127SSebastian Grimberg 53ca94c3ddSJeremy L Thompson @param[in] orients Array of shape `[num_elem, elem_size]` 54ca94c3ddSJeremy L Thompson @param[out] block_orients Array of permuted and padded array values of shape `[num_block, elem_size, block_size]` 55e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 5677d1c127SSebastian Grimberg @param[in] num_elem Number of elements 57e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 5877d1c127SSebastian Grimberg @param[in] elem_size Size of each element 5977d1c127SSebastian Grimberg 6077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 6177d1c127SSebastian Grimberg 6277d1c127SSebastian Grimberg @ref Utility 6377d1c127SSebastian Grimberg **/ 64e7f679fcSJeremy L Thompson int CeedPermutePadOrients(const bool *orients, bool *block_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, CeedInt elem_size) { 65e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 66e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 6777d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 68e7f679fcSJeremy L Thompson block_orients[e * elem_size + k * block_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 6977d1c127SSebastian Grimberg } 7077d1c127SSebastian Grimberg } 7177d1c127SSebastian Grimberg } 7277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 7377d1c127SSebastian Grimberg } 7477d1c127SSebastian Grimberg 750c73c039SSebastian Grimberg /** 76ca94c3ddSJeremy L Thompson @brief Permute and pad curl-conforming orientations for a blocked `CeedElemRestriction` 770c73c039SSebastian Grimberg 785c7e0f51SSebastian Grimberg @param[in] curl_orients Array of shape `[num_elem, elem_size]` 79ca94c3ddSJeremy L Thompson @param[out] block_curl_orients Array of permuted and padded array values of shape `[num_block, elem_size, block_size]` 80e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 810c73c039SSebastian Grimberg @param[in] num_elem Number of elements 82e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 830c73c039SSebastian Grimberg @param[in] elem_size Size of each element 840c73c039SSebastian Grimberg 850c73c039SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 860c73c039SSebastian Grimberg 870c73c039SSebastian Grimberg @ref Utility 880c73c039SSebastian Grimberg **/ 89e7f679fcSJeremy L Thompson int CeedPermutePadCurlOrients(const CeedInt8 *curl_orients, CeedInt8 *block_curl_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, 900c73c039SSebastian Grimberg CeedInt elem_size) { 91e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 92e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 930c73c039SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 94e7f679fcSJeremy L Thompson block_curl_orients[e * elem_size + k * block_size + j] = curl_orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 950c73c039SSebastian Grimberg } 960c73c039SSebastian Grimberg } 970c73c039SSebastian Grimberg } 980c73c039SSebastian Grimberg return CEED_ERROR_SUCCESS; 990c73c039SSebastian Grimberg } 1000c73c039SSebastian Grimberg 1017a982d89SJeremy L. Thompson /// @} 1027a982d89SJeremy L. Thompson 1037a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1047a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 1057a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1067a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 1077a982d89SJeremy L. Thompson /// @{ 1087a982d89SJeremy L. Thompson 1097a982d89SJeremy L. Thompson /** 110ca94c3ddSJeremy L Thompson @brief Get the type of a `CeedElemRestriction` 111a681ae63Sjeremylt 112ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 113fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 114fcbe8c06SSebastian Grimberg 115fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 116fcbe8c06SSebastian Grimberg 117fcbe8c06SSebastian Grimberg @ref Backend 118fcbe8c06SSebastian Grimberg **/ 119fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 120fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 121fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 122fcbe8c06SSebastian Grimberg } 123fcbe8c06SSebastian Grimberg 124fcbe8c06SSebastian Grimberg /** 125ca94c3ddSJeremy L Thompson @brief Get the strided status of a `CeedElemRestriction` 126fcbe8c06SSebastian Grimberg 127ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 128ca94c3ddSJeremy L Thompson @param[out] is_strided Variable to store strided status 129ca94c3ddSJeremy L Thompson 130ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 131ca94c3ddSJeremy L Thompson 132ca94c3ddSJeremy L Thompson @ref Backend 133fcbe8c06SSebastian Grimberg **/ 134fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 135fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 136fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 137fcbe8c06SSebastian Grimberg } 138fcbe8c06SSebastian Grimberg 139fcbe8c06SSebastian Grimberg /** 140ca94c3ddSJeremy L Thompson @brief Get the points status of a `CeedElemRestriction` 1413ac8f562SJeremy L Thompson 142ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 143ca94c3ddSJeremy L Thompson @param[out] is_points Variable to store points status 144ca94c3ddSJeremy L Thompson 145ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 146ca94c3ddSJeremy L Thompson 147ca94c3ddSJeremy L Thompson @ref Backend 1483ac8f562SJeremy L Thompson **/ 1493ac8f562SJeremy L Thompson int CeedElemRestrictionIsPoints(CeedElemRestriction rstr, bool *is_points) { 1503ac8f562SJeremy L Thompson *is_points = (rstr->rstr_type == CEED_RESTRICTION_POINTS); 1513ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 1523ac8f562SJeremy L Thompson } 1533ac8f562SJeremy L Thompson 1543ac8f562SJeremy L Thompson /** 155ca94c3ddSJeremy L Thompson @brief Check if two `CeedElemRestriction` created with @ref CeedElemRestrictionCreateAtPoints() and use the same points per element 15648acf710SJeremy L Thompson 157ca94c3ddSJeremy L Thompson @param[in] rstr_a First `CeedElemRestriction` 158ca94c3ddSJeremy L Thompson @param[in] rstr_b Second `CeedElemRestriction` 15948acf710SJeremy L Thompson @param[out] are_compatible Variable to store compatibility status 160ca94c3ddSJeremy L Thompson 161ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 162ca94c3ddSJeremy L Thompson 163ca94c3ddSJeremy L Thompson @ref Backend 16448acf710SJeremy L Thompson **/ 16548acf710SJeremy L Thompson int CeedElemRestrictionAtPointsAreCompatible(CeedElemRestriction rstr_a, CeedElemRestriction rstr_b, bool *are_compatible) { 16648acf710SJeremy L Thompson CeedInt num_elem_a, num_elem_b, num_points_a, num_points_b; 167*1203703bSJeremy L Thompson Ceed ceed; 168*1203703bSJeremy L Thompson 169*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr_a, &ceed)); 17048acf710SJeremy L Thompson 17148acf710SJeremy L Thompson // Cannot compare non-points restrictions 172*1203703bSJeremy L Thompson CeedCheck(rstr_a->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_UNSUPPORTED, "First CeedElemRestriction must be AtPoints"); 173*1203703bSJeremy 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]) { 207*1203703bSJeremy L Thompson Ceed ceed; 208*1203703bSJeremy L Thompson 209*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 210*1203703bSJeremy L Thompson CeedCheck(rstr->strides, ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 21156c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) strides[i] = rstr->strides[i]; 212e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2137a982d89SJeremy L. Thompson } 2147a982d89SJeremy L. Thompson 2157a982d89SJeremy L. Thompson /** 216ca94c3ddSJeremy L Thompson @brief Get the backend stride status of a `CeedElemRestriction` 21777d1c127SSebastian Grimberg 218ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 21977d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 22077d1c127SSebastian Grimberg 22177d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 22277d1c127SSebastian Grimberg 22377d1c127SSebastian Grimberg @ref Backend 22477d1c127SSebastian Grimberg **/ 22577d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 226*1203703bSJeremy L Thompson Ceed ceed; 227*1203703bSJeremy L Thompson 228*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 229*1203703bSJeremy L Thompson CeedCheck(rstr->strides, ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 23077d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 23177d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 23277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 23377d1c127SSebastian Grimberg } 23477d1c127SSebastian Grimberg 23577d1c127SSebastian Grimberg /** 236ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` offsets array by @ref CeedMemType 237bd33150aSjeremylt 238ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve offsets 239fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 240fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 241ca94c3ddSJeremy L Thompson @param[out] offsets Array on memory type `mem_type` 242bd33150aSjeremylt 243bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 244bd33150aSjeremylt 245bd33150aSjeremylt @ref User 246bd33150aSjeremylt **/ 2472b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 2487c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2497c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 250c17ec2beSJeremy L Thompson } else { 251*1203703bSJeremy L Thompson Ceed ceed; 252*1203703bSJeremy L Thompson 253*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 254*1203703bSJeremy L Thompson CeedCheck(rstr->GetOffsets, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedElemRestrictionGetOffsets"); 2552b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 256d1d35e2fSjeremylt rstr->num_readers++; 257c17ec2beSJeremy L Thompson } 258e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 259430758c8SJeremy L Thompson } 260430758c8SJeremy L Thompson 261430758c8SJeremy L Thompson /** 262ca94c3ddSJeremy L Thompson @brief Restore an offsets array obtained using @ref CeedElemRestrictionGetOffsets() 263430758c8SJeremy L Thompson 264ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 265ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 266430758c8SJeremy L Thompson 267430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 268430758c8SJeremy L Thompson 269430758c8SJeremy L Thompson @ref User 270430758c8SJeremy L Thompson **/ 2712b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2727c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2737c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 274c17ec2beSJeremy L Thompson } else { 275430758c8SJeremy L Thompson *offsets = NULL; 276d1d35e2fSjeremylt rstr->num_readers--; 277c17ec2beSJeremy L Thompson } 278e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 279bd33150aSjeremylt } 280bd33150aSjeremylt 281bd33150aSjeremylt /** 282ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` orientations array by @ref CeedMemType 2833ac43b2cSJeremy L Thompson 284ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve orientations 285fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 286fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 287ca94c3ddSJeremy L Thompson @param[out] orients Array on memory type `mem_type` 2883ac43b2cSJeremy L Thompson 2893ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2903ac43b2cSJeremy L Thompson 29177d1c127SSebastian Grimberg @ref User 2923ac43b2cSJeremy L Thompson **/ 29377d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 294*1203703bSJeremy L Thompson Ceed ceed; 295*1203703bSJeremy L Thompson 296*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 297*1203703bSJeremy L Thompson CeedCheck(rstr->GetOrientations, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedElemRestrictionGetOrientations"); 29877d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 29977d1c127SSebastian Grimberg rstr->num_readers++; 300e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3013ac43b2cSJeremy L Thompson } 3023ac43b2cSJeremy L Thompson 3033ac43b2cSJeremy L Thompson /** 304ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetOrientations() 305b435c5a6Srezgarshakeri 306ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 30777d1c127SSebastian Grimberg @param[in] orients Array of orientation data 308b435c5a6Srezgarshakeri 309b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 310b435c5a6Srezgarshakeri 31177d1c127SSebastian Grimberg @ref User 312b435c5a6Srezgarshakeri **/ 31377d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 31477d1c127SSebastian Grimberg *orients = NULL; 31577d1c127SSebastian Grimberg rstr->num_readers--; 316b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 317b435c5a6Srezgarshakeri } 318b435c5a6Srezgarshakeri 319b435c5a6Srezgarshakeri /** 320ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` curl-conforming orientations array by @ref CeedMemType 3217a982d89SJeremy L. Thompson 322ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve curl-conforming orientations 323fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 324fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 325ca94c3ddSJeremy L Thompson @param[out] curl_orients Array on memory type `mem_type` 3267a982d89SJeremy L. Thompson 3277a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3287a982d89SJeremy L. Thompson 32977d1c127SSebastian Grimberg @ref User 3307a982d89SJeremy L. Thompson **/ 3310c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 332*1203703bSJeremy L Thompson Ceed ceed; 333*1203703bSJeremy L Thompson 334*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 335*1203703bSJeremy L Thompson CeedCheck(rstr->GetCurlOrientations, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedElemRestrictionGetCurlOrientations"); 33677d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 33777d1c127SSebastian Grimberg rstr->num_readers++; 33877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 33977d1c127SSebastian Grimberg } 34077d1c127SSebastian Grimberg 34177d1c127SSebastian Grimberg /** 342ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetCurlOrientations() 34377d1c127SSebastian Grimberg 344ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 34577d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 34677d1c127SSebastian Grimberg 34777d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 34877d1c127SSebastian Grimberg 34977d1c127SSebastian Grimberg @ref User 35077d1c127SSebastian Grimberg **/ 3510c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 35277d1c127SSebastian Grimberg *curl_orients = NULL; 35377d1c127SSebastian Grimberg rstr->num_readers--; 354e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3557a982d89SJeremy L. Thompson } 3567a982d89SJeremy L. Thompson 3577a982d89SJeremy L. Thompson /** 35849fd234cSJeremy L Thompson 35922eb1385SJeremy L Thompson @brief Get the L-vector layout of a strided `CeedElemRestriction` 36022eb1385SJeremy L Thompson 36122eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 36222eb1385SJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 36322eb1385SJeremy 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]`. 36422eb1385SJeremy L Thompson 36522eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 36622eb1385SJeremy L Thompson 36722eb1385SJeremy L Thompson @ref Backend 36822eb1385SJeremy L Thompson **/ 36956c48462SJeremy L Thompson int CeedElemRestrictionGetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 37022eb1385SJeremy L Thompson bool has_backend_strides; 37122eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 372*1203703bSJeremy L Thompson Ceed ceed; 37322eb1385SJeremy L Thompson 374*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 37522eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 376*1203703bSJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, ceed, CEED_ERROR_MINOR, "Only strided CeedElemRestriction have strided L-vector layout"); 37722eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 37822eb1385SJeremy L Thompson if (has_backend_strides) { 379*1203703bSJeremy L Thompson CeedCheck(rstr->l_layout[0], ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no L-vector layout data"); 38056c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->l_layout[i]; 38122eb1385SJeremy L Thompson } else { 38222eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetStrides(rstr, layout)); 38322eb1385SJeremy L Thompson } 38422eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 38522eb1385SJeremy L Thompson } 38622eb1385SJeremy L Thompson 38722eb1385SJeremy L Thompson /** 38822eb1385SJeremy L Thompson 38922eb1385SJeremy L Thompson @brief Set the L-vector layout of a strided `CeedElemRestriction` 39022eb1385SJeremy L Thompson 39122eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 39222eb1385SJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 39322eb1385SJeremy 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]`. 39422eb1385SJeremy L Thompson 39522eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 39622eb1385SJeremy L Thompson 39722eb1385SJeremy L Thompson @ref Backend 39822eb1385SJeremy L Thompson **/ 39922eb1385SJeremy L Thompson int CeedElemRestrictionSetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 40022eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 401*1203703bSJeremy L Thompson Ceed ceed; 40222eb1385SJeremy L Thompson 403*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 40422eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 405*1203703bSJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, ceed, CEED_ERROR_MINOR, "Only strided CeedElemRestriction have strided L-vector layout"); 40622eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->l_layout[i] = layout[i]; 40722eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 40822eb1385SJeremy L Thompson } 40922eb1385SJeremy L Thompson 41022eb1385SJeremy L Thompson /** 41122eb1385SJeremy L Thompson 412ca94c3ddSJeremy L Thompson @brief Get the E-vector layout of a `CeedElemRestriction` 41349fd234cSJeremy L Thompson 414ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 415ca94c3ddSJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 416ca94c3ddSJeremy 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]`. 41749fd234cSJeremy L Thompson 41849fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 41949fd234cSJeremy L Thompson 42049fd234cSJeremy L Thompson @ref Backend 42149fd234cSJeremy L Thompson **/ 42256c48462SJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 423*1203703bSJeremy L Thompson Ceed ceed; 424*1203703bSJeremy L Thompson 425*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 426*1203703bSJeremy L Thompson CeedCheck(rstr->e_layout[0], ceed, CEED_ERROR_MINOR, "CeedElemRestriction has no E-vector layout data"); 42756c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->e_layout[i]; 428e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 42949fd234cSJeremy L Thompson } 43049fd234cSJeremy L Thompson 43149fd234cSJeremy L Thompson /** 43249fd234cSJeremy L Thompson 433ca94c3ddSJeremy L Thompson @brief Set the E-vector layout of a `CeedElemRestriction` 43449fd234cSJeremy L Thompson 435ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 436ca94c3ddSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 437ca94c3ddSJeremy 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]`. 43849fd234cSJeremy L Thompson 43949fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 44049fd234cSJeremy L Thompson 44149fd234cSJeremy L Thompson @ref Backend 44249fd234cSJeremy L Thompson **/ 4432b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 44422eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->e_layout[i] = layout[i]; 445e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 44649fd234cSJeremy L Thompson } 44749fd234cSJeremy L Thompson 44849fd234cSJeremy L Thompson /** 449ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedElemRestriction` 4507a982d89SJeremy L. Thompson 451ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 4527a982d89SJeremy L. Thompson @param[out] data Variable to store data 4537a982d89SJeremy L. Thompson 4547a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4557a982d89SJeremy L. Thompson 4567a982d89SJeremy L. Thompson @ref Backend 4577a982d89SJeremy L. Thompson **/ 458777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 459777ff853SJeremy L Thompson *(void **)data = rstr->data; 460e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4617a982d89SJeremy L. Thompson } 4627a982d89SJeremy L. Thompson 4637a982d89SJeremy L. Thompson /** 464ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedElemRestriction` 4657a982d89SJeremy L. Thompson 466ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` 467ea61e9acSJeremy L Thompson @param[in] data Data to set 4687a982d89SJeremy L. Thompson 4697a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4707a982d89SJeremy L. Thompson 4717a982d89SJeremy L. Thompson @ref Backend 4727a982d89SJeremy L. Thompson **/ 473777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 474777ff853SJeremy L Thompson rstr->data = data; 475e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4767a982d89SJeremy L. Thompson } 4777a982d89SJeremy L. Thompson 47834359f16Sjeremylt /** 479ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedElemRestriction` 48034359f16Sjeremylt 481ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to increment the reference counter 48234359f16Sjeremylt 48334359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 48434359f16Sjeremylt 48534359f16Sjeremylt @ref Backend 48634359f16Sjeremylt **/ 4879560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 48834359f16Sjeremylt rstr->ref_count++; 48934359f16Sjeremylt return CEED_ERROR_SUCCESS; 49034359f16Sjeremylt } 49134359f16Sjeremylt 4926e15d496SJeremy L Thompson /** 493ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedElemRestriction` in `t_mode` 4946e15d496SJeremy L Thompson 495ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to estimate FLOPs for 496ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 497ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 4986e15d496SJeremy L Thompson 4996e15d496SJeremy L Thompson @ref Backend 5006e15d496SJeremy L Thompson **/ 5012b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 502*1203703bSJeremy L Thompson CeedSize e_size, scale = 0; 50389edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 5041c66c397SJeremy L Thompson 505*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 50689edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 50777d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 50889edb9e3SSebastian Grimberg switch (rstr_type) { 5093ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 5103ac8f562SJeremy L Thompson scale = 0; 5113ac8f562SJeremy L Thompson break; 51289edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 51389edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 51477d1c127SSebastian Grimberg scale = 1; 51589edb9e3SSebastian Grimberg break; 51689edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 51777d1c127SSebastian Grimberg scale = 2; 51889edb9e3SSebastian Grimberg break; 51989edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 52077d1c127SSebastian Grimberg scale = 6; 52189edb9e3SSebastian Grimberg break; 5226e15d496SJeremy L Thompson } 52377d1c127SSebastian Grimberg } else { 52489edb9e3SSebastian Grimberg switch (rstr_type) { 52589edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 52689edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 5273ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 52877d1c127SSebastian Grimberg scale = 0; 52989edb9e3SSebastian Grimberg break; 53089edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 53177d1c127SSebastian Grimberg scale = 1; 53289edb9e3SSebastian Grimberg break; 53389edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 53477d1c127SSebastian Grimberg scale = 5; 53589edb9e3SSebastian Grimberg break; 53677d1c127SSebastian Grimberg } 53777d1c127SSebastian Grimberg } 5386e15d496SJeremy L Thompson *flops = e_size * scale; 5396e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5406e15d496SJeremy L Thompson } 5416e15d496SJeremy L Thompson 5427a982d89SJeremy L. Thompson /// @} 5437a982d89SJeremy L. Thompson 54415910d16Sjeremylt /// @cond DOXYGEN_SKIP 54515910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 54615910d16Sjeremylt /// @endcond 54715910d16Sjeremylt 5487a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5497a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 5507a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5517a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 552d7b241e6Sjeremylt /// @{ 553d7b241e6Sjeremylt 5547a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 55545f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 5567a982d89SJeremy L. Thompson 557ca94c3ddSJeremy L Thompson /// Argument for @ref CeedOperatorSetField() indicating that the field does not require a `CeedElemRestriction` 5582b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 5597a982d89SJeremy L. Thompson 560d7b241e6Sjeremylt /** 561ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` 562d7b241e6Sjeremylt 563ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 564ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 565ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 566ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 567fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 568ca94c3ddSJeremy 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`. 569fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 570fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 571ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 572ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 573ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 574ca94c3ddSJeremy 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. 575ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 576ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 577d7b241e6Sjeremylt 578b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 579dfdf5a53Sjeremylt 5807a982d89SJeremy L. Thompson @ref User 581b11c1e72Sjeremylt **/ 5822b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 5832b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 5845fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 5855fe0d4faSjeremylt Ceed delegate; 5866574a04fSJeremy L Thompson 5872b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 588ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreate"); 5892b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 590e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5915fe0d4faSjeremylt } 5925fe0d4faSjeremylt 593e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 5946574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 595ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 596ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 597e022e1f8SJeremy L Thompson 5982b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 599db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 600d1d35e2fSjeremylt (*rstr)->ref_count = 1; 601d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 602d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 603d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 604d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 605d1d35e2fSjeremylt (*rstr)->l_size = l_size; 606*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 607e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 608e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 60961a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 610fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 611e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 612d7b241e6Sjeremylt } 613d7b241e6Sjeremylt 614d7b241e6Sjeremylt /** 615ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with orientation signs 616fc0567d9Srezgarshakeri 617ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 618ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 619ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 620ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 621fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 622ca94c3ddSJeremy 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`. 623fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 624fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 625ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 626ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 627ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 628ca94c3ddSJeremy 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`. 629ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 630ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation 631ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 632fc0567d9Srezgarshakeri 633fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 634fc0567d9Srezgarshakeri 635fc0567d9Srezgarshakeri @ref User 636fc0567d9Srezgarshakeri **/ 6372b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 63877d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 639fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 640fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 641fc0567d9Srezgarshakeri Ceed delegate; 6426574a04fSJeremy L Thompson 6432b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 644ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateOriented"); 6452b730f8bSJeremy L Thompson CeedCall( 64677d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 647fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 648fc0567d9Srezgarshakeri } 649fc0567d9Srezgarshakeri 650e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6516574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 652ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 653ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 654e022e1f8SJeremy L Thompson 6552b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 656db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 657fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 658fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 659fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 660fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 661fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 662fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 663*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 664e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 665e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 666fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 667fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 66877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 66977d1c127SSebastian Grimberg } 67077d1c127SSebastian Grimberg 67177d1c127SSebastian Grimberg /** 672ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with a general tridiagonal transformation matrix for curl-conforming elements 67377d1c127SSebastian Grimberg 674ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 675ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 67677d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 67777d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 678fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 679ca94c3ddSJeremy 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`. 680fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 681fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 682ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 683ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 684ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 685ca94c3ddSJeremy 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`. 686ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 687ca94c3ddSJeremy 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. 688ca94c3ddSJeremy 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). 689ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 69077d1c127SSebastian Grimberg 69177d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 69277d1c127SSebastian Grimberg 69377d1c127SSebastian Grimberg @ref User 69477d1c127SSebastian Grimberg **/ 69577d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 6960c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 69777d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 698fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 69977d1c127SSebastian Grimberg Ceed delegate; 70077d1c127SSebastian Grimberg 70177d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 702ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateCurlOriented"); 70377d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 70477d1c127SSebastian Grimberg curl_orients, rstr)); 70577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 70677d1c127SSebastian Grimberg } 70777d1c127SSebastian Grimberg 708e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 70977d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 710ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 711ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 71277d1c127SSebastian Grimberg 71377d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 714fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 71577d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 71677d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 71777d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 71877d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 71977d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 72077d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 721*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 722e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 723e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 724fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 725fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 726fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 727fc0567d9Srezgarshakeri } 728fc0567d9Srezgarshakeri 729fc0567d9Srezgarshakeri /** 730ca94c3ddSJeremy L Thompson @brief Create a strided `CeedElemRestriction` 731d7b241e6Sjeremylt 732ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 733ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 734ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 735ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 736fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 737fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 738ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 739ca94c3ddSJeremy 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]`. 740ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 741972f909dSJeremy L Thompson `CEED_STRIDES_BACKEND` should only be used pass data between `CeedOperator` created with the same `Ceed` backend. 742972f909dSJeremy L Thompson The L-vector layout will, in general, be different between `Ceed` backends. 743ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 744d7b241e6Sjeremylt 745b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 746dfdf5a53Sjeremylt 7477a982d89SJeremy L. Thompson @ref User 748b11c1e72Sjeremylt **/ 7492b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 750f90c8643Sjeremylt CeedElemRestriction *rstr) { 7515fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 7525fe0d4faSjeremylt Ceed delegate; 753b04eb3d9SSebastian Grimberg 7542b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 755ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateStrided"); 7562b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 757e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7585fe0d4faSjeremylt } 7595fe0d4faSjeremylt 760e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7616574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 762ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 763e7f679fcSJeremy L Thompson CeedCheck(l_size >= num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector size must be at least num_elem * elem_size * num_comp"); 764e022e1f8SJeremy L Thompson 7652b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 766db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 767d1d35e2fSjeremylt (*rstr)->ref_count = 1; 768d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 769d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 770d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 771d1d35e2fSjeremylt (*rstr)->l_size = l_size; 772*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 773e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 774e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 775fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 7762b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 7772b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 778fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 779e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 780d7b241e6Sjeremylt } 781d7b241e6Sjeremylt 782d7b241e6Sjeremylt /** 783ca94c3ddSJeremy 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. 7843ac8f562SJeremy L Thompson 7853ac8f562SJeremy L Thompson The offsets array is arranged as 7863ac8f562SJeremy L Thompson 7873ac8f562SJeremy L Thompson element_0_start_index 7883ac8f562SJeremy L Thompson element_1_start_index 7893ac8f562SJeremy L Thompson ... 7903ac8f562SJeremy L Thompson element_n_start_index 7913ac8f562SJeremy L Thompson element_n_stop_index 7923ac8f562SJeremy L Thompson element_0_point_0 7933ac8f562SJeremy L Thompson element_0_point_1 7943ac8f562SJeremy L Thompson ... 7953ac8f562SJeremy L Thompson 796ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 797ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 798ca94c3ddSJeremy L Thompson @param[in] num_points Number of points described in the `offsets` array 7993ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 8003ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 8013ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 8023ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 803ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 804ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 805ca94c3ddSJeremy L Thompson @param[in] offsets Array of size `num_elem + 1 + num_points`. 8063ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 8073ac8f562SJeremy L Thompson The second portion holds the indices for each element. 808ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 8093ac8f562SJeremy L Thompson 8103ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8113ac8f562SJeremy L Thompson 8123ac8f562SJeremy L Thompson @ref Backend 8133ac8f562SJeremy L Thompson **/ 8143ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 8153ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 8163ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 8173ac8f562SJeremy L Thompson Ceed delegate; 8183ac8f562SJeremy L Thompson 8193ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 820ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateAtPoints"); 8213ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 8223ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 8233ac8f562SJeremy L Thompson } 8243ac8f562SJeremy L Thompson 8253ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8263ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 827ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 8283ac8f562SJeremy L Thompson CeedCheck(l_size >= num_points * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector must be at least num_points * num_comp"); 8293ac8f562SJeremy L Thompson 8303ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 8313ac8f562SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 8323ac8f562SJeremy L Thompson (*rstr)->ref_count = 1; 8333ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 8343ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 8353ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 8363ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 837*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_points * (CeedSize)num_comp; 83805fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 8393ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 8403ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 8413ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 8423ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 8433ac8f562SJeremy L Thompson } 8443ac8f562SJeremy L Thompson 8453ac8f562SJeremy L Thompson /** 846ca94c3ddSJeremy L Thompson @brief Create a blocked `CeedElemRestriction`, typically only used by backends 847d7b241e6Sjeremylt 848ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 849ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 850ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 851e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 852ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 853fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 854ca94c3ddSJeremy 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`. 855fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 856fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 857ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 858ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 859ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 860ca94c3ddSJeremy 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`. 861ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 862ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 863ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 864ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 865d7b241e6Sjeremylt 866b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 867dfdf5a53Sjeremylt 8687a982d89SJeremy L. Thompson @ref Backend 869b11c1e72Sjeremylt **/ 870e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 8712b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 8724ce2993fSjeremylt CeedElemRestriction *rstr) { 8731c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 874d7b241e6Sjeremylt 8755fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 8765fe0d4faSjeremylt Ceed delegate; 8776574a04fSJeremy L Thompson 8782b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 879ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlocked"); 880e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 881e7f679fcSJeremy L Thompson rstr)); 882e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8835fe0d4faSjeremylt } 884d7b241e6Sjeremylt 885e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8866574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 887e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 888ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 889ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 890e022e1f8SJeremy L Thompson 891e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 892e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 893d7b241e6Sjeremylt 894db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 895db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 896d1d35e2fSjeremylt (*rstr)->ref_count = 1; 897d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 898d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 899d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 900d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 901d1d35e2fSjeremylt (*rstr)->l_size = l_size; 902*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 903e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 904e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 90561a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 906e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 9071c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 908e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 909d7b241e6Sjeremylt } 910d7b241e6Sjeremylt 911b11c1e72Sjeremylt /** 912ca94c3ddSJeremy L Thompson @brief Create a blocked oriented `CeedElemRestriction`, typically only used by backends 91377d1c127SSebastian Grimberg 914ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 915ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 91677d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 917e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 91877d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 919fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 920ca94c3ddSJeremy 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`. 921fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 922fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 923ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 924ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 925ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 926ca94c3ddSJeremy 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`. 927ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 928ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 929ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 930ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation. 931ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to `offsets`. 932ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 93377d1c127SSebastian Grimberg 93477d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 93577d1c127SSebastian Grimberg 93677d1c127SSebastian Grimberg @ref Backend 93777d1c127SSebastian Grimberg **/ 938e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 939e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 940e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 941e7f679fcSJeremy L Thompson bool *block_orients; 9421c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 94377d1c127SSebastian Grimberg 944fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 94577d1c127SSebastian Grimberg Ceed delegate; 94677d1c127SSebastian Grimberg 94777d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 948ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedOriented"); 949e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 95077d1c127SSebastian Grimberg offsets, orients, rstr)); 95177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 95277d1c127SSebastian Grimberg } 95377d1c127SSebastian Grimberg 95477d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 955e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 956ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 957ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 95877d1c127SSebastian Grimberg 959e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 960e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 961e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 962e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 96377d1c127SSebastian Grimberg 964fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 965fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 96677d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 96777d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 96877d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 96977d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 97077d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 97177d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 972*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 973e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 974e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 975fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 976e7f679fcSJeremy L Thompson CeedCall( 977e7f679fcSJeremy L Thompson ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, *rstr)); 9781c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 97977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 98077d1c127SSebastian Grimberg } 98177d1c127SSebastian Grimberg 98277d1c127SSebastian Grimberg /** 983ca94c3ddSJeremy L Thompson @brief Create a blocked curl-oriented `CeedElemRestriction`, typically only used by backends 98477d1c127SSebastian Grimberg 985ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 986ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 98777d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 988e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 98977d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 990fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 991ca94c3ddSJeremy 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`. 992fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 993fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 994ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 995ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 996ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 997ca94c3ddSJeremy 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`. 998ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 999ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 1000ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 1001ca94c3ddSJeremy 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. 1002ca94c3ddSJeremy 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). 1003ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to offsets. 1004ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 100577d1c127SSebastian Grimberg 100677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 100777d1c127SSebastian Grimberg 100877d1c127SSebastian Grimberg @ref Backend 100977d1c127SSebastian Grimberg **/ 1010e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 101177d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 10120c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 1013e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 10141c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 101577d1c127SSebastian Grimberg 1016fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 101777d1c127SSebastian Grimberg Ceed delegate; 101877d1c127SSebastian Grimberg 101977d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1020ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedCurlOriented"); 1021e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 1022e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 102377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 102477d1c127SSebastian Grimberg } 102577d1c127SSebastian Grimberg 1026e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 102777d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1028e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1029ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1030ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 103177d1c127SSebastian Grimberg 1032e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 1033e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 1034e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 1035e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 103677d1c127SSebastian Grimberg 1037fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 1038fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 103977d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 104077d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 104177d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 104277d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 104377d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 104477d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 1045*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1046e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1047e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1048fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 1049e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 1050e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 10511c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 105277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 105377d1c127SSebastian Grimberg } 105477d1c127SSebastian Grimberg 105577d1c127SSebastian Grimberg /** 1056ca94c3ddSJeremy L Thompson @brief Create a blocked strided `CeedElemRestriction`, typically only used by backends 10577509a596Sjeremylt 1058ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1059ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 1060ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 1061e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 1062ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1063fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1064fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1065ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 1066ca94c3ddSJeremy 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]`. 1067ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 1068ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 10697509a596Sjeremylt 10707509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 10717509a596Sjeremylt 10727a982d89SJeremy L. Thompson @ref User 10737509a596Sjeremylt **/ 1074e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 10758621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 1076e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 10777509a596Sjeremylt 10787509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 10797509a596Sjeremylt Ceed delegate; 10806574a04fSJeremy L Thompson 10812b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1082ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedStrided"); 1083e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 1084e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10857509a596Sjeremylt } 10867509a596Sjeremylt 1087e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 10886574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1089e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1090ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1091e7f679fcSJeremy L Thompson CeedCheck(l_size >= num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector size must be at least num_elem * elem_size * num_comp"); 1092e022e1f8SJeremy L Thompson 10932b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 1094db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 1095d1d35e2fSjeremylt (*rstr)->ref_count = 1; 1096d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 1097d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 1098d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 1099d1d35e2fSjeremylt (*rstr)->l_size = l_size; 1100*1203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1101e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1102e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1103fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 11042b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 11052b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 1106fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 1107e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11087509a596Sjeremylt } 11097509a596Sjeremylt 11107509a596Sjeremylt /** 1111ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unsigned version. 1112c17ec2beSJeremy L Thompson 1113ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 1114c17ec2beSJeremy L Thompson 1115ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unsigned reference to 1116ca94c3ddSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned `CeedElemRestriction` 1117c17ec2beSJeremy L Thompson 1118c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1119c17ec2beSJeremy L Thompson 1120c17ec2beSJeremy L Thompson @ref User 1121c17ec2beSJeremy L Thompson **/ 1122c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1123c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1124c17ec2beSJeremy L Thompson 1125c17ec2beSJeremy L Thompson // Copy old rstr 1126c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1127c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 1128c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 1129c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 1130c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1131c17ec2beSJeremy L Thompson if (rstr->strides) { 1132c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1133c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1134c17ec2beSJeremy L Thompson } 11357c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1136c17ec2beSJeremy L Thompson 1137c17ec2beSJeremy L Thompson // Override Apply 1138c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1139c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1140c17ec2beSJeremy L Thompson } 1141c17ec2beSJeremy L Thompson 1142c17ec2beSJeremy L Thompson /** 1143ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unoriented version. 11447c1dbaffSSebastian Grimberg 1145ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 11467c1dbaffSSebastian Grimberg 1147ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unoriented reference to 1148ca94c3ddSJeremy L Thompson @param[in,out] rstr_unoriented Variable to store unoriented `CeedElemRestriction` 11497c1dbaffSSebastian Grimberg 11507c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 11517c1dbaffSSebastian Grimberg 11527c1dbaffSSebastian Grimberg @ref User 11537c1dbaffSSebastian Grimberg **/ 11547c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 11557c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 11567c1dbaffSSebastian Grimberg 11577c1dbaffSSebastian Grimberg // Copy old rstr 11587c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 11597c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 11607c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 11617c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 11627c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 11637c1dbaffSSebastian Grimberg if (rstr->strides) { 11647c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 11657c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 11667c1dbaffSSebastian Grimberg } 11677c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 11687c1dbaffSSebastian Grimberg 11697c1dbaffSSebastian Grimberg // Override Apply 11707c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 11717c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 11727c1dbaffSSebastian Grimberg } 11737c1dbaffSSebastian Grimberg 11747c1dbaffSSebastian Grimberg /** 1175ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction`. 11769fd66db6SSebastian Grimberg 1177ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 11789560d06aSjeremylt 1179ca94c3ddSJeremy 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`. 1180ca94c3ddSJeremy L Thompson This `CeedElemRestriction` will be destroyed if `*rstr_copy` is the only reference to this `CeedElemRestriction`. 1181ea61e9acSJeremy L Thompson 1182ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to copy reference to 1183ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 11849560d06aSjeremylt 11859560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 11869560d06aSjeremylt 11879560d06aSjeremylt @ref User 11889560d06aSjeremylt **/ 11892b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1190393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 11912b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 11929560d06aSjeremylt *rstr_copy = rstr; 11939560d06aSjeremylt return CEED_ERROR_SUCCESS; 11949560d06aSjeremylt } 11959560d06aSjeremylt 11969560d06aSjeremylt /** 1197ca94c3ddSJeremy L Thompson @brief Create `CeedVector` associated with a `CeedElemRestriction` 1198b11c1e72Sjeremylt 1199ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1200ca94c3ddSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or `NULL` 1201ca94c3ddSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or `NULL` 1202b11c1e72Sjeremylt 1203b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1204dfdf5a53Sjeremylt 12057a982d89SJeremy L. Thompson @ref User 1206b11c1e72Sjeremylt **/ 12072b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1208d2643443SJeremy L Thompson CeedSize e_size, l_size; 1209*1203703bSJeremy L Thompson Ceed ceed; 121048acf710SJeremy L Thompson 1211*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 1212*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 1213*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 1214*1203703bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(ceed, l_size, l_vec)); 1215*1203703bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(ceed, e_size, e_vec)); 1216e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1217d7b241e6Sjeremylt } 1218d7b241e6Sjeremylt 1219d7b241e6Sjeremylt /** 1220d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1221d7b241e6Sjeremylt 1222ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1223ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1224ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1225ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[num_elem * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1226fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1227ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1228b11c1e72Sjeremylt 1229b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1230dfdf5a53Sjeremylt 12317a982d89SJeremy L. Thompson @ref User 1232b11c1e72Sjeremylt **/ 12332b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1234701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1235701e7d35SJeremy L Thompson CeedInt num_elem; 1236*1203703bSJeremy L Thompson Ceed ceed; 1237d7b241e6Sjeremylt 1238*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 1239d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1240701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_ru_len)); 1241701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1242d7b241e6Sjeremylt } else { 1243701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_u_len)); 1244701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1245d7b241e6Sjeremylt } 1246701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 1247*1203703bSJeremy L Thompson CeedCheck(min_u_len <= len, ceed, CEED_ERROR_DIMENSION, 1248701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1249701e7d35SJeremy L Thompson min_u_len); 1250701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 1251*1203703bSJeremy L Thompson CeedCheck(min_ru_len <= len, ceed, CEED_ERROR_DIMENSION, 1252701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1253701e7d35SJeremy L Thompson min_ru_len); 1254701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 1255701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1256e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1257d7b241e6Sjeremylt } 1258d7b241e6Sjeremylt 1259d7b241e6Sjeremylt /** 12603ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 12613ac8f562SJeremy L Thompson 1262ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1263ca94c3ddSJeremy L Thompson @param[in] elem Element number in range `[0, num_elem)` 12643ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1265ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1266ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape [`num_points * num_comp]` when `t_mode` = @ref CEED_NOTRANSPOSE). 12673ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 12683ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 12693ac8f562SJeremy L Thompson 12703ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 12713ac8f562SJeremy L Thompson 12723ac8f562SJeremy L Thompson @ref User 12733ac8f562SJeremy L Thompson **/ 127405fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 12753ac8f562SJeremy L Thompson CeedRequest *request) { 1276701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1277701e7d35SJeremy L Thompson CeedInt num_elem; 1278*1203703bSJeremy L Thompson Ceed ceed; 12793ac8f562SJeremy L Thompson 1280*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 12813ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 1282701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1283701e7d35SJeremy L Thompson 1284701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1285701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1286701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1287701e7d35SJeremy L Thompson min_ru_len = (CeedSize)num_points * (CeedSize)num_comp; 12883ac8f562SJeremy L Thompson } else { 1289701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1290701e7d35SJeremy L Thompson 1291701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1292701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1293701e7d35SJeremy L Thompson min_u_len = (CeedSize)num_points * (CeedSize)num_comp; 1294701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 12953ac8f562SJeremy L Thompson } 1296701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 1297*1203703bSJeremy L Thompson CeedCheck(min_u_len <= len, ceed, CEED_ERROR_DIMENSION, 12983ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 12993ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1300701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1301701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 1302*1203703bSJeremy L Thompson CeedCheck(min_ru_len <= len, ceed, CEED_ERROR_DIMENSION, 13033ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 13043ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1305701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1306701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 1307*1203703bSJeremy L Thompson CeedCheck(elem < num_elem, ceed, CEED_ERROR_DIMENSION, 1308701e7d35SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, num_elem); 1309701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 13103ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 13113ac8f562SJeremy L Thompson } 13123ac8f562SJeremy L Thompson 13133ac8f562SJeremy L Thompson /** 1314d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1315be9261b7Sjeremylt 1316ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1317ca94c3ddSJeremy 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]` 1318ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1319ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1320ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[block_size * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1321fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1322ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1323be9261b7Sjeremylt 1324be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1325be9261b7Sjeremylt 13267a982d89SJeremy L. Thompson @ref Backend 1327be9261b7Sjeremylt **/ 13282b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 13292b730f8bSJeremy L Thompson CeedRequest *request) { 1330701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1331701e7d35SJeremy L Thompson CeedInt block_size, num_elem; 1332*1203703bSJeremy L Thompson Ceed ceed; 1333be9261b7Sjeremylt 1334*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 1335*1203703bSJeremy L Thompson CeedCheck(rstr->ApplyBlock, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionApplyBlock"); 13366402da51SJeremy L Thompson 1337701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetBlockSize(rstr, &block_size)); 1338d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1339701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1340701e7d35SJeremy L Thompson 1341701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1342701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1343701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1344701e7d35SJeremy L Thompson min_ru_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1345be9261b7Sjeremylt } else { 1346701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1347701e7d35SJeremy L Thompson 1348701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1349701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1350701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1351701e7d35SJeremy L Thompson min_u_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1352be9261b7Sjeremylt } 1353701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 1354*1203703bSJeremy L Thompson CeedCheck(min_u_len == len, ceed, CEED_ERROR_DIMENSION, 1355701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1356701e7d35SJeremy L Thompson min_ru_len); 1357701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 1358*1203703bSJeremy L Thompson CeedCheck(min_ru_len == len, ceed, CEED_ERROR_DIMENSION, 1359701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1360701e7d35SJeremy L Thompson min_u_len); 1361701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 1362*1203703bSJeremy L Thompson CeedCheck(block_size * block <= num_elem, ceed, CEED_ERROR_DIMENSION, 1363701e7d35SJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, block_size * block, 1364701e7d35SJeremy L Thompson num_elem); 13652b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1366e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1367be9261b7Sjeremylt } 1368be9261b7Sjeremylt 1369be9261b7Sjeremylt /** 1370ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedElemRestriction` 1371b7c9bbdaSJeremy L Thompson 1372ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1373ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1374b7c9bbdaSJeremy L Thompson 1375b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1376b7c9bbdaSJeremy L Thompson 1377b7c9bbdaSJeremy L Thompson @ref Advanced 1378b7c9bbdaSJeremy L Thompson **/ 1379b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1380b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1381b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1382b7c9bbdaSJeremy L Thompson } 1383b7c9bbdaSJeremy L Thompson 1384b7c9bbdaSJeremy L Thompson /** 1385d979a051Sjeremylt @brief Get the L-vector component stride 1386a681ae63Sjeremylt 1387ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1388d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1389a681ae63Sjeremylt 1390a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1391a681ae63Sjeremylt 1392b7c9bbdaSJeremy L Thompson @ref Advanced 1393a681ae63Sjeremylt **/ 13942b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1395d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1396e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1397a681ae63Sjeremylt } 1398a681ae63Sjeremylt 1399a681ae63Sjeremylt /** 1400ca94c3ddSJeremy L Thompson @brief Get the total number of elements in the range of a `CeedElemRestriction` 1401a681ae63Sjeremylt 1402ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1403d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1404a681ae63Sjeremylt 1405a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1406a681ae63Sjeremylt 1407b7c9bbdaSJeremy L Thompson @ref Advanced 1408a681ae63Sjeremylt **/ 14092b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1410d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1411e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1412a681ae63Sjeremylt } 1413a681ae63Sjeremylt 1414a681ae63Sjeremylt /** 1415ca94c3ddSJeremy L Thompson @brief Get the size of elements in the `CeedElemRestriction` 1416a681ae63Sjeremylt 1417ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1418d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1419a681ae63Sjeremylt 1420a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1421a681ae63Sjeremylt 1422b7c9bbdaSJeremy L Thompson @ref Advanced 1423a681ae63Sjeremylt **/ 14242b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1425d1d35e2fSjeremylt *elem_size = rstr->elem_size; 14262c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 14272c7e7413SJeremy L Thompson } 14282c7e7413SJeremy L Thompson 14292c7e7413SJeremy L Thompson /** 143007d5dec1SJeremy L Thompson 1431ca94c3ddSJeremy L Thompson @brief Get the number of points in the l-vector for a points `CeedElemRestriction` 143207d5dec1SJeremy L Thompson 1433ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 143407d5dec1SJeremy L Thompson @param[out] num_points The number of points in the l-vector 143507d5dec1SJeremy L Thompson 143607d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 143707d5dec1SJeremy L Thompson 1438c63574e3SJeremy L Thompson @ref User 143907d5dec1SJeremy L Thompson **/ 144007d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) { 1441*1203703bSJeremy L Thompson CeedRestrictionType rstr_type; 144207d5dec1SJeremy L Thompson Ceed ceed; 144307d5dec1SJeremy L Thompson 144407d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 1445*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 1446*1203703bSJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 144707d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 144807d5dec1SJeremy L Thompson 144907d5dec1SJeremy L Thompson *num_points = rstr->num_points; 145007d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 145107d5dec1SJeremy L Thompson } 145207d5dec1SJeremy L Thompson 145307d5dec1SJeremy L Thompson /** 145407d5dec1SJeremy L Thompson 1455ca94c3ddSJeremy L Thompson @brief Get the number of points in an element of a `CeedElemRestriction` at points 145607d5dec1SJeremy L Thompson 1457ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 145807d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 145907d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 146007d5dec1SJeremy L Thompson 146107d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 146207d5dec1SJeremy L Thompson 1463c63574e3SJeremy L Thompson @ref User 146407d5dec1SJeremy L Thompson **/ 146507d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 1466*1203703bSJeremy L Thompson CeedRestrictionType rstr_type; 146707d5dec1SJeremy L Thompson const CeedInt *offsets; 1468*1203703bSJeremy L Thompson Ceed ceed; 146907d5dec1SJeremy L Thompson 147007d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 1471*1203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 1472*1203703bSJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 147307d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 147407d5dec1SJeremy L Thompson 147507d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 147607d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem]; 147707d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 147807d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 147907d5dec1SJeremy L Thompson } 148007d5dec1SJeremy L Thompson 148107d5dec1SJeremy L Thompson /** 1482ca94c3ddSJeremy L Thompson @brief Get the maximum number of points in an element for a `CeedElemRestriction` at points 14832c7e7413SJeremy L Thompson 1484ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 14852c7e7413SJeremy L Thompson @param[out] max_points Variable to store size of elements 14862c7e7413SJeremy L Thompson 14872c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14882c7e7413SJeremy L Thompson 14892c7e7413SJeremy L Thompson @ref Advanced 14902c7e7413SJeremy L Thompson **/ 14912c7e7413SJeremy L Thompson int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 14922c7e7413SJeremy L Thompson CeedInt num_elem; 14932c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 1494*1203703bSJeremy L Thompson Ceed ceed; 14952c7e7413SJeremy L Thompson 14962c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 14972c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 14982c7e7413SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 14992c7e7413SJeremy L Thompson "Cannot compute max points for a CeedElemRestriction that does not use points"); 15002c7e7413SJeremy L Thompson 15012c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 15022c7e7413SJeremy L Thompson *max_points = 0; 15032c7e7413SJeremy L Thompson for (CeedInt e = 0; e < num_elem; e++) { 15042c7e7413SJeremy L Thompson CeedInt num_points; 15052c7e7413SJeremy L Thompson 15062c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 15072c7e7413SJeremy L Thompson *max_points = CeedIntMax(num_points, *max_points); 15082c7e7413SJeremy L Thompson } 1509e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1510a681ae63Sjeremylt } 1511a681ae63Sjeremylt 1512a681ae63Sjeremylt /** 1513ca94c3ddSJeremy L Thompson @brief Get the size of the l-vector for a `CeedElemRestriction` 1514a681ae63Sjeremylt 1515ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1516701e7d35SJeremy L Thompson @param[out] l_size Variable to store l-vector size 1517a681ae63Sjeremylt 1518a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1519a681ae63Sjeremylt 1520b7c9bbdaSJeremy L Thompson @ref Advanced 1521a681ae63Sjeremylt **/ 15222b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1523d1d35e2fSjeremylt *l_size = rstr->l_size; 1524e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1525a681ae63Sjeremylt } 1526a681ae63Sjeremylt 1527a681ae63Sjeremylt /** 1528701e7d35SJeremy L Thompson @brief Get the size of the e-vector for a `CeedElemRestriction` 1529701e7d35SJeremy L Thompson 1530701e7d35SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1531701e7d35SJeremy L Thompson @param[out] e_size Variable to store e-vector size 1532701e7d35SJeremy L Thompson 1533701e7d35SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1534701e7d35SJeremy L Thompson 1535701e7d35SJeremy L Thompson @ref Advanced 1536701e7d35SJeremy L Thompson **/ 1537701e7d35SJeremy L Thompson int CeedElemRestrictionGetEVectorSize(CeedElemRestriction rstr, CeedSize *e_size) { 1538701e7d35SJeremy L Thompson *e_size = rstr->e_size; 1539701e7d35SJeremy L Thompson return CEED_ERROR_SUCCESS; 1540701e7d35SJeremy L Thompson } 1541701e7d35SJeremy L Thompson 1542701e7d35SJeremy L Thompson /** 1543ca94c3ddSJeremy L Thompson @brief Get the number of components in the elements of a `CeedElemRestriction` 1544a681ae63Sjeremylt 1545ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1546d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1547a681ae63Sjeremylt 1548a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1549a681ae63Sjeremylt 1550b7c9bbdaSJeremy L Thompson @ref Advanced 1551a681ae63Sjeremylt **/ 15522b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1553d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1554e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1555a681ae63Sjeremylt } 1556a681ae63Sjeremylt 1557a681ae63Sjeremylt /** 1558ca94c3ddSJeremy L Thompson @brief Get the number of blocks in a `CeedElemRestriction` 1559a681ae63Sjeremylt 1560ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1561d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1562a681ae63Sjeremylt 1563a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1564a681ae63Sjeremylt 1565b7c9bbdaSJeremy L Thompson @ref Advanced 1566a681ae63Sjeremylt **/ 15672b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1568e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1569e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1570a681ae63Sjeremylt } 1571a681ae63Sjeremylt 1572a681ae63Sjeremylt /** 1573ca94c3ddSJeremy L Thompson @brief Get the size of blocks in the `CeedElemRestriction` 1574a681ae63Sjeremylt 1575ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1576e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1577a681ae63Sjeremylt 1578a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1579a681ae63Sjeremylt 1580b7c9bbdaSJeremy L Thompson @ref Advanced 1581a681ae63Sjeremylt **/ 1582e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1583e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1584e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1585a681ae63Sjeremylt } 1586a681ae63Sjeremylt 1587a681ae63Sjeremylt /** 1588ca94c3ddSJeremy L Thompson @brief Get the multiplicity of nodes in a `CeedElemRestriction` 15891469ee4dSjeremylt 1590ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1591ca94c3ddSJeremy L Thompson @param[out] mult Vector to store multiplicity (of size `l_size`) 15921469ee4dSjeremylt 15931469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 15941469ee4dSjeremylt 15957a982d89SJeremy L. Thompson @ref User 15961469ee4dSjeremylt **/ 15972b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1598d1d35e2fSjeremylt CeedVector e_vec; 15991469ee4dSjeremylt 160025509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 16012b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 16021469ee4dSjeremylt 160325509ebbSRezgar Shakeri // Compute e_vec = E * 1 16042b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 16052b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 160625509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 16072b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 16082b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 16091469ee4dSjeremylt // Cleanup 16102b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1611e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 16121469ee4dSjeremylt } 16131469ee4dSjeremylt 16141469ee4dSjeremylt /** 1615ca94c3ddSJeremy L Thompson @brief View a `CeedElemRestriction` 1616f02ca4a2SJed Brown 1617ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view 1618ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1619f02ca4a2SJed Brown 1620f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1621f02ca4a2SJed Brown 16227a982d89SJeremy L. Thompson @ref User 1623f02ca4a2SJed Brown **/ 1624f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 16250930e4e7SJeremy L Thompson CeedRestrictionType rstr_type; 16260930e4e7SJeremy L Thompson 16270930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 16280930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 16290930e4e7SJeremy L Thompson CeedInt max_points; 16300930e4e7SJeremy L Thompson 16310930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points)); 16320930e4e7SJeremy L Thompson fprintf(stream, 1633249f8407SJeremy L Thompson "CeedElemRestriction at points from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT 16340930e4e7SJeremy L Thompson " points on an element\n", 16350930e4e7SJeremy L Thompson rstr->l_size, rstr->num_comp, rstr->num_elem, max_points); 16360930e4e7SJeremy L Thompson } else { 1637249f8407SJeremy L Thompson char strides_str[500]; 16381c66c397SJeremy L Thompson 16392b730f8bSJeremy L Thompson if (rstr->strides) { 1640249f8407SJeremy L Thompson sprintf(strides_str, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 16412b730f8bSJeremy L Thompson } else { 1642249f8407SJeremy L Thompson sprintf(strides_str, "%" CeedInt_FMT, rstr->comp_stride); 16432b730f8bSJeremy L Thompson } 1644249f8407SJeremy L Thompson fprintf(stream, 1645249f8407SJeremy L Thompson "%sCeedElemRestriction from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT 1646249f8407SJeremy L Thompson " nodes each and %s %s\n", 1647e7f679fcSJeremy L Thompson rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1648249f8407SJeremy L Thompson rstr->strides ? "strides" : "component stride", strides_str); 16490930e4e7SJeremy L Thompson } 1650e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1651f02ca4a2SJed Brown } 1652f02ca4a2SJed Brown 1653f02ca4a2SJed Brown /** 1654ca94c3ddSJeremy L Thompson @brief Destroy a `CeedElemRestriction` 1655b11c1e72Sjeremylt 1656ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to destroy 1657b11c1e72Sjeremylt 1658b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1659dfdf5a53Sjeremylt 16607a982d89SJeremy L. Thompson @ref User 1661b11c1e72Sjeremylt **/ 16624ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1663393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1664ad6481ceSJeremy L Thompson *rstr = NULL; 1665ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1666ad6481ceSJeremy L Thompson } 16676574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 16686574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1669c17ec2beSJeremy L Thompson 1670c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 16717c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1672c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1673c17ec2beSJeremy L Thompson 16742b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 16752b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 16762b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1677e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1678d7b241e6Sjeremylt } 1679d7b241e6Sjeremylt 1680d7b241e6Sjeremylt /// @} 1681