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,78 @@ 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 , PetscInt ncomp , PetscInt * nedgenodes ,
75+ EdgeNode * edgenodes ) {
76+
77+ PetscInt ierr ;
78+ PetscInt cstart , cend , nstart , nend , nnodes , depth , edgenode = 0 ;
79+ PetscSection section ;
80+ PetscFunctionBeginUser ;
81+ // Get Nelem
82+ ierr = DMGetSection (dm , & section ); CHKERRQ (ierr );
83+ ierr = DMPlexGetHeightStratum (dm , 0 , & cstart , & cend ); CHKERRQ (ierr );
84+ ierr = DMPlexGetDepth (dm , & depth ); CHKERRQ (ierr );
85+ ierr = DMPlexGetHeightStratum (dm , depth , & nstart , & nend ); CHKERRQ (ierr );
86+ nnodes = nend - nstart ;
87+ unsigned int bitmap [nnodes ];
88+ ierr = PetscMemzero (bitmap , sizeof (bitmap )); CHKERRQ (ierr );
89+
90+ // Get indices
91+ for (PetscInt c = cstart ; c < cend ; c ++ ) { // Traverse elements
92+ PetscInt numindices , * indices , n , panel ;
93+ // Query element panel
94+ ierr = DMGetLabelValue (dm , "panel" , c , & panel ); CHKERRQ (ierr );
95+ ierr = DMPlexGetClosureIndices (dm , section , section , c , PETSC_TRUE ,
96+ & numindices , & indices , NULL , NULL );
97+ CHKERRQ (ierr );
98+ for (n = 0 ; n < numindices ; n += ncomp ) { // Traverse nodes per element
99+ PetscInt bitmapidx = indices [n ] / ncomp ;
100+ bitmap [bitmapidx ] |= (1 << panel );
101+ }
102+ ierr = DMPlexRestoreClosureIndices (dm , section , section , c , PETSC_TRUE ,
103+ & numindices , & indices , NULL , NULL );
104+ CHKERRQ (ierr );
105+ }
106+ // Read the 1's in the resulting bitmap and extract edge nodes only
107+ ierr = PetscMalloc1 (nnodes + 24 , edgenodes ); CHKERRQ (ierr );
108+ for (PetscInt i = 0 ; i < nnodes ; i ++ ) {
109+ PetscInt ones = 0 , panels [3 ];
110+ for (PetscInt p = 0 ; p < 6 ; p ++ ) {
111+ if (bitmap [i ] & 1 )
112+ panels [ones ++ ] = p ;
113+ bitmap [i ] >>= 1 ;
114+ }
115+ if (ones == 2 ) {
116+ (* edgenodes )[edgenode ].idx = i ;
117+ (* edgenodes )[edgenode ].panelA = panels [0 ];
118+ (* edgenodes )[edgenode ].panelB = panels [1 ];
119+ edgenode ++ ;
120+ }
121+ else if (ones == 3 ) {
122+ (* edgenodes )[edgenode ].idx = i ;
123+ (* edgenodes )[edgenode ].panelA = panels [0 ];
124+ (* edgenodes )[edgenode ].panelB = panels [1 ];
125+ edgenode ++ ;
126+ (* edgenodes )[edgenode ].idx = i ;
127+ (* edgenodes )[edgenode ].panelA = panels [0 ];
128+ (* edgenodes )[edgenode ].panelB = panels [2 ];
129+ edgenode ++ ;
130+ (* edgenodes )[edgenode ].idx = i ;
131+ (* edgenodes )[edgenode ].panelA = panels [1 ];
132+ (* edgenodes )[edgenode ].panelB = panels [2 ];
133+ edgenode ++ ;
134+ }
135+ }
136+ ierr = PetscRealloc (edgenode , edgenodes ); CHKERRQ (ierr );
137+ * nedgenodes = edgenode ;
138+
139+ PetscFunctionReturn (0 );
140+ }
141+
69142// -----------------------------------------------------------------------------
70143// Auxiliary function to create PETSc FE space for a given degree
71144// -----------------------------------------------------------------------------
@@ -178,7 +251,7 @@ PetscErrorCode SetupDM(DM dm, PetscInt degree, PetscInt ncompq,
178251// PETSc sphere auxiliary function
179252// -----------------------------------------------------------------------------
180253
181- // Utility function taken from petsc/src/dm/impls/plex/examples/ tutorials/ex7.c
254+ // Utility function taken from petsc/src/dm/impls/plex/tutorials/ex7.c
182255PetscErrorCode ProjectToUnitSphere (DM dm ) {
183256 Vec coordinates ;
184257 PetscScalar * coords ;
@@ -223,13 +296,13 @@ PetscErrorCode CreateRestrictionPlex(Ceed ceed, DM dm, CeedInt P,
223296
224297 // Get indices
225298 ierr = PetscMalloc1 (nelem * P * P , & erestrict ); CHKERRQ (ierr );
226- for (c = cStart , eoffset = 0 ; c < cEnd ; c ++ ) {
299+ for (c = cStart , eoffset = 0 ; c < cEnd ; c ++ ) {
227300 PetscInt numindices , * indices , i ;
228301 ierr = DMPlexGetClosureIndices (dm , section , section , c , PETSC_TRUE ,
229302 & numindices , & indices , NULL , NULL );
230303 CHKERRQ (ierr );
231- for (i = 0 ; i < numindices ; i += ncomp ) {
232- for (PetscInt j = 0 ; j < ncomp ; j ++ ) {
304+ for (i = 0 ; i < numindices ; i += ncomp ) {
305+ for (PetscInt j = 0 ; j < ncomp ; j ++ ) {
233306 if (indices [i + j ] != indices [i ] + (PetscInt )(copysign (j , indices [i ])))
234307 SETERRQ1 (PETSC_COMM_SELF , PETSC_ERR_ARG_INCOMP ,
235308 "Cell %D closure indices not interlaced" , c );
@@ -244,7 +317,7 @@ PetscErrorCode CreateRestrictionPlex(Ceed ceed, DM dm, CeedInt P,
244317 }
245318 if (eoffset != nelem * P * P ) SETERRQ3 (PETSC_COMM_SELF ,
246319 PETSC_ERR_LIB , "ElemRestriction of size (%D,%D) initialized %D nodes" ,
247- nelem , P * P ,eoffset );
320+ nelem , P * P , eoffset );
248321
249322 // Setup CEED restriction
250323 ierr = DMGetLocalVector (dm , & Uloc ); CHKERRQ (ierr );
0 commit comments