19ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3d7b241e6Sjeremylt //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5d7b241e6Sjeremylt //
63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed
7d7b241e6Sjeremylt
83d576824SJeremy L Thompson #include <ceed-impl.h>
949aac155SJeremy L Thompson #include <ceed.h>
102b730f8bSJeremy L Thompson #include <ceed/backend.h>
113d576824SJeremy L Thompson #include <stdbool.h>
123d576824SJeremy L Thompson #include <stdio.h>
13c17ec2beSJeremy L Thompson #include <string.h>
14d7b241e6Sjeremylt
157a982d89SJeremy L. Thompson /// @file
167a982d89SJeremy L. Thompson /// Implementation of CeedElemRestriction interfaces
177a982d89SJeremy L. Thompson
187a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
197a982d89SJeremy L. Thompson /// CeedElemRestriction Library Internal Functions
207a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
217a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionDeveloper
227a982d89SJeremy L. Thompson /// @{
237a982d89SJeremy L. Thompson
247a982d89SJeremy L. Thompson /**
25ca94c3ddSJeremy L Thompson @brief Permute and pad offsets for a blocked `CeedElemRestriction`
267a982d89SJeremy L. Thompson
27ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`
28ca94c3ddSJeremy L Thompson @param[out] block_offsets Array of permuted and padded array values of shape `[num_block, elem_size, block_size]`
29e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks
30ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements
31e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block
32ea61e9acSJeremy L Thompson @param[in] elem_size Size of each element
337a982d89SJeremy L. Thompson
347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
357a982d89SJeremy L. Thompson
367a982d89SJeremy L. Thompson @ref Utility
377a982d89SJeremy L. Thompson **/
CeedPermutePadOffsets(const CeedInt * offsets,CeedInt * block_offsets,CeedInt num_block,CeedInt num_elem,CeedInt block_size,CeedInt elem_size)38e7f679fcSJeremy L Thompson int CeedPermutePadOffsets(const CeedInt *offsets, CeedInt *block_offsets, CeedInt num_block, CeedInt num_elem, CeedInt block_size,
39e7f679fcSJeremy L Thompson CeedInt elem_size) {
40e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) {
41e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) {
422b730f8bSJeremy L Thompson for (CeedInt k = 0; k < elem_size; k++) {
43e7f679fcSJeremy L Thompson block_offsets[e * elem_size + k * block_size + j] = offsets[CeedIntMin(e + j, num_elem - 1) * elem_size + k];
442b730f8bSJeremy L Thompson }
452b730f8bSJeremy L Thompson }
462b730f8bSJeremy L Thompson }
47e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
487a982d89SJeremy L. Thompson }
497a982d89SJeremy L. Thompson
5077d1c127SSebastian Grimberg /**
51ca94c3ddSJeremy L Thompson @brief Permute and pad orientations for a blocked `CeedElemRestriction`
5277d1c127SSebastian Grimberg
53ca94c3ddSJeremy L Thompson @param[in] orients Array of shape `[num_elem, elem_size]`
54ca94c3ddSJeremy L Thompson @param[out] block_orients Array of permuted and padded array values of shape `[num_block, elem_size, block_size]`
55e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks
5677d1c127SSebastian Grimberg @param[in] num_elem Number of elements
57e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block
5877d1c127SSebastian Grimberg @param[in] elem_size Size of each element
5977d1c127SSebastian Grimberg
6077d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
6177d1c127SSebastian Grimberg
6277d1c127SSebastian Grimberg @ref Utility
6377d1c127SSebastian Grimberg **/
CeedPermutePadOrients(const bool * orients,bool * block_orients,CeedInt num_block,CeedInt num_elem,CeedInt block_size,CeedInt elem_size)64e7f679fcSJeremy L Thompson int CeedPermutePadOrients(const bool *orients, bool *block_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size, CeedInt elem_size) {
65e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) {
66e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) {
6777d1c127SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) {
68e7f679fcSJeremy L Thompson block_orients[e * elem_size + k * block_size + j] = orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k];
6977d1c127SSebastian Grimberg }
7077d1c127SSebastian Grimberg }
7177d1c127SSebastian Grimberg }
7277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
7377d1c127SSebastian Grimberg }
7477d1c127SSebastian Grimberg
750c73c039SSebastian Grimberg /**
76ca94c3ddSJeremy L Thompson @brief Permute and pad curl-conforming orientations for a blocked `CeedElemRestriction`
770c73c039SSebastian Grimberg
785c7e0f51SSebastian Grimberg @param[in] curl_orients Array of shape `[num_elem, elem_size]`
79ca94c3ddSJeremy L Thompson @param[out] block_curl_orients Array of permuted and padded array values of shape `[num_block, elem_size, block_size]`
80e7f679fcSJeremy L Thompson @param[in] num_block Number of blocks
810c73c039SSebastian Grimberg @param[in] num_elem Number of elements
82e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block
830c73c039SSebastian Grimberg @param[in] elem_size Size of each element
840c73c039SSebastian Grimberg
850c73c039SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
860c73c039SSebastian Grimberg
870c73c039SSebastian Grimberg @ref Utility
880c73c039SSebastian Grimberg **/
CeedPermutePadCurlOrients(const CeedInt8 * curl_orients,CeedInt8 * block_curl_orients,CeedInt num_block,CeedInt num_elem,CeedInt block_size,CeedInt elem_size)89e7f679fcSJeremy L Thompson int CeedPermutePadCurlOrients(const CeedInt8 *curl_orients, CeedInt8 *block_curl_orients, CeedInt num_block, CeedInt num_elem, CeedInt block_size,
900c73c039SSebastian Grimberg CeedInt elem_size) {
91e7f679fcSJeremy L Thompson for (CeedInt e = 0; e < num_block * block_size; e += block_size) {
92e7f679fcSJeremy L Thompson for (CeedInt j = 0; j < block_size; j++) {
930c73c039SSebastian Grimberg for (CeedInt k = 0; k < elem_size; k++) {
94e7f679fcSJeremy L Thompson block_curl_orients[e * elem_size + k * block_size + j] = curl_orients[CeedIntMin(e + j, num_elem - 1) * elem_size + k];
950c73c039SSebastian Grimberg }
960c73c039SSebastian Grimberg }
970c73c039SSebastian Grimberg }
980c73c039SSebastian Grimberg return CEED_ERROR_SUCCESS;
990c73c039SSebastian Grimberg }
1000c73c039SSebastian Grimberg
101b0f67a9cSJeremy L Thompson /**
102b0f67a9cSJeremy L Thompson @brief View a `CeedElemRestriction` passed as a `CeedObject`
103b0f67a9cSJeremy L Thompson
104b0f67a9cSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view
105b0f67a9cSJeremy L Thompson @param[in] stream Filestream to write to
106b0f67a9cSJeremy L Thompson
107b0f67a9cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
108b0f67a9cSJeremy L Thompson
109b0f67a9cSJeremy L Thompson @ref Developer
110b0f67a9cSJeremy L Thompson **/
CeedElemRestrictionView_Object(CeedObject rstr,FILE * stream)111b0f67a9cSJeremy L Thompson static int CeedElemRestrictionView_Object(CeedObject rstr, FILE *stream) {
112b0f67a9cSJeremy L Thompson CeedCall(CeedElemRestrictionView((CeedElemRestriction)rstr, stream));
113b0f67a9cSJeremy L Thompson return CEED_ERROR_SUCCESS;
114b0f67a9cSJeremy L Thompson }
115b0f67a9cSJeremy L Thompson
116*6c328a79SJeremy L Thompson /**
117*6c328a79SJeremy L Thompson @brief Destroy a `CeedElemRestricton` passed as a `CeedObject`
118*6c328a79SJeremy L Thompson
119*6c328a79SJeremy L Thompson @param[in,out] rstr Address of `CeedElemRestriction` to destroy
120*6c328a79SJeremy L Thompson
121*6c328a79SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
122*6c328a79SJeremy L Thompson
123*6c328a79SJeremy L Thompson @ref Developer
124*6c328a79SJeremy L Thompson **/
CeedElemRestrictionDestroy_Object(CeedObject * rstr)125*6c328a79SJeremy L Thompson static int CeedElemRestrictionDestroy_Object(CeedObject *rstr) {
126*6c328a79SJeremy L Thompson CeedCall(CeedElemRestrictionDestroy((CeedElemRestriction *)rstr));
127*6c328a79SJeremy L Thompson return CEED_ERROR_SUCCESS;
128*6c328a79SJeremy L Thompson }
129*6c328a79SJeremy L Thompson
1307a982d89SJeremy L. Thompson /// @}
1317a982d89SJeremy L. Thompson
1327a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
1337a982d89SJeremy L. Thompson /// CeedElemRestriction Backend API
1347a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
1357a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionBackend
1367a982d89SJeremy L. Thompson /// @{
1377a982d89SJeremy L. Thompson
1387a982d89SJeremy L. Thompson /**
139ca94c3ddSJeremy L Thompson @brief Get the type of a `CeedElemRestriction`
140a681ae63Sjeremylt
141ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
142fcbe8c06SSebastian Grimberg @param[out] rstr_type Variable to store restriction type
143fcbe8c06SSebastian Grimberg
144fcbe8c06SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
145fcbe8c06SSebastian Grimberg
146fcbe8c06SSebastian Grimberg @ref Backend
147fcbe8c06SSebastian Grimberg **/
CeedElemRestrictionGetType(CeedElemRestriction rstr,CeedRestrictionType * rstr_type)148fcbe8c06SSebastian Grimberg int CeedElemRestrictionGetType(CeedElemRestriction rstr, CeedRestrictionType *rstr_type) {
149fcbe8c06SSebastian Grimberg *rstr_type = rstr->rstr_type;
150fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS;
151fcbe8c06SSebastian Grimberg }
152fcbe8c06SSebastian Grimberg
153fcbe8c06SSebastian Grimberg /**
154ca94c3ddSJeremy L Thompson @brief Get the strided status of a `CeedElemRestriction`
155fcbe8c06SSebastian Grimberg
156ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
157ca94c3ddSJeremy L Thompson @param[out] is_strided Variable to store strided status
158ca94c3ddSJeremy L Thompson
159ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
160ca94c3ddSJeremy L Thompson
161ca94c3ddSJeremy L Thompson @ref Backend
162fcbe8c06SSebastian Grimberg **/
CeedElemRestrictionIsStrided(CeedElemRestriction rstr,bool * is_strided)163fcbe8c06SSebastian Grimberg int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) {
164fcbe8c06SSebastian Grimberg *is_strided = (rstr->rstr_type == CEED_RESTRICTION_STRIDED);
165fcbe8c06SSebastian Grimberg return CEED_ERROR_SUCCESS;
166fcbe8c06SSebastian Grimberg }
167fcbe8c06SSebastian Grimberg
168fcbe8c06SSebastian Grimberg /**
169ca94c3ddSJeremy L Thompson @brief Get the points status of a `CeedElemRestriction`
1703ac8f562SJeremy L Thompson
171ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
172ca94c3ddSJeremy L Thompson @param[out] is_points Variable to store points status
173ca94c3ddSJeremy L Thompson
174ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
175ca94c3ddSJeremy L Thompson
176ca94c3ddSJeremy L Thompson @ref Backend
1773ac8f562SJeremy L Thompson **/
CeedElemRestrictionIsAtPoints(CeedElemRestriction rstr,bool * is_points)178637baffdSJeremy L Thompson int CeedElemRestrictionIsAtPoints(CeedElemRestriction rstr, bool *is_points) {
1793ac8f562SJeremy L Thompson *is_points = (rstr->rstr_type == CEED_RESTRICTION_POINTS);
1803ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS;
1813ac8f562SJeremy L Thompson }
1823ac8f562SJeremy L Thompson
1833ac8f562SJeremy L Thompson /**
184ca94c3ddSJeremy L Thompson @brief Check if two `CeedElemRestriction` created with @ref CeedElemRestrictionCreateAtPoints() and use the same points per element
18548acf710SJeremy L Thompson
186ca94c3ddSJeremy L Thompson @param[in] rstr_a First `CeedElemRestriction`
187ca94c3ddSJeremy L Thompson @param[in] rstr_b Second `CeedElemRestriction`
18848acf710SJeremy L Thompson @param[out] are_compatible Variable to store compatibility status
189ca94c3ddSJeremy L Thompson
190ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
191ca94c3ddSJeremy L Thompson
192ca94c3ddSJeremy L Thompson @ref Backend
19348acf710SJeremy L Thompson **/
CeedElemRestrictionAtPointsAreCompatible(CeedElemRestriction rstr_a,CeedElemRestriction rstr_b,bool * are_compatible)19448acf710SJeremy L Thompson int CeedElemRestrictionAtPointsAreCompatible(CeedElemRestriction rstr_a, CeedElemRestriction rstr_b, bool *are_compatible) {
19548acf710SJeremy L Thompson CeedInt num_elem_a, num_elem_b, num_points_a, num_points_b;
19648acf710SJeremy L Thompson
19748acf710SJeremy L Thompson // Cannot compare non-points restrictions
1989bc66399SJeremy L Thompson CeedCheck(rstr_a->rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr_a), CEED_ERROR_UNSUPPORTED,
1999bc66399SJeremy L Thompson "First CeedElemRestriction must be AtPoints");
2009bc66399SJeremy L Thompson CeedCheck(rstr_b->rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr_a), CEED_ERROR_UNSUPPORTED,
2019bc66399SJeremy L Thompson "Second CeedElemRestriction must be AtPoints");
20248acf710SJeremy L Thompson
20348acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_a, &num_elem_a));
20448acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr_b, &num_elem_b));
20548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_a, &num_points_a));
20648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPoints(rstr_b, &num_points_b));
20748acf710SJeremy L Thompson
20848acf710SJeremy L Thompson // Check size and contents of offsets arrays
20948acf710SJeremy L Thompson *are_compatible = true;
21048acf710SJeremy L Thompson if (num_elem_a != num_elem_b) *are_compatible = false;
21148acf710SJeremy L Thompson if (num_points_a != num_points_b) *are_compatible = false;
21248acf710SJeremy L Thompson if (*are_compatible) {
21348acf710SJeremy L Thompson const CeedInt *offsets_a, *offsets_b;
21448acf710SJeremy L Thompson
21548acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_a, CEED_MEM_HOST, &offsets_a));
21648acf710SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr_b, CEED_MEM_HOST, &offsets_b));
21748acf710SJeremy L Thompson for (CeedInt i = 0; i < num_elem_a + 1 + num_points_a; i++) *are_compatible &= offsets_a[i] == offsets_b[i];
21848acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_a, &offsets_a));
21948acf710SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr_b, &offsets_b));
22048acf710SJeremy L Thompson }
22148acf710SJeremy L Thompson return CEED_ERROR_SUCCESS;
22248acf710SJeremy L Thompson }
22348acf710SJeremy L Thompson
22448acf710SJeremy L Thompson /**
225ca94c3ddSJeremy L Thompson @brief Get the strides of a strided `CeedElemRestriction`
2267a982d89SJeremy L. Thompson
227ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
228a681ae63Sjeremylt @param[out] strides Variable to store strides array
2297a982d89SJeremy L. Thompson
2307a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
2317a982d89SJeremy L. Thompson
2327a982d89SJeremy L. Thompson @ref Backend
2337a982d89SJeremy L. Thompson **/
CeedElemRestrictionGetStrides(CeedElemRestriction rstr,CeedInt strides[3])23456c48462SJeremy L Thompson int CeedElemRestrictionGetStrides(CeedElemRestriction rstr, CeedInt strides[3]) {
2356e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data");
23656c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) strides[i] = rstr->strides[i];
237e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
2387a982d89SJeremy L. Thompson }
2397a982d89SJeremy L. Thompson
2407a982d89SJeremy L. Thompson /**
241ca94c3ddSJeremy L Thompson @brief Get the backend stride status of a `CeedElemRestriction`
24277d1c127SSebastian Grimberg
243ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
24477d1c127SSebastian Grimberg @param[out] has_backend_strides Variable to store stride status
24577d1c127SSebastian Grimberg
24677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
24777d1c127SSebastian Grimberg
24877d1c127SSebastian Grimberg @ref Backend
24977d1c127SSebastian Grimberg **/
CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr,bool * has_backend_strides)25077d1c127SSebastian Grimberg int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr, bool *has_backend_strides) {
2516e536b99SJeremy L Thompson CeedCheck(rstr->strides, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no stride data");
25277d1c127SSebastian Grimberg *has_backend_strides = ((rstr->strides[0] == CEED_STRIDES_BACKEND[0]) && (rstr->strides[1] == CEED_STRIDES_BACKEND[1]) &&
25377d1c127SSebastian Grimberg (rstr->strides[2] == CEED_STRIDES_BACKEND[2]));
25477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
25577d1c127SSebastian Grimberg }
25677d1c127SSebastian Grimberg
25777d1c127SSebastian Grimberg /**
258ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` offsets array by @ref CeedMemType
259bd33150aSjeremylt
260ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve offsets
261fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array.
262fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached).
263ca94c3ddSJeremy L Thompson @param[out] offsets Array on memory type `mem_type`
264bd33150aSjeremylt
265bd33150aSjeremylt @return An error code: 0 - success, otherwise - failure
266bd33150aSjeremylt
267bd33150aSjeremylt @ref User
268bd33150aSjeremylt **/
CeedElemRestrictionGetOffsets(CeedElemRestriction rstr,CeedMemType mem_type,const CeedInt ** offsets)2692b730f8bSJeremy L Thompson int CeedElemRestrictionGetOffsets(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) {
2707c1dbaffSSebastian Grimberg if (rstr->rstr_base) {
2717c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionGetOffsets(rstr->rstr_base, mem_type, offsets));
272c17ec2beSJeremy L Thompson } else {
2736e536b99SJeremy L Thompson CeedCheck(rstr->GetOffsets, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED,
2741ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetOffsets");
2752b730f8bSJeremy L Thompson CeedCall(rstr->GetOffsets(rstr, mem_type, offsets));
276d1d35e2fSjeremylt rstr->num_readers++;
277c17ec2beSJeremy L Thompson }
278e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
279430758c8SJeremy L Thompson }
280430758c8SJeremy L Thompson
281430758c8SJeremy L Thompson /**
282ca94c3ddSJeremy L Thompson @brief Restore an offsets array obtained using @ref CeedElemRestrictionGetOffsets()
283430758c8SJeremy L Thompson
284ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore
285ea61e9acSJeremy L Thompson @param[in] offsets Array of offset data
286430758c8SJeremy L Thompson
287430758c8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
288430758c8SJeremy L Thompson
289430758c8SJeremy L Thompson @ref User
290430758c8SJeremy L Thompson **/
CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,const CeedInt ** offsets)2912b730f8bSJeremy L Thompson int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr, const CeedInt **offsets) {
2927c1dbaffSSebastian Grimberg if (rstr->rstr_base) {
2937c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionRestoreOffsets(rstr->rstr_base, offsets));
294c17ec2beSJeremy L Thompson } else {
295430758c8SJeremy L Thompson *offsets = NULL;
296d1d35e2fSjeremylt rstr->num_readers--;
297c17ec2beSJeremy L Thompson }
298e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
299bd33150aSjeremylt }
300bd33150aSjeremylt
301bd33150aSjeremylt /**
302ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` orientations array by @ref CeedMemType
3033ac43b2cSJeremy L Thompson
304ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve orientations
305fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array.
306fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached).
307ca94c3ddSJeremy L Thompson @param[out] orients Array on memory type `mem_type`
3083ac43b2cSJeremy L Thompson
3093ac43b2cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
3103ac43b2cSJeremy L Thompson
31177d1c127SSebastian Grimberg @ref User
3123ac43b2cSJeremy L Thompson **/
CeedElemRestrictionGetOrientations(CeedElemRestriction rstr,CeedMemType mem_type,const bool ** orients)31377d1c127SSebastian Grimberg int CeedElemRestrictionGetOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) {
3146e536b99SJeremy L Thompson CeedCheck(rstr->GetOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED,
3151ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetOrientations");
31677d1c127SSebastian Grimberg CeedCall(rstr->GetOrientations(rstr, mem_type, orients));
31777d1c127SSebastian Grimberg rstr->num_readers++;
318e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
3193ac43b2cSJeremy L Thompson }
3203ac43b2cSJeremy L Thompson
3213ac43b2cSJeremy L Thompson /**
322ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetOrientations()
323b435c5a6Srezgarshakeri
324ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore
32577d1c127SSebastian Grimberg @param[in] orients Array of orientation data
326b435c5a6Srezgarshakeri
327b435c5a6Srezgarshakeri @return An error code: 0 - success, otherwise - failure
328b435c5a6Srezgarshakeri
32977d1c127SSebastian Grimberg @ref User
330b435c5a6Srezgarshakeri **/
CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr,const bool ** orients)33177d1c127SSebastian Grimberg int CeedElemRestrictionRestoreOrientations(CeedElemRestriction rstr, const bool **orients) {
33277d1c127SSebastian Grimberg *orients = NULL;
33377d1c127SSebastian Grimberg rstr->num_readers--;
334b435c5a6Srezgarshakeri return CEED_ERROR_SUCCESS;
335b435c5a6Srezgarshakeri }
336b435c5a6Srezgarshakeri
337b435c5a6Srezgarshakeri /**
338ca94c3ddSJeremy L Thompson @brief Get read-only access to a `CeedElemRestriction` curl-conforming orientations array by @ref CeedMemType
3397a982d89SJeremy L. Thompson
340ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to retrieve curl-conforming orientations
341fcbe8c06SSebastian Grimberg @param[in] mem_type Memory type on which to access the array.
342fcbe8c06SSebastian Grimberg If the backend uses a different memory type, this will perform a copy (possibly cached).
343ca94c3ddSJeremy L Thompson @param[out] curl_orients Array on memory type `mem_type`
3447a982d89SJeremy L. Thompson
3457a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
3467a982d89SJeremy L. Thompson
34777d1c127SSebastian Grimberg @ref User
3487a982d89SJeremy L. Thompson **/
CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr,CeedMemType mem_type,const CeedInt8 ** curl_orients)3490c73c039SSebastian Grimberg int CeedElemRestrictionGetCurlOrientations(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) {
3506e536b99SJeremy L Thompson CeedCheck(rstr->GetCurlOrientations, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED,
3511ef3a2a9SJeremy L Thompson "Backend does not implement CeedElemRestrictionGetCurlOrientations");
35277d1c127SSebastian Grimberg CeedCall(rstr->GetCurlOrientations(rstr, mem_type, curl_orients));
35377d1c127SSebastian Grimberg rstr->num_readers++;
35477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
35577d1c127SSebastian Grimberg }
35677d1c127SSebastian Grimberg
35777d1c127SSebastian Grimberg /**
358ca94c3ddSJeremy L Thompson @brief Restore an orientations array obtained using @ref CeedElemRestrictionGetCurlOrientations()
35977d1c127SSebastian Grimberg
360ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to restore
36177d1c127SSebastian Grimberg @param[in] curl_orients Array of orientation data
36277d1c127SSebastian Grimberg
36377d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
36477d1c127SSebastian Grimberg
36577d1c127SSebastian Grimberg @ref User
36677d1c127SSebastian Grimberg **/
CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr,const CeedInt8 ** curl_orients)3670c73c039SSebastian Grimberg int CeedElemRestrictionRestoreCurlOrientations(CeedElemRestriction rstr, const CeedInt8 **curl_orients) {
36877d1c127SSebastian Grimberg *curl_orients = NULL;
36977d1c127SSebastian Grimberg rstr->num_readers--;
370e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
3717a982d89SJeremy L. Thompson }
3727a982d89SJeremy L. Thompson
3737a982d89SJeremy L. Thompson /**
37449fd234cSJeremy L Thompson
37522eb1385SJeremy L Thompson @brief Get the L-vector layout of a strided `CeedElemRestriction`
37622eb1385SJeremy L Thompson
37722eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction`
37822eb1385SJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`.
37922eb1385SJeremy L Thompson The data for node `i`, component `j`, element `k` in the E-vector is given by `i*layout[0] + j*layout[1] + k*layout[2]`.
38022eb1385SJeremy L Thompson
38122eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
38222eb1385SJeremy L Thompson
38322eb1385SJeremy L Thompson @ref Backend
38422eb1385SJeremy L Thompson **/
CeedElemRestrictionGetLLayout(CeedElemRestriction rstr,CeedInt layout[3])38556c48462SJeremy L Thompson int CeedElemRestrictionGetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) {
38622eb1385SJeremy L Thompson bool has_backend_strides;
38722eb1385SJeremy L Thompson CeedRestrictionType rstr_type;
38822eb1385SJeremy L Thompson
38922eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
3909bc66399SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR,
3919bc66399SJeremy L Thompson "Only strided CeedElemRestriction have strided L-vector layout");
39222eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides));
39322eb1385SJeremy L Thompson if (has_backend_strides) {
3949bc66399SJeremy L Thompson CeedCheck(rstr->l_layout[0], CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no L-vector layout data");
39556c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->l_layout[i];
39622eb1385SJeremy L Thompson } else {
39722eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetStrides(rstr, layout));
39822eb1385SJeremy L Thompson }
39922eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS;
40022eb1385SJeremy L Thompson }
40122eb1385SJeremy L Thompson
40222eb1385SJeremy L Thompson /**
40322eb1385SJeremy L Thompson
40422eb1385SJeremy L Thompson @brief Set the L-vector layout of a strided `CeedElemRestriction`
40522eb1385SJeremy L Thompson
40622eb1385SJeremy L Thompson @param[in] rstr `CeedElemRestriction`
40722eb1385SJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`.
40822eb1385SJeremy L Thompson The data for node `i`, component `j`, element `k` in the E-vector is given by `i*layout[0] + j*layout[1] + k*layout[2]`.
40922eb1385SJeremy L Thompson
41022eb1385SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
41122eb1385SJeremy L Thompson
41222eb1385SJeremy L Thompson @ref Backend
41322eb1385SJeremy L Thompson **/
CeedElemRestrictionSetLLayout(CeedElemRestriction rstr,CeedInt layout[3])41422eb1385SJeremy L Thompson int CeedElemRestrictionSetLLayout(CeedElemRestriction rstr, CeedInt layout[3]) {
41522eb1385SJeremy L Thompson CeedRestrictionType rstr_type;
41622eb1385SJeremy L Thompson
41722eb1385SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
4186e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_STRIDED, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR,
4196e536b99SJeremy L Thompson "Only strided CeedElemRestriction have strided L-vector layout");
42022eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->l_layout[i] = layout[i];
42122eb1385SJeremy L Thompson return CEED_ERROR_SUCCESS;
42222eb1385SJeremy L Thompson }
42322eb1385SJeremy L Thompson
42422eb1385SJeremy L Thompson /**
42522eb1385SJeremy L Thompson
426ca94c3ddSJeremy L Thompson @brief Get the E-vector layout of a `CeedElemRestriction`
42749fd234cSJeremy L Thompson
428ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
429ca94c3ddSJeremy L Thompson @param[out] layout Variable to store layout array, stored as `[nodes, components, elements]`.
430ca94c3ddSJeremy L Thompson The data for node `i`, component `j`, element `k` in the E-vector is given by `i*layout[0] + j*layout[1] + k*layout[2]`.
43149fd234cSJeremy L Thompson
43249fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
43349fd234cSJeremy L Thompson
43449fd234cSJeremy L Thompson @ref Backend
43549fd234cSJeremy L Thompson **/
CeedElemRestrictionGetELayout(CeedElemRestriction rstr,CeedInt layout[3])43656c48462SJeremy L Thompson int CeedElemRestrictionGetELayout(CeedElemRestriction rstr, CeedInt layout[3]) {
4376e536b99SJeremy L Thompson CeedCheck(rstr->e_layout[0], CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_MINOR, "CeedElemRestriction has no E-vector layout data");
43856c48462SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) layout[i] = rstr->e_layout[i];
439e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
44049fd234cSJeremy L Thompson }
44149fd234cSJeremy L Thompson
44249fd234cSJeremy L Thompson /**
44349fd234cSJeremy L Thompson
444ca94c3ddSJeremy L Thompson @brief Set the E-vector layout of a `CeedElemRestriction`
44549fd234cSJeremy L Thompson
446ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
447ca94c3ddSJeremy L Thompson @param[in] layout Variable to containing layout array, stored as `[nodes, components, elements]`.
448ca94c3ddSJeremy L Thompson The data for node `i`, component `j`, element `k` in the E-vector is given by `i*layout[0] + j*layout[1] + k*layout[2]`.
44949fd234cSJeremy L Thompson
45049fd234cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
45149fd234cSJeremy L Thompson
45249fd234cSJeremy L Thompson @ref Backend
45349fd234cSJeremy L Thompson **/
CeedElemRestrictionSetELayout(CeedElemRestriction rstr,CeedInt layout[3])4542b730f8bSJeremy L Thompson int CeedElemRestrictionSetELayout(CeedElemRestriction rstr, CeedInt layout[3]) {
45522eb1385SJeremy L Thompson for (CeedInt i = 0; i < 3; i++) rstr->e_layout[i] = layout[i];
456e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
45749fd234cSJeremy L Thompson }
45849fd234cSJeremy L Thompson
45949fd234cSJeremy L Thompson /**
46019605835SJeremy L Thompson
46119605835SJeremy L Thompson @brief Get the E-vector element offset of a `CeedElemRestriction` at points
46219605835SJeremy L Thompson
46319605835SJeremy L Thompson @param[in] rstr `CeedElemRestriction`
46419605835SJeremy L Thompson @param[in] elem Element number index into E-vector for
46519605835SJeremy L Thompson @param[out] elem_offset Offset for element `elem` in the E-vector.
46619605835SJeremy L Thompson The data for point `i`, component `j`, element `elem` in the E-vector is given by `i*e_layout[0] + j*e_layout[1] + elem_offset`.
46719605835SJeremy L Thompson
46819605835SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
46919605835SJeremy L Thompson
47019605835SJeremy L Thompson @ref Backend
47119605835SJeremy L Thompson **/
CeedElemRestrictionGetAtPointsElementOffset(CeedElemRestriction rstr,CeedInt elem,CeedSize * elem_offset)47219605835SJeremy L Thompson int CeedElemRestrictionGetAtPointsElementOffset(CeedElemRestriction rstr, CeedInt elem, CeedSize *elem_offset) {
47319605835SJeremy L Thompson CeedInt num_comp;
47419605835SJeremy L Thompson CeedRestrictionType rstr_type;
47519605835SJeremy L Thompson
47619605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
47719605835SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE,
47819605835SJeremy L Thompson "Can only compute offset for a points CeedElemRestriction");
47919605835SJeremy L Thompson
48019605835SJeremy L Thompson // Backend method
48119605835SJeremy L Thompson if (rstr->GetAtPointsElementOffset) {
48219605835SJeremy L Thompson CeedCall(rstr->GetAtPointsElementOffset(rstr, elem, elem_offset));
48319605835SJeremy L Thompson return CEED_ERROR_SUCCESS;
48419605835SJeremy L Thompson }
48519605835SJeremy L Thompson
48619605835SJeremy L Thompson // Default layout (CPU)
48719605835SJeremy L Thompson *elem_offset = 0;
48819605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp));
48919605835SJeremy L Thompson for (CeedInt i = 0; i < elem; i++) {
49019605835SJeremy L Thompson CeedInt num_points;
49119605835SJeremy L Thompson
49219605835SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, i, &num_points));
49319605835SJeremy L Thompson *elem_offset += num_points * num_comp;
49419605835SJeremy L Thompson }
49519605835SJeremy L Thompson return CEED_ERROR_SUCCESS;
49619605835SJeremy L Thompson }
49719605835SJeremy L Thompson
49819605835SJeremy L Thompson /**
499ff1bc20eSJeremy L Thompson
500ff1bc20eSJeremy L Thompson @brief Set the E-vector size of a `CeedElemRestriction` at points
501ff1bc20eSJeremy L Thompson
502ff1bc20eSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction`
503ff1bc20eSJeremy L Thompson @param[in] e_size New E-vector size; must be longer than the current E-vector size
504ff1bc20eSJeremy L Thompson
505ff1bc20eSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
506ff1bc20eSJeremy L Thompson
507ff1bc20eSJeremy L Thompson @ref Backend
508ff1bc20eSJeremy L Thompson **/
CeedElemRestrictionSetAtPointsEVectorSize(CeedElemRestriction rstr,CeedSize e_size)509ff1bc20eSJeremy L Thompson int CeedElemRestrictionSetAtPointsEVectorSize(CeedElemRestriction rstr, CeedSize e_size) {
510ff1bc20eSJeremy L Thompson CeedRestrictionType rstr_type;
511ff1bc20eSJeremy L Thompson
512ff1bc20eSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
5139bc66399SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE,
5149bc66399SJeremy L Thompson "Can only compute offset for a points CeedElemRestriction");
5159bc66399SJeremy L Thompson CeedCheck(e_size >= rstr->e_size, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE,
5163f08121cSJeremy L Thompson "Can only increase the size of the E-vector for the CeedElemRestriction."
5173f08121cSJeremy L Thompson " Current size: %" CeedSize_FMT " New size: %" CeedSize_FMT,
5183f08121cSJeremy L Thompson rstr->e_size, e_size);
519ff1bc20eSJeremy L Thompson rstr->e_size = e_size;
520ff1bc20eSJeremy L Thompson return CEED_ERROR_SUCCESS;
521ff1bc20eSJeremy L Thompson }
522ff1bc20eSJeremy L Thompson
523ff1bc20eSJeremy L Thompson /**
524ca94c3ddSJeremy L Thompson @brief Get the backend data of a `CeedElemRestriction`
5257a982d89SJeremy L. Thompson
526ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
5277a982d89SJeremy L. Thompson @param[out] data Variable to store data
5287a982d89SJeremy L. Thompson
5297a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
5307a982d89SJeremy L. Thompson
5317a982d89SJeremy L. Thompson @ref Backend
5327a982d89SJeremy L. Thompson **/
CeedElemRestrictionGetData(CeedElemRestriction rstr,void * data)533777ff853SJeremy L Thompson int CeedElemRestrictionGetData(CeedElemRestriction rstr, void *data) {
534777ff853SJeremy L Thompson *(void **)data = rstr->data;
535e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
5367a982d89SJeremy L. Thompson }
5377a982d89SJeremy L. Thompson
5387a982d89SJeremy L. Thompson /**
539ca94c3ddSJeremy L Thompson @brief Set the backend data of a `CeedElemRestriction`
5407a982d89SJeremy L. Thompson
541ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction`
542ea61e9acSJeremy L Thompson @param[in] data Data to set
5437a982d89SJeremy L. Thompson
5447a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
5457a982d89SJeremy L. Thompson
5467a982d89SJeremy L. Thompson @ref Backend
5477a982d89SJeremy L. Thompson **/
CeedElemRestrictionSetData(CeedElemRestriction rstr,void * data)548777ff853SJeremy L Thompson int CeedElemRestrictionSetData(CeedElemRestriction rstr, void *data) {
549777ff853SJeremy L Thompson rstr->data = data;
550e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
5517a982d89SJeremy L. Thompson }
5527a982d89SJeremy L. Thompson
55334359f16Sjeremylt /**
554ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedElemRestriction`
55534359f16Sjeremylt
556ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to increment the reference counter
55734359f16Sjeremylt
55834359f16Sjeremylt @return An error code: 0 - success, otherwise - failure
55934359f16Sjeremylt
56034359f16Sjeremylt @ref Backend
56134359f16Sjeremylt **/
CeedElemRestrictionReference(CeedElemRestriction rstr)5629560d06aSjeremylt int CeedElemRestrictionReference(CeedElemRestriction rstr) {
563b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)rstr));
56434359f16Sjeremylt return CEED_ERROR_SUCCESS;
56534359f16Sjeremylt }
56634359f16Sjeremylt
5676e15d496SJeremy L Thompson /**
568ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs required to apply `CeedElemRestriction` in `t_mode`
5696e15d496SJeremy L Thompson
570ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to estimate FLOPs for
571ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose
572ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate
5736e15d496SJeremy L Thompson
5746e15d496SJeremy L Thompson @ref Backend
5756e15d496SJeremy L Thompson **/
CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr,CeedTransposeMode t_mode,CeedSize * flops)5762b730f8bSJeremy L Thompson int CeedElemRestrictionGetFlopsEstimate(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedSize *flops) {
5771203703bSJeremy L Thompson CeedSize e_size, scale = 0;
57889edb9e3SSebastian Grimberg CeedRestrictionType rstr_type;
5791c66c397SJeremy L Thompson
5801203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size));
58189edb9e3SSebastian Grimberg CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
58277d1c127SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) {
58389edb9e3SSebastian Grimberg switch (rstr_type) {
5843ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS:
5853ac8f562SJeremy L Thompson scale = 0;
5863ac8f562SJeremy L Thompson break;
58789edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED:
58889edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD:
58977d1c127SSebastian Grimberg scale = 1;
59089edb9e3SSebastian Grimberg break;
59189edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED:
59277d1c127SSebastian Grimberg scale = 2;
59389edb9e3SSebastian Grimberg break;
59489edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED:
59577d1c127SSebastian Grimberg scale = 6;
59689edb9e3SSebastian Grimberg break;
5976e15d496SJeremy L Thompson }
59877d1c127SSebastian Grimberg } else {
59989edb9e3SSebastian Grimberg switch (rstr_type) {
60089edb9e3SSebastian Grimberg case CEED_RESTRICTION_STRIDED:
60189edb9e3SSebastian Grimberg case CEED_RESTRICTION_STANDARD:
6023ac8f562SJeremy L Thompson case CEED_RESTRICTION_POINTS:
60377d1c127SSebastian Grimberg scale = 0;
60489edb9e3SSebastian Grimberg break;
60589edb9e3SSebastian Grimberg case CEED_RESTRICTION_ORIENTED:
60677d1c127SSebastian Grimberg scale = 1;
60789edb9e3SSebastian Grimberg break;
60889edb9e3SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED:
60977d1c127SSebastian Grimberg scale = 5;
61089edb9e3SSebastian Grimberg break;
61177d1c127SSebastian Grimberg }
61277d1c127SSebastian Grimberg }
6136e15d496SJeremy L Thompson *flops = e_size * scale;
6146e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS;
6156e15d496SJeremy L Thompson }
6166e15d496SJeremy L Thompson
6177a982d89SJeremy L. Thompson /// @}
6187a982d89SJeremy L. Thompson
61915910d16Sjeremylt /// @cond DOXYGEN_SKIP
62015910d16Sjeremylt static struct CeedElemRestriction_private ceed_elemrestriction_none;
62115910d16Sjeremylt /// @endcond
62215910d16Sjeremylt
6237a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
6247a982d89SJeremy L. Thompson /// CeedElemRestriction Public API
6257a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
6267a982d89SJeremy L. Thompson /// @addtogroup CeedElemRestrictionUser
627d7b241e6Sjeremylt /// @{
628d7b241e6Sjeremylt
6297a982d89SJeremy L. Thompson /// Indicate that the stride is determined by the backend
63045f1e315Sjeremylt const CeedInt CEED_STRIDES_BACKEND[3] = {0};
6317a982d89SJeremy L. Thompson
632ca94c3ddSJeremy L Thompson /// Argument for @ref CeedOperatorSetField() indicating that the field does not require a `CeedElemRestriction`
6332b730f8bSJeremy L Thompson const CeedElemRestriction CEED_ELEMRESTRICTION_NONE = &ceed_elemrestriction_none;
6347a982d89SJeremy L. Thompson
635d7b241e6Sjeremylt /**
636ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction`
637d7b241e6Sjeremylt
638ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
639ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array
640ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element
641ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields)
642fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node".
643ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `offsets[i + k*elem_size] + j*comp_stride`.
644fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
645fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
646ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType
647ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode
648ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`.
649ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where 0 <= i < @a num_elem.
650ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`.
651ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
652d7b241e6Sjeremylt
653b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
654dfdf5a53Sjeremylt
6557a982d89SJeremy L. Thompson @ref User
656b11c1e72Sjeremylt **/
CeedElemRestrictionCreate(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt num_comp,CeedInt comp_stride,CeedSize l_size,CeedMemType mem_type,CeedCopyMode copy_mode,const CeedInt * offsets,CeedElemRestriction * rstr)6572b730f8bSJeremy L Thompson int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size,
6582b730f8bSJeremy L Thompson CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) {
6595fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) {
6605fe0d4faSjeremylt Ceed delegate;
6616574a04fSJeremy L Thompson
6622b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
663ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreate");
6642b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreate(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, rstr));
6659bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
666e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
6675fe0d4faSjeremylt }
6685fe0d4faSjeremylt
669e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
6706574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
671ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
672ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1");
673e022e1f8SJeremy L Thompson
6742b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr));
675*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
676d1d35e2fSjeremylt (*rstr)->num_elem = num_elem;
677d1d35e2fSjeremylt (*rstr)->elem_size = elem_size;
678d1d35e2fSjeremylt (*rstr)->num_comp = num_comp;
679d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride;
680d1d35e2fSjeremylt (*rstr)->l_size = l_size;
6811203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp;
682e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem;
683e7f679fcSJeremy L Thompson (*rstr)->block_size = 1;
68461a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD;
685fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, NULL, *rstr));
686e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
687d7b241e6Sjeremylt }
688d7b241e6Sjeremylt
689d7b241e6Sjeremylt /**
690ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with orientation signs
691fc0567d9Srezgarshakeri
692ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
693ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array
694ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element
695ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields)
696fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node".
697ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `offsets[i + k*elem_size] + j*comp_stride`.
698fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
699fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
700ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType
701ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode
702ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`.
703ca94c3ddSJeremy L Thompson Row i holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`.
704ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`.
705ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation
706ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
707fc0567d9Srezgarshakeri
708fc0567d9Srezgarshakeri @return An error code: 0 - success, otherwise - failure
709fc0567d9Srezgarshakeri
710fc0567d9Srezgarshakeri @ref User
711fc0567d9Srezgarshakeri **/
CeedElemRestrictionCreateOriented(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt num_comp,CeedInt comp_stride,CeedSize l_size,CeedMemType mem_type,CeedCopyMode copy_mode,const CeedInt * offsets,const bool * orients,CeedElemRestriction * rstr)7122b730f8bSJeremy L Thompson int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size,
71377d1c127SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients,
714fc0567d9Srezgarshakeri CeedElemRestriction *rstr) {
715fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) {
716fc0567d9Srezgarshakeri Ceed delegate;
7176574a04fSJeremy L Thompson
7182b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
719ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateOriented");
7201a8516d0SJames Wright CeedCall(CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets, orients,
7211a8516d0SJames Wright rstr));
7229bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
723fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS;
724fc0567d9Srezgarshakeri }
725fc0567d9Srezgarshakeri
726e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
7276574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
728ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
729ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1");
730e022e1f8SJeremy L Thompson
7312b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr));
732*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
733fc0567d9Srezgarshakeri (*rstr)->num_elem = num_elem;
734fc0567d9Srezgarshakeri (*rstr)->elem_size = elem_size;
735fc0567d9Srezgarshakeri (*rstr)->num_comp = num_comp;
736fc0567d9Srezgarshakeri (*rstr)->comp_stride = comp_stride;
737fc0567d9Srezgarshakeri (*rstr)->l_size = l_size;
7381203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp;
739e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem;
740e7f679fcSJeremy L Thompson (*rstr)->block_size = 1;
741fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED;
742fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, orients, NULL, *rstr));
74377d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
74477d1c127SSebastian Grimberg }
74577d1c127SSebastian Grimberg
74677d1c127SSebastian Grimberg /**
747ca94c3ddSJeremy L Thompson @brief Create a `CeedElemRestriction` with a general tridiagonal transformation matrix for curl-conforming elements
74877d1c127SSebastian Grimberg
749ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
750ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array
75177d1c127SSebastian Grimberg @param[in] elem_size Size (number of "nodes") per element
75277d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields)
753fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node".
754ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `offsets[i + k*elem_size] + j*comp_stride`.
755fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
756fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
757ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType
758ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode
759ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`.
760ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`.
761ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`.
762ca94c3ddSJeremy L Thompson @param[in] curl_orients Array of shape `[num_elem, 3 * elem_size]` representing a row-major tridiagonal matrix (`curl_orients[i * 3 * elem_size] = curl_orients[(i + 1) * 3 * elem_size - 1] = 0`, where `0 <= i < num_elem`) which is applied to the element unknowns upon restriction.
763ca94c3ddSJeremy L Thompson This orientation matrix allows for pairs of face degrees of freedom on elements for \f$H(\mathrm{curl})\f$ spaces to be coupled in the element restriction operation, which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456).
764ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
76577d1c127SSebastian Grimberg
76677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
76777d1c127SSebastian Grimberg
76877d1c127SSebastian Grimberg @ref User
76977d1c127SSebastian Grimberg **/
CeedElemRestrictionCreateCurlOriented(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt num_comp,CeedInt comp_stride,CeedSize l_size,CeedMemType mem_type,CeedCopyMode copy_mode,const CeedInt * offsets,const CeedInt8 * curl_orients,CeedElemRestriction * rstr)77077d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedSize l_size,
7710c73c039SSebastian Grimberg CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt8 *curl_orients,
77277d1c127SSebastian Grimberg CeedElemRestriction *rstr) {
773fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreate) {
77477d1c127SSebastian Grimberg Ceed delegate;
77577d1c127SSebastian Grimberg
77677d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
777ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateCurlOriented");
77877d1c127SSebastian Grimberg CeedCall(CeedElemRestrictionCreateCurlOriented(delegate, num_elem, elem_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets,
77977d1c127SSebastian Grimberg curl_orients, rstr));
7809bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
78177d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
78277d1c127SSebastian Grimberg }
78377d1c127SSebastian Grimberg
784e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
78577d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
786ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
787ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1");
78877d1c127SSebastian Grimberg
78977d1c127SSebastian Grimberg CeedCall(CeedCalloc(1, rstr));
790*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
79177d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem;
79277d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size;
79377d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp;
79477d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride;
79577d1c127SSebastian Grimberg (*rstr)->l_size = l_size;
7961203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp;
797e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem;
798e7f679fcSJeremy L Thompson (*rstr)->block_size = 1;
799fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED;
800fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, NULL, curl_orients, *rstr));
801fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS;
802fc0567d9Srezgarshakeri }
803fc0567d9Srezgarshakeri
804fc0567d9Srezgarshakeri /**
805ca94c3ddSJeremy L Thompson @brief Create a strided `CeedElemRestriction`
806d7b241e6Sjeremylt
807ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
808ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction
809ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element
810ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation "node" (1 for scalar fields)
811fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
812fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
813ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`.
814ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `i*strides[0] + j*strides[1] + k*strides[2]`.
815ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend.
816972f909dSJeremy L Thompson `CEED_STRIDES_BACKEND` should only be used pass data between `CeedOperator` created with the same `Ceed` backend.
817972f909dSJeremy L Thompson The L-vector layout will, in general, be different between `Ceed` backends.
818ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
819d7b241e6Sjeremylt
820b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
821dfdf5a53Sjeremylt
8227a982d89SJeremy L. Thompson @ref User
823b11c1e72Sjeremylt **/
CeedElemRestrictionCreateStrided(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt num_comp,CeedSize l_size,const CeedInt strides[3],CeedElemRestriction * rstr)8242b730f8bSJeremy L Thompson int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedSize l_size, const CeedInt strides[3],
825f90c8643Sjeremylt CeedElemRestriction *rstr) {
8265fe0d4faSjeremylt if (!ceed->ElemRestrictionCreate) {
8275fe0d4faSjeremylt Ceed delegate;
828b04eb3d9SSebastian Grimberg
8292b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
830ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateStrided");
8312b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateStrided(delegate, num_elem, elem_size, num_comp, l_size, strides, rstr));
8329bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
833e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
8345fe0d4faSjeremylt }
8355fe0d4faSjeremylt
836e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
8376574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
838ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
839aa72de07SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, ceed, CEED_ERROR_DIMENSION,
840870ea2d9SJeremy L Thompson "L-vector size must be at least num_elem * elem_size * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT,
841870ea2d9SJeremy L Thompson (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, l_size);
842e022e1f8SJeremy L Thompson
8432b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr));
844*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
845d1d35e2fSjeremylt (*rstr)->num_elem = num_elem;
846d1d35e2fSjeremylt (*rstr)->elem_size = elem_size;
847d1d35e2fSjeremylt (*rstr)->num_comp = num_comp;
848d1d35e2fSjeremylt (*rstr)->l_size = l_size;
8491203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp;
850e7f679fcSJeremy L Thompson (*rstr)->num_block = num_elem;
851e7f679fcSJeremy L Thompson (*rstr)->block_size = 1;
852fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED;
8532b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides));
8542b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i];
855fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreate(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr));
856e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
857d7b241e6Sjeremylt }
858d7b241e6Sjeremylt
859d7b241e6Sjeremylt /**
860ca94c3ddSJeremy L Thompson @brief Create a points `CeedElemRestriction`, for restricting for restricting from a all local points to the current element in which they are located.
8613ac8f562SJeremy L Thompson
8623ac8f562SJeremy L Thompson The offsets array is arranged as
8633ac8f562SJeremy L Thompson
8643ac8f562SJeremy L Thompson element_0_start_index
8653ac8f562SJeremy L Thompson element_1_start_index
8663ac8f562SJeremy L Thompson ...
8673ac8f562SJeremy L Thompson element_n_start_index
8683ac8f562SJeremy L Thompson element_n_stop_index
8693ac8f562SJeremy L Thompson element_0_point_0
8703ac8f562SJeremy L Thompson element_0_point_1
8713ac8f562SJeremy L Thompson ...
8723ac8f562SJeremy L Thompson
873ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
874ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array
875ca94c3ddSJeremy L Thompson @param[in] num_points Number of points described in the `offsets` array
8763ac8f562SJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields).
8773ac8f562SJeremy L Thompson Components are assumed to be contiguous by point.
8783ac8f562SJeremy L Thompson @param[in] l_size The size of the L-vector.
8793ac8f562SJeremy L Thompson This vector may be larger than the elements and fields given by this restriction.
880ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType
881ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode
882ca94c3ddSJeremy L Thompson @param[in] offsets Array of size `num_elem + 1 + num_points`.
8833ac8f562SJeremy L Thompson The first portion of the offsets array holds the ranges of indices corresponding to each element.
8843ac8f562SJeremy L Thompson The second portion holds the indices for each element.
885ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
8863ac8f562SJeremy L Thompson
8873ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
8883ac8f562SJeremy L Thompson
8893ac8f562SJeremy L Thompson @ref Backend
8903ac8f562SJeremy L Thompson **/
CeedElemRestrictionCreateAtPoints(Ceed ceed,CeedInt num_elem,CeedInt num_points,CeedInt num_comp,CeedSize l_size,CeedMemType mem_type,CeedCopyMode copy_mode,const CeedInt * offsets,CeedElemRestriction * rstr)8913ac8f562SJeremy L Thompson int CeedElemRestrictionCreateAtPoints(Ceed ceed, CeedInt num_elem, CeedInt num_points, CeedInt num_comp, CeedSize l_size, CeedMemType mem_type,
8923ac8f562SJeremy L Thompson CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction *rstr) {
8933ac8f562SJeremy L Thompson if (!ceed->ElemRestrictionCreateAtPoints) {
8943ac8f562SJeremy L Thompson Ceed delegate;
8953ac8f562SJeremy L Thompson
8963ac8f562SJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
897ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateAtPoints");
8983ac8f562SJeremy L Thompson CeedCall(CeedElemRestrictionCreateAtPoints(delegate, num_elem, num_points, num_comp, l_size, mem_type, copy_mode, offsets, rstr));
8999bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
9003ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS;
9013ac8f562SJeremy L Thompson }
9023ac8f562SJeremy L Thompson
9033ac8f562SJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
9043ac8f562SJeremy L Thompson CeedCheck(num_points >= 0, ceed, CEED_ERROR_DIMENSION, "Number of points must be non-negative");
905ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
906870ea2d9SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_points * num_comp, ceed, CEED_ERROR_DIMENSION,
907870ea2d9SJeremy L Thompson "L-vector must be at least num_points * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT, (CeedSize)num_points * num_comp,
908870ea2d9SJeremy L Thompson l_size);
9093ac8f562SJeremy L Thompson
9103ac8f562SJeremy L Thompson CeedCall(CeedCalloc(1, rstr));
911*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
9123ac8f562SJeremy L Thompson (*rstr)->num_elem = num_elem;
9133ac8f562SJeremy L Thompson (*rstr)->num_points = num_points;
9143ac8f562SJeremy L Thompson (*rstr)->num_comp = num_comp;
9152c2c926cSJeremy L Thompson (*rstr)->comp_stride = 1;
9163ac8f562SJeremy L Thompson (*rstr)->l_size = l_size;
9171203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_points * (CeedSize)num_comp;
91805fa913cSJeremy L Thompson (*rstr)->num_block = num_elem;
9193ac8f562SJeremy L Thompson (*rstr)->block_size = 1;
9203ac8f562SJeremy L Thompson (*rstr)->rstr_type = CEED_RESTRICTION_POINTS;
9213ac8f562SJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateAtPoints(mem_type, copy_mode, offsets, NULL, NULL, *rstr));
9223ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS;
9233ac8f562SJeremy L Thompson }
9243ac8f562SJeremy L Thompson
9253ac8f562SJeremy L Thompson /**
926ca94c3ddSJeremy L Thompson @brief Create a blocked `CeedElemRestriction`, typically only used by backends
927d7b241e6Sjeremylt
928ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
929ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array
930ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of unknowns) per element
931e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block
932ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields)
933fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node".
934ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `offsets[i + k*elem_size] + j*comp_stride`.
935fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
936fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
937ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType
938ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode
939ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`.
940ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`.
941ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`.
942ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend.
943ca94c3ddSJeremy L Thompson The default reordering is to interlace elements.
944ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
945d7b241e6Sjeremylt
946b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
947dfdf5a53Sjeremylt
9487a982d89SJeremy L. Thompson @ref Backend
949b11c1e72Sjeremylt **/
CeedElemRestrictionCreateBlocked(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt block_size,CeedInt num_comp,CeedInt comp_stride,CeedSize l_size,CeedMemType mem_type,CeedCopyMode copy_mode,const CeedInt * offsets,CeedElemRestriction * rstr)950e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedInt comp_stride,
9512b730f8bSJeremy L Thompson CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets,
9524ce2993fSjeremylt CeedElemRestriction *rstr) {
9531c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size);
954d7b241e6Sjeremylt
9555fe0d4faSjeremylt if (!ceed->ElemRestrictionCreateBlocked) {
9565fe0d4faSjeremylt Ceed delegate;
9576574a04fSJeremy L Thompson
9582b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
959ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlocked");
960e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlocked(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode, offsets,
961e7f679fcSJeremy L Thompson rstr));
9629bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
963e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
9645fe0d4faSjeremylt }
965d7b241e6Sjeremylt
966e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
9676574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
968e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1");
969ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
970ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1");
971e022e1f8SJeremy L Thompson
972e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets));
973e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size));
974d7b241e6Sjeremylt
975db002c03SJeremy L Thompson CeedCall(CeedCalloc(1, rstr));
976*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
977d1d35e2fSjeremylt (*rstr)->num_elem = num_elem;
978d1d35e2fSjeremylt (*rstr)->elem_size = elem_size;
979d1d35e2fSjeremylt (*rstr)->num_comp = num_comp;
980d1d35e2fSjeremylt (*rstr)->comp_stride = comp_stride;
981d1d35e2fSjeremylt (*rstr)->l_size = l_size;
9821203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp;
983e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block;
984e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size;
98561a27d74SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STANDARD;
986e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL, NULL, *rstr));
9871c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets));
988e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
989d7b241e6Sjeremylt }
990d7b241e6Sjeremylt
991b11c1e72Sjeremylt /**
992ca94c3ddSJeremy L Thompson @brief Create a blocked oriented `CeedElemRestriction`, typically only used by backends
99377d1c127SSebastian Grimberg
994ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
995ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array.
99677d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element
997e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block
99877d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields)
999fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node".
1000ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `offsets[i + k*elem_size] + j*comp_stride`.
1001fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
1002fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
1003ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType
1004ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode
1005ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`.
1006ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`.
1007ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`.
1008ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend.
1009ca94c3ddSJeremy L Thompson The default reordering is to interlace elements.
1010ca94c3ddSJeremy L Thompson @param[in] orients Boolean array of shape `[num_elem, elem_size]` with `false` for positively oriented and `true` to flip the orientation.
1011ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to `offsets`.
1012ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
101377d1c127SSebastian Grimberg
101477d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
101577d1c127SSebastian Grimberg
101677d1c127SSebastian Grimberg @ref Backend
101777d1c127SSebastian Grimberg **/
CeedElemRestrictionCreateBlockedOriented(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt block_size,CeedInt num_comp,CeedInt comp_stride,CeedSize l_size,CeedMemType mem_type,CeedCopyMode copy_mode,const CeedInt * offsets,const bool * orients,CeedElemRestriction * rstr)1018e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp,
1019e7f679fcSJeremy L Thompson CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode,
1020e7f679fcSJeremy L Thompson const CeedInt *offsets, const bool *orients, CeedElemRestriction *rstr) {
1021e7f679fcSJeremy L Thompson bool *block_orients;
10221c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size);
102377d1c127SSebastian Grimberg
1024fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) {
102577d1c127SSebastian Grimberg Ceed delegate;
102677d1c127SSebastian Grimberg
102777d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
1028ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedOriented");
1029e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type, copy_mode,
103077d1c127SSebastian Grimberg offsets, orients, rstr));
10319bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
103277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
103377d1c127SSebastian Grimberg }
103477d1c127SSebastian Grimberg
103577d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
1036e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1");
1037ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
1038ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1");
103977d1c127SSebastian Grimberg
1040e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets));
1041e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_orients));
1042e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size));
1043e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOrients(orients, block_orients, num_block, num_elem, block_size, elem_size));
104477d1c127SSebastian Grimberg
1045fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr));
1046*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
104777d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem;
104877d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size;
104977d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp;
105077d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride;
105177d1c127SSebastian Grimberg (*rstr)->l_size = l_size;
10521203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp;
1053e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block;
1054e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size;
1055fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_ORIENTED;
10561a8516d0SJames Wright CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, (const bool *)block_orients, NULL,
10571a8516d0SJames Wright *rstr));
10581c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets));
105977d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
106077d1c127SSebastian Grimberg }
106177d1c127SSebastian Grimberg
106277d1c127SSebastian Grimberg /**
1063ca94c3ddSJeremy L Thompson @brief Create a blocked curl-oriented `CeedElemRestriction`, typically only used by backends
106477d1c127SSebastian Grimberg
1065ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
1066ca94c3ddSJeremy L Thompson @param[in] num_elem Number of elements described in the `offsets` array.
106777d1c127SSebastian Grimberg @param[in] elem_size Size (number of unknowns) per element
1068e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block
106977d1c127SSebastian Grimberg @param[in] num_comp Number of field components per interpolation node (1 for scalar fields)
1070fcbe8c06SSebastian Grimberg @param[in] comp_stride Stride between components for the same L-vector "node".
1071ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `offsets[i + k*elem_size] + j*comp_stride`.
1072fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
1073fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
1074ca94c3ddSJeremy L Thompson @param[in] mem_type Memory type of the `offsets` array, see @ref CeedMemType
1075ca94c3ddSJeremy L Thompson @param[in] copy_mode Copy mode for the `offsets` array, see @ref CeedCopyMode
1076ca94c3ddSJeremy L Thompson @param[in] offsets Array of shape `[num_elem, elem_size]`.
1077ca94c3ddSJeremy L Thompson Row `i` holds the ordered list of the offsets (into the input `CeedVector`) for the unknowns corresponding to element `i`, where `0 <= i < num_elem`.
1078ca94c3ddSJeremy L Thompson All offsets must be in the range `[0, l_size - 1]`.
1079ca94c3ddSJeremy L Thompson The backend will permute and pad this array to the desired ordering for the blocksize, which is typically given by the backend.
1080ca94c3ddSJeremy L Thompson The default reordering is to interlace elements.
1081ca94c3ddSJeremy L Thompson @param[in] curl_orients Array of shape `[num_elem, 3 * elem_size]` representing a row-major tridiagonal matrix (`curl_orients[i * 3 * elem_size] = curl_orients[(i + 1) * 3 * elem_size - 1] = 0`, where `0 <= i < num_elem`) which is applied to the element unknowns upon restriction.
1082ca94c3ddSJeremy L Thompson This orientation matrix allows for pairs of face degrees of freedom on elements for \f$H(\mathrm{curl})\f$ spaces to be coupled in the element restriction operation, which is a way to resolve face orientation issues for 3D meshes (https://dl.acm.org/doi/pdf/10.1145/3524456).
1083ca94c3ddSJeremy L Thompson Will also be permuted and padded similarly to offsets.
1084ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
108577d1c127SSebastian Grimberg
108677d1c127SSebastian Grimberg @return An error code: 0 - success, otherwise - failure
108777d1c127SSebastian Grimberg
108877d1c127SSebastian Grimberg @ref Backend
108977d1c127SSebastian Grimberg **/
CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt block_size,CeedInt num_comp,CeedInt comp_stride,CeedSize l_size,CeedMemType mem_type,CeedCopyMode copy_mode,const CeedInt * offsets,const CeedInt8 * curl_orients,CeedElemRestriction * rstr)1090e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedCurlOriented(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp,
109177d1c127SSebastian Grimberg CeedInt comp_stride, CeedSize l_size, CeedMemType mem_type, CeedCopyMode copy_mode,
10920c73c039SSebastian Grimberg const CeedInt *offsets, const CeedInt8 *curl_orients, CeedElemRestriction *rstr) {
1093e7f679fcSJeremy L Thompson CeedInt8 *block_curl_orients;
10941c66c397SJeremy L Thompson CeedInt *block_offsets, num_block = (num_elem / block_size) + !!(num_elem % block_size);
109577d1c127SSebastian Grimberg
1096fcbe8c06SSebastian Grimberg if (!ceed->ElemRestrictionCreateBlocked) {
109777d1c127SSebastian Grimberg Ceed delegate;
109877d1c127SSebastian Grimberg
109977d1c127SSebastian Grimberg CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
1100ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedCurlOriented");
1101e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedCurlOriented(delegate, num_elem, elem_size, block_size, num_comp, comp_stride, l_size, mem_type,
1102e7f679fcSJeremy L Thompson copy_mode, offsets, curl_orients, rstr));
11039bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
110477d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
110577d1c127SSebastian Grimberg }
110677d1c127SSebastian Grimberg
1107e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
110877d1c127SSebastian Grimberg CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
1109e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1");
1110ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
1111ca94c3ddSJeremy L Thompson CeedCheck(num_comp == 1 || comp_stride > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction component stride must be at least 1");
111277d1c127SSebastian Grimberg
1113e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * elem_size, &block_offsets));
1114e7f679fcSJeremy L Thompson CeedCall(CeedCalloc(num_block * block_size * 3 * elem_size, &block_curl_orients));
1115e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadOffsets(offsets, block_offsets, num_block, num_elem, block_size, elem_size));
1116e7f679fcSJeremy L Thompson CeedCall(CeedPermutePadCurlOrients(curl_orients, block_curl_orients, num_block, num_elem, block_size, 3 * elem_size));
111777d1c127SSebastian Grimberg
1118fcbe8c06SSebastian Grimberg CeedCall(CeedCalloc(1, rstr));
1119*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
112077d1c127SSebastian Grimberg (*rstr)->num_elem = num_elem;
112177d1c127SSebastian Grimberg (*rstr)->elem_size = elem_size;
112277d1c127SSebastian Grimberg (*rstr)->num_comp = num_comp;
112377d1c127SSebastian Grimberg (*rstr)->comp_stride = comp_stride;
112477d1c127SSebastian Grimberg (*rstr)->l_size = l_size;
11251203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp;
1126e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block;
1127e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size;
1128fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_CURL_ORIENTED;
1129e7f679fcSJeremy L Thompson CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, (const CeedInt *)block_offsets, NULL,
1130e7f679fcSJeremy L Thompson (const CeedInt8 *)block_curl_orients, *rstr));
11311c66c397SJeremy L Thompson if (copy_mode == CEED_OWN_POINTER) CeedCall(CeedFree(&offsets));
113277d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS;
113377d1c127SSebastian Grimberg }
113477d1c127SSebastian Grimberg
113577d1c127SSebastian Grimberg /**
1136ca94c3ddSJeremy L Thompson @brief Create a blocked strided `CeedElemRestriction`, typically only used by backends
11377509a596Sjeremylt
1138ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context used to create the `CeedElemRestriction`
1139ea61e9acSJeremy L Thompson @param[in] num_elem Number of elements described by the restriction
1140ea61e9acSJeremy L Thompson @param[in] elem_size Size (number of "nodes") per element
1141e7f679fcSJeremy L Thompson @param[in] block_size Number of elements in a block
1142ea61e9acSJeremy L Thompson @param[in] num_comp Number of field components per interpolation node (1 for scalar fields)
1143fcbe8c06SSebastian Grimberg @param[in] l_size The size of the L-vector.
1144fcbe8c06SSebastian Grimberg This vector may be larger than the elements and fields given by this restriction.
1145ca94c3ddSJeremy L Thompson @param[in] strides Array for strides between `[nodes, components, elements]`.
1146ca94c3ddSJeremy L Thompson Data for node `i`, component `j`, element `k` can be found in the L-vector at index `i*strides[0] + j*strides[1] +k*strides[2]`.
1147ca94c3ddSJeremy L Thompson @ref CEED_STRIDES_BACKEND may be used for `CeedVector` ordered by the same `Ceed` backend.
1148ca94c3ddSJeremy L Thompson @param[out] rstr Address of the variable where the newly created `CeedElemRestriction` will be stored
11497509a596Sjeremylt
11507509a596Sjeremylt @return An error code: 0 - success, otherwise - failure
11517509a596Sjeremylt
11527a982d89SJeremy L. Thompson @ref User
11537509a596Sjeremylt **/
CeedElemRestrictionCreateBlockedStrided(Ceed ceed,CeedInt num_elem,CeedInt elem_size,CeedInt block_size,CeedInt num_comp,CeedSize l_size,const CeedInt strides[3],CeedElemRestriction * rstr)1154e7f679fcSJeremy L Thompson int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem, CeedInt elem_size, CeedInt block_size, CeedInt num_comp, CeedSize l_size,
11558621c6c6SJeremy L Thompson const CeedInt strides[3], CeedElemRestriction *rstr) {
1156e7f679fcSJeremy L Thompson CeedInt num_block = (num_elem / block_size) + !!(num_elem % block_size);
11577509a596Sjeremylt
11587509a596Sjeremylt if (!ceed->ElemRestrictionCreateBlocked) {
11597509a596Sjeremylt Ceed delegate;
11606574a04fSJeremy L Thompson
11612b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction"));
1162ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedElemRestrictionCreateBlockedStrided");
1163e7f679fcSJeremy L Thompson CeedCall(CeedElemRestrictionCreateBlockedStrided(delegate, num_elem, elem_size, block_size, num_comp, l_size, strides, rstr));
11649bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
1165e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
11667509a596Sjeremylt }
11677509a596Sjeremylt
1168e7f679fcSJeremy L Thompson CeedCheck(num_elem >= 0, ceed, CEED_ERROR_DIMENSION, "Number of elements must be non-negative");
11696574a04fSJeremy L Thompson CeedCheck(elem_size > 0, ceed, CEED_ERROR_DIMENSION, "Element size must be at least 1");
1170e7f679fcSJeremy L Thompson CeedCheck(block_size > 0, ceed, CEED_ERROR_DIMENSION, "Block size must be at least 1");
1171ca94c3ddSJeremy L Thompson CeedCheck(num_comp > 0, ceed, CEED_ERROR_DIMENSION, "CeedElemRestriction must have at least 1 component");
1172aa72de07SJeremy L Thompson CeedCheck(l_size >= (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, ceed, CEED_ERROR_DIMENSION,
1173870ea2d9SJeremy L Thompson "L-vector size must be at least num_elem * elem_size * num_comp. Expected: > %" CeedSize_FMT " Found: %" CeedSize_FMT,
1174870ea2d9SJeremy L Thompson (CeedSize)num_elem * (CeedSize)elem_size * (CeedSize)num_comp, l_size);
1175e022e1f8SJeremy L Thompson
11762b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, rstr));
1177*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(ceed, CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object, &(*rstr)->obj));
1178d1d35e2fSjeremylt (*rstr)->num_elem = num_elem;
1179d1d35e2fSjeremylt (*rstr)->elem_size = elem_size;
1180d1d35e2fSjeremylt (*rstr)->num_comp = num_comp;
1181d1d35e2fSjeremylt (*rstr)->l_size = l_size;
11821203703bSJeremy L Thompson (*rstr)->e_size = (CeedSize)num_block * (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp;
1183e7f679fcSJeremy L Thompson (*rstr)->num_block = num_block;
1184e7f679fcSJeremy L Thompson (*rstr)->block_size = block_size;
1185fcbe8c06SSebastian Grimberg (*rstr)->rstr_type = CEED_RESTRICTION_STRIDED;
11862b730f8bSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr)->strides));
11872b730f8bSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr)->strides[i] = strides[i];
1188fcbe8c06SSebastian Grimberg CeedCall(ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER, NULL, NULL, NULL, *rstr));
1189e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
11907509a596Sjeremylt }
11917509a596Sjeremylt
11927509a596Sjeremylt /**
1193ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unsigned version.
1194c17ec2beSJeremy L Thompson
1195ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy().
1196c17ec2beSJeremy L Thompson
1197ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unsigned reference to
1198ca94c3ddSJeremy L Thompson @param[in,out] rstr_unsigned Variable to store unsigned `CeedElemRestriction`
1199c17ec2beSJeremy L Thompson
1200c17ec2beSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1201c17ec2beSJeremy L Thompson
1202c17ec2beSJeremy L Thompson @ref User
1203c17ec2beSJeremy L Thompson **/
CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr,CeedElemRestriction * rstr_unsigned)1204c17ec2beSJeremy L Thompson int CeedElemRestrictionCreateUnsignedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unsigned) {
1205c17ec2beSJeremy L Thompson CeedCall(CeedCalloc(1, rstr_unsigned));
1206c17ec2beSJeremy L Thompson
1207c17ec2beSJeremy L Thompson // Copy old rstr
1208c17ec2beSJeremy L Thompson memcpy(*rstr_unsigned, rstr, sizeof(struct CeedElemRestriction_private));
1209*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(CeedElemRestrictionReturnCeed(rstr), CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object,
1210*6c328a79SJeremy L Thompson &(*rstr_unsigned)->obj));
1211c17ec2beSJeremy L Thompson (*rstr_unsigned)->strides = NULL;
1212c17ec2beSJeremy L Thompson if (rstr->strides) {
1213c17ec2beSJeremy L Thompson CeedCall(CeedMalloc(3, &(*rstr_unsigned)->strides));
1214c17ec2beSJeremy L Thompson for (CeedInt i = 0; i < 3; i++) (*rstr_unsigned)->strides[i] = rstr->strides[i];
1215c17ec2beSJeremy L Thompson }
12167c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unsigned)->rstr_base));
1217c17ec2beSJeremy L Thompson
1218c17ec2beSJeremy L Thompson // Override Apply
1219c17ec2beSJeremy L Thompson (*rstr_unsigned)->Apply = rstr->ApplyUnsigned;
1220c17ec2beSJeremy L Thompson return CEED_ERROR_SUCCESS;
1221c17ec2beSJeremy L Thompson }
1222c17ec2beSJeremy L Thompson
1223c17ec2beSJeremy L Thompson /**
1224ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction` and set @ref CeedElemRestrictionApply() implementation to use the unoriented version.
12257c1dbaffSSebastian Grimberg
1226ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy().
12277c1dbaffSSebastian Grimberg
1228ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to create unoriented reference to
1229ca94c3ddSJeremy L Thompson @param[in,out] rstr_unoriented Variable to store unoriented `CeedElemRestriction`
12307c1dbaffSSebastian Grimberg
12317c1dbaffSSebastian Grimberg @return An error code: 0 - success, otherwise - failure
12327c1dbaffSSebastian Grimberg
12337c1dbaffSSebastian Grimberg @ref User
12347c1dbaffSSebastian Grimberg **/
CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr,CeedElemRestriction * rstr_unoriented)12357c1dbaffSSebastian Grimberg int CeedElemRestrictionCreateUnorientedCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_unoriented) {
12367c1dbaffSSebastian Grimberg CeedCall(CeedCalloc(1, rstr_unoriented));
12377c1dbaffSSebastian Grimberg
12387c1dbaffSSebastian Grimberg // Copy old rstr
12397c1dbaffSSebastian Grimberg memcpy(*rstr_unoriented, rstr, sizeof(struct CeedElemRestriction_private));
1240*6c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(CeedElemRestrictionReturnCeed(rstr), CeedElemRestrictionView_Object, CeedElemRestrictionDestroy_Object,
1241*6c328a79SJeremy L Thompson &(*rstr_unoriented)->obj));
12427c1dbaffSSebastian Grimberg (*rstr_unoriented)->strides = NULL;
12437c1dbaffSSebastian Grimberg if (rstr->strides) {
12447c1dbaffSSebastian Grimberg CeedCall(CeedMalloc(3, &(*rstr_unoriented)->strides));
12457c1dbaffSSebastian Grimberg for (CeedInt i = 0; i < 3; i++) (*rstr_unoriented)->strides[i] = rstr->strides[i];
12467c1dbaffSSebastian Grimberg }
12477c1dbaffSSebastian Grimberg CeedCall(CeedElemRestrictionReferenceCopy(rstr, &(*rstr_unoriented)->rstr_base));
12487c1dbaffSSebastian Grimberg
12497c1dbaffSSebastian Grimberg // Override Apply
12507c1dbaffSSebastian Grimberg (*rstr_unoriented)->Apply = rstr->ApplyUnoriented;
12517c1dbaffSSebastian Grimberg return CEED_ERROR_SUCCESS;
12527c1dbaffSSebastian Grimberg }
12537c1dbaffSSebastian Grimberg
12547c1dbaffSSebastian Grimberg /**
1255ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedElemRestriction`.
12569fd66db6SSebastian Grimberg
1257ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedElemRestrictionDestroy().
12589560d06aSjeremylt
1259ca94c3ddSJeremy L Thompson Note: If the value of `*rstr_copy` passed into this function is non-`NULL`, then it is assumed that `*rstr_copy` is a pointer to a `CeedElemRestriction`.
1260ca94c3ddSJeremy L Thompson This `CeedElemRestriction` will be destroyed if `*rstr_copy` is the only reference to this `CeedElemRestriction`.
1261ea61e9acSJeremy L Thompson
1262ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to copy reference to
1263ea61e9acSJeremy L Thompson @param[in,out] rstr_copy Variable to store copied reference
12649560d06aSjeremylt
12659560d06aSjeremylt @return An error code: 0 - success, otherwise - failure
12669560d06aSjeremylt
12679560d06aSjeremylt @ref User
12689560d06aSjeremylt **/
CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr,CeedElemRestriction * rstr_copy)12692b730f8bSJeremy L Thompson int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr, CeedElemRestriction *rstr_copy) {
1270393ac2cdSJeremy L Thompson if (rstr != CEED_ELEMRESTRICTION_NONE) CeedCall(CeedElemRestrictionReference(rstr));
12712b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionDestroy(rstr_copy));
12729560d06aSjeremylt *rstr_copy = rstr;
12739560d06aSjeremylt return CEED_ERROR_SUCCESS;
12749560d06aSjeremylt }
12759560d06aSjeremylt
12769560d06aSjeremylt /**
1277ca94c3ddSJeremy L Thompson @brief Create `CeedVector` associated with a `CeedElemRestriction`
1278b11c1e72Sjeremylt
1279ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1280ca94c3ddSJeremy L Thompson @param[out] l_vec The address of the L-vector to be created, or `NULL`
1281ca94c3ddSJeremy L Thompson @param[out] e_vec The address of the E-vector to be created, or `NULL`
1282b11c1e72Sjeremylt
1283b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
1284dfdf5a53Sjeremylt
12857a982d89SJeremy L. Thompson @ref User
1286b11c1e72Sjeremylt **/
CeedElemRestrictionCreateVector(CeedElemRestriction rstr,CeedVector * l_vec,CeedVector * e_vec)12872b730f8bSJeremy L Thompson int CeedElemRestrictionCreateVector(CeedElemRestriction rstr, CeedVector *l_vec, CeedVector *e_vec) {
1288d2643443SJeremy L Thompson CeedSize e_size, l_size;
12891203703bSJeremy L Thompson Ceed ceed;
129048acf710SJeremy L Thompson
12911203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetCeed(rstr, &ceed));
12921203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &l_size));
12931203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &e_size));
12941203703bSJeremy L Thompson if (l_vec) CeedCall(CeedVectorCreate(ceed, l_size, l_vec));
12951203703bSJeremy L Thompson if (e_vec) CeedCall(CeedVectorCreate(ceed, e_size, e_vec));
12969bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed));
1297e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1298d7b241e6Sjeremylt }
1299d7b241e6Sjeremylt
1300d7b241e6Sjeremylt /**
1301d9e1f99aSValeria Barra @brief Restrict an L-vector to an E-vector or apply its transpose
1302d7b241e6Sjeremylt
1303ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1304ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose
1305ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE)
1306ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[num_elem * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE).
1307fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend.
1308ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE
1309b11c1e72Sjeremylt
1310b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
1311dfdf5a53Sjeremylt
13127a982d89SJeremy L. Thompson @ref User
1313b11c1e72Sjeremylt **/
CeedElemRestrictionApply(CeedElemRestriction rstr,CeedTransposeMode t_mode,CeedVector u,CeedVector ru,CeedRequest * request)13142b730f8bSJeremy L Thompson int CeedElemRestrictionApply(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request) {
1315701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len;
1316701e7d35SJeremy L Thompson CeedInt num_elem;
1317d7b241e6Sjeremylt
1318d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) {
1319701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_ru_len));
1320701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len));
1321d7b241e6Sjeremylt } else {
1322701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetEVectorSize(rstr, &min_u_len));
1323701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len));
1324d7b241e6Sjeremylt }
1325701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len));
13269bc66399SJeremy L Thompson CeedCheck(min_u_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
1327701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len,
1328701e7d35SJeremy L Thompson min_u_len);
1329701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len));
13309bc66399SJeremy L Thompson CeedCheck(min_ru_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
1331701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len,
1332701e7d35SJeremy L Thompson min_ru_len);
1333701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem));
1334701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->Apply(rstr, t_mode, u, ru, request));
1335e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1336d7b241e6Sjeremylt }
1337d7b241e6Sjeremylt
1338d7b241e6Sjeremylt /**
13393ac8f562SJeremy L Thompson @brief Restrict an L-vector of points to a single element or apply its transpose
13403ac8f562SJeremy L Thompson
1341ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1342ca94c3ddSJeremy L Thompson @param[in] elem Element number in range `[0, num_elem)`
13433ac8f562SJeremy L Thompson @param[in] t_mode Apply restriction or transpose
1344ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE)
1345ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape [`num_points * num_comp]` when `t_mode` = @ref CEED_NOTRANSPOSE).
13463ac8f562SJeremy L Thompson Ordering of the e-vector is decided by the backend.
13473ac8f562SJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE
13483ac8f562SJeremy L Thompson
13493ac8f562SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
13503ac8f562SJeremy L Thompson
13513ac8f562SJeremy L Thompson @ref User
13523ac8f562SJeremy L Thompson **/
CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr,CeedInt elem,CeedTransposeMode t_mode,CeedVector u,CeedVector ru,CeedRequest * request)135305fa913cSJeremy L Thompson int CeedElemRestrictionApplyAtPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedTransposeMode t_mode, CeedVector u, CeedVector ru,
13543ac8f562SJeremy L Thompson CeedRequest *request) {
1355701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len;
1356701e7d35SJeremy L Thompson CeedInt num_elem;
13573ac8f562SJeremy L Thompson
13589bc66399SJeremy L Thompson CeedCheck(rstr->ApplyAtPointsInElement, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED,
13599bc66399SJeremy L Thompson "Backend does not implement CeedElemRestrictionApplyAtPointsInElement");
13601ef3a2a9SJeremy L Thompson
13613ac8f562SJeremy L Thompson if (t_mode == CEED_NOTRANSPOSE) {
1362701e7d35SJeremy L Thompson CeedInt num_points, num_comp;
1363701e7d35SJeremy L Thompson
1364701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len));
1365701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points));
1366701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp));
1367701e7d35SJeremy L Thompson min_ru_len = (CeedSize)num_points * (CeedSize)num_comp;
13683ac8f562SJeremy L Thompson } else {
1369701e7d35SJeremy L Thompson CeedInt num_points, num_comp;
1370701e7d35SJeremy L Thompson
1371701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, elem, &num_points));
1372701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp));
1373701e7d35SJeremy L Thompson min_u_len = (CeedSize)num_points * (CeedSize)num_comp;
1374701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len));
13753ac8f562SJeremy L Thompson }
1376701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len));
13779bc66399SJeremy L Thompson CeedCheck(min_u_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
13783ac8f562SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT
13793ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT,
1380701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem);
1381701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len));
13829bc66399SJeremy L Thompson CeedCheck(min_ru_len <= len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
13833ac8f562SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT
13843ac8f562SJeremy L Thompson ") for element %" CeedInt_FMT,
1385701e7d35SJeremy L Thompson len, min_ru_len, min_u_len, elem);
1386701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem));
13879bc66399SJeremy L Thompson CeedCheck(elem < num_elem, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
1388701e7d35SJeremy L Thompson "Cannot retrieve element %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", elem, elem, num_elem);
1389701e7d35SJeremy L Thompson if (num_elem > 0) CeedCall(rstr->ApplyAtPointsInElement(rstr, elem, t_mode, u, ru, request));
13903ac8f562SJeremy L Thompson return CEED_ERROR_SUCCESS;
13913ac8f562SJeremy L Thompson }
13923ac8f562SJeremy L Thompson
13933ac8f562SJeremy L Thompson /**
1394d9e1f99aSValeria Barra @brief Restrict an L-vector to a block of an E-vector or apply its transpose
1395be9261b7Sjeremylt
1396ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1397ca94c3ddSJeremy L Thompson @param[in] block Block number to restrict to/from, i.e. `block = 0` will handle elements `[0 : block_size]` and `block = 3` will handle elements `[3*block_size : 4*block_size]`
1398ea61e9acSJeremy L Thompson @param[in] t_mode Apply restriction or transpose
1399ca94c3ddSJeremy L Thompson @param[in] u Input vector (of size `l_size` when `t_mode` = @ref CEED_NOTRANSPOSE)
1400ca94c3ddSJeremy L Thompson @param[out] ru Output vector (of shape `[block_size * elem_size]` when `t_mode` = @ref CEED_NOTRANSPOSE).
1401fcbe8c06SSebastian Grimberg Ordering of the e-vector is decided by the backend.
1402ea61e9acSJeremy L Thompson @param[in] request Request or @ref CEED_REQUEST_IMMEDIATE
1403be9261b7Sjeremylt
1404be9261b7Sjeremylt @return An error code: 0 - success, otherwise - failure
1405be9261b7Sjeremylt
14067a982d89SJeremy L. Thompson @ref Backend
1407be9261b7Sjeremylt **/
CeedElemRestrictionApplyBlock(CeedElemRestriction rstr,CeedInt block,CeedTransposeMode t_mode,CeedVector u,CeedVector ru,CeedRequest * request)14082b730f8bSJeremy L Thompson int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru,
14092b730f8bSJeremy L Thompson CeedRequest *request) {
1410701e7d35SJeremy L Thompson CeedSize min_u_len, min_ru_len, len;
1411701e7d35SJeremy L Thompson CeedInt block_size, num_elem;
1412be9261b7Sjeremylt
14139bc66399SJeremy L Thompson CeedCheck(rstr->ApplyBlock, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_UNSUPPORTED,
14149bc66399SJeremy L Thompson "Backend does not implement CeedElemRestrictionApplyBlock");
14156402da51SJeremy L Thompson
1416701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetBlockSize(rstr, &block_size));
1417d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) {
1418701e7d35SJeremy L Thompson CeedInt elem_size, num_comp;
1419701e7d35SJeremy L Thompson
1420701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size));
1421701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp));
1422701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_u_len));
1423701e7d35SJeremy L Thompson min_ru_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp;
1424be9261b7Sjeremylt } else {
1425701e7d35SJeremy L Thompson CeedInt elem_size, num_comp;
1426701e7d35SJeremy L Thompson
1427701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetElementSize(rstr, &elem_size));
1428701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumComponents(rstr, &num_comp));
1429701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetLVectorSize(rstr, &min_ru_len));
1430701e7d35SJeremy L Thompson min_u_len = (CeedSize)block_size * (CeedSize)elem_size * (CeedSize)num_comp;
1431be9261b7Sjeremylt }
1432701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(u, &len));
14339bc66399SJeremy L Thompson CeedCheck(min_u_len == len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
1434701e7d35SJeremy L Thompson "Input vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_u_len,
1435701e7d35SJeremy L Thompson min_ru_len);
1436701e7d35SJeremy L Thompson CeedCall(CeedVectorGetLength(ru, &len));
14379bc66399SJeremy L Thompson CeedCheck(min_ru_len == len, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
1438701e7d35SJeremy L Thompson "Output vector size %" CeedInt_FMT " not compatible with element restriction (%" CeedInt_FMT ", %" CeedInt_FMT ")", len, min_ru_len,
1439701e7d35SJeremy L Thompson min_u_len);
1440701e7d35SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem));
14419bc66399SJeremy L Thompson CeedCheck(block_size * block <= num_elem, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_DIMENSION,
1442701e7d35SJeremy L Thompson "Cannot retrieve block %" CeedInt_FMT ", element %" CeedInt_FMT " > total elements %" CeedInt_FMT "", block, block_size * block,
1443701e7d35SJeremy L Thompson num_elem);
14442b730f8bSJeremy L Thompson CeedCall(rstr->ApplyBlock(rstr, block, t_mode, u, ru, request));
1445e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1446be9261b7Sjeremylt }
1447be9261b7Sjeremylt
1448be9261b7Sjeremylt /**
1449ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedElemRestriction`
1450b7c9bbdaSJeremy L Thompson
1451ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1452ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store `Ceed`
1453b7c9bbdaSJeremy L Thompson
1454b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1455b7c9bbdaSJeremy L Thompson
1456b7c9bbdaSJeremy L Thompson @ref Advanced
1457b7c9bbdaSJeremy L Thompson **/
CeedElemRestrictionGetCeed(CeedElemRestriction rstr,Ceed * ceed)1458b7c9bbdaSJeremy L Thompson int CeedElemRestrictionGetCeed(CeedElemRestriction rstr, Ceed *ceed) {
1459b0f67a9cSJeremy L Thompson CeedCall(CeedObjectGetCeed((CeedObject)rstr, ceed));
1460b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS;
1461b7c9bbdaSJeremy L Thompson }
1462b7c9bbdaSJeremy L Thompson
1463b7c9bbdaSJeremy L Thompson /**
14646e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedElemRestriction`
14656e536b99SJeremy L Thompson
14666e536b99SJeremy L Thompson @param[in] rstr `CeedElemRestriction`
14676e536b99SJeremy L Thompson
14686e536b99SJeremy L Thompson @return `Ceed` associated with the `rstr`
14696e536b99SJeremy L Thompson
14706e536b99SJeremy L Thompson @ref Advanced
14716e536b99SJeremy L Thompson **/
CeedElemRestrictionReturnCeed(CeedElemRestriction rstr)1472b0f67a9cSJeremy L Thompson Ceed CeedElemRestrictionReturnCeed(CeedElemRestriction rstr) { return CeedObjectReturnCeed((CeedObject)rstr); }
14736e536b99SJeremy L Thompson
14746e536b99SJeremy L Thompson /**
1475d979a051Sjeremylt @brief Get the L-vector component stride
1476a681ae63Sjeremylt
1477ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1478d1d35e2fSjeremylt @param[out] comp_stride Variable to store component stride
1479a681ae63Sjeremylt
1480a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure
1481a681ae63Sjeremylt
1482b7c9bbdaSJeremy L Thompson @ref Advanced
1483a681ae63Sjeremylt **/
CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,CeedInt * comp_stride)14842b730f8bSJeremy L Thompson int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr, CeedInt *comp_stride) {
1485d1d35e2fSjeremylt *comp_stride = rstr->comp_stride;
1486e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1487a681ae63Sjeremylt }
1488a681ae63Sjeremylt
1489a681ae63Sjeremylt /**
1490ca94c3ddSJeremy L Thompson @brief Get the total number of elements in the range of a `CeedElemRestriction`
1491a681ae63Sjeremylt
1492ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1493d1d35e2fSjeremylt @param[out] num_elem Variable to store number of elements
1494a681ae63Sjeremylt
1495a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure
1496a681ae63Sjeremylt
1497b7c9bbdaSJeremy L Thompson @ref Advanced
1498a681ae63Sjeremylt **/
CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,CeedInt * num_elem)14992b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr, CeedInt *num_elem) {
1500d1d35e2fSjeremylt *num_elem = rstr->num_elem;
1501e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1502a681ae63Sjeremylt }
1503a681ae63Sjeremylt
1504a681ae63Sjeremylt /**
1505ca94c3ddSJeremy L Thompson @brief Get the size of elements in the `CeedElemRestriction`
1506a681ae63Sjeremylt
1507ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1508d1d35e2fSjeremylt @param[out] elem_size Variable to store size of elements
1509a681ae63Sjeremylt
1510a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure
1511a681ae63Sjeremylt
1512b7c9bbdaSJeremy L Thompson @ref Advanced
1513a681ae63Sjeremylt **/
CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,CeedInt * elem_size)15142b730f8bSJeremy L Thompson int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr, CeedInt *elem_size) {
1515d1d35e2fSjeremylt *elem_size = rstr->elem_size;
15162c7e7413SJeremy L Thompson return CEED_ERROR_SUCCESS;
15172c7e7413SJeremy L Thompson }
15182c7e7413SJeremy L Thompson
15192c7e7413SJeremy L Thompson /**
152007d5dec1SJeremy L Thompson
1521725a297dSZach Atkins @brief Get the number of points in the offsets array for a points `CeedElemRestriction`
152207d5dec1SJeremy L Thompson
1523ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1524725a297dSZach Atkins @param[out] num_points The number of points in the offsets array
152507d5dec1SJeremy L Thompson
152607d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
152707d5dec1SJeremy L Thompson
1528c63574e3SJeremy L Thompson @ref User
152907d5dec1SJeremy L Thompson **/
CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr,CeedInt * num_points)153007d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPoints(CeedElemRestriction rstr, CeedInt *num_points) {
15311203703bSJeremy L Thompson CeedRestrictionType rstr_type;
153207d5dec1SJeremy L Thompson
15331203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
15346e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE,
153507d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction");
153607d5dec1SJeremy L Thompson
153707d5dec1SJeremy L Thompson *num_points = rstr->num_points;
153807d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS;
153907d5dec1SJeremy L Thompson }
154007d5dec1SJeremy L Thompson
154107d5dec1SJeremy L Thompson /**
154207d5dec1SJeremy L Thompson
1543ca94c3ddSJeremy L Thompson @brief Get the number of points in an element of a `CeedElemRestriction` at points
154407d5dec1SJeremy L Thompson
1545ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
154607d5dec1SJeremy L Thompson @param[in] elem Index number of element to retrieve the number of points for
154707d5dec1SJeremy L Thompson @param[out] num_points The number of points in the element at index elem
154807d5dec1SJeremy L Thompson
154907d5dec1SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
155007d5dec1SJeremy L Thompson
1551c63574e3SJeremy L Thompson @ref User
155207d5dec1SJeremy L Thompson **/
CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr,CeedInt elem,CeedInt * num_points)155307d5dec1SJeremy L Thompson int CeedElemRestrictionGetNumPointsInElement(CeedElemRestriction rstr, CeedInt elem, CeedInt *num_points) {
15541203703bSJeremy L Thompson CeedRestrictionType rstr_type;
155507d5dec1SJeremy L Thompson const CeedInt *offsets;
155607d5dec1SJeremy L Thompson
15571203703bSJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
15586e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE,
155907d5dec1SJeremy L Thompson "Can only retrieve the number of points for a points CeedElemRestriction");
156007d5dec1SJeremy L Thompson
156107d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionGetOffsets(rstr, CEED_MEM_HOST, &offsets));
156207d5dec1SJeremy L Thompson *num_points = offsets[elem + 1] - offsets[elem];
156307d5dec1SJeremy L Thompson CeedCall(CeedElemRestrictionRestoreOffsets(rstr, &offsets));
156407d5dec1SJeremy L Thompson return CEED_ERROR_SUCCESS;
156507d5dec1SJeremy L Thompson }
156607d5dec1SJeremy L Thompson
156707d5dec1SJeremy L Thompson /**
1568a4065bfbSZach Atkins @brief Get the minimum and/or maximum number of points in an element for a `CeedElemRestriction` at points
15692c7e7413SJeremy L Thompson
1570ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1571a4065bfbSZach Atkins @param[out] min_points Variable to minimum number of points in an element, or `NULL`
1572a4065bfbSZach Atkins @param[out] max_points Variable to maximum number of points in an element, or `NULL`
15732c7e7413SJeremy L Thompson
15742c7e7413SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
15752c7e7413SJeremy L Thompson
15762c7e7413SJeremy L Thompson @ref Advanced
15772c7e7413SJeremy L Thompson **/
CeedElemRestrictionGetMinMaxPointsInElement(CeedElemRestriction rstr,CeedInt * min_points,CeedInt * max_points)1578a4065bfbSZach Atkins int CeedElemRestrictionGetMinMaxPointsInElement(CeedElemRestriction rstr, CeedInt *min_points, CeedInt *max_points) {
1579a4065bfbSZach Atkins CeedInt num_elem, num_points;
15802c7e7413SJeremy L Thompson CeedRestrictionType rstr_type;
15812c7e7413SJeremy L Thompson
15822c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
15836e536b99SJeremy L Thompson CeedCheck(rstr_type == CEED_RESTRICTION_POINTS, CeedElemRestrictionReturnCeed(rstr), CEED_ERROR_INCOMPATIBLE,
1584a4065bfbSZach Atkins "Cannot compute min/max points for a CeedElemRestriction that does not use points");
15852c7e7413SJeremy L Thompson
15862c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumElements(rstr, &num_elem));
15872c7e7413SJeremy L Thompson
1588a4065bfbSZach Atkins // Exit early if there are no elements
1589a4065bfbSZach Atkins if (num_elem == 0) {
1590a4065bfbSZach Atkins if (min_points) *min_points = 0;
1591a4065bfbSZach Atkins if (max_points) *max_points = 0;
1592a4065bfbSZach Atkins return CEED_ERROR_SUCCESS;
1593a4065bfbSZach Atkins }
1594a4065bfbSZach Atkins
1595a4065bfbSZach Atkins // Initialize to the number of points in the first element
1596a4065bfbSZach Atkins CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, 0, &num_points));
1597a4065bfbSZach Atkins if (min_points) *min_points = num_points;
1598a4065bfbSZach Atkins if (max_points) *max_points = num_points;
1599a4065bfbSZach Atkins for (CeedInt e = 1; e < num_elem; e++) {
16002c7e7413SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumPointsInElement(rstr, e, &num_points));
1601a4065bfbSZach Atkins if (min_points) *min_points = CeedIntMin(num_points, *min_points);
1602a4065bfbSZach Atkins if (max_points) *max_points = CeedIntMax(num_points, *max_points);
16032c7e7413SJeremy L Thompson }
1604e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1605a681ae63Sjeremylt }
1606a681ae63Sjeremylt
1607a681ae63Sjeremylt /**
1608a4065bfbSZach Atkins @brief Get the maximum number of points in an element for a `CeedElemRestriction` at points
1609a4065bfbSZach Atkins
1610a4065bfbSZach Atkins @param[in] rstr `CeedElemRestriction`
1611a4065bfbSZach Atkins @param[out] max_points Variable to store maximum number of points in an element
1612a4065bfbSZach Atkins
1613a4065bfbSZach Atkins @return An error code: 0 - success, otherwise - failure
1614a4065bfbSZach Atkins
1615a4065bfbSZach Atkins @ref User
1616a4065bfbSZach Atkins
1617a4065bfbSZach Atkins @see CeedElemRestrictionGetMinMaxPointsInElement()
1618a4065bfbSZach Atkins **/
CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr,CeedInt * max_points)1619a4065bfbSZach Atkins int CeedElemRestrictionGetMaxPointsInElement(CeedElemRestriction rstr, CeedInt *max_points) {
1620a4065bfbSZach Atkins return CeedElemRestrictionGetMinMaxPointsInElement(rstr, NULL, max_points);
1621a4065bfbSZach Atkins }
1622a4065bfbSZach Atkins
1623a4065bfbSZach Atkins /**
1624a4065bfbSZach Atkins @brief Get the minimum number of points in an element for a `CeedElemRestriction` at points
1625a4065bfbSZach Atkins
1626a4065bfbSZach Atkins @param[in] rstr `CeedElemRestriction`
1627a4065bfbSZach Atkins @param[out] min_points Variable to store minimum number of points in an element
1628a4065bfbSZach Atkins
1629a4065bfbSZach Atkins @return An error code: 0 - success, otherwise - failure
1630a4065bfbSZach Atkins
1631a4065bfbSZach Atkins @ref User
1632a4065bfbSZach Atkins
1633a4065bfbSZach Atkins @see CeedElemRestrictionGetMinMaxPointsInElement()
1634a4065bfbSZach Atkins **/
CeedElemRestrictionGetMinPointsInElement(CeedElemRestriction rstr,CeedInt * min_points)1635a4065bfbSZach Atkins int CeedElemRestrictionGetMinPointsInElement(CeedElemRestriction rstr, CeedInt *min_points) {
1636a4065bfbSZach Atkins return CeedElemRestrictionGetMinMaxPointsInElement(rstr, min_points, NULL);
1637a4065bfbSZach Atkins }
1638a4065bfbSZach Atkins
1639a4065bfbSZach Atkins /**
1640ca94c3ddSJeremy L Thompson @brief Get the size of the l-vector for a `CeedElemRestriction`
1641a681ae63Sjeremylt
1642ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1643701e7d35SJeremy L Thompson @param[out] l_size Variable to store l-vector size
1644a681ae63Sjeremylt
1645a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure
1646a681ae63Sjeremylt
1647b7c9bbdaSJeremy L Thompson @ref Advanced
1648a681ae63Sjeremylt **/
CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,CeedSize * l_size)16492b730f8bSJeremy L Thompson int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr, CeedSize *l_size) {
1650d1d35e2fSjeremylt *l_size = rstr->l_size;
1651e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1652a681ae63Sjeremylt }
1653a681ae63Sjeremylt
1654a681ae63Sjeremylt /**
1655701e7d35SJeremy L Thompson @brief Get the size of the e-vector for a `CeedElemRestriction`
1656701e7d35SJeremy L Thompson
1657701e7d35SJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1658701e7d35SJeremy L Thompson @param[out] e_size Variable to store e-vector size
1659701e7d35SJeremy L Thompson
1660701e7d35SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1661701e7d35SJeremy L Thompson
1662701e7d35SJeremy L Thompson @ref Advanced
1663701e7d35SJeremy L Thompson **/
CeedElemRestrictionGetEVectorSize(CeedElemRestriction rstr,CeedSize * e_size)1664701e7d35SJeremy L Thompson int CeedElemRestrictionGetEVectorSize(CeedElemRestriction rstr, CeedSize *e_size) {
1665701e7d35SJeremy L Thompson *e_size = rstr->e_size;
1666701e7d35SJeremy L Thompson return CEED_ERROR_SUCCESS;
1667701e7d35SJeremy L Thompson }
1668701e7d35SJeremy L Thompson
1669701e7d35SJeremy L Thompson /**
1670ca94c3ddSJeremy L Thompson @brief Get the number of components in the elements of a `CeedElemRestriction`
1671a681ae63Sjeremylt
1672ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1673d1d35e2fSjeremylt @param[out] num_comp Variable to store number of components
1674a681ae63Sjeremylt
1675a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure
1676a681ae63Sjeremylt
1677b7c9bbdaSJeremy L Thompson @ref Advanced
1678a681ae63Sjeremylt **/
CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,CeedInt * num_comp)16792b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr, CeedInt *num_comp) {
1680d1d35e2fSjeremylt *num_comp = rstr->num_comp;
1681e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1682a681ae63Sjeremylt }
1683a681ae63Sjeremylt
1684a681ae63Sjeremylt /**
1685ca94c3ddSJeremy L Thompson @brief Get the number of blocks in a `CeedElemRestriction`
1686a681ae63Sjeremylt
1687ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1688d1d35e2fSjeremylt @param[out] num_block Variable to store number of blocks
1689a681ae63Sjeremylt
1690a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure
1691a681ae63Sjeremylt
1692b7c9bbdaSJeremy L Thompson @ref Advanced
1693a681ae63Sjeremylt **/
CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,CeedInt * num_block)16942b730f8bSJeremy L Thompson int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr, CeedInt *num_block) {
1695e7f679fcSJeremy L Thompson *num_block = rstr->num_block;
1696e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1697a681ae63Sjeremylt }
1698a681ae63Sjeremylt
1699a681ae63Sjeremylt /**
1700ca94c3ddSJeremy L Thompson @brief Get the size of blocks in the `CeedElemRestriction`
1701a681ae63Sjeremylt
1702ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1703e7f679fcSJeremy L Thompson @param[out] block_size Variable to store size of blocks
1704a681ae63Sjeremylt
1705a681ae63Sjeremylt @return An error code: 0 - success, otherwise - failure
1706a681ae63Sjeremylt
1707b7c9bbdaSJeremy L Thompson @ref Advanced
1708a681ae63Sjeremylt **/
CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,CeedInt * block_size)1709e7f679fcSJeremy L Thompson int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr, CeedInt *block_size) {
1710e7f679fcSJeremy L Thompson *block_size = rstr->block_size;
1711e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1712a681ae63Sjeremylt }
1713a681ae63Sjeremylt
1714a681ae63Sjeremylt /**
1715ca94c3ddSJeremy L Thompson @brief Get the multiplicity of nodes in a `CeedElemRestriction`
17161469ee4dSjeremylt
1717ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction`
1718ca94c3ddSJeremy L Thompson @param[out] mult Vector to store multiplicity (of size `l_size`)
17191469ee4dSjeremylt
17201469ee4dSjeremylt @return An error code: 0 - success, otherwise - failure
17211469ee4dSjeremylt
17227a982d89SJeremy L. Thompson @ref User
17231469ee4dSjeremylt **/
CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,CeedVector mult)17242b730f8bSJeremy L Thompson int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr, CeedVector mult) {
1725d1d35e2fSjeremylt CeedVector e_vec;
17261469ee4dSjeremylt
172725509ebbSRezgar Shakeri // Create e_vec to hold intermediate computation in E^T (E 1)
17282b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionCreateVector(rstr, NULL, &e_vec));
17291469ee4dSjeremylt
173025509ebbSRezgar Shakeri // Compute e_vec = E * 1
17312b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 1.0));
17322b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_NOTRANSPOSE, mult, e_vec, CEED_REQUEST_IMMEDIATE));
173325509ebbSRezgar Shakeri // Compute multiplicity, mult = E^T * e_vec = E^T (E 1)
17342b730f8bSJeremy L Thompson CeedCall(CeedVectorSetValue(mult, 0.0));
17352b730f8bSJeremy L Thompson CeedCall(CeedElemRestrictionApply(rstr, CEED_TRANSPOSE, e_vec, mult, CEED_REQUEST_IMMEDIATE));
17361469ee4dSjeremylt // Cleanup
17372b730f8bSJeremy L Thompson CeedCall(CeedVectorDestroy(&e_vec));
1738e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
17391469ee4dSjeremylt }
17401469ee4dSjeremylt
17411469ee4dSjeremylt /**
17424c789ea2SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedElemRestrictionView() output
17434c789ea2SJeremy L Thompson
17444c789ea2SJeremy L Thompson @param[in] rstr `CeedElemRestriction` to set the number of view tabs
17454c789ea2SJeremy L Thompson @param[in] num_tabs Number of view tabs to set
17464c789ea2SJeremy L Thompson
17474c789ea2SJeremy L Thompson @return Error code: 0 - success, otherwise - failure
17484c789ea2SJeremy L Thompson
17494c789ea2SJeremy L Thompson @ref User
17504c789ea2SJeremy L Thompson **/
CeedElemRestrictionSetNumViewTabs(CeedElemRestriction rstr,CeedInt num_tabs)17514c789ea2SJeremy L Thompson int CeedElemRestrictionSetNumViewTabs(CeedElemRestriction rstr, CeedInt num_tabs) {
1752a299a25bSJeremy L Thompson CeedCall(CeedObjectSetNumViewTabs((CeedObject)rstr, num_tabs));
17534c789ea2SJeremy L Thompson return CEED_ERROR_SUCCESS;
17544c789ea2SJeremy L Thompson }
17554c789ea2SJeremy L Thompson
17564c789ea2SJeremy L Thompson /**
1757690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedElemRestrictionView() output
1758690992b2SZach Atkins
1759690992b2SZach Atkins @param[in] rstr `CeedElemRestriction` to get the number of view tabs
1760690992b2SZach Atkins @param[out] num_tabs Number of view tabs
1761690992b2SZach Atkins
1762690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure
1763690992b2SZach Atkins
1764690992b2SZach Atkins @ref User
1765690992b2SZach Atkins **/
CeedElemRestrictionGetNumViewTabs(CeedElemRestriction rstr,CeedInt * num_tabs)1766690992b2SZach Atkins int CeedElemRestrictionGetNumViewTabs(CeedElemRestriction rstr, CeedInt *num_tabs) {
1767a299a25bSJeremy L Thompson CeedCall(CeedObjectGetNumViewTabs((CeedObject)rstr, num_tabs));
1768690992b2SZach Atkins return CEED_ERROR_SUCCESS;
1769690992b2SZach Atkins }
1770690992b2SZach Atkins
1771690992b2SZach Atkins /**
1772ca94c3ddSJeremy L Thompson @brief View a `CeedElemRestriction`
1773f02ca4a2SJed Brown
1774ca94c3ddSJeremy L Thompson @param[in] rstr `CeedElemRestriction` to view
1775ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file
1776f02ca4a2SJed Brown
1777f02ca4a2SJed Brown @return Error code: 0 - success, otherwise - failure
1778f02ca4a2SJed Brown
17797a982d89SJeremy L. Thompson @ref User
1780f02ca4a2SJed Brown **/
CeedElemRestrictionView(CeedElemRestriction rstr,FILE * stream)1781f02ca4a2SJed Brown int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream) {
17824c789ea2SJeremy L Thompson char *tabs = NULL;
17830930e4e7SJeremy L Thompson CeedRestrictionType rstr_type;
17840930e4e7SJeremy L Thompson
17854c789ea2SJeremy L Thompson {
17864c789ea2SJeremy L Thompson CeedInt num_tabs = 0;
17874c789ea2SJeremy L Thompson
17884c789ea2SJeremy L Thompson CeedCall(CeedElemRestrictionGetNumViewTabs(rstr, &num_tabs));
17894c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * num_tabs + 1, &tabs));
17904c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' ';
17914c789ea2SJeremy L Thompson }
17924c789ea2SJeremy L Thompson
17930930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetType(rstr, &rstr_type));
17940930e4e7SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) {
17950930e4e7SJeremy L Thompson CeedInt max_points;
17960930e4e7SJeremy L Thompson
17970930e4e7SJeremy L Thompson CeedCall(CeedElemRestrictionGetMaxPointsInElement(rstr, &max_points));
17980930e4e7SJeremy L Thompson fprintf(stream,
17994c789ea2SJeremy L Thompson "%sCeedElemRestriction at points from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with a maximum of %" CeedInt_FMT
18000930e4e7SJeremy L Thompson " points on an element\n",
18014c789ea2SJeremy L Thompson tabs, rstr->l_size, rstr->num_comp, rstr->num_elem, max_points);
18020930e4e7SJeremy L Thompson } else {
1803249f8407SJeremy L Thompson char strides_str[500];
18041c66c397SJeremy L Thompson
18052b730f8bSJeremy L Thompson if (rstr->strides) {
1806249f8407SJeremy L Thompson sprintf(strides_str, "[%" CeedInt_FMT ", %" CeedInt_FMT ", %" CeedInt_FMT "]", rstr->strides[0], rstr->strides[1], rstr->strides[2]);
18072b730f8bSJeremy L Thompson } else {
1808249f8407SJeremy L Thompson sprintf(strides_str, "%" CeedInt_FMT, rstr->comp_stride);
18092b730f8bSJeremy L Thompson }
1810249f8407SJeremy L Thompson fprintf(stream,
18114c789ea2SJeremy L Thompson "%s%sCeedElemRestriction from (%" CeedSize_FMT ", %" CeedInt_FMT ") to %" CeedInt_FMT " elements with %" CeedInt_FMT
1812249f8407SJeremy L Thompson " nodes each and %s %s\n",
18134c789ea2SJeremy L Thompson tabs, rstr->block_size > 1 ? "Blocked " : "", rstr->l_size, rstr->num_comp, rstr->num_elem, rstr->elem_size,
1814249f8407SJeremy L Thompson rstr->strides ? "strides" : "component stride", strides_str);
18150930e4e7SJeremy L Thompson }
18164c789ea2SJeremy L Thompson CeedCall(CeedFree(&tabs));
1817e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1818f02ca4a2SJed Brown }
1819f02ca4a2SJed Brown
1820f02ca4a2SJed Brown /**
1821ca94c3ddSJeremy L Thompson @brief Destroy a `CeedElemRestriction`
1822b11c1e72Sjeremylt
1823ca94c3ddSJeremy L Thompson @param[in,out] rstr `CeedElemRestriction` to destroy
1824b11c1e72Sjeremylt
1825b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
1826dfdf5a53Sjeremylt
18277a982d89SJeremy L. Thompson @ref User
1828b11c1e72Sjeremylt **/
CeedElemRestrictionDestroy(CeedElemRestriction * rstr)18294ce2993fSjeremylt int CeedElemRestrictionDestroy(CeedElemRestriction *rstr) {
1830b0f67a9cSJeremy L Thompson if (!*rstr || *rstr == CEED_ELEMRESTRICTION_NONE || CeedObjectDereference((CeedObject)*rstr) > 0) {
1831ad6481ceSJeremy L Thompson *rstr = NULL;
1832ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS;
1833ad6481ceSJeremy L Thompson }
1834b0f67a9cSJeremy L Thompson CeedCheck((*rstr)->num_readers == 0, CeedElemRestrictionReturnCeed(*rstr), CEED_ERROR_ACCESS,
18356574a04fSJeremy L Thompson "Cannot destroy CeedElemRestriction, a process has read access to the offset data");
1836c17ec2beSJeremy L Thompson
1837c17ec2beSJeremy L Thompson // Only destroy backend data once between rstr and unsigned copy
18387c1dbaffSSebastian Grimberg if ((*rstr)->rstr_base) CeedCall(CeedElemRestrictionDestroy(&(*rstr)->rstr_base));
1839c17ec2beSJeremy L Thompson else if ((*rstr)->Destroy) CeedCall((*rstr)->Destroy(*rstr));
1840c17ec2beSJeremy L Thompson
18412b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*rstr)->strides));
1842*6c328a79SJeremy L Thompson CeedCall(CeedObjectDestroy_Private(&(*rstr)->obj));
18432b730f8bSJeremy L Thompson CeedCall(CeedFree(rstr));
1844e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1845d7b241e6Sjeremylt }
1846d7b241e6Sjeremylt
1847d7b241e6Sjeremylt /// @}
1848