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> 9*2b730f8bSJeremy L Thompson #include <ceed/backend.h> 10*2b730f8bSJeremy L Thompson #include <ceed/ceed.h> 113d576824SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdio.h> 13d7b241e6Sjeremylt 147a982d89SJeremy L. Thompson /// @file 157a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces 167a982d89SJeremy L. Thompson 177a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 187a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions 197a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 207a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper 217a982d89SJeremy L. Thompson /// @{ 227a982d89SJeremy L. Thompson 237a982d89SJeremy L. Thompson /** 24d979a051Sjeremylt @brief Permute and pad offsets for a blocked restriction 257a982d89SJeremy L. Thompson 26d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 27d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 287a982d89SJeremy L. Thompson for the unknowns corresponding to element i, where 29d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 30d1d35e2fSjeremylt [0, @a l_size - 1]. 31d1d35e2fSjeremylt @param blk_offsets Array of permuted and padded offsets of 32d1d35e2fSjeremylt shape [@a num_blk, @a elem_size, @a blk_size]. 33d1d35e2fSjeremylt @param num_blk Number of blocks 34d1d35e2fSjeremylt @param num_elem Number of elements 35d1d35e2fSjeremylt @param blk_size Number of elements in a block 36d1d35e2fSjeremylt @param elem_size Size of each element 377a982d89SJeremy L. Thompson 387a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 397a982d89SJeremy L. Thompson 407a982d89SJeremy L. Thompson @ref Utility 417a982d89SJeremy L. Thompson **/ 42*2b730f8bSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, CeedInt elem_size) { 43*2b730f8bSJeremy L Thompson for (CeedInt e = 0; e < num_blk * blk_size; e += blk_size) { 44*2b730f8bSJeremy L Thompson for (CeedInt j = 0; j < blk_size; j++) { 45*2b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) { 46*2b730f8bSJeremy L Thompson blk_offsets[e * elem_size + k * blk_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k]; 47*2b730f8bSJeremy L Thompson } 48*2b730f8bSJeremy L Thompson } 49*2b730f8bSJeremy L Thompson } 50e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 517a982d89SJeremy L. Thompson } 527a982d89SJeremy L. Thompson 537a982d89SJeremy L. Thompson /// @} 547a982d89SJeremy L. Thompson 557a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 567a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API 577a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 587a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend 597a982d89SJeremy L. Thompson /// @{ 607a982d89SJeremy L. Thompson 617a982d89SJeremy L. Thompson /** 62a681ae63Sjeremylt 63a681ae63Sjeremylt @brief Get the strides of a strided CeedElemRestriction 647a982d89SJeremy L. Thompson 657a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 66a681ae63Sjeremylt @param[out] strides Variable to store strides array 677a982d89SJeremy L. Thompson 687a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 697a982d89SJeremy L. Thompson 707a982d89SJeremy L. Thompson @ref Backend 717a982d89SJeremy L. Thompson **/ 72*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt (*strides)[3]) { 73*2b730f8bSJeremy L Thompson if (!rstr->strides) { 74a681ae63Sjeremylt // LCOV_EXCL_START 75*2b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 76a681ae63Sjeremylt // LCOV_EXCL_STOP 77*2b730f8bSJeremy L Thompson } 78a681ae63Sjeremylt 79*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*strides)[i] = rstr->strides[i]; 80e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 817a982d89SJeremy L. Thompson } 827a982d89SJeremy L. Thompson 837a982d89SJeremy L. Thompson /** 84bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 85bd33150aSjeremylt 86bd33150aSjeremylt @param rstr CeedElemRestriction to retrieve offsets 87d1d35e2fSjeremylt @param mem_type Memory type on which to access the array. If the backend 88bd33150aSjeremylt uses a different memory type, this will perform a copy 89bd33150aSjeremylt (possibly cached). 90d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 91bd33150aSjeremylt 92bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 93bd33150aSjeremylt 94bd33150aSjeremylt @ref User 95bd33150aSjeremylt **/ 96*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 97*2b730f8bSJeremy L Thompson if (!rstr->GetOffsets) { 98bd33150aSjeremylt // LCOV_EXCL_START 99*2b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetOffsets"); 100bd33150aSjeremylt // LCOV_EXCL_STOP 101*2b730f8bSJeremy L Thompson } 102bd33150aSjeremylt 103*2b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets)); 104d1d35e2fSjeremylt rstr->num_readers++; 105e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 106430758c8SJeremy L Thompson } 107430758c8SJeremy L Thompson 108430758c8SJeremy L Thompson /** 109430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 110430758c8SJeremy L Thompson 111430758c8SJeremy L Thompson @param rstr CeedElemRestriction to restore 112430758c8SJeremy L Thompson @param offsets Array of offset data 113430758c8SJeremy L Thompson 114430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 115430758c8SJeremy L Thompson 116430758c8SJeremy L Thompson @ref User 117430758c8SJeremy L Thompson **/ 118*2b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) { 119430758c8SJeremy L Thompson *offsets = NULL; 120d1d35e2fSjeremylt rstr->num_readers--; 121e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 122bd33150aSjeremylt } 123bd33150aSjeremylt 124bd33150aSjeremylt /** 1253ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1263ac43b2cSJeremy L Thompson 1273ac43b2cSJeremy L Thompson @param rstr CeedElemRestriction 128d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1293ac43b2cSJeremy L Thompson 1303ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1313ac43b2cSJeremy L Thompson 1323ac43b2cSJeremy L Thompson @ref Backend 1333ac43b2cSJeremy L Thompson **/ 134d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 135d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 136e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1373ac43b2cSJeremy L Thompson } 1383ac43b2cSJeremy L Thompson 1393ac43b2cSJeremy L Thompson /** 140b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 141b435c5a6Srezgarshakeri 142b435c5a6Srezgarshakeri @param rstr CeedElemRestriction 143b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 144b435c5a6Srezgarshakeri 145b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 146b435c5a6Srezgarshakeri 147b435c5a6Srezgarshakeri @ref Backend 148b435c5a6Srezgarshakeri **/ 149b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 150b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 151b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 152b435c5a6Srezgarshakeri } 153b435c5a6Srezgarshakeri 154b435c5a6Srezgarshakeri /** 155a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1567a982d89SJeremy L. Thompson 1577a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 15896b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1597a982d89SJeremy L. Thompson 1607a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1617a982d89SJeremy L. Thompson 1627a982d89SJeremy L. Thompson @ref Backend 1637a982d89SJeremy L. Thompson **/ 164*2b730f8bSJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) { 165*2b730f8bSJeremy L Thompson if (!rstr->strides) { 166a681ae63Sjeremylt // LCOV_EXCL_START 167*2b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no stride data"); 168a681ae63Sjeremylt // LCOV_EXCL_STOP 169*2b730f8bSJeremy L Thompson } 1707a982d89SJeremy L. Thompson 171*2b730f8bSJeremy L Thompson *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 172a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 173e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1747a982d89SJeremy L. Thompson } 1757a982d89SJeremy L. Thompson 1767a982d89SJeremy L. Thompson /** 17749fd234cSJeremy L Thompson 17849fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 17949fd234cSJeremy L Thompson 18049fd234cSJeremy L Thompson @param rstr CeedElemRestriction 18149fd234cSJeremy L Thompson @param[out] layout Variable to store layout array, 18249fd234cSJeremy L Thompson stored as [nodes, components, elements]. 18349fd234cSJeremy L Thompson The data for node i, component j, element k in the 18449fd234cSJeremy L Thompson E-vector is given by 18595e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 18649fd234cSJeremy L Thompson 18749fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 18849fd234cSJeremy L Thompson 18949fd234cSJeremy L Thompson @ref Backend 19049fd234cSJeremy L Thompson **/ 191*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt (*layout)[3]) { 192*2b730f8bSJeremy L Thompson if (!rstr->layout[0]) { 19349fd234cSJeremy L Thompson // LCOV_EXCL_START 194*2b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, "ElemRestriction has no layout data"); 19549fd234cSJeremy L Thompson // LCOV_EXCL_STOP 196*2b730f8bSJeremy L Thompson } 19749fd234cSJeremy L Thompson 198*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*layout)[i] = rstr->layout[i]; 199e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 20049fd234cSJeremy L Thompson } 20149fd234cSJeremy L Thompson 20249fd234cSJeremy L Thompson /** 20349fd234cSJeremy L Thompson 20449fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 20549fd234cSJeremy L Thompson 20649fd234cSJeremy L Thompson @param rstr CeedElemRestriction 20749fd234cSJeremy L Thompson @param layout Variable to containing layout array, 20849fd234cSJeremy L Thompson stored as [nodes, components, elements]. 20949fd234cSJeremy L Thompson The data for node i, component j, element k in the 21049fd234cSJeremy L Thompson E-vector is given by 21195e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 21249fd234cSJeremy L Thompson 21349fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 21449fd234cSJeremy L Thompson 21549fd234cSJeremy L Thompson @ref Backend 21649fd234cSJeremy L Thompson **/ 217*2b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) { 218*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->layout[i] = layout[i]; 219e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 22049fd234cSJeremy L Thompson } 22149fd234cSJeremy L Thompson 22249fd234cSJeremy L Thompson /** 2237a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2247a982d89SJeremy L. Thompson 2257a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 2267a982d89SJeremy L. Thompson @param[out] data Variable to store data 2277a982d89SJeremy L. Thompson 2287a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2297a982d89SJeremy L. Thompson 2307a982d89SJeremy L. Thompson @ref Backend 2317a982d89SJeremy L. Thompson **/ 232777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 233777ff853SJeremy L Thompson *(void **)data = rstr->data; 234e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2357a982d89SJeremy L. Thompson } 2367a982d89SJeremy L. Thompson 2377a982d89SJeremy L. Thompson /** 2387a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2397a982d89SJeremy L. Thompson 2407a982d89SJeremy L. Thompson @param[out] rstr CeedElemRestriction 2417a982d89SJeremy L. Thompson @param data Data to set 2427a982d89SJeremy L. Thompson 2437a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2447a982d89SJeremy L. Thompson 2457a982d89SJeremy L. Thompson @ref Backend 2467a982d89SJeremy L. Thompson **/ 247777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 248777ff853SJeremy L Thompson rstr->data = data; 249e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2507a982d89SJeremy L. Thompson } 2517a982d89SJeremy L. Thompson 25234359f16Sjeremylt /** 25334359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 25434359f16Sjeremylt 25534359f16Sjeremylt @param rstr ElemRestriction to increment the reference counter 25634359f16Sjeremylt 25734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 25834359f16Sjeremylt 25934359f16Sjeremylt @ref Backend 26034359f16Sjeremylt **/ 2619560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 26234359f16Sjeremylt rstr->ref_count++; 26334359f16Sjeremylt return CEED_ERROR_SUCCESS; 26434359f16Sjeremylt } 26534359f16Sjeremylt 2666e15d496SJeremy L Thompson /** 2676e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 2686e15d496SJeremy L Thompson 2696e15d496SJeremy L Thompson @param rstr ElemRestriction to estimate FLOPs for 2706e15d496SJeremy L Thompson @param t_mode Apply restriction or transpose 2716e15d496SJeremy L Thompson @param flops Address of variable to hold FLOPs estimate 2726e15d496SJeremy L Thompson 2736e15d496SJeremy L Thompson @ref Backend 2746e15d496SJeremy L Thompson **/ 275*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) { 2766e15d496SJeremy L Thompson bool is_oriented; 277*2b730f8bSJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp, scale = 0; 2786e15d496SJeremy L Thompson 279*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionIsOriented(rstr, &is_oriented)); 2806e15d496SJeremy L Thompson switch (t_mode) { 281*2b730f8bSJeremy L Thompson case CEED_NOTRANSPOSE: 282*2b730f8bSJeremy L Thompson scale = is_oriented ? 1 : 0; 283*2b730f8bSJeremy L Thompson break; 284*2b730f8bSJeremy L Thompson case CEED_TRANSPOSE: 285*2b730f8bSJeremy L Thompson scale = is_oriented ? 2 : 1; 286*2b730f8bSJeremy L Thompson break; 2876e15d496SJeremy L Thompson } 2886e15d496SJeremy L Thompson *flops = e_size * scale; 2896e15d496SJeremy L Thompson 2906e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 2916e15d496SJeremy L Thompson } 2926e15d496SJeremy L Thompson 2937a982d89SJeremy L. Thompson /// @} 2947a982d89SJeremy L. Thompson 29515910d16Sjeremylt /// @cond DOXYGEN_SKIP 29615910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 29715910d16Sjeremylt /// @endcond 29815910d16Sjeremylt 2997a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3007a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 3017a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3027a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 303d7b241e6Sjeremylt /// @{ 304d7b241e6Sjeremylt 3057a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 30645f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 3077a982d89SJeremy L. Thompson 3084cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 309*2b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none; 3107a982d89SJeremy L. Thompson 311d7b241e6Sjeremylt /** 312b11c1e72Sjeremylt @brief Create a CeedElemRestriction 313d7b241e6Sjeremylt 314b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 315d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array 316d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 317d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 31895bb1877Svaleriabarra (1 for scalar fields) 319d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 32095e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 32195e93d34SJeremy L Thompson the L-vector at index 322d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 323d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 324d979a051Sjeremylt the elements and fields given by this restriction. 325d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 326d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 327d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 328d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3298795c945Sjeremylt for the unknowns corresponding to element i, where 330d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 331d1d35e2fSjeremylt [0, @a l_size - 1]. 3324ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 333b11c1e72Sjeremylt CeedElemRestriction will be stored 334d7b241e6Sjeremylt 335b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 336dfdf5a53Sjeremylt 3377a982d89SJeremy L. Thompson @ref User 338b11c1e72Sjeremylt **/ 339*2b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 340*2b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) { 3415fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3425fe0d4faSjeremylt Ceed delegate; 343*2b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 3445fe0d4faSjeremylt 345*2b730f8bSJeremy L Thompson if (!delegate) { 346c042f62fSJeremy L Thompson // LCOV_EXCL_START 347*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreate"); 348c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 349*2b730f8bSJeremy L Thompson } 3505fe0d4faSjeremylt 351*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 352e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3535fe0d4faSjeremylt } 3545fe0d4faSjeremylt 355*2b730f8bSJeremy L Thompson if (elem_size < 1) { 356e022e1f8SJeremy L Thompson // LCOV_EXCL_START 357*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 358e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 359*2b730f8bSJeremy L Thompson } 360e022e1f8SJeremy L Thompson 361*2b730f8bSJeremy L Thompson if (num_comp < 1) { 362e022e1f8SJeremy L Thompson // LCOV_EXCL_START 363*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 364e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 365*2b730f8bSJeremy L Thompson } 366e022e1f8SJeremy L Thompson 367*2b730f8bSJeremy L Thompson if (num_comp > 1 && comp_stride < 1) { 368e022e1f8SJeremy L Thompson // LCOV_EXCL_START 369*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 370e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 371*2b730f8bSJeremy L Thompson } 372e022e1f8SJeremy L Thompson 373*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 3744ce2993fSjeremylt (*rstr)->ceed = ceed; 375*2b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 376d1d35e2fSjeremylt (*rstr)->ref_count = 1; 377d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 378d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 379d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 380d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 381d1d35e2fSjeremylt (*rstr)->l_size = l_size; 382d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 383d1d35e2fSjeremylt (*rstr)->blk_size = 1; 384b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 385*2b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr)); 386e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 387d7b241e6Sjeremylt } 388d7b241e6Sjeremylt 389d7b241e6Sjeremylt /** 390fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 391fc0567d9Srezgarshakeri 392fc0567d9Srezgarshakeri @param ceed A Ceed object where the CeedElemRestriction will be created 393fc0567d9Srezgarshakeri @param num_elem Number of elements described in the @a offsets array 394fc0567d9Srezgarshakeri @param elem_size Size (number of "nodes") per element 395fc0567d9Srezgarshakeri @param num_comp Number of field components per interpolation node 396fc0567d9Srezgarshakeri (1 for scalar fields) 397fc0567d9Srezgarshakeri @param comp_stride Stride between components for the same L-vector "node". 398fc0567d9Srezgarshakeri Data for node i, component j, element k can be found in 399fc0567d9Srezgarshakeri the L-vector at index 400fc0567d9Srezgarshakeri offsets[i + k*elem_size] + j*comp_stride. 401fc0567d9Srezgarshakeri @param l_size The size of the L-vector. This vector may be larger than 402fc0567d9Srezgarshakeri the elements and fields given by this restriction. 403fc0567d9Srezgarshakeri @param mem_type Memory type of the @a offsets array, see CeedMemType 404fc0567d9Srezgarshakeri @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 405fc0567d9Srezgarshakeri @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 406fc0567d9Srezgarshakeri ordered list of the offsets (into the input CeedVector) 407fc0567d9Srezgarshakeri for the unknowns corresponding to element i, where 408fc0567d9Srezgarshakeri 0 <= i < @a num_elem. All offsets must be in the range 409fc0567d9Srezgarshakeri [0, @a l_size - 1]. 410fc0567d9Srezgarshakeri @param orient Array of shape [@a num_elem, @a elem_size] with bool false 411fc0567d9Srezgarshakeri for positively oriented and true to flip the orientation. 412fc0567d9Srezgarshakeri @param[out] rstr Address of the variable where the newly created 413fc0567d9Srezgarshakeri CeedElemRestriction will be stored 414fc0567d9Srezgarshakeri 415fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 416fc0567d9Srezgarshakeri 417fc0567d9Srezgarshakeri @ref User 418fc0567d9Srezgarshakeri **/ 419*2b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size, 420*2b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orient, 421fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 422c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 423fc0567d9Srezgarshakeri Ceed delegate; 424*2b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 425fc0567d9Srezgarshakeri 426*2b730f8bSJeremy L Thompson if (!delegate) { 427fc0567d9Srezgarshakeri // LCOV_EXCL_START 428*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement ElemRestrictionCreateOriented"); 429fc0567d9Srezgarshakeri // LCOV_EXCL_STOP 430*2b730f8bSJeremy L Thompson } 431fc0567d9Srezgarshakeri 432*2b730f8bSJeremy L Thompson CeedCall( 433*2b730f8bSJeremy L Thompson CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orient, rstr)); 434fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 435fc0567d9Srezgarshakeri } 436fc0567d9Srezgarshakeri 437*2b730f8bSJeremy L Thompson if (elem_size < 1) { 438e022e1f8SJeremy L Thompson // LCOV_EXCL_START 439*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 440e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 441*2b730f8bSJeremy L Thompson } 442e022e1f8SJeremy L Thompson 443*2b730f8bSJeremy L Thompson if (num_comp < 1) { 444e022e1f8SJeremy L Thompson // LCOV_EXCL_START 445*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 446e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 447*2b730f8bSJeremy L Thompson } 448e022e1f8SJeremy L Thompson 449*2b730f8bSJeremy L Thompson if (num_comp > 1 && comp_stride < 1) { 450e022e1f8SJeremy L Thompson // LCOV_EXCL_START 451*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 452e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 453*2b730f8bSJeremy L Thompson } 454e022e1f8SJeremy L Thompson 455*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 456fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 457*2b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 458fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 459fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 460fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 461fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 462fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 463fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 464fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 465fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 466b435c5a6Srezgarshakeri (*rstr)->is_oriented = 1; 467*2b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, offsets, orient, *rstr)); 468fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 469fc0567d9Srezgarshakeri } 470fc0567d9Srezgarshakeri 471fc0567d9Srezgarshakeri /** 4727509a596Sjeremylt @brief Create a strided CeedElemRestriction 473d7b241e6Sjeremylt 474b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 475d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 476d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 477d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 47895bb1877Svaleriabarra (1 for scalar fields) 479d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 480d979a051Sjeremylt the elements and fields given by this restriction. 4817509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 48295e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 48395e93d34SJeremy L Thompson the L-vector at index 48495e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 48595e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 48695e93d34SJeremy L Thompson by a Ceed backend. 4874ce2993fSjeremylt @param rstr Address of the variable where the newly created 488b11c1e72Sjeremylt CeedElemRestriction will be stored 489d7b241e6Sjeremylt 490b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 491dfdf5a53Sjeremylt 4927a982d89SJeremy L. Thompson @ref User 493b11c1e72Sjeremylt **/ 494*2b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3], 495f90c8643Sjeremylt CeedElemRestriction *rstr) { 4965fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4975fe0d4faSjeremylt Ceed delegate; 498*2b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 4995fe0d4faSjeremylt 500*2b730f8bSJeremy L Thompson if (!delegate) { 501c042f62fSJeremy L Thompson // LCOV_EXCL_START 502*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreate"); 503c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 504*2b730f8bSJeremy L Thompson } 5055fe0d4faSjeremylt 506*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr)); 507e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5085fe0d4faSjeremylt } 5095fe0d4faSjeremylt 510*2b730f8bSJeremy L Thompson if (elem_size < 1) { 511e022e1f8SJeremy L Thompson // LCOV_EXCL_START 512*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 513e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 514*2b730f8bSJeremy L Thompson } 515e022e1f8SJeremy L Thompson 516*2b730f8bSJeremy L Thompson if (num_comp < 1) { 517e022e1f8SJeremy L Thompson // LCOV_EXCL_START 518*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 519e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 520*2b730f8bSJeremy L Thompson } 521e022e1f8SJeremy L Thompson 522*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 5234ce2993fSjeremylt (*rstr)->ceed = ceed; 524*2b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 525d1d35e2fSjeremylt (*rstr)->ref_count = 1; 526d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 527d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 528d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 529d1d35e2fSjeremylt (*rstr)->l_size = l_size; 530d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 531d1d35e2fSjeremylt (*rstr)->blk_size = 1; 532b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 533*2b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 534*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 535*2b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 536e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 537d7b241e6Sjeremylt } 538d7b241e6Sjeremylt 539d7b241e6Sjeremylt /** 540b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 541d7b241e6Sjeremylt 542d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 543d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 544d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 545d1d35e2fSjeremylt @param blk_size Number of elements in a block 546d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 54795bb1877Svaleriabarra (1 for scalar fields) 548d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 54995e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 55095e93d34SJeremy L Thompson the L-vector at index 551d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 552d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 553d979a051Sjeremylt the elements and fields given by this restriction. 554d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 555d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 556d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 557d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 5588795c945Sjeremylt for the unknowns corresponding to element i, where 559d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 560d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 5618795c945Sjeremylt array to the desired ordering for the blocksize, which is 5628795c945Sjeremylt typically given by the backend. The default reordering is 5638795c945Sjeremylt to interlace elements. 5644ce2993fSjeremylt @param rstr Address of the variable where the newly created 565b11c1e72Sjeremylt CeedElemRestriction will be stored 566d7b241e6Sjeremylt 567b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 568dfdf5a53Sjeremylt 5697a982d89SJeremy L. Thompson @ref Backend 570b11c1e72Sjeremylt **/ 571*2b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride, 572*2b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, 5734ce2993fSjeremylt CeedElemRestriction *rstr) { 574d1d35e2fSjeremylt CeedInt *blk_offsets; 575d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 576d7b241e6Sjeremylt 5775fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5785fe0d4faSjeremylt Ceed delegate; 579*2b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 5805fe0d4faSjeremylt 581*2b730f8bSJeremy L Thompson if (!delegate) { 582c042f62fSJeremy L Thompson // LCOV_EXCL_START 583*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateBlocked"); 584c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 585*2b730f8bSJeremy L Thompson } 5865fe0d4faSjeremylt 587*2b730f8bSJeremy L Thompson CeedCall( 588*2b730f8bSJeremy L Thompson CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr)); 589e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5905fe0d4faSjeremylt } 591d7b241e6Sjeremylt 592*2b730f8bSJeremy L Thompson if (elem_size < 1) { 593e022e1f8SJeremy L Thompson // LCOV_EXCL_START 594*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 595e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 596*2b730f8bSJeremy L Thompson } 597e022e1f8SJeremy L Thompson 598*2b730f8bSJeremy L Thompson if (blk_size < 1) { 599e022e1f8SJeremy L Thompson // LCOV_EXCL_START 600*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 601e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 602*2b730f8bSJeremy L Thompson } 603e022e1f8SJeremy L Thompson 604*2b730f8bSJeremy L Thompson if (num_comp < 1) { 605e022e1f8SJeremy L Thompson // LCOV_EXCL_START 606*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 607e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 608*2b730f8bSJeremy L Thompson } 609e022e1f8SJeremy L Thompson 610*2b730f8bSJeremy L Thompson if (num_comp > 1 && comp_stride < 1) { 611e022e1f8SJeremy L Thompson // LCOV_EXCL_START 612*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction component stride must be at least 1"); 613e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 614*2b730f8bSJeremy L Thompson } 615e022e1f8SJeremy L Thompson 616*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 617d7b241e6Sjeremylt 618*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(num_blk * blk_size * elem_size, &blk_offsets)); 619*2b730f8bSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, elem_size)); 620d7b241e6Sjeremylt 6214ce2993fSjeremylt (*rstr)->ceed = ceed; 622*2b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 623d1d35e2fSjeremylt (*rstr)->ref_count = 1; 624d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 625d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 626d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 627d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 628d1d35e2fSjeremylt (*rstr)->l_size = l_size; 629d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 630d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 631b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 632*2b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)blk_offsets, *rstr)); 633d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 634*2b730f8bSJeremy L Thompson CeedCall(CeedFree(&offsets)); 6351d102b48SJeremy L Thompson } 636e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 637d7b241e6Sjeremylt } 638d7b241e6Sjeremylt 639b11c1e72Sjeremylt /** 6407509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 6417509a596Sjeremylt 6427509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 643d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 644d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 645d1d35e2fSjeremylt @param blk_size Number of elements in a block 646d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 6477509a596Sjeremylt (1 for scalar fields) 648d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 649d979a051Sjeremylt the elements and fields given by this restriction. 6507509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 65195e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 65295e93d34SJeremy L Thompson the L-vector at index 65395e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 65495e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 65595e93d34SJeremy L Thompson by a Ceed backend. 6567509a596Sjeremylt @param rstr Address of the variable where the newly created 6577509a596Sjeremylt CeedElemRestriction will be stored 6587509a596Sjeremylt 6597509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 6607509a596Sjeremylt 6617a982d89SJeremy L. Thompson @ref User 6627509a596Sjeremylt **/ 663*2b730f8bSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 6648621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 665d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 6667509a596Sjeremylt 6677509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6687509a596Sjeremylt Ceed delegate; 669*2b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction")); 6707509a596Sjeremylt 671*2b730f8bSJeremy L Thompson if (!delegate) { 6727509a596Sjeremylt // LCOV_EXCL_START 673*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ElemRestrictionCreateBlocked"); 6747509a596Sjeremylt // LCOV_EXCL_STOP 675*2b730f8bSJeremy L Thompson } 6767509a596Sjeremylt 677*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, blk_size, num_comp, l_size, strides, rstr)); 678e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6797509a596Sjeremylt } 6807509a596Sjeremylt 681*2b730f8bSJeremy L Thompson if (elem_size < 1) { 682e022e1f8SJeremy L Thompson // LCOV_EXCL_START 683*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1"); 684e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 685*2b730f8bSJeremy L Thompson } 686e022e1f8SJeremy L Thompson 687*2b730f8bSJeremy L Thompson if (blk_size < 1) { 688e022e1f8SJeremy L Thompson // LCOV_EXCL_START 689*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1"); 690e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 691*2b730f8bSJeremy L Thompson } 692e022e1f8SJeremy L Thompson 693*2b730f8bSJeremy L Thompson if (num_comp < 1) { 694e022e1f8SJeremy L Thompson // LCOV_EXCL_START 695*2b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_DIMENSION, "ElemRestriction must have at least 1 component"); 696e022e1f8SJeremy L Thompson // LCOV_EXCL_STOP 697*2b730f8bSJeremy L Thompson } 698e022e1f8SJeremy L Thompson 699*2b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr)); 7007509a596Sjeremylt 7017509a596Sjeremylt (*rstr)->ceed = ceed; 702*2b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 703d1d35e2fSjeremylt (*rstr)->ref_count = 1; 704d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 705d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 706d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 707d1d35e2fSjeremylt (*rstr)->l_size = l_size; 708d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 709d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 710b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 711*2b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides)); 712*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i]; 713*2b730f8bSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, *rstr)); 714e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7157509a596Sjeremylt } 7167509a596Sjeremylt 7177509a596Sjeremylt /** 7189560d06aSjeremylt @brief Copy the pointer to a CeedElemRestriction. Both pointers should 7199560d06aSjeremylt be destroyed with `CeedElemRestrictionDestroy()`; 7209560d06aSjeremylt Note: If `*rstr_copy` is non-NULL, then it is assumed that 7219560d06aSjeremylt `*rstr_copy` is a pointer to a CeedElemRestriction. This 7229560d06aSjeremylt CeedElemRestriction will be destroyed if `*rstr_copy` is the 7239560d06aSjeremylt only reference to this CeedElemRestriction. 7249560d06aSjeremylt 7259560d06aSjeremylt @param rstr CeedElemRestriction to copy reference to 7269560d06aSjeremylt @param[out] rstr_copy Variable to store copied reference 7279560d06aSjeremylt 7289560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7299560d06aSjeremylt 7309560d06aSjeremylt @ref User 7319560d06aSjeremylt **/ 732*2b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) { 733*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionReference(rstr)); 734*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy)); 7359560d06aSjeremylt *rstr_copy = rstr; 7369560d06aSjeremylt return CEED_ERROR_SUCCESS; 7379560d06aSjeremylt } 7389560d06aSjeremylt 7399560d06aSjeremylt /** 740b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 741b11c1e72Sjeremylt 7424ce2993fSjeremylt @param rstr CeedElemRestriction 743d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 744d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 745b11c1e72Sjeremylt 746b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 747dfdf5a53Sjeremylt 7487a982d89SJeremy L. Thompson @ref User 749b11c1e72Sjeremylt **/ 750*2b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) { 751d2643443SJeremy L Thompson CeedSize e_size, l_size; 752d1d35e2fSjeremylt l_size = rstr->l_size; 753d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 754*2b730f8bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(rstr->ceed, l_size, l_vec)); 755*2b730f8bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(rstr->ceed, e_size, e_vec)); 756e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 757d7b241e6Sjeremylt } 758d7b241e6Sjeremylt 759d7b241e6Sjeremylt /** 760d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 761d7b241e6Sjeremylt 7624ce2993fSjeremylt @param rstr CeedElemRestriction 763d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 764d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 765d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 766d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7677aaeacdcSjeremylt by the backend. 7684cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 769b11c1e72Sjeremylt 770b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 771dfdf5a53Sjeremylt 7727a982d89SJeremy L. Thompson @ref User 773b11c1e72Sjeremylt **/ 774*2b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) { 775d7b241e6Sjeremylt CeedInt m, n; 776d7b241e6Sjeremylt 777d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 778d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 779d1d35e2fSjeremylt n = rstr->l_size; 780d7b241e6Sjeremylt } else { 781d1d35e2fSjeremylt m = rstr->l_size; 782d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 783d7b241e6Sjeremylt } 784*2b730f8bSJeremy L Thompson if (n != u->length) { 785c042f62fSJeremy L Thompson // LCOV_EXCL_START 786e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 787*2b730f8bSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, 788*2b730f8bSJeremy L Thompson n); 789c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 79052b3e6a7SJed Brown } 791*2b730f8bSJeremy L Thompson if (m != ru->length) { 792*2b730f8bSJeremy L Thompson // LCOV_EXCL_START 793*2b730f8bSJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 794*2b730f8bSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, 795*2b730f8bSJeremy L Thompson m, n); 796*2b730f8bSJeremy L Thompson // LCOV_EXCL_STOP 797*2b730f8bSJeremy L Thompson } 798*2b730f8bSJeremy L Thompson if (rstr->num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request)); 799e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 800d7b241e6Sjeremylt } 801d7b241e6Sjeremylt 802d7b241e6Sjeremylt /** 803d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 804be9261b7Sjeremylt 805be9261b7Sjeremylt @param rstr CeedElemRestriction 8061f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 807d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 808d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 809d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 810d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 811d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 812d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 8137aaeacdcSjeremylt by the backend. 8144cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 815be9261b7Sjeremylt 816be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 817be9261b7Sjeremylt 8187a982d89SJeremy L. Thompson @ref Backend 819be9261b7Sjeremylt **/ 820*2b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, 821*2b730f8bSJeremy L Thompson CeedRequest *request) { 822be9261b7Sjeremylt CeedInt m, n; 823be9261b7Sjeremylt 824d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 825d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 826d1d35e2fSjeremylt n = rstr->l_size; 827be9261b7Sjeremylt } else { 828d1d35e2fSjeremylt m = rstr->l_size; 829d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 830be9261b7Sjeremylt } 831*2b730f8bSJeremy L Thompson if (n != u->length) { 832c042f62fSJeremy L Thompson // LCOV_EXCL_START 833e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 834*2b730f8bSJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", u->length, m, 835*2b730f8bSJeremy L Thompson n); 836c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 837*2b730f8bSJeremy L Thompson } 838*2b730f8bSJeremy L Thompson if (m != ru->length) { 839c042f62fSJeremy L Thompson // LCOV_EXCL_START 840e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 841*2b730f8bSJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", ru->length, 842*2b730f8bSJeremy L Thompson m, n); 843c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 844*2b730f8bSJeremy L Thompson } 845*2b730f8bSJeremy L Thompson if (rstr->blk_size * block > rstr->num_elem) { 846c042f62fSJeremy L Thompson // LCOV_EXCL_START 847e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 848*2b730f8bSJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, 849*2b730f8bSJeremy L Thompson rstr->blk_size * block, rstr->num_elem); 850c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 851*2b730f8bSJeremy L Thompson } 852*2b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request)); 853e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 854be9261b7Sjeremylt } 855be9261b7Sjeremylt 856be9261b7Sjeremylt /** 857b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 858b7c9bbdaSJeremy L Thompson 859b7c9bbdaSJeremy L Thompson @param rstr CeedElemRestriction 860b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 861b7c9bbdaSJeremy L Thompson 862b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 863b7c9bbdaSJeremy L Thompson 864b7c9bbdaSJeremy L Thompson @ref Advanced 865b7c9bbdaSJeremy L Thompson **/ 866b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 867b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 868b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 869b7c9bbdaSJeremy L Thompson } 870b7c9bbdaSJeremy L Thompson 871b7c9bbdaSJeremy L Thompson /** 872d979a051Sjeremylt @brief Get the L-vector component stride 873a681ae63Sjeremylt 874a681ae63Sjeremylt @param rstr CeedElemRestriction 875d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 876a681ae63Sjeremylt 877a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 878a681ae63Sjeremylt 879b7c9bbdaSJeremy L Thompson @ref Advanced 880a681ae63Sjeremylt **/ 881*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) { 882d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 883e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 884a681ae63Sjeremylt } 885a681ae63Sjeremylt 886a681ae63Sjeremylt /** 887a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 888a681ae63Sjeremylt 889a681ae63Sjeremylt @param rstr CeedElemRestriction 890d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 891a681ae63Sjeremylt 892a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 893a681ae63Sjeremylt 894b7c9bbdaSJeremy L Thompson @ref Advanced 895a681ae63Sjeremylt **/ 896*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) { 897d1d35e2fSjeremylt *num_elem = rstr->num_elem; 898e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 899a681ae63Sjeremylt } 900a681ae63Sjeremylt 901a681ae63Sjeremylt /** 902a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 903a681ae63Sjeremylt 904a681ae63Sjeremylt @param rstr CeedElemRestriction 905d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 906a681ae63Sjeremylt 907a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 908a681ae63Sjeremylt 909b7c9bbdaSJeremy L Thompson @ref Advanced 910a681ae63Sjeremylt **/ 911*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) { 912d1d35e2fSjeremylt *elem_size = rstr->elem_size; 913e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 914a681ae63Sjeremylt } 915a681ae63Sjeremylt 916a681ae63Sjeremylt /** 917d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 918a681ae63Sjeremylt 919a681ae63Sjeremylt @param rstr CeedElemRestriction 920d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 921a681ae63Sjeremylt 922a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 923a681ae63Sjeremylt 924b7c9bbdaSJeremy L Thompson @ref Advanced 925a681ae63Sjeremylt **/ 926*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) { 927d1d35e2fSjeremylt *l_size = rstr->l_size; 928e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 929a681ae63Sjeremylt } 930a681ae63Sjeremylt 931a681ae63Sjeremylt /** 932a681ae63Sjeremylt @brief Get the number of components in the elements of a 933a681ae63Sjeremylt CeedElemRestriction 934a681ae63Sjeremylt 935a681ae63Sjeremylt @param rstr CeedElemRestriction 936d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 937a681ae63Sjeremylt 938a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 939a681ae63Sjeremylt 940b7c9bbdaSJeremy L Thompson @ref Advanced 941a681ae63Sjeremylt **/ 942*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) { 943d1d35e2fSjeremylt *num_comp = rstr->num_comp; 944e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 945a681ae63Sjeremylt } 946a681ae63Sjeremylt 947a681ae63Sjeremylt /** 948a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 949a681ae63Sjeremylt 950a681ae63Sjeremylt @param rstr CeedElemRestriction 951d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 952a681ae63Sjeremylt 953a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 954a681ae63Sjeremylt 955b7c9bbdaSJeremy L Thompson @ref Advanced 956a681ae63Sjeremylt **/ 957*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) { 958d1d35e2fSjeremylt *num_block = rstr->num_blk; 959e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 960a681ae63Sjeremylt } 961a681ae63Sjeremylt 962a681ae63Sjeremylt /** 963a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 964a681ae63Sjeremylt 965a681ae63Sjeremylt @param rstr CeedElemRestriction 966d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 967a681ae63Sjeremylt 968a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 969a681ae63Sjeremylt 970b7c9bbdaSJeremy L Thompson @ref Advanced 971a681ae63Sjeremylt **/ 972*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *blk_size) { 973d1d35e2fSjeremylt *blk_size = rstr->blk_size; 974e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 975a681ae63Sjeremylt } 976a681ae63Sjeremylt 977a681ae63Sjeremylt /** 978d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 9791469ee4dSjeremylt 9801469ee4dSjeremylt @param rstr CeedElemRestriction 981d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 9821469ee4dSjeremylt 9831469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 9841469ee4dSjeremylt 9857a982d89SJeremy L. Thompson @ref User 9861469ee4dSjeremylt **/ 987*2b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) { 988d1d35e2fSjeremylt CeedVector e_vec; 9891469ee4dSjeremylt 99025509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 991*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec)); 9921469ee4dSjeremylt 99325509ebbSRezgar Shakeri // Compute e_vec = E * 1 994*2b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0)); 995*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE)); 99625509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 997*2b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0)); 998*2b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE)); 9991469ee4dSjeremylt // Cleanup 1000*2b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec)); 1001e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10021469ee4dSjeremylt } 10031469ee4dSjeremylt 10041469ee4dSjeremylt /** 1005f02ca4a2SJed Brown @brief View a CeedElemRestriction 1006f02ca4a2SJed Brown 1007f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 1008f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 1009f02ca4a2SJed Brown 1010f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1011f02ca4a2SJed Brown 10127a982d89SJeremy L. Thompson @ref User 1013f02ca4a2SJed Brown **/ 1014f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 10157509a596Sjeremylt char stridesstr[500]; 1016*2b730f8bSJeremy L Thompson if (rstr->strides) { 1017*2b730f8bSJeremy L Thompson sprintf(stridesstr, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]); 1018*2b730f8bSJeremy L Thompson } else { 1019990fdeb6SJeremy L Thompson sprintf(stridesstr, "%" CeedInt_FMT, rstr->comp_stride); 1020*2b730f8bSJeremy L Thompson } 10217509a596Sjeremylt 1022*2b730f8bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT " nodes each and %s %s\n", 1023*2b730f8bSJeremy L Thompson rstr->blk_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1024d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1025e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1026f02ca4a2SJed Brown } 1027f02ca4a2SJed Brown 1028f02ca4a2SJed Brown /** 1029b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1030b11c1e72Sjeremylt 10314ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 1032b11c1e72Sjeremylt 1033b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1034dfdf5a53Sjeremylt 10357a982d89SJeremy L. Thompson @ref User 1036b11c1e72Sjeremylt **/ 10374ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1038d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 1039*2b730f8bSJeremy L Thompson if ((*rstr)->num_readers) { 10408229195eSjeremylt // LCOV_EXCL_START 1041*2b730f8bSJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, "Cannot destroy CeedElemRestriction, a process has read access to the offset data"); 10428229195eSjeremylt // LCOV_EXCL_STOP 1043d7b241e6Sjeremylt } 1044*2b730f8bSJeremy L Thompson if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr)); 1045*2b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides)); 1046*2b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*rstr)->ceed)); 1047*2b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr)); 1048e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1049d7b241e6Sjeremylt } 1050d7b241e6Sjeremylt 1051d7b241e6Sjeremylt /// @} 1052