1*3d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2*3d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 4*3d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 6*3d8e8822SJeremy 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 2797a982d89SJeremy L. Thompson /// @} 2807a982d89SJeremy L. Thompson 28115910d16Sjeremylt /// @cond DOXYGEN_SKIP 28215910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none; 28315910d16Sjeremylt /// @endcond 28415910d16Sjeremylt 2857a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2867a982d89SJeremy L. Thompson /// CeedElemRestriction Public API 2877a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2887a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser 289d7b241e6Sjeremylt /// @{ 290d7b241e6Sjeremylt 2917a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend 29245f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0}; 2937a982d89SJeremy L. Thompson 2944cc79fe7SJed Brown /// Indicate that no CeedElemRestriction is provided by the user 2957a982d89SJeremy L. Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = 2967a982d89SJeremy L. Thompson &ceed_elemrestriction_none; 2977a982d89SJeremy L. Thompson 298d7b241e6Sjeremylt /** 299b11c1e72Sjeremylt @brief Create a CeedElemRestriction 300d7b241e6Sjeremylt 301b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 302d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array 303d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 304d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 30595bb1877Svaleriabarra (1 for scalar fields) 306d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 30795e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 30895e93d34SJeremy L Thompson the L-vector at index 309d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 310d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 311d979a051Sjeremylt the elements and fields given by this restriction. 312d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 313d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 314d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 315d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 3168795c945Sjeremylt for the unknowns corresponding to element i, where 317d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 318d1d35e2fSjeremylt [0, @a l_size - 1]. 3194ce2993fSjeremylt @param[out] rstr Address of the variable where the newly created 320b11c1e72Sjeremylt CeedElemRestriction will be stored 321d7b241e6Sjeremylt 322b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 323dfdf5a53Sjeremylt 3247a982d89SJeremy L. Thompson @ref User 325b11c1e72Sjeremylt **/ 326d1d35e2fSjeremylt int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, 327d1d35e2fSjeremylt CeedInt num_comp, CeedInt comp_stride, 328e79b91d9SJeremy L Thompson CeedSize l_size, CeedMemType mem_type, 329d1d35e2fSjeremylt CeedCopyMode copy_mode, const CeedInt *offsets, 3304ce2993fSjeremylt CeedElemRestriction *rstr) { 331d7b241e6Sjeremylt int ierr; 332d7b241e6Sjeremylt 3335fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 3345fe0d4faSjeremylt Ceed delegate; 335aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 336aefd8378Sjeremylt CeedChk(ierr); 3375fe0d4faSjeremylt 3385fe0d4faSjeremylt if (!delegate) 339c042f62fSJeremy L Thompson // LCOV_EXCL_START 340e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 341e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 342c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 3435fe0d4faSjeremylt 344d1d35e2fSjeremylt ierr = CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, 345d1d35e2fSjeremylt comp_stride, l_size, mem_type, copy_mode, 346d979a051Sjeremylt offsets, rstr); CeedChk(ierr); 347e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3485fe0d4faSjeremylt } 3495fe0d4faSjeremylt 3504ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 3514ce2993fSjeremylt (*rstr)->ceed = ceed; 3529560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 353d1d35e2fSjeremylt (*rstr)->ref_count = 1; 354d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 355d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 356d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 357d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 358d1d35e2fSjeremylt (*rstr)->l_size = l_size; 359d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 360d1d35e2fSjeremylt (*rstr)->blk_size = 1; 361b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 362d1d35e2fSjeremylt ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr); 363d979a051Sjeremylt CeedChk(ierr); 364e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 365d7b241e6Sjeremylt } 366d7b241e6Sjeremylt 367d7b241e6Sjeremylt /** 368fc0567d9Srezgarshakeri @brief Create a CeedElemRestriction with orientation sign 369fc0567d9Srezgarshakeri 370fc0567d9Srezgarshakeri @param ceed A Ceed object where the CeedElemRestriction will be created 371fc0567d9Srezgarshakeri @param num_elem Number of elements described in the @a offsets array 372fc0567d9Srezgarshakeri @param elem_size Size (number of "nodes") per element 373fc0567d9Srezgarshakeri @param num_comp Number of field components per interpolation node 374fc0567d9Srezgarshakeri (1 for scalar fields) 375fc0567d9Srezgarshakeri @param comp_stride Stride between components for the same L-vector "node". 376fc0567d9Srezgarshakeri Data for node i, component j, element k can be found in 377fc0567d9Srezgarshakeri the L-vector at index 378fc0567d9Srezgarshakeri offsets[i + k*elem_size] + j*comp_stride. 379fc0567d9Srezgarshakeri @param l_size The size of the L-vector. This vector may be larger than 380fc0567d9Srezgarshakeri the elements and fields given by this restriction. 381fc0567d9Srezgarshakeri @param mem_type Memory type of the @a offsets array, see CeedMemType 382fc0567d9Srezgarshakeri @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 383fc0567d9Srezgarshakeri @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 384fc0567d9Srezgarshakeri ordered list of the offsets (into the input CeedVector) 385fc0567d9Srezgarshakeri for the unknowns corresponding to element i, where 386fc0567d9Srezgarshakeri 0 <= i < @a num_elem. All offsets must be in the range 387fc0567d9Srezgarshakeri [0, @a l_size - 1]. 388fc0567d9Srezgarshakeri @param orient Array of shape [@a num_elem, @a elem_size] with bool false 389fc0567d9Srezgarshakeri for positively oriented and true to flip the orientation. 390fc0567d9Srezgarshakeri @param[out] rstr Address of the variable where the newly created 391fc0567d9Srezgarshakeri CeedElemRestriction will be stored 392fc0567d9Srezgarshakeri 393fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure 394fc0567d9Srezgarshakeri 395fc0567d9Srezgarshakeri @ref User 396fc0567d9Srezgarshakeri **/ 397fc0567d9Srezgarshakeri int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, 398fc0567d9Srezgarshakeri CeedInt elem_size, CeedInt num_comp, 399e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 400fc0567d9Srezgarshakeri CeedMemType mem_type, CeedCopyMode copy_mode, 401fc0567d9Srezgarshakeri const CeedInt *offsets, const bool *orient, 402fc0567d9Srezgarshakeri CeedElemRestriction *rstr) { 403fc0567d9Srezgarshakeri int ierr; 404fc0567d9Srezgarshakeri 405c7745053SRezgar Shakeri if (!ceed->ElemRestrictionCreateOriented) { 406fc0567d9Srezgarshakeri Ceed delegate; 407fc0567d9Srezgarshakeri ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 408fc0567d9Srezgarshakeri CeedChk(ierr); 409fc0567d9Srezgarshakeri 410fc0567d9Srezgarshakeri if (!delegate) 411fc0567d9Srezgarshakeri // LCOV_EXCL_START 412fc0567d9Srezgarshakeri return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 41361e7462cSRezgar Shakeri "Backend does not implement ElemRestrictionCreateOriented"); 414fc0567d9Srezgarshakeri // LCOV_EXCL_STOP 415fc0567d9Srezgarshakeri 416fc0567d9Srezgarshakeri ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, 417c7745053SRezgar Shakeri num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, 4184dd06d33Srezgarshakeri orient, rstr); CeedChk(ierr); 419fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 420fc0567d9Srezgarshakeri } 421fc0567d9Srezgarshakeri 422fc0567d9Srezgarshakeri ierr = CeedCalloc(1, rstr); CeedChk(ierr); 423fc0567d9Srezgarshakeri (*rstr)->ceed = ceed; 424fc0567d9Srezgarshakeri ierr = CeedReference(ceed); CeedChk(ierr); 425fc0567d9Srezgarshakeri (*rstr)->ref_count = 1; 426fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem; 427fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size; 428fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp; 429fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride; 430fc0567d9Srezgarshakeri (*rstr)->l_size = l_size; 431fc0567d9Srezgarshakeri (*rstr)->num_blk = num_elem; 432fc0567d9Srezgarshakeri (*rstr)->blk_size = 1; 433b435c5a6Srezgarshakeri (*rstr)->is_oriented = 1; 4344dd06d33Srezgarshakeri ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode, 4354dd06d33Srezgarshakeri offsets, orient, *rstr); CeedChk(ierr); 436fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 437fc0567d9Srezgarshakeri } 438fc0567d9Srezgarshakeri 439fc0567d9Srezgarshakeri /** 4407509a596Sjeremylt @brief Create a strided CeedElemRestriction 441d7b241e6Sjeremylt 442b11c1e72Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 443d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 444d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 445d1d35e2fSjeremylt @param num_comp Number of field components per interpolation "node" 44695bb1877Svaleriabarra (1 for scalar fields) 447d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 448d979a051Sjeremylt the elements and fields given by this restriction. 4497509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 45095e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 45195e93d34SJeremy L Thompson the L-vector at index 45295e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 45395e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 45495e93d34SJeremy L Thompson by a Ceed backend. 4554ce2993fSjeremylt @param rstr Address of the variable where the newly created 456b11c1e72Sjeremylt CeedElemRestriction will be stored 457d7b241e6Sjeremylt 458b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 459dfdf5a53Sjeremylt 4607a982d89SJeremy L. Thompson @ref User 461b11c1e72Sjeremylt **/ 462d1d35e2fSjeremylt int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, 463d1d35e2fSjeremylt CeedInt elem_size, 464e79b91d9SJeremy L Thompson CeedInt num_comp, CeedSize l_size, 4658621c6c6SJeremy L Thompson const CeedInt strides[3], 466f90c8643Sjeremylt CeedElemRestriction *rstr) { 467d7b241e6Sjeremylt int ierr; 468d7b241e6Sjeremylt 4695fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) { 4705fe0d4faSjeremylt Ceed delegate; 471aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 472aefd8378Sjeremylt CeedChk(ierr); 4735fe0d4faSjeremylt 4745fe0d4faSjeremylt if (!delegate) 475c042f62fSJeremy L Thompson // LCOV_EXCL_START 476e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, 477e15f9bd0SJeremy L Thompson "Backend does not support ElemRestrictionCreate"); 478c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 4795fe0d4faSjeremylt 480d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, 481d1d35e2fSjeremylt l_size, strides, rstr); 482d979a051Sjeremylt CeedChk(ierr); 483e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4845fe0d4faSjeremylt } 4855fe0d4faSjeremylt 4864ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 4874ce2993fSjeremylt (*rstr)->ceed = ceed; 4889560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 489d1d35e2fSjeremylt (*rstr)->ref_count = 1; 490d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 491d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 492d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 493d1d35e2fSjeremylt (*rstr)->l_size = l_size; 494d1d35e2fSjeremylt (*rstr)->num_blk = num_elem; 495d1d35e2fSjeremylt (*rstr)->blk_size = 1; 496b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 4977509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 4987509a596Sjeremylt for (int i=0; i<3; i++) 4997509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 5001dfeef1dSjeremylt ierr = ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, 5011dfeef1dSjeremylt *rstr); 5024b8bea3bSJed Brown CeedChk(ierr); 503e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 504d7b241e6Sjeremylt } 505d7b241e6Sjeremylt 506d7b241e6Sjeremylt /** 507b11c1e72Sjeremylt @brief Create a blocked CeedElemRestriction, typically only called by backends 508d7b241e6Sjeremylt 509d7b241e6Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created. 510d1d35e2fSjeremylt @param num_elem Number of elements described in the @a offsets array. 511d1d35e2fSjeremylt @param elem_size Size (number of unknowns) per element 512d1d35e2fSjeremylt @param blk_size Number of elements in a block 513d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 51495bb1877Svaleriabarra (1 for scalar fields) 515d1d35e2fSjeremylt @param comp_stride Stride between components for the same L-vector "node". 51695e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 51795e93d34SJeremy L Thompson the L-vector at index 518d1d35e2fSjeremylt offsets[i + k*elem_size] + j*comp_stride. 519d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 520d979a051Sjeremylt the elements and fields given by this restriction. 521d1d35e2fSjeremylt @param mem_type Memory type of the @a offsets array, see CeedMemType 522d1d35e2fSjeremylt @param copy_mode Copy mode for the @a offsets array, see CeedCopyMode 523d1d35e2fSjeremylt @param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the 524d979a051Sjeremylt ordered list of the offsets (into the input CeedVector) 5258795c945Sjeremylt for the unknowns corresponding to element i, where 526d1d35e2fSjeremylt 0 <= i < @a num_elem. All offsets must be in the range 527d1d35e2fSjeremylt [0, @a l_size - 1]. The backend will permute and pad this 5288795c945Sjeremylt array to the desired ordering for the blocksize, which is 5298795c945Sjeremylt typically given by the backend. The default reordering is 5308795c945Sjeremylt to interlace elements. 5314ce2993fSjeremylt @param rstr Address of the variable where the newly created 532b11c1e72Sjeremylt CeedElemRestriction will be stored 533d7b241e6Sjeremylt 534b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 535dfdf5a53Sjeremylt 5367a982d89SJeremy L. Thompson @ref Backend 537b11c1e72Sjeremylt **/ 538d1d35e2fSjeremylt int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, 539d1d35e2fSjeremylt CeedInt elem_size, 540d1d35e2fSjeremylt CeedInt blk_size, CeedInt num_comp, 541e79b91d9SJeremy L Thompson CeedInt comp_stride, CeedSize l_size, 542d1d35e2fSjeremylt CeedMemType mem_type, CeedCopyMode copy_mode, 543d979a051Sjeremylt const CeedInt *offsets, 5444ce2993fSjeremylt CeedElemRestriction *rstr) { 545d7b241e6Sjeremylt int ierr; 546d1d35e2fSjeremylt CeedInt *blk_offsets; 547d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 548d7b241e6Sjeremylt 5495fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 5505fe0d4faSjeremylt Ceed delegate; 551aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 552aefd8378Sjeremylt CeedChk(ierr); 5535fe0d4faSjeremylt 5545fe0d4faSjeremylt if (!delegate) 555c042f62fSJeremy L Thompson // LCOV_EXCL_START 556e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 5571d102b48SJeremy L Thompson "ElemRestrictionCreateBlocked"); 558c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5595fe0d4faSjeremylt 560d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, blk_size, 561d1d35e2fSjeremylt num_comp, comp_stride, l_size, mem_type, 562d1d35e2fSjeremylt copy_mode, offsets, rstr); 563d979a051Sjeremylt CeedChk(ierr); 564e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5655fe0d4faSjeremylt } 566d7b241e6Sjeremylt 5674ce2993fSjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 568d7b241e6Sjeremylt 569d1d35e2fSjeremylt ierr = CeedCalloc(num_blk*blk_size*elem_size, &blk_offsets); CeedChk(ierr); 570d1d35e2fSjeremylt ierr = CeedPermutePadOffsets(offsets, blk_offsets, num_blk, num_elem, blk_size, 571d1d35e2fSjeremylt elem_size); CeedChk(ierr); 572d7b241e6Sjeremylt 5734ce2993fSjeremylt (*rstr)->ceed = ceed; 5749560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 575d1d35e2fSjeremylt (*rstr)->ref_count = 1; 576d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 577d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 578d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 579d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride; 580d1d35e2fSjeremylt (*rstr)->l_size = l_size; 581d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 582d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 583b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 584667bc5fcSjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 585d1d35e2fSjeremylt (const CeedInt *) blk_offsets, *rstr); CeedChk(ierr); 586d1d35e2fSjeremylt if (copy_mode == CEED_OWN_POINTER) { 587d979a051Sjeremylt ierr = CeedFree(&offsets); CeedChk(ierr); 5881d102b48SJeremy L Thompson } 589e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 590d7b241e6Sjeremylt } 591d7b241e6Sjeremylt 592b11c1e72Sjeremylt /** 5937509a596Sjeremylt @brief Create a blocked strided CeedElemRestriction 5947509a596Sjeremylt 5957509a596Sjeremylt @param ceed A Ceed object where the CeedElemRestriction will be created 596d1d35e2fSjeremylt @param num_elem Number of elements described by the restriction 597d1d35e2fSjeremylt @param elem_size Size (number of "nodes") per element 598d1d35e2fSjeremylt @param blk_size Number of elements in a block 599d1d35e2fSjeremylt @param num_comp Number of field components per interpolation node 6007509a596Sjeremylt (1 for scalar fields) 601d1d35e2fSjeremylt @param l_size The size of the L-vector. This vector may be larger than 602d979a051Sjeremylt the elements and fields given by this restriction. 6037509a596Sjeremylt @param strides Array for strides between [nodes, components, elements]. 60495e93d34SJeremy L Thompson Data for node i, component j, element k can be found in 60595e93d34SJeremy L Thompson the L-vector at index 60695e93d34SJeremy L Thompson i*strides[0] + j*strides[1] + k*strides[2]. 60795e93d34SJeremy L Thompson @a CEED_STRIDES_BACKEND may be used with vectors created 60895e93d34SJeremy L Thompson by a Ceed backend. 6097509a596Sjeremylt @param rstr Address of the variable where the newly created 6107509a596Sjeremylt CeedElemRestriction will be stored 6117509a596Sjeremylt 6127509a596Sjeremylt @return An error code: 0 - success, otherwise - failure 6137509a596Sjeremylt 6147a982d89SJeremy L. Thompson @ref User 6157509a596Sjeremylt **/ 616d1d35e2fSjeremylt int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, 617e79b91d9SJeremy L Thompson CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedSize l_size, 6188621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) { 6197509a596Sjeremylt int ierr; 620d1d35e2fSjeremylt CeedInt num_blk = (num_elem / blk_size) + !!(num_elem % blk_size); 6217509a596Sjeremylt 6227509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) { 6237509a596Sjeremylt Ceed delegate; 6247509a596Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"); 6257509a596Sjeremylt CeedChk(ierr); 6267509a596Sjeremylt 6277509a596Sjeremylt if (!delegate) 6287509a596Sjeremylt // LCOV_EXCL_START 629e15f9bd0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support " 6307509a596Sjeremylt "ElemRestrictionCreateBlocked"); 6317509a596Sjeremylt // LCOV_EXCL_STOP 6327509a596Sjeremylt 633d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, 634d1d35e2fSjeremylt blk_size, num_comp, l_size, strides, rstr); CeedChk(ierr); 635e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6367509a596Sjeremylt } 6377509a596Sjeremylt 6387509a596Sjeremylt ierr = CeedCalloc(1, rstr); CeedChk(ierr); 6397509a596Sjeremylt 6407509a596Sjeremylt (*rstr)->ceed = ceed; 6419560d06aSjeremylt ierr = CeedReference(ceed); CeedChk(ierr); 642d1d35e2fSjeremylt (*rstr)->ref_count = 1; 643d1d35e2fSjeremylt (*rstr)->num_elem = num_elem; 644d1d35e2fSjeremylt (*rstr)->elem_size = elem_size; 645d1d35e2fSjeremylt (*rstr)->num_comp = num_comp; 646d1d35e2fSjeremylt (*rstr)->l_size = l_size; 647d1d35e2fSjeremylt (*rstr)->num_blk = num_blk; 648d1d35e2fSjeremylt (*rstr)->blk_size = blk_size; 649b435c5a6Srezgarshakeri (*rstr)->is_oriented = 0; 6507509a596Sjeremylt ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr); 6517509a596Sjeremylt for (int i=0; i<3; i++) 6527509a596Sjeremylt (*rstr)->strides[i] = strides[i]; 6537509a596Sjeremylt ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, 6547509a596Sjeremylt NULL, *rstr); CeedChk(ierr); 655e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6567509a596Sjeremylt } 6577509a596Sjeremylt 6587509a596Sjeremylt /** 6599560d06aSjeremylt @brief Copy the pointer to a CeedElemRestriction. Both pointers should 6609560d06aSjeremylt be destroyed with `CeedElemRestrictionDestroy()`; 6619560d06aSjeremylt Note: If `*rstr_copy` is non-NULL, then it is assumed that 6629560d06aSjeremylt `*rstr_copy` is a pointer to a CeedElemRestriction. This 6639560d06aSjeremylt CeedElemRestriction will be destroyed if `*rstr_copy` is the 6649560d06aSjeremylt only reference to this CeedElemRestriction. 6659560d06aSjeremylt 6669560d06aSjeremylt @param rstr CeedElemRestriction to copy reference to 6679560d06aSjeremylt @param[out] rstr_copy Variable to store copied reference 6689560d06aSjeremylt 6699560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 6709560d06aSjeremylt 6719560d06aSjeremylt @ref User 6729560d06aSjeremylt **/ 6739560d06aSjeremylt int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, 6749560d06aSjeremylt CeedElemRestriction *rstr_copy) { 6759560d06aSjeremylt int ierr; 6769560d06aSjeremylt 6779560d06aSjeremylt ierr = CeedElemRestrictionReference(rstr); CeedChk(ierr); 6789560d06aSjeremylt ierr = CeedElemRestrictionDestroy(rstr_copy); CeedChk(ierr); 6799560d06aSjeremylt *rstr_copy = rstr; 6809560d06aSjeremylt return CEED_ERROR_SUCCESS; 6819560d06aSjeremylt } 6829560d06aSjeremylt 6839560d06aSjeremylt /** 684b11c1e72Sjeremylt @brief Create CeedVectors associated with a CeedElemRestriction 685b11c1e72Sjeremylt 6864ce2993fSjeremylt @param rstr CeedElemRestriction 687d1d35e2fSjeremylt @param l_vec The address of the L-vector to be created, or NULL 688d1d35e2fSjeremylt @param e_vec The address of the E-vector to be created, or NULL 689b11c1e72Sjeremylt 690b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 691dfdf5a53Sjeremylt 6927a982d89SJeremy L. Thompson @ref User 693b11c1e72Sjeremylt **/ 694d1d35e2fSjeremylt int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, 695d1d35e2fSjeremylt CeedVector *e_vec) { 696d7b241e6Sjeremylt int ierr; 697d1d35e2fSjeremylt CeedInt e_size, l_size; 698d1d35e2fSjeremylt l_size = rstr->l_size; 699d1d35e2fSjeremylt e_size = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 700d1d35e2fSjeremylt if (l_vec) { 701d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, l_size, l_vec); CeedChk(ierr); 702d7b241e6Sjeremylt } 703d1d35e2fSjeremylt if (e_vec) { 704d1d35e2fSjeremylt ierr = CeedVectorCreate(rstr->ceed, e_size, e_vec); CeedChk(ierr); 705d7b241e6Sjeremylt } 706e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 707d7b241e6Sjeremylt } 708d7b241e6Sjeremylt 709d7b241e6Sjeremylt /** 710d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose 711d7b241e6Sjeremylt 7124ce2993fSjeremylt @param rstr CeedElemRestriction 713d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 714d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 715d1d35e2fSjeremylt @param ru Output vector (of shape [@a num_elem * @a elem_size] when 716d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7177aaeacdcSjeremylt by the backend. 7184cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 719b11c1e72Sjeremylt 720b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 721dfdf5a53Sjeremylt 7227a982d89SJeremy L. Thompson @ref User 723b11c1e72Sjeremylt **/ 724d1d35e2fSjeremylt int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, 725a8d32208Sjeremylt CeedVector u, CeedVector ru, 726a8d32208Sjeremylt CeedRequest *request) { 727d7b241e6Sjeremylt CeedInt m, n; 728d7b241e6Sjeremylt int ierr; 729d7b241e6Sjeremylt 730d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 731d1d35e2fSjeremylt m = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 732d1d35e2fSjeremylt n = rstr->l_size; 733d7b241e6Sjeremylt } else { 734d1d35e2fSjeremylt m = rstr->l_size; 735d1d35e2fSjeremylt n = rstr->num_blk * rstr->blk_size * rstr->elem_size * rstr->num_comp; 736d7b241e6Sjeremylt } 737d7b241e6Sjeremylt if (n != u->length) 738c042f62fSJeremy L Thompson // LCOV_EXCL_START 739e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 740e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7411d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 742c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 743a8d32208Sjeremylt if (m != ru->length) 744c042f62fSJeremy L Thompson // LCOV_EXCL_START 745e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 746e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 747a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 748c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 749d1d35e2fSjeremylt ierr = rstr->Apply(rstr, t_mode, u, ru, request); CeedChk(ierr); 750e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 751d7b241e6Sjeremylt } 752d7b241e6Sjeremylt 753d7b241e6Sjeremylt /** 754d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose 755be9261b7Sjeremylt 756be9261b7Sjeremylt @param rstr CeedElemRestriction 7571f37b403Sjeremylt @param block Block number to restrict to/from, i.e. block=0 will handle 758d1d35e2fSjeremylt elements [0 : blk_size] and block=3 will handle elements 759d1d35e2fSjeremylt [3*blk_size : 4*blk_size] 760d1d35e2fSjeremylt @param t_mode Apply restriction or transpose 761d1d35e2fSjeremylt @param u Input vector (of size @a l_size when t_mode=@ref CEED_NOTRANSPOSE) 762d1d35e2fSjeremylt @param ru Output vector (of shape [@a blk_size * @a elem_size] when 763d1d35e2fSjeremylt t_mode=@ref CEED_NOTRANSPOSE). Ordering of the e-vector is decided 7647aaeacdcSjeremylt by the backend. 7654cc79fe7SJed Brown @param request Request or @ref CEED_REQUEST_IMMEDIATE 766be9261b7Sjeremylt 767be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure 768be9261b7Sjeremylt 7697a982d89SJeremy L. Thompson @ref Backend 770be9261b7Sjeremylt **/ 771be9261b7Sjeremylt int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, 772d1d35e2fSjeremylt CeedTransposeMode t_mode, CeedVector u, 773a8d32208Sjeremylt CeedVector ru, CeedRequest *request) { 774be9261b7Sjeremylt CeedInt m, n; 775be9261b7Sjeremylt int ierr; 776be9261b7Sjeremylt 777d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 778d1d35e2fSjeremylt m = rstr->blk_size * rstr->elem_size * rstr->num_comp; 779d1d35e2fSjeremylt n = rstr->l_size; 780be9261b7Sjeremylt } else { 781d1d35e2fSjeremylt m = rstr->l_size; 782d1d35e2fSjeremylt n = rstr->blk_size * rstr->elem_size * rstr->num_comp; 783be9261b7Sjeremylt } 784be9261b7Sjeremylt if (n != u->length) 785c042f62fSJeremy L Thompson // LCOV_EXCL_START 786e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 787e15f9bd0SJeremy L Thompson "Input vector size %d not compatible with " 7881d102b48SJeremy L Thompson "element restriction (%d, %d)", u->length, m, n); 789c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 790a8d32208Sjeremylt if (m != ru->length) 791c042f62fSJeremy L Thompson // LCOV_EXCL_START 792e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 793e15f9bd0SJeremy L Thompson "Output vector size %d not compatible with " 794a8d32208Sjeremylt "element restriction (%d, %d)", ru->length, m, n); 795c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 796d1d35e2fSjeremylt if (rstr->blk_size*block > rstr->num_elem) 797c042f62fSJeremy L Thompson // LCOV_EXCL_START 798e15f9bd0SJeremy L Thompson return CeedError(rstr->ceed, CEED_ERROR_DIMENSION, 799e15f9bd0SJeremy L Thompson "Cannot retrieve block %d, element %d > " 800d1d35e2fSjeremylt "total elements %d", block, rstr->blk_size*block, 801d1d35e2fSjeremylt rstr->num_elem); 802c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 803d1d35e2fSjeremylt ierr = rstr->ApplyBlock(rstr, block, t_mode, u, ru, request); 804be9261b7Sjeremylt CeedChk(ierr); 805e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 806be9261b7Sjeremylt } 807be9261b7Sjeremylt 808be9261b7Sjeremylt /** 809b7c9bbdaSJeremy L Thompson @brief Get the Ceed associated with a CeedElemRestriction 810b7c9bbdaSJeremy L Thompson 811b7c9bbdaSJeremy L Thompson @param rstr CeedElemRestriction 812b7c9bbdaSJeremy L Thompson @param[out] ceed Variable to store Ceed 813b7c9bbdaSJeremy L Thompson 814b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 815b7c9bbdaSJeremy L Thompson 816b7c9bbdaSJeremy L Thompson @ref Advanced 817b7c9bbdaSJeremy L Thompson **/ 818b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) { 819b7c9bbdaSJeremy L Thompson *ceed = rstr->ceed; 820b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 821b7c9bbdaSJeremy L Thompson } 822b7c9bbdaSJeremy L Thompson 823b7c9bbdaSJeremy L Thompson /** 824d979a051Sjeremylt @brief Get the L-vector component stride 825a681ae63Sjeremylt 826a681ae63Sjeremylt @param rstr CeedElemRestriction 827d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride 828a681ae63Sjeremylt 829a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 830a681ae63Sjeremylt 831b7c9bbdaSJeremy L Thompson @ref Advanced 832a681ae63Sjeremylt **/ 833d979a051Sjeremylt int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, 834d1d35e2fSjeremylt CeedInt *comp_stride) { 835d1d35e2fSjeremylt *comp_stride = rstr->comp_stride; 836e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 837a681ae63Sjeremylt } 838a681ae63Sjeremylt 839a681ae63Sjeremylt /** 840a681ae63Sjeremylt @brief Get the total number of elements in the range of a CeedElemRestriction 841a681ae63Sjeremylt 842a681ae63Sjeremylt @param rstr CeedElemRestriction 843d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements 844a681ae63Sjeremylt 845a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 846a681ae63Sjeremylt 847b7c9bbdaSJeremy L Thompson @ref Advanced 848a681ae63Sjeremylt **/ 849a681ae63Sjeremylt int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, 850d1d35e2fSjeremylt CeedInt *num_elem) { 851d1d35e2fSjeremylt *num_elem = rstr->num_elem; 852e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 853a681ae63Sjeremylt } 854a681ae63Sjeremylt 855a681ae63Sjeremylt /** 856a681ae63Sjeremylt @brief Get the size of elements in the CeedElemRestriction 857a681ae63Sjeremylt 858a681ae63Sjeremylt @param rstr CeedElemRestriction 859d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements 860a681ae63Sjeremylt 861a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 862a681ae63Sjeremylt 863b7c9bbdaSJeremy L Thompson @ref Advanced 864a681ae63Sjeremylt **/ 865a681ae63Sjeremylt int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, 866d1d35e2fSjeremylt CeedInt *elem_size) { 867d1d35e2fSjeremylt *elem_size = rstr->elem_size; 868e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 869a681ae63Sjeremylt } 870a681ae63Sjeremylt 871a681ae63Sjeremylt /** 872d979a051Sjeremylt @brief Get the size of the l-vector for a CeedElemRestriction 873a681ae63Sjeremylt 874a681ae63Sjeremylt @param rstr CeedElemRestriction 875d1d35e2fSjeremylt @param[out] l_size Variable to store number of nodes 876a681ae63Sjeremylt 877a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 878a681ae63Sjeremylt 879b7c9bbdaSJeremy L Thompson @ref Advanced 880a681ae63Sjeremylt **/ 881d979a051Sjeremylt int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, 882e79b91d9SJeremy L Thompson CeedSize *l_size) { 883d1d35e2fSjeremylt *l_size = rstr->l_size; 884e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 885a681ae63Sjeremylt } 886a681ae63Sjeremylt 887a681ae63Sjeremylt /** 888a681ae63Sjeremylt @brief Get the number of components in the elements of a 889a681ae63Sjeremylt CeedElemRestriction 890a681ae63Sjeremylt 891a681ae63Sjeremylt @param rstr CeedElemRestriction 892d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components 893a681ae63Sjeremylt 894a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 895a681ae63Sjeremylt 896b7c9bbdaSJeremy L Thompson @ref Advanced 897a681ae63Sjeremylt **/ 898a681ae63Sjeremylt int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, 899d1d35e2fSjeremylt CeedInt *num_comp) { 900d1d35e2fSjeremylt *num_comp = rstr->num_comp; 901e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 902a681ae63Sjeremylt } 903a681ae63Sjeremylt 904a681ae63Sjeremylt /** 905a681ae63Sjeremylt @brief Get the number of blocks in a CeedElemRestriction 906a681ae63Sjeremylt 907a681ae63Sjeremylt @param rstr CeedElemRestriction 908d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks 909a681ae63Sjeremylt 910a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 911a681ae63Sjeremylt 912b7c9bbdaSJeremy L Thompson @ref Advanced 913a681ae63Sjeremylt **/ 914a681ae63Sjeremylt int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, 915d1d35e2fSjeremylt CeedInt *num_block) { 916d1d35e2fSjeremylt *num_block = rstr->num_blk; 917e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 918a681ae63Sjeremylt } 919a681ae63Sjeremylt 920a681ae63Sjeremylt /** 921a681ae63Sjeremylt @brief Get the size of blocks in the CeedElemRestriction 922a681ae63Sjeremylt 923a681ae63Sjeremylt @param rstr CeedElemRestriction 924d1d35e2fSjeremylt @param[out] blk_size Variable to store size of blocks 925a681ae63Sjeremylt 926a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure 927a681ae63Sjeremylt 928b7c9bbdaSJeremy L Thompson @ref Advanced 929a681ae63Sjeremylt **/ 930a681ae63Sjeremylt int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, 931d1d35e2fSjeremylt CeedInt *blk_size) { 932d1d35e2fSjeremylt *blk_size = rstr->blk_size; 933e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 934a681ae63Sjeremylt } 935a681ae63Sjeremylt 936a681ae63Sjeremylt /** 937d9e1f99aSValeria Barra @brief Get the multiplicity of nodes in a CeedElemRestriction 9381469ee4dSjeremylt 9391469ee4dSjeremylt @param rstr CeedElemRestriction 940d1d35e2fSjeremylt @param[out] mult Vector to store multiplicity (of size l_size) 9411469ee4dSjeremylt 9421469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure 9431469ee4dSjeremylt 9447a982d89SJeremy L. Thompson @ref User 9451469ee4dSjeremylt **/ 9461469ee4dSjeremylt int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, 9471469ee4dSjeremylt CeedVector mult) { 9481469ee4dSjeremylt int ierr; 949d1d35e2fSjeremylt CeedVector e_vec; 9501469ee4dSjeremylt 95125509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1) 952d1d35e2fSjeremylt ierr = CeedElemRestrictionCreateVector(rstr, NULL, &e_vec); CeedChk(ierr); 9531469ee4dSjeremylt 95425509ebbSRezgar Shakeri // Compute e_vec = E * 1 95525509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 1.0); CeedChk(ierr); 95625509ebbSRezgar Shakeri ierr = CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, 95725509ebbSRezgar Shakeri CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 95825509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1) 95925509ebbSRezgar Shakeri ierr = CeedVectorSetValue(mult, 0.0); CeedChk(ierr); 960d1d35e2fSjeremylt ierr = CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, 961efc78312Sjeremylt CEED_REQUEST_IMMEDIATE); CeedChk(ierr); 9621469ee4dSjeremylt // Cleanup 963d1d35e2fSjeremylt ierr = CeedVectorDestroy(&e_vec); CeedChk(ierr); 964e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 9651469ee4dSjeremylt } 9661469ee4dSjeremylt 9671469ee4dSjeremylt /** 968f02ca4a2SJed Brown @brief View a CeedElemRestriction 969f02ca4a2SJed Brown 970f02ca4a2SJed Brown @param[in] rstr CeedElemRestriction to view 971f02ca4a2SJed Brown @param[in] stream Stream to write; typically stdout/stderr or a file 972f02ca4a2SJed Brown 973f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure 974f02ca4a2SJed Brown 9757a982d89SJeremy L. Thompson @ref User 976f02ca4a2SJed Brown **/ 977f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) { 9787509a596Sjeremylt char stridesstr[500]; 9797509a596Sjeremylt if (rstr->strides) 9807509a596Sjeremylt sprintf(stridesstr, "[%d, %d, %d]", rstr->strides[0], rstr->strides[1], 9817509a596Sjeremylt rstr->strides[2]); 982d979a051Sjeremylt else 983d1d35e2fSjeremylt sprintf(stridesstr, "%d", rstr->comp_stride); 9847509a596Sjeremylt 9855b76854bSJeremy L Thompson fprintf(stream, "%sCeedElemRestriction from (%td, %d) to %d elements with %d " 986d1d35e2fSjeremylt "nodes each and %s %s\n", rstr->blk_size > 1 ? "Blocked " : "", 987d1d35e2fSjeremylt rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size, 988d979a051Sjeremylt rstr->strides ? "strides" : "component stride", stridesstr); 989e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 990f02ca4a2SJed Brown } 991f02ca4a2SJed Brown 992f02ca4a2SJed Brown /** 993b11c1e72Sjeremylt @brief Destroy a CeedElemRestriction 994b11c1e72Sjeremylt 9954ce2993fSjeremylt @param rstr CeedElemRestriction to destroy 996b11c1e72Sjeremylt 997b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 998dfdf5a53Sjeremylt 9997a982d89SJeremy L. Thompson @ref User 1000b11c1e72Sjeremylt **/ 10014ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) { 1002d7b241e6Sjeremylt int ierr; 1003d7b241e6Sjeremylt 1004d1d35e2fSjeremylt if (!*rstr || --(*rstr)->ref_count > 0) return CEED_ERROR_SUCCESS; 1005d1d35e2fSjeremylt if ((*rstr)->num_readers) 10068229195eSjeremylt // LCOV_EXCL_START 1007e15f9bd0SJeremy L Thompson return CeedError((*rstr)->ceed, CEED_ERROR_ACCESS, 1008e15f9bd0SJeremy L Thompson "Cannot destroy CeedElemRestriction, " 1009430758c8SJeremy L Thompson "a process has read access to the offset data"); 10108229195eSjeremylt // LCOV_EXCL_STOP 10114ce2993fSjeremylt if ((*rstr)->Destroy) { 10124ce2993fSjeremylt ierr = (*rstr)->Destroy(*rstr); CeedChk(ierr); 1013d7b241e6Sjeremylt } 10147509a596Sjeremylt ierr = CeedFree(&(*rstr)->strides); CeedChk(ierr); 10154ce2993fSjeremylt ierr = CeedDestroy(&(*rstr)->ceed); CeedChk(ierr); 10164ce2993fSjeremylt ierr = CeedFree(rstr); CeedChk(ierr); 1017e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1018d7b241e6Sjeremylt } 1019d7b241e6Sjeremylt 1020d7b241e6Sjeremylt /// @} 1021