Skip to content

Commit c6e1a27

Browse files
authored
Merge pull request #889 from CEED/rezgar/oriented-restr
Element Restriction Oriented
2 parents 5392e1e + 000294e commit c6e1a27

17 files changed

+208
-10
lines changed

backends/ref/ceed-ref-restriction.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r,
3737
ierr = CeedElemRestrictionGetElementSize(r, &elem_size); CeedChkBackend(ierr);
3838
v_offset = start*blk_size*elem_size*num_comp;
3939

40+
bool is_oriented;
41+
ierr = CeedElemRestrictionIsOriented(r, &is_oriented); CeedChkBackend(ierr);
4042
ierr = CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu); CeedChkBackend(ierr);
4143
if (t_mode == CEED_TRANSPOSE) {
4244
// Sum into for transpose mode, e-vec to l-vec
@@ -91,7 +93,8 @@ static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r,
9193
CeedPragmaSIMD
9294
for (CeedInt i = 0; i < elem_size*blk_size; i++)
9395
vv[elem_size*(k*blk_size+num_comp*e) + i - v_offset]
94-
= uu[impl->offsets[i+elem_size*e] + k*comp_stride];
96+
= uu[impl->offsets[i+elem_size*e] + k*comp_stride] *
97+
(is_oriented && impl->orient[i+elem_size*e] ? -1. : 1.);
9598
}
9699
} else {
97100
// Restriction from E-vector to L-vector
@@ -137,7 +140,8 @@ static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r,
137140
// Iteration bound set to discard padding elements
138141
for (CeedInt j = i; j < i+CeedIntMin(blk_size, num_elem-e); j++)
139142
vv[impl->offsets[j+e*elem_size] + k*comp_stride]
140-
+= uu[elem_size*(k*blk_size+num_comp*e) + j - v_offset];
143+
+= uu[elem_size*(k*blk_size+num_comp*e) + j - v_offset] *
144+
(is_oriented && impl->orient[j+e*elem_size] ? -1. : 1.);
141145
}
142146
}
143147
ierr = CeedVectorRestoreArrayRead(u, &uu); CeedChkBackend(ierr);
@@ -456,4 +460,40 @@ int CeedElemRestrictionCreate_Ref(CeedMemType mem_type, CeedCopyMode copy_mode,
456460

457461
return CEED_ERROR_SUCCESS;
458462
}
463+
464+
//------------------------------------------------------------------------------
465+
// ElemRestriction Create Oriented
466+
//------------------------------------------------------------------------------
467+
int CeedElemRestrictionCreateOriented_Ref(CeedMemType mem_type,
468+
CeedCopyMode copy_mode,
469+
const CeedInt *offsets, const bool *orient,
470+
CeedElemRestriction r) {
471+
int ierr;
472+
CeedElemRestriction_Ref *impl;
473+
CeedInt num_elem, elem_size;
474+
// Set up for normal restriction with explicit offsets. This sets up dispatch to
475+
// CeedElemRestrictionApply_Ref_* and manages the impl->offsets array copy/allocation.
476+
ierr = CeedElemRestrictionCreate_Ref(mem_type, copy_mode, offsets, r);
477+
CeedChkBackend(ierr);
478+
479+
ierr = CeedElemRestrictionGetData(r, &impl); CeedChkBackend(ierr);
480+
ierr = CeedElemRestrictionGetNumElements(r, &num_elem); CeedChkBackend(ierr);
481+
ierr = CeedElemRestrictionGetElementSize(r, &elem_size); CeedChkBackend(ierr);
482+
switch (copy_mode) {
483+
case CEED_COPY_VALUES:
484+
ierr = CeedMalloc(num_elem * elem_size, &impl->orient_allocated);
485+
CeedChkBackend(ierr);
486+
memcpy(impl->orient_allocated, orient,
487+
num_elem * elem_size * sizeof(orient[0]));
488+
impl->orient = impl->orient_allocated;
489+
break;
490+
case CEED_OWN_POINTER:
491+
impl->orient_allocated = (bool *)orient;
492+
impl->orient = impl->orient_allocated;
493+
break;
494+
case CEED_USE_POINTER:
495+
impl->orient = orient;
496+
}
497+
return CEED_ERROR_SUCCESS;
498+
}
459499
//------------------------------------------------------------------------------

