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 2943ac8f562SJeremy L Thompson @brief Get the number of points in an element of a points CeedElemRestriction 2953ac8f562SJeremy L Thompson 2963ac8f562SJeremy L Thompson @param[in] rstr CeedElemRestriction 2973ac8f562SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for 2983ac8f562SJeremy L Thompson @param[out] num_points The number of points in the element at index elem 2993ac8f562SJeremy L Thompson 3003ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3013ac8f562SJeremy L Thompson 3023ac8f562SJeremy L Thompson @ref Backend 3033ac8f562SJeremy L Thompson **/ 3043ac8f562SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) { 3053ac8f562SJeremy L Thompson Ceed ceed; 3063ac8f562SJeremy L Thompson const CeedInt *offsets; 3073ac8f562SJeremy L Thompson 3083ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 3093ac8f562SJeremy L Thompson CeedCheck(rstr->rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 3103ac8f562SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction"); 3113ac8f562SJeremy L Thompson 3123ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets)); 3133ac8f562SJeremy L Thompson *num_points = offsets[elem - 1] - offsets[elem]; 3143ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets)); 3153ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 3163ac8f562SJeremy L Thompson } 3173ac8f562SJeremy L Thompson 3183ac8f562SJeremy L Thompson /** 3193ac8f562SJeremy L Thompson 32049fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 32149fd234cSJeremy L Thompson 322ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 323fcbe8c06SSebastian Grimberg @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 324fcbe8c06SSebastian 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] 32549fd234cSJeremy L Thompson 32649fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 32749fd234cSJeremy L Thompson 32849fd234cSJeremy L Thompson @ref Backend 32949fd234cSJeremy L Thompson **/ 3302b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 3316574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 3322b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 333e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 33449fd234cSJeremy L Thompson } 33549fd234cSJeremy L Thompson 33649fd234cSJeremy L Thompson /** 33749fd234cSJeremy L Thompson 33849fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 33949fd234cSJeremy L Thompson 340ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 341ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 342ea61e9acSJeremy 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] 34349fd234cSJeremy L Thompson 34449fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 34549fd234cSJeremy L Thompson 34649fd234cSJeremy L Thompson @ref Backend 34749fd234cSJeremy L Thompson **/ 3482b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 3492b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 350e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 35149fd234cSJeremy L Thompson } 35249fd234cSJeremy L Thompson 35349fd234cSJeremy L Thompson /** 3547a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 3557a982d89SJeremy L. Thompson 356ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 3577a982d89SJeremy L. Thompson @param[out] data Variable to store data 3587a982d89SJeremy L. Thompson 3597a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3607a982d89SJeremy L. Thompson 3617a982d89SJeremy L. Thompson @ref Backend 3627a982d89SJeremy L. Thompson **/ 363777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 364777ff853SJeremy L Thompson *(void **)data = rstr->data; 365e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3667a982d89SJeremy L. Thompson } 3677a982d89SJeremy L. Thompson 3687a982d89SJeremy L. Thompson /** 3697a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 3707a982d89SJeremy L. Thompson 371ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 372ea61e9acSJeremy L Thompson @param[in] data Data to set 3737a982d89SJeremy L. Thompson 3747a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3757a982d89SJeremy L. Thompson 3767a982d89SJeremy L. Thompson @ref Backend 3777a982d89SJeremy L. Thompson **/ 378777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 379777ff853SJeremy L Thompson rstr->data = data; 380e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3817a982d89SJeremy L. Thompson } 3827a982d89SJeremy L. Thompson 38334359f16Sjeremylt /** 38434359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 38534359f16Sjeremylt 386ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 38734359f16Sjeremylt 38834359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 38934359f16Sjeremylt 39034359f16Sjeremylt @ref Backend 39134359f16Sjeremylt **/ 3929560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 39334359f16Sjeremylt rstr->ref_count++; 39434359f16Sjeremylt return CEED_ERROR_SUCCESS; 39534359f16Sjeremylt } 39634359f16Sjeremylt 3976e15d496SJeremy L Thompson /** 3986e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 3996e15d496SJeremy L Thompson 400ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 401ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 402ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 4036e15d496SJeremy L Thompson 4046e15d496SJeremy L Thompson @ref Backend 4056e15d496SJeremy L Thompson **/ 4062b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 407e7f679fcSJeremy L Thompson CeedInt e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp, scale = 0; 40889edb9e3SSebastian Grimberg CeedRestrictionType rstr_type; 4091c66c397SJeremy L Thompson 41089edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 4113ac8f562SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) e_size = rstr->num_points * rstr->num_comp; 41277d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 41389edb9e3SSebastian Grimberg switch (rstr_type) { 4143ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 4153ac8f562SJeremy L Thompson scale = 0; 4163ac8f562SJeremy L Thompson break; 41789edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 41889edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 41977d1c127SSebastian Grimberg scale = 1; 42089edb9e3SSebastian Grimberg break; 42189edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 42277d1c127SSebastian Grimberg scale = 2; 42389edb9e3SSebastian Grimberg break; 42489edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 42577d1c127SSebastian Grimberg scale = 6; 42689edb9e3SSebastian Grimberg break; 4276e15d496SJeremy L Thompson } 42877d1c127SSebastian Grimberg } else { 42989edb9e3SSebastian Grimberg switch (rstr_type) { 43089edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED: 43189edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD: 4323ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS: 43377d1c127SSebastian Grimberg scale = 0; 43489edb9e3SSebastian Grimberg break; 43589edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: 43677d1c127SSebastian Grimberg scale = 1; 43789edb9e3SSebastian Grimberg break; 43889edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: 43977d1c127SSebastian Grimberg scale = 5; 44089edb9e3SSebastian Grimberg break; 44177d1c127SSebastian Grimberg } 44277d1c127SSebastian Grimberg } 4436e15d496SJeremy L Thompson *flops = e_size * scale; 4446e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 4456e15d496SJeremy L Thompson } 4466e15d496SJeremy L Thompson 4477a982d89SJeremy L. Thompson /// @} 4487a982d89SJeremy L. Thompson 44915910d16Sjeremylt /// @cond DOXYGEN_SKIP 45015910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 45115910d16Sjeremylt /// @endcond 45215910d16Sjeremylt 4537a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4547a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 4557a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 4567a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 457d7b241e6Sjeremylt /// @{ 458d7b241e6Sjeremylt 4597a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 46045f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 4617a982d89SJeremy L. Thompson 462356036faSJeremy L Thompson /// Argument for CeedOperatorSetField indicating that the field does not requre a CeedElemRestriction 4632b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 4647a982d89SJeremy L. Thompson 465d7b241e6Sjeremylt /** 466b11c1e72Sjeremylt @brief Create a CeedElemRestriction 467d7b241e6Sjeremylt 468ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 469ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 470ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 471ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 472fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 473fcbe8c06SSebastian 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. 474fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 475fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 476ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 477ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 478fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 479fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 480fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 481ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 482d7b241e6Sjeremylt 483b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 484dfdf5a53Sjeremylt 4857a982d89SJeremy L. Thompson @ref User 486b11c1e72Sjeremylt **/ 4872b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 4882b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 4895fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4905fe0d4faSjeremylt Ceed delegate; 4916574a04fSJeremy L Thompson 4922b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 49377d1c127SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 4942b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 495e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4965fe0d4faSjeremylt } 4975fe0d4faSjeremylt 498e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 4996574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5006574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5016574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 502e022e1f8SJeremy L Thompson 5032b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 504db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 505d1d35e2fSjeremylt (*rstr)->ref_count = 1; 506d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 507d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 508d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 509d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 510d1d35e2fSjeremylt (*rstr)->l_size = l_size; 511*05fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 512e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 513e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 51461a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 515fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 516e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 517d7b241e6Sjeremylt } 518d7b241e6Sjeremylt 519d7b241e6Sjeremylt /** 52077d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with orientation signs 521fc0567d9Srezgarshakeri 522ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 523ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 524ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 525ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 526fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 527fcbe8c06SSebastian 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. 528fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 529fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 530ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 531ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 532fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 533fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 534fcbe8c06SSebastian Grimberg 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 53577d1c127SSebastian 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. 536ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 537fc0567d9Srezgarshakeri 538fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 539fc0567d9Srezgarshakeri 540fc0567d9Srezgarshakeri @ref User 541fc0567d9Srezgarshakeri **/ 5422b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 54377d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 544fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 545fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 546fc0567d9Srezgarshakeri Ceed delegate; 5476574a04fSJeremy L Thompson 5482b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 549fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 5502b730f8bSJeremy L Thompson CeedCall( 55177d1c127SSebastian Grimberg CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients, rstr)); 552fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 553fc0567d9Srezgarshakeri } 554fc0567d9Srezgarshakeri 555e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 5566574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5576574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 5586574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 559e022e1f8SJeremy L Thompson 5602b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 561db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 562fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 563fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 564fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 565fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 566fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 567fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 568*05fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 569e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 570e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 571fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 572fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr)); 57377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 57477d1c127SSebastian Grimberg } 57577d1c127SSebastian Grimberg 57677d1c127SSebastian Grimberg /** 57777d1c127SSebastian Grimberg @brief Create a CeedElemRestriction with a general tridiagonal transformation matrix for curl-conforming elements 57877d1c127SSebastian Grimberg 57977d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created 58077d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array 58177d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element 58277d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 583fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 584fcbe8c06SSebastian 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. 585fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 586fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 58777d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 58877d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 589fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 590fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 591fcbe8c06SSebastian Grimberg where 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 5927c1dbaffSSebastian 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] 5937c1dbaffSSebastian 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 5947c1dbaffSSebastian 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, 5957c1dbaffSSebastian Grimberg which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456). 59677d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 59777d1c127SSebastian Grimberg 59877d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 59977d1c127SSebastian Grimberg 60077d1c127SSebastian Grimberg @ref User 60177d1c127SSebastian Grimberg **/ 60277d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 6030c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients, 60477d1c127SSebastian Grimberg CeedElemRestriction *rstr) { 605fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) { 60677d1c127SSebastian Grimberg Ceed delegate; 60777d1c127SSebastian Grimberg 60877d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 609fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 61077d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 61177d1c127SSebastian Grimberg curl_orients, rstr)); 61277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 61377d1c127SSebastian Grimberg } 61477d1c127SSebastian Grimberg 615e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 61677d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 61777d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 61877d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 61977d1c127SSebastian Grimberg 62077d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 621fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 62277d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 62377d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 62477d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 62577d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 62677d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 62777d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 628*05fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 629e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 630e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 631fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 632fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr)); 633fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 634fc0567d9Srezgarshakeri } 635fc0567d9Srezgarshakeri 636fc0567d9Srezgarshakeri /** 6377509a596Sjeremylt @brief Create a strided CeedElemRestriction 638d7b241e6Sjeremylt 639ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 640ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 641ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 642ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 643fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 644fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 645fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 646fcbe8c06SSebastian 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]. 647fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 648ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 649d7b241e6Sjeremylt 650b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 651dfdf5a53Sjeremylt 6527a982d89SJeremy L. Thompson @ref User 653b11c1e72Sjeremylt **/ 6542b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 655f90c8643Sjeremylt CeedElemRestriction *rstr) { 6565fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 6575fe0d4faSjeremylt Ceed delegate; 658b04eb3d9SSebastian Grimberg 6592b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 660fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreate"); 6612b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 662e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6635fe0d4faSjeremylt } 6645fe0d4faSjeremylt 665e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 6666574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 6676574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 668e7f679fcSJeremy 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"); 669e022e1f8SJeremy L Thompson 6702b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 671db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 672d1d35e2fSjeremylt (*rstr)->ref_count = 1; 673d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 674d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 675d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 676d1d35e2fSjeremylt (*rstr)->l_size = l_size; 677*05fa913cSJeremy L Thompson (*rstr)->e_size = num_elem * elem_size * num_comp; 678e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem; 679e7f679fcSJeremy L Thompson (*rstr)->block_size = 1; 680fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 6812b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 6822b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 683fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 684e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 685d7b241e6Sjeremylt } 686d7b241e6Sjeremylt 687d7b241e6Sjeremylt /** 6883ac8f562SJeremy L Thompson @brief Create a points CeedElemRestriction, for restricting for restricting from a all local points to the current element in which they are 6893ac8f562SJeremy L Thompson located. 6903ac8f562SJeremy L Thompson 6913ac8f562SJeremy L Thompson The offsets array is arranged as 6923ac8f562SJeremy L Thompson 6933ac8f562SJeremy L Thompson element_0_start_index 6943ac8f562SJeremy L Thompson element_1_start_index 6953ac8f562SJeremy L Thompson ... 6963ac8f562SJeremy L Thompson element_n_start_index 6973ac8f562SJeremy L Thompson element_n_stop_index 6983ac8f562SJeremy L Thompson element_0_point_0 6993ac8f562SJeremy L Thompson element_0_point_1 7003ac8f562SJeremy L Thompson ... 7013ac8f562SJeremy L Thompson 7023ac8f562SJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 7033ac8f562SJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 7043ac8f562SJeremy L Thompson @param[in] num_points Number of points described in the @a offsets array 7053ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields). 7063ac8f562SJeremy L Thompson Components are assumed to be contiguous by point. 7073ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector. 7083ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 7093ac8f562SJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 7103ac8f562SJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 7113ac8f562SJeremy L Thompson @param[in] offsets Array of size num_elem + 1 + num_points. 7123ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element. 7133ac8f562SJeremy L Thompson The second portion holds the indices for each element. 7143ac8f562SJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 7153ac8f562SJeremy L Thompson 7163ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7173ac8f562SJeremy L Thompson 7183ac8f562SJeremy L Thompson @ref Backend 7193ac8f562SJeremy L Thompson **/ 7203ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type, 7213ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 7223ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) { 7233ac8f562SJeremy L Thompson Ceed delegate; 7243ac8f562SJeremy L Thompson 7253ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 7263ac8f562SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateAtPoints"); 7273ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr)); 7283ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 7293ac8f562SJeremy L Thompson } 7303ac8f562SJeremy L Thompson 7313ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7323ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative"); 7333ac8f562SJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 7343ac8f562SJeremy L Thompson CeedCheck(l_size >= num_points * num_comp, ceed, CEED_ERROR_DIMENSION, "L-vector must be at least num_points * num_comp"); 7353ac8f562SJeremy L Thompson 7363ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 7373ac8f562SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 7383ac8f562SJeremy L Thompson (*rstr)->ref_count = 1; 7393ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem; 7403ac8f562SJeremy L Thompson (*rstr)->num_points = num_points; 7413ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp; 7423ac8f562SJeremy L Thompson (*rstr)->l_size = l_size; 743*05fa913cSJeremy L Thompson (*rstr)->e_size = num_points * num_comp; 744*05fa913cSJeremy L Thompson (*rstr)->num_block = num_elem; 7453ac8f562SJeremy L Thompson (*rstr)->block_size = 1; 7463ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS; 7473ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr)); 7483ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 7493ac8f562SJeremy L Thompson } 7503ac8f562SJeremy L Thompson 7513ac8f562SJeremy L Thompson /** 752b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 753d7b241e6Sjeremylt 7543ac8f562SJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 7553ac8f562SJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 756ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 757e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 758ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 759fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 760fcbe8c06SSebastian 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. 761fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 762fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 763ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 764ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 765fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 766e7f679fcSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 767e7f679fcSJeremy 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 768e7f679fcSJeremy L Thompson for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 769ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 770d7b241e6Sjeremylt 771b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 772dfdf5a53Sjeremylt 7737a982d89SJeremy L. Thompson @ref Backend 774b11c1e72Sjeremylt **/ 775e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride, 7762b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 7774ce2993fSjeremylt CeedElemRestriction *rstr) { 7781c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 779d7b241e6Sjeremylt 7805fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 7815fe0d4faSjeremylt Ceed delegate; 7826574a04fSJeremy L Thompson 7832b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 7846402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 785e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 786e7f679fcSJeremy L Thompson rstr)); 787e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7885fe0d4faSjeremylt } 789d7b241e6Sjeremylt 790e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 7916574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 792e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 7936574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 7946574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 795e022e1f8SJeremy L Thompson 796e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 797e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 798d7b241e6Sjeremylt 799db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 800db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 801d1d35e2fSjeremylt (*rstr)->ref_count = 1; 802d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 803d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 804d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 805d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 806d1d35e2fSjeremylt (*rstr)->l_size = l_size; 807*05fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 808e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 809e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 81061a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD; 811e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr)); 8121c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 813e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 814d7b241e6Sjeremylt } 815d7b241e6Sjeremylt 816b11c1e72Sjeremylt /** 81777d1c127SSebastian Grimberg @brief Create a blocked oriented CeedElemRestriction, typically only called by backends 81877d1c127SSebastian Grimberg 81977d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 82077d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 82177d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 822e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 82377d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 824fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 825fcbe8c06SSebastian 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. 826fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 827fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 82877d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 82977d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 830fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 831fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 832fcbe8c06SSebastian 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 833fcbe8c06SSebastian Grimberg the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 834fcbe8c06SSebastian 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. 835fcbe8c06SSebastian Grimberg Will also be permuted and padded similarly to @a offsets. 83677d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 83777d1c127SSebastian Grimberg 83877d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 83977d1c127SSebastian Grimberg 84077d1c127SSebastian Grimberg @ref Backend 84177d1c127SSebastian Grimberg **/ 842e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 843e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 844e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) { 845e7f679fcSJeremy L Thompson bool *block_orients; 8461c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 84777d1c127SSebastian Grimberg 848fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 84977d1c127SSebastian Grimberg Ceed delegate; 85077d1c127SSebastian Grimberg 85177d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 852fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 853e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, 85477d1c127SSebastian Grimberg offsets, orients, rstr)); 85577d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 85677d1c127SSebastian Grimberg } 85777d1c127SSebastian Grimberg 85877d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 859e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 86077d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 86177d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 86277d1c127SSebastian Grimberg 863e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 864e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients)); 865e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 866e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size)); 86777d1c127SSebastian Grimberg 868fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 869fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 87077d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 87177d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 87277d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 87377d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 87477d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 87577d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 876*05fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 877e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 878e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 879fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED; 880e7f679fcSJeremy L Thompson CeedCall( 881e7f679fcSJeremy L Thompson ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL, *rstr)); 8821c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 88377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 88477d1c127SSebastian Grimberg } 88577d1c127SSebastian Grimberg 88677d1c127SSebastian Grimberg /** 88777d1c127SSebastian Grimberg @brief Create a blocked curl-oriented CeedElemRestriction, typically only called by backends 88877d1c127SSebastian Grimberg 88977d1c127SSebastian Grimberg @param[in] ceed Ceed object where the CeedElemRestriction will be created. 89077d1c127SSebastian Grimberg @param[in] num_elem Number of elements described in the @a offsets array. 89177d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element 892e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 89377d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 894fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node". 895fcbe8c06SSebastian 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. 896fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 897fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 89877d1c127SSebastian Grimberg @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 89977d1c127SSebastian Grimberg @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 900fcbe8c06SSebastian Grimberg @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 901fcbe8c06SSebastian Grimberg Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, 902fcbe8c06SSebastian 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 903fcbe8c06SSebastian Grimberg for the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 9047c1dbaffSSebastian 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] 9057c1dbaffSSebastian 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 9067c1dbaffSSebastian 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, 9077c1dbaffSSebastian 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 9087c1dbaffSSebastian Grimberg similarly to @a offsets. 90977d1c127SSebastian Grimberg @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 91077d1c127SSebastian Grimberg 91177d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 91277d1c127SSebastian Grimberg 91377d1c127SSebastian Grimberg @ref Backend 91477d1c127SSebastian Grimberg **/ 915e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, 91677d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, 9170c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) { 918e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients; 9191c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size); 92077d1c127SSebastian Grimberg 921fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) { 92277d1c127SSebastian Grimberg Ceed delegate; 92377d1c127SSebastian Grimberg 92477d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 925fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 926e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, 927e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr)); 92877d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 92977d1c127SSebastian Grimberg } 93077d1c127SSebastian Grimberg 931e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 93277d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 933e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 93477d1c127SSebastian Grimberg CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 93577d1c127SSebastian Grimberg CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 93677d1c127SSebastian Grimberg 937e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets)); 938e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients)); 939e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size)); 940e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size)); 94177d1c127SSebastian Grimberg 942fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr)); 943fcbe8c06SSebastian Grimberg CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 94477d1c127SSebastian Grimberg (*rstr)->ref_count = 1; 94577d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem; 94677d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size; 94777d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp; 94877d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride; 94977d1c127SSebastian Grimberg (*rstr)->l_size = l_size; 950*05fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 951e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 952e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 953fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED; 954e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, 955e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr)); 9561c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets)); 95777d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 95877d1c127SSebastian Grimberg } 95977d1c127SSebastian Grimberg 96077d1c127SSebastian Grimberg /** 96177d1c127SSebastian Grimberg @brief Create a blocked strided CeedElemRestriction, typically only called by backends 9627509a596Sjeremylt 963ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 964ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 965ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 966e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block 967ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 968fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector. 969fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction. 970fcbe8c06SSebastian Grimberg @param[in] strides Array for strides between [nodes, components, elements]. 971fcbe8c06SSebastian 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]. 972fcbe8c06SSebastian Grimberg @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 973ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 9747509a596Sjeremylt 9757509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 9767509a596Sjeremylt 9777a982d89SJeremy L. Thompson @ref User 9787509a596Sjeremylt **/ 979e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size, 9808621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 981e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size); 9827509a596Sjeremylt 9837509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 9847509a596Sjeremylt Ceed delegate; 9856574a04fSJeremy L Thompson 9862b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 987fcbe8c06SSebastian Grimberg CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 988e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr)); 989e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9907509a596Sjeremylt } 9917509a596Sjeremylt 992e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative"); 9936574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 994e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 9956574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 996e7f679fcSJeremy 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"); 997e022e1f8SJeremy L Thompson 9982b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 999db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*rstr)->ceed)); 1000d1d35e2fSjeremylt (*rstr)->ref_count = 1; 1001d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 1002d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 1003d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 1004d1d35e2fSjeremylt (*rstr)->l_size = l_size; 1005*05fa913cSJeremy L Thompson (*rstr)->e_size = num_block * block_size * elem_size * num_comp; 1006e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block; 1007e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size; 1008fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED; 10092b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 10102b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 1011fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr)); 1012e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10137509a596Sjeremylt } 10147509a596Sjeremylt 10157509a596Sjeremylt /** 10167c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unsigned version. 1017c17ec2beSJeremy L Thompson 1018c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 1019c17ec2beSJeremy L Thompson 1020c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 1021c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 1022c17ec2beSJeremy L Thompson 1023c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1024c17ec2beSJeremy L Thompson 1025c17ec2beSJeremy L Thompson @ref User 1026c17ec2beSJeremy L Thompson **/ 1027c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 1028c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 1029c17ec2beSJeremy L Thompson 1030c17ec2beSJeremy L Thompson // Copy old rstr 1031c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 1032c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 1033c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 1034c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 1035c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 1036c17ec2beSJeremy L Thompson if (rstr->strides) { 1037c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 1038c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 1039c17ec2beSJeremy L Thompson } 10407c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base)); 1041c17ec2beSJeremy L Thompson 1042c17ec2beSJeremy L Thompson // Override Apply 1043c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 1044c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 1045c17ec2beSJeremy L Thompson } 1046c17ec2beSJeremy L Thompson 1047c17ec2beSJeremy L Thompson /** 10487c1dbaffSSebastian Grimberg @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to use the unoriented version. 10497c1dbaffSSebastian Grimberg 10507c1dbaffSSebastian Grimberg Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 10517c1dbaffSSebastian Grimberg 10527c1dbaffSSebastian Grimberg @param[in] rstr CeedElemRestriction to create unoriented reference to 10537c1dbaffSSebastian Grimberg @param[in,out] rstr_unoriented Variable to store unoriented CeedElemRestriction 10547c1dbaffSSebastian Grimberg 10557c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure 10567c1dbaffSSebastian Grimberg 10577c1dbaffSSebastian Grimberg @ref User 10587c1dbaffSSebastian Grimberg **/ 10597c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) { 10607c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented)); 10617c1dbaffSSebastian Grimberg 10627c1dbaffSSebastian Grimberg // Copy old rstr 10637c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private)); 10647c1dbaffSSebastian Grimberg (*rstr_unoriented)->ceed = NULL; 10657c1dbaffSSebastian Grimberg CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unoriented)->ceed)); 10667c1dbaffSSebastian Grimberg (*rstr_unoriented)->ref_count = 1; 10677c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL; 10687c1dbaffSSebastian Grimberg if (rstr->strides) { 10697c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides)); 10707c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i]; 10717c1dbaffSSebastian Grimberg } 10727c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base)); 10737c1dbaffSSebastian Grimberg 10747c1dbaffSSebastian Grimberg // Override Apply 10757c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented; 10767c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS; 10777c1dbaffSSebastian Grimberg } 10787c1dbaffSSebastian Grimberg 10797c1dbaffSSebastian Grimberg /** 1080ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 10819fd66db6SSebastian Grimberg 1082ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 10839560d06aSjeremylt 10849fd66db6SSebastian 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. 10859fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 1086ea61e9acSJeremy L Thompson 1087ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 1088ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 10899560d06aSjeremylt 10909560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 10919560d06aSjeremylt 10929560d06aSjeremylt @ref User 10939560d06aSjeremylt **/ 10942b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 1095393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 10962b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 10979560d06aSjeremylt *rstr_copy = rstr; 10989560d06aSjeremylt return CEED_ERROR_SUCCESS; 10999560d06aSjeremylt } 11009560d06aSjeremylt 11019560d06aSjeremylt /** 1102b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 1103b11c1e72Sjeremylt 1104ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1105ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 1106ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 1107b11c1e72Sjeremylt 1108b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1109dfdf5a53Sjeremylt 11107a982d89SJeremy L. Thompson @ref User 1111b11c1e72Sjeremylt **/ 11122b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 1113d2643443SJeremy L Thompson CeedSize e_size, l_size; 1114d1d35e2fSjeremylt l_size = rstr->l_size; 1115e7f679fcSJeremy L Thompson e_size = rstr->num_block * rstr->block_size * rstr->elem_size * rstr->num_comp; 11162b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 11172b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 1118e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1119d7b241e6Sjeremylt } 1120d7b241e6Sjeremylt 1121d7b241e6Sjeremylt /** 1122d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 1123d7b241e6Sjeremylt 1124ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1125ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1126ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1127fcbe8c06SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1128fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1129ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1130b11c1e72Sjeremylt 1131b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1132dfdf5a53Sjeremylt 11337a982d89SJeremy L. Thompson @ref User 1134b11c1e72Sjeremylt **/ 11352b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 1136d7b241e6Sjeremylt CeedInt m, n; 1137d7b241e6Sjeremylt 1138d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1139*05fa913cSJeremy L Thompson m = rstr->e_size; 1140d1d35e2fSjeremylt n = rstr->l_size; 1141d7b241e6Sjeremylt } else { 1142d1d35e2fSjeremylt m = rstr->l_size; 1143*05fa913cSJeremy L Thompson n = rstr->e_size; 1144d7b241e6Sjeremylt } 1145*05fa913cSJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11466574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 1147*05fa913cSJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11486574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 11492b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 1150e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1151d7b241e6Sjeremylt } 1152d7b241e6Sjeremylt 1153d7b241e6Sjeremylt /** 11543ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose 11553ac8f562SJeremy L Thompson 11563ac8f562SJeremy L Thompson @param[in] rstr CeedElemRestriction 11573ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose 11583ac8f562SJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 11593ac8f562SJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 11603ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend. 11613ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 11623ac8f562SJeremy L Thompson 11633ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11643ac8f562SJeremy L Thompson 11653ac8f562SJeremy L Thompson @ref User 11663ac8f562SJeremy L Thompson **/ 1167*05fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 11683ac8f562SJeremy L Thompson CeedRequest *request) { 11693ac8f562SJeremy L Thompson CeedInt m, n; 11703ac8f562SJeremy L Thompson 11713ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) { 11723ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &m)); 11733ac8f562SJeremy L Thompson n = rstr->l_size; 11743ac8f562SJeremy L Thompson } else { 11753ac8f562SJeremy L Thompson m = rstr->l_size; 11763ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &n)); 11773ac8f562SJeremy L Thompson } 11783ac8f562SJeremy L Thompson CeedCheck(n <= u->length, rstr->ceed, CEED_ERROR_DIMENSION, 11793ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 11803ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 11813ac8f562SJeremy L Thompson u->length, m, n, elem); 11823ac8f562SJeremy L Thompson CeedCheck(m <= ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 11833ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT 11843ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT, 11853ac8f562SJeremy L Thompson ru->length, m, n, elem); 11863ac8f562SJeremy L Thompson CeedCheck(elem <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 11873ac8f562SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, rstr->num_elem); 1188*05fa913cSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request)); 11893ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS; 11903ac8f562SJeremy L Thompson } 11913ac8f562SJeremy L Thompson 11923ac8f562SJeremy L Thompson /** 1193d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 1194be9261b7Sjeremylt 1195ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1196e7f679fcSJeremy 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 1197e7f679fcSJeremy L Thompson [3*block_size : 4*block_size] 1198ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 1199ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 1200e7f679fcSJeremy L Thompson @param[out] ru Output vector (of shape [@a block_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 1201fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend. 1202ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 1203be9261b7Sjeremylt 1204be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 1205be9261b7Sjeremylt 12067a982d89SJeremy L. Thompson @ref Backend 1207be9261b7Sjeremylt **/ 12082b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 12092b730f8bSJeremy L Thompson CeedRequest *request) { 1210be9261b7Sjeremylt CeedInt m, n; 1211be9261b7Sjeremylt 12126402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 12136402da51SJeremy L Thompson 1214d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 1215e7f679fcSJeremy L Thompson m = rstr->block_size * rstr->elem_size * rstr->num_comp; 1216d1d35e2fSjeremylt n = rstr->l_size; 1217be9261b7Sjeremylt } else { 1218d1d35e2fSjeremylt m = rstr->l_size; 1219e7f679fcSJeremy L Thompson n = rstr->block_size * rstr->elem_size * rstr->num_comp; 1220be9261b7Sjeremylt } 12216574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 12226574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 12236574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 12246574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 1225e7f679fcSJeremy L Thompson CeedCheck(rstr->block_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 1226e7f679fcSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->block_size * block, 12276574a04fSJeremy L Thompson rstr->num_elem); 12282b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 1229e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1230be9261b7Sjeremylt } 1231be9261b7Sjeremylt 1232be9261b7Sjeremylt /** 1233b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 1234b7c9bbdaSJeremy L Thompson 1235ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1236b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 1237b7c9bbdaSJeremy L Thompson 1238b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1239b7c9bbdaSJeremy L Thompson 1240b7c9bbdaSJeremy L Thompson @ref Advanced 1241b7c9bbdaSJeremy L Thompson **/ 1242b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 1243b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 1244b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1245b7c9bbdaSJeremy L Thompson } 1246b7c9bbdaSJeremy L Thompson 1247b7c9bbdaSJeremy L Thompson /** 1248d979a051Sjeremylt @brief Get the L-vector component stride 1249a681ae63Sjeremylt 1250ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1251d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 1252a681ae63Sjeremylt 1253a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1254a681ae63Sjeremylt 1255b7c9bbdaSJeremy L Thompson @ref Advanced 1256a681ae63Sjeremylt **/ 12572b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 1258d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 1259e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1260a681ae63Sjeremylt } 1261a681ae63Sjeremylt 1262a681ae63Sjeremylt /** 1263a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 1264a681ae63Sjeremylt 1265ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1266d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 1267a681ae63Sjeremylt 1268a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1269a681ae63Sjeremylt 1270b7c9bbdaSJeremy L Thompson @ref Advanced 1271a681ae63Sjeremylt **/ 12722b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 1273d1d35e2fSjeremylt *num_elem = rstr->num_elem; 1274e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1275a681ae63Sjeremylt } 1276a681ae63Sjeremylt 1277a681ae63Sjeremylt /** 1278a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 1279a681ae63Sjeremylt 1280ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1281d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 1282a681ae63Sjeremylt 1283a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1284a681ae63Sjeremylt 1285b7c9bbdaSJeremy L Thompson @ref Advanced 1286a681ae63Sjeremylt **/ 12872b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 1288d1d35e2fSjeremylt *elem_size = rstr->elem_size; 12892c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS; 12902c7e7413SJeremy L Thompson } 12912c7e7413SJeremy L Thompson 12922c7e7413SJeremy L Thompson /** 12932c7e7413SJeremy L Thompson @brief Get the maximum number of points in an element for a CeedElemRestriction at points 12942c7e7413SJeremy L Thompson 12952c7e7413SJeremy L Thompson @param[in] rstr CeedElemRestriction 12962c7e7413SJeremy L Thompson @param[out] max_points Variable to store size of elements 12972c7e7413SJeremy L Thompson 12982c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 12992c7e7413SJeremy L Thompson 13002c7e7413SJeremy L Thompson @ref Advanced 13012c7e7413SJeremy L Thompson **/ 13022c7e7413SJeremy L Thompson int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) { 13032c7e7413SJeremy L Thompson Ceed ceed; 13042c7e7413SJeremy L Thompson CeedInt num_elem; 13052c7e7413SJeremy L Thompson CeedRestrictionType rstr_type; 13062c7e7413SJeremy L Thompson 13072c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed)); 13082c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type)); 13092c7e7413SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, ceed, CEED_ERROR_INCOMPATIBLE, 13102c7e7413SJeremy L Thompson "Cannot compute max points for a CeedElemRestriction that does not use points"); 13112c7e7413SJeremy L Thompson 13122c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 13132c7e7413SJeremy L Thompson *max_points = 0; 13142c7e7413SJeremy L Thompson for (CeedInt e = 0; e < num_elem; e++) { 13152c7e7413SJeremy L Thompson CeedInt num_points; 13162c7e7413SJeremy L Thompson 13172c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points)); 13182c7e7413SJeremy L Thompson *max_points = CeedIntMax(num_points, *max_points); 13192c7e7413SJeremy L Thompson } 1320e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1321a681ae63Sjeremylt } 1322a681ae63Sjeremylt 1323a681ae63Sjeremylt /** 1324d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 1325a681ae63Sjeremylt 1326ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1327d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 1328a681ae63Sjeremylt 1329a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1330a681ae63Sjeremylt 1331b7c9bbdaSJeremy L Thompson @ref Advanced 1332a681ae63Sjeremylt **/ 13332b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 1334d1d35e2fSjeremylt *l_size = rstr->l_size; 1335e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1336a681ae63Sjeremylt } 1337a681ae63Sjeremylt 1338a681ae63Sjeremylt /** 1339ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 1340a681ae63Sjeremylt 1341ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1342d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 1343a681ae63Sjeremylt 1344a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1345a681ae63Sjeremylt 1346b7c9bbdaSJeremy L Thompson @ref Advanced 1347a681ae63Sjeremylt **/ 13482b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 1349d1d35e2fSjeremylt *num_comp = rstr->num_comp; 1350e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1351a681ae63Sjeremylt } 1352a681ae63Sjeremylt 1353a681ae63Sjeremylt /** 1354a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 1355a681ae63Sjeremylt 1356ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1357d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 1358a681ae63Sjeremylt 1359a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1360a681ae63Sjeremylt 1361b7c9bbdaSJeremy L Thompson @ref Advanced 1362a681ae63Sjeremylt **/ 13632b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 1364e7f679fcSJeremy L Thompson *num_block = rstr->num_block; 1365e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1366a681ae63Sjeremylt } 1367a681ae63Sjeremylt 1368a681ae63Sjeremylt /** 1369a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 1370a681ae63Sjeremylt 1371ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1372e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks 1373a681ae63Sjeremylt 1374a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 1375a681ae63Sjeremylt 1376b7c9bbdaSJeremy L Thompson @ref Advanced 1377a681ae63Sjeremylt **/ 1378e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) { 1379e7f679fcSJeremy L Thompson *block_size = rstr->block_size; 1380e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1381a681ae63Sjeremylt } 1382a681ae63Sjeremylt 1383a681ae63Sjeremylt /** 1384d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 13851469ee4dSjeremylt 1386ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 1387d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 13881469ee4dSjeremylt 13891469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 13901469ee4dSjeremylt 13917a982d89SJeremy L. Thompson @ref User 13921469ee4dSjeremylt **/ 13932b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 1394d1d35e2fSjeremylt CeedVector e_vec; 13951469ee4dSjeremylt 139625509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 13972b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 13981469ee4dSjeremylt 139925509ebbSRezgar Shakeri // Compute e_vec = E * 1 14002b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 14012b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 140225509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 14032b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 14042b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 14051469ee4dSjeremylt // Cleanup 14062b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1407e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 14081469ee4dSjeremylt } 14091469ee4dSjeremylt 14101469ee4dSjeremylt /** 1411f02ca4a2SJed Brown @brief View a CeedElemRestriction 1412f02ca4a2SJed Brown 1413f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1414f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1415f02ca4a2SJed Brown 1416f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1417f02ca4a2SJed Brown 14187a982d89SJeremy L. Thompson @ref User 1419f02ca4a2SJed Brown **/ 1420f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 14217509a596Sjeremylt char stridesstr[500]; 14221c66c397SJeremy L Thompson 14232b730f8bSJeremy L Thompson if (rstr->strides) { 14242b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 14252b730f8bSJeremy L Thompson } else { 1426990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 14272b730f8bSJeremy L Thompson } 14287509a596Sjeremylt 14292b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 1430e7f679fcSJeremy L Thompson rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1431d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1432e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1433f02ca4a2SJed Brown } 1434f02ca4a2SJed Brown 1435f02ca4a2SJed Brown /** 1436b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1437b11c1e72Sjeremylt 1438ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 1439b11c1e72Sjeremylt 1440b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1441dfdf5a53Sjeremylt 14427a982d89SJeremy L. Thompson @ref User 1443b11c1e72Sjeremylt **/ 14444ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1445393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 1446ad6481ceSJeremy L Thompson *rstr = NULL; 1447ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1448ad6481ceSJeremy L Thompson } 14496574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 14506574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 1451c17ec2beSJeremy L Thompson 1452c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 14537c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base)); 1454c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1455c17ec2beSJeremy L Thompson 14562b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 14572b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 14582b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1459e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1460d7b241e6Sjeremylt } 1461d7b241e6Sjeremylt 1462d7b241e6Sjeremylt /// @} 1463