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]. 28e7f679fcSJeremy L Thompson @param[out] block_offsets Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 29e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 30ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 31e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 32ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 337a982d89SJeremy L. Thompson 347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 357a982d89SJeremy L. Thompson 367a982d89SJeremy L. Thompson @ref Utility 377a982d89SJeremy L. Thompson **/ 38e7f679fcSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *block_offsets, CeedInt num_block, CeedInt num_elem, CeedInt block_size, 39e7f679fcSJeremy L Thompson CeedInt elem_size) { 40e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 41e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 422b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 43e7f679fcSJeremy L Thompson block_offsets[e * elem_size + k * block_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 442b730f8bSJeremy L Thompson } 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 47e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 487a982d89SJeremy L. Thompson } 497a982d89SJeremy L. Thompson 5077d1c127SSebastian Grimberg /** 5177d1c127SSebastian Grimberg @brief Permute and pad orientations for a blocked restriction 5277d1c127SSebastian Grimberg 53fcbe8c06SSebastian Grimberg @param[in] orients Array of shape [@a num_elem, @a elem_size]. 54e7f679fcSJeremy L Thompson @param[out] block_orients Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 55e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 5677d1c127SSebastian Grimberg @param[in] num_elem Number of elements 57e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 5877d1c127SSebastian Grimberg @param[in] elem_size Size of each element 5977d1c127SSebastian Grimberg 6077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 6177d1c127SSebastian Grimberg 6277d1c127SSebastian Grimberg @ref Utility 6377d1c127SSebastian Grimberg **/ 64e7f679fcSJeremy L Thompson int CeedPermutePadOrients(const bool *orients, bool *block_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, CeedInt elem_size) { 65e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 66e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 6777d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 68e7f679fcSJeremy L Thompson block_orients[e * elem_size + k * block_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 6977d1c127SSebastian Grimberg } 7077d1c127SSebastian Grimberg } 7177d1c127SSebastian Grimberg } 7277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 7377d1c127SSebastian Grimberg } 7477d1c127SSebastian Grimberg 750c73c039SSebastian Grimberg /** 760c73c039SSebastian Grimberg @brief Permute and pad curl-conforming orientations for a blocked restriction 770c73c039SSebastian Grimberg 780c73c039SSebastian Grimberg @param[in] curl_orients Array of shape [@a num_elem, @a 3 * elem_size]. 79e7f679fcSJeremy L Thompson @param[out] block_curl_orients Array of permuted and padded array values of shape [@a num_block, @a elem_size, @a block_size]. 80e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks 810c73c039SSebastian Grimberg @param[in] num_elem Number of elements 82e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 830c73c039SSebastian Grimberg @param[in] elem_size Size of each element 840c73c039SSebastian Grimberg 850c73c039SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 860c73c039SSebastian Grimberg 870c73c039SSebastian Grimberg @ref Utility 880c73c039SSebastian Grimberg **/ 89e7f679fcSJeremy L Thompson int CeedPermutePadCurlOrients(const CeedInt8 *curl_orients, CeedInt8 *block_curl_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, 900c73c039SSebastian Grimberg CeedInt elem_size) { 91e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) { 92e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) { 930c73c039SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) { 94e7f679fcSJeremy L Thompson block_curl_orients[e * elem_size + k * block_size + j] = curl_orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 950c73c039SSebastian Grimberg } 960c73c039SSebastian Grimberg } 970c73c039SSebastian Grimberg } 980c73c039SSebastian Grimberg return CEED_ERROR_SUCCESS; 990c73c039SSebastian Grimberg } 1000c73c039SSebastian Grimberg 1017a982d89SJeremy L. Thompson /// @} 1027a982d89SJeremy L. Thompson 1037a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1047a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 1057a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1067a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 1077a982d89SJeremy L. Thompson /// @{ 1087a982d89SJeremy L. Thompson 1097a982d89SJeremy L. Thompson /** 110fcbe8c06SSebastian Grimberg @brief Get the type of a CeedElemRestriction 111a681ae63Sjeremylt 112fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 113fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type 114fcbe8c06SSebastian Grimberg 115fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 116fcbe8c06SSebastian Grimberg 117fcbe8c06SSebastian Grimberg @ref Backend 118fcbe8c06SSebastian Grimberg **/ 119fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) { 120fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type; 121fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 122fcbe8c06SSebastian Grimberg } 123fcbe8c06SSebastian Grimberg 124fcbe8c06SSebastian Grimberg /** 125fcbe8c06SSebastian Grimberg @brief Get the strided status of a CeedElemRestriction 126fcbe8c06SSebastian Grimberg 127fcbe8c06SSebastian Grimberg @param[in] rstr CeedElemRestriction 128fcbe8c06SSebastian Grimberg @param[out] is_strided Variable to store strided status, 1 if strided else 0 129fcbe8c06SSebastian Grimberg **/ 130fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 131fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED); 132fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS; 133fcbe8c06SSebastian Grimberg } 134fcbe8c06SSebastian Grimberg 135fcbe8c06SSebastian Grimberg /** 1363ac8f562SJeremy L Thompson @brief Get the points status of a CeedElemRestriction 1373ac8f562SJeremy L Thompson 1383ac8f562SJeremy L Thompson @param[in] rstr CeedElemRestriction 1393ac8f562SJeremy L Thompson @param[out] is_points Variable to store points status, 1 if points else 0 1403ac8f562SJeremy L Thompson **/ 1413ac8f562SJeremy L Thompson int CeedElemRestrictionIsPoints(CeedElemRestriction rstr, bool *is_points) { 1423ac8f562SJeremy L Thompson *is_points = (rstr->rstr_type == CEED_RESTRICTION_POINTS); 1433ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 1443ac8f562SJeremy L Thompson } 1453ac8f562SJeremy L Thompson 1463ac8f562SJeremy L Thompson /** 147a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 1487a982d89SJeremy L. Thompson 149ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 150a681ae63Sjeremylt @param[out] strides Variable to store strides array 1517a982d89SJeremy L. Thompson 1527a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1537a982d89SJeremy L. Thompson 1547a982d89SJeremy L. Thompson @ref Backend 1557a982d89SJeremy L. Thompson **/ 1562b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 1576574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1582b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 159e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1607a982d89SJeremy L. Thompson } 1617a982d89SJeremy L. Thompson 1627a982d89SJeremy L. Thompson /** 16377d1c127SSebastian Grimberg @brief Get the backend stride status of a CeedElemRestriction 16477d1c127SSebastian Grimberg 16577d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction 16677d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status 16777d1c127SSebastian Grimberg 16877d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 16977d1c127SSebastian Grimberg 17077d1c127SSebastian Grimberg @ref Backend 17177d1c127SSebastian Grimberg **/ 17277d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 17377d1c127SSebastian Grimberg CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 17477d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 17577d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 17677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 17777d1c127SSebastian Grimberg } 17877d1c127SSebastian Grimberg 17977d1c127SSebastian Grimberg /** 180bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 181bd33150aSjeremylt 182ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 183fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 184fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 185d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 186bd33150aSjeremylt 187bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 188bd33150aSjeremylt 189bd33150aSjeremylt @ref User 190bd33150aSjeremylt **/ 1912b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 1927c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 1937c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets)); 194c17ec2beSJeremy L Thompson } else { 1956574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 1962b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 197d1d35e2fSjeremylt rstr->num_readers++; 198c17ec2beSJeremy L Thompson } 199e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 200430758c8SJeremy L Thompson } 201430758c8SJeremy L Thompson 202430758c8SJeremy L Thompson /** 203430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 204430758c8SJeremy L Thompson 205ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 206ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 207430758c8SJeremy L Thompson 208430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 209430758c8SJeremy L Thompson 210430758c8SJeremy L Thompson @ref User 211430758c8SJeremy L Thompson **/ 2122b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 2137c1dbaffSSebastian Grimberg if (rstr->rstr_base) { 2147c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets)); 215c17ec2beSJeremy L Thompson } else { 216430758c8SJeremy L Thompson *offsets = NULL; 217d1d35e2fSjeremylt rstr->num_readers--; 218c17ec2beSJeremy L Thompson } 219e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 220bd33150aSjeremylt } 221bd33150aSjeremylt 222bd33150aSjeremylt /** 22377d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction orientations array by memtype 2243ac43b2cSJeremy L Thompson 22577d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve orientations 226fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 227fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 22877d1c127SSebastian Grimberg @param[out] orients Array on memory type mem_type 2293ac43b2cSJeremy L Thompson 2303ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2313ac43b2cSJeremy L Thompson 23277d1c127SSebastian Grimberg @ref User 2333ac43b2cSJeremy L Thompson **/ 23477d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 235fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOrientations"); 23677d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients)); 23777d1c127SSebastian Grimberg rstr->num_readers++; 238e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2393ac43b2cSJeremy L Thompson } 2403ac43b2cSJeremy L Thompson 2413ac43b2cSJeremy L Thompson /** 24277d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetOrientations() 243b435c5a6Srezgarshakeri 24477d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 24577d1c127SSebastian Grimberg @param[in] orients Array of orientation data 246b435c5a6Srezgarshakeri 247b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 248b435c5a6Srezgarshakeri 24977d1c127SSebastian Grimberg @ref User 250b435c5a6Srezgarshakeri **/ 25177d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) { 25277d1c127SSebastian Grimberg *orients = NULL; 25377d1c127SSebastian Grimberg rstr->num_readers--; 254b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 255b435c5a6Srezgarshakeri } 256b435c5a6Srezgarshakeri 257b435c5a6Srezgarshakeri /** 25877d1c127SSebastian Grimberg @brief Get read-only access to a CeedElemRestriction curl-conforming orientations array by memtype 2597a982d89SJeremy L. Thompson 26077d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to retrieve curl-conforming orientations 261fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array. 262fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached). 26377d1c127SSebastian Grimberg @param[out] curl_orients Array on memory type mem_type 2647a982d89SJeremy L. Thompson 2657a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2667a982d89SJeremy L. Thompson 26777d1c127SSebastian Grimberg @ref User 2687a982d89SJeremy L. Thompson **/ 2690c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 270fcbe8c06SSebastian Grimberg CeedCheck(rstr->GetCurlOrientations, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetCurlOrientations"); 27177d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients)); 27277d1c127SSebastian Grimberg rstr->num_readers++; 27377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 27477d1c127SSebastian Grimberg } 27577d1c127SSebastian Grimberg 27677d1c127SSebastian Grimberg /** 27777d1c127SSebastian Grimberg @brief Restore an orientations array obtained using CeedElemRestrictionGetCurlOrientations() 27877d1c127SSebastian Grimberg 27977d1c127SSebastian Grimberg @param[in] rstr CeedElemRestriction to restore 28077d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data 28177d1c127SSebastian Grimberg 28277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 28377d1c127SSebastian Grimberg 28477d1c127SSebastian Grimberg @ref User 28577d1c127SSebastian Grimberg **/ 2860c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) { 28777d1c127SSebastian Grimberg *curl_orients = NULL; 28877d1c127SSebastian Grimberg rstr->num_readers--; 289e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2907a982d89SJeremy L. Thompson } 2917a982d89SJeremy L. Thompson 2927a982d89SJeremy L. Thompson /** 29349fd234cSJeremy L Thompson 29449fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 29549fd234cSJeremy L Thompson 296ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 297fcbe8c06SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 298fcbe8c06SSebastian 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] 29949fd234cSJeremy L Thompson 30049fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 30149fd234cSJeremy L Thompson 30249fd234cSJeremy L Thompson @ref Backend 30349fd234cSJeremy L Thompson **/ 3042b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 3056574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 3062b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 307e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 30849fd234cSJeremy L Thompson } 30949fd234cSJeremy L Thompson 31049fd234cSJeremy L Thompson /** 31149fd234cSJeremy L Thompson 31249fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 31349fd234cSJeremy L Thompson 314ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 315ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 316ea61e9acSJeremy 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] 31749fd234cSJeremy L Thompson 31849fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 31949fd234cSJeremy L Thompson 32049fd234cSJeremy L Thompson @ref Backend 32149fd234cSJeremy L Thompson **/ 3222b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 3232b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 324e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 32549fd234cSJeremy L Thompson } 32649fd234cSJeremy L Thompson 32749fd234cSJeremy L Thompson /** 3287a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3297a982d89SJeremy L. Thompson 330ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3317a982d89SJeremy L. Thompson @param[out] data Variable to store data 3327a982d89SJeremy L. Thompson 3337a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3347a982d89SJeremy L. Thompson 3357a982d89SJeremy L. Thompson @ref Backend 3367a982d89SJeremy L. Thompson **/ 337777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 338777ff853SJeremy L Thompson *(void **)data = rstr->data; 339e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3407a982d89SJeremy L. Thompson } 3417a982d89SJeremy L. Thompson 3427a982d89SJeremy L. Thompson /** 3437a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3447a982d89SJeremy L. Thompson 345ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 346ea61e9acSJeremy L Thompson @param[in] data Data to set 3477a982d89SJeremy L. Thompson 3487a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3497a982d89SJeremy L. Thompson 3507a982d89SJeremy L. Thompson @ref Backend 3517a982d89SJeremy L. Thompson **/ 352777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 353777ff853SJeremy L Thompson rstr->data = data; 354e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3557a982d89SJeremy L. Thompson } 3567a982d89SJeremy L. Thompson 35734359f16Sjeremylt /** 35834359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 35934359f16Sjeremylt 360ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 36134359f16Sjeremylt 36234359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 36334359f16Sjeremylt 36434359f16Sjeremylt @ref Backend 36534359f16Sjeremylt **/ 3669560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 36734359f16Sjeremylt rstr->ref_count++; 36834359f16Sjeremylt return CEED_ERROR_SUCCESS; 36934359f16Sjeremylt } 37034359f16Sjeremylt 3716e15d496SJeremy L Thompson /** 3726e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 3736e15d496SJeremy L Thompson 374ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 375ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 376ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 3776e15d496SJeremy L Thompson 3786e15d496SJeremy L Thompson @ref Backend 3796e15d496SJeremy L Thompson **/ 3802b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 381e7f679fcSJeremy L Thompson CeedInt e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp, scale = 0; 38289edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 3831c66c397SJeremy L Thompson 38489edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 3853ac8f562SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) e_size = rstr->num_points * rstr->num_comp; 38677d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 38789edb9e3SSebastian Grimberg switch (rstr_type) { 3883ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 3893ac8f562SJeremy L Thompson scale = 0; 3903ac8f562SJeremy L Thompson break; 39189edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 39289edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 39377d1c127SSebastian Grimberg scale = 1; 39489edb9e3SSebastian Grimberg break; 39589edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 39677d1c127SSebastian Grimberg scale = 2; 39789edb9e3SSebastian Grimberg break; 39889edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 39977d1c127SSebastian Grimberg scale = 6; 40089edb9e3SSebastian Grimberg break; 4016e15d496SJeremy L Thompson } 40277d1c127SSebastian Grimberg } else { 40389edb9e3SSebastian Grimberg switch (rstr_type) { 40489edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 40589edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 4063ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 40777d1c127SSebastian Grimberg scale = 0; 40889edb9e3SSebastian Grimberg break; 40989edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 41077d1c127SSebastian Grimberg scale = 1; 41189edb9e3SSebastian Grimberg break; 41289edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 41377d1c127SSebastian Grimberg scale = 5; 41489edb9e3SSebastian Grimberg break; 41577d1c127SSebastian Grimberg } 41677d1c127SSebastian Grimberg } 4176e15d496SJeremy L Thompson *flops = e_size * scale; 4186e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 4196e15d496SJeremy L Thompson } 4206e15d496SJeremy L Thompson 4217a982d89SJeremy L. Thompson /// @} 4227a982d89SJeremy L. Thompson 42315910d16Sjeremylt /// @cond DOXYGEN_SKIP 42415910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 42515910d16Sjeremylt /// @endcond 42615910d16Sjeremylt 4277a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4287a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4297a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4307a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 431d7b241e6Sjeremylt /// @{ 432d7b241e6Sjeremylt 4337a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 43445f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4357a982d89SJeremy L. Thompson 436356036faSJeremy L Thompson /// Argument for CeedOperatorSetField indicating that the field does not requre a CeedElemRestriction 4372b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4387a982d89SJeremy L. Thompson 439d7b241e6Sjeremylt /** 440b11c1e72Sjeremylt @brief Create a CeedElemRestriction 441d7b241e6Sjeremylt 442ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 443ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 444ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 445ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 446fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 447fcbe8c06SSebastian 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. 448fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 449fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 450ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 451ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 452fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 453fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 454fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 455ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 456d7b241e6Sjeremylt 457b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 458dfdf5a53Sjeremylt 4597a982d89SJeremy L. Thompson @ref User 460b11c1e72Sjeremylt **/ 4612b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4622b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4635fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4645fe0d4faSjeremylt Ceed delegate; 4656574a04fSJeremy L Thompson 4662b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 46777d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4682b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 469e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4705fe0d4faSjeremylt } 4715fe0d4faSjeremylt 472e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 4736574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4746574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4756574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 476e022e1f8SJeremy L Thompson 4772b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 478db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 479d1d35e2fSjeremylt (*rstr)->ref_count = 1; 480d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 481d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 482d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 483d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 484d1d35e2fSjeremylt (*rstr)->l_size = l_size; 48505fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 486e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 487e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 48861a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 489fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 490e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 491d7b241e6Sjeremylt } 492d7b241e6Sjeremylt 493d7b241e6Sjeremylt /** 49477d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 495fc0567d9Srezgarshakeri 496ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 497ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 498ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 499ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 500fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 501fcbe8c06SSebastian 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. 502fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 503fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 504ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 505ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 506fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 507fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 508fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 50977d1c127SSebastian 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. 510ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 511fc0567d9Srezgarshakeri 512fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 513fc0567d9Srezgarshakeri 514fc0567d9Srezgarshakeri @ref User 515fc0567d9Srezgarshakeri **/ 5162b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 51777d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 518fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 519fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 520fc0567d9Srezgarshakeri Ceed delegate; 5216574a04fSJeremy L Thompson 5222b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 523fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5242b730f8bSJeremy L Thompson CeedCall( 52577d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 526fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 527fc0567d9Srezgarshakeri } 528fc0567d9Srezgarshakeri 529e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 5306574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5316574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5326574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 533e022e1f8SJeremy L Thompson 5342b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 535db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 536fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 537fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 538fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 539fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 540fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 541fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 54205fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 543e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 544e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 545fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 546fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 54777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 54877d1c127SSebastian Grimberg } 54977d1c127SSebastian Grimberg 55077d1c127SSebastian Grimberg /** 55177d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 55277d1c127SSebastian Grimberg 55377d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 55477d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 55577d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 55677d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 557fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 558fcbe8c06SSebastian 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. 559fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 560fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 56177d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 56277d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 563fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 564fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 565fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 5667c1dbaffSSebastian 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] 5677c1dbaffSSebastian 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 5687c1dbaffSSebastian 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, 5697c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 57077d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 57177d1c127SSebastian Grimberg 57277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 57377d1c127SSebastian Grimberg 57477d1c127SSebastian Grimberg @ref User 57577d1c127SSebastian Grimberg **/ 57677d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 5770c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 57877d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 579fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 58077d1c127SSebastian Grimberg Ceed delegate; 58177d1c127SSebastian Grimberg 58277d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 583fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 58477d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 58577d1c127SSebastian Grimberg curl_orients, rstr)); 58677d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 58777d1c127SSebastian Grimberg } 58877d1c127SSebastian Grimberg 589e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 59077d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 59177d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 59277d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 59377d1c127SSebastian Grimberg 59477d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 595fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 59677d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 59777d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 59877d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 59977d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 60077d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 60177d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 60205fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 603e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 604e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 605fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 606fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 607fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 608fc0567d9Srezgarshakeri } 609fc0567d9Srezgarshakeri 610fc0567d9Srezgarshakeri /** 6117509a596Sjeremylt @brief Create a strided CeedElemRestriction 612d7b241e6Sjeremylt 613ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 614ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 615ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 616ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 617fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 618fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 619fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 620fcbe8c06SSebastian 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]. 621fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 622ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 623d7b241e6Sjeremylt 624b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 625dfdf5a53Sjeremylt 6267a982d89SJeremy L. Thompson @ref User 627b11c1e72Sjeremylt **/ 6282b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 629f90c8643Sjeremylt CeedElemRestriction *rstr) { 6305fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6315fe0d4faSjeremylt Ceed delegate; 632b04eb3d9SSebastian Grimberg 6332b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 634fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6352b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 636e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6375fe0d4faSjeremylt } 6385fe0d4faSjeremylt 639e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6406574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6416574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 642e7f679fcSJeremy L Thompson CeedCheck(l_size >= num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector size must be at least num_elem * elem_size * num_comp"); 643e022e1f8SJeremy L Thompson 6442b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 645db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 646d1d35e2fSjeremylt (*rstr)->ref_count = 1; 647d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 648d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 649d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 650d1d35e2fSjeremylt (*rstr)->l_size = l_size; 65105fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 652e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 653e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 654fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6552b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6562b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 657fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 658e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 659d7b241e6Sjeremylt } 660d7b241e6Sjeremylt 661d7b241e6Sjeremylt /** 6623ac8f562SJeremy L Thompson @brief Create a points CeedElemRestriction, for restricting for restricting from a all local points to the current element in which they are 6633ac8f562SJeremy L Thompson located. 6643ac8f562SJeremy L Thompson 6653ac8f562SJeremy L Thompson The offsets array is arranged as 6663ac8f562SJeremy L Thompson 6673ac8f562SJeremy L Thompson element_0_start_index 6683ac8f562SJeremy L Thompson element_1_start_index 6693ac8f562SJeremy L Thompson ... 6703ac8f562SJeremy L Thompson element_n_start_index 6713ac8f562SJeremy L Thompson element_n_stop_index 6723ac8f562SJeremy L Thompson element_0_point_0 6733ac8f562SJeremy L Thompson element_0_point_1 6743ac8f562SJeremy L Thompson ... 6753ac8f562SJeremy L Thompson 6763ac8f562SJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 6773ac8f562SJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 6783ac8f562SJeremy L Thompson @param[in] num_points Number of points described in the @a offsets array 6793ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 6803ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 6813ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 6823ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 6833ac8f562SJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 6843ac8f562SJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 6853ac8f562SJeremy L Thompson @param[in] offsets Array of size num_elem + 1 + num_points. 6863ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 6873ac8f562SJeremy L Thompson The second portion holds the indices for each element. 6883ac8f562SJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 6893ac8f562SJeremy L Thompson 6903ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6913ac8f562SJeremy L Thompson 6923ac8f562SJeremy L Thompson @ref Backend 6933ac8f562SJeremy L Thompson **/ 6943ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 6953ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 6963ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 6973ac8f562SJeremy L Thompson Ceed delegate; 6983ac8f562SJeremy L Thompson 6993ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 7003ac8f562SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateAtPoints"); 7013ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 7023ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 7033ac8f562SJeremy L Thompson } 7043ac8f562SJeremy L Thompson 7053ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7063ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 7073ac8f562SJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 7083ac8f562SJeremy L Thompson CeedCheck(l_size >= num_points * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector must be at least num_points * num_comp"); 7093ac8f562SJeremy L Thompson 7103ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 7113ac8f562SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 7123ac8f562SJeremy L Thompson (*rstr)->ref_count = 1; 7133ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 7143ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 7153ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 7163ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 71705fa913cSJeremy L Thompson (*rstr)->e_size = num_points * num_comp; 71805fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 7193ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 7203ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 7213ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 7223ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 7233ac8f562SJeremy L Thompson } 7243ac8f562SJeremy L Thompson 7253ac8f562SJeremy L Thompson /** 726b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 727d7b241e6Sjeremylt 7283ac8f562SJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 7293ac8f562SJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 730ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 731e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 732ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 733fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 734fcbe8c06SSebastian 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. 735fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 736fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 737ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 738ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 739fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 740e7f679fcSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 741e7f679fcSJeremy L Thompson 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 742e7f679fcSJeremy L Thompson for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 743ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 744d7b241e6Sjeremylt 745b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 746dfdf5a53Sjeremylt 7477a982d89SJeremy L. Thompson @ref Backend 748b11c1e72Sjeremylt **/ 749e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 7502b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 7514ce2993fSjeremylt CeedElemRestriction *rstr) { 7521c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 753d7b241e6Sjeremylt 7545fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 7555fe0d4faSjeremylt Ceed delegate; 7566574a04fSJeremy L Thompson 7572b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 7586402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 759e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 760e7f679fcSJeremy L Thompson rstr)); 761e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7625fe0d4faSjeremylt } 763d7b241e6Sjeremylt 764e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7656574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 766e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 7676574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 7686574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 769e022e1f8SJeremy L Thompson 770e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 771e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 772d7b241e6Sjeremylt 773db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 774db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 775d1d35e2fSjeremylt (*rstr)->ref_count = 1; 776d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 777d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 778d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 779d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 780d1d35e2fSjeremylt (*rstr)->l_size = l_size; 78105fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 782e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 783e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 78461a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 785e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 7861c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 787e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 788d7b241e6Sjeremylt } 789d7b241e6Sjeremylt 790b11c1e72Sjeremylt /** 79177d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 79277d1c127SSebastian Grimberg 79377d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 79477d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 79577d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 796e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 79777d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 798fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 799fcbe8c06SSebastian 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. 800fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 801fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 80277d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 80377d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 804fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 805fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 806fcbe8c06SSebastian 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 807fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 808fcbe8c06SSebastian 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. 809fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 81077d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 81177d1c127SSebastian Grimberg 81277d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 81377d1c127SSebastian Grimberg 81477d1c127SSebastian Grimberg @ref Backend 81577d1c127SSebastian Grimberg **/ 816e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 817e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 818e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 819e7f679fcSJeremy L Thompson bool *block_orients; 8201c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 82177d1c127SSebastian Grimberg 822fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 82377d1c127SSebastian Grimberg Ceed delegate; 82477d1c127SSebastian Grimberg 82577d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 826fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 827e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 82877d1c127SSebastian Grimberg offsets, orients, rstr)); 82977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 83077d1c127SSebastian Grimberg } 83177d1c127SSebastian Grimberg 83277d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 833e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 83477d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 83577d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 83677d1c127SSebastian Grimberg 837e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 838e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 839e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 840e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 84177d1c127SSebastian Grimberg 842fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 843fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 84477d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 84577d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 84677d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 84777d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 84877d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 84977d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 85005fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 851e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 852e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 853fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 854e7f679fcSJeremy L Thompson CeedCall( 855e7f679fcSJeremy L Thompson ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, *rstr)); 8561c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 85777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 85877d1c127SSebastian Grimberg } 85977d1c127SSebastian Grimberg 86077d1c127SSebastian Grimberg /** 86177d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 86277d1c127SSebastian Grimberg 86377d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 86477d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 86577d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 866e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 86777d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 868fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 869fcbe8c06SSebastian 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. 870fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 871fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 87277d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 87377d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 874fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 875fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 876fcbe8c06SSebastian 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 877fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 8787c1dbaffSSebastian 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] 8797c1dbaffSSebastian 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 8807c1dbaffSSebastian 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, 8817c1dbaffSSebastian 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 8827c1dbaffSSebastian Grimberg similarly to @a offsets. 88377d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 88477d1c127SSebastian Grimberg 88577d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 88677d1c127SSebastian Grimberg 88777d1c127SSebastian Grimberg @ref Backend 88877d1c127SSebastian Grimberg **/ 889e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 89077d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 8910c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 892e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 8931c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 89477d1c127SSebastian Grimberg 895fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 89677d1c127SSebastian Grimberg Ceed delegate; 89777d1c127SSebastian Grimberg 89877d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 899fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 900e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 901e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 90277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 90377d1c127SSebastian Grimberg } 90477d1c127SSebastian Grimberg 905e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 90677d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 907e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 90877d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 90977d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 91077d1c127SSebastian Grimberg 911e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 912e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 913e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 914e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 91577d1c127SSebastian Grimberg 916fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 917fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 91877d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 91977d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 92077d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 92177d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 92277d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 92377d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 92405fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 925e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 926e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 927fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 928e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 929e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 9301c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 93177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 93277d1c127SSebastian Grimberg } 93377d1c127SSebastian Grimberg 93477d1c127SSebastian Grimberg /** 93577d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 9367509a596Sjeremylt 937ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 938ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 939ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 940e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 941ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 942fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 943fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 944fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 945fcbe8c06SSebastian 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]. 946fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 947ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 9487509a596Sjeremylt 9497509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 9507509a596Sjeremylt 9517a982d89SJeremy L. Thompson @ref User 9527509a596Sjeremylt **/ 953e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 9548621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 955e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 9567509a596Sjeremylt 9577509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 9587509a596Sjeremylt Ceed delegate; 9596574a04fSJeremy L Thompson 9602b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 961fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 962e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 963e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9647509a596Sjeremylt } 9657509a596Sjeremylt 966e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 9676574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 968e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 9696574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 970e7f679fcSJeremy L Thompson CeedCheck(l_size >= num_elem * elem_size * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector size must be at least num_elem * elem_size * num_comp"); 971e022e1f8SJeremy L Thompson 9722b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 973db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 974d1d35e2fSjeremylt (*rstr)->ref_count = 1; 975d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 976d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 977d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 978d1d35e2fSjeremylt (*rstr)->l_size = l_size; 97905fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 980e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 981e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 982fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 9832b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 9842b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 985fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 986e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9877509a596Sjeremylt } 9887509a596Sjeremylt 9897509a596Sjeremylt /** 9907c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unsigned version. 991c17ec2beSJeremy L Thompson 992c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 993c17ec2beSJeremy L Thompson 994c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 995c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 996c17ec2beSJeremy L Thompson 997c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 998c17ec2beSJeremy L Thompson 999c17ec2beSJeremy L Thompson @ref User 1000c17ec2beSJeremy L Thompson **/ 1001c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1002c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1003c17ec2beSJeremy L Thompson 1004c17ec2beSJeremy L Thompson // Copy old rstr 1005c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1006c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 1007c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 1008c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 1009c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1010c17ec2beSJeremy L Thompson if (rstr->strides) { 1011c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1012c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1013c17ec2beSJeremy L Thompson } 10147c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1015c17ec2beSJeremy L Thompson 1016c17ec2beSJeremy L Thompson // Override Apply 1017c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1018c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1019c17ec2beSJeremy L Thompson } 1020c17ec2beSJeremy L Thompson 1021c17ec2beSJeremy L Thompson /** 10227c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unoriented version. 10237c1dbaffSSebastian Grimberg 10247c1dbaffSSebastian Grimberg Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 10257c1dbaffSSebastian Grimberg 10267c1dbaffSSebastian Grimberg @param[in] rstr CeedElemRestriction to create unoriented reference to 10277c1dbaffSSebastian Grimberg @param[in,out] rstr_unoriented Variable to store unoriented CeedElemRestriction 10287c1dbaffSSebastian Grimberg 10297c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 10307c1dbaffSSebastian Grimberg 10317c1dbaffSSebastian Grimberg @ref User 10327c1dbaffSSebastian Grimberg **/ 10337c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 10347c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 10357c1dbaffSSebastian Grimberg 10367c1dbaffSSebastian Grimberg // Copy old rstr 10377c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 10387c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 10397c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 10407c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 10417c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 10427c1dbaffSSebastian Grimberg if (rstr->strides) { 10437c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 10447c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 10457c1dbaffSSebastian Grimberg } 10467c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 10477c1dbaffSSebastian Grimberg 10487c1dbaffSSebastian Grimberg // Override Apply 10497c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 10507c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 10517c1dbaffSSebastian Grimberg } 10527c1dbaffSSebastian Grimberg 10537c1dbaffSSebastian Grimberg /** 1054ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 10559fd66db6SSebastian Grimberg 1056ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 10579560d06aSjeremylt 10589fd66db6SSebastian 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. 10599fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 1060ea61e9acSJeremy L Thompson 1061ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 1062ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 10639560d06aSjeremylt 10649560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 10659560d06aSjeremylt 10669560d06aSjeremylt @ref User 10679560d06aSjeremylt **/ 10682b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1069393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 10702b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 10719560d06aSjeremylt *rstr_copy = rstr; 10729560d06aSjeremylt return CEED_ERROR_SUCCESS; 10739560d06aSjeremylt } 10749560d06aSjeremylt 10759560d06aSjeremylt /** 1076b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 1077b11c1e72Sjeremylt 1078ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1079ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 1080ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 1081b11c1e72Sjeremylt 1082b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1083dfdf5a53Sjeremylt 10847a982d89SJeremy L. Thompson @ref User 1085b11c1e72Sjeremylt **/ 10862b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1087d2643443SJeremy L Thompson CeedSize e_size, l_size; 1088d1d35e2fSjeremylt l_size = rstr->l_size; 1089e7f679fcSJeremy L Thompson e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp; 10902b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 10912b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 1092e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1093d7b241e6Sjeremylt } 1094d7b241e6Sjeremylt 1095d7b241e6Sjeremylt /** 1096d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1097d7b241e6Sjeremylt 1098ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1099ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1100ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1101fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1102fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1103ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1104b11c1e72Sjeremylt 1105b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1106dfdf5a53Sjeremylt 11077a982d89SJeremy L. Thompson @ref User 1108b11c1e72Sjeremylt **/ 11092b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1110d7b241e6Sjeremylt CeedInt m, n; 1111d7b241e6Sjeremylt 1112d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 111305fa913cSJeremy L Thompson m = rstr->e_size; 1114d1d35e2fSjeremylt n = rstr->l_size; 1115d7b241e6Sjeremylt } else { 1116d1d35e2fSjeremylt m = rstr->l_size; 111705fa913cSJeremy L Thompson n = rstr->e_size; 1118d7b241e6Sjeremylt } 111905fa913cSJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11206574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 112105fa913cSJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11226574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 11232b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1124e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1125d7b241e6Sjeremylt } 1126d7b241e6Sjeremylt 1127d7b241e6Sjeremylt /** 11283ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 11293ac8f562SJeremy L Thompson 11303ac8f562SJeremy L Thompson @param[in] rstr CeedElemRestriction 11316cec60aaSJed Brown @param[in] elem Element number in range 0..@a num_elem 11323ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 11333ac8f562SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1134*6595d053SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_points * @a num_comp] when t_mode=@ref CEED_NOTRANSPOSE). 11353ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 11363ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 11373ac8f562SJeremy L Thompson 11383ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11393ac8f562SJeremy L Thompson 11403ac8f562SJeremy L Thompson @ref User 11413ac8f562SJeremy L Thompson **/ 114205fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 11433ac8f562SJeremy L Thompson CeedRequest *request) { 11443ac8f562SJeremy L Thompson CeedInt m, n; 11453ac8f562SJeremy L Thompson 11463ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 11473ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &m)); 11483ac8f562SJeremy L Thompson n = rstr->l_size; 11493ac8f562SJeremy L Thompson } else { 11503ac8f562SJeremy L Thompson m = rstr->l_size; 11513ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &n)); 11523ac8f562SJeremy L Thompson } 11533ac8f562SJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11543ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 11553ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 11563ac8f562SJeremy L Thompson u->length, m, n, elem); 11573ac8f562SJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11583ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 11593ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 11603ac8f562SJeremy L Thompson ru->length, m, n, elem); 11610930e4e7SJeremy L Thompson CeedCheck(elem < rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 11623ac8f562SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, rstr->num_elem); 116305fa913cSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 11643ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 11653ac8f562SJeremy L Thompson } 11663ac8f562SJeremy L Thompson 11673ac8f562SJeremy L Thompson /** 1168d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1169be9261b7Sjeremylt 1170ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1171e7f679fcSJeremy L Thompson @param[in] block Block number to restrict to/from, i.e. block=0 will handle elements [0 : block_size] and block=3 will handle elements 1172e7f679fcSJeremy L Thompson [3*block_size : 4*block_size] 1173ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1174ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1175e7f679fcSJeremy L Thompson @param[out] ru Output vector (of shape [@a block_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1176fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1177ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1178be9261b7Sjeremylt 1179be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1180be9261b7Sjeremylt 11817a982d89SJeremy L. Thompson @ref Backend 1182be9261b7Sjeremylt **/ 11832b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 11842b730f8bSJeremy L Thompson CeedRequest *request) { 1185be9261b7Sjeremylt CeedInt m, n; 1186be9261b7Sjeremylt 11876402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 11886402da51SJeremy L Thompson 1189d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1190e7f679fcSJeremy L Thompson m = rstr->block_size * rstr->elem_size * rstr->num_comp; 1191d1d35e2fSjeremylt n = rstr->l_size; 1192be9261b7Sjeremylt } else { 1193d1d35e2fSjeremylt m = rstr->l_size; 1194e7f679fcSJeremy L Thompson n = rstr->block_size * rstr->elem_size * rstr->num_comp; 1195be9261b7Sjeremylt } 11966574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11976574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 11986574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11996574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 1200e7f679fcSJeremy L Thompson CeedCheck(rstr->block_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 1201e7f679fcSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->block_size * block, 12026574a04fSJeremy L Thompson rstr->num_elem); 12032b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1204e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1205be9261b7Sjeremylt } 1206be9261b7Sjeremylt 1207be9261b7Sjeremylt /** 1208b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1209b7c9bbdaSJeremy L Thompson 1210ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1211b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1212b7c9bbdaSJeremy L Thompson 1213b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1214b7c9bbdaSJeremy L Thompson 1215b7c9bbdaSJeremy L Thompson @ref Advanced 1216b7c9bbdaSJeremy L Thompson **/ 1217b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1218b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1219b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1220b7c9bbdaSJeremy L Thompson } 1221b7c9bbdaSJeremy L Thompson 1222b7c9bbdaSJeremy L Thompson /** 1223d979a051Sjeremylt @brief Get the L-vector component stride 1224a681ae63Sjeremylt 1225ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1226d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1227a681ae63Sjeremylt 1228a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1229a681ae63Sjeremylt 1230b7c9bbdaSJeremy L Thompson @ref Advanced 1231a681ae63Sjeremylt **/ 12322b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1233d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1234e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1235a681ae63Sjeremylt } 1236a681ae63Sjeremylt 1237a681ae63Sjeremylt /** 1238a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1239a681ae63Sjeremylt 1240ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1241d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1242a681ae63Sjeremylt 1243a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1244a681ae63Sjeremylt 1245b7c9bbdaSJeremy L Thompson @ref Advanced 1246a681ae63Sjeremylt **/ 12472b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1248d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1249e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1250a681ae63Sjeremylt } 1251a681ae63Sjeremylt 1252a681ae63Sjeremylt /** 1253a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1254a681ae63Sjeremylt 1255ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1256d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1257a681ae63Sjeremylt 1258a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1259a681ae63Sjeremylt 1260b7c9bbdaSJeremy L Thompson @ref Advanced 1261a681ae63Sjeremylt **/ 12622b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1263d1d35e2fSjeremylt *elem_size = rstr->elem_size; 12642c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 12652c7e7413SJeremy L Thompson } 12662c7e7413SJeremy L Thompson 12672c7e7413SJeremy L Thompson /** 126807d5dec1SJeremy L Thompson 126907d5dec1SJeremy L Thompson @brief Get the number of points in the l-vector for a points CeedElemRestriction 127007d5dec1SJeremy L Thompson 127107d5dec1SJeremy L Thompson @param[in] rstr CeedElemRestriction 127207d5dec1SJeremy L Thompson @param[out] num_points The number of points in the l-vector 127307d5dec1SJeremy L Thompson 127407d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 127507d5dec1SJeremy L Thompson 1276c63574e3SJeremy L Thompson @ref User 127707d5dec1SJeremy L Thompson **/ 127807d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) { 127907d5dec1SJeremy L Thompson Ceed ceed; 128007d5dec1SJeremy L Thompson 128107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 128207d5dec1SJeremy L Thompson CeedCheck(rstr->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 128307d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 128407d5dec1SJeremy L Thompson 128507d5dec1SJeremy L Thompson *num_points = rstr->num_points; 128607d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 128707d5dec1SJeremy L Thompson } 128807d5dec1SJeremy L Thompson 128907d5dec1SJeremy L Thompson /** 129007d5dec1SJeremy L Thompson 129107d5dec1SJeremy L Thompson @brief Get the number of points in an element of a points CeedElemRestriction 129207d5dec1SJeremy L Thompson 129307d5dec1SJeremy L Thompson @param[in] rstr CeedElemRestriction 129407d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 129507d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 129607d5dec1SJeremy L Thompson 129707d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 129807d5dec1SJeremy L Thompson 1299c63574e3SJeremy L Thompson @ref User 130007d5dec1SJeremy L Thompson **/ 130107d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 130207d5dec1SJeremy L Thompson Ceed ceed; 130307d5dec1SJeremy L Thompson const CeedInt *offsets; 130407d5dec1SJeremy L Thompson 130507d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 130607d5dec1SJeremy L Thompson CeedCheck(rstr->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 130707d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 130807d5dec1SJeremy L Thompson 130907d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 131007d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem]; 131107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 131207d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS; 131307d5dec1SJeremy L Thompson } 131407d5dec1SJeremy L Thompson 131507d5dec1SJeremy L Thompson /** 13162c7e7413SJeremy L Thompson @brief Get the maximum number of points in an element for a CeedElemRestriction at points 13172c7e7413SJeremy L Thompson 13182c7e7413SJeremy L Thompson @param[in] rstr CeedElemRestriction 13192c7e7413SJeremy L Thompson @param[out] max_points Variable to store size of elements 13202c7e7413SJeremy L Thompson 13212c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13222c7e7413SJeremy L Thompson 13232c7e7413SJeremy L Thompson @ref Advanced 13242c7e7413SJeremy L Thompson **/ 13252c7e7413SJeremy L Thompson int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 13262c7e7413SJeremy L Thompson Ceed ceed; 13272c7e7413SJeremy L Thompson CeedInt num_elem; 13282c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 13292c7e7413SJeremy L Thompson 13302c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 13312c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 13322c7e7413SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 13332c7e7413SJeremy L Thompson "Cannot compute max points for a CeedElemRestriction that does not use points"); 13342c7e7413SJeremy L Thompson 13352c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 13362c7e7413SJeremy L Thompson *max_points = 0; 13372c7e7413SJeremy L Thompson for (CeedInt e = 0; e < num_elem; e++) { 13382c7e7413SJeremy L Thompson CeedInt num_points; 13392c7e7413SJeremy L Thompson 13402c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 13412c7e7413SJeremy L Thompson *max_points = CeedIntMax(num_points, *max_points); 13422c7e7413SJeremy L Thompson } 1343e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1344a681ae63Sjeremylt } 1345a681ae63Sjeremylt 1346a681ae63Sjeremylt /** 1347d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1348a681ae63Sjeremylt 1349ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1350d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1351a681ae63Sjeremylt 1352a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1353a681ae63Sjeremylt 1354b7c9bbdaSJeremy L Thompson @ref Advanced 1355a681ae63Sjeremylt **/ 13562b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1357d1d35e2fSjeremylt *l_size = rstr->l_size; 1358e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1359a681ae63Sjeremylt } 1360a681ae63Sjeremylt 1361a681ae63Sjeremylt /** 1362ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1363a681ae63Sjeremylt 1364ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1365d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1366a681ae63Sjeremylt 1367a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1368a681ae63Sjeremylt 1369b7c9bbdaSJeremy L Thompson @ref Advanced 1370a681ae63Sjeremylt **/ 13712b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1372d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1373e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1374a681ae63Sjeremylt } 1375a681ae63Sjeremylt 1376a681ae63Sjeremylt /** 1377a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1378a681ae63Sjeremylt 1379ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1380d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1381a681ae63Sjeremylt 1382a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1383a681ae63Sjeremylt 1384b7c9bbdaSJeremy L Thompson @ref Advanced 1385a681ae63Sjeremylt **/ 13862b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1387e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1388e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1389a681ae63Sjeremylt } 1390a681ae63Sjeremylt 1391a681ae63Sjeremylt /** 1392a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1393a681ae63Sjeremylt 1394ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1395e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1396a681ae63Sjeremylt 1397a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1398a681ae63Sjeremylt 1399b7c9bbdaSJeremy L Thompson @ref Advanced 1400a681ae63Sjeremylt **/ 1401e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1402e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1403e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1404a681ae63Sjeremylt } 1405a681ae63Sjeremylt 1406a681ae63Sjeremylt /** 1407d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 14081469ee4dSjeremylt 1409ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1410d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 14111469ee4dSjeremylt 14121469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 14131469ee4dSjeremylt 14147a982d89SJeremy L. Thompson @ref User 14151469ee4dSjeremylt **/ 14162b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1417d1d35e2fSjeremylt CeedVector e_vec; 14181469ee4dSjeremylt 141925509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 14202b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 14211469ee4dSjeremylt 142225509ebbSRezgar Shakeri // Compute e_vec = E * 1 14232b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 14242b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 142525509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 14262b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 14272b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 14281469ee4dSjeremylt // Cleanup 14292b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1430e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 14311469ee4dSjeremylt } 14321469ee4dSjeremylt 14331469ee4dSjeremylt /** 1434f02ca4a2SJed Brown @brief View a CeedElemRestriction 1435f02ca4a2SJed Brown 1436f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1437f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1438f02ca4a2SJed Brown 1439f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1440f02ca4a2SJed Brown 14417a982d89SJeremy L. Thompson @ref User 1442f02ca4a2SJed Brown **/ 1443f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 14440930e4e7SJeremy L Thompson CeedRestrictionType rstr_type; 14450930e4e7SJeremy L Thompson 14460930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 14470930e4e7SJeremy L Thompson 14480930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 14490930e4e7SJeremy L Thompson CeedInt max_points; 14500930e4e7SJeremy L Thompson 14510930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points)); 14520930e4e7SJeremy L Thompson fprintf(stream, 14530930e4e7SJeremy L Thompson "CeedElemRestriction at points from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT 14540930e4e7SJeremy L Thompson " points on an element\n", 14550930e4e7SJeremy L Thompson rstr->l_size, rstr->num_comp, rstr->num_elem, max_points); 14560930e4e7SJeremy L Thompson } else { 14577509a596Sjeremylt char stridesstr[500]; 14581c66c397SJeremy L Thompson 14592b730f8bSJeremy L Thompson if (rstr->strides) { 14602b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 14612b730f8bSJeremy L Thompson } else { 1462990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 14632b730f8bSJeremy L Thompson } 14642b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 1465e7f679fcSJeremy L Thompson rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1466d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 14670930e4e7SJeremy L Thompson } 1468e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1469f02ca4a2SJed Brown } 1470f02ca4a2SJed Brown 1471f02ca4a2SJed Brown /** 1472b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1473b11c1e72Sjeremylt 1474ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1475b11c1e72Sjeremylt 1476b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1477dfdf5a53Sjeremylt 14787a982d89SJeremy L. Thompson @ref User 1479b11c1e72Sjeremylt **/ 14804ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1481393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1482ad6481ceSJeremy L Thompson *rstr = NULL; 1483ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1484ad6481ceSJeremy L Thompson } 14856574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 14866574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1487c17ec2beSJeremy L Thompson 1488c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 14897c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1490c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1491c17ec2beSJeremy L Thompson 14922b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 14932b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 14942b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1495e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1496d7b241e6Sjeremylt } 1497d7b241e6Sjeremylt 1498d7b241e6Sjeremylt /// @} 1499