backends/ref/ceed-ref.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ static int CeedInit_Ref(const char *resource, Ceed ceed) {
4444
CeedTensorContractCreate_Ref); CeedChkBackend(ierr);
4545
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed, "ElemRestrictionCreate",
4646
CeedElemRestrictionCreate_Ref); CeedChkBackend(ierr);
47+
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed,
48+
"ElemRestrictionCreateOriented",
49+
CeedElemRestrictionCreateOriented_Ref); CeedChkBackend(ierr);
4750
ierr = CeedSetBackendFunction(ceed, "Ceed", ceed,
4851
"ElemRestrictionCreateBlocked",
4952
CeedElemRestrictionCreate_Ref); CeedChkBackend(ierr);

backends/ref/ceed-ref.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ typedef struct {
3636
typedef struct {
3737
const CeedInt *offsets;
3838
CeedInt *offsets_allocated;
39+
// Orientation, if it exists, is true when the face must be flipped (multiplies by -1.).
40+
const bool *orient;
41+
bool *orient_allocated;
3942
int (*Apply)(CeedElemRestriction, const CeedInt, const CeedInt,
4043
const CeedInt, CeedInt, CeedInt, CeedTransposeMode, CeedVector,
4144
CeedVector, CeedRequest *);
@@ -70,6 +73,10 @@ CEED_INTERN int CeedVectorCreate_Ref(CeedInt n, CeedVector vec);
7073
CEED_INTERN int CeedElemRestrictionCreate_Ref(CeedMemType mem_type,
7174
CeedCopyMode copy_mode, const CeedInt *indices, CeedElemRestriction r);
7275

76+
CEED_INTERN int CeedElemRestrictionCreateOriented_Ref(CeedMemType mem_type,
77+
CeedCopyMode copy_mode, const CeedInt *indices,
78+
const bool *orient, CeedElemRestriction r);
79+
7380
CEED_INTERN int CeedBasisCreateTensorH1_Ref(CeedInt dim, CeedInt P_1d,
7481
CeedInt Q_1d, const CeedScalar *interp_1d, const CeedScalar *grad_1d,
7582
const CeedScalar *q_ref_1d, const CeedScalar *q_weight_1d, CeedBasis basis);

include/ceed-impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ struct Ceed_private {
105105
int (*VectorCreate)(CeedInt, CeedVector);
106106
int (*ElemRestrictionCreate)(CeedMemType, CeedCopyMode,
107107
const CeedInt *, CeedElemRestriction);
108+
int (*ElemRestrictionCreateOriented)(CeedMemType, CeedCopyMode,
109+
const CeedInt *, const bool *,
110+
CeedElemRestriction);
108111
int (*ElemRestrictionCreateBlocked)(CeedMemType, CeedCopyMode,
109112
const CeedInt *, CeedElemRestriction);
110113
int (*BasisCreateTensorH1)(CeedInt, CeedInt, CeedInt, const CeedScalar *,
@@ -177,6 +180,7 @@ struct CeedElemRestriction_private {
177180
CeedInt *strides; /* strides between [nodes, components, elements] */
178181
CeedInt layout[3]; /* E-vector layout [nodes, components, elements] */
179182
uint64_t num_readers; /* number of instances of offset read only access */
183+
bool is_oriented; /* flag for oriented restriction */
180184
void *data; /* place for the backend to store any data */
181185
};
182186

include/ceed/backend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ CEED_EXTERN int CeedElemRestrictionRestoreOffsets(CeedElemRestriction rstr,
148148
const CeedInt **offsets);
149149
CEED_EXTERN int CeedElemRestrictionIsStrided(CeedElemRestriction rstr,
150150
bool *is_strided);
151+
CEED_EXTERN int CeedElemRestrictionIsOriented(CeedElemRestriction rstr,
152+
bool *is_oriented);
151153
CEED_EXTERN int CeedElemRestrictionHasBackendStrides(CeedElemRestriction rstr,
152154
bool *has_backend_strides);
153155
CEED_EXTERN int CeedElemRestrictionGetELayout(CeedElemRestriction rstr,

include/ceed/ceed.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,10 @@ CEED_EXTERN int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem,
415415
CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedInt l_size,
416416
CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets,
417417
CeedElemRestriction *rstr);
418+
CEED_EXTERN int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem,
419+
CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedInt l_size,
420+
CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets,
421+
const bool *orient, CeedElemRestriction *rstr);
418422
CEED_EXTERN int CeedElemRestrictionCreateStrided(Ceed ceed,
419423
CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt l_size,
420424
const CeedInt strides[3], CeedElemRestriction *rstr);

interface/ceed-elemrestriction.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,21 @@ int CeedElemRestrictionIsStrided(CeedElemRestriction rstr, bool *is_strided) {
152152
return CEED_ERROR_SUCCESS;
153153
}
154154

155+
/**
156+
@brief Get oriented status of a CeedElemRestriction
157+
158+
@param rstr CeedElemRestriction
159+
@param[out] is_oriented Variable to store oriented status, 1 if oriented else 0
160+
161+
@return An error code: 0 - success, otherwise - failure
162+
163+
@ref Backend
164+
**/
165+
int CeedElemRestrictionIsOriented(CeedElemRestriction rstr, bool *is_oriented) {
166+
*is_oriented = rstr->is_oriented;
167+
return CEED_ERROR_SUCCESS;
168+
}
169+
155170
/**
156171
@brief Get the backend stride status of a CeedElemRestriction
157172
@@ -352,11 +367,84 @@ int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem, CeedInt elem_size,
352367
(*rstr)->l_size = l_size;
353368
(*rstr)->num_blk = num_elem;
354369
(*rstr)->blk_size = 1;
370+
(*rstr)->is_oriented = 0;
355371
ierr = ceed->ElemRestrictionCreate(mem_type, copy_mode, offsets, *rstr);
356372
CeedChk(ierr);
357373
return CEED_ERROR_SUCCESS;
358374
}
359375

376+
/**
377+
@brief Create a CeedElemRestriction with orientation sign
378+
379+
@param ceed A Ceed object where the CeedElemRestriction will be created
380+
@param num_elem Number of elements described in the @a offsets array
381+
@param elem_size Size (number of "nodes") per element
382+
@param num_comp Number of field components per interpolation node
383+
(1 for scalar fields)
384+
@param comp_stride Stride between components for the same L-vector "node".
385+
Data for node i, component j, element k can be found in
386+
the L-vector at index
387+
offsets[i + k*elem_size] + j*comp_stride.
388+
@param l_size The size of the L-vector. This vector may be larger than
389+
the elements and fields given by this restriction.
390+
@param mem_type Memory type of the @a offsets array, see CeedMemType
391+
@param copy_mode Copy mode for the @a offsets array, see CeedCopyMode
392+
@param offsets Array of shape [@a num_elem, @a elem_size]. Row i holds the
393+
ordered list of the offsets (into the input CeedVector)
394+
for the unknowns corresponding to element i, where
395+
0 <= i < @a num_elem. All offsets must be in the range
396+
[0, @a l_size - 1].
397+
@param orient Array of shape [@a num_elem, @a elem_size] with bool false
398+
for positively oriented and true to flip the orientation.
399+
@param[out] rstr Address of the variable where the newly created
400+
CeedElemRestriction will be stored
401+
402+
@return An error code: 0 - success, otherwise - failure
403+
404+
@ref User
405+
**/
406+
int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem,
407+
CeedInt elem_size, CeedInt num_comp,
408+
CeedInt comp_stride, CeedInt l_size,
409+
CeedMemType mem_type, CeedCopyMode copy_mode,
410+
const CeedInt *offsets, const bool *orient,
411+
CeedElemRestriction *rstr) {
412+
int ierr;
413+
414+
if (!ceed->ElemRestrictionCreateOriented) {
415+
Ceed delegate;
416+
ierr = CeedGetObjectDelegate(ceed, &delegate, "ElemRestriction");
417+
CeedChk(ierr);
418+
419+
if (!delegate)
420+
// LCOV_EXCL_START
421+
return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
422+
"Backend does not implement ElemRestrictionCreateOriented");
423+
// LCOV_EXCL_STOP
424+
425+
ierr = CeedElemRestrictionCreateOriented(delegate, num_elem, elem_size,
426+
num_comp, comp_stride, l_size, mem_type, copy_mode, offsets,
427+
orient, rstr); CeedChk(ierr);
428+
return CEED_ERROR_SUCCESS;
429+
}
430+
431+
ierr = CeedCalloc(1, rstr); CeedChk(ierr);
432+
(*rstr)->ceed = ceed;
433+
ierr = CeedReference(ceed); CeedChk(ierr);
434+
(*rstr)->ref_count = 1;
435+
(*rstr)->num_elem = num_elem;
436+
(*rstr)->elem_size = elem_size;
437+
(*rstr)->num_comp = num_comp;
438+
(*rstr)->comp_stride = comp_stride;
439+
(*rstr)->l_size = l_size;
440+
(*rstr)->num_blk = num_elem;
441+
(*rstr)->blk_size = 1;
442+
(*rstr)->is_oriented = 1;
443+
ierr = ceed->ElemRestrictionCreateOriented(mem_type, copy_mode,
444+
offsets, orient, *rstr); CeedChk(ierr);
445+
return CEED_ERROR_SUCCESS;
446+
}
447+
360448
/**
361449
@brief Create a strided CeedElemRestriction
362450
@@ -414,6 +502,7 @@ int CeedElemRestrictionCreateStrided(Ceed ceed, CeedInt num_elem,
414502
(*rstr)->l_size = l_size;
415503
(*rstr)->num_blk = num_elem;
416504
(*rstr)->blk_size = 1;
505+
(*rstr)->is_oriented = 0;
417506
ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
418507
for (int i=0; i<3; i++)
419508
(*rstr)->strides[i] = strides[i];
@@ -500,6 +589,7 @@ int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem,
500589
(*rstr)->l_size = l_size;
501590
(*rstr)->num_blk = num_blk;
502591
(*rstr)->blk_size = blk_size;
592+
(*rstr)->is_oriented = 0;
503593
ierr = ceed->ElemRestrictionCreateBlocked(CEED_MEM_HOST, CEED_OWN_POINTER,
504594
(const CeedInt *) blk_offsets, *rstr); CeedChk(ierr);
505595
if (copy_mode == CEED_OWN_POINTER) {
@@ -565,6 +655,7 @@ int CeedElemRestrictionCreateBlockedStrided(Ceed ceed, CeedInt num_elem,
565655
(*rstr)->l_size = l_size;
566656
(*rstr)->num_blk = num_blk;
567657
(*rstr)->blk_size = blk_size;
658+
(*rstr)->is_oriented = 0;
568659
ierr = CeedMalloc(3, &(*rstr)->strides); CeedChk(ierr);
569660
for (int i=0; i<3; i++)
570661
(*rstr)->strides[i] = strides[i];

interface/ceed.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,7 @@ int CeedInit(const char *resource, Ceed *ceed) {
836836
CEED_FTABLE_ENTRY(Ceed, Destroy),
837837
CEED_FTABLE_ENTRY(Ceed, VectorCreate),
838838
CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreate),
839+
CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateOriented),
839840
CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateBlocked),
840841
CEED_FTABLE_ENTRY(Ceed, BasisCreateTensorH1),
841842
CEED_FTABLE_ENTRY(Ceed, BasisCreateH1),

tests/t200-elemrestriction.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ int main(int argc, char **argv) {
2626
CeedElemRestrictionCreate(ceed, num_elem, 2, 1, 1, num_elem+1, CEED_MEM_HOST,
2727
CEED_USE_POINTER, ind, &r);
2828
CeedVectorCreate(ceed, num_elem*2, &y);
29-
CeedVectorSetValue(y, 0); // Allocates array
3029
CeedElemRestrictionApply(r, CEED_NOTRANSPOSE, x, y, CEED_REQUEST_IMMEDIATE);
3130

3231
CeedVectorGetArrayRead(y, CEED_MEM_HOST, &yy);

tests/t201-elemrestriction.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ int main(int argc, char **argv) {
2323

2424
CeedElemRestrictionCreateStrided(ceed, num_elem, 2, 1, num_elem*2, strides, &r);
2525
CeedVectorCreate(ceed, num_elem*2, &y);
26-
CeedVectorSetValue(y, 0); // Allocates array
2726
CeedElemRestrictionApply(r, CEED_NOTRANSPOSE, x, y, CEED_REQUEST_IMMEDIATE);
2827

2928
CeedVectorGetArrayRead(y, CEED_MEM_HOST, &yy);

0 commit comments

Comments
 (0)