19ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, 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 101b0f67a9cSJeremy L Thompson /** 102b0f67a9cSJeremy L Thompson @brief View a `CeedElemRestriction` passed as a `CeedObject` 103b0f67a9cSJeremy L Thompson 104b0f67a9cSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view 105b0f67a9cSJeremy L Thompson @param[in] stream Filestream to write to 106b0f67a9cSJeremy L Thompson 107b0f67a9cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 108b0f67a9cSJeremy L Thompson 109b0f67a9cSJeremy L Thompson @ref Developer 110b0f67a9cSJeremy L Thompson **/ 111b0f67a9cSJeremy L Thompson static int CeedElemRestrictionView_Object(CeedObject rstr, FILE *stream) { 112b0f67a9cSJeremy L Thompson CeedCall(CeedElemRestrictionView((CeedElemRestriction)rstr, stream)); 113b0f67a9cSJeremy L Thompson return CEED_ERROR_SUCCESS; 114b0f67a9cSJeremy L Thompson } 115b0f67a9cSJeremy L Thompson 116*6c328a79SJeremy L Thompson /** 117*6c328a79SJeremy L Thompson @brief Destroy a `CeedElemRestricton` passed as a `CeedObject` 118*6c328a79SJeremy L Thompson 119*6c328a79SJeremy L Thompson @param[in,out] rstr Address of `CeedElemRestriction` to destroy 120*6c328a79SJeremy L Thompson 121*6c328a79SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 122*6c328a79SJeremy L Thompson 123*6c328a79SJeremy L Thompson @ref Developer 124*6c328a79SJeremy L Thompson **/ 125*6c328a79SJeremy L Thompson static int CeedElemRestrictionDestroy_Object(CeedObject *rstr) { 126*6c328a79SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy((CeedElemRestriction *)rstr)); 127*6c328a79SJeremy L Thompson return CEED_ERROR_SUCCESS; 128*6c328a79SJeremy L Thompson } 129*6c328a79SJeremy L Thompson 1307a982d89SJeremy L. Thompson /// @} 1317a982d89SJeremy L. Thompson 1327a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1337a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 1347a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1357a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 1367a982d89SJeremy L. Thompson /// @{ 1377a982d89SJeremy L. Thompson 1387a982d89SJeremy L. Thompson /** 139ca94c3ddSJeremy L Thompson @brief Get the type of a `CeedElemRestriction` 140a681ae63Sjeremylt 141ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 142fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 143fcbe8c06SSebastian Grimberg 144fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 145fcbe8c06SSebastian Grimberg 146fcbe8c06SSebastian Grimberg @ref Backend 147fcbe8c06SSebastian Grimberg **/ 148fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 149fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 150fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 151fcbe8c06SSebastian Grimberg } 152fcbe8c06SSebastian Grimberg 153fcbe8c06SSebastian Grimberg /** 154ca94c3ddSJeremy L Thompson @brief Get the strided status of a `CeedElemRestriction` 155fcbe8c06SSebastian Grimberg 156ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 157ca94c3ddSJeremy L Thompson @param[out] is_strided Variable to store strided status 158ca94c3ddSJeremy L Thompson 159ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 160ca94c3ddSJeremy L Thompson 161ca94c3ddSJeremy L Thompson @ref Backend 162fcbe8c06SSebastian Grimberg **/ 163fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 164fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 165fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 166fcbe8c06SSebastian Grimberg } 167fcbe8c06SSebastian Grimberg 168fcbe8c06SSebastian Grimberg /** 169ca94c3ddSJeremy L Thompson @brief Get the points status of a `CeedElemRestriction` 1703ac8f562SJeremy L Thompson 171ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 172ca94c3ddSJeremy L Thompson @param[out] is_points Variable to store points status 173ca94c3ddSJeremy L Thompson 174ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 175ca94c3ddSJeremy L Thompson 176ca94c3ddSJeremy L Thompson @ref Backend 1773ac8f562SJeremy L Thompson **/ 178637baffdSJeremy L Thompson int CeedElemRestrictionIsAtPoints(CeedElemRestriction rstr, bool *is_points) { 1793ac8f562SJeremy L Thompson *is_points = (rstr->rstr_type == CEED_RESTRICTION_POINTS); 1803ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 1813ac8f562SJeremy L Thompson } 1823ac8f562SJeremy L Thompson 1833ac8f562SJeremy L Thompson /** 184ca94c3ddSJeremy L Thompson @brief Check if two `CeedElemRestriction` created with @ref CeedElemRestrictionCreateAtPoints() and use the same points per element 18548acf710SJeremy L Thompson 186ca94c3ddSJeremy L Thompson @param[in] rstr_a First `CeedElemRestriction` 187ca94c3ddSJeremy L Thompson @param[in] rstr_b Second `CeedElemRestriction` 18848acf710SJeremy L Thompson @param[out] are_compatible Variable to store compatibility status 189ca94c3ddSJeremy L Thompson 190ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 191ca94c3ddSJeremy L Thompson 192ca94c3ddSJeremy L Thompson @ref Backend 19348acf710SJeremy L Thompson **/ 19448acf710SJeremy L Thompson int CeedElemRestrictionAtPointsAreCompatible(CeedElemRestriction rstr_a, CeedElemRestriction rstr_b, bool *are_compatible) { 19548acf710SJeremy L Thompson CeedInt num_elem_a, num_elem_b, num_points_a, num_points_b; 19648acf710SJeremy L Thompson 19748acf710SJeremy L Thompson // Cannot compare non-points restrictions 1989bc66399SJeremy L Thompson CeedCheck(rstr_a->rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr_a), CEED_ERROR_UNSUPPORTED, 1999bc66399SJeremy L Thompson "First CeedElemRestriction must be AtPoints"); 2009bc66399SJeremy L Thompson CeedCheck(rstr_b->rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr_a), CEED_ERROR_UNSUPPORTED, 2019bc66399SJeremy L Thompson "Second CeedElemRestriction must be AtPoints"); 20248acf710SJeremy L Thompson 20348acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_a, &num_elem_a)); 20448acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_b, &num_elem_b)); 20548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_a, &num_points_a)); 20648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_b, &num_points_b)); 20748acf710SJeremy L Thompson 20848acf710SJeremy L Thompson // Check size and contents of offsets arrays 20948acf710SJeremy L Thompson *are_compatible = true; 21048acf710SJeremy L Thompson if (num_elem_a != num_elem_b) *are_compatible = false; 21148acf710SJeremy L Thompson if (num_points_a != num_points_b) *are_compatible = false; 21248acf710SJeremy L Thompson if (*are_compatible) { 21348acf710SJeremy L Thompson const CeedInt *offsets_a, *offsets_b; 21448acf710SJeremy L Thompson 21548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_a, CEED_MEM_HOST, &offsets_a)); 21648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_b, CEED_MEM_HOST, &offsets_b)); 21748acf710SJeremy L Thompson for (CeedInt i = 0; i < num_elem_a + 1 + num_points_a; i++) *are_compatible &= offsets_a[i] == offsets_b[i]; 21848acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_a, &offsets_a)); 21948acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_b, &offsets_b)); 22048acf710SJeremy L Thompson } 22148acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 22248acf710SJeremy L Thompson } 22348acf710SJeremy L Thompson 22448acf710SJeremy L Thompson /** 225ca94c3ddSJeremy L Thompson @brief Get the strides of a strided `CeedElemRestriction` 2267a982d89SJeremy L. Thompson 227ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 228a681ae63Sjeremylt @param[out] strides Variable to store strides array 2297a982d89SJeremy L. Thompson 2307a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2317a982d89SJeremy L. Thompson 2327a982d89SJeremy L. Thompson @ref Backend 2337a982d89SJeremy L. Thompson **/ 23456c48462SJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt strides[3]) { 2356e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 23656c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) strides[i] = rstr->strides[i]; 237e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2387a982d89SJeremy L. Thompson } 2397a982d89SJeremy L. Thompson 2407a982d89SJeremy L. Thompson /** 241ca94c3ddSJeremy L Thompson @brief Get the backend stride status of a `CeedElemRestriction` 24277d1c127SSebastian Grimberg 243ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 24477d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 24577d1c127SSebastian Grimberg 24677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 24777d1c127SSebastian Grimberg 24877d1c127SSebastian Grimberg @ref Backend 24977d1c127SSebastian Grimberg **/ 25077d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 2516e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 25277d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 25377d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 25477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 25577d1c127SSebastian Grimberg } 25677d1c127SSebastian Grimberg 25777d1c127SSebastian Grimberg /** 258ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` offsets array by @ref CeedMemType 259bd33150aSjeremylt 260ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve offsets 261fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 262fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 263ca94c3ddSJeremy L Thompson @param[out] offsets Array on memory type `mem_type` 264bd33150aSjeremylt 265bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 266bd33150aSjeremylt 267bd33150aSjeremylt @ref User 268bd33150aSjeremylt **/ 2692b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 2707c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2717c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 272c17ec2beSJeremy L Thompson } else { 2736e536b99SJeremy L Thompson CeedCheck(rstr->GetOffsets, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 2741ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetOffsets"); 2752b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 276d1d35e2fSjeremylt rstr->num_readers++; 277c17ec2beSJeremy L Thompson } 278e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 279430758c8SJeremy L Thompson } 280430758c8SJeremy L Thompson 281430758c8SJeremy L Thompson /** 282ca94c3ddSJeremy L Thompson @brief Restore an offsets array obtained using @ref CeedElemRestrictionGetOffsets() 283430758c8SJeremy L Thompson 284ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 285ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 286430758c8SJeremy L Thompson 287430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 288430758c8SJeremy L Thompson 289430758c8SJeremy L Thompson @ref User 290430758c8SJeremy L Thompson **/ 2912b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2927c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2937c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 294c17ec2beSJeremy L Thompson } else { 295430758c8SJeremy L Thompson *offsets = NULL; 296d1d35e2fSjeremylt rstr->num_readers--; 297c17ec2beSJeremy L Thompson } 298e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 299bd33150aSjeremylt } 300bd33150aSjeremylt 301bd33150aSjeremylt /** 302ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` orientations array by @ref CeedMemType 3033ac43b2cSJeremy L Thompson 304ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve orientations 305fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 306fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 307ca94c3ddSJeremy L Thompson @param[out] orients Array on memory type `mem_type` 3083ac43b2cSJeremy L Thompson 3093ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3103ac43b2cSJeremy L Thompson 31177d1c127SSebastian Grimberg @ref User 3123ac43b2cSJeremy L Thompson **/ 31377d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 3146e536b99SJeremy L Thompson CeedCheck(rstr->GetOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 3151ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetOrientations"); 31677d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 31777d1c127SSebastian Grimberg rstr->num_readers++; 318e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3193ac43b2cSJeremy L Thompson } 3203ac43b2cSJeremy L Thompson 3213ac43b2cSJeremy L Thompson /** 322ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetOrientations() 323b435c5a6Srezgarshakeri 324ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 32577d1c127SSebastian Grimberg @param[in] orients Array of orientation data 326b435c5a6Srezgarshakeri 327b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 328b435c5a6Srezgarshakeri 32977d1c127SSebastian Grimberg @ref User 330b435c5a6Srezgarshakeri **/ 33177d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 33277d1c127SSebastian Grimberg *orients = NULL; 33377d1c127SSebastian Grimberg rstr->num_readers--; 334b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 335b435c5a6Srezgarshakeri } 336b435c5a6Srezgarshakeri 337b435c5a6Srezgarshakeri /** 338ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` curl-conforming orientations array by @ref CeedMemType 3397a982d89SJeremy L. Thompson 340ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve curl-conforming orientations 341fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 342fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 343ca94c3ddSJeremy L Thompson @param[out] curl_orients Array on memory type `mem_type` 3447a982d89SJeremy L. Thompson 3457a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3467a982d89SJeremy L. Thompson 34777d1c127SSebastian Grimberg @ref User 3487a982d89SJeremy L. Thompson **/ 3490c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 3506e536b99SJeremy L Thompson CeedCheck(rstr->GetCurlOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 3511ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetCurlOrientations"); 35277d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 35377d1c127SSebastian Grimberg rstr->num_readers++; 35477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 35577d1c127SSebastian Grimberg } 35677d1c127SSebastian Grimberg 35777d1c127SSebastian Grimberg /** 358ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetCurlOrientations() 35977d1c127SSebastian Grimberg 360ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 36177d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 36277d1c127SSebastian Grimberg 36377d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 36477d1c127SSebastian Grimberg 36577d1c127SSebastian Grimberg @ref User 36677d1c127SSebastian Grimberg **/ 3670c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 36877d1c127SSebastian Grimberg *curl_orients = NULL; 36977d1c127SSebastian Grimberg rstr->num_readers--; 370e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3717a982d89SJeremy L. Thompson } 3727a982d89SJeremy L. Thompson 3737a982d89SJeremy L. Thompson /** 37449fd234cSJeremy L Thompson 37522eb1385SJeremy L Thompson @brief Get the L-vector layout of a strided `CeedElemRestriction` 37622eb1385SJeremy L Thompson 37722eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 37822eb1385SJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 37922eb1385SJeremy 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]`. 38022eb1385SJeremy L Thompson 38122eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 38222eb1385SJeremy L Thompson 38322eb1385SJeremy L Thompson @ref Backend 38422eb1385SJeremy L Thompson **/ 38556c48462SJeremy L Thompson int CeedElemRestrictionGetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 38622eb1385SJeremy L Thompson bool has_backend_strides; 38722eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 38822eb1385SJeremy L Thompson 38922eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 3909bc66399SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, 3919bc66399SJeremy L Thompson "Only strided CeedElemRestriction have strided L-vector layout"); 39222eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 39322eb1385SJeremy L Thompson if (has_backend_strides) { 3949bc66399SJeremy L Thompson CeedCheck(rstr->l_layout[0], CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no L-vector layout data"); 39556c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->l_layout[i]; 39622eb1385SJeremy L Thompson } else { 39722eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetStrides(rstr, layout)); 39822eb1385SJeremy L Thompson } 39922eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 40022eb1385SJeremy L Thompson } 40122eb1385SJeremy L Thompson 40222eb1385SJeremy L Thompson /** 40322eb1385SJeremy L Thompson 40422eb1385SJeremy L Thompson @brief Set the L-vector layout of a strided `CeedElemRestriction` 40522eb1385SJeremy L Thompson 40622eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 40722eb1385SJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 40822eb1385SJeremy 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]`. 40922eb1385SJeremy L Thompson 41022eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 41122eb1385SJeremy L Thompson 41222eb1385SJeremy L Thompson @ref Backend 41322eb1385SJeremy L Thompson **/ 41422eb1385SJeremy L Thompson int CeedElemRestrictionSetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 41522eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 41622eb1385SJeremy L Thompson 41722eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 4186e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, 4196e536b99SJeremy L Thompson "Only strided CeedElemRestriction have strided L-vector layout"); 42022eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->l_layout[i] = layout[i]; 42122eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 42222eb1385SJeremy L Thompson } 42322eb1385SJeremy L Thompson 42422eb1385SJeremy L Thompson /** 42522eb1385SJeremy L Thompson 426ca94c3ddSJeremy L Thompson @brief Get the E-vector layout of a `CeedElemRestriction` 42749fd234cSJeremy L Thompson 428ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 429ca94c3ddSJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 430ca94c3ddSJeremy 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]`. 43149fd234cSJeremy L Thompson 43249fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 43349fd234cSJeremy L Thompson 43449fd234cSJeremy L Thompson @ref Backend 43549fd234cSJeremy L Thompson **/ 43656c48462SJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 4376e536b99SJeremy L Thompson CeedCheck(rstr->e_layout[0], CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no E-vector layout data"); 43856c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->e_layout[i]; 439e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 44049fd234cSJeremy L Thompson } 44149fd234cSJeremy L Thompson 44249fd234cSJeremy L Thompson /** 44349fd234cSJeremy L Thompson 444ca94c3ddSJeremy L Thompson @brief Set the E-vector layout of a `CeedElemRestriction` 44549fd234cSJeremy L Thompson 446ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 447ca94c3ddSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 448ca94c3ddSJeremy 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]`. 44949fd234cSJeremy L Thompson 45049fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 45149fd234cSJeremy L Thompson 45249fd234cSJeremy L Thompson @ref Backend 45349fd234cSJeremy L Thompson **/ 4542b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 45522eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->e_layout[i] = layout[i]; 456e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 45749fd234cSJeremy L Thompson } 45849fd234cSJeremy L Thompson 45949fd234cSJeremy L Thompson /** 46019605835SJeremy L Thompson 46119605835SJeremy L Thompson @brief Get the E-vector element offset of a `CeedElemRestriction` at points 46219605835SJeremy L Thompson 46319605835SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 46419605835SJeremy L Thompson @param[in] elem Element number index into E-vector for 46519605835SJeremy L Thompson @param[out] elem_offset Offset for element `elem` in the E-vector. 46619605835SJeremy L Thompson The data for point `i`, component `j`, element `elem` in the E-vector is given by `i*e_layout[0] + j*e_layout[1] + elem_offset`. 46719605835SJeremy L Thompson 46819605835SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 46919605835SJeremy L Thompson 47019605835SJeremy L Thompson @ref Backend 47119605835SJeremy L Thompson **/ 47219605835SJeremy L Thompson int CeedElemRestrictionGetAtPointsElementOffset(CeedElemRestriction rstr, CeedInt elem, CeedSize *elem_offset) { 47319605835SJeremy L Thompson CeedInt num_comp; 47419605835SJeremy L Thompson CeedRestrictionType rstr_type; 47519605835SJeremy L Thompson 47619605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 47719605835SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 47819605835SJeremy L Thompson "Can only compute offset for a points CeedElemRestriction"); 47919605835SJeremy L Thompson 48019605835SJeremy L Thompson // Backend method 48119605835SJeremy L Thompson if (rstr->GetAtPointsElementOffset) { 48219605835SJeremy L Thompson CeedCall(rstr->GetAtPointsElementOffset(rstr, elem, elem_offset)); 48319605835SJeremy L Thompson return CEED_ERROR_SUCCESS; 48419605835SJeremy L Thompson } 48519605835SJeremy L Thompson 48619605835SJeremy L Thompson // Default layout (CPU) 48719605835SJeremy L Thompson *elem_offset = 0; 48819605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 48919605835SJeremy L Thompson for (CeedInt i = 0; i < elem; i++) { 49019605835SJeremy L Thompson CeedInt num_points; 49119605835SJeremy L Thompson 49219605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, i, &num_points)); 49319605835SJeremy L Thompson *elem_offset += num_points * num_comp; 49419605835SJeremy L Thompson } 49519605835SJeremy L Thompson return CEED_ERROR_SUCCESS; 49619605835SJeremy L Thompson } 49719605835SJeremy L Thompson 49819605835SJeremy L Thompson /** 499ff1bc20eSJeremy L Thompson 500ff1bc20eSJeremy L Thompson @brief Set the E-vector size of a `CeedElemRestriction` at points 501ff1bc20eSJeremy L Thompson 502ff1bc20eSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` 503ff1bc20eSJeremy L Thompson @param[in] e_size New E-vector size; must be longer than the current E-vector size 504ff1bc20eSJeremy L Thompson 505ff1bc20eSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 506ff1bc20eSJeremy L Thompson 507ff1bc20eSJeremy L Thompson @ref Backend 508ff1bc20eSJeremy L Thompson **/ 509ff1bc20eSJeremy L Thompson int CeedElemRestrictionSetAtPointsEVectorSize(CeedElemRestriction rstr, CeedSize e_size) { 510ff1bc20eSJeremy L Thompson CeedRestrictionType rstr_type; 511ff1bc20eSJeremy L Thompson 512ff1bc20eSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 5139bc66399SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 5149bc66399SJeremy L Thompson "Can only compute offset for a points CeedElemRestriction"); 5159bc66399SJeremy L Thompson CeedCheck(e_size >= rstr->e_size, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 5163f08121cSJeremy L Thompson "Can only increase the size of the E-vector for the CeedElemRestriction." 5173f08121cSJeremy L Thompson " Current size: %" CeedSize_FMT " New size: %" CeedSize_FMT, 5183f08121cSJeremy L Thompson rstr->e_size, e_size); 519ff1bc20eSJeremy L Thompson rstr->e_size = e_size; 520ff1bc20eSJeremy L Thompson return CEED_ERROR_SUCCESS; 521ff1bc20eSJeremy L Thompson } 522ff1bc20eSJeremy L Thompson 523ff1bc20eSJeremy L Thompson /** 524ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedElemRestriction` 5257a982d89SJeremy L. Thompson 526ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 5277a982d89SJeremy L. Thompson @param[out] data Variable to store data 5287a982d89SJeremy L. Thompson 5297a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5307a982d89SJeremy L. Thompson 5317a982d89SJeremy L. Thompson @ref Backend 5327a982d89SJeremy L. Thompson **/ 533777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 534777ff853SJeremy L Thompson *(void **)data = rstr->data; 535e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5367a982d89SJeremy L. Thompson } 5377a982d89SJeremy L. Thompson 5387a982d89SJeremy L. Thompson /** 539ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedElemRestriction` 5407a982d89SJeremy L. Thompson 541ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` 542ea61e9acSJeremy L Thompson @param[in] data Data to set 5437a982d89SJeremy L. Thompson 5447a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5457a982d89SJeremy L. Thompson 5467a982d89SJeremy L. Thompson @ref Backend 5477a982d89SJeremy L. Thompson **/ 548777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 549777ff853SJeremy L Thompson rstr->data = data; 550e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5517a982d89SJeremy L. Thompson } 5527a982d89SJeremy L. Thompson 55334359f16Sjeremylt /** 554ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedElemRestriction` 55534359f16Sjeremylt 556ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to increment the reference counter 55734359f16Sjeremylt 55834359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 55934359f16Sjeremylt 56034359f16Sjeremylt @ref Backend 56134359f16Sjeremylt **/ 5629560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 563b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)rstr)); 56434359f16Sjeremylt return CEED_ERROR_SUCCESS; 56534359f16Sjeremylt } 56634359f16Sjeremylt 5676e15d496SJeremy L Thompson /** 568ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedElemRestriction` in `t_mode` 5696e15d496SJeremy L Thompson 570ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to estimate FLOPs for 571ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 572ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5736e15d496SJeremy L Thompson 5746e15d496SJeremy L Thompson @ref Backend 5756e15d496SJeremy L Thompson **/ 5762b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 5771203703bSJeremy L Thompson CeedSize e_size, scale = 0; 57889edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 5791c66c397SJeremy L Thompson 5801203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 58189edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 58277d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 58389edb9e3SSebastian Grimberg switch (rstr_type) { 5843ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 5853ac8f562SJeremy L Thompson scale = 0; 5863ac8f562SJeremy L Thompson break; 58789edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 58889edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 58977d1c127SSebastian Grimberg scale = 1; 59089edb9e3SSebastian Grimberg break; 59189edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 59277d1c127SSebastian Grimberg scale = 2; 59389edb9e3SSebastian Grimberg break; 59489edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 59577d1c127SSebastian Grimberg scale = 6; 59689edb9e3SSebastian Grimberg break; 5976e15d496SJeremy L Thompson } 59877d1c127SSebastian Grimberg } else { 59989edb9e3SSebastian Grimberg switch (rstr_type) { 60089edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 60189edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 6023ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 60377d1c127SSebastian Grimberg scale = 0; 60489edb9e3SSebastian Grimberg break; 60589edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 60677d1c127SSebastian Grimberg scale = 1; 60789edb9e3SSebastian Grimberg break; 60889edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 60977d1c127SSebastian Grimberg scale = 5; 61089edb9e3SSebastian Grimberg break; 61177d1c127SSebastian Grimberg } 61277d1c127SSebastian Grimberg } 6136e15d496SJeremy L Thompson *flops = e_size * scale; 6146e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 6156e15d496SJeremy L Thompson } 6166e15d496SJeremy L Thompson 6177a982d89SJeremy L. Thompson /// @} 6187a982d89SJeremy L. Thompson 61915910d16Sjeremylt /// @cond DOXYGEN_SKIP 62015910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 62115910d16Sjeremylt /// @endcond 62215910d16Sjeremylt 6237a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6247a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 6257a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6267a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 627d7b241e6Sjeremylt /// @{ 628d7b241e6Sjeremylt 6297a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 63045f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 6317a982d89SJeremy L. Thompson 632ca94c3ddSJeremy L Thompson /// Argument for @ref CeedOperatorSetField() indicating that the field does not require a `CeedElemRestriction` 6332b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 6347a982d89SJeremy L. Thompson 635d7b241e6Sjeremylt /** 636ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` 637d7b241e6Sjeremylt 638ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 639ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 640ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 641ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 642fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 643ca94c3ddSJeremy 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`. 644fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 645fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 646ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 647ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 648ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 649ca94c3ddSJeremy 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. 650ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 651ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 652d7b241e6Sjeremylt 653b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 654dfdf5a53Sjeremylt 6557a982d89SJeremy L. Thompson @ref User 656b11c1e72Sjeremylt **/ 6572b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 6582b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 6595fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6605fe0d4faSjeremylt Ceed delegate; 6616574a04fSJeremy L Thompson 6622b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 663ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreate"); 6642b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 6659bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 666e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6675fe0d4faSjeremylt } 6685fe0d4faSjeremylt 669e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6706574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 671ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 672ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 673e022e1f8SJeremy L Thompson 6742b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 675*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 676d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 677d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 678d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 679d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 680d1d35e2fSjeremylt (*rstr)->l_size = l_size; 6811203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 682e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 683e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 68461a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 685fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 686e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 687d7b241e6Sjeremylt } 688d7b241e6Sjeremylt 689d7b241e6Sjeremylt /** 690ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with orientation signs 691fc0567d9Srezgarshakeri 692ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 693ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 694ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 695ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 696fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 697ca94c3ddSJeremy 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`. 698fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 699fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 700ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 701ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 702ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 703ca94c3ddSJeremy 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`. 704ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 705ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation 706ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 707fc0567d9Srezgarshakeri 708fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 709fc0567d9Srezgarshakeri 710fc0567d9Srezgarshakeri @ref User 711fc0567d9Srezgarshakeri **/ 7122b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 71377d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 714fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 715fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 716fc0567d9Srezgarshakeri Ceed delegate; 7176574a04fSJeremy L Thompson 7182b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 719ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateOriented"); 7201a8516d0SJames Wright CeedCall(CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, 7211a8516d0SJames Wright rstr)); 7229bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 723fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 724fc0567d9Srezgarshakeri } 725fc0567d9Srezgarshakeri 726e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7276574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 728ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 729ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 730e022e1f8SJeremy L Thompson 7312b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 732*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 733fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 734fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 735fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 736fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 737fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 7381203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 739e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 740e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 741fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 742fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 74377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 74477d1c127SSebastian Grimberg } 74577d1c127SSebastian Grimberg 74677d1c127SSebastian Grimberg /** 747ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with a general tridiagonal transformation matrix for curl-conforming elements 74877d1c127SSebastian Grimberg 749ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 750ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 75177d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 75277d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 753fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 754ca94c3ddSJeremy 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`. 755fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 756fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 757ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 758ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 759ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 760ca94c3ddSJeremy 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`. 761ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 762ca94c3ddSJeremy 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. 763ca94c3ddSJeremy 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). 764ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 76577d1c127SSebastian Grimberg 76677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 76777d1c127SSebastian Grimberg 76877d1c127SSebastian Grimberg @ref User 76977d1c127SSebastian Grimberg **/ 77077d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 7710c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 77277d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 773fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 77477d1c127SSebastian Grimberg Ceed delegate; 77577d1c127SSebastian Grimberg 77677d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 777ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateCurlOriented"); 77877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 77977d1c127SSebastian Grimberg curl_orients, rstr)); 7809bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 78177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 78277d1c127SSebastian Grimberg } 78377d1c127SSebastian Grimberg 784e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 78577d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 786ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 787ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 78877d1c127SSebastian Grimberg 78977d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 790*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 79177d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 79277d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 79377d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 79477d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 79577d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 7961203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 797e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 798e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 799fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 800fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 801fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 802fc0567d9Srezgarshakeri } 803fc0567d9Srezgarshakeri 804fc0567d9Srezgarshakeri /** 805ca94c3ddSJeremy L Thompson @brief Create a strided `CeedElemRestriction` 806d7b241e6Sjeremylt 807ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 808ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 809ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 810ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 811fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 812fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 813ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 814ca94c3ddSJeremy 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]`. 815ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 816972f909dSJeremy L Thompson `CEED_STRIDES_BACKEND` should only be used pass data between `CeedOperator` created with the same `Ceed` backend. 817972f909dSJeremy L Thompson The L-vector layout will, in general, be different between `Ceed` backends. 818ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 819d7b241e6Sjeremylt 820b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 821dfdf5a53Sjeremylt 8227a982d89SJeremy L. Thompson @ref User 823b11c1e72Sjeremylt **/ 8242b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 825f90c8643Sjeremylt CeedElemRestriction *rstr) { 8265fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 8275fe0d4faSjeremylt Ceed delegate; 828b04eb3d9SSebastian Grimberg 8292b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 830ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateStrided"); 8312b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 8329bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 833e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8345fe0d4faSjeremylt } 8355fe0d4faSjeremylt 836e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8376574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 838ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 839aa72de07SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, ceed, CEED_ERROR_DIMENSION, 840870ea2d9SJeremy L Thompson "L-vector size must be at least num_elem * elem_size * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT, 841870ea2d9SJeremy L Thompson (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, l_size); 842e022e1f8SJeremy L Thompson 8432b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 844*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 845d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 846d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 847d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 848d1d35e2fSjeremylt (*rstr)->l_size = l_size; 8491203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 850e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 851e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 852fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 8532b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 8542b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 855fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 856e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 857d7b241e6Sjeremylt } 858d7b241e6Sjeremylt 859d7b241e6Sjeremylt /** 860ca94c3ddSJeremy 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. 8613ac8f562SJeremy L Thompson 8623ac8f562SJeremy L Thompson The offsets array is arranged as 8633ac8f562SJeremy L Thompson 8643ac8f562SJeremy L Thompson element_0_start_index 8653ac8f562SJeremy L Thompson element_1_start_index 8663ac8f562SJeremy L Thompson ... 8673ac8f562SJeremy L Thompson element_n_start_index 8683ac8f562SJeremy L Thompson element_n_stop_index 8693ac8f562SJeremy L Thompson element_0_point_0 8703ac8f562SJeremy L Thompson element_0_point_1 8713ac8f562SJeremy L Thompson ... 8723ac8f562SJeremy L Thompson 873ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 874ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 875ca94c3ddSJeremy L Thompson @param[in] num_points Number of points described in the `offsets` array 8763ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 8773ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 8783ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 8793ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 880ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 881ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 882ca94c3ddSJeremy L Thompson @param[in] offsets Array of size `num_elem + 1 + num_points`. 8833ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 8843ac8f562SJeremy L Thompson The second portion holds the indices for each element. 885ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 8863ac8f562SJeremy L Thompson 8873ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8883ac8f562SJeremy L Thompson 8893ac8f562SJeremy L Thompson @ref Backend 8903ac8f562SJeremy L Thompson **/ 8913ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 8923ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 8933ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 8943ac8f562SJeremy L Thompson Ceed delegate; 8953ac8f562SJeremy L Thompson 8963ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 897ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateAtPoints"); 8983ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 8999bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 9003ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 9013ac8f562SJeremy L Thompson } 9023ac8f562SJeremy L Thompson 9033ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 9043ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 905ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 906870ea2d9SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_points * num_comp, ceed, CEED_ERROR_DIMENSION, 907870ea2d9SJeremy L Thompson "L-vector must be at least num_points * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT, (CeedSize)num_points * num_comp, 908870ea2d9SJeremy L Thompson l_size); 9093ac8f562SJeremy L Thompson 9103ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 911*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 9123ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 9133ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 9143ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 9152c2c926cSJeremy L Thompson (*rstr)->comp_stride = 1; 9163ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 9171203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_points * (CeedSize)num_comp; 91805fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 9193ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 9203ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 9213ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 9223ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 9233ac8f562SJeremy L Thompson } 9243ac8f562SJeremy L Thompson 9253ac8f562SJeremy L Thompson /** 926ca94c3ddSJeremy L Thompson @brief Create a blocked `CeedElemRestriction`, typically only used by backends 927d7b241e6Sjeremylt 928ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 929ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 930ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 931e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 932ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 933fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 934ca94c3ddSJeremy 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`. 935fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 936fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 937ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 938ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 939ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 940ca94c3ddSJeremy 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`. 941ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 942ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 943ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 944ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 945d7b241e6Sjeremylt 946b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 947dfdf5a53Sjeremylt 9487a982d89SJeremy L. Thompson @ref Backend 949b11c1e72Sjeremylt **/ 950e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 9512b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 9524ce2993fSjeremylt CeedElemRestriction *rstr) { 9531c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 954d7b241e6Sjeremylt 9555fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 9565fe0d4faSjeremylt Ceed delegate; 9576574a04fSJeremy L Thompson 9582b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 959ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlocked"); 960e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 961e7f679fcSJeremy L Thompson rstr)); 9629bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 963e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9645fe0d4faSjeremylt } 965d7b241e6Sjeremylt 966e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 9676574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 968e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 969ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 970ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 971e022e1f8SJeremy L Thompson 972e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 973e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 974d7b241e6Sjeremylt 975db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 976*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 977d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 978d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 979d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 980d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 981d1d35e2fSjeremylt (*rstr)->l_size = l_size; 9821203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 983e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 984e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 98561a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 986e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 9871c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 988e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 989d7b241e6Sjeremylt } 990d7b241e6Sjeremylt 991b11c1e72Sjeremylt /** 992ca94c3ddSJeremy L Thompson @brief Create a blocked oriented `CeedElemRestriction`, typically only used by backends 99377d1c127SSebastian Grimberg 994ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 995ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 99677d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 997e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 99877d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 999fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 1000ca94c3ddSJeremy 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`. 1001fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1002fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1003ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 1004ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 1005ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 1006ca94c3ddSJeremy 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`. 1007ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 1008ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 1009ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 1010ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation. 1011ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to `offsets`. 1012ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 101377d1c127SSebastian Grimberg 101477d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 101577d1c127SSebastian Grimberg 101677d1c127SSebastian Grimberg @ref Backend 101777d1c127SSebastian Grimberg **/ 1018e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 1019e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 1020e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 1021e7f679fcSJeremy L Thompson bool *block_orients; 10221c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 102377d1c127SSebastian Grimberg 1024fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 102577d1c127SSebastian Grimberg Ceed delegate; 102677d1c127SSebastian Grimberg 102777d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1028ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedOriented"); 1029e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 103077d1c127SSebastian Grimberg offsets, orients, rstr)); 10319bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 103277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 103377d1c127SSebastian Grimberg } 103477d1c127SSebastian Grimberg 103577d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1036e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1037ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1038ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 103977d1c127SSebastian Grimberg 1040e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 1041e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 1042e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 1043e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 104477d1c127SSebastian Grimberg 1045fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 1046*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 104777d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 104877d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 104977d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 105077d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 105177d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 10521203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1053e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1054e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1055fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 10561a8516d0SJames Wright CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, 10571a8516d0SJames Wright *rstr)); 10581c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 105977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 106077d1c127SSebastian Grimberg } 106177d1c127SSebastian Grimberg 106277d1c127SSebastian Grimberg /** 1063ca94c3ddSJeremy L Thompson @brief Create a blocked curl-oriented `CeedElemRestriction`, typically only used by backends 106477d1c127SSebastian Grimberg 1065ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1066ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 106777d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 1068e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 106977d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1070fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 1071ca94c3ddSJeremy 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`. 1072fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1073fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1074ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 1075ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 1076ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 1077ca94c3ddSJeremy 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`. 1078ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 1079ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 1080ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 1081ca94c3ddSJeremy 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. 1082ca94c3ddSJeremy 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). 1083ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to offsets. 1084ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 108577d1c127SSebastian Grimberg 108677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 108777d1c127SSebastian Grimberg 108877d1c127SSebastian Grimberg @ref Backend 108977d1c127SSebastian Grimberg **/ 1090e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 109177d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 10920c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 1093e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 10941c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 109577d1c127SSebastian Grimberg 1096fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 109777d1c127SSebastian Grimberg Ceed delegate; 109877d1c127SSebastian Grimberg 109977d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1100ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedCurlOriented"); 1101e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 1102e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 11039bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 110477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 110577d1c127SSebastian Grimberg } 110677d1c127SSebastian Grimberg 1107e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 110877d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1109e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1110ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1111ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 111277d1c127SSebastian Grimberg 1113e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 1114e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 1115e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 1116e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 111777d1c127SSebastian Grimberg 1118fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 1119*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 112077d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 112177d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 112277d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 112377d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 112477d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 11251203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1126e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1127e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1128fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 1129e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 1130e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 11311c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 113277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 113377d1c127SSebastian Grimberg } 113477d1c127SSebastian Grimberg 113577d1c127SSebastian Grimberg /** 1136ca94c3ddSJeremy L Thompson @brief Create a blocked strided `CeedElemRestriction`, typically only used by backends 11377509a596Sjeremylt 1138ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1139ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 1140ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 1141e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 1142ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1143fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1144fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1145ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 1146ca94c3ddSJeremy 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]`. 1147ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 1148ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 11497509a596Sjeremylt 11507509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 11517509a596Sjeremylt 11527a982d89SJeremy L. Thompson @ref User 11537509a596Sjeremylt **/ 1154e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 11558621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 1156e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 11577509a596Sjeremylt 11587509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 11597509a596Sjeremylt Ceed delegate; 11606574a04fSJeremy L Thompson 11612b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1162ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedStrided"); 1163e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 11649bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 1165e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11667509a596Sjeremylt } 11677509a596Sjeremylt 1168e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 11696574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1170e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1171ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1172aa72de07SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, ceed, CEED_ERROR_DIMENSION, 1173870ea2d9SJeremy L Thompson "L-vector size must be at least num_elem * elem_size * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT, 1174870ea2d9SJeremy L Thompson (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, l_size); 1175e022e1f8SJeremy L Thompson 11762b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 1177*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj)); 1178d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 1179d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 1180d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 1181d1d35e2fSjeremylt (*rstr)->l_size = l_size; 11821203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1183e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1184e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1185fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 11862b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 11872b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 1188fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 1189e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11907509a596Sjeremylt } 11917509a596Sjeremylt 11927509a596Sjeremylt /** 1193ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unsigned version. 1194c17ec2beSJeremy L Thompson 1195ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 1196c17ec2beSJeremy L Thompson 1197ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unsigned reference to 1198ca94c3ddSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned `CeedElemRestriction` 1199c17ec2beSJeremy L Thompson 1200c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1201c17ec2beSJeremy L Thompson 1202c17ec2beSJeremy L Thompson @ref User 1203c17ec2beSJeremy L Thompson **/ 1204c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1205c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1206c17ec2beSJeremy L Thompson 1207c17ec2beSJeremy L Thompson // Copy old rstr 1208c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1209*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(CeedElemRestrictionReturnCeed(rstr), CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, 1210*6c328a79SJeremy L Thompson &(*rstr_unsigned)->obj)); 1211c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1212c17ec2beSJeremy L Thompson if (rstr->strides) { 1213c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1214c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1215c17ec2beSJeremy L Thompson } 12167c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1217c17ec2beSJeremy L Thompson 1218c17ec2beSJeremy L Thompson // Override Apply 1219c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1220c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1221c17ec2beSJeremy L Thompson } 1222c17ec2beSJeremy L Thompson 1223c17ec2beSJeremy L Thompson /** 1224ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unoriented version. 12257c1dbaffSSebastian Grimberg 1226ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 12277c1dbaffSSebastian Grimberg 1228ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unoriented reference to 1229ca94c3ddSJeremy L Thompson @param[in,out] rstr_unoriented Variable to store unoriented `CeedElemRestriction` 12307c1dbaffSSebastian Grimberg 12317c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 12327c1dbaffSSebastian Grimberg 12337c1dbaffSSebastian Grimberg @ref User 12347c1dbaffSSebastian Grimberg **/ 12357c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 12367c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 12377c1dbaffSSebastian Grimberg 12387c1dbaffSSebastian Grimberg // Copy old rstr 12397c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 1240*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(CeedElemRestrictionReturnCeed(rstr), CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, 1241*6c328a79SJeremy L Thompson &(*rstr_unoriented)->obj)); 12427c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 12437c1dbaffSSebastian Grimberg if (rstr->strides) { 12447c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 12457c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 12467c1dbaffSSebastian Grimberg } 12477c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 12487c1dbaffSSebastian Grimberg 12497c1dbaffSSebastian Grimberg // Override Apply 12507c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 12517c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 12527c1dbaffSSebastian Grimberg } 12537c1dbaffSSebastian Grimberg 12547c1dbaffSSebastian Grimberg /** 1255ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction`. 12569fd66db6SSebastian Grimberg 1257ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 12589560d06aSjeremylt 1259ca94c3ddSJeremy 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`. 1260ca94c3ddSJeremy L Thompson This `CeedElemRestriction` will be destroyed if `*rstr_copy` is the only reference to this `CeedElemRestriction`. 1261ea61e9acSJeremy L Thompson 1262ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to copy reference to 1263ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 12649560d06aSjeremylt 12659560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 12669560d06aSjeremylt 12679560d06aSjeremylt @ref User 12689560d06aSjeremylt **/ 12692b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1270393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 12712b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 12729560d06aSjeremylt *rstr_copy = rstr; 12739560d06aSjeremylt return CEED_ERROR_SUCCESS; 12749560d06aSjeremylt } 12759560d06aSjeremylt 12769560d06aSjeremylt /** 1277ca94c3ddSJeremy L Thompson @brief Create `CeedVector` associated with a `CeedElemRestriction` 1278b11c1e72Sjeremylt 1279ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1280ca94c3ddSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or `NULL` 1281ca94c3ddSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or `NULL` 1282b11c1e72Sjeremylt 1283b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1284dfdf5a53Sjeremylt 12857a982d89SJeremy L. Thompson @ref User 1286b11c1e72Sjeremylt **/ 12872b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1288d2643443SJeremy L Thompson CeedSize e_size, l_size; 12891203703bSJeremy L Thompson Ceed ceed; 129048acf710SJeremy L Thompson 12911203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 12921203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 12931203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 12941203703bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(ceed, l_size, l_vec)); 12951203703bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(ceed, e_size, e_vec)); 12969bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed)); 1297e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1298d7b241e6Sjeremylt } 1299d7b241e6Sjeremylt 1300d7b241e6Sjeremylt /** 1301d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1302d7b241e6Sjeremylt 1303ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1304ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1305ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1306ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[num_elem * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1307fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1308ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1309b11c1e72Sjeremylt 1310b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1311dfdf5a53Sjeremylt 13127a982d89SJeremy L. Thompson @ref User 1313b11c1e72Sjeremylt **/ 13142b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1315701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1316701e7d35SJeremy L Thompson CeedInt num_elem; 1317d7b241e6Sjeremylt 1318d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1319701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_ru_len)); 1320701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1321d7b241e6Sjeremylt } else { 1322701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_u_len)); 1323701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1324d7b241e6Sjeremylt } 1325701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 13269bc66399SJeremy L Thompson CeedCheck(min_u_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1327701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1328701e7d35SJeremy L Thompson min_u_len); 1329701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 13309bc66399SJeremy L Thompson CeedCheck(min_ru_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1331701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1332701e7d35SJeremy L Thompson min_ru_len); 1333701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 1334701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1335e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1336d7b241e6Sjeremylt } 1337d7b241e6Sjeremylt 1338d7b241e6Sjeremylt /** 13393ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 13403ac8f562SJeremy L Thompson 1341ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1342ca94c3ddSJeremy L Thompson @param[in] elem Element number in range `[0, num_elem)` 13433ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1344ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1345ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape [`num_points * num_comp]` when `t_mode` = @ref CEED_NOTRANSPOSE). 13463ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 13473ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 13483ac8f562SJeremy L Thompson 13493ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13503ac8f562SJeremy L Thompson 13513ac8f562SJeremy L Thompson @ref User 13523ac8f562SJeremy L Thompson **/ 135305fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 13543ac8f562SJeremy L Thompson CeedRequest *request) { 1355701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1356701e7d35SJeremy L Thompson CeedInt num_elem; 13573ac8f562SJeremy L Thompson 13589bc66399SJeremy L Thompson CeedCheck(rstr->ApplyAtPointsInElement, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 13599bc66399SJeremy L Thompson "Backend does not implement CeedElemRestrictionApplyAtPointsInElement"); 13601ef3a2a9SJeremy L Thompson 13613ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 1362701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1363701e7d35SJeremy L Thompson 1364701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1365701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1366701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1367701e7d35SJeremy L Thompson min_ru_len = (CeedSize)num_points * (CeedSize)num_comp; 13683ac8f562SJeremy L Thompson } else { 1369701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1370701e7d35SJeremy L Thompson 1371701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1372701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1373701e7d35SJeremy L Thompson min_u_len = (CeedSize)num_points * (CeedSize)num_comp; 1374701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 13753ac8f562SJeremy L Thompson } 1376701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 13779bc66399SJeremy L Thompson CeedCheck(min_u_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 13783ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 13793ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1380701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1381701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 13829bc66399SJeremy L Thompson CeedCheck(min_ru_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 13833ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 13843ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1385701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1386701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 13879bc66399SJeremy L Thompson CeedCheck(elem < num_elem, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1388701e7d35SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, num_elem); 1389701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 13903ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 13913ac8f562SJeremy L Thompson } 13923ac8f562SJeremy L Thompson 13933ac8f562SJeremy L Thompson /** 1394d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1395be9261b7Sjeremylt 1396ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1397ca94c3ddSJeremy 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]` 1398ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1399ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1400ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[block_size * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1401fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1402ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1403be9261b7Sjeremylt 1404be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1405be9261b7Sjeremylt 14067a982d89SJeremy L. Thompson @ref Backend 1407be9261b7Sjeremylt **/ 14082b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 14092b730f8bSJeremy L Thompson CeedRequest *request) { 1410701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1411701e7d35SJeremy L Thompson CeedInt block_size, num_elem; 1412be9261b7Sjeremylt 14139bc66399SJeremy L Thompson CeedCheck(rstr->ApplyBlock, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 14149bc66399SJeremy L Thompson "Backend does not implement CeedElemRestrictionApplyBlock"); 14156402da51SJeremy L Thompson 1416701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetBlockSize(rstr, &block_size)); 1417d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1418701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1419701e7d35SJeremy L Thompson 1420701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1421701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1422701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1423701e7d35SJeremy L Thompson min_ru_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1424be9261b7Sjeremylt } else { 1425701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1426701e7d35SJeremy L Thompson 1427701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1428701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1429701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1430701e7d35SJeremy L Thompson min_u_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1431be9261b7Sjeremylt } 1432701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 14339bc66399SJeremy L Thompson CeedCheck(min_u_len == len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1434701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1435701e7d35SJeremy L Thompson min_ru_len); 1436701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 14379bc66399SJeremy L Thompson CeedCheck(min_ru_len == len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1438701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1439701e7d35SJeremy L Thompson min_u_len); 1440701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 14419bc66399SJeremy L Thompson CeedCheck(block_size * block <= num_elem, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1442701e7d35SJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, block_size * block, 1443701e7d35SJeremy L Thompson num_elem); 14442b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1445e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1446be9261b7Sjeremylt } 1447be9261b7Sjeremylt 1448be9261b7Sjeremylt /** 1449ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedElemRestriction` 1450b7c9bbdaSJeremy L Thompson 1451ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1452ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1453b7c9bbdaSJeremy L Thompson 1454b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1455b7c9bbdaSJeremy L Thompson 1456b7c9bbdaSJeremy L Thompson @ref Advanced 1457b7c9bbdaSJeremy L Thompson **/ 1458b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1459b0f67a9cSJeremy L Thompson CeedCall(CeedObjectGetCeed((CeedObject)rstr, ceed)); 1460b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1461b7c9bbdaSJeremy L Thompson } 1462b7c9bbdaSJeremy L Thompson 1463b7c9bbdaSJeremy L Thompson /** 14646e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedElemRestriction` 14656e536b99SJeremy L Thompson 14666e536b99SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 14676e536b99SJeremy L Thompson 14686e536b99SJeremy L Thompson @return `Ceed` associated with the `rstr` 14696e536b99SJeremy L Thompson 14706e536b99SJeremy L Thompson @ref Advanced 14716e536b99SJeremy L Thompson **/ 1472b0f67a9cSJeremy L Thompson Ceed CeedElemRestrictionReturnCeed(CeedElemRestriction rstr) { return CeedObjectReturnCeed((CeedObject)rstr); } 14736e536b99SJeremy L Thompson 14746e536b99SJeremy L Thompson /** 1475d979a051Sjeremylt @brief Get the L-vector component stride 1476a681ae63Sjeremylt 1477ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1478d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1479a681ae63Sjeremylt 1480a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1481a681ae63Sjeremylt 1482b7c9bbdaSJeremy L Thompson @ref Advanced 1483a681ae63Sjeremylt **/ 14842b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1485d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1486e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1487a681ae63Sjeremylt } 1488a681ae63Sjeremylt 1489a681ae63Sjeremylt /** 1490ca94c3ddSJeremy L Thompson @brief Get the total number of elements in the range of a `CeedElemRestriction` 1491a681ae63Sjeremylt 1492ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1493d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1494a681ae63Sjeremylt 1495a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1496a681ae63Sjeremylt 1497b7c9bbdaSJeremy L Thompson @ref Advanced 1498a681ae63Sjeremylt **/ 14992b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1500d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1501e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1502a681ae63Sjeremylt } 1503a681ae63Sjeremylt 1504a681ae63Sjeremylt /** 1505ca94c3ddSJeremy L Thompson @brief Get the size of elements in the `CeedElemRestriction` 1506a681ae63Sjeremylt 1507ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1508d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1509a681ae63Sjeremylt 1510a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1511a681ae63Sjeremylt 1512b7c9bbdaSJeremy L Thompson @ref Advanced 1513a681ae63Sjeremylt **/ 15142b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1515d1d35e2fSjeremylt *elem_size = rstr->elem_size; 15162c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 15172c7e7413SJeremy L Thompson } 15182c7e7413SJeremy L Thompson 15192c7e7413SJeremy L Thompson /** 152007d5dec1SJeremy L Thompson 1521725a297dSZach Atkins @brief Get the number of points in the offsets array for a points `CeedElemRestriction` 152207d5dec1SJeremy L Thompson 1523ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1524725a297dSZach Atkins @param[out] num_points The number of points in the offsets array 152507d5dec1SJeremy L Thompson 152607d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 152707d5dec1SJeremy L Thompson 1528c63574e3SJeremy L Thompson @ref User 152907d5dec1SJeremy L Thompson **/ 153007d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) { 15311203703bSJeremy L Thompson CeedRestrictionType rstr_type; 153207d5dec1SJeremy L Thompson 15331203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15346e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 153507d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 153607d5dec1SJeremy L Thompson 153707d5dec1SJeremy L Thompson *num_points = rstr->num_points; 153807d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 153907d5dec1SJeremy L Thompson } 154007d5dec1SJeremy L Thompson 154107d5dec1SJeremy L Thompson /** 154207d5dec1SJeremy L Thompson 1543ca94c3ddSJeremy L Thompson @brief Get the number of points in an element of a `CeedElemRestriction` at points 154407d5dec1SJeremy L Thompson 1545ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 154607d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 154707d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 154807d5dec1SJeremy L Thompson 154907d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 155007d5dec1SJeremy L Thompson 1551c63574e3SJeremy L Thompson @ref User 155207d5dec1SJeremy L Thompson **/ 155307d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 15541203703bSJeremy L Thompson CeedRestrictionType rstr_type; 155507d5dec1SJeremy L Thompson const CeedInt *offsets; 155607d5dec1SJeremy L Thompson 15571203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15586e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 155907d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 156007d5dec1SJeremy L Thompson 156107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 156207d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem]; 156307d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 156407d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 156507d5dec1SJeremy L Thompson } 156607d5dec1SJeremy L Thompson 156707d5dec1SJeremy L Thompson /** 1568a4065bfbSZach Atkins @brief Get the minimum and/or maximum number of points in an element for a `CeedElemRestriction` at points 15692c7e7413SJeremy L Thompson 1570ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1571a4065bfbSZach Atkins @param[out] min_points Variable to minimum number of points in an element, or `NULL` 1572a4065bfbSZach Atkins @param[out] max_points Variable to maximum number of points in an element, or `NULL` 15732c7e7413SJeremy L Thompson 15742c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 15752c7e7413SJeremy L Thompson 15762c7e7413SJeremy L Thompson @ref Advanced 15772c7e7413SJeremy L Thompson **/ 1578a4065bfbSZach Atkins int CeedElemRestrictionGetMinMaxPointsInElement(CeedElemRestriction rstr, CeedInt *min_points, CeedInt *max_points) { 1579a4065bfbSZach Atkins CeedInt num_elem, num_points; 15802c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 15812c7e7413SJeremy L Thompson 15822c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15836e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 1584a4065bfbSZach Atkins "Cannot compute min/max points for a CeedElemRestriction that does not use points"); 15852c7e7413SJeremy L Thompson 15862c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 15872c7e7413SJeremy L Thompson 1588a4065bfbSZach Atkins // Exit early if there are no elements 1589a4065bfbSZach Atkins if (num_elem == 0) { 1590a4065bfbSZach Atkins if (min_points) *min_points = 0; 1591a4065bfbSZach Atkins if (max_points) *max_points = 0; 1592a4065bfbSZach Atkins return CEED_ERROR_SUCCESS; 1593a4065bfbSZach Atkins } 1594a4065bfbSZach Atkins 1595a4065bfbSZach Atkins // Initialize to the number of points in the first element 1596a4065bfbSZach Atkins CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, 0, &num_points)); 1597a4065bfbSZach Atkins if (min_points) *min_points = num_points; 1598a4065bfbSZach Atkins if (max_points) *max_points = num_points; 1599a4065bfbSZach Atkins for (CeedInt e = 1; e < num_elem; e++) { 16002c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 1601a4065bfbSZach Atkins if (min_points) *min_points = CeedIntMin(num_points, *min_points); 1602a4065bfbSZach Atkins if (max_points) *max_points = CeedIntMax(num_points, *max_points); 16032c7e7413SJeremy L Thompson } 1604e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1605a681ae63Sjeremylt } 1606a681ae63Sjeremylt 1607a681ae63Sjeremylt /** 1608a4065bfbSZach Atkins @brief Get the maximum number of points in an element for a `CeedElemRestriction` at points 1609a4065bfbSZach Atkins 1610a4065bfbSZach Atkins @param[in] rstr `CeedElemRestriction` 1611a4065bfbSZach Atkins @param[out] max_points Variable to store maximum number of points in an element 1612a4065bfbSZach Atkins 1613a4065bfbSZach Atkins @return An error code: 0 - success, otherwise - failure 1614a4065bfbSZach Atkins 1615a4065bfbSZach Atkins @ref User 1616a4065bfbSZach Atkins 1617a4065bfbSZach Atkins @see CeedElemRestrictionGetMinMaxPointsInElement() 1618a4065bfbSZach Atkins **/ 1619a4065bfbSZach Atkins int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 1620a4065bfbSZach Atkins return CeedElemRestrictionGetMinMaxPointsInElement(rstr, NULL, max_points); 1621a4065bfbSZach Atkins } 1622a4065bfbSZach Atkins 1623a4065bfbSZach Atkins /** 1624a4065bfbSZach Atkins @brief Get the minimum number of points in an element for a `CeedElemRestriction` at points 1625a4065bfbSZach Atkins 1626a4065bfbSZach Atkins @param[in] rstr `CeedElemRestriction` 1627a4065bfbSZach Atkins @param[out] min_points Variable to store minimum number of points in an element 1628a4065bfbSZach Atkins 1629a4065bfbSZach Atkins @return An error code: 0 - success, otherwise - failure 1630a4065bfbSZach Atkins 1631a4065bfbSZach Atkins @ref User 1632a4065bfbSZach Atkins 1633a4065bfbSZach Atkins @see CeedElemRestrictionGetMinMaxPointsInElement() 1634a4065bfbSZach Atkins **/ 1635a4065bfbSZach Atkins int CeedElemRestrictionGetMinPointsInElement(CeedElemRestriction rstr, CeedInt *min_points) { 1636a4065bfbSZach Atkins return CeedElemRestrictionGetMinMaxPointsInElement(rstr, min_points, NULL); 1637a4065bfbSZach Atkins } 1638a4065bfbSZach Atkins 1639a4065bfbSZach Atkins /** 1640ca94c3ddSJeremy L Thompson @brief Get the size of the l-vector for a `CeedElemRestriction` 1641a681ae63Sjeremylt 1642ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1643701e7d35SJeremy L Thompson @param[out] l_size Variable to store l-vector size 1644a681ae63Sjeremylt 1645a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1646a681ae63Sjeremylt 1647b7c9bbdaSJeremy L Thompson @ref Advanced 1648a681ae63Sjeremylt **/ 16492b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1650d1d35e2fSjeremylt *l_size = rstr->l_size; 1651e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1652a681ae63Sjeremylt } 1653a681ae63Sjeremylt 1654a681ae63Sjeremylt /** 1655701e7d35SJeremy L Thompson @brief Get the size of the e-vector for a `CeedElemRestriction` 1656701e7d35SJeremy L Thompson 1657701e7d35SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1658701e7d35SJeremy L Thompson @param[out] e_size Variable to store e-vector size 1659701e7d35SJeremy L Thompson 1660701e7d35SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1661701e7d35SJeremy L Thompson 1662701e7d35SJeremy L Thompson @ref Advanced 1663701e7d35SJeremy L Thompson **/ 1664701e7d35SJeremy L Thompson int CeedElemRestrictionGetEVectorSize(CeedElemRestriction rstr, CeedSize *e_size) { 1665701e7d35SJeremy L Thompson *e_size = rstr->e_size; 1666701e7d35SJeremy L Thompson return CEED_ERROR_SUCCESS; 1667701e7d35SJeremy L Thompson } 1668701e7d35SJeremy L Thompson 1669701e7d35SJeremy L Thompson /** 1670ca94c3ddSJeremy L Thompson @brief Get the number of components in the elements of a `CeedElemRestriction` 1671a681ae63Sjeremylt 1672ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1673d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1674a681ae63Sjeremylt 1675a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1676a681ae63Sjeremylt 1677b7c9bbdaSJeremy L Thompson @ref Advanced 1678a681ae63Sjeremylt **/ 16792b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1680d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1681e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1682a681ae63Sjeremylt } 1683a681ae63Sjeremylt 1684a681ae63Sjeremylt /** 1685ca94c3ddSJeremy L Thompson @brief Get the number of blocks in a `CeedElemRestriction` 1686a681ae63Sjeremylt 1687ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1688d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1689a681ae63Sjeremylt 1690a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1691a681ae63Sjeremylt 1692b7c9bbdaSJeremy L Thompson @ref Advanced 1693a681ae63Sjeremylt **/ 16942b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1695e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1696e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1697a681ae63Sjeremylt } 1698a681ae63Sjeremylt 1699a681ae63Sjeremylt /** 1700ca94c3ddSJeremy L Thompson @brief Get the size of blocks in the `CeedElemRestriction` 1701a681ae63Sjeremylt 1702ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1703e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1704a681ae63Sjeremylt 1705a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1706a681ae63Sjeremylt 1707b7c9bbdaSJeremy L Thompson @ref Advanced 1708a681ae63Sjeremylt **/ 1709e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1710e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1711e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1712a681ae63Sjeremylt } 1713a681ae63Sjeremylt 1714a681ae63Sjeremylt /** 1715ca94c3ddSJeremy L Thompson @brief Get the multiplicity of nodes in a `CeedElemRestriction` 17161469ee4dSjeremylt 1717ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1718ca94c3ddSJeremy L Thompson @param[out] mult Vector to store multiplicity (of size `l_size`) 17191469ee4dSjeremylt 17201469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 17211469ee4dSjeremylt 17227a982d89SJeremy L. Thompson @ref User 17231469ee4dSjeremylt **/ 17242b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1725d1d35e2fSjeremylt CeedVector e_vec; 17261469ee4dSjeremylt 172725509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 17282b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 17291469ee4dSjeremylt 173025509ebbSRezgar Shakeri // Compute e_vec = E * 1 17312b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 17322b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 173325509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 17342b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 17352b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 17361469ee4dSjeremylt // Cleanup 17372b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1738e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 17391469ee4dSjeremylt } 17401469ee4dSjeremylt 17411469ee4dSjeremylt /** 17424c789ea2SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedElemRestrictionView() output 17434c789ea2SJeremy L Thompson 17444c789ea2SJeremy L Thompson @param[in] rstr `CeedElemRestriction` to set the number of view tabs 17454c789ea2SJeremy L Thompson @param[in] num_tabs Number of view tabs to set 17464c789ea2SJeremy L Thompson 17474c789ea2SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 17484c789ea2SJeremy L Thompson 17494c789ea2SJeremy L Thompson @ref User 17504c789ea2SJeremy L Thompson **/ 17514c789ea2SJeremy L Thompson int CeedElemRestrictionSetNumViewTabs(CeedElemRestriction rstr, CeedInt num_tabs) { 1752a299a25bSJeremy L Thompson CeedCall(CeedObjectSetNumViewTabs((CeedObject)rstr, num_tabs)); 17534c789ea2SJeremy L Thompson return CEED_ERROR_SUCCESS; 17544c789ea2SJeremy L Thompson } 17554c789ea2SJeremy L Thompson 17564c789ea2SJeremy L Thompson /** 1757690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedElemRestrictionView() output 1758690992b2SZach Atkins 1759690992b2SZach Atkins @param[in] rstr `CeedElemRestriction` to get the number of view tabs 1760690992b2SZach Atkins @param[out] num_tabs Number of view tabs 1761690992b2SZach Atkins 1762690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure 1763690992b2SZach Atkins 1764690992b2SZach Atkins @ref User 1765690992b2SZach Atkins **/ 1766690992b2SZach Atkins int CeedElemRestrictionGetNumViewTabs(CeedElemRestriction rstr, CeedInt *num_tabs) { 1767a299a25bSJeremy L Thompson CeedCall(CeedObjectGetNumViewTabs((CeedObject)rstr, num_tabs)); 1768690992b2SZach Atkins return CEED_ERROR_SUCCESS; 1769690992b2SZach Atkins } 1770690992b2SZach Atkins 1771690992b2SZach Atkins /** 1772ca94c3ddSJeremy L Thompson @brief View a `CeedElemRestriction` 1773f02ca4a2SJed Brown 1774ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view 1775ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1776f02ca4a2SJed Brown 1777f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1778f02ca4a2SJed Brown 17797a982d89SJeremy L. Thompson @ref User 1780f02ca4a2SJed Brown **/ 1781f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 17824c789ea2SJeremy L Thompson char *tabs = NULL; 17830930e4e7SJeremy L Thompson CeedRestrictionType rstr_type; 17840930e4e7SJeremy L Thompson 17854c789ea2SJeremy L Thompson { 17864c789ea2SJeremy L Thompson CeedInt num_tabs = 0; 17874c789ea2SJeremy L Thompson 17884c789ea2SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumViewTabs(rstr, &num_tabs)); 17894c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * num_tabs + 1, &tabs)); 17904c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' '; 17914c789ea2SJeremy L Thompson } 17924c789ea2SJeremy L Thompson 17930930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 17940930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 17950930e4e7SJeremy L Thompson CeedInt max_points; 17960930e4e7SJeremy L Thompson 17970930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points)); 17980930e4e7SJeremy L Thompson fprintf(stream, 17994c789ea2SJeremy L Thompson "%sCeedElemRestriction at points from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT 18000930e4e7SJeremy L Thompson " points on an element\n", 18014c789ea2SJeremy L Thompson tabs, rstr->l_size, rstr->num_comp, rstr->num_elem, max_points); 18020930e4e7SJeremy L Thompson } else { 1803249f8407SJeremy L Thompson char strides_str[500]; 18041c66c397SJeremy L Thompson 18052b730f8bSJeremy L Thompson if (rstr->strides) { 1806249f8407SJeremy L Thompson sprintf(strides_str, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 18072b730f8bSJeremy L Thompson } else { 1808249f8407SJeremy L Thompson sprintf(strides_str, "%" CeedInt_FMT, rstr->comp_stride); 18092b730f8bSJeremy L Thompson } 1810249f8407SJeremy L Thompson fprintf(stream, 18114c789ea2SJeremy L Thompson "%s%sCeedElemRestriction from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT 1812249f8407SJeremy L Thompson " nodes each and %s %s\n", 18134c789ea2SJeremy L Thompson tabs, rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1814249f8407SJeremy L Thompson rstr->strides ? "strides" : "component stride", strides_str); 18150930e4e7SJeremy L Thompson } 18164c789ea2SJeremy L Thompson CeedCall(CeedFree(&tabs)); 1817e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1818f02ca4a2SJed Brown } 1819f02ca4a2SJed Brown 1820f02ca4a2SJed Brown /** 1821ca94c3ddSJeremy L Thompson @brief Destroy a `CeedElemRestriction` 1822b11c1e72Sjeremylt 1823ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to destroy 1824b11c1e72Sjeremylt 1825b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1826dfdf5a53Sjeremylt 18277a982d89SJeremy L. Thompson @ref User 1828b11c1e72Sjeremylt **/ 18294ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1830b0f67a9cSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || CeedObjectDereference((CeedObject)*rstr) > 0) { 1831ad6481ceSJeremy L Thompson *rstr = NULL; 1832ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1833ad6481ceSJeremy L Thompson } 1834b0f67a9cSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, CeedElemRestrictionReturnCeed(*rstr), CEED_ERROR_ACCESS, 18356574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1836c17ec2beSJeremy L Thompson 1837c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 18387c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1839c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1840c17ec2beSJeremy L Thompson 18412b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 1842*6c328a79SJeremy L Thompson CeedCall(CeedObjectDestroy_Private(&(*rstr)->obj)); 18432b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1844e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1845d7b241e6Sjeremylt } 1846d7b241e6Sjeremylt 1847d7b241e6Sjeremylt /// @} 1848