2020#include <stdbool.h>
2121#include <string.h>
2222#include <petsc.h>
23+ #include <petscsys.h>
2324#include <petscdmplex.h>
2425#include <petscfe.h>
2526#include <ceed.h>
@@ -66,6 +67,76 @@ problemData problemOptions[] = {
6667 }
6768};
6869
70+ // -----------------------------------------------------------------------------
71+ // Auxiliary function to determine if nodes belong to cube faces (panels)
72+ // -----------------------------------------------------------------------------
73+
74+ PetscErrorCode FindPanelEdgeNodes (DM dm , CeedInt ncomp , EdgeNode * edgenodes ) {
75+
76+ PetscInt ierr ;
77+ PetscInt cstart , cend , nstart , nend , nnodes , depth , edgenode = 0 ;
78+ PetscSection section ;
79+ PetscFunctionBeginUser ;
80+ // Get Nelem
81+ ierr = DMGetSection (dm , & section ); CHKERRQ (ierr );
82+ ierr = DMPlexGetHeightStratum (dm , 0 , & cstart , & cend ); CHKERRQ (ierr );
83+ ierr = DMPlexGetDepth (dm , & depth ); CHKERRQ (ierr );
84+ ierr = DMPlexGetHeightStratum (dm , depth , & nstart , & nend ); CHKERRQ (ierr );
85+ nnodes = nend - nstart ;
86+ unsigned int bitmap [nnodes ];
87+ ierr = PetscMemzero (bitmap , sizeof (bitmap )); CHKERRQ (ierr );
88+
89+ // Get indices
90+ for (PetscInt c = cstart ; c < cend ; c ++ ) { // Traverse elements
91+ PetscInt numindices , * indices , n , panel ;
92+ // Query element panel
93+ ierr = DMGetLabelValue (dm , "panel" , c , & panel ); CHKERRQ (ierr );
94+ ierr = DMPlexGetClosureIndices (dm , section , section , c , PETSC_TRUE ,
95+ & numindices , & indices , NULL , NULL );
96+ CHKERRQ (ierr );
97+ for (n = 0 ; n < numindices ; n += ncomp ) { // Traverse nodes per element
98+ PetscInt bitmapidx = indices [n ] / ncomp ;
99+ bitmap [bitmapidx ] |= (1 << panel );
100+ }
101+ ierr = DMPlexRestoreClosureIndices (dm , section , section , c , PETSC_TRUE ,
102+ & numindices , & indices , NULL , NULL );
103+ CHKERRQ (ierr );
104+ }
105+ // Read the 1's in the resulting bitmap and extract edge nodes only
106+ ierr = PetscMalloc1 (nnodes + 24 , edgenodes ); CHKERRQ (ierr );
107+ for (PetscInt i = 0 ; i < nnodes ; i ++ ) {
108+ PetscInt ones = 0 , panels [3 ];
109+ for (PetscInt p = 0 ; p < 6 ; p ++ ) {
110+ if (bitmap [i ] & 1 )
111+ panels [ones ++ ] = p ;
112+ bitmap [i ] >>= 1 ;
113+ }
114+ if (ones == 2 ) {
115+ (* edgenodes )[edgenode ].idx = i ;
116+ (* edgenodes )[edgenode ].panelA = panels [0 ];
117+ (* edgenodes )[edgenode ].panelB = panels [1 ];
118+ edgenode ++ ;
119+ }
120+ else if (ones == 3 ) {
121+ (* edgenodes )[edgenode ].idx = i ;
122+ (* edgenodes )[edgenode ].panelA = panels [0 ];
123+ (* edgenodes )[edgenode ].panelB = panels [1 ];
124+ edgenode ++ ;
125+ (* edgenodes )[edgenode ].idx = i ;
126+ (* edgenodes )[edgenode ].panelA = panels [0 ];
127+ (* edgenodes )[edgenode ].panelB = panels [2 ];
128+ edgenode ++ ;
129+ (* edgenodes )[edgenode ].idx = i ;
130+ (* edgenodes )[edgenode ].panelA = panels [1 ];
131+ (* edgenodes )[edgenode ].panelB = panels [2 ];
132+ edgenode ++ ;
133+ }
134+ }
135+ ierr = PetscRealloc (edgenode , edgenodes ); CHKERRQ (ierr );
136+
137+ PetscFunctionReturn (0 );
138+ }
139+
69140// -----------------------------------------------------------------------------
70141// Auxiliary function to create PETSc FE space for a given degree
71142// -----------------------------------------------------------------------------
@@ -178,7 +249,7 @@ PetscErrorCode SetupDM(DM dm, PetscInt degree, PetscInt ncompq,
178249// PETSc sphere auxiliary function
179250// -----------------------------------------------------------------------------
180251
181- // Utility function taken from petsc/src/dm/impls/plex/examples/ tutorials/ex7.c
252+ // Utility function taken from petsc/src/dm/impls/plex/tutorials/ex7.c
182253PetscErrorCode ProjectToUnitSphere (DM dm ) {
183254 Vec coordinates ;
184255 PetscScalar * coords ;
@@ -223,13 +294,13 @@ PetscErrorCode CreateRestrictionPlex(Ceed ceed, DM dm, CeedInt P,
223294
224295 // Get indices
225296 ierr = PetscMalloc1 (nelem * P * P , & erestrict ); CHKERRQ (ierr );
226- for (c = cStart , eoffset = 0 ; c < cEnd ; c ++ ) {
297+ for (c = cStart , eoffset = 0 ; c < cEnd ; c ++ ) {
227298 PetscInt numindices , * indices , i ;
228299 ierr = DMPlexGetClosureIndices (dm , section , section , c , PETSC_TRUE ,
229300 & numindices , & indices , NULL , NULL );
230301 CHKERRQ (ierr );
231- for (i = 0 ; i < numindices ; i += ncomp ) {
232- for (PetscInt j = 0 ; j < ncomp ; j ++ ) {
302+ for (i = 0 ; i < numindices ; i += ncomp ) {
303+ for (PetscInt j = 0 ; j < ncomp ; j ++ ) {
233304 if (indices [i + j ] != indices [i ] + (PetscInt )(copysign (j , indices [i ])))
234305 SETERRQ1 (PETSC_COMM_SELF , PETSC_ERR_ARG_INCOMP ,
235306 "Cell %D closure indices not interlaced" , c );
@@ -244,7 +315,7 @@ PetscErrorCode CreateRestrictionPlex(Ceed ceed, DM dm, CeedInt P,
244315 }
245316 if (eoffset != nelem * P * P ) SETERRQ3 (PETSC_COMM_SELF ,
246317 PETSC_ERR_LIB , "ElemRestriction of size (%D,%D) initialized %D nodes" ,
247- nelem , P * P ,eoffset );
318+ nelem , P * P , eoffset );
248319
249320 // Setup CEED restriction
250321 ierr = DMGetLocalVector (dm , & Uloc ); CHKERRQ (ierr );
0 commit comments