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 8ec3da8bcSJed Brown #include <ceed/ceed.h> 9ec3da8bcSJed Brown #include <ceed/backend.h> 103d576824SJeremy L Thompson #include <ceed-impl.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 **/ 42d1d35e2fSjeremylt int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *blk_offsets, 43d1d35e2fSjeremylt CeedInt num_blk, CeedInt num_elem, CeedInt blk_size, 44d1d35e2fSjeremylt CeedInt elem_size) { 45d1d35e2fSjeremylt for (CeedInt e=0; e<num_blk*blk_size; e+=blk_size) 46d1d35e2fSjeremylt for (int j=0; j<blk_size; j++) 47d1d35e2fSjeremylt for (int k=0; k<elem_size; k++) 48d1d35e2fSjeremylt blk_offsets[e*elem_size + k*blk_size + j] 49d1d35e2fSjeremylt = offsets[CeedIntMin(e+j,num_elem-1)*elem_size + k]; 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 **/ 72a681ae63Sjeremylt int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, 73a681ae63Sjeremylt CeedInt (*strides)[3]) { 74a681ae63Sjeremylt if (!rstr->strides) 75a681ae63Sjeremylt // LCOV_EXCL_START 76e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 77e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 78a681ae63Sjeremylt // LCOV_EXCL_STOP 79a681ae63Sjeremylt 80a681ae63Sjeremylt for (int i=0; i<3; i++) 81a681ae63Sjeremylt (*strides)[i] = rstr->strides[i]; 82e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 837a982d89SJeremy L. Thompson } 847a982d89SJeremy L. Thompson 857a982d89SJeremy L. Thompson /** 86bd33150aSjeremylt @brief Get read-only access to a CeedElemRestriction offsets array by memtype 87bd33150aSjeremylt 88bd33150aSjeremylt @param rstr CeedElemRestriction to retrieve offsets 89d1d35e2fSjeremylt @param mem_type Memory type on which to access the array. If the backend 90bd33150aSjeremylt uses a different memory type, this will perform a copy 91bd33150aSjeremylt (possibly cached). 92d1d35e2fSjeremylt @param[out] offsets Array on memory type mem_type 93bd33150aSjeremylt 94bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure 95bd33150aSjeremylt 96bd33150aSjeremylt @ref User 97bd33150aSjeremylt **/ 98d1d35e2fSjeremylt int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, 99d1d35e2fSjeremylt CeedMemType mem_type, 100bd33150aSjeremylt const CeedInt **offsets) { 101bd33150aSjeremylt int ierr; 102bd33150aSjeremylt 103bd33150aSjeremylt if (!rstr->GetOffsets) 104bd33150aSjeremylt // LCOV_EXCL_START 105e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_UNSUPPORTED, 106e15f9bd0SJeremy L Thompson "Backend does not support GetOffsets"); 107bd33150aSjeremylt // LCOV_EXCL_STOP 108bd33150aSjeremylt 109d1d35e2fSjeremylt ierr = rstr->GetOffsets(rstr, mem_type, offsets); CeedChk(ierr); 110d1d35e2fSjeremylt rstr->num_readers++; 111e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 112430758c8SJeremy L Thompson } 113430758c8SJeremy L Thompson 114430758c8SJeremy L Thompson /** 115430758c8SJeremy L Thompson @brief Restore an offsets array obtained using CeedElemRestrictionGetOffsets() 116430758c8SJeremy L Thompson 117430758c8SJeremy L Thompson @param rstr CeedElemRestriction to restore 118430758c8SJeremy L Thompson @param offsets Array of offset data 119430758c8SJeremy L Thompson 120430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 121430758c8SJeremy L Thompson 122430758c8SJeremy L Thompson @ref User 123430758c8SJeremy L Thompson **/ 124430758c8SJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, 125430758c8SJeremy L Thompson const CeedInt **offsets) { 126430758c8SJeremy L Thompson *offsets = NULL; 127d1d35e2fSjeremylt rstr->num_readers--; 128e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 129bd33150aSjeremylt } 130bd33150aSjeremylt 131bd33150aSjeremylt /** 1323ac43b2cSJeremy L Thompson @brief Get the strided status of a CeedElemRestriction 1333ac43b2cSJeremy L Thompson 1343ac43b2cSJeremy L Thompson @param rstr CeedElemRestriction 135d1d35e2fSjeremylt @param[out] is_strided Variable to store strided status, 1 if strided else 0 1363ac43b2cSJeremy L Thompson 1373ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1383ac43b2cSJeremy L Thompson 1393ac43b2cSJeremy L Thompson @ref Backend 1403ac43b2cSJeremy L Thompson **/ 141d1d35e2fSjeremylt int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) { 142d1d35e2fSjeremylt *is_strided = rstr->strides ? true : false; 143e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1443ac43b2cSJeremy L Thompson } 1453ac43b2cSJeremy L Thompson 1463ac43b2cSJeremy L Thompson /** 147b435c5a6Srezgarshakeri @brief Get oriented status of a CeedElemRestriction 148b435c5a6Srezgarshakeri 149b435c5a6Srezgarshakeri @param rstr CeedElemRestriction 150b435c5a6Srezgarshakeri @param[out] is_oriented Variable to store oriented status, 1 if oriented else 0 151b435c5a6Srezgarshakeri 152b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure 153b435c5a6Srezgarshakeri 154b435c5a6Srezgarshakeri @ref Backend 155b435c5a6Srezgarshakeri **/ 156b435c5a6Srezgarshakeri int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) { 157b435c5a6Srezgarshakeri *is_oriented = rstr->is_oriented; 158b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS; 159b435c5a6Srezgarshakeri } 160b435c5a6Srezgarshakeri 161b435c5a6Srezgarshakeri /** 162a681ae63Sjeremylt @brief Get the backend stride status of a CeedElemRestriction 1637a982d89SJeremy L. Thompson 1647a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 16596b902e2Sjeremylt @param[out] has_backend_strides Variable to store stride status 1667a982d89SJeremy L. Thompson 1677a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1687a982d89SJeremy L. Thompson 1697a982d89SJeremy L. Thompson @ref Backend 1707a982d89SJeremy L. Thompson **/ 171fd364f38SJeremy L Thompson int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, 172d1d35e2fSjeremylt bool *has_backend_strides) { 173a681ae63Sjeremylt if (!rstr->strides) 174a681ae63Sjeremylt // LCOV_EXCL_START 175e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 176e15f9bd0SJeremy L Thompson "ElemRestriction has no stride data"); 177a681ae63Sjeremylt // LCOV_EXCL_STOP 1787a982d89SJeremy L. Thompson 179d1d35e2fSjeremylt *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && 180a681ae63Sjeremylt (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) && 181a681ae63Sjeremylt (rstr->strides[2] == CEED_STRIDES_BACKEND[2])); 182e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1837a982d89SJeremy L. Thompson } 1847a982d89SJeremy L. Thompson 1857a982d89SJeremy L. Thompson /** 18649fd234cSJeremy L Thompson 18749fd234cSJeremy L Thompson @brief Get the E-vector layout of a CeedElemRestriction 18849fd234cSJeremy L Thompson 18949fd234cSJeremy L Thompson @param rstr CeedElemRestriction 19049fd234cSJeremy L Thompson @param[out] layout Variable to store layout array, 19149fd234cSJeremy L Thompson stored as [nodes, components, elements]. 19249fd234cSJeremy L Thompson The data for node i, component j, element k in the 19349fd234cSJeremy L Thompson E-vector is given by 19495e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 19549fd234cSJeremy L Thompson 19649fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 19749fd234cSJeremy L Thompson 19849fd234cSJeremy L Thompson @ref Backend 19949fd234cSJeremy L Thompson **/ 20049fd234cSJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, 20149fd234cSJeremy L Thompson CeedInt (*layout)[3]) { 20249fd234cSJeremy L Thompson if (!rstr->layout[0]) 20349fd234cSJeremy L Thompson // LCOV_EXCL_START 204e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_MINOR, 205e15f9bd0SJeremy L Thompson "ElemRestriction has no layout data"); 20649fd234cSJeremy L Thompson // LCOV_EXCL_STOP 20749fd234cSJeremy L Thompson 20849fd234cSJeremy L Thompson for (int i=0; i<3; i++) 20949fd234cSJeremy L Thompson (*layout)[i] = rstr->layout[i]; 210e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 21149fd234cSJeremy L Thompson } 21249fd234cSJeremy L Thompson 21349fd234cSJeremy L Thompson /** 21449fd234cSJeremy L Thompson 21549fd234cSJeremy L Thompson @brief Set the E-vector layout of a CeedElemRestriction 21649fd234cSJeremy L Thompson 21749fd234cSJeremy L Thompson @param rstr CeedElemRestriction 21849fd234cSJeremy L Thompson @param layout Variable to containing layout array, 21949fd234cSJeremy L Thompson stored as [nodes, components, elements]. 22049fd234cSJeremy L Thompson The data for node i, component j, element k in the 22149fd234cSJeremy L Thompson E-vector is given by 22295e93d34SJeremy L Thompson i*layout[0] + j*layout[1] + k*layout[2] 22349fd234cSJeremy L Thompson 22449fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 22549fd234cSJeremy L Thompson 22649fd234cSJeremy L Thompson @ref Backend 22749fd234cSJeremy L Thompson **/ 22849fd234cSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, 22949fd234cSJeremy L Thompson CeedInt layout[3]) { 23049fd234cSJeremy L Thompson for (int i = 0; i<3; i++) 23149fd234cSJeremy L Thompson rstr->layout[i] = layout[i]; 232e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 23349fd234cSJeremy L Thompson } 23449fd234cSJeremy L Thompson 23549fd234cSJeremy L Thompson /** 2367a982d89SJeremy L. Thompson @brief Get the backend data of a CeedElemRestriction 2377a982d89SJeremy L. Thompson 2387a982d89SJeremy L. Thompson @param rstr CeedElemRestriction 2397a982d89SJeremy L. Thompson @param[out] data Variable to store data 2407a982d89SJeremy L. Thompson 2417a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2427a982d89SJeremy L. Thompson 2437a982d89SJeremy L. Thompson @ref Backend 2447a982d89SJeremy L. Thompson **/ 245777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) { 246777ff853SJeremy L Thompson *(void **)data = rstr->data; 247e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2487a982d89SJeremy L. Thompson } 2497a982d89SJeremy L. Thompson 2507a982d89SJeremy L. Thompson /** 2517a982d89SJeremy L. Thompson @brief Set the backend data of a CeedElemRestriction 2527a982d89SJeremy L. Thompson 2537a982d89SJeremy L. Thompson @param[out] rstr CeedElemRestriction 2547a982d89SJeremy L. Thompson @param data Data to set 2557a982d89SJeremy L. Thompson 2567a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2577a982d89SJeremy L. Thompson 2587a982d89SJeremy L. Thompson @ref Backend 2597a982d89SJeremy L. Thompson **/ 260777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) { 261777ff853SJeremy L Thompson rstr->data = data; 262e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2637a982d89SJeremy L. Thompson } 2647a982d89SJeremy L. Thompson 26534359f16Sjeremylt /** 26634359f16Sjeremylt @brief Increment the reference counter for a CeedElemRestriction 26734359f16Sjeremylt 26834359f16Sjeremylt @param rstr ElemRestriction to increment the reference counter 26934359f16Sjeremylt 27034359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 27134359f16Sjeremylt 27234359f16Sjeremylt @ref Backend 27334359f16Sjeremylt **/ 2749560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) { 27534359f16Sjeremylt rstr->ref_count++; 27634359f16Sjeremylt return CEED_ERROR_SUCCESS; 27734359f16Sjeremylt } 27834359f16Sjeremylt 279*6e15d496SJeremy L Thompson /** 280*6e15d496SJeremy L Thompson @brief Estimate number of FLOPs required to apply CeedElemRestriction in t_mode 281*6e15d496SJeremy L Thompson 282*6e15d496SJeremy L Thompson @param rstr ElemRestriction to estimate FLOPs for 283*6e15d496SJeremy L Thompson @param t_mode Apply restriction or transpose 284*6e15d496SJeremy L Thompson @param flops Address of variable to hold FLOPs estimate 285*6e15d496SJeremy L Thompson 286*6e15d496SJeremy L Thompson @ref Backend 287*6e15d496SJeremy L Thompson **/ 288*6e15d496SJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, 289*6e15d496SJeremy L Thompson CeedTransposeMode t_mode, CeedInt *flops) { 290*6e15d496SJeremy L Thompson int ierr; 291*6e15d496SJeremy L Thompson bool is_oriented; 292*6e15d496SJeremy L Thompson CeedInt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * 293*6e15d496SJeremy L Thompson rstr->num_comp, 294*6e15d496SJeremy L Thompson scale = 0; 295*6e15d496SJeremy L Thompson 296*6e15d496SJeremy L Thompson ierr = CeedElemRestrictionIsOriented(rstr, &is_oriented); CeedChk(ierr); 297*6e15d496SJeremy L Thompson switch (t_mode) { 298*6e15d496SJeremy L Thompson case CEED_NOTRANSPOSE: scale = is_oriented ? 1 : 0; break; 299*6e15d496SJeremy L Thompson case CEED_TRANSPOSE: scale = is_oriented ? 2 : 1; break; 300*6e15d496SJeremy L Thompson } 301*6e15d496SJeremy L Thompson *flops = e_size * scale; 302*6e15d496SJeremy L Thompson 303*6e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 304*6e15d496SJeremy L Thompson } 305*6e15d496SJeremy L Thompson 3067a982d89SJeremy L. Thompson /// @} 3077a982d89SJeremy L. Thompson 30815910d16Sjeremylt /// @cond DOXYGEN_SKIP 30915910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 31015910d16Sjeremylt /// @endcond 31115910d16Sjeremylt 3127a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3137a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 3147a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 3157a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 316d7b241e6Sjeremylt /// @{ 317d7b241e6Sjeremylt 3187a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 31945f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 3207a982d89SJeremy L. Thompson 3214cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 3227a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 3237a982d89SJeremy L. Thompson &ceed_elemrestriction_none; 3247a982d89SJeremy L. Thompson 325d7b241e6Sjeremylt /** 326b11c1e72Sjeremylt @brief Create a CeedElemRestriction 327d7b241e6Sjeremylt 328b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 329d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array 330d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 331d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 33295bb1877Svaleriabarra (1 for scalar fields) 333d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 33495e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 33595e93d34SJeremy L Thompson the L-vector at index 336d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 337d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 338d979a051Sjeremylt the elements and fields given by this restriction. 339d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 340d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 341d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 342d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3438795c945Sjeremylt for the unknowns corresponding to element i, where 344d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 345d1d35e2fSjeremylt [0, @a l_size - 1]. 3464ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 347b11c1e72Sjeremylt CeedElemRestriction will be stored 348d7b241e6Sjeremylt 349b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 350dfdf5a53Sjeremylt 3517a982d89SJeremy L. Thompson @ref User 352b11c1e72Sjeremylt **/ 353d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, 354d1d35e2fSjeremylt CeedInt num_comp, CeedInt comp_stride, 355e79b91d9SJeremy L Thompson CeedSize l_size, CeedMemType mem_type, 356d1d35e2fSjeremylt CeedCopyMode copy_mode, const CeedInt *offsets, 3574ce2993fSjeremylt CeedElemRestriction *rstr) { 358d7b241e6Sjeremylt int ierr; 359d7b241e6Sjeremylt 3605fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3615fe0d4faSjeremylt Ceed delegate; 362aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 363aefd8378Sjeremylt CeedChk(ierr); 3645fe0d4faSjeremylt 3655fe0d4faSjeremylt if (!delegate) 366c042f62fSJeremy L Thompson // LCOV_EXCL_START 367e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 368e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 369c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3705fe0d4faSjeremylt 371d1d35e2fSjeremylt ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, 372d1d35e2fSjeremylt comp_stride, l_size, mem_type, copy_mode, 373d979a051Sjeremylt offsets, rstr); CeedChk(ierr); 374e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3755fe0d4faSjeremylt } 3765fe0d4faSjeremylt 3774ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3784ce2993fSjeremylt (*rstr)->ceed = ceed; 3799560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 380d1d35e2fSjeremylt (*rstr)->ref_count = 1; 381d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 382d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 383d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 384d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 385d1d35e2fSjeremylt (*rstr)->l_size = l_size; 386d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 387d1d35e2fSjeremylt (*rstr)->blk_size = 1; 388b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 389d1d35e2fSjeremylt ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr); 390d979a051Sjeremylt CeedChk(ierr); 391e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 392d7b241e6Sjeremylt } 393d7b241e6Sjeremylt 394d7b241e6Sjeremylt /** 395fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 396fc0567d9Srezgarshakeri 397fc0567d9Srezgarshakeri @param ceed A Ceed object where the CeedElemRestriction will be created 398fc0567d9Srezgarshakeri @param num_elem Number of elements described in the @a offsets array 399fc0567d9Srezgarshakeri @param elem_size Size (number of "nodes") per element 400fc0567d9Srezgarshakeri @param num_comp Number of field components per interpolation node 401fc0567d9Srezgarshakeri (1 for scalar fields) 402fc0567d9Srezgarshakeri @param comp_stride Stride between components for the same L-vector "node". 403fc0567d9Srezgarshakeri Data for node i, component j, element k can be found in 404fc0567d9Srezgarshakeri the L-vector at index 405fc0567d9Srezgarshakeri offsets[i + k*elem_size] + j*comp_stride. 406fc0567d9Srezgarshakeri @param l_size The size of the L-vector. This vector may be larger than 407fc0567d9Srezgarshakeri the elements and fields given by this restriction. 408fc0567d9Srezgarshakeri @param mem_type Memory type of the @a offsets array, see CeedMemType 409fc0567d9Srezgarshakeri @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 410fc0567d9Srezgarshakeri @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 411fc0567d9Srezgarshakeri ordered list of the offsets (into the input CeedVector) 412fc0567d9Srezgarshakeri for the unknowns corresponding to element i, where 413fc0567d9Srezgarshakeri 0 <= i < @a num_elem. All offsets must be in the range 414fc0567d9Srezgarshakeri [0, @a l_size - 1]. 415fc0567d9Srezgarshakeri @param orient Array of shape [@a num_elem, @a elem_size] with bool false 416fc0567d9Srezgarshakeri for positively oriented and true to flip the orientation. 417fc0567d9Srezgarshakeri @param[out] rstr Address of the variable where the newly created 418fc0567d9Srezgarshakeri CeedElemRestriction will be stored 419fc0567d9Srezgarshakeri 420fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 421fc0567d9Srezgarshakeri 422fc0567d9Srezgarshakeri @ref User 423fc0567d9Srezgarshakeri **/ 424fc0567d9Srezgarshakeri int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, 425fc0567d9Srezgarshakeri CeedInt elem_size, CeedInt num_comp, 426e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 427fc0567d9Srezgarshakeri CeedMemType mem_type, CeedCopyMode copy_mode, 428fc0567d9Srezgarshakeri const CeedInt *offsets, const bool *orient, 429fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 430fc0567d9Srezgarshakeri int ierr; 431fc0567d9Srezgarshakeri 432c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 433fc0567d9Srezgarshakeri Ceed delegate; 434fc0567d9Srezgarshakeri ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 435fc0567d9Srezgarshakeri CeedChk(ierr); 436fc0567d9Srezgarshakeri 437fc0567d9Srezgarshakeri if (!delegate) 438fc0567d9Srezgarshakeri // LCOV_EXCL_START 439fc0567d9Srezgarshakeri return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 44061e7462cSRezgar Shakeri "Backend does not implement ElemRestrictionCreateOriented"); 441fc0567d9Srezgarshakeri // LCOV_EXCL_STOP 442fc0567d9Srezgarshakeri 443fc0567d9Srezgarshakeri ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, 444c7745053SRezgar Shakeri num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 4454dd06d33Srezgarshakeri orient, rstr); CeedChk(ierr); 446fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 447fc0567d9Srezgarshakeri } 448fc0567d9Srezgarshakeri 449fc0567d9Srezgarshakeri ierr = CeedCalloc(1, rstr); CeedChk(ierr); 450fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 451fc0567d9Srezgarshakeri ierr = CeedReference(ceed); CeedChk(ierr); 452fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 453fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 454fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 455fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 456fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 457fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 458fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 459fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 460b435c5a6Srezgarshakeri (*rstr)->is_oriented = 1; 4614dd06d33Srezgarshakeri ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, 4624dd06d33Srezgarshakeri offsets, orient, *rstr); CeedChk(ierr); 463fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 464fc0567d9Srezgarshakeri } 465fc0567d9Srezgarshakeri 466fc0567d9Srezgarshakeri /** 4677509a596Sjeremylt @brief Create a strided CeedElemRestriction 468d7b241e6Sjeremylt 469b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 470d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 471d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 472d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 47395bb1877Svaleriabarra (1 for scalar fields) 474d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 475d979a051Sjeremylt the elements and fields given by this restriction. 4767509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 47795e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 47895e93d34SJeremy L Thompson the L-vector at index 47995e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 48095e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 48195e93d34SJeremy L Thompson by a Ceed backend. 4824ce2993fSjeremylt @param rstr Address of the variable where the newly created 483b11c1e72Sjeremylt CeedElemRestriction will be stored 484d7b241e6Sjeremylt 485b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 486dfdf5a53Sjeremylt 4877a982d89SJeremy L. Thompson @ref User 488b11c1e72Sjeremylt **/ 489d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, 490d1d35e2fSjeremylt CeedInt elem_size, 491e79b91d9SJeremy L Thompson CeedInt num_comp, CeedSize l_size, 4928621c6c6SJeremy L Thompson const CeedInt strides[3], 493f90c8643Sjeremylt CeedElemRestriction *rstr) { 494d7b241e6Sjeremylt int ierr; 495d7b241e6Sjeremylt 4965fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4975fe0d4faSjeremylt Ceed delegate; 498aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 499aefd8378Sjeremylt CeedChk(ierr); 5005fe0d4faSjeremylt 5015fe0d4faSjeremylt if (!delegate) 502c042f62fSJeremy L Thompson // LCOV_EXCL_START 503e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 504e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 505c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5065fe0d4faSjeremylt 507d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, 508d1d35e2fSjeremylt l_size, strides, rstr); 509d979a051Sjeremylt CeedChk(ierr); 510e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5115fe0d4faSjeremylt } 5125fe0d4faSjeremylt 5134ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 5144ce2993fSjeremylt (*rstr)->ceed = ceed; 5159560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 516d1d35e2fSjeremylt (*rstr)->ref_count = 1; 517d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 518d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 519d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 520d1d35e2fSjeremylt (*rstr)->l_size = l_size; 521d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 522d1d35e2fSjeremylt (*rstr)->blk_size = 1; 523b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 5247509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 5257509a596Sjeremylt for (int i=0; i<3; i++) 5267509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 5271dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 5281dfeef1dSjeremylt *rstr); 5294b8bea3bSJed Brown CeedChk(ierr); 530e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 531d7b241e6Sjeremylt } 532d7b241e6Sjeremylt 533d7b241e6Sjeremylt /** 534b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 535d7b241e6Sjeremylt 536d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 537d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 538d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 539d1d35e2fSjeremylt @param blk_size Number of elements in a block 540d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 54195bb1877Svaleriabarra (1 for scalar fields) 542d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 54395e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 54495e93d34SJeremy L Thompson the L-vector at index 545d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 546d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 547d979a051Sjeremylt the elements and fields given by this restriction. 548d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 549d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 550d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 551d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 5528795c945Sjeremylt for the unknowns corresponding to element i, where 553d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 554d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 5558795c945Sjeremylt array to the desired ordering for the blocksize, which is 5568795c945Sjeremylt typically given by the backend. The default reordering is 5578795c945Sjeremylt to interlace elements. 5584ce2993fSjeremylt @param rstr Address of the variable where the newly created 559b11c1e72Sjeremylt CeedElemRestriction will be stored 560d7b241e6Sjeremylt 561b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 562dfdf5a53Sjeremylt 5637a982d89SJeremy L. Thompson @ref Backend 564b11c1e72Sjeremylt **/ 565d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, 566d1d35e2fSjeremylt CeedInt elem_size, 567d1d35e2fSjeremylt CeedInt blk_size, CeedInt num_comp, 568e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 569d1d35e2fSjeremylt CeedMemType mem_type, CeedCopyMode copy_mode, 570d979a051Sjeremylt const CeedInt *offsets, 5714ce2993fSjeremylt CeedElemRestriction *rstr) { 572d7b241e6Sjeremylt int ierr; 573d1d35e2fSjeremylt CeedInt *blk_offsets; 574d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 575d7b241e6Sjeremylt 5765fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5775fe0d4faSjeremylt Ceed delegate; 578aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 579aefd8378Sjeremylt CeedChk(ierr); 5805fe0d4faSjeremylt 5815fe0d4faSjeremylt if (!delegate) 582c042f62fSJeremy L Thompson // LCOV_EXCL_START 583e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 5841d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 585c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5865fe0d4faSjeremylt 587d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, 588d1d35e2fSjeremylt num_comp, comp_stride, l_size, mem_type, 589d1d35e2fSjeremylt copy_mode, offsets, rstr); 590d979a051Sjeremylt CeedChk(ierr); 591e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5925fe0d4faSjeremylt } 593d7b241e6Sjeremylt 5944ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 595d7b241e6Sjeremylt 596d1d35e2fSjeremylt ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr); 597d1d35e2fSjeremylt ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, 598d1d35e2fSjeremylt elem_size); CeedChk(ierr); 599d7b241e6Sjeremylt 6004ce2993fSjeremylt (*rstr)->ceed = ceed; 6019560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 602d1d35e2fSjeremylt (*rstr)->ref_count = 1; 603d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 604d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 605d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 606d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 607d1d35e2fSjeremylt (*rstr)->l_size = l_size; 608d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 609d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 610b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 611667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 612d1d35e2fSjeremylt (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr); 613d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 614d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 6151d102b48SJeremy L Thompson } 616e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 617d7b241e6Sjeremylt } 618d7b241e6Sjeremylt 619b11c1e72Sjeremylt /** 6207509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 6217509a596Sjeremylt 6227509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 623d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 624d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 625d1d35e2fSjeremylt @param blk_size Number of elements in a block 626d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 6277509a596Sjeremylt (1 for scalar fields) 628d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 629d979a051Sjeremylt the elements and fields given by this restriction. 6307509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 63195e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 63295e93d34SJeremy L Thompson the L-vector at index 63395e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 63495e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 63595e93d34SJeremy L Thompson by a Ceed backend. 6367509a596Sjeremylt @param rstr Address of the variable where the newly created 6377509a596Sjeremylt CeedElemRestriction will be stored 6387509a596Sjeremylt 6397509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 6407509a596Sjeremylt 6417a982d89SJeremy L. Thompson @ref User 6427509a596Sjeremylt **/ 643d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, 644e79b91d9SJeremy L Thompson CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 6458621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 6467509a596Sjeremylt int ierr; 647d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 6487509a596Sjeremylt 6497509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6507509a596Sjeremylt Ceed delegate; 6517509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 6527509a596Sjeremylt CeedChk(ierr); 6537509a596Sjeremylt 6547509a596Sjeremylt if (!delegate) 6557509a596Sjeremylt // LCOV_EXCL_START 656e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 6577509a596Sjeremylt "ElemRestrictionCreateBlocked"); 6587509a596Sjeremylt // LCOV_EXCL_STOP 6597509a596Sjeremylt 660d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, 661d1d35e2fSjeremylt blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr); 662e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6637509a596Sjeremylt } 6647509a596Sjeremylt 6657509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 6667509a596Sjeremylt 6677509a596Sjeremylt (*rstr)->ceed = ceed; 6689560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 669d1d35e2fSjeremylt (*rstr)->ref_count = 1; 670d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 671d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 672d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 673d1d35e2fSjeremylt (*rstr)->l_size = l_size; 674d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 675d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 676b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 6777509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 6787509a596Sjeremylt for (int i=0; i<3; i++) 6797509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 6807509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 6817509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 682e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6837509a596Sjeremylt } 6847509a596Sjeremylt 6857509a596Sjeremylt /** 6869560d06aSjeremylt @brief Copy the pointer to a CeedElemRestriction. Both pointers should 6879560d06aSjeremylt be destroyed with `CeedElemRestrictionDestroy()`; 6889560d06aSjeremylt Note: If `*rstr_copy` is non-NULL, then it is assumed that 6899560d06aSjeremylt `*rstr_copy` is a pointer to a CeedElemRestriction. This 6909560d06aSjeremylt CeedElemRestriction will be destroyed if `*rstr_copy` is the 6919560d06aSjeremylt only reference to this CeedElemRestriction. 6929560d06aSjeremylt 6939560d06aSjeremylt @param rstr CeedElemRestriction to copy reference to 6949560d06aSjeremylt @param[out] rstr_copy Variable to store copied reference 6959560d06aSjeremylt 6969560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6979560d06aSjeremylt 6989560d06aSjeremylt @ref User 6999560d06aSjeremylt **/ 7009560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, 7019560d06aSjeremylt CeedElemRestriction *rstr_copy) { 7029560d06aSjeremylt int ierr; 7039560d06aSjeremylt 7049560d06aSjeremylt ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr); 7059560d06aSjeremylt ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr); 7069560d06aSjeremylt *rstr_copy = rstr; 7079560d06aSjeremylt return CEED_ERROR_SUCCESS; 7089560d06aSjeremylt } 7099560d06aSjeremylt 7109560d06aSjeremylt /** 711b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 712b11c1e72Sjeremylt 7134ce2993fSjeremylt @param rstr CeedElemRestriction 714d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 715d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 716b11c1e72Sjeremylt 717b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 718dfdf5a53Sjeremylt 7197a982d89SJeremy L. Thompson @ref User 720b11c1e72Sjeremylt **/ 721d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, 722d1d35e2fSjeremylt CeedVector *e_vec) { 723d7b241e6Sjeremylt int ierr; 724d2643443SJeremy L Thompson CeedSize e_size, l_size; 725d1d35e2fSjeremylt l_size = rstr->l_size; 726d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 727d1d35e2fSjeremylt if (l_vec) { 728d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr); 729d7b241e6Sjeremylt } 730d1d35e2fSjeremylt if (e_vec) { 731d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr); 732d7b241e6Sjeremylt } 733e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 734d7b241e6Sjeremylt } 735d7b241e6Sjeremylt 736d7b241e6Sjeremylt /** 737d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 738d7b241e6Sjeremylt 7394ce2993fSjeremylt @param rstr CeedElemRestriction 740d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 741d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 742d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 743d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7447aaeacdcSjeremylt by the backend. 7454cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 746b11c1e72Sjeremylt 747b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 748dfdf5a53Sjeremylt 7497a982d89SJeremy L. Thompson @ref User 750b11c1e72Sjeremylt **/ 751d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, 752a8d32208Sjeremylt CeedVector u, CeedVector ru, 753a8d32208Sjeremylt CeedRequest *request) { 754d7b241e6Sjeremylt CeedInt m, n; 755d7b241e6Sjeremylt int ierr; 756d7b241e6Sjeremylt 757d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 758d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 759d1d35e2fSjeremylt n = rstr->l_size; 760d7b241e6Sjeremylt } else { 761d1d35e2fSjeremylt m = rstr->l_size; 762d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 763d7b241e6Sjeremylt } 764d7b241e6Sjeremylt if (n != u->length) 765c042f62fSJeremy L Thompson // LCOV_EXCL_START 766e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 767e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7681d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 769c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 770a8d32208Sjeremylt if (m != ru->length) 771c042f62fSJeremy L Thompson // LCOV_EXCL_START 772e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 773e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 774a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 775c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 776d1d35e2fSjeremylt ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr); 777e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 778d7b241e6Sjeremylt } 779d7b241e6Sjeremylt 780d7b241e6Sjeremylt /** 781d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 782be9261b7Sjeremylt 783be9261b7Sjeremylt @param rstr CeedElemRestriction 7841f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 785d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 786d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 787d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 788d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 789d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 790d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7917aaeacdcSjeremylt by the backend. 7924cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 793be9261b7Sjeremylt 794be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 795be9261b7Sjeremylt 7967a982d89SJeremy L. Thompson @ref Backend 797be9261b7Sjeremylt **/ 798be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 799d1d35e2fSjeremylt CeedTransposeMode t_mode, CeedVector u, 800a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 801be9261b7Sjeremylt CeedInt m, n; 802be9261b7Sjeremylt int ierr; 803be9261b7Sjeremylt 804d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 805d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 806d1d35e2fSjeremylt n = rstr->l_size; 807be9261b7Sjeremylt } else { 808d1d35e2fSjeremylt m = rstr->l_size; 809d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 810be9261b7Sjeremylt } 811be9261b7Sjeremylt if (n != u->length) 812c042f62fSJeremy L Thompson // LCOV_EXCL_START 813e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 814e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 8151d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 816c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 817a8d32208Sjeremylt if (m != ru->length) 818c042f62fSJeremy L Thompson // LCOV_EXCL_START 819e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 820e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 821a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 822c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 823d1d35e2fSjeremylt if (rstr->blk_size*block > rstr->num_elem) 824c042f62fSJeremy L Thompson // LCOV_EXCL_START 825e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 826e15f9bd0SJeremy L Thompson "Cannot retrieve block %d, element %d > " 827d1d35e2fSjeremylt "total elements %d", block, rstr->blk_size*block, 828d1d35e2fSjeremylt rstr->num_elem); 829c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 830d1d35e2fSjeremylt ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request); 831be9261b7Sjeremylt CeedChk(ierr); 832e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 833be9261b7Sjeremylt } 834be9261b7Sjeremylt 835be9261b7Sjeremylt /** 836b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 837b7c9bbdaSJeremy L Thompson 838b7c9bbdaSJeremy L Thompson @param rstr CeedElemRestriction 839b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 840b7c9bbdaSJeremy L Thompson 841b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 842b7c9bbdaSJeremy L Thompson 843b7c9bbdaSJeremy L Thompson @ref Advanced 844b7c9bbdaSJeremy L Thompson **/ 845b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 846b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 847b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 848b7c9bbdaSJeremy L Thompson } 849b7c9bbdaSJeremy L Thompson 850b7c9bbdaSJeremy L Thompson /** 851d979a051Sjeremylt @brief Get the L-vector component stride 852a681ae63Sjeremylt 853a681ae63Sjeremylt @param rstr CeedElemRestriction 854d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 855a681ae63Sjeremylt 856a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 857a681ae63Sjeremylt 858b7c9bbdaSJeremy L Thompson @ref Advanced 859a681ae63Sjeremylt **/ 860d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 861d1d35e2fSjeremylt CeedInt *comp_stride) { 862d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 863e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 864a681ae63Sjeremylt } 865a681ae63Sjeremylt 866a681ae63Sjeremylt /** 867a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 868a681ae63Sjeremylt 869a681ae63Sjeremylt @param rstr CeedElemRestriction 870d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 871a681ae63Sjeremylt 872a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 873a681ae63Sjeremylt 874b7c9bbdaSJeremy L Thompson @ref Advanced 875a681ae63Sjeremylt **/ 876a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 877d1d35e2fSjeremylt CeedInt *num_elem) { 878d1d35e2fSjeremylt *num_elem = rstr->num_elem; 879e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 880a681ae63Sjeremylt } 881a681ae63Sjeremylt 882a681ae63Sjeremylt /** 883a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 884a681ae63Sjeremylt 885a681ae63Sjeremylt @param rstr CeedElemRestriction 886d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 887a681ae63Sjeremylt 888a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 889a681ae63Sjeremylt 890b7c9bbdaSJeremy L Thompson @ref Advanced 891a681ae63Sjeremylt **/ 892a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 893d1d35e2fSjeremylt CeedInt *elem_size) { 894d1d35e2fSjeremylt *elem_size = rstr->elem_size; 895e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 896a681ae63Sjeremylt } 897a681ae63Sjeremylt 898a681ae63Sjeremylt /** 899d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 900a681ae63Sjeremylt 901a681ae63Sjeremylt @param rstr CeedElemRestriction 902d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 903a681ae63Sjeremylt 904a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 905a681ae63Sjeremylt 906b7c9bbdaSJeremy L Thompson @ref Advanced 907a681ae63Sjeremylt **/ 908d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 909e79b91d9SJeremy L Thompson CeedSize *l_size) { 910d1d35e2fSjeremylt *l_size = rstr->l_size; 911e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 912a681ae63Sjeremylt } 913a681ae63Sjeremylt 914a681ae63Sjeremylt /** 915a681ae63Sjeremylt @brief Get the number of components in the elements of a 916a681ae63Sjeremylt CeedElemRestriction 917a681ae63Sjeremylt 918a681ae63Sjeremylt @param rstr CeedElemRestriction 919d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 920a681ae63Sjeremylt 921a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 922a681ae63Sjeremylt 923b7c9bbdaSJeremy L Thompson @ref Advanced 924a681ae63Sjeremylt **/ 925a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 926d1d35e2fSjeremylt CeedInt *num_comp) { 927d1d35e2fSjeremylt *num_comp = rstr->num_comp; 928e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 929a681ae63Sjeremylt } 930a681ae63Sjeremylt 931a681ae63Sjeremylt /** 932a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 933a681ae63Sjeremylt 934a681ae63Sjeremylt @param rstr CeedElemRestriction 935d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 936a681ae63Sjeremylt 937a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 938a681ae63Sjeremylt 939b7c9bbdaSJeremy L Thompson @ref Advanced 940a681ae63Sjeremylt **/ 941a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 942d1d35e2fSjeremylt CeedInt *num_block) { 943d1d35e2fSjeremylt *num_block = rstr->num_blk; 944e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 945a681ae63Sjeremylt } 946a681ae63Sjeremylt 947a681ae63Sjeremylt /** 948a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 949a681ae63Sjeremylt 950a681ae63Sjeremylt @param rstr CeedElemRestriction 951d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 952a681ae63Sjeremylt 953a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 954a681ae63Sjeremylt 955b7c9bbdaSJeremy L Thompson @ref Advanced 956a681ae63Sjeremylt **/ 957a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 958d1d35e2fSjeremylt CeedInt *blk_size) { 959d1d35e2fSjeremylt *blk_size = rstr->blk_size; 960e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 961a681ae63Sjeremylt } 962a681ae63Sjeremylt 963a681ae63Sjeremylt /** 964d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 9651469ee4dSjeremylt 9661469ee4dSjeremylt @param rstr CeedElemRestriction 967d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 9681469ee4dSjeremylt 9691469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 9701469ee4dSjeremylt 9717a982d89SJeremy L. Thompson @ref User 9721469ee4dSjeremylt **/ 9731469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 9741469ee4dSjeremylt CeedVector mult) { 9751469ee4dSjeremylt int ierr; 976d1d35e2fSjeremylt CeedVector e_vec; 9771469ee4dSjeremylt 97825509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 979d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr); 9801469ee4dSjeremylt 98125509ebbSRezgar Shakeri // Compute e_vec = E * 1 98225509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 1.0); CeedChk(ierr); 98325509ebbSRezgar Shakeri ierr = CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, 98425509ebbSRezgar Shakeri CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 98525509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 98625509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 987d1d35e2fSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, 988efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 9891469ee4dSjeremylt // Cleanup 990d1d35e2fSjeremylt ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr); 991e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9921469ee4dSjeremylt } 9931469ee4dSjeremylt 9941469ee4dSjeremylt /** 995f02ca4a2SJed Brown @brief View a CeedElemRestriction 996f02ca4a2SJed Brown 997f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 998f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 999f02ca4a2SJed Brown 1000f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 1001f02ca4a2SJed Brown 10027a982d89SJeremy L. Thompson @ref User 1003f02ca4a2SJed Brown **/ 1004f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 10057509a596Sjeremylt char stridesstr[500]; 10067509a596Sjeremylt if (rstr->strides) 10077509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 10087509a596Sjeremylt rstr->strides[2]); 1009d979a051Sjeremylt else 1010d1d35e2fSjeremylt sprintf(stridesstr, "%d", rstr->comp_stride); 10117509a596Sjeremylt 10125b76854bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %d) to %d elements with %d " 1013d1d35e2fSjeremylt "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "", 1014d1d35e2fSjeremylt rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 1015d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 1016e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1017f02ca4a2SJed Brown } 1018f02ca4a2SJed Brown 1019f02ca4a2SJed Brown /** 1020b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 1021b11c1e72Sjeremylt 10224ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 1023b11c1e72Sjeremylt 1024b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1025dfdf5a53Sjeremylt 10267a982d89SJeremy L. Thompson @ref User 1027b11c1e72Sjeremylt **/ 10284ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1029d7b241e6Sjeremylt int ierr; 1030d7b241e6Sjeremylt 1031d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 1032d1d35e2fSjeremylt if ((*rstr)->num_readers) 10338229195eSjeremylt // LCOV_EXCL_START 1034e15f9bd0SJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, 1035e15f9bd0SJeremy L Thompson "Cannot destroy CeedElemRestriction, " 1036430758c8SJeremy L Thompson "a process has read access to the offset data"); 10378229195eSjeremylt // LCOV_EXCL_STOP 10384ce2993fSjeremylt if ((*rstr)->Destroy) { 10394ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 1040d7b241e6Sjeremylt } 10417509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 10424ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 10434ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 1044e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1045d7b241e6Sjeremylt } 1046d7b241e6Sjeremylt 1047d7b241e6Sjeremylt /// @} 1048