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) { 180*7c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 181*7c1dbaffSSebastian 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) { 201*7c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 202*7c1dbaffSSebastian 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) { 36977d1c127SSebastian Grimberg const bool *orients = NULL; 3700c73c039SSebastian Grimberg const CeedInt8 *curl_orients = NULL; 3712b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 3726e15d496SJeremy L Thompson 37377d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetOrientations(rstr, CEED_MEM_HOST, &orients)); 37477d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionGetCurlOrientations(rstr, CEED_MEM_HOST, &curl_orients)); 37577d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 37677d1c127SSebastian Grimberg if (!orients && !curl_orients) { 37777d1c127SSebastian Grimberg scale = 1; 37877d1c127SSebastian Grimberg } else if (!curl_orients) { 37977d1c127SSebastian Grimberg scale = 2; 38077d1c127SSebastian Grimberg } else { 38177d1c127SSebastian Grimberg scale = 6; 3826e15d496SJeremy L Thompson } 38377d1c127SSebastian Grimberg } else { 38477d1c127SSebastian Grimberg if (!orients && !curl_orients) { 38577d1c127SSebastian Grimberg scale = 0; 38677d1c127SSebastian Grimberg } else if (!curl_orients) { 38777d1c127SSebastian Grimberg scale = 1; 38877d1c127SSebastian Grimberg } else { 38977d1c127SSebastian Grimberg scale = 5; 39077d1c127SSebastian Grimberg } 39177d1c127SSebastian Grimberg } 39277d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOrientations(rstr, &orients)); 39377d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionRestoreCurlOrientations(rstr, &curl_orients)); 3946e15d496SJeremy L Thompson *flops = e_size * scale; 3956e15d496SJeremy L Thompson 3966e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 3976e15d496SJeremy L Thompson } 3986e15d496SJeremy L Thompson 3997a982d89SJeremy L. Thompson /// @} 4007a982d89SJeremy L. Thompson 40115910d16Sjeremylt /// @cond DOXYGEN_SKIP 40215910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 40315910d16Sjeremylt /// @endcond 40415910d16Sjeremylt 4057a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4067a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4077a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4087a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 409d7b241e6Sjeremylt /// @{ 410d7b241e6Sjeremylt 4117a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 41245f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4137a982d89SJeremy L. Thompson 4144cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 4152b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4167a982d89SJeremy L. Thompson 417d7b241e6Sjeremylt /** 418b11c1e72Sjeremylt @brief Create a CeedElemRestriction 419d7b241e6Sjeremylt 420ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 421ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 422ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 423ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 424fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 425fcbe8c06SSebastian 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. 426fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 427fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 428ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 429ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 430fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 431fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 432fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 433ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 434d7b241e6Sjeremylt 435b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 436dfdf5a53Sjeremylt 4377a982d89SJeremy L. Thompson @ref User 438b11c1e72Sjeremylt **/ 4392b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4402b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4415fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4425fe0d4faSjeremylt Ceed delegate; 4436574a04fSJeremy L Thompson 4442b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 44577d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4462b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 447e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4485fe0d4faSjeremylt } 4495fe0d4faSjeremylt 4506574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4516574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4526574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 453e022e1f8SJeremy L Thompson 4542b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 455db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 456d1d35e2fSjeremylt (*rstr)->ref_count = 1; 457d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 458d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 459d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 460d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 461d1d35e2fSjeremylt (*rstr)->l_size = l_size; 462d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 463d1d35e2fSjeremylt (*rstr)->blk_size = 1; 464fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_DEFAULT; 465fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 466e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 467d7b241e6Sjeremylt } 468d7b241e6Sjeremylt 469d7b241e6Sjeremylt /** 47077d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 471fc0567d9Srezgarshakeri 472ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 473ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 474ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 475ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 476fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 477fcbe8c06SSebastian 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. 478fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 479fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 480ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 481ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 482fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 483fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 484fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 48577d1c127SSebastian 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. 486ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 487fc0567d9Srezgarshakeri 488fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 489fc0567d9Srezgarshakeri 490fc0567d9Srezgarshakeri @ref User 491fc0567d9Srezgarshakeri **/ 4922b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 49377d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 494fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 495fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 496fc0567d9Srezgarshakeri Ceed delegate; 4976574a04fSJeremy L Thompson 4982b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 499fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5002b730f8bSJeremy L Thompson CeedCall( 50177d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 502fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 503fc0567d9Srezgarshakeri } 504fc0567d9Srezgarshakeri 5056574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5066574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5076574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 508e022e1f8SJeremy L Thompson 5092b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 510db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 511fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 512fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 513fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 514fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 515fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 516fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 517fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 518fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 519fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 520fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 52177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 52277d1c127SSebastian Grimberg } 52377d1c127SSebastian Grimberg 52477d1c127SSebastian Grimberg /** 52577d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 52677d1c127SSebastian Grimberg 52777d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 52877d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 52977d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 53077d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 531fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 532fcbe8c06SSebastian 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. 533fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 534fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 53577d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 53677d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 537fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 538fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 539fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 540*7c1dbaffSSebastian 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] 541*7c1dbaffSSebastian 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 542*7c1dbaffSSebastian 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, 543*7c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 54477d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 54577d1c127SSebastian Grimberg 54677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 54777d1c127SSebastian Grimberg 54877d1c127SSebastian Grimberg @ref User 54977d1c127SSebastian Grimberg **/ 55077d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 5510c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 55277d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 553fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 55477d1c127SSebastian Grimberg Ceed delegate; 55577d1c127SSebastian Grimberg 55677d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 557fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 55877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 55977d1c127SSebastian Grimberg curl_orients, rstr)); 56077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 56177d1c127SSebastian Grimberg } 56277d1c127SSebastian Grimberg 56377d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 56477d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 56577d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 56677d1c127SSebastian Grimberg 56777d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 568fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 56977d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 57077d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 57177d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 57277d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 57377d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 57477d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 57577d1c127SSebastian Grimberg (*rstr)->num_blk = num_elem; 57677d1c127SSebastian Grimberg (*rstr)->blk_size = 1; 577fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 578fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 579fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 580fc0567d9Srezgarshakeri } 581fc0567d9Srezgarshakeri 582fc0567d9Srezgarshakeri /** 5837509a596Sjeremylt @brief Create a strided CeedElemRestriction 584d7b241e6Sjeremylt 585ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 586ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 587ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 588ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 589fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 590fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 591fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 592fcbe8c06SSebastian 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]. 593fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 594ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 595d7b241e6Sjeremylt 596b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 597dfdf5a53Sjeremylt 5987a982d89SJeremy L. Thompson @ref User 599b11c1e72Sjeremylt **/ 6002b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 601f90c8643Sjeremylt CeedElemRestriction *rstr) { 6025fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6035fe0d4faSjeremylt Ceed delegate; 604b04eb3d9SSebastian Grimberg 6052b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 606fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6072b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 608e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6095fe0d4faSjeremylt } 6105fe0d4faSjeremylt 6116574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6126574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 613e022e1f8SJeremy L Thompson 6142b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 615db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 616d1d35e2fSjeremylt (*rstr)->ref_count = 1; 617d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 618d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 619d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 620d1d35e2fSjeremylt (*rstr)->l_size = l_size; 621d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 622d1d35e2fSjeremylt (*rstr)->blk_size = 1; 623fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6242b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6252b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 626fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 627e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 628d7b241e6Sjeremylt } 629d7b241e6Sjeremylt 630d7b241e6Sjeremylt /** 631b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 632d7b241e6Sjeremylt 633ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 634ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 635ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 636ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 637ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 638fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 639fcbe8c06SSebastian 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. 640fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 641fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 642ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 643ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 644fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 645fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 646fcbe8c06SSebastian 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 647fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 648ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 649d7b241e6Sjeremylt 650b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 651dfdf5a53Sjeremylt 6527a982d89SJeremy L. Thompson @ref Backend 653b11c1e72Sjeremylt **/ 6542b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 6552b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 6564ce2993fSjeremylt CeedElemRestriction *rstr) { 657d1d35e2fSjeremylt CeedInt *blk_offsets; 658d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 659d7b241e6Sjeremylt 6605fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6615fe0d4faSjeremylt Ceed delegate; 6626574a04fSJeremy L Thompson 6632b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 6646402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 6652b730f8bSJeremy L Thompson CeedCall( 6662b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 667e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6685fe0d4faSjeremylt } 669d7b241e6Sjeremylt 6706574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6716574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 6726574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 6736574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 674e022e1f8SJeremy L Thompson 6752b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 6762b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 677d7b241e6Sjeremylt 678db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 679db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 680d1d35e2fSjeremylt (*rstr)->ref_count = 1; 681d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 682d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 683d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 684d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 685d1d35e2fSjeremylt (*rstr)->l_size = l_size; 686d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 687d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 688fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_DEFAULT; 689fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, NULL, *rstr)); 690d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 6912b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 6921d102b48SJeremy L Thompson } 693e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 694d7b241e6Sjeremylt } 695d7b241e6Sjeremylt 696b11c1e72Sjeremylt /** 69777d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 69877d1c127SSebastian Grimberg 69977d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 70077d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 70177d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 70277d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 70377d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 704fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 705fcbe8c06SSebastian 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. 706fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 707fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 70877d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 70977d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 710fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 711fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 712fcbe8c06SSebastian 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 713fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 714fcbe8c06SSebastian 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. 715fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 71677d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 71777d1c127SSebastian Grimberg 71877d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 71977d1c127SSebastian Grimberg 72077d1c127SSebastian Grimberg @ref Backend 72177d1c127SSebastian Grimberg **/ 72277d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 72377d1c127SSebastian Grimberg CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 72477d1c127SSebastian Grimberg const bool *orients, CeedElemRestriction *rstr) { 72577d1c127SSebastian Grimberg CeedInt *blk_offsets; 72677d1c127SSebastian Grimberg bool *blk_orients; 72777d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 72877d1c127SSebastian Grimberg 729fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 73077d1c127SSebastian Grimberg Ceed delegate; 73177d1c127SSebastian Grimberg 73277d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 733fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 73477d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 73577d1c127SSebastian Grimberg offsets, orients, rstr)); 73677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 73777d1c127SSebastian Grimberg } 73877d1c127SSebastian Grimberg 73977d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 74077d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 74177d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 74277d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 74377d1c127SSebastian Grimberg 74477d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 74577d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_orients)); 74677d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 7470c73c039SSebastian Grimberg CeedCall(CeedPermutePadOrients(orients, blk_orients, num_blk, num_elem, blk_size, elem_size)); 74877d1c127SSebastian Grimberg 749fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 750fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 75177d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 75277d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 75377d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 75477d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 75577d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 75677d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 75777d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 75877d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 759fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 760fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, (const bool *)blk_orients, NULL, *rstr)); 76177d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 76277d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 76377d1c127SSebastian Grimberg } 76477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 76577d1c127SSebastian Grimberg } 76677d1c127SSebastian Grimberg 76777d1c127SSebastian Grimberg /** 76877d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 76977d1c127SSebastian Grimberg 77077d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 77177d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 77277d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 77377d1c127SSebastian Grimberg @param[in] blk_size Number of elements in a block 77477d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 775fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 776fcbe8c06SSebastian 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. 777fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 778fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 77977d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 78077d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 781fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 782fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 783fcbe8c06SSebastian 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 784fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 785*7c1dbaffSSebastian 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] 786*7c1dbaffSSebastian 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 787*7c1dbaffSSebastian 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, 788*7c1dbaffSSebastian 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 789*7c1dbaffSSebastian Grimberg similarly to @a offsets. 79077d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 79177d1c127SSebastian Grimberg 79277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 79377d1c127SSebastian Grimberg 79477d1c127SSebastian Grimberg @ref Backend 79577d1c127SSebastian Grimberg **/ 79677d1c127SSebastian Grimberg int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, 79777d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 7980c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 79977d1c127SSebastian Grimberg CeedInt *blk_offsets; 8000c73c039SSebastian Grimberg CeedInt8 *blk_curl_orients; 80177d1c127SSebastian Grimberg CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 80277d1c127SSebastian Grimberg 803fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 80477d1c127SSebastian Grimberg Ceed delegate; 80577d1c127SSebastian Grimberg 80677d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 807fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 80877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 80977d1c127SSebastian Grimberg offsets, curl_orients, rstr)); 81077d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 81177d1c127SSebastian Grimberg } 81277d1c127SSebastian Grimberg 81377d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 81477d1c127SSebastian Grimberg CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 81577d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 81677d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 81777d1c127SSebastian Grimberg 81877d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 81977d1c127SSebastian Grimberg CeedCall(CeedCalloc(num_blk * blk_size * 3 * elem_size, &blk_curl_orients)); 82077d1c127SSebastian Grimberg CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 8210c73c039SSebastian Grimberg CeedCall(CeedPermutePadCurlOrients(curl_orients, blk_curl_orients, num_blk, num_elem, blk_size, 3 * elem_size)); 82277d1c127SSebastian Grimberg 823fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 824fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 82577d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 82677d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 82777d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 82877d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 82977d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 83077d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 83177d1c127SSebastian Grimberg (*rstr)->num_blk = num_blk; 83277d1c127SSebastian Grimberg (*rstr)->blk_size = blk_size; 833fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 8340c73c039SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, NULL, (const CeedInt8 *)blk_curl_orients, 835fcbe8c06SSebastian Grimberg *rstr)); 83677d1c127SSebastian Grimberg if (copy_mode == CEED_OWN_POINTER) { 83777d1c127SSebastian Grimberg CeedCall(CeedFree(&offsets)); 83877d1c127SSebastian Grimberg } 83977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 84077d1c127SSebastian Grimberg } 84177d1c127SSebastian Grimberg 84277d1c127SSebastian Grimberg /** 84377d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 8447509a596Sjeremylt 845ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 846ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 847ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 848ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 849ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 850fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 851fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 852fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 853fcbe8c06SSebastian 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]. 854fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 855ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 8567509a596Sjeremylt 8577509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 8587509a596Sjeremylt 8597a982d89SJeremy L. Thompson @ref User 8607509a596Sjeremylt **/ 8612b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 8628621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 863d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 8647509a596Sjeremylt 8657509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 8667509a596Sjeremylt Ceed delegate; 8676574a04fSJeremy L Thompson 8682b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 869fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 8702b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 871e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8727509a596Sjeremylt } 8737509a596Sjeremylt 8746574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 8756574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 8766574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 877e022e1f8SJeremy L Thompson 8782b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 879db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 880d1d35e2fSjeremylt (*rstr)->ref_count = 1; 881d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 882d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 883d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 884d1d35e2fSjeremylt (*rstr)->l_size = l_size; 885d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 886d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 887fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 8882b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 8892b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 890fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 891e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8927509a596Sjeremylt } 8937509a596Sjeremylt 8947509a596Sjeremylt /** 895*7c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unsigned version. 896c17ec2beSJeremy L Thompson 897c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 898c17ec2beSJeremy L Thompson 899c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 900c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 901c17ec2beSJeremy L Thompson 902c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 903c17ec2beSJeremy L Thompson 904c17ec2beSJeremy L Thompson @ref User 905c17ec2beSJeremy L Thompson **/ 906c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 907c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 908c17ec2beSJeremy L Thompson 909c17ec2beSJeremy L Thompson // Copy old rstr 910c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 911c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 912c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 913c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 914c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 915c17ec2beSJeremy L Thompson if (rstr->strides) { 916c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 917c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 918c17ec2beSJeremy L Thompson } 919*7c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 920c17ec2beSJeremy L Thompson 921c17ec2beSJeremy L Thompson // Override Apply 922c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 923c17ec2beSJeremy L Thompson 924c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 925c17ec2beSJeremy L Thompson } 926c17ec2beSJeremy L Thompson 927c17ec2beSJeremy L Thompson /** 928*7c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unoriented version. 929*7c1dbaffSSebastian Grimberg 930*7c1dbaffSSebastian Grimberg Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 931*7c1dbaffSSebastian Grimberg 932*7c1dbaffSSebastian Grimberg @param[in] rstr CeedElemRestriction to create unoriented reference to 933*7c1dbaffSSebastian Grimberg @param[in,out] rstr_unoriented Variable to store unoriented CeedElemRestriction 934*7c1dbaffSSebastian Grimberg 935*7c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 936*7c1dbaffSSebastian Grimberg 937*7c1dbaffSSebastian Grimberg @ref User 938*7c1dbaffSSebastian Grimberg **/ 939*7c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 940*7c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 941*7c1dbaffSSebastian Grimberg 942*7c1dbaffSSebastian Grimberg // Copy old rstr 943*7c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 944*7c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 945*7c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 946*7c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 947*7c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 948*7c1dbaffSSebastian Grimberg if (rstr->strides) { 949*7c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 950*7c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 951*7c1dbaffSSebastian Grimberg } 952*7c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 953*7c1dbaffSSebastian Grimberg 954*7c1dbaffSSebastian Grimberg // Override Apply 955*7c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 956*7c1dbaffSSebastian Grimberg 957*7c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 958*7c1dbaffSSebastian Grimberg } 959*7c1dbaffSSebastian Grimberg 960*7c1dbaffSSebastian Grimberg /** 961ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 9629fd66db6SSebastian Grimberg 963ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 9649560d06aSjeremylt 9659fd66db6SSebastian 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. 9669fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 967ea61e9acSJeremy L Thompson 968ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 969ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 9709560d06aSjeremylt 9719560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 9729560d06aSjeremylt 9739560d06aSjeremylt @ref User 9749560d06aSjeremylt **/ 9752b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 976393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 9772b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 9789560d06aSjeremylt *rstr_copy = rstr; 9799560d06aSjeremylt return CEED_ERROR_SUCCESS; 9809560d06aSjeremylt } 9819560d06aSjeremylt 9829560d06aSjeremylt /** 983b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 984b11c1e72Sjeremylt 985ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 986ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 987ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 988b11c1e72Sjeremylt 989b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 990dfdf5a53Sjeremylt 9917a982d89SJeremy L. Thompson @ref User 992b11c1e72Sjeremylt **/ 9932b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 994d2643443SJeremy L Thompson CeedSize e_size, l_size; 995d1d35e2fSjeremylt l_size = rstr->l_size; 996d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 9972b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 9982b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 999e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1000d7b241e6Sjeremylt } 1001d7b241e6Sjeremylt 1002d7b241e6Sjeremylt /** 1003d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1004d7b241e6Sjeremylt 1005ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1006ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1007ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1008fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1009fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1010ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1011b11c1e72Sjeremylt 1012b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1013dfdf5a53Sjeremylt 10147a982d89SJeremy L. Thompson @ref User 1015b11c1e72Sjeremylt **/ 10162b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1017d7b241e6Sjeremylt CeedInt m, n; 1018d7b241e6Sjeremylt 1019d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1020d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1021d1d35e2fSjeremylt n = rstr->l_size; 1022d7b241e6Sjeremylt } else { 1023d1d35e2fSjeremylt m = rstr->l_size; 1024d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 1025d7b241e6Sjeremylt } 10266574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10276574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10286574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10296574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10302b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1031e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1032d7b241e6Sjeremylt } 1033d7b241e6Sjeremylt 1034d7b241e6Sjeremylt /** 1035d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1036be9261b7Sjeremylt 1037ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1038ea61e9acSJeremy 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 1039ea61e9acSJeremy L Thompson : 4*blk_size] 1040ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1041ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1042fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1043fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1044ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1045be9261b7Sjeremylt 1046be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1047be9261b7Sjeremylt 10487a982d89SJeremy L. Thompson @ref Backend 1049be9261b7Sjeremylt **/ 10502b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 10512b730f8bSJeremy L Thompson CeedRequest *request) { 1052be9261b7Sjeremylt CeedInt m, n; 1053be9261b7Sjeremylt 10546402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 10556402da51SJeremy L Thompson 1056d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1057d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1058d1d35e2fSjeremylt n = rstr->l_size; 1059be9261b7Sjeremylt } else { 1060d1d35e2fSjeremylt m = rstr->l_size; 1061d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 1062be9261b7Sjeremylt } 10636574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 10646574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 10656574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 10666574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 10676574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 10686574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 10696574a04fSJeremy L Thompson rstr->num_elem); 10702b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1071e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1072be9261b7Sjeremylt } 1073be9261b7Sjeremylt 1074be9261b7Sjeremylt /** 1075b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1076b7c9bbdaSJeremy L Thompson 1077ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1078b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1079b7c9bbdaSJeremy L Thompson 1080b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1081b7c9bbdaSJeremy L Thompson 1082b7c9bbdaSJeremy L Thompson @ref Advanced 1083b7c9bbdaSJeremy L Thompson **/ 1084b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1085b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1086b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1087b7c9bbdaSJeremy L Thompson } 1088b7c9bbdaSJeremy L Thompson 1089b7c9bbdaSJeremy L Thompson /** 1090d979a051Sjeremylt @brief Get the L-vector component stride 1091a681ae63Sjeremylt 1092ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1093d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1094a681ae63Sjeremylt 1095a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1096a681ae63Sjeremylt 1097b7c9bbdaSJeremy L Thompson @ref Advanced 1098a681ae63Sjeremylt **/ 10992b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1100d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1101e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1102a681ae63Sjeremylt } 1103a681ae63Sjeremylt 1104a681ae63Sjeremylt /** 1105a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1106a681ae63Sjeremylt 1107ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1108d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1109a681ae63Sjeremylt 1110a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1111a681ae63Sjeremylt 1112b7c9bbdaSJeremy L Thompson @ref Advanced 1113a681ae63Sjeremylt **/ 11142b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1115d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1116e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1117a681ae63Sjeremylt } 1118a681ae63Sjeremylt 1119a681ae63Sjeremylt /** 1120a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1121a681ae63Sjeremylt 1122ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1123d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1124a681ae63Sjeremylt 1125a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1126a681ae63Sjeremylt 1127b7c9bbdaSJeremy L Thompson @ref Advanced 1128a681ae63Sjeremylt **/ 11292b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1130d1d35e2fSjeremylt *elem_size = rstr->elem_size; 1131e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1132a681ae63Sjeremylt } 1133a681ae63Sjeremylt 1134a681ae63Sjeremylt /** 1135d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1136a681ae63Sjeremylt 1137ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1138d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1139a681ae63Sjeremylt 1140a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1141a681ae63Sjeremylt 1142b7c9bbdaSJeremy L Thompson @ref Advanced 1143a681ae63Sjeremylt **/ 11442b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1145d1d35e2fSjeremylt *l_size = rstr->l_size; 1146e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1147a681ae63Sjeremylt } 1148a681ae63Sjeremylt 1149a681ae63Sjeremylt /** 1150ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1151a681ae63Sjeremylt 1152ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1153d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1154a681ae63Sjeremylt 1155a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1156a681ae63Sjeremylt 1157b7c9bbdaSJeremy L Thompson @ref Advanced 1158a681ae63Sjeremylt **/ 11592b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1160d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1161e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1162a681ae63Sjeremylt } 1163a681ae63Sjeremylt 1164a681ae63Sjeremylt /** 1165a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1166a681ae63Sjeremylt 1167ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1168d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1169a681ae63Sjeremylt 1170a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1171a681ae63Sjeremylt 1172b7c9bbdaSJeremy L Thompson @ref Advanced 1173a681ae63Sjeremylt **/ 11742b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1175d1d35e2fSjeremylt *num_block = rstr->num_blk; 1176e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1177a681ae63Sjeremylt } 1178a681ae63Sjeremylt 1179a681ae63Sjeremylt /** 1180a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1181a681ae63Sjeremylt 1182ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1183d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 1184a681ae63Sjeremylt 1185a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1186a681ae63Sjeremylt 1187b7c9bbdaSJeremy L Thompson @ref Advanced 1188a681ae63Sjeremylt **/ 11892b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 1190d1d35e2fSjeremylt *blk_size = rstr->blk_size; 1191e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1192a681ae63Sjeremylt } 1193a681ae63Sjeremylt 1194a681ae63Sjeremylt /** 1195d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 11961469ee4dSjeremylt 1197ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1198d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 11991469ee4dSjeremylt 12001469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 12011469ee4dSjeremylt 12027a982d89SJeremy L. Thompson @ref User 12031469ee4dSjeremylt **/ 12042b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1205d1d35e2fSjeremylt CeedVector e_vec; 12061469ee4dSjeremylt 120725509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 12082b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 12091469ee4dSjeremylt 121025509ebbSRezgar Shakeri // Compute e_vec = E * 1 12112b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 12122b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 121325509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 12142b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 12152b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 12161469ee4dSjeremylt // Cleanup 12172b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1218e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 12191469ee4dSjeremylt } 12201469ee4dSjeremylt 12211469ee4dSjeremylt /** 1222f02ca4a2SJed Brown @brief View a CeedElemRestriction 1223f02ca4a2SJed Brown 1224f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1225f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1226f02ca4a2SJed Brown 1227f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1228f02ca4a2SJed Brown 12297a982d89SJeremy L. Thompson @ref User 1230f02ca4a2SJed Brown **/ 1231f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 12327509a596Sjeremylt char stridesstr[500]; 12332b730f8bSJeremy L Thompson if (rstr->strides) { 12342b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 12352b730f8bSJeremy L Thompson } else { 1236990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 12372b730f8bSJeremy L Thompson } 12387509a596Sjeremylt 12392b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 12402b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1241d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1242e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1243f02ca4a2SJed Brown } 1244f02ca4a2SJed Brown 1245f02ca4a2SJed Brown /** 1246b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1247b11c1e72Sjeremylt 1248ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1249b11c1e72Sjeremylt 1250b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1251dfdf5a53Sjeremylt 12527a982d89SJeremy L. Thompson @ref User 1253b11c1e72Sjeremylt **/ 12544ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1255393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1256ad6481ceSJeremy L Thompson *rstr = NULL; 1257ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1258ad6481ceSJeremy L Thompson } 12596574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 12606574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1261c17ec2beSJeremy L Thompson 1262c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 1263*7c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1264c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1265c17ec2beSJeremy L Thompson 12662b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 12672b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 12682b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1269e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1270d7b241e6Sjeremylt } 1271d7b241e6Sjeremylt 1272d7b241e6Sjeremylt /// @} 1273