13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 83d576824SJeremy L Thompson #include <ceed-impl.h> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 13c17ec2beSJeremy L Thompson #include <string.h> 14d7b241e6Sjeremylt 157a982d89SJeremy L. Thompson /// @file 167a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces 177a982d89SJeremy L. Thompson 187a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 197a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions 207a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 217a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper 227a982d89SJeremy L. Thompson /// @{ 237a982d89SJeremy L. Thompson 247a982d89SJeremy L. Thompson /** 25d979a051Sjeremylt @brief Permute and pad offsets for a blocked restriction 267a982d89SJeremy L. Thompson 27fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 280c73c039SSebastian Grimberg @param[out] blk_offsets Array of permuted and padded array values of shape [@a num_blk, @a elem_size, @a blk_size]. 29ea61e9acSJeremy L Thompson @param[in] num_blk Number of blocks 30ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 31ea61e9acSJeremy L Thompson @param[in] blk_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 **/ 382b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 392b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 402b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 412b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 422b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 432b730f8bSJeremy L Thompson } 442b730f8bSJeremy L Thompson } 452b730f8bSJeremy L Thompson } 46e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 477a982d89SJeremy L. Thompson } 487a982d89SJeremy L. Thompson 4977d1c127SSebastian Grimberg /** 5077d1c127SSebastian Grimberg @brief Permute and pad orientations for a blocked restriction 5177d1c127SSebastian Grimberg 52fcbe8c06SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size]. 530c73c039SSebastian Grimberg @param[out] blk_orients Array of permuted and padded array values of shape [@a num_blk, @a elem_size, @a blk_size]. 5477d1c127SSebastian Grimberg @param[in] num_blk Number of blocks 5577d1c127SSebastian Grimberg @param[in] num_elem Number of elements 5677d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 5777d1c127SSebastian Grimberg @param[in] elem_size Size of each element 5877d1c127SSebastian Grimberg 5977d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 6077d1c127SSebastian Grimberg 6177d1c127SSebastian Grimberg @ref Utility 6277d1c127SSebastian Grimberg **/ 630c73c039SSebastian Grimberg int CeedPermutePadOrients(const bool *orients, bool *blk_orients, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 6477d1c127SSebastian Grimberg for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 6577d1c127SSebastian Grimberg for (CeedInt j = 0; j < blk_size; j++) { 6677d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 6777d1c127SSebastian Grimberg blk_orients[e * elem_size + k * blk_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 6877d1c127SSebastian Grimberg } 6977d1c127SSebastian Grimberg } 7077d1c127SSebastian Grimberg } 7177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 7277d1c127SSebastian Grimberg } 7377d1c127SSebastian Grimberg 740c73c039SSebastian Grimberg /** 750c73c039SSebastian Grimberg @brief Permute and pad curl-conforming orientations for a blocked restriction 760c73c039SSebastian Grimberg 770c73c039SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size]. 780c73c039SSebastian Grimberg @param[out] blk_curl_orients Array of permuted and padded array values of shape [@a num_blk, @a elem_size, @a blk_size]. 790c73c039SSebastian Grimberg @param[in] num_blk Number of blocks 800c73c039SSebastian Grimberg @param[in] num_elem Number of elements 810c73c039SSebastian Grimberg @param[in] blk_size Number of elements in a block 820c73c039SSebastian Grimberg @param[in] elem_size Size of each element 830c73c039SSebastian Grimberg 840c73c039SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 850c73c039SSebastian Grimberg 860c73c039SSebastian Grimberg @ref Utility 870c73c039SSebastian Grimberg **/ 880c73c039SSebastian Grimberg int CeedPermutePadCurlOrients(const CeedInt8 *curl_orients, CeedInt8 *blk_curl_orients, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, 890c73c039SSebastian Grimberg CeedInt elem_size) { 900c73c039SSebastian Grimberg for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 910c73c039SSebastian Grimberg for (CeedInt j = 0; j < blk_size; j++) { 920c73c039SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 930c73c039SSebastian Grimberg blk_curl_orients[e * elem_size + k * blk_size + j] = curl_orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 940c73c039SSebastian Grimberg } 950c73c039SSebastian Grimberg } 960c73c039SSebastian Grimberg } 970c73c039SSebastian Grimberg return CEED_ERROR_SUCCESS; 980c73c039SSebastian Grimberg } 990c73c039SSebastian Grimberg 1007a982d89SJeremy L. Thompson /// @} 1017a982d89SJeremy L. Thompson 1027a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1037a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 1047a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1057a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 1067a982d89SJeremy L. Thompson /// @{ 1077a982d89SJeremy L. Thompson 1087a982d89SJeremy L. Thompson /** 109fcbe8c06SSebastian Grimberg @brief Get the type of a CeedElemRestriction 110a681ae63Sjeremylt 111fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 112fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 113fcbe8c06SSebastian Grimberg 114fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 115fcbe8c06SSebastian Grimberg 116fcbe8c06SSebastian Grimberg @ref Backend 117fcbe8c06SSebastian Grimberg **/ 118fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 119fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 120fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 121fcbe8c06SSebastian Grimberg } 122fcbe8c06SSebastian Grimberg 123fcbe8c06SSebastian Grimberg /** 124fcbe8c06SSebastian Grimberg @brief Get the strided status of a CeedElemRestriction 125fcbe8c06SSebastian Grimberg 126fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 127fcbe8c06SSebastian Grimberg @param[out] is_strided Variable to store strided status, 1 if strided else 0 128fcbe8c06SSebastian Grimberg **/ 129fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 130fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 131fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 132fcbe8c06SSebastian Grimberg } 133fcbe8c06SSebastian Grimberg 134fcbe8c06SSebastian Grimberg /** 135a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 1367a982d89SJeremy L. Thompson 137ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 138a681ae63Sjeremylt @param[out] strides Variable to store strides array 1397a982d89SJeremy L. Thompson 1407a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1417a982d89SJeremy L. Thompson 1427a982d89SJeremy L. Thompson @ref Backend 1437a982d89SJeremy L. Thompson **/ 1442b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1456574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1462b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 147e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1487a982d89SJeremy L. Thompson } 1497a982d89SJeremy L. Thompson 1507a982d89SJeremy L. Thompson /** 15177d1c127SSebastian Grimberg @brief Get the backend stride status of a CeedElemRestriction 15277d1c127SSebastian Grimberg 15377d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction 15477d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 15577d1c127SSebastian Grimberg 15677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 15777d1c127SSebastian Grimberg 15877d1c127SSebastian Grimberg @ref Backend 15977d1c127SSebastian Grimberg **/ 16077d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 16177d1c127SSebastian Grimberg CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 16277d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 16377d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 16477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 16577d1c127SSebastian Grimberg } 16677d1c127SSebastian Grimberg 16777d1c127SSebastian Grimberg /** 168bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 169bd33150aSjeremylt 170ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 171fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 172fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 173d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 174bd33150aSjeremylt 175bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 176bd33150aSjeremylt 177bd33150aSjeremylt @ref User 178bd33150aSjeremylt **/ 1792b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 1807c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 1817c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 182c17ec2beSJeremy L Thompson } else { 1836574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 1842b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 185d1d35e2fSjeremylt rstr->num_readers++; 186c17ec2beSJeremy L Thompson } 187e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 188430758c8SJeremy L Thompson } 189430758c8SJeremy L Thompson 190430758c8SJeremy L Thompson /** 191430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 192430758c8SJeremy L Thompson 193ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 194ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 195430758c8SJeremy L Thompson 196430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 197430758c8SJeremy L Thompson 198430758c8SJeremy L Thompson @ref User 199430758c8SJeremy L Thompson **/ 2002b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2017c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2027c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 203c17ec2beSJeremy L Thompson } else { 204430758c8SJeremy L Thompson *offsets = NULL; 205d1d35e2fSjeremylt rstr->num_readers--; 206c17ec2beSJeremy L Thompson } 207e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 208bd33150aSjeremylt } 209bd33150aSjeremylt 210bd33150aSjeremylt /** 21177d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction orientations array by memtype 2123ac43b2cSJeremy L Thompson 21377d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve orientations 214fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 215fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 21677d1c127SSebastian Grimberg @param[out] orients Array on memory type mem_type 2173ac43b2cSJeremy L Thompson 2183ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2193ac43b2cSJeremy L Thompson 22077d1c127SSebastian Grimberg @ref User 2213ac43b2cSJeremy L Thompson **/ 22277d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 223fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOrientations"); 22477d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 22577d1c127SSebastian Grimberg rstr->num_readers++; 226e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2273ac43b2cSJeremy L Thompson } 2283ac43b2cSJeremy L Thompson 2293ac43b2cSJeremy L Thompson /** 23077d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetOrientations() 231b435c5a6Srezgarshakeri 23277d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 23377d1c127SSebastian Grimberg @param[in] orients Array of orientation data 234b435c5a6Srezgarshakeri 235b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 236b435c5a6Srezgarshakeri 23777d1c127SSebastian Grimberg @ref User 238b435c5a6Srezgarshakeri **/ 23977d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 24077d1c127SSebastian Grimberg *orients = NULL; 24177d1c127SSebastian Grimberg rstr->num_readers--; 242b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 243b435c5a6Srezgarshakeri } 244b435c5a6Srezgarshakeri 245b435c5a6Srezgarshakeri /** 24677d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction curl-conforming orientations array by memtype 2477a982d89SJeremy L. Thompson 24877d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve curl-conforming orientations 249fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 250fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 25177d1c127SSebastian Grimberg @param[out] curl_orients Array on memory type mem_type 2527a982d89SJeremy L. Thompson 2537a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2547a982d89SJeremy L. Thompson 25577d1c127SSebastian Grimberg @ref User 2567a982d89SJeremy L. Thompson **/ 2570c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 258fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetCurlOrientations"); 25977d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 26077d1c127SSebastian Grimberg rstr->num_readers++; 26177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 26277d1c127SSebastian Grimberg } 26377d1c127SSebastian Grimberg 26477d1c127SSebastian Grimberg /** 26577d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetCurlOrientations() 26677d1c127SSebastian Grimberg 26777d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 26877d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 26977d1c127SSebastian Grimberg 27077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 27177d1c127SSebastian Grimberg 27277d1c127SSebastian Grimberg @ref User 27377d1c127SSebastian Grimberg **/ 2740c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 27577d1c127SSebastian Grimberg *curl_orients = NULL; 27677d1c127SSebastian Grimberg rstr->num_readers--; 277e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2787a982d89SJeremy L. Thompson } 2797a982d89SJeremy L. Thompson 2807a982d89SJeremy L. Thompson /** 28149fd234cSJeremy L Thompson 28249fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 28349fd234cSJeremy L Thompson 284ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 285fcbe8c06SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 286fcbe8c06SSebastian Grimberg 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] 28749fd234cSJeremy L Thompson 28849fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 28949fd234cSJeremy L Thompson 29049fd234cSJeremy L Thompson @ref Backend 29149fd234cSJeremy L Thompson **/ 2922b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 2936574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 2942b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 295e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 29649fd234cSJeremy L Thompson } 29749fd234cSJeremy L Thompson 29849fd234cSJeremy L Thompson /** 29949fd234cSJeremy L Thompson 30049fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 30149fd234cSJeremy L Thompson 302ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 303ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 304ea61e9acSJeremy 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] 30549fd234cSJeremy L Thompson 30649fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 30749fd234cSJeremy L Thompson 30849fd234cSJeremy L Thompson @ref Backend 30949fd234cSJeremy L Thompson **/ 3102b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 3112b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 312e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 31349fd234cSJeremy L Thompson } 31449fd234cSJeremy L Thompson 31549fd234cSJeremy L Thompson /** 3167a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3177a982d89SJeremy L. Thompson 318ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3197a982d89SJeremy L. Thompson @param[out] data Variable to store data 3207a982d89SJeremy L. Thompson 3217a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3227a982d89SJeremy L. Thompson 3237a982d89SJeremy L. Thompson @ref Backend 3247a982d89SJeremy L. Thompson **/ 325777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 326777ff853SJeremy L Thompson *(void **)data = rstr->data; 327e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3287a982d89SJeremy L. Thompson } 3297a982d89SJeremy L. Thompson 3307a982d89SJeremy L. Thompson /** 3317a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3327a982d89SJeremy L. Thompson 333ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 334ea61e9acSJeremy L Thompson @param[in] data Data to set 3357a982d89SJeremy L. Thompson 3367a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3377a982d89SJeremy L. Thompson 3387a982d89SJeremy L. Thompson @ref Backend 3397a982d89SJeremy L. Thompson **/ 340777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 341777ff853SJeremy L Thompson rstr->data = data; 342e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3437a982d89SJeremy L. Thompson } 3447a982d89SJeremy L. Thompson 34534359f16Sjeremylt /** 34634359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 34734359f16Sjeremylt 348ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 34934359f16Sjeremylt 35034359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 35134359f16Sjeremylt 35234359f16Sjeremylt @ref Backend 35334359f16Sjeremylt **/ 3549560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 35534359f16Sjeremylt rstr->ref_count++; 35634359f16Sjeremylt return CEED_ERROR_SUCCESS; 35734359f16Sjeremylt } 35834359f16Sjeremylt 3596e15d496SJeremy L Thompson /** 3606e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 3616e15d496SJeremy L Thompson 362ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 363ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 364ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 3656e15d496SJeremy L Thompson 3666e15d496SJeremy L Thompson @ref Backend 3676e15d496SJeremy L Thompson **/ 3682b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 3692b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 370*89edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 371*89edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 37277d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 373*89edb9e3SSebastian Grimberg switch (rstr_type) { 374*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 375*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 37677d1c127SSebastian Grimberg scale = 1; 377*89edb9e3SSebastian Grimberg break; 378*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 37977d1c127SSebastian Grimberg scale = 2; 380*89edb9e3SSebastian Grimberg break; 381*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 38277d1c127SSebastian Grimberg scale = 6; 383*89edb9e3SSebastian Grimberg break; 3846e15d496SJeremy L Thompson } 38577d1c127SSebastian Grimberg } else { 386*89edb9e3SSebastian Grimberg switch (rstr_type) { 387*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 388*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 38977d1c127SSebastian Grimberg scale = 0; 390*89edb9e3SSebastian Grimberg break; 391*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 39277d1c127SSebastian Grimberg scale = 1; 393*89edb9e3SSebastian Grimberg break; 394*89edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 39577d1c127SSebastian Grimberg scale = 5; 396*89edb9e3SSebastian Grimberg break; 39777d1c127SSebastian Grimberg } 39877d1c127SSebastian Grimberg } 3996e15d496SJeremy L Thompson *flops = e_size * scale; 4006e15d496SJeremy L Thompson 4016e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 4026e15d496SJeremy L Thompson } 4036e15d496SJeremy L Thompson 4047a982d89SJeremy L. Thompson /// @} 4057a982d89SJeremy L. Thompson 40615910d16Sjeremylt /// @cond DOXYGEN_SKIP 40715910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 40815910d16Sjeremylt /// @endcond 40915910d16Sjeremylt 4107a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4117a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4127a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4137a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 414d7b241e6Sjeremylt /// @{ 415d7b241e6Sjeremylt 4167a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 41745f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4187a982d89SJeremy L. Thompson 4194cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 4202b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4217a982d89SJeremy L. Thompson 422d7b241e6Sjeremylt /** 423b11c1e72Sjeremylt @brief Create a CeedElemRestriction 424d7b241e6Sjeremylt 425ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 426ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 427ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 428ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 429fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 430fcbe8c06SSebastian Grimberg 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. 431fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 432fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 433ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 434ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 435fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 436fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 437fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 438ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 439d7b241e6Sjeremylt 440b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 441dfdf5a53Sjeremylt 4427a982d89SJeremy L. Thompson @ref User 443b11c1e72Sjeremylt **/ 4442b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4452b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4465fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4475fe0d4faSjeremylt Ceed delegate; 4486574a04fSJeremy L Thompson 4492b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 45077d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4512b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 452e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4535fe0d4faSjeremylt } 4545fe0d4faSjeremylt 4556574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4566574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4576574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 458e022e1f8SJeremy L Thompson 4592b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 460db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 461d1d35e2fSjeremylt (*rstr)->ref_count = 1; 462d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 463d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 464d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 465d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 466d1d35e2fSjeremylt (*rstr)->l_size = l_size; 467d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 468d1d35e2fSjeremylt (*rstr)->blk_size = 1; 46961a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 470fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 471e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 472d7b241e6Sjeremylt } 473d7b241e6Sjeremylt 474d7b241e6Sjeremylt /** 47577d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 476fc0567d9Srezgarshakeri 477ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 478ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 479ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 480ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 481fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 482fcbe8c06SSebastian Grimberg 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. 483fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 484fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 485ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 486ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 487fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 488fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 489fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 49077d1c127SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size] with bool false for positively oriented and true to flip the orientation. 491ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 492fc0567d9Srezgarshakeri 493fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 494fc0567d9Srezgarshakeri 495fc0567d9Srezgarshakeri @ref User 496fc0567d9Srezgarshakeri **/ 4972b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 49877d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 499fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 500fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 501fc0567d9Srezgarshakeri Ceed delegate; 5026574a04fSJeremy L Thompson 5032b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 504fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5052b730f8bSJeremy L Thompson CeedCall( 50677d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 507fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 508fc0567d9Srezgarshakeri } 509fc0567d9Srezgarshakeri 5106574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5116574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5126574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 513e022e1f8SJeremy L Thompson 5142b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 515db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 516fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 517fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 518fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 519fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 520fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 521fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 522fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 523fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 524fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 525fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 52677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 52777d1c127SSebastian Grimberg } 52877d1c127SSebastian Grimberg 52977d1c127SSebastian Grimberg /** 53077d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 53177d1c127SSebastian Grimberg 53277d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 53377d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 53477d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 53577d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 536fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 537fcbe8c06SSebastian Grimberg 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. 538fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 539fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 54077d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 54177d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 542fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 543fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 544fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 5457c1dbaffSSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[i * 3 * elem_size] 5467c1dbaffSSebastian Grimberg = curl_orients[(i + 1) * 3 * elem_size - 1] = 0, where 0 <= i < @a num_elem) which is applied to the element unknowns upon restriction. This 5477c1dbaffSSebastian Grimberg orientation matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the element restriction operation, 5487c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 54977d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 55077d1c127SSebastian Grimberg 55177d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 55277d1c127SSebastian Grimberg 55377d1c127SSebastian Grimberg @ref User 55477d1c127SSebastian Grimberg **/ 55577d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 5560c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 55777d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 558fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 55977d1c127SSebastian Grimberg Ceed delegate; 56077d1c127SSebastian Grimberg 56177d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 562fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 56377d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 56477d1c127SSebastian Grimberg curl_orients, rstr)); 56577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 56677d1c127SSebastian Grimberg } 56777d1c127SSebastian Grimberg 56877d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 56977d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 57077d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 57177d1c127SSebastian Grimberg 57277d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 573fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 57477d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 57577d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 57677d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 57777d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 57877d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 57977d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 58077d1c127SSebastian Grimberg (*rstr)->num_blk = num_elem; 58177d1c127SSebastian Grimberg (*rstr)->blk_size = 1; 582fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 583fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 584fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 585fc0567d9Srezgarshakeri } 586fc0567d9Srezgarshakeri 587fc0567d9Srezgarshakeri /** 5887509a596Sjeremylt @brief Create a strided CeedElemRestriction 589d7b241e6Sjeremylt 590ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 591ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 592ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 593ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 594fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 595fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 596fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 597fcbe8c06SSebastian Grimberg 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]. 598fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 599ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 600d7b241e6Sjeremylt 601b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 602dfdf5a53Sjeremylt 6037a982d89SJeremy L. Thompson @ref User 604b11c1e72Sjeremylt **/ 6052b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 606f90c8643Sjeremylt CeedElemRestriction *rstr) { 6075fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6085fe0d4faSjeremylt Ceed delegate; 609b04eb3d9SSebastian Grimberg 6102b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 611fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6122b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 613e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6145fe0d4faSjeremylt } 6155fe0d4faSjeremylt 6166574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6176574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 618e022e1f8SJeremy L Thompson 6192b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 620db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 621d1d35e2fSjeremylt (*rstr)->ref_count = 1; 622d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 623d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 624d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 625d1d35e2fSjeremylt (*rstr)->l_size = l_size; 626d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 627d1d35e2fSjeremylt (*rstr)->blk_size = 1; 628fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6292b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6302b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 631fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 632e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 633d7b241e6Sjeremylt } 634d7b241e6Sjeremylt 635d7b241e6Sjeremylt /** 636b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 637d7b241e6Sjeremylt 638ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 639ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 640ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 641ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 642ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 643fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 644fcbe8c06SSebastian Grimberg 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. 645fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 646fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 647ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 648ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 649fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 650fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 651fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. The backend will permute and pad this array to the desired ordering for 652fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 653ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 654d7b241e6Sjeremylt 655b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 656dfdf5a53Sjeremylt 6577a982d89SJeremy L. Thompson @ref Backend 658b11c1e72Sjeremylt **/ 6592b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 6602b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 6614ce2993fSjeremylt CeedElemRestriction *rstr) { 662d1d35e2fSjeremylt CeedInt *blk_offsets; 663d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 664d7b241e6Sjeremylt 6655fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6665fe0d4faSjeremylt Ceed delegate; 6676574a04fSJeremy L Thompson 6682b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 6696402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 6702b730f8bSJeremy L Thompson CeedCall( 6712b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 672e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6735fe0d4faSjeremylt } 674d7b241e6Sjeremylt 6756574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6766574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 6776574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 6786574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 679e022e1f8SJeremy L Thompson 6802b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 6812b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 682d7b241e6Sjeremylt 683db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 684db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 685d1d35e2fSjeremylt (*rstr)->ref_count = 1; 686d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 687d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 688d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 689d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 690d1d35e2fSjeremylt (*rstr)->l_size = l_size; 691d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 692d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 69361a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 694fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, NULL, *rstr)); 695d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 6962b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 6971d102b48SJeremy L Thompson } 698e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 699d7b241e6Sjeremylt } 700d7b241e6Sjeremylt 701b11c1e72Sjeremylt /** 70277d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 70377d1c127SSebastian Grimberg 70477d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 70577d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 70677d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 70777d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 70877d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 709fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 710fcbe8c06SSebastian Grimberg 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. 711fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 712fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 71377d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 71477d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 715fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 716fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 717fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. The backend will permute and pad this array to the desired ordering for 718fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 719fcbe8c06SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size] with bool false for positively oriented and true to flip the orientation. 720fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 72177d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 72277d1c127SSebastian Grimberg 72377d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 72477d1c127SSebastian Grimberg 72577d1c127SSebastian Grimberg @ref Backend 72677d1c127SSebastian Grimberg **/ 72777d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 72877d1c127SSebastian Grimberg CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 72977d1c127SSebastian Grimberg const bool *orients, CeedElemRestriction *rstr) { 73077d1c127SSebastian Grimberg CeedInt *blk_offsets; 73177d1c127SSebastian Grimberg bool *blk_orients; 73277d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 73377d1c127SSebastian Grimberg 734fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 73577d1c127SSebastian Grimberg Ceed delegate; 73677d1c127SSebastian Grimberg 73777d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 738fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 73977d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 74077d1c127SSebastian Grimberg offsets, orients, rstr)); 74177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 74277d1c127SSebastian Grimberg } 74377d1c127SSebastian Grimberg 74477d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 74577d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 74677d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 74777d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 74877d1c127SSebastian Grimberg 74977d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 75077d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_orients)); 75177d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 7520c73c039SSebastian Grimberg CeedCall(CeedPermutePadOrients(orients, blk_orients, num_blk, num_elem, blk_size, elem_size)); 75377d1c127SSebastian Grimberg 754fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 755fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 75677d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 75777d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 75877d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 75977d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 76077d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 76177d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 76277d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 76377d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 764fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 765fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, (const bool *)blk_orients, NULL, *rstr)); 76677d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 76777d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 76877d1c127SSebastian Grimberg } 76977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 77077d1c127SSebastian Grimberg } 77177d1c127SSebastian Grimberg 77277d1c127SSebastian Grimberg /** 77377d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 77477d1c127SSebastian Grimberg 77577d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 77677d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 77777d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 77877d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 77977d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 780fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 781fcbe8c06SSebastian Grimberg 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. 782fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 783fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 78477d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 78577d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 786fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 787fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 788fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. The backend will permute and pad this array to the desired ordering 789fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 7907c1dbaffSSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size] representing a row-major tridiagonal matrix (curl_orients[i * 3 * elem_size] 7917c1dbaffSSebastian Grimberg = curl_orients[(i + 1) * 3 * elem_size - 1] = 0, where 0 <= i < @a num_elem) which is applied to the element unknowns upon restriction. This 7927c1dbaffSSebastian Grimberg orientation matrix allows for pairs of face degrees of freedom on elements for H(curl) spaces to be coupled in the element restriction operation, 7937c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). Will also be permuted and padded 7947c1dbaffSSebastian Grimberg similarly to @a offsets. 79577d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 79677d1c127SSebastian Grimberg 79777d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 79877d1c127SSebastian Grimberg 79977d1c127SSebastian Grimberg @ref Backend 80077d1c127SSebastian Grimberg **/ 80177d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, 80277d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 8030c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 80477d1c127SSebastian Grimberg CeedInt *blk_offsets; 8050c73c039SSebastian Grimberg CeedInt8 *blk_curl_orients; 80677d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 80777d1c127SSebastian Grimberg 808fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 80977d1c127SSebastian Grimberg Ceed delegate; 81077d1c127SSebastian Grimberg 81177d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 812fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 81377d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 81477d1c127SSebastian Grimberg offsets, curl_orients, rstr)); 81577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 81677d1c127SSebastian Grimberg } 81777d1c127SSebastian Grimberg 81877d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 81977d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 82077d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 82177d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 82277d1c127SSebastian Grimberg 82377d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 82477d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * 3 * elem_size, &blk_curl_orients)); 82577d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 8260c73c039SSebastian Grimberg CeedCall(CeedPermutePadCurlOrients(curl_orients, blk_curl_orients, num_blk, num_elem, blk_size, 3 * elem_size)); 82777d1c127SSebastian Grimberg 828fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 829fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 83077d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 83177d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 83277d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 83377d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 83477d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 83577d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 83677d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 83777d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 838fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 8390c73c039SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, (const CeedInt8 *)blk_curl_orients, 840fcbe8c06SSebastian Grimberg *rstr)); 84177d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 84277d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 84377d1c127SSebastian Grimberg } 84477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 84577d1c127SSebastian Grimberg } 84677d1c127SSebastian Grimberg 84777d1c127SSebastian Grimberg /** 84877d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 8497509a596Sjeremylt 850ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 851ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 852ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 853ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 854ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 855fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 856fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 857fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 858fcbe8c06SSebastian Grimberg 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]. 859fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 860ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 8617509a596Sjeremylt 8627509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 8637509a596Sjeremylt 8647a982d89SJeremy L. Thompson @ref User 8657509a596Sjeremylt **/ 8662b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 8678621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 868d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 8697509a596Sjeremylt 8707509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 8717509a596Sjeremylt Ceed delegate; 8726574a04fSJeremy L Thompson 8732b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 874fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 8752b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 876e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8777509a596Sjeremylt } 8787509a596Sjeremylt 8796574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 8806574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 8816574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 882e022e1f8SJeremy L Thompson 8832b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 884db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 885d1d35e2fSjeremylt (*rstr)->ref_count = 1; 886d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 887d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 888d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 889d1d35e2fSjeremylt (*rstr)->l_size = l_size; 890d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 891d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 892fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 8932b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 8942b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 895fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 896e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8977509a596Sjeremylt } 8987509a596Sjeremylt 8997509a596Sjeremylt /** 9007c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unsigned version. 901c17ec2beSJeremy L Thompson 902c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 903c17ec2beSJeremy L Thompson 904c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 905c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 906c17ec2beSJeremy L Thompson 907c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 908c17ec2beSJeremy L Thompson 909c17ec2beSJeremy L Thompson @ref User 910c17ec2beSJeremy L Thompson **/ 911c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 912c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 913c17ec2beSJeremy L Thompson 914c17ec2beSJeremy L Thompson // Copy old rstr 915c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 916c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 917c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 918c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 919c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 920c17ec2beSJeremy L Thompson if (rstr->strides) { 921c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 922c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 923c17ec2beSJeremy L Thompson } 9247c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 925c17ec2beSJeremy L Thompson 926c17ec2beSJeremy L Thompson // Override Apply 927c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 928c17ec2beSJeremy L Thompson 929c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 930c17ec2beSJeremy L Thompson } 931c17ec2beSJeremy L Thompson 932c17ec2beSJeremy L Thompson /** 9337c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unoriented version. 9347c1dbaffSSebastian Grimberg 9357c1dbaffSSebastian Grimberg Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 9367c1dbaffSSebastian Grimberg 9377c1dbaffSSebastian Grimberg @param[in] rstr CeedElemRestriction to create unoriented reference to 9387c1dbaffSSebastian Grimberg @param[in,out] rstr_unoriented Variable to store unoriented CeedElemRestriction 9397c1dbaffSSebastian Grimberg 9407c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 9417c1dbaffSSebastian Grimberg 9427c1dbaffSSebastian Grimberg @ref User 9437c1dbaffSSebastian Grimberg **/ 9447c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 9457c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 9467c1dbaffSSebastian Grimberg 9477c1dbaffSSebastian Grimberg // Copy old rstr 9487c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 9497c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 9507c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 9517c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 9527c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 9537c1dbaffSSebastian Grimberg if (rstr->strides) { 9547c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 9557c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 9567c1dbaffSSebastian Grimberg } 9577c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 9587c1dbaffSSebastian Grimberg 9597c1dbaffSSebastian Grimberg // Override Apply 9607c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 9617c1dbaffSSebastian Grimberg 9627c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 9637c1dbaffSSebastian Grimberg } 9647c1dbaffSSebastian Grimberg 9657c1dbaffSSebastian Grimberg /** 966ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 9679fd66db6SSebastian Grimberg 968ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 9699560d06aSjeremylt 9709fd66db6SSebastian Grimberg 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. 9719fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 972ea61e9acSJeremy L Thompson 973ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 974ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 9759560d06aSjeremylt 9769560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 9779560d06aSjeremylt 9789560d06aSjeremylt @ref User 9799560d06aSjeremylt **/ 9802b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 981393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 9822b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 9839560d06aSjeremylt *rstr_copy = rstr; 9849560d06aSjeremylt return CEED_ERROR_SUCCESS; 9859560d06aSjeremylt } 9869560d06aSjeremylt 9879560d06aSjeremylt /** 988b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 989b11c1e72Sjeremylt 990ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 991ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 992ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 993b11c1e72Sjeremylt 994b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 995dfdf5a53Sjeremylt 9967a982d89SJeremy L. Thompson @ref User 997b11c1e72Sjeremylt **/ 9982b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 999d2643443SJeremy L Thompson CeedSize e_size, l_size; 1000d1d35e2fSjeremylt l_size = rstr->l_size; 1001d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 10022b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 10032b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 1004e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1005d7b241e6Sjeremylt } 1006d7b241e6Sjeremylt 1007d7b241e6Sjeremylt /** 1008d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1009d7b241e6Sjeremylt 1010ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1011ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1012ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1013fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1014fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1015ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1016b11c1e72Sjeremylt 1017b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1018dfdf5a53Sjeremylt 10197a982d89SJeremy L. Thompson @ref User 1020b11c1e72Sjeremylt **/ 10212b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1022d7b241e6Sjeremylt CeedInt m, n; 1023d7b241e6Sjeremylt 1024d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1025d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1026d1d35e2fSjeremylt n = rstr->l_size; 1027d7b241e6Sjeremylt } else { 1028d1d35e2fSjeremylt m = rstr->l_size; 1029d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1030d7b241e6Sjeremylt } 10316574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10326574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10336574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10346574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10352b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1036e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1037d7b241e6Sjeremylt } 1038d7b241e6Sjeremylt 1039d7b241e6Sjeremylt /** 1040d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1041be9261b7Sjeremylt 1042ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1043ea61e9acSJeremy L Thompson @param[in] block Block number to restrict to/from, i.e. block=0 will handle elements [0 : blk_size] and block=3 will handle elements [3*blk_size 1044ea61e9acSJeremy L Thompson : 4*blk_size] 1045ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1046ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1047fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1048fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1049ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1050be9261b7Sjeremylt 1051be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1052be9261b7Sjeremylt 10537a982d89SJeremy L. Thompson @ref Backend 1054be9261b7Sjeremylt **/ 10552b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 10562b730f8bSJeremy L Thompson CeedRequest *request) { 1057be9261b7Sjeremylt CeedInt m, n; 1058be9261b7Sjeremylt 10596402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 10606402da51SJeremy L Thompson 1061d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1062d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1063d1d35e2fSjeremylt n = rstr->l_size; 1064be9261b7Sjeremylt } else { 1065d1d35e2fSjeremylt m = rstr->l_size; 1066d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1067be9261b7Sjeremylt } 10686574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10696574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10706574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10716574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10726574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 10736574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 10746574a04fSJeremy L Thompson rstr->num_elem); 10752b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1076e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1077be9261b7Sjeremylt } 1078be9261b7Sjeremylt 1079be9261b7Sjeremylt /** 1080b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1081b7c9bbdaSJeremy L Thompson 1082ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1083b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1084b7c9bbdaSJeremy L Thompson 1085b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1086b7c9bbdaSJeremy L Thompson 1087b7c9bbdaSJeremy L Thompson @ref Advanced 1088b7c9bbdaSJeremy L Thompson **/ 1089b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1090b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1091b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1092b7c9bbdaSJeremy L Thompson } 1093b7c9bbdaSJeremy L Thompson 1094b7c9bbdaSJeremy L Thompson /** 1095d979a051Sjeremylt @brief Get the L-vector component stride 1096a681ae63Sjeremylt 1097ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1098d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1099a681ae63Sjeremylt 1100a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1101a681ae63Sjeremylt 1102b7c9bbdaSJeremy L Thompson @ref Advanced 1103a681ae63Sjeremylt **/ 11042b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1105d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1106e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1107a681ae63Sjeremylt } 1108a681ae63Sjeremylt 1109a681ae63Sjeremylt /** 1110a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1111a681ae63Sjeremylt 1112ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1113d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1114a681ae63Sjeremylt 1115a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1116a681ae63Sjeremylt 1117b7c9bbdaSJeremy L Thompson @ref Advanced 1118a681ae63Sjeremylt **/ 11192b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1120d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1121e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1122a681ae63Sjeremylt } 1123a681ae63Sjeremylt 1124a681ae63Sjeremylt /** 1125a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1126a681ae63Sjeremylt 1127ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1128d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1129a681ae63Sjeremylt 1130a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1131a681ae63Sjeremylt 1132b7c9bbdaSJeremy L Thompson @ref Advanced 1133a681ae63Sjeremylt **/ 11342b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1135d1d35e2fSjeremylt *elem_size = rstr->elem_size; 1136e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1137a681ae63Sjeremylt } 1138a681ae63Sjeremylt 1139a681ae63Sjeremylt /** 1140d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1141a681ae63Sjeremylt 1142ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1143d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1144a681ae63Sjeremylt 1145a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1146a681ae63Sjeremylt 1147b7c9bbdaSJeremy L Thompson @ref Advanced 1148a681ae63Sjeremylt **/ 11492b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1150d1d35e2fSjeremylt *l_size = rstr->l_size; 1151e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1152a681ae63Sjeremylt } 1153a681ae63Sjeremylt 1154a681ae63Sjeremylt /** 1155ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1156a681ae63Sjeremylt 1157ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1158d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1159a681ae63Sjeremylt 1160a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1161a681ae63Sjeremylt 1162b7c9bbdaSJeremy L Thompson @ref Advanced 1163a681ae63Sjeremylt **/ 11642b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1165d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1166e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1167a681ae63Sjeremylt } 1168a681ae63Sjeremylt 1169a681ae63Sjeremylt /** 1170a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1171a681ae63Sjeremylt 1172ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1173d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1174a681ae63Sjeremylt 1175a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1176a681ae63Sjeremylt 1177b7c9bbdaSJeremy L Thompson @ref Advanced 1178a681ae63Sjeremylt **/ 11792b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1180d1d35e2fSjeremylt *num_block = rstr->num_blk; 1181e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1182a681ae63Sjeremylt } 1183a681ae63Sjeremylt 1184a681ae63Sjeremylt /** 1185a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1186a681ae63Sjeremylt 1187ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1188d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 1189a681ae63Sjeremylt 1190a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1191a681ae63Sjeremylt 1192b7c9bbdaSJeremy L Thompson @ref Advanced 1193a681ae63Sjeremylt **/ 11942b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 1195d1d35e2fSjeremylt *blk_size = rstr->blk_size; 1196e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1197a681ae63Sjeremylt } 1198a681ae63Sjeremylt 1199a681ae63Sjeremylt /** 1200d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 12011469ee4dSjeremylt 1202ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1203d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 12041469ee4dSjeremylt 12051469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 12061469ee4dSjeremylt 12077a982d89SJeremy L. Thompson @ref User 12081469ee4dSjeremylt **/ 12092b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1210d1d35e2fSjeremylt CeedVector e_vec; 12111469ee4dSjeremylt 121225509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 12132b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 12141469ee4dSjeremylt 121525509ebbSRezgar Shakeri // Compute e_vec = E * 1 12162b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 12172b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 121825509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 12192b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 12202b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 12211469ee4dSjeremylt // Cleanup 12222b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1223e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12241469ee4dSjeremylt } 12251469ee4dSjeremylt 12261469ee4dSjeremylt /** 1227f02ca4a2SJed Brown @brief View a CeedElemRestriction 1228f02ca4a2SJed Brown 1229f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1230f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1231f02ca4a2SJed Brown 1232f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1233f02ca4a2SJed Brown 12347a982d89SJeremy L. Thompson @ref User 1235f02ca4a2SJed Brown **/ 1236f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 12377509a596Sjeremylt char stridesstr[500]; 12382b730f8bSJeremy L Thompson if (rstr->strides) { 12392b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 12402b730f8bSJeremy L Thompson } else { 1241990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 12422b730f8bSJeremy L Thompson } 12437509a596Sjeremylt 12442b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 12452b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1246d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1247e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1248f02ca4a2SJed Brown } 1249f02ca4a2SJed Brown 1250f02ca4a2SJed Brown /** 1251b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1252b11c1e72Sjeremylt 1253ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1254b11c1e72Sjeremylt 1255b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1256dfdf5a53Sjeremylt 12577a982d89SJeremy L. Thompson @ref User 1258b11c1e72Sjeremylt **/ 12594ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1260393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1261ad6481ceSJeremy L Thompson *rstr = NULL; 1262ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1263ad6481ceSJeremy L Thompson } 12646574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 12656574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1266c17ec2beSJeremy L Thompson 1267c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 12687c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1269c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1270c17ec2beSJeremy L Thompson 12712b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 12722b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 12732b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1274e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1275d7b241e6Sjeremylt } 1276d7b241e6Sjeremylt 1277d7b241e6Sjeremylt /// @} 1278