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 101*b0f67a9cSJeremy L Thompson /** 102*b0f67a9cSJeremy L Thompson @brief View a `CeedElemRestriction` passed as a `CeedObject` 103*b0f67a9cSJeremy L Thompson 104*b0f67a9cSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view 105*b0f67a9cSJeremy L Thompson @param[in] stream Filestream to write to 106*b0f67a9cSJeremy L Thompson 107*b0f67a9cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 108*b0f67a9cSJeremy L Thompson 109*b0f67a9cSJeremy L Thompson @ref Developer 110*b0f67a9cSJeremy L Thompson **/ 111*b0f67a9cSJeremy L Thompson static int CeedElemRestrictionView_Object(CeedObject rstr, FILE *stream) { 112*b0f67a9cSJeremy L Thompson CeedCall(CeedElemRestrictionView((CeedElemRestriction)rstr, stream)); 113*b0f67a9cSJeremy L Thompson return CEED_ERROR_SUCCESS; 114*b0f67a9cSJeremy L Thompson } 115*b0f67a9cSJeremy L Thompson 1167a982d89SJeremy L. Thompson /// @} 1177a982d89SJeremy L. Thompson 1187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1197a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 1207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1217a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 1227a982d89SJeremy L. Thompson /// @{ 1237a982d89SJeremy L. Thompson 1247a982d89SJeremy L. Thompson /** 125ca94c3ddSJeremy L Thompson @brief Get the type of a `CeedElemRestriction` 126a681ae63Sjeremylt 127ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 128fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 129fcbe8c06SSebastian Grimberg 130fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 131fcbe8c06SSebastian Grimberg 132fcbe8c06SSebastian Grimberg @ref Backend 133fcbe8c06SSebastian Grimberg **/ 134fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 135fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 136fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 137fcbe8c06SSebastian Grimberg } 138fcbe8c06SSebastian Grimberg 139fcbe8c06SSebastian Grimberg /** 140ca94c3ddSJeremy L Thompson @brief Get the strided status of a `CeedElemRestriction` 141fcbe8c06SSebastian Grimberg 142ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 143ca94c3ddSJeremy L Thompson @param[out] is_strided Variable to store strided status 144ca94c3ddSJeremy L Thompson 145ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 146ca94c3ddSJeremy L Thompson 147ca94c3ddSJeremy L Thompson @ref Backend 148fcbe8c06SSebastian Grimberg **/ 149fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 150fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 151fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 152fcbe8c06SSebastian Grimberg } 153fcbe8c06SSebastian Grimberg 154fcbe8c06SSebastian Grimberg /** 155ca94c3ddSJeremy L Thompson @brief Get the points status of a `CeedElemRestriction` 1563ac8f562SJeremy L Thompson 157ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 158ca94c3ddSJeremy L Thompson @param[out] is_points Variable to store points status 159ca94c3ddSJeremy L Thompson 160ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 161ca94c3ddSJeremy L Thompson 162ca94c3ddSJeremy L Thompson @ref Backend 1633ac8f562SJeremy L Thompson **/ 164637baffdSJeremy L Thompson int CeedElemRestrictionIsAtPoints(CeedElemRestriction rstr, bool *is_points) { 1653ac8f562SJeremy L Thompson *is_points = (rstr->rstr_type == CEED_RESTRICTION_POINTS); 1663ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 1673ac8f562SJeremy L Thompson } 1683ac8f562SJeremy L Thompson 1693ac8f562SJeremy L Thompson /** 170ca94c3ddSJeremy L Thompson @brief Check if two `CeedElemRestriction` created with @ref CeedElemRestrictionCreateAtPoints() and use the same points per element 17148acf710SJeremy L Thompson 172ca94c3ddSJeremy L Thompson @param[in] rstr_a First `CeedElemRestriction` 173ca94c3ddSJeremy L Thompson @param[in] rstr_b Second `CeedElemRestriction` 17448acf710SJeremy L Thompson @param[out] are_compatible Variable to store compatibility status 175ca94c3ddSJeremy L Thompson 176ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 177ca94c3ddSJeremy L Thompson 178ca94c3ddSJeremy L Thompson @ref Backend 17948acf710SJeremy L Thompson **/ 18048acf710SJeremy L Thompson int CeedElemRestrictionAtPointsAreCompatible(CeedElemRestriction rstr_a, CeedElemRestriction rstr_b, bool *are_compatible) { 18148acf710SJeremy L Thompson CeedInt num_elem_a, num_elem_b, num_points_a, num_points_b; 18248acf710SJeremy L Thompson 18348acf710SJeremy L Thompson // Cannot compare non-points restrictions 1849bc66399SJeremy L Thompson CeedCheck(rstr_a->rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr_a), CEED_ERROR_UNSUPPORTED, 1859bc66399SJeremy L Thompson "First CeedElemRestriction must be AtPoints"); 1869bc66399SJeremy L Thompson CeedCheck(rstr_b->rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr_a), CEED_ERROR_UNSUPPORTED, 1879bc66399SJeremy L Thompson "Second CeedElemRestriction must be AtPoints"); 18848acf710SJeremy L Thompson 18948acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_a, &num_elem_a)); 19048acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_b, &num_elem_b)); 19148acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_a, &num_points_a)); 19248acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_b, &num_points_b)); 19348acf710SJeremy L Thompson 19448acf710SJeremy L Thompson // Check size and contents of offsets arrays 19548acf710SJeremy L Thompson *are_compatible = true; 19648acf710SJeremy L Thompson if (num_elem_a != num_elem_b) *are_compatible = false; 19748acf710SJeremy L Thompson if (num_points_a != num_points_b) *are_compatible = false; 19848acf710SJeremy L Thompson if (*are_compatible) { 19948acf710SJeremy L Thompson const CeedInt *offsets_a, *offsets_b; 20048acf710SJeremy L Thompson 20148acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_a, CEED_MEM_HOST, &offsets_a)); 20248acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_b, CEED_MEM_HOST, &offsets_b)); 20348acf710SJeremy L Thompson for (CeedInt i = 0; i < num_elem_a + 1 + num_points_a; i++) *are_compatible &= offsets_a[i] == offsets_b[i]; 20448acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_a, &offsets_a)); 20548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_b, &offsets_b)); 20648acf710SJeremy L Thompson } 20748acf710SJeremy L Thompson return CEED_ERROR_SUCCESS; 20848acf710SJeremy L Thompson } 20948acf710SJeremy L Thompson 21048acf710SJeremy L Thompson /** 211ca94c3ddSJeremy L Thompson @brief Get the strides of a strided `CeedElemRestriction` 2127a982d89SJeremy L. Thompson 213ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 214a681ae63Sjeremylt @param[out] strides Variable to store strides array 2157a982d89SJeremy L. Thompson 2167a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2177a982d89SJeremy L. Thompson 2187a982d89SJeremy L. Thompson @ref Backend 2197a982d89SJeremy L. Thompson **/ 22056c48462SJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt strides[3]) { 2216e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 22256c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) strides[i] = rstr->strides[i]; 223e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2247a982d89SJeremy L. Thompson } 2257a982d89SJeremy L. Thompson 2267a982d89SJeremy L. Thompson /** 227ca94c3ddSJeremy L Thompson @brief Get the backend stride status of a `CeedElemRestriction` 22877d1c127SSebastian Grimberg 229ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 23077d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 23177d1c127SSebastian Grimberg 23277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 23377d1c127SSebastian Grimberg 23477d1c127SSebastian Grimberg @ref Backend 23577d1c127SSebastian Grimberg **/ 23677d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 2376e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data"); 23877d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 23977d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 24077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 24177d1c127SSebastian Grimberg } 24277d1c127SSebastian Grimberg 24377d1c127SSebastian Grimberg /** 244ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` offsets array by @ref CeedMemType 245bd33150aSjeremylt 246ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve offsets 247fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 248fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 249ca94c3ddSJeremy L Thompson @param[out] offsets Array on memory type `mem_type` 250bd33150aSjeremylt 251bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 252bd33150aSjeremylt 253bd33150aSjeremylt @ref User 254bd33150aSjeremylt **/ 2552b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 2567c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2577c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 258c17ec2beSJeremy L Thompson } else { 2596e536b99SJeremy L Thompson CeedCheck(rstr->GetOffsets, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 2601ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetOffsets"); 2612b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 262d1d35e2fSjeremylt rstr->num_readers++; 263c17ec2beSJeremy L Thompson } 264e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 265430758c8SJeremy L Thompson } 266430758c8SJeremy L Thompson 267430758c8SJeremy L Thompson /** 268ca94c3ddSJeremy L Thompson @brief Restore an offsets array obtained using @ref CeedElemRestrictionGetOffsets() 269430758c8SJeremy L Thompson 270ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 271ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 272430758c8SJeremy L Thompson 273430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 274430758c8SJeremy L Thompson 275430758c8SJeremy L Thompson @ref User 276430758c8SJeremy L Thompson **/ 2772b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2787c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2797c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 280c17ec2beSJeremy L Thompson } else { 281430758c8SJeremy L Thompson *offsets = NULL; 282d1d35e2fSjeremylt rstr->num_readers--; 283c17ec2beSJeremy L Thompson } 284e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 285bd33150aSjeremylt } 286bd33150aSjeremylt 287bd33150aSjeremylt /** 288ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` orientations array by @ref CeedMemType 2893ac43b2cSJeremy L Thompson 290ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve orientations 291fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 292fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 293ca94c3ddSJeremy L Thompson @param[out] orients Array on memory type `mem_type` 2943ac43b2cSJeremy L Thompson 2953ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2963ac43b2cSJeremy L Thompson 29777d1c127SSebastian Grimberg @ref User 2983ac43b2cSJeremy L Thompson **/ 29977d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 3006e536b99SJeremy L Thompson CeedCheck(rstr->GetOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 3011ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetOrientations"); 30277d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 30377d1c127SSebastian Grimberg rstr->num_readers++; 304e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3053ac43b2cSJeremy L Thompson } 3063ac43b2cSJeremy L Thompson 3073ac43b2cSJeremy L Thompson /** 308ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetOrientations() 309b435c5a6Srezgarshakeri 310ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 31177d1c127SSebastian Grimberg @param[in] orients Array of orientation data 312b435c5a6Srezgarshakeri 313b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 314b435c5a6Srezgarshakeri 31577d1c127SSebastian Grimberg @ref User 316b435c5a6Srezgarshakeri **/ 31777d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 31877d1c127SSebastian Grimberg *orients = NULL; 31977d1c127SSebastian Grimberg rstr->num_readers--; 320b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 321b435c5a6Srezgarshakeri } 322b435c5a6Srezgarshakeri 323b435c5a6Srezgarshakeri /** 324ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` curl-conforming orientations array by @ref CeedMemType 3257a982d89SJeremy L. Thompson 326ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve curl-conforming orientations 327fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 328fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 329ca94c3ddSJeremy L Thompson @param[out] curl_orients Array on memory type `mem_type` 3307a982d89SJeremy L. Thompson 3317a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3327a982d89SJeremy L. Thompson 33377d1c127SSebastian Grimberg @ref User 3347a982d89SJeremy L. Thompson **/ 3350c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 3366e536b99SJeremy L Thompson CeedCheck(rstr->GetCurlOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 3371ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetCurlOrientations"); 33877d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 33977d1c127SSebastian Grimberg rstr->num_readers++; 34077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 34177d1c127SSebastian Grimberg } 34277d1c127SSebastian Grimberg 34377d1c127SSebastian Grimberg /** 344ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetCurlOrientations() 34577d1c127SSebastian Grimberg 346ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore 34777d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 34877d1c127SSebastian Grimberg 34977d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 35077d1c127SSebastian Grimberg 35177d1c127SSebastian Grimberg @ref User 35277d1c127SSebastian Grimberg **/ 3530c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 35477d1c127SSebastian Grimberg *curl_orients = NULL; 35577d1c127SSebastian Grimberg rstr->num_readers--; 356e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3577a982d89SJeremy L. Thompson } 3587a982d89SJeremy L. Thompson 3597a982d89SJeremy L. Thompson /** 36049fd234cSJeremy L Thompson 36122eb1385SJeremy L Thompson @brief Get the L-vector layout of a strided `CeedElemRestriction` 36222eb1385SJeremy L Thompson 36322eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 36422eb1385SJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 36522eb1385SJeremy 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]`. 36622eb1385SJeremy L Thompson 36722eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 36822eb1385SJeremy L Thompson 36922eb1385SJeremy L Thompson @ref Backend 37022eb1385SJeremy L Thompson **/ 37156c48462SJeremy L Thompson int CeedElemRestrictionGetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 37222eb1385SJeremy L Thompson bool has_backend_strides; 37322eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 37422eb1385SJeremy L Thompson 37522eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 3769bc66399SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, 3779bc66399SJeremy L Thompson "Only strided CeedElemRestriction have strided L-vector layout"); 37822eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 37922eb1385SJeremy L Thompson if (has_backend_strides) { 3809bc66399SJeremy L Thompson CeedCheck(rstr->l_layout[0], CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no L-vector layout data"); 38156c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->l_layout[i]; 38222eb1385SJeremy L Thompson } else { 38322eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetStrides(rstr, layout)); 38422eb1385SJeremy L Thompson } 38522eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 38622eb1385SJeremy L Thompson } 38722eb1385SJeremy L Thompson 38822eb1385SJeremy L Thompson /** 38922eb1385SJeremy L Thompson 39022eb1385SJeremy L Thompson @brief Set the L-vector layout of a strided `CeedElemRestriction` 39122eb1385SJeremy L Thompson 39222eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 39322eb1385SJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 39422eb1385SJeremy 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]`. 39522eb1385SJeremy L Thompson 39622eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 39722eb1385SJeremy L Thompson 39822eb1385SJeremy L Thompson @ref Backend 39922eb1385SJeremy L Thompson **/ 40022eb1385SJeremy L Thompson int CeedElemRestrictionSetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) { 40122eb1385SJeremy L Thompson CeedRestrictionType rstr_type; 40222eb1385SJeremy L Thompson 40322eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 4046e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, 4056e536b99SJeremy L Thompson "Only strided CeedElemRestriction have strided L-vector layout"); 40622eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->l_layout[i] = layout[i]; 40722eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS; 40822eb1385SJeremy L Thompson } 40922eb1385SJeremy L Thompson 41022eb1385SJeremy L Thompson /** 41122eb1385SJeremy L Thompson 412ca94c3ddSJeremy L Thompson @brief Get the E-vector layout of a `CeedElemRestriction` 41349fd234cSJeremy L Thompson 414ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 415ca94c3ddSJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`. 416ca94c3ddSJeremy L Thompson The data for node `i`, component `j`, element `k` in the E-vector is given by `i*layout[0] + j*layout[1] + k*layout[2]`. 41749fd234cSJeremy L Thompson 41849fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 41949fd234cSJeremy L Thompson 42049fd234cSJeremy L Thompson @ref Backend 42149fd234cSJeremy L Thompson **/ 42256c48462SJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 4236e536b99SJeremy L Thompson CeedCheck(rstr->e_layout[0], CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no E-vector layout data"); 42456c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->e_layout[i]; 425e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 42649fd234cSJeremy L Thompson } 42749fd234cSJeremy L Thompson 42849fd234cSJeremy L Thompson /** 42949fd234cSJeremy L Thompson 430ca94c3ddSJeremy L Thompson @brief Set the E-vector layout of a `CeedElemRestriction` 43149fd234cSJeremy L Thompson 432ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 433ca94c3ddSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`. 434ca94c3ddSJeremy 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]`. 43549fd234cSJeremy L Thompson 43649fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 43749fd234cSJeremy L Thompson 43849fd234cSJeremy L Thompson @ref Backend 43949fd234cSJeremy L Thompson **/ 4402b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 44122eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->e_layout[i] = layout[i]; 442e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 44349fd234cSJeremy L Thompson } 44449fd234cSJeremy L Thompson 44549fd234cSJeremy L Thompson /** 44619605835SJeremy L Thompson 44719605835SJeremy L Thompson @brief Get the E-vector element offset of a `CeedElemRestriction` at points 44819605835SJeremy L Thompson 44919605835SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 45019605835SJeremy L Thompson @param[in] elem Element number index into E-vector for 45119605835SJeremy L Thompson @param[out] elem_offset Offset for element `elem` in the E-vector. 45219605835SJeremy 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`. 45319605835SJeremy L Thompson 45419605835SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 45519605835SJeremy L Thompson 45619605835SJeremy L Thompson @ref Backend 45719605835SJeremy L Thompson **/ 45819605835SJeremy L Thompson int CeedElemRestrictionGetAtPointsElementOffset(CeedElemRestriction rstr, CeedInt elem, CeedSize *elem_offset) { 45919605835SJeremy L Thompson CeedInt num_comp; 46019605835SJeremy L Thompson CeedRestrictionType rstr_type; 46119605835SJeremy L Thompson 46219605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 46319605835SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 46419605835SJeremy L Thompson "Can only compute offset for a points CeedElemRestriction"); 46519605835SJeremy L Thompson 46619605835SJeremy L Thompson // Backend method 46719605835SJeremy L Thompson if (rstr->GetAtPointsElementOffset) { 46819605835SJeremy L Thompson CeedCall(rstr->GetAtPointsElementOffset(rstr, elem, elem_offset)); 46919605835SJeremy L Thompson return CEED_ERROR_SUCCESS; 47019605835SJeremy L Thompson } 47119605835SJeremy L Thompson 47219605835SJeremy L Thompson // Default layout (CPU) 47319605835SJeremy L Thompson *elem_offset = 0; 47419605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 47519605835SJeremy L Thompson for (CeedInt i = 0; i < elem; i++) { 47619605835SJeremy L Thompson CeedInt num_points; 47719605835SJeremy L Thompson 47819605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, i, &num_points)); 47919605835SJeremy L Thompson *elem_offset += num_points * num_comp; 48019605835SJeremy L Thompson } 48119605835SJeremy L Thompson return CEED_ERROR_SUCCESS; 48219605835SJeremy L Thompson } 48319605835SJeremy L Thompson 48419605835SJeremy L Thompson /** 485ff1bc20eSJeremy L Thompson 486ff1bc20eSJeremy L Thompson @brief Set the E-vector size of a `CeedElemRestriction` at points 487ff1bc20eSJeremy L Thompson 488ff1bc20eSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` 489ff1bc20eSJeremy L Thompson @param[in] e_size New E-vector size; must be longer than the current E-vector size 490ff1bc20eSJeremy L Thompson 491ff1bc20eSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 492ff1bc20eSJeremy L Thompson 493ff1bc20eSJeremy L Thompson @ref Backend 494ff1bc20eSJeremy L Thompson **/ 495ff1bc20eSJeremy L Thompson int CeedElemRestrictionSetAtPointsEVectorSize(CeedElemRestriction rstr, CeedSize e_size) { 496ff1bc20eSJeremy L Thompson CeedRestrictionType rstr_type; 497ff1bc20eSJeremy L Thompson 498ff1bc20eSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 4999bc66399SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 5009bc66399SJeremy L Thompson "Can only compute offset for a points CeedElemRestriction"); 5019bc66399SJeremy L Thompson CeedCheck(e_size >= rstr->e_size, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 5023f08121cSJeremy L Thompson "Can only increase the size of the E-vector for the CeedElemRestriction." 5033f08121cSJeremy L Thompson " Current size: %" CeedSize_FMT " New size: %" CeedSize_FMT, 5043f08121cSJeremy L Thompson rstr->e_size, e_size); 505ff1bc20eSJeremy L Thompson rstr->e_size = e_size; 506ff1bc20eSJeremy L Thompson return CEED_ERROR_SUCCESS; 507ff1bc20eSJeremy L Thompson } 508ff1bc20eSJeremy L Thompson 509ff1bc20eSJeremy L Thompson /** 510ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedElemRestriction` 5117a982d89SJeremy L. Thompson 512ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 5137a982d89SJeremy L. Thompson @param[out] data Variable to store data 5147a982d89SJeremy L. Thompson 5157a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5167a982d89SJeremy L. Thompson 5177a982d89SJeremy L. Thompson @ref Backend 5187a982d89SJeremy L. Thompson **/ 519777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 520777ff853SJeremy L Thompson *(void **)data = rstr->data; 521e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5227a982d89SJeremy L. Thompson } 5237a982d89SJeremy L. Thompson 5247a982d89SJeremy L. Thompson /** 525ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedElemRestriction` 5267a982d89SJeremy L. Thompson 527ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` 528ea61e9acSJeremy L Thompson @param[in] data Data to set 5297a982d89SJeremy L. Thompson 5307a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5317a982d89SJeremy L. Thompson 5327a982d89SJeremy L. Thompson @ref Backend 5337a982d89SJeremy L. Thompson **/ 534777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 535777ff853SJeremy L Thompson rstr->data = data; 536e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5377a982d89SJeremy L. Thompson } 5387a982d89SJeremy L. Thompson 53934359f16Sjeremylt /** 540ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedElemRestriction` 54134359f16Sjeremylt 542ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to increment the reference counter 54334359f16Sjeremylt 54434359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 54534359f16Sjeremylt 54634359f16Sjeremylt @ref Backend 54734359f16Sjeremylt **/ 5489560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 549*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)rstr)); 55034359f16Sjeremylt return CEED_ERROR_SUCCESS; 55134359f16Sjeremylt } 55234359f16Sjeremylt 5536e15d496SJeremy L Thompson /** 554ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedElemRestriction` in `t_mode` 5556e15d496SJeremy L Thompson 556ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to estimate FLOPs for 557ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 558ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5596e15d496SJeremy L Thompson 5606e15d496SJeremy L Thompson @ref Backend 5616e15d496SJeremy L Thompson **/ 5622b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 5631203703bSJeremy L Thompson CeedSize e_size, scale = 0; 56489edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 5651c66c397SJeremy L Thompson 5661203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 56789edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 56877d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 56989edb9e3SSebastian Grimberg switch (rstr_type) { 5703ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 5713ac8f562SJeremy L Thompson scale = 0; 5723ac8f562SJeremy L Thompson break; 57389edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 57489edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 57577d1c127SSebastian Grimberg scale = 1; 57689edb9e3SSebastian Grimberg break; 57789edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 57877d1c127SSebastian Grimberg scale = 2; 57989edb9e3SSebastian Grimberg break; 58089edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 58177d1c127SSebastian Grimberg scale = 6; 58289edb9e3SSebastian Grimberg break; 5836e15d496SJeremy L Thompson } 58477d1c127SSebastian Grimberg } else { 58589edb9e3SSebastian Grimberg switch (rstr_type) { 58689edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 58789edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 5883ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 58977d1c127SSebastian Grimberg scale = 0; 59089edb9e3SSebastian Grimberg break; 59189edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 59277d1c127SSebastian Grimberg scale = 1; 59389edb9e3SSebastian Grimberg break; 59489edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 59577d1c127SSebastian Grimberg scale = 5; 59689edb9e3SSebastian Grimberg break; 59777d1c127SSebastian Grimberg } 59877d1c127SSebastian Grimberg } 5996e15d496SJeremy L Thompson *flops = e_size * scale; 6006e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 6016e15d496SJeremy L Thompson } 6026e15d496SJeremy L Thompson 6037a982d89SJeremy L. Thompson /// @} 6047a982d89SJeremy L. Thompson 60515910d16Sjeremylt /// @cond DOXYGEN_SKIP 60615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 60715910d16Sjeremylt /// @endcond 60815910d16Sjeremylt 6097a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6107a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 6117a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 6127a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 613d7b241e6Sjeremylt /// @{ 614d7b241e6Sjeremylt 6157a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 61645f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 6177a982d89SJeremy L. Thompson 618ca94c3ddSJeremy L Thompson /// Argument for @ref CeedOperatorSetField() indicating that the field does not require a `CeedElemRestriction` 6192b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 6207a982d89SJeremy L. Thompson 621d7b241e6Sjeremylt /** 622ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` 623d7b241e6Sjeremylt 624ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 625ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 626ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 627ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 628fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 629ca94c3ddSJeremy 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`. 630fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 631fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 632ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 633ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 634ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 635ca94c3ddSJeremy 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. 636ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 637ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 638d7b241e6Sjeremylt 639b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 640dfdf5a53Sjeremylt 6417a982d89SJeremy L. Thompson @ref User 642b11c1e72Sjeremylt **/ 6432b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 6442b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 6455fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6465fe0d4faSjeremylt Ceed delegate; 6476574a04fSJeremy L Thompson 6482b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 649ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreate"); 6502b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 6519bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 652e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6535fe0d4faSjeremylt } 6545fe0d4faSjeremylt 655e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6566574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 657ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 658ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 659e022e1f8SJeremy L Thompson 6602b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 661*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 662d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 663d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 664d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 665d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 666d1d35e2fSjeremylt (*rstr)->l_size = l_size; 6671203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 668e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 669e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 67061a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 671fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 672e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 673d7b241e6Sjeremylt } 674d7b241e6Sjeremylt 675d7b241e6Sjeremylt /** 676ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with orientation signs 677fc0567d9Srezgarshakeri 678ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 679ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 680ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 681ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 682fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 683ca94c3ddSJeremy 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`. 684fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 685fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 686ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 687ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 688ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 689ca94c3ddSJeremy 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`. 690ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 691ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation 692ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 693fc0567d9Srezgarshakeri 694fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 695fc0567d9Srezgarshakeri 696fc0567d9Srezgarshakeri @ref User 697fc0567d9Srezgarshakeri **/ 6982b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 69977d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 700fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 701fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 702fc0567d9Srezgarshakeri Ceed delegate; 7036574a04fSJeremy L Thompson 7042b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 705ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateOriented"); 7061a8516d0SJames Wright CeedCall(CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, 7071a8516d0SJames Wright rstr)); 7089bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 709fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 710fc0567d9Srezgarshakeri } 711fc0567d9Srezgarshakeri 712e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7136574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 714ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 715ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 716e022e1f8SJeremy L Thompson 7172b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 718*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 719fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 720fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 721fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 722fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 723fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 7241203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 725e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 726e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 727fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 728fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 72977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 73077d1c127SSebastian Grimberg } 73177d1c127SSebastian Grimberg 73277d1c127SSebastian Grimberg /** 733ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with a general tridiagonal transformation matrix for curl-conforming elements 73477d1c127SSebastian Grimberg 735ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 736ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 73777d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 73877d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 739fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 740ca94c3ddSJeremy 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`. 741fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 742fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 743ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 744ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 745ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 746ca94c3ddSJeremy 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`. 747ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 748ca94c3ddSJeremy 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. 749ca94c3ddSJeremy 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). 750ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 75177d1c127SSebastian Grimberg 75277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 75377d1c127SSebastian Grimberg 75477d1c127SSebastian Grimberg @ref User 75577d1c127SSebastian Grimberg **/ 75677d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 7570c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 75877d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 759fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 76077d1c127SSebastian Grimberg Ceed delegate; 76177d1c127SSebastian Grimberg 76277d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 763ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateCurlOriented"); 76477d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 76577d1c127SSebastian Grimberg curl_orients, rstr)); 7669bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 76777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 76877d1c127SSebastian Grimberg } 76977d1c127SSebastian Grimberg 770e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 77177d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 772ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 773ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 77477d1c127SSebastian Grimberg 77577d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 776*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 77777d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 77877d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 77977d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 78077d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 78177d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 7821203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 783e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 784e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 785fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 786fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 787fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 788fc0567d9Srezgarshakeri } 789fc0567d9Srezgarshakeri 790fc0567d9Srezgarshakeri /** 791ca94c3ddSJeremy L Thompson @brief Create a strided `CeedElemRestriction` 792d7b241e6Sjeremylt 793ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 794ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 795ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 796ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 797fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 798fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 799ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 800ca94c3ddSJeremy 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]`. 801ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 802972f909dSJeremy L Thompson `CEED_STRIDES_BACKEND` should only be used pass data between `CeedOperator` created with the same `Ceed` backend. 803972f909dSJeremy L Thompson The L-vector layout will, in general, be different between `Ceed` backends. 804ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 805d7b241e6Sjeremylt 806b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 807dfdf5a53Sjeremylt 8087a982d89SJeremy L. Thompson @ref User 809b11c1e72Sjeremylt **/ 8102b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 811f90c8643Sjeremylt CeedElemRestriction *rstr) { 8125fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 8135fe0d4faSjeremylt Ceed delegate; 814b04eb3d9SSebastian Grimberg 8152b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 816ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateStrided"); 8172b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 8189bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 819e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8205fe0d4faSjeremylt } 8215fe0d4faSjeremylt 822e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8236574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 824ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 825aa72de07SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, ceed, CEED_ERROR_DIMENSION, 826870ea2d9SJeremy L Thompson "L-vector size must be at least num_elem * elem_size * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT, 827870ea2d9SJeremy L Thompson (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, l_size); 828e022e1f8SJeremy L Thompson 8292b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 830*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 831d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 832d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 833d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 834d1d35e2fSjeremylt (*rstr)->l_size = l_size; 8351203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp; 836e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 837e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 838fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 8392b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 8402b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 841fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 842e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 843d7b241e6Sjeremylt } 844d7b241e6Sjeremylt 845d7b241e6Sjeremylt /** 846ca94c3ddSJeremy 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. 8473ac8f562SJeremy L Thompson 8483ac8f562SJeremy L Thompson The offsets array is arranged as 8493ac8f562SJeremy L Thompson 8503ac8f562SJeremy L Thompson element_0_start_index 8513ac8f562SJeremy L Thompson element_1_start_index 8523ac8f562SJeremy L Thompson ... 8533ac8f562SJeremy L Thompson element_n_start_index 8543ac8f562SJeremy L Thompson element_n_stop_index 8553ac8f562SJeremy L Thompson element_0_point_0 8563ac8f562SJeremy L Thompson element_0_point_1 8573ac8f562SJeremy L Thompson ... 8583ac8f562SJeremy L Thompson 859ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 860ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 861ca94c3ddSJeremy L Thompson @param[in] num_points Number of points described in the `offsets` array 8623ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 8633ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 8643ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 8653ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 866ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 867ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 868ca94c3ddSJeremy L Thompson @param[in] offsets Array of size `num_elem + 1 + num_points`. 8693ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 8703ac8f562SJeremy L Thompson The second portion holds the indices for each element. 871ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 8723ac8f562SJeremy L Thompson 8733ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8743ac8f562SJeremy L Thompson 8753ac8f562SJeremy L Thompson @ref Backend 8763ac8f562SJeremy L Thompson **/ 8773ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 8783ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 8793ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 8803ac8f562SJeremy L Thompson Ceed delegate; 8813ac8f562SJeremy L Thompson 8823ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 883ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateAtPoints"); 8843ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 8859bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 8863ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 8873ac8f562SJeremy L Thompson } 8883ac8f562SJeremy L Thompson 8893ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 8903ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 891ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 892870ea2d9SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_points * num_comp, ceed, CEED_ERROR_DIMENSION, 893870ea2d9SJeremy L Thompson "L-vector must be at least num_points * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT, (CeedSize)num_points * num_comp, 894870ea2d9SJeremy L Thompson l_size); 8953ac8f562SJeremy L Thompson 8963ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 897*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 8983ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 8993ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 9003ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 9012c2c926cSJeremy L Thompson (*rstr)->comp_stride = 1; 9023ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 9031203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_points * (CeedSize)num_comp; 90405fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 9053ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 9063ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 9073ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 9083ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 9093ac8f562SJeremy L Thompson } 9103ac8f562SJeremy L Thompson 9113ac8f562SJeremy L Thompson /** 912ca94c3ddSJeremy L Thompson @brief Create a blocked `CeedElemRestriction`, typically only used by backends 913d7b241e6Sjeremylt 914ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 915ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array 916ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 917e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 918ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 919fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 920ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `offsets[i + k*elem_size] + j*comp_stride`. 921fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 922fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 923ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 924ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 925ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 926ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`. 927ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 928ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 929ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 930ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 931d7b241e6Sjeremylt 932b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 933dfdf5a53Sjeremylt 9347a982d89SJeremy L. Thompson @ref Backend 935b11c1e72Sjeremylt **/ 936e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 9372b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 9384ce2993fSjeremylt CeedElemRestriction *rstr) { 9391c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 940d7b241e6Sjeremylt 9415fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 9425fe0d4faSjeremylt Ceed delegate; 9436574a04fSJeremy L Thompson 9442b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 945ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlocked"); 946e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 947e7f679fcSJeremy L Thompson rstr)); 9489bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 949e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9505fe0d4faSjeremylt } 951d7b241e6Sjeremylt 952e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 9536574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 954e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 955ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 956ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 957e022e1f8SJeremy L Thompson 958e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 959e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 960d7b241e6Sjeremylt 961db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 962*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 963d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 964d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 965d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 966d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 967d1d35e2fSjeremylt (*rstr)->l_size = l_size; 9681203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 969e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 970e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 97161a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 972e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 9731c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 974e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 975d7b241e6Sjeremylt } 976d7b241e6Sjeremylt 977b11c1e72Sjeremylt /** 978ca94c3ddSJeremy L Thompson @brief Create a blocked oriented `CeedElemRestriction`, typically only used by backends 97977d1c127SSebastian Grimberg 980ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 981ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 98277d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 983e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 98477d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 985fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 986ca94c3ddSJeremy 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`. 987fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 988fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 989ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 990ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 991ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 992ca94c3ddSJeremy 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`. 993ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 994ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 995ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 996ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation. 997ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to `offsets`. 998ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 99977d1c127SSebastian Grimberg 100077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 100177d1c127SSebastian Grimberg 100277d1c127SSebastian Grimberg @ref Backend 100377d1c127SSebastian Grimberg **/ 1004e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 1005e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 1006e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 1007e7f679fcSJeremy L Thompson bool *block_orients; 10081c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 100977d1c127SSebastian Grimberg 1010fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 101177d1c127SSebastian Grimberg Ceed delegate; 101277d1c127SSebastian Grimberg 101377d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1014ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedOriented"); 1015e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 101677d1c127SSebastian Grimberg offsets, orients, rstr)); 10179bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 101877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 101977d1c127SSebastian Grimberg } 102077d1c127SSebastian Grimberg 102177d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1022e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1023ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1024ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 102577d1c127SSebastian Grimberg 1026e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 1027e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 1028e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 1029e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 103077d1c127SSebastian Grimberg 1031fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 1032*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 103377d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 103477d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 103577d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 103677d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 103777d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 10381203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1039e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1040e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1041fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 10421a8516d0SJames Wright CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, 10431a8516d0SJames Wright *rstr)); 10441c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 104577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 104677d1c127SSebastian Grimberg } 104777d1c127SSebastian Grimberg 104877d1c127SSebastian Grimberg /** 1049ca94c3ddSJeremy L Thompson @brief Create a blocked curl-oriented `CeedElemRestriction`, typically only used by backends 105077d1c127SSebastian Grimberg 1051ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1052ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array. 105377d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 1054e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 105577d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1056fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 1057ca94c3ddSJeremy 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`. 1058fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1059fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1060ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType 1061ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode 1062ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`. 1063ca94c3ddSJeremy 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`. 1064ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`. 1065ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend. 1066ca94c3ddSJeremy L Thompson The default reordering is to interlace elements. 1067ca94c3ddSJeremy 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. 1068ca94c3ddSJeremy 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). 1069ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to offsets. 1070ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 107177d1c127SSebastian Grimberg 107277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 107377d1c127SSebastian Grimberg 107477d1c127SSebastian Grimberg @ref Backend 107577d1c127SSebastian Grimberg **/ 1076e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 107777d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 10780c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 1079e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 10801c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 108177d1c127SSebastian Grimberg 1082fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 108377d1c127SSebastian Grimberg Ceed delegate; 108477d1c127SSebastian Grimberg 108577d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1086ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedCurlOriented"); 1087e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 1088e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 10899bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 109077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 109177d1c127SSebastian Grimberg } 109277d1c127SSebastian Grimberg 1093e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 109477d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1095e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1096ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1097ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1"); 109877d1c127SSebastian Grimberg 1099e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 1100e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 1101e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 1102e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 110377d1c127SSebastian Grimberg 1104fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 1105*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 110677d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 110777d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 110877d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 110977d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 111077d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 11111203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1112e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1113e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1114fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 1115e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 1116e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 11171c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 111877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 111977d1c127SSebastian Grimberg } 112077d1c127SSebastian Grimberg 112177d1c127SSebastian Grimberg /** 1122ca94c3ddSJeremy L Thompson @brief Create a blocked strided `CeedElemRestriction`, typically only used by backends 11237509a596Sjeremylt 1124ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction` 1125ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 1126ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 1127e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 1128ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 1129fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 1130fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 1131ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`. 1132ca94c3ddSJeremy 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]`. 1133ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend. 1134ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored 11357509a596Sjeremylt 11367509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 11377509a596Sjeremylt 11387a982d89SJeremy L. Thompson @ref User 11397509a596Sjeremylt **/ 1140e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 11418621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 1142e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 11437509a596Sjeremylt 11447509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 11457509a596Sjeremylt Ceed delegate; 11466574a04fSJeremy L Thompson 11472b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 1148ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedStrided"); 1149e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 11509bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 1151e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11527509a596Sjeremylt } 11537509a596Sjeremylt 1154e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 11556574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 1156e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 1157ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component"); 1158aa72de07SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, ceed, CEED_ERROR_DIMENSION, 1159870ea2d9SJeremy L Thompson "L-vector size must be at least num_elem * elem_size * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT, 1160870ea2d9SJeremy L Thompson (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, l_size); 1161e022e1f8SJeremy L Thompson 11622b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 1163*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, &(*rstr)->obj)); 1164d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 1165d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 1166d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 1167d1d35e2fSjeremylt (*rstr)->l_size = l_size; 11681203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1169e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1170e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1171fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 11722b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 11732b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 1174fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 1175e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11767509a596Sjeremylt } 11777509a596Sjeremylt 11787509a596Sjeremylt /** 1179ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unsigned version. 1180c17ec2beSJeremy L Thompson 1181ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 1182c17ec2beSJeremy L Thompson 1183ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unsigned reference to 1184ca94c3ddSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned `CeedElemRestriction` 1185c17ec2beSJeremy L Thompson 1186c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1187c17ec2beSJeremy L Thompson 1188c17ec2beSJeremy L Thompson @ref User 1189c17ec2beSJeremy L Thompson **/ 1190c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1191c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1192c17ec2beSJeremy L Thompson 1193c17ec2beSJeremy L Thompson // Copy old rstr 1194c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1195*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(CeedElemRestrictionReturnCeed(rstr), CeedElemRestrictionView_Object, &(*rstr_unsigned)->obj)); 1196c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1197c17ec2beSJeremy L Thompson if (rstr->strides) { 1198c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1199c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1200c17ec2beSJeremy L Thompson } 12017c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1202c17ec2beSJeremy L Thompson 1203c17ec2beSJeremy L Thompson // Override Apply 1204c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1205c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1206c17ec2beSJeremy L Thompson } 1207c17ec2beSJeremy L Thompson 1208c17ec2beSJeremy L Thompson /** 1209ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unoriented version. 12107c1dbaffSSebastian Grimberg 1211ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 12127c1dbaffSSebastian Grimberg 1213ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unoriented reference to 1214ca94c3ddSJeremy L Thompson @param[in,out] rstr_unoriented Variable to store unoriented `CeedElemRestriction` 12157c1dbaffSSebastian Grimberg 12167c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 12177c1dbaffSSebastian Grimberg 12187c1dbaffSSebastian Grimberg @ref User 12197c1dbaffSSebastian Grimberg **/ 12207c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 12217c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 12227c1dbaffSSebastian Grimberg 12237c1dbaffSSebastian Grimberg // Copy old rstr 12247c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 1225*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(CeedElemRestrictionReturnCeed(rstr), CeedElemRestrictionView_Object, &(*rstr_unoriented)->obj)); 12267c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 12277c1dbaffSSebastian Grimberg if (rstr->strides) { 12287c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 12297c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 12307c1dbaffSSebastian Grimberg } 12317c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 12327c1dbaffSSebastian Grimberg 12337c1dbaffSSebastian Grimberg // Override Apply 12347c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 12357c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 12367c1dbaffSSebastian Grimberg } 12377c1dbaffSSebastian Grimberg 12387c1dbaffSSebastian Grimberg /** 1239ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction`. 12409fd66db6SSebastian Grimberg 1241ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy(). 12429560d06aSjeremylt 1243ca94c3ddSJeremy 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`. 1244ca94c3ddSJeremy L Thompson This `CeedElemRestriction` will be destroyed if `*rstr_copy` is the only reference to this `CeedElemRestriction`. 1245ea61e9acSJeremy L Thompson 1246ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to copy reference to 1247ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 12489560d06aSjeremylt 12499560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 12509560d06aSjeremylt 12519560d06aSjeremylt @ref User 12529560d06aSjeremylt **/ 12532b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1254393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 12552b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 12569560d06aSjeremylt *rstr_copy = rstr; 12579560d06aSjeremylt return CEED_ERROR_SUCCESS; 12589560d06aSjeremylt } 12599560d06aSjeremylt 12609560d06aSjeremylt /** 1261ca94c3ddSJeremy L Thompson @brief Create `CeedVector` associated with a `CeedElemRestriction` 1262b11c1e72Sjeremylt 1263ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1264ca94c3ddSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or `NULL` 1265ca94c3ddSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or `NULL` 1266b11c1e72Sjeremylt 1267b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1268dfdf5a53Sjeremylt 12697a982d89SJeremy L. Thompson @ref User 1270b11c1e72Sjeremylt **/ 12712b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1272d2643443SJeremy L Thompson CeedSize e_size, l_size; 12731203703bSJeremy L Thompson Ceed ceed; 127448acf710SJeremy L Thompson 12751203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 12761203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 12771203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size)); 12781203703bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(ceed, l_size, l_vec)); 12791203703bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(ceed, e_size, e_vec)); 12809bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed)); 1281e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1282d7b241e6Sjeremylt } 1283d7b241e6Sjeremylt 1284d7b241e6Sjeremylt /** 1285d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1286d7b241e6Sjeremylt 1287ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1288ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1289ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1290ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[num_elem * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1291fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1292ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1293b11c1e72Sjeremylt 1294b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1295dfdf5a53Sjeremylt 12967a982d89SJeremy L. Thompson @ref User 1297b11c1e72Sjeremylt **/ 12982b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1299701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1300701e7d35SJeremy L Thompson CeedInt num_elem; 1301d7b241e6Sjeremylt 1302d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1303701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_ru_len)); 1304701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1305d7b241e6Sjeremylt } else { 1306701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_u_len)); 1307701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1308d7b241e6Sjeremylt } 1309701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 13109bc66399SJeremy L Thompson CeedCheck(min_u_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1311701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1312701e7d35SJeremy L Thompson min_u_len); 1313701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 13149bc66399SJeremy L Thompson CeedCheck(min_ru_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1315701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1316701e7d35SJeremy L Thompson min_ru_len); 1317701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 1318701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1319e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1320d7b241e6Sjeremylt } 1321d7b241e6Sjeremylt 1322d7b241e6Sjeremylt /** 13233ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 13243ac8f562SJeremy L Thompson 1325ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1326ca94c3ddSJeremy L Thompson @param[in] elem Element number in range `[0, num_elem)` 13273ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1328ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1329ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape [`num_points * num_comp]` when `t_mode` = @ref CEED_NOTRANSPOSE). 13303ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 13313ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 13323ac8f562SJeremy L Thompson 13333ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13343ac8f562SJeremy L Thompson 13353ac8f562SJeremy L Thompson @ref User 13363ac8f562SJeremy L Thompson **/ 133705fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 13383ac8f562SJeremy L Thompson CeedRequest *request) { 1339701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1340701e7d35SJeremy L Thompson CeedInt num_elem; 13413ac8f562SJeremy L Thompson 13429bc66399SJeremy L Thompson CeedCheck(rstr->ApplyAtPointsInElement, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 13439bc66399SJeremy L Thompson "Backend does not implement CeedElemRestrictionApplyAtPointsInElement"); 13441ef3a2a9SJeremy L Thompson 13453ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 1346701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1347701e7d35SJeremy L Thompson 1348701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1349701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1350701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1351701e7d35SJeremy L Thompson min_ru_len = (CeedSize)num_points * (CeedSize)num_comp; 13523ac8f562SJeremy L Thompson } else { 1353701e7d35SJeremy L Thompson CeedInt num_points, num_comp; 1354701e7d35SJeremy L Thompson 1355701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points)); 1356701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1357701e7d35SJeremy L Thompson min_u_len = (CeedSize)num_points * (CeedSize)num_comp; 1358701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 13593ac8f562SJeremy L Thompson } 1360701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 13619bc66399SJeremy L Thompson CeedCheck(min_u_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 13623ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 13633ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1364701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1365701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 13669bc66399SJeremy L Thompson CeedCheck(min_ru_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 13673ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 13683ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 1369701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem); 1370701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 13719bc66399SJeremy L Thompson CeedCheck(elem < num_elem, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1372701e7d35SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, num_elem); 1373701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 13743ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 13753ac8f562SJeremy L Thompson } 13763ac8f562SJeremy L Thompson 13773ac8f562SJeremy L Thompson /** 1378d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1379be9261b7Sjeremylt 1380ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1381ca94c3ddSJeremy 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]` 1382ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1383ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE) 1384ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[block_size * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE). 1385fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1386ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1387be9261b7Sjeremylt 1388be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1389be9261b7Sjeremylt 13907a982d89SJeremy L. Thompson @ref Backend 1391be9261b7Sjeremylt **/ 13922b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 13932b730f8bSJeremy L Thompson CeedRequest *request) { 1394701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len; 1395701e7d35SJeremy L Thompson CeedInt block_size, num_elem; 1396be9261b7Sjeremylt 13979bc66399SJeremy L Thompson CeedCheck(rstr->ApplyBlock, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED, 13989bc66399SJeremy L Thompson "Backend does not implement CeedElemRestrictionApplyBlock"); 13996402da51SJeremy L Thompson 1400701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetBlockSize(rstr, &block_size)); 1401d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1402701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1403701e7d35SJeremy L Thompson 1404701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1405701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1406701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len)); 1407701e7d35SJeremy L Thompson min_ru_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1408be9261b7Sjeremylt } else { 1409701e7d35SJeremy L Thompson CeedInt elem_size, num_comp; 1410701e7d35SJeremy L Thompson 1411701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 1412701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 1413701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len)); 1414701e7d35SJeremy L Thompson min_u_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp; 1415be9261b7Sjeremylt } 1416701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len)); 14179bc66399SJeremy L Thompson CeedCheck(min_u_len == len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1418701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len, 1419701e7d35SJeremy L Thompson min_ru_len); 1420701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len)); 14219bc66399SJeremy L Thompson CeedCheck(min_ru_len == len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1422701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len, 1423701e7d35SJeremy L Thompson min_u_len); 1424701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 14259bc66399SJeremy L Thompson CeedCheck(block_size * block <= num_elem, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION, 1426701e7d35SJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, block_size * block, 1427701e7d35SJeremy L Thompson num_elem); 14282b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1429e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1430be9261b7Sjeremylt } 1431be9261b7Sjeremylt 1432be9261b7Sjeremylt /** 1433ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedElemRestriction` 1434b7c9bbdaSJeremy L Thompson 1435ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1436ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed` 1437b7c9bbdaSJeremy L Thompson 1438b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1439b7c9bbdaSJeremy L Thompson 1440b7c9bbdaSJeremy L Thompson @ref Advanced 1441b7c9bbdaSJeremy L Thompson **/ 1442b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1443*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectGetCeed((CeedObject)rstr, ceed)); 1444b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1445b7c9bbdaSJeremy L Thompson } 1446b7c9bbdaSJeremy L Thompson 1447b7c9bbdaSJeremy L Thompson /** 14486e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedElemRestriction` 14496e536b99SJeremy L Thompson 14506e536b99SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 14516e536b99SJeremy L Thompson 14526e536b99SJeremy L Thompson @return `Ceed` associated with the `rstr` 14536e536b99SJeremy L Thompson 14546e536b99SJeremy L Thompson @ref Advanced 14556e536b99SJeremy L Thompson **/ 1456*b0f67a9cSJeremy L Thompson Ceed CeedElemRestrictionReturnCeed(CeedElemRestriction rstr) { return CeedObjectReturnCeed((CeedObject)rstr); } 14576e536b99SJeremy L Thompson 14586e536b99SJeremy L Thompson /** 1459d979a051Sjeremylt @brief Get the L-vector component stride 1460a681ae63Sjeremylt 1461ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1462d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1463a681ae63Sjeremylt 1464a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1465a681ae63Sjeremylt 1466b7c9bbdaSJeremy L Thompson @ref Advanced 1467a681ae63Sjeremylt **/ 14682b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1469d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1470e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1471a681ae63Sjeremylt } 1472a681ae63Sjeremylt 1473a681ae63Sjeremylt /** 1474ca94c3ddSJeremy L Thompson @brief Get the total number of elements in the range of a `CeedElemRestriction` 1475a681ae63Sjeremylt 1476ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1477d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1478a681ae63Sjeremylt 1479a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1480a681ae63Sjeremylt 1481b7c9bbdaSJeremy L Thompson @ref Advanced 1482a681ae63Sjeremylt **/ 14832b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1484d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1485e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1486a681ae63Sjeremylt } 1487a681ae63Sjeremylt 1488a681ae63Sjeremylt /** 1489ca94c3ddSJeremy L Thompson @brief Get the size of elements in the `CeedElemRestriction` 1490a681ae63Sjeremylt 1491ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1492d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1493a681ae63Sjeremylt 1494a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1495a681ae63Sjeremylt 1496b7c9bbdaSJeremy L Thompson @ref Advanced 1497a681ae63Sjeremylt **/ 14982b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1499d1d35e2fSjeremylt *elem_size = rstr->elem_size; 15002c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 15012c7e7413SJeremy L Thompson } 15022c7e7413SJeremy L Thompson 15032c7e7413SJeremy L Thompson /** 150407d5dec1SJeremy L Thompson 1505725a297dSZach Atkins @brief Get the number of points in the offsets array for a points `CeedElemRestriction` 150607d5dec1SJeremy L Thompson 1507ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1508725a297dSZach Atkins @param[out] num_points The number of points in the offsets array 150907d5dec1SJeremy L Thompson 151007d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 151107d5dec1SJeremy L Thompson 1512c63574e3SJeremy L Thompson @ref User 151307d5dec1SJeremy L Thompson **/ 151407d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) { 15151203703bSJeremy L Thompson CeedRestrictionType rstr_type; 151607d5dec1SJeremy L Thompson 15171203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15186e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 151907d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 152007d5dec1SJeremy L Thompson 152107d5dec1SJeremy L Thompson *num_points = rstr->num_points; 152207d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 152307d5dec1SJeremy L Thompson } 152407d5dec1SJeremy L Thompson 152507d5dec1SJeremy L Thompson /** 152607d5dec1SJeremy L Thompson 1527ca94c3ddSJeremy L Thompson @brief Get the number of points in an element of a `CeedElemRestriction` at points 152807d5dec1SJeremy L Thompson 1529ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 153007d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 153107d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 153207d5dec1SJeremy L Thompson 153307d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 153407d5dec1SJeremy L Thompson 1535c63574e3SJeremy L Thompson @ref User 153607d5dec1SJeremy L Thompson **/ 153707d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 15381203703bSJeremy L Thompson CeedRestrictionType rstr_type; 153907d5dec1SJeremy L Thompson const CeedInt *offsets; 154007d5dec1SJeremy L Thompson 15411203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15426e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 154307d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 154407d5dec1SJeremy L Thompson 154507d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 154607d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem]; 154707d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 154807d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 154907d5dec1SJeremy L Thompson } 155007d5dec1SJeremy L Thompson 155107d5dec1SJeremy L Thompson /** 1552a4065bfbSZach Atkins @brief Get the minimum and/or maximum number of points in an element for a `CeedElemRestriction` at points 15532c7e7413SJeremy L Thompson 1554ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1555a4065bfbSZach Atkins @param[out] min_points Variable to minimum number of points in an element, or `NULL` 1556a4065bfbSZach Atkins @param[out] max_points Variable to maximum number of points in an element, or `NULL` 15572c7e7413SJeremy L Thompson 15582c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 15592c7e7413SJeremy L Thompson 15602c7e7413SJeremy L Thompson @ref Advanced 15612c7e7413SJeremy L Thompson **/ 1562a4065bfbSZach Atkins int CeedElemRestrictionGetMinMaxPointsInElement(CeedElemRestriction rstr, CeedInt *min_points, CeedInt *max_points) { 1563a4065bfbSZach Atkins CeedInt num_elem, num_points; 15642c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 15652c7e7413SJeremy L Thompson 15662c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 15676e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE, 1568a4065bfbSZach Atkins "Cannot compute min/max points for a CeedElemRestriction that does not use points"); 15692c7e7413SJeremy L Thompson 15702c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 15712c7e7413SJeremy L Thompson 1572a4065bfbSZach Atkins // Exit early if there are no elements 1573a4065bfbSZach Atkins if (num_elem == 0) { 1574a4065bfbSZach Atkins if (min_points) *min_points = 0; 1575a4065bfbSZach Atkins if (max_points) *max_points = 0; 1576a4065bfbSZach Atkins return CEED_ERROR_SUCCESS; 1577a4065bfbSZach Atkins } 1578a4065bfbSZach Atkins 1579a4065bfbSZach Atkins // Initialize to the number of points in the first element 1580a4065bfbSZach Atkins CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, 0, &num_points)); 1581a4065bfbSZach Atkins if (min_points) *min_points = num_points; 1582a4065bfbSZach Atkins if (max_points) *max_points = num_points; 1583a4065bfbSZach Atkins for (CeedInt e = 1; e < num_elem; e++) { 15842c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 1585a4065bfbSZach Atkins if (min_points) *min_points = CeedIntMin(num_points, *min_points); 1586a4065bfbSZach Atkins if (max_points) *max_points = CeedIntMax(num_points, *max_points); 15872c7e7413SJeremy L Thompson } 1588e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1589a681ae63Sjeremylt } 1590a681ae63Sjeremylt 1591a681ae63Sjeremylt /** 1592a4065bfbSZach Atkins @brief Get the maximum number of points in an element for a `CeedElemRestriction` at points 1593a4065bfbSZach Atkins 1594a4065bfbSZach Atkins @param[in] rstr `CeedElemRestriction` 1595a4065bfbSZach Atkins @param[out] max_points Variable to store maximum number of points in an element 1596a4065bfbSZach Atkins 1597a4065bfbSZach Atkins @return An error code: 0 - success, otherwise - failure 1598a4065bfbSZach Atkins 1599a4065bfbSZach Atkins @ref User 1600a4065bfbSZach Atkins 1601a4065bfbSZach Atkins @see CeedElemRestrictionGetMinMaxPointsInElement() 1602a4065bfbSZach Atkins **/ 1603a4065bfbSZach Atkins int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 1604a4065bfbSZach Atkins return CeedElemRestrictionGetMinMaxPointsInElement(rstr, NULL, max_points); 1605a4065bfbSZach Atkins } 1606a4065bfbSZach Atkins 1607a4065bfbSZach Atkins /** 1608a4065bfbSZach Atkins @brief Get the minimum number of points in an element for a `CeedElemRestriction` at points 1609a4065bfbSZach Atkins 1610a4065bfbSZach Atkins @param[in] rstr `CeedElemRestriction` 1611a4065bfbSZach Atkins @param[out] min_points Variable to store minimum 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 CeedElemRestrictionGetMinPointsInElement(CeedElemRestriction rstr, CeedInt *min_points) { 1620a4065bfbSZach Atkins return CeedElemRestrictionGetMinMaxPointsInElement(rstr, min_points, NULL); 1621a4065bfbSZach Atkins } 1622a4065bfbSZach Atkins 1623a4065bfbSZach Atkins /** 1624ca94c3ddSJeremy L Thompson @brief Get the size of the l-vector for a `CeedElemRestriction` 1625a681ae63Sjeremylt 1626ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1627701e7d35SJeremy L Thompson @param[out] l_size Variable to store l-vector size 1628a681ae63Sjeremylt 1629a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1630a681ae63Sjeremylt 1631b7c9bbdaSJeremy L Thompson @ref Advanced 1632a681ae63Sjeremylt **/ 16332b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1634d1d35e2fSjeremylt *l_size = rstr->l_size; 1635e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1636a681ae63Sjeremylt } 1637a681ae63Sjeremylt 1638a681ae63Sjeremylt /** 1639701e7d35SJeremy L Thompson @brief Get the size of the e-vector for a `CeedElemRestriction` 1640701e7d35SJeremy L Thompson 1641701e7d35SJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1642701e7d35SJeremy L Thompson @param[out] e_size Variable to store e-vector size 1643701e7d35SJeremy L Thompson 1644701e7d35SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1645701e7d35SJeremy L Thompson 1646701e7d35SJeremy L Thompson @ref Advanced 1647701e7d35SJeremy L Thompson **/ 1648701e7d35SJeremy L Thompson int CeedElemRestrictionGetEVectorSize(CeedElemRestriction rstr, CeedSize *e_size) { 1649701e7d35SJeremy L Thompson *e_size = rstr->e_size; 1650701e7d35SJeremy L Thompson return CEED_ERROR_SUCCESS; 1651701e7d35SJeremy L Thompson } 1652701e7d35SJeremy L Thompson 1653701e7d35SJeremy L Thompson /** 1654ca94c3ddSJeremy L Thompson @brief Get the number of components in the elements of a `CeedElemRestriction` 1655a681ae63Sjeremylt 1656ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1657d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1658a681ae63Sjeremylt 1659a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1660a681ae63Sjeremylt 1661b7c9bbdaSJeremy L Thompson @ref Advanced 1662a681ae63Sjeremylt **/ 16632b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1664d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1665e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1666a681ae63Sjeremylt } 1667a681ae63Sjeremylt 1668a681ae63Sjeremylt /** 1669ca94c3ddSJeremy L Thompson @brief Get the number of blocks in a `CeedElemRestriction` 1670a681ae63Sjeremylt 1671ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1672d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1673a681ae63Sjeremylt 1674a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1675a681ae63Sjeremylt 1676b7c9bbdaSJeremy L Thompson @ref Advanced 1677a681ae63Sjeremylt **/ 16782b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1679e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1680e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1681a681ae63Sjeremylt } 1682a681ae63Sjeremylt 1683a681ae63Sjeremylt /** 1684ca94c3ddSJeremy L Thompson @brief Get the size of blocks in the `CeedElemRestriction` 1685a681ae63Sjeremylt 1686ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1687e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1688a681ae63Sjeremylt 1689a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1690a681ae63Sjeremylt 1691b7c9bbdaSJeremy L Thompson @ref Advanced 1692a681ae63Sjeremylt **/ 1693e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1694e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1695e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1696a681ae63Sjeremylt } 1697a681ae63Sjeremylt 1698a681ae63Sjeremylt /** 1699ca94c3ddSJeremy L Thompson @brief Get the multiplicity of nodes in a `CeedElemRestriction` 17001469ee4dSjeremylt 1701ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` 1702ca94c3ddSJeremy L Thompson @param[out] mult Vector to store multiplicity (of size `l_size`) 17031469ee4dSjeremylt 17041469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 17051469ee4dSjeremylt 17067a982d89SJeremy L. Thompson @ref User 17071469ee4dSjeremylt **/ 17082b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1709d1d35e2fSjeremylt CeedVector e_vec; 17101469ee4dSjeremylt 171125509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 17122b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 17131469ee4dSjeremylt 171425509ebbSRezgar Shakeri // Compute e_vec = E * 1 17152b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 17162b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 171725509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 17182b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 17192b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 17201469ee4dSjeremylt // Cleanup 17212b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1722e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 17231469ee4dSjeremylt } 17241469ee4dSjeremylt 17251469ee4dSjeremylt /** 17264c789ea2SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedElemRestrictionView() output 17274c789ea2SJeremy L Thompson 17284c789ea2SJeremy L Thompson @param[in] rstr `CeedElemRestriction` to set the number of view tabs 17294c789ea2SJeremy L Thompson @param[in] num_tabs Number of view tabs to set 17304c789ea2SJeremy L Thompson 17314c789ea2SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 17324c789ea2SJeremy L Thompson 17334c789ea2SJeremy L Thompson @ref User 17344c789ea2SJeremy L Thompson **/ 17354c789ea2SJeremy L Thompson int CeedElemRestrictionSetNumViewTabs(CeedElemRestriction rstr, CeedInt num_tabs) { 17364c789ea2SJeremy L Thompson CeedCheck(num_tabs >= 0, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "Number of view tabs must be non-negative"); 17374c789ea2SJeremy L Thompson rstr->num_tabs = num_tabs; 17384c789ea2SJeremy L Thompson return CEED_ERROR_SUCCESS; 17394c789ea2SJeremy L Thompson } 17404c789ea2SJeremy L Thompson 17414c789ea2SJeremy L Thompson /** 1742690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedElemRestrictionView() output 1743690992b2SZach Atkins 1744690992b2SZach Atkins @param[in] rstr `CeedElemRestriction` to get the number of view tabs 1745690992b2SZach Atkins @param[out] num_tabs Number of view tabs 1746690992b2SZach Atkins 1747690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure 1748690992b2SZach Atkins 1749690992b2SZach Atkins @ref User 1750690992b2SZach Atkins **/ 1751690992b2SZach Atkins int CeedElemRestrictionGetNumViewTabs(CeedElemRestriction rstr, CeedInt *num_tabs) { 1752690992b2SZach Atkins *num_tabs = rstr->num_tabs; 1753690992b2SZach Atkins return CEED_ERROR_SUCCESS; 1754690992b2SZach Atkins } 1755690992b2SZach Atkins 1756690992b2SZach Atkins /** 1757ca94c3ddSJeremy L Thompson @brief View a `CeedElemRestriction` 1758f02ca4a2SJed Brown 1759ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view 1760ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 1761f02ca4a2SJed Brown 1762f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1763f02ca4a2SJed Brown 17647a982d89SJeremy L. Thompson @ref User 1765f02ca4a2SJed Brown **/ 1766f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 17674c789ea2SJeremy L Thompson char *tabs = NULL; 17680930e4e7SJeremy L Thompson CeedRestrictionType rstr_type; 17690930e4e7SJeremy L Thompson 17704c789ea2SJeremy L Thompson { 17714c789ea2SJeremy L Thompson CeedInt num_tabs = 0; 17724c789ea2SJeremy L Thompson 17734c789ea2SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumViewTabs(rstr, &num_tabs)); 17744c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * num_tabs + 1, &tabs)); 17754c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' '; 17764c789ea2SJeremy L Thompson } 17774c789ea2SJeremy L Thompson 17780930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 17790930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 17800930e4e7SJeremy L Thompson CeedInt max_points; 17810930e4e7SJeremy L Thompson 17820930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points)); 17830930e4e7SJeremy L Thompson fprintf(stream, 17844c789ea2SJeremy L Thompson "%sCeedElemRestriction at points from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT 17850930e4e7SJeremy L Thompson " points on an element\n", 17864c789ea2SJeremy L Thompson tabs, rstr->l_size, rstr->num_comp, rstr->num_elem, max_points); 17870930e4e7SJeremy L Thompson } else { 1788249f8407SJeremy L Thompson char strides_str[500]; 17891c66c397SJeremy L Thompson 17902b730f8bSJeremy L Thompson if (rstr->strides) { 1791249f8407SJeremy L Thompson sprintf(strides_str, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 17922b730f8bSJeremy L Thompson } else { 1793249f8407SJeremy L Thompson sprintf(strides_str, "%" CeedInt_FMT, rstr->comp_stride); 17942b730f8bSJeremy L Thompson } 1795249f8407SJeremy L Thompson fprintf(stream, 17964c789ea2SJeremy L Thompson "%s%sCeedElemRestriction from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT 1797249f8407SJeremy L Thompson " nodes each and %s %s\n", 17984c789ea2SJeremy L Thompson tabs, rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1799249f8407SJeremy L Thompson rstr->strides ? "strides" : "component stride", strides_str); 18000930e4e7SJeremy L Thompson } 18014c789ea2SJeremy L Thompson CeedCall(CeedFree(&tabs)); 1802e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1803f02ca4a2SJed Brown } 1804f02ca4a2SJed Brown 1805f02ca4a2SJed Brown /** 1806ca94c3ddSJeremy L Thompson @brief Destroy a `CeedElemRestriction` 1807b11c1e72Sjeremylt 1808ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to destroy 1809b11c1e72Sjeremylt 1810b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1811dfdf5a53Sjeremylt 18127a982d89SJeremy L. Thompson @ref User 1813b11c1e72Sjeremylt **/ 18144ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1815*b0f67a9cSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || CeedObjectDereference((CeedObject)*rstr) > 0) { 1816ad6481ceSJeremy L Thompson *rstr = NULL; 1817ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1818ad6481ceSJeremy L Thompson } 1819*b0f67a9cSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, CeedElemRestrictionReturnCeed(*rstr), CEED_ERROR_ACCESS, 18206574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1821c17ec2beSJeremy L Thompson 1822c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 18237c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1824c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1825c17ec2beSJeremy L Thompson 18262b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 1827*b0f67a9cSJeremy L Thompson CeedCall(CeedObjectDestroy(&(*rstr)->obj)); 18282b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1829e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1830d7b241e6Sjeremylt } 1831d7b241e6Sjeremylt 1832d7b241e6Sjeremylt /// @} 1833