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> 13*c17ec2beSJeremy 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 27ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 28ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 29ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 30ea61e9acSJeremy L Thompson @param[out] blk_offsets Array of permuted and padded offsets of shape [@a num_blk, @a elem_size, @a blk_size]. 31ea61e9acSJeremy L Thompson @param[in] num_blk Number of blocks 32ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements 33ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 34ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element 357a982d89SJeremy L. Thompson 367a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 377a982d89SJeremy L. Thompson 387a982d89SJeremy L. Thompson @ref Utility 397a982d89SJeremy L. Thompson **/ 402b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 412b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 422b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 432b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 442b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 452b730f8bSJeremy L Thompson } 462b730f8bSJeremy L Thompson } 472b730f8bSJeremy L Thompson } 48e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 497a982d89SJeremy L. Thompson } 507a982d89SJeremy L. Thompson 517a982d89SJeremy L. Thompson /// @} 527a982d89SJeremy L. Thompson 537a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 547a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 557a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 567a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 577a982d89SJeremy L. Thompson /// @{ 587a982d89SJeremy L. Thompson 597a982d89SJeremy L. Thompson /** 60a681ae63Sjeremylt 61a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 627a982d89SJeremy L. Thompson 63ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 64a681ae63Sjeremylt @param[out] strides Variable to store strides array 657a982d89SJeremy L. Thompson 667a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 677a982d89SJeremy L. Thompson 687a982d89SJeremy L. Thompson @ref Backend 697a982d89SJeremy L. Thompson **/ 702b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 716574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 722b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 73e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 747a982d89SJeremy L. Thompson } 757a982d89SJeremy L. Thompson 767a982d89SJeremy L. Thompson /** 77bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 78bd33150aSjeremylt 79ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to retrieve offsets 80ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the array. 81ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy (possibly cached). 82d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 83bd33150aSjeremylt 84bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 85bd33150aSjeremylt 86bd33150aSjeremylt @ref User 87bd33150aSjeremylt **/ 882b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 89*c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 90*c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_signed, mem_type, offsets)); 91*c17ec2beSJeremy L Thompson } else { 926574a04fSJeremy L Thompson CeedCheck(rstr->GetOffsets, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 932b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 94d1d35e2fSjeremylt rstr->num_readers++; 95*c17ec2beSJeremy L Thompson } 96e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 97430758c8SJeremy L Thompson } 98430758c8SJeremy L Thompson 99430758c8SJeremy L Thompson /** 100430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 101430758c8SJeremy L Thompson 102ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to restore 103ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data 104430758c8SJeremy L Thompson 105430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 106430758c8SJeremy L Thompson 107430758c8SJeremy L Thompson @ref User 108430758c8SJeremy L Thompson **/ 1092b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 110*c17ec2beSJeremy L Thompson if (rstr->rstr_signed) { 111*c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_signed, offsets)); 112*c17ec2beSJeremy L Thompson } else { 113430758c8SJeremy L Thompson *offsets = NULL; 114d1d35e2fSjeremylt rstr->num_readers--; 115*c17ec2beSJeremy L Thompson } 116e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 117bd33150aSjeremylt } 118bd33150aSjeremylt 119bd33150aSjeremylt /** 1203ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1213ac43b2cSJeremy L Thompson 122ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 123d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1243ac43b2cSJeremy L Thompson 1253ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1263ac43b2cSJeremy L Thompson 1273ac43b2cSJeremy L Thompson @ref Backend 1283ac43b2cSJeremy L Thompson **/ 129d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 130d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 131e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1323ac43b2cSJeremy L Thompson } 1333ac43b2cSJeremy L Thompson 1343ac43b2cSJeremy L Thompson /** 135b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 136b435c5a6Srezgarshakeri 137ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 138b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 139b435c5a6Srezgarshakeri 140b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 141b435c5a6Srezgarshakeri 142b435c5a6Srezgarshakeri @ref Backend 143b435c5a6Srezgarshakeri **/ 144b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 145b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 146b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 147b435c5a6Srezgarshakeri } 148b435c5a6Srezgarshakeri 149b435c5a6Srezgarshakeri /** 150a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1517a982d89SJeremy L. Thompson 152ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 15396b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1547a982d89SJeremy L. Thompson 1557a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1567a982d89SJeremy L. Thompson 1577a982d89SJeremy L. Thompson @ref Backend 1587a982d89SJeremy L. Thompson **/ 1592b730f8bSJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 1606574a04fSJeremy L Thompson CeedCheck(rstr->strides, rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 1612b730f8bSJeremy L Thompson *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 162a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 163e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1647a982d89SJeremy L. Thompson } 1657a982d89SJeremy L. Thompson 1667a982d89SJeremy L. Thompson /** 16749fd234cSJeremy L Thompson 16849fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 16949fd234cSJeremy L Thompson 170ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 171ea61e9acSJeremy L Thompson @param[out] layout Variable to store layout array, stored as [nodes, components, elements]. 172ea61e9acSJeremy 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] 17349fd234cSJeremy L Thompson 17449fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 17549fd234cSJeremy L Thompson 17649fd234cSJeremy L Thompson @ref Backend 17749fd234cSJeremy L Thompson **/ 1782b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 1796574a04fSJeremy L Thompson CeedCheck(rstr->layout[0], rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 1802b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 181e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 18249fd234cSJeremy L Thompson } 18349fd234cSJeremy L Thompson 18449fd234cSJeremy L Thompson /** 18549fd234cSJeremy L Thompson 18649fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 18749fd234cSJeremy L Thompson 188ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 189ea61e9acSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as [nodes, components, elements]. 190ea61e9acSJeremy 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] 19149fd234cSJeremy L Thompson 19249fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19349fd234cSJeremy L Thompson 19449fd234cSJeremy L Thompson @ref Backend 19549fd234cSJeremy L Thompson **/ 1962b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 1972b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 198e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 19949fd234cSJeremy L Thompson } 20049fd234cSJeremy L Thompson 20149fd234cSJeremy L Thompson /** 2027a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2037a982d89SJeremy L. Thompson 204ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 2057a982d89SJeremy L. Thompson @param[out] data Variable to store data 2067a982d89SJeremy L. Thompson 2077a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2087a982d89SJeremy L. Thompson 2097a982d89SJeremy L. Thompson @ref Backend 2107a982d89SJeremy L. Thompson **/ 211777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 212777ff853SJeremy L Thompson *(void **)data = rstr->data; 213e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2147a982d89SJeremy L. Thompson } 2157a982d89SJeremy L. Thompson 2167a982d89SJeremy L. Thompson /** 2177a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2187a982d89SJeremy L. Thompson 219ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction 220ea61e9acSJeremy L Thompson @param[in] data Data to set 2217a982d89SJeremy L. Thompson 2227a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2237a982d89SJeremy L. Thompson 2247a982d89SJeremy L. Thompson @ref Backend 2257a982d89SJeremy L. Thompson **/ 226777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 227777ff853SJeremy L Thompson rstr->data = data; 228e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2297a982d89SJeremy L. Thompson } 2307a982d89SJeremy L. Thompson 23134359f16Sjeremylt /** 23234359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 23334359f16Sjeremylt 234ea61e9acSJeremy L Thompson @param[in,out] rstr ElemRestriction to increment the reference counter 23534359f16Sjeremylt 23634359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 23734359f16Sjeremylt 23834359f16Sjeremylt @ref Backend 23934359f16Sjeremylt **/ 2409560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 24134359f16Sjeremylt rstr->ref_count++; 24234359f16Sjeremylt return CEED_ERROR_SUCCESS; 24334359f16Sjeremylt } 24434359f16Sjeremylt 2456e15d496SJeremy L Thompson /** 2466e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 2476e15d496SJeremy L Thompson 248ea61e9acSJeremy L Thompson @param[in] rstr ElemRestriction to estimate FLOPs for 249ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 250ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 2516e15d496SJeremy L Thompson 2526e15d496SJeremy L Thompson @ref Backend 2536e15d496SJeremy L Thompson **/ 2542b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 2556e15d496SJeremy L Thompson bool is_oriented; 2562b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 2576e15d496SJeremy L Thompson 2582b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionIsOriented(rstr, &is_oriented)); 2596e15d496SJeremy L Thompson switch (t_mode) { 2602b730f8bSJeremy L Thompson case CEED_NOTRANSPOSE: 2612b730f8bSJeremy L Thompson scale = is_oriented ? 1 : 0; 2622b730f8bSJeremy L Thompson break; 2632b730f8bSJeremy L Thompson case CEED_TRANSPOSE: 2642b730f8bSJeremy L Thompson scale = is_oriented ? 2 : 1; 2652b730f8bSJeremy L Thompson break; 2666e15d496SJeremy L Thompson } 2676e15d496SJeremy L Thompson *flops = e_size * scale; 2686e15d496SJeremy L Thompson 2696e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 2706e15d496SJeremy L Thompson } 2716e15d496SJeremy L Thompson 2727a982d89SJeremy L. Thompson /// @} 2737a982d89SJeremy L. Thompson 27415910d16Sjeremylt /// @cond DOXYGEN_SKIP 27515910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 27615910d16Sjeremylt /// @endcond 27715910d16Sjeremylt 2787a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2797a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2807a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2817a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 282d7b241e6Sjeremylt /// @{ 283d7b241e6Sjeremylt 2847a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 28545f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 2867a982d89SJeremy L. Thompson 2874cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 2882b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 2897a982d89SJeremy L. Thompson 290d7b241e6Sjeremylt /** 291b11c1e72Sjeremylt @brief Create a CeedElemRestriction 292d7b241e6Sjeremylt 293ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 294ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 295ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 296ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 297ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 298ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index offsets[i + k*elem_size] + j*comp_stride. 299ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 300ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 301ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 302ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 303ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 304ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 305ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 306ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 307d7b241e6Sjeremylt 308b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 309dfdf5a53Sjeremylt 3107a982d89SJeremy L. Thompson @ref User 311b11c1e72Sjeremylt **/ 3122b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 3132b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 3145fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3155fe0d4faSjeremylt Ceed delegate; 3166574a04fSJeremy L Thompson 3172b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 3186574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreate"); 3192b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 320e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3215fe0d4faSjeremylt } 3225fe0d4faSjeremylt 3236574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 3246574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 3256574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 326e022e1f8SJeremy L Thompson 3272b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 3284ce2993fSjeremylt (*rstr)->ceed = ceed; 3292b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 330d1d35e2fSjeremylt (*rstr)->ref_count = 1; 331d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 332d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 333d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 334d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 335d1d35e2fSjeremylt (*rstr)->l_size = l_size; 336d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 337d1d35e2fSjeremylt (*rstr)->blk_size = 1; 3386402da51SJeremy L Thompson (*rstr)->is_oriented = false; 3392b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr)); 340e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 341d7b241e6Sjeremylt } 342d7b241e6Sjeremylt 343d7b241e6Sjeremylt /** 344fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 345fc0567d9Srezgarshakeri 346ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 347ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array 348ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 349ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 350ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 351ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index offsets[i + k*elem_size] + j*comp_stride. 352ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 353ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 354ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 355ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 356ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 357ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 358ea61e9acSJeremy L Thompson 0 <= i < @a num_elem. All offsets must be in the range [0, @a l_size - 1]. 359ea61e9acSJeremy L Thompson @param[in] orient Array of shape [@a num_elem, @a elem_size] with bool false for positively oriented and true to flip the orientation. 360ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 361fc0567d9Srezgarshakeri 362fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 363fc0567d9Srezgarshakeri 364fc0567d9Srezgarshakeri @ref User 365fc0567d9Srezgarshakeri **/ 3662b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 3672b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orient, 368fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 369c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 370fc0567d9Srezgarshakeri Ceed delegate; 3716574a04fSJeremy L Thompson 3722b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 3736574a04fSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateOriented"); 3742b730f8bSJeremy L Thompson CeedCall( 3752b730f8bSJeremy L Thompson CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orient, rstr)); 376fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 377fc0567d9Srezgarshakeri } 378fc0567d9Srezgarshakeri 3796574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 3806574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 3816574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 382e022e1f8SJeremy L Thompson 3832b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 384fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 3852b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 386fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 387fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 388fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 389fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 390fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 391fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 392fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 393fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 3946402da51SJeremy L Thompson (*rstr)->is_oriented = true; 3952b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient, *rstr)); 396fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 397fc0567d9Srezgarshakeri } 398fc0567d9Srezgarshakeri 399fc0567d9Srezgarshakeri /** 4007509a596Sjeremylt @brief Create a strided CeedElemRestriction 401d7b241e6Sjeremylt 402ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 403ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 404ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 405ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields) 406ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 407ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 408ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 409ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index i*strides[0] + j*strides[1] + k*strides[2]. 410ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 411ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 412d7b241e6Sjeremylt 413b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 414dfdf5a53Sjeremylt 4157a982d89SJeremy L. Thompson @ref User 416b11c1e72Sjeremylt **/ 4172b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 418f90c8643Sjeremylt CeedElemRestriction *rstr) { 4195fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4205fe0d4faSjeremylt Ceed delegate; 421b04eb3d9SSebastian Grimberg 4222b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4236402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateStrided"); 4242b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 425e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4265fe0d4faSjeremylt } 4275fe0d4faSjeremylt 4286574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4296574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 430e022e1f8SJeremy L Thompson 4312b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 4324ce2993fSjeremylt (*rstr)->ceed = ceed; 4332b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 434d1d35e2fSjeremylt (*rstr)->ref_count = 1; 435d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 436d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 437d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 438d1d35e2fSjeremylt (*rstr)->l_size = l_size; 439d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 440d1d35e2fSjeremylt (*rstr)->blk_size = 1; 4416402da51SJeremy L Thompson (*rstr)->is_oriented = false; 4422b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 4432b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 4442b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 445e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 446d7b241e6Sjeremylt } 447d7b241e6Sjeremylt 448d7b241e6Sjeremylt /** 449b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 450d7b241e6Sjeremylt 451ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created. 452ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described in the @a offsets array. 453ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element 454ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 455ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 456ea61e9acSJeremy L Thompson @param[in] comp_stride Stride between components for the same L-vector "node". 457ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index offsets[i + k*elem_size] + j*comp_stride. 458ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 459ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 460ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the @a offsets array, see CeedMemType 461ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the @a offsets array, see CeedCopyMode 462ea61e9acSJeremy L Thompson @param[in] offsets Array of shape [@a num_elem, @a elem_size]. 463ea61e9acSJeremy L Thompson Row i holds the ordered list of the offsets (into the input CeedVector) for the unknowns corresponding to element i, where 464ea61e9acSJeremy L Thompson 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 465ea61e9acSJeremy L Thompson the blocksize, which is typically given by the backend. The default reordering is to interlace elements. 466ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 467d7b241e6Sjeremylt 468b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 469dfdf5a53Sjeremylt 4707a982d89SJeremy L. Thompson @ref Backend 471b11c1e72Sjeremylt **/ 4722b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 4732b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 4744ce2993fSjeremylt CeedElemRestriction *rstr) { 475d1d35e2fSjeremylt CeedInt *blk_offsets; 476d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 477d7b241e6Sjeremylt 4785fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 4795fe0d4faSjeremylt Ceed delegate; 4806574a04fSJeremy L Thompson 4812b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4826402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlocked"); 4832b730f8bSJeremy L Thompson CeedCall( 4842b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 485e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4865fe0d4faSjeremylt } 487d7b241e6Sjeremylt 4886574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 4896574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 4906574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 4916574a04fSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 492e022e1f8SJeremy L Thompson 4932b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 494d7b241e6Sjeremylt 4952b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 4962b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 497d7b241e6Sjeremylt 4984ce2993fSjeremylt (*rstr)->ceed = ceed; 4992b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 500d1d35e2fSjeremylt (*rstr)->ref_count = 1; 501d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 502d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 503d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 504d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 505d1d35e2fSjeremylt (*rstr)->l_size = l_size; 506d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 507d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5086402da51SJeremy L Thompson (*rstr)->is_oriented = false; 5092b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, *rstr)); 510d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 5112b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 5121d102b48SJeremy L Thompson } 513e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 514d7b241e6Sjeremylt } 515d7b241e6Sjeremylt 516b11c1e72Sjeremylt /** 5177509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5187509a596Sjeremylt 519ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedElemRestriction will be created 520ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction 521ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element 522ea61e9acSJeremy L Thompson @param[in] blk_size Number of elements in a block 523ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields) 524ea61e9acSJeremy L Thompson @param[in] l_size The size of the L-vector. 525ea61e9acSJeremy L Thompson This vector may be larger than the elements and fields given by this restriction. 526ea61e9acSJeremy L Thompson @param[in] strides Array for strides between [nodes, components, elements]. 527ea61e9acSJeremy L Thompson Data for node i, component j, element k can be found in the L-vector at index i*strides[0] + j*strides[1] + k*strides[2]. 528ea61e9acSJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created by a Ceed backend. 529ea61e9acSJeremy L Thompson @param[out] rstr Address of the variable where the newly created CeedElemRestriction will be stored 5307509a596Sjeremylt 5317509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 5327509a596Sjeremylt 5337a982d89SJeremy L. Thompson @ref User 5347509a596Sjeremylt **/ 5352b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 5368621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 537d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 5387509a596Sjeremylt 5397509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5407509a596Sjeremylt Ceed delegate; 5416574a04fSJeremy L Thompson 5422b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5436402da51SJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateBlockedStrided"); 5442b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 545e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5467509a596Sjeremylt } 5477509a596Sjeremylt 5486574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 5496574a04fSJeremy L Thompson CeedCheck(blk_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 5506574a04fSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 551e022e1f8SJeremy L Thompson 5522b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 5537509a596Sjeremylt 5547509a596Sjeremylt (*rstr)->ceed = ceed; 5552b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 556d1d35e2fSjeremylt (*rstr)->ref_count = 1; 557d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 558d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 559d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 560d1d35e2fSjeremylt (*rstr)->l_size = l_size; 561d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 562d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 5636402da51SJeremy L Thompson (*rstr)->is_oriented = false; 5642b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 5652b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 5662b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 567e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5687509a596Sjeremylt } 5697509a596Sjeremylt 5707509a596Sjeremylt /** 571*c17ec2beSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction and set `CeedElemRestrictionApply()` implementation to `CeedElemRestrictionApplyUnsigned()`. 572*c17ec2beSJeremy L Thompson 573*c17ec2beSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 574*c17ec2beSJeremy L Thompson 575*c17ec2beSJeremy L Thompson @param[in] rstr CeedElemRestriction to create unsigned reference to 576*c17ec2beSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned CeedElemRestriction 577*c17ec2beSJeremy L Thompson 578*c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 579*c17ec2beSJeremy L Thompson 580*c17ec2beSJeremy L Thompson @ref User 581*c17ec2beSJeremy L Thompson **/ 582*c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) { 583*c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned)); 584*c17ec2beSJeremy L Thompson 585*c17ec2beSJeremy L Thompson // Copy old rstr 586*c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private)); 587*c17ec2beSJeremy L Thompson (*rstr_unsigned)->ceed = NULL; 588*c17ec2beSJeremy L Thompson CeedCall(CeedReferenceCopy(rstr->ceed, &(*rstr_unsigned)->ceed)); 589*c17ec2beSJeremy L Thompson (*rstr_unsigned)->ref_count = 1; 590*c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL; 591*c17ec2beSJeremy L Thompson if (rstr->strides) { 592*c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides)); 593*c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i]; 594*c17ec2beSJeremy L Thompson } 595*c17ec2beSJeremy L Thompson CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_signed)); 596*c17ec2beSJeremy L Thompson 597*c17ec2beSJeremy L Thompson // Override Apply 598*c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned; 599*c17ec2beSJeremy L Thompson 600*c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS; 601*c17ec2beSJeremy L Thompson } 602*c17ec2beSJeremy L Thompson 603*c17ec2beSJeremy L Thompson /** 604ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedElemRestriction. 6059fd66db6SSebastian Grimberg 606ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedElemRestrictionDestroy()`. 6079560d06aSjeremylt 6089fd66db6SSebastian 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. 6099fd66db6SSebastian Grimberg This CeedElemRestriction will be destroyed if `rstr_copy` is the only reference to this CeedElemRestriction. 610ea61e9acSJeremy L Thompson 611ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction to copy reference to 612ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference 6139560d06aSjeremylt 6149560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6159560d06aSjeremylt 6169560d06aSjeremylt @ref User 6179560d06aSjeremylt **/ 6182b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 619393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr)); 6202b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 6219560d06aSjeremylt *rstr_copy = rstr; 6229560d06aSjeremylt return CEED_ERROR_SUCCESS; 6239560d06aSjeremylt } 6249560d06aSjeremylt 6259560d06aSjeremylt /** 626b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 627b11c1e72Sjeremylt 628ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 629ea61e9acSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or NULL 630ea61e9acSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or NULL 631b11c1e72Sjeremylt 632b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 633dfdf5a53Sjeremylt 6347a982d89SJeremy L. Thompson @ref User 635b11c1e72Sjeremylt **/ 6362b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 637d2643443SJeremy L Thompson CeedSize e_size, l_size; 638d1d35e2fSjeremylt l_size = rstr->l_size; 639d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 6402b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 6412b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 642e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 643d7b241e6Sjeremylt } 644d7b241e6Sjeremylt 645d7b241e6Sjeremylt /** 646d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 647d7b241e6Sjeremylt 648ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 649ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 650ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 651ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 652ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 653ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 654b11c1e72Sjeremylt 655b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 656dfdf5a53Sjeremylt 6577a982d89SJeremy L. Thompson @ref User 658b11c1e72Sjeremylt **/ 6592b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 660d7b241e6Sjeremylt CeedInt m, n; 661d7b241e6Sjeremylt 662d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 663d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 664d1d35e2fSjeremylt n = rstr->l_size; 665d7b241e6Sjeremylt } else { 666d1d35e2fSjeremylt m = rstr->l_size; 667d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 668d7b241e6Sjeremylt } 6696574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 6706574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 6716574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 6726574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 6732b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 674e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 675d7b241e6Sjeremylt } 676d7b241e6Sjeremylt 677d7b241e6Sjeremylt /** 678f30b1135SSebastian Grimberg @brief Restrict an L-vector to an E-vector or apply its transpose ignoring any 679f30b1135SSebastian Grimberg provided orientations 680f30b1135SSebastian Grimberg 681f30b1135SSebastian Grimberg @param[in] rstr CeedElemRestriction 682f30b1135SSebastian Grimberg @param[in] t_mode Apply restriction or transpose 683f30b1135SSebastian Grimberg @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 684f30b1135SSebastian Grimberg @param[out] ru Output vector (of shape [@a num_elem * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 685f30b1135SSebastian Grimberg Ordering of the e-vector is decided by the backend. 686f30b1135SSebastian Grimberg @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 687f30b1135SSebastian Grimberg 688f30b1135SSebastian Grimberg @return An error code: 0 - success, otherwise - failure 689f30b1135SSebastian Grimberg 690f30b1135SSebastian Grimberg @ref User 691f30b1135SSebastian Grimberg **/ 692f30b1135SSebastian Grimberg int CeedElemRestrictionApplyUnsigned(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 693f30b1135SSebastian Grimberg CeedInt m, n; 694f30b1135SSebastian Grimberg 695b04eb3d9SSebastian Grimberg CeedCheck(rstr->ApplyUnsigned, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionApplyUnsigned"); 696b17517eeSSebastian Grimberg 697f30b1135SSebastian Grimberg if (t_mode == CEED_NOTRANSPOSE) { 698f30b1135SSebastian Grimberg m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 699f30b1135SSebastian Grimberg n = rstr->l_size; 700f30b1135SSebastian Grimberg } else { 701f30b1135SSebastian Grimberg m = rstr->l_size; 702f30b1135SSebastian Grimberg n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 703f30b1135SSebastian Grimberg } 704c7be5f81SSebastian Grimberg CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 705c7be5f81SSebastian Grimberg "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 706c7be5f81SSebastian Grimberg CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 707c7be5f81SSebastian Grimberg "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 708b17517eeSSebastian Grimberg if (rstr->num_elem > 0) CeedCall(rstr->ApplyUnsigned(rstr, t_mode, u, ru, request)); 709f30b1135SSebastian Grimberg return CEED_ERROR_SUCCESS; 710f30b1135SSebastian Grimberg } 711f30b1135SSebastian Grimberg 712f30b1135SSebastian Grimberg /** 713d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 714be9261b7Sjeremylt 715ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 716ea61e9acSJeremy L Thompson @param[in] block Block number to restrict to/from, i.e. block=0 will handle elements [0 : blk_size] and block=3 will handle elements [3*blk_size 717ea61e9acSJeremy L Thompson : 4*blk_size] 718ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose 719ea61e9acSJeremy L Thompson @param[in] u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 720ea61e9acSJeremy L Thompson @param[out] ru Output vector (of shape [@a blk_size * @a elem_size] when t_mode=@ref CEED_NOTRANSPOSE). 721ea61e9acSJeremy L Thompson Ordering of the e-vector is decided by the backend. 722ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE 723be9261b7Sjeremylt 724be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 725be9261b7Sjeremylt 7267a982d89SJeremy L. Thompson @ref Backend 727be9261b7Sjeremylt **/ 7282b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 7292b730f8bSJeremy L Thompson CeedRequest *request) { 730be9261b7Sjeremylt CeedInt m, n; 731be9261b7Sjeremylt 7326402da51SJeremy L Thompson CeedCheck(rstr->ApplyBlock, rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionApplyBlock"); 7336402da51SJeremy L Thompson 734d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 735d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 736d1d35e2fSjeremylt n = rstr->l_size; 737be9261b7Sjeremylt } else { 738d1d35e2fSjeremylt m = rstr->l_size; 739d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 740be9261b7Sjeremylt } 7416574a04fSJeremy L Thompson CeedCheck(n == u->length, rstr->ceed, CEED_ERROR_DIMENSION, 7426574a04fSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, n); 7436574a04fSJeremy L Thompson CeedCheck(m == ru->length, rstr->ceed, CEED_ERROR_DIMENSION, 7446574a04fSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, m, n); 7456574a04fSJeremy L Thompson CeedCheck(rstr->blk_size * block <= rstr->num_elem, rstr->ceed, CEED_ERROR_DIMENSION, 7466574a04fSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, rstr->blk_size * block, 7476574a04fSJeremy L Thompson rstr->num_elem); 7482b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 749e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 750be9261b7Sjeremylt } 751be9261b7Sjeremylt 752be9261b7Sjeremylt /** 753b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 754b7c9bbdaSJeremy L Thompson 755ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 756b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 757b7c9bbdaSJeremy L Thompson 758b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 759b7c9bbdaSJeremy L Thompson 760b7c9bbdaSJeremy L Thompson @ref Advanced 761b7c9bbdaSJeremy L Thompson **/ 762b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 763b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 764b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 765b7c9bbdaSJeremy L Thompson } 766b7c9bbdaSJeremy L Thompson 767b7c9bbdaSJeremy L Thompson /** 768d979a051Sjeremylt @brief Get the L-vector component stride 769a681ae63Sjeremylt 770ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 771d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 772a681ae63Sjeremylt 773a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 774a681ae63Sjeremylt 775b7c9bbdaSJeremy L Thompson @ref Advanced 776a681ae63Sjeremylt **/ 7772b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 778d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 779e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 780a681ae63Sjeremylt } 781a681ae63Sjeremylt 782a681ae63Sjeremylt /** 783a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 784a681ae63Sjeremylt 785ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 786d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 787a681ae63Sjeremylt 788a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 789a681ae63Sjeremylt 790b7c9bbdaSJeremy L Thompson @ref Advanced 791a681ae63Sjeremylt **/ 7922b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 793d1d35e2fSjeremylt *num_elem = rstr->num_elem; 794e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 795a681ae63Sjeremylt } 796a681ae63Sjeremylt 797a681ae63Sjeremylt /** 798a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 799a681ae63Sjeremylt 800ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 801d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 802a681ae63Sjeremylt 803a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 804a681ae63Sjeremylt 805b7c9bbdaSJeremy L Thompson @ref Advanced 806a681ae63Sjeremylt **/ 8072b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 808d1d35e2fSjeremylt *elem_size = rstr->elem_size; 809e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 810a681ae63Sjeremylt } 811a681ae63Sjeremylt 812a681ae63Sjeremylt /** 813d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 814a681ae63Sjeremylt 815ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 816d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 817a681ae63Sjeremylt 818a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 819a681ae63Sjeremylt 820b7c9bbdaSJeremy L Thompson @ref Advanced 821a681ae63Sjeremylt **/ 8222b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 823d1d35e2fSjeremylt *l_size = rstr->l_size; 824e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 825a681ae63Sjeremylt } 826a681ae63Sjeremylt 827a681ae63Sjeremylt /** 828ea61e9acSJeremy L Thompson @brief Get the number of components in the elements of a CeedElemRestriction 829a681ae63Sjeremylt 830ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 831d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 832a681ae63Sjeremylt 833a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 834a681ae63Sjeremylt 835b7c9bbdaSJeremy L Thompson @ref Advanced 836a681ae63Sjeremylt **/ 8372b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 838d1d35e2fSjeremylt *num_comp = rstr->num_comp; 839e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 840a681ae63Sjeremylt } 841a681ae63Sjeremylt 842a681ae63Sjeremylt /** 843a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 844a681ae63Sjeremylt 845ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 846d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 847a681ae63Sjeremylt 848a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 849a681ae63Sjeremylt 850b7c9bbdaSJeremy L Thompson @ref Advanced 851a681ae63Sjeremylt **/ 8522b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 853d1d35e2fSjeremylt *num_block = rstr->num_blk; 854e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 855a681ae63Sjeremylt } 856a681ae63Sjeremylt 857a681ae63Sjeremylt /** 858a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 859a681ae63Sjeremylt 860ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 861d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 862a681ae63Sjeremylt 863a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 864a681ae63Sjeremylt 865b7c9bbdaSJeremy L Thompson @ref Advanced 866a681ae63Sjeremylt **/ 8672b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 868d1d35e2fSjeremylt *blk_size = rstr->blk_size; 869e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 870a681ae63Sjeremylt } 871a681ae63Sjeremylt 872a681ae63Sjeremylt /** 873d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 8741469ee4dSjeremylt 875ea61e9acSJeremy L Thompson @param[in] rstr CeedElemRestriction 876d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 8771469ee4dSjeremylt 8781469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 8791469ee4dSjeremylt 8807a982d89SJeremy L. Thompson @ref User 8811469ee4dSjeremylt **/ 8822b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 883d1d35e2fSjeremylt CeedVector e_vec; 8841469ee4dSjeremylt 88525509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 8862b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 8871469ee4dSjeremylt 88825509ebbSRezgar Shakeri // Compute e_vec = E * 1 8892b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 8902b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 89125509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 8922b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 8932b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 8941469ee4dSjeremylt // Cleanup 8952b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 896e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 8971469ee4dSjeremylt } 8981469ee4dSjeremylt 8991469ee4dSjeremylt /** 900f02ca4a2SJed Brown @brief View a CeedElemRestriction 901f02ca4a2SJed Brown 902f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 903f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 904f02ca4a2SJed Brown 905f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 906f02ca4a2SJed Brown 9077a982d89SJeremy L. Thompson @ref User 908f02ca4a2SJed Brown **/ 909f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 9107509a596Sjeremylt char stridesstr[500]; 9112b730f8bSJeremy L Thompson if (rstr->strides) { 9122b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 9132b730f8bSJeremy L Thompson } else { 914990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 9152b730f8bSJeremy L Thompson } 9167509a596Sjeremylt 9172b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 9182b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 919d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 920e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 921f02ca4a2SJed Brown } 922f02ca4a2SJed Brown 923f02ca4a2SJed Brown /** 924b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 925b11c1e72Sjeremylt 926ea61e9acSJeremy L Thompson @param[in,out] rstr CeedElemRestriction to destroy 927b11c1e72Sjeremylt 928b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 929dfdf5a53Sjeremylt 9307a982d89SJeremy L. Thompson @ref User 931b11c1e72Sjeremylt **/ 9324ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 933393ac2cdSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || --(*rstr)->ref_count > 0) { 934ad6481ceSJeremy L Thompson *rstr = NULL; 935ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 936ad6481ceSJeremy L Thompson } 9376574a04fSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, (*rstr)->ceed, CEED_ERROR_ACCESS, 9386574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 939*c17ec2beSJeremy L Thompson 940*c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy 941*c17ec2beSJeremy L Thompson if ((*rstr)->rstr_signed) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_signed)); 942*c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 943*c17ec2beSJeremy L Thompson 9442b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 9452b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 9462b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 947e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 948d7b241e6Sjeremylt } 949d7b241e6Sjeremylt 950d7b241e6Sjeremylt /// @} 951