Skip to content

Commit f6e118e

Browse files
committed
SWE: Add FindPanelEdgeNodes() function to determine which nodes are on the cube edges
The algorithm with bit manipulation was greatly inspired-by and helped-by @matteovigni Thanks-to @matteovigni
1 parent 236dcbd commit f6e118e

4 files changed

Lines changed: 94 additions & 6 deletions

File tree

examples/fluids/shallow-water/qfunctions/setup_geo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ CEED_QFUNCTION(SetupGeo)(void *ctx, CeedInt Q,
171171
qdata[7][i] = dxdXTdxdXinv[0][0];
172172
qdata[8][i] = dxdXTdxdXinv[1][1];
173173
qdata[9][i] = dxdXTdxdXinv[0][1];
174-
174+
175175
// Terrain topography, hs
176176
qdata[10][i] = sin(xx[0]) + cos(xx[1]); // put 0 for constant flat topography
177177
} // End of Quadrature Point Loop

examples/fluids/shallow-water/shallowwater.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ int main(int argc, char **argv) {
5656
Units units;
5757
problemType problemChoice;
5858
problemData *problem = NULL;
59+
EdgeNode edgenodes;
5960
StabilizationType stab;
6061
PetscBool implicit;
6162
PetscInt degree, qextra, outputfreq, steps, contsteps;
@@ -374,6 +375,9 @@ int main(int argc, char **argv) {
374375
// Set up global mass vector
375376
ierr = VecDuplicate(Q, &user->M); CHKERRQ(ierr);
376377

378+
// Setup global lat-long vector for different panels (charts) of the cube
379+
ierr = FindPanelEdgeNodes(dm, ncompq, &edgenodes); CHKERRQ(ierr);
380+
377381
// Setup libCEED's objects
378382
ierr = PetscMalloc1(1, &ceeddata); CHKERRQ(ierr);
379383
ierr = SetupLibceed(dm, ceed, degree, qextra, ncompx, ncompq, user, ceeddata,

examples/fluids/shallow-water/src/setup.c

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
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
182253
PetscErrorCode 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);

examples/fluids/shallow-water/sw_headers.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static const char *const StabilizationTypes[] = {
9393
// PETSc user data
9494
typedef struct User_ *User;
9595
typedef struct Units_ *Units;
96+
typedef struct EdgeNode_ *EdgeNode;
9697

9798
struct User_ {
9899
MPI_Comm comm;
@@ -117,6 +118,11 @@ struct Units_ {
117118
PetscScalar mpersquareds;
118119
};
119120

121+
struct EdgeNode_ {
122+
PetscInt idx; // Node index
123+
PetscInt panelA, panelB; // Indices of panels sharing the edge node
124+
};
125+
120126
// libCEED data struct
121127
typedef struct CeedData_ *CeedData;
122128
struct CeedData_ {
@@ -132,6 +138,13 @@ struct CeedData_ {
132138
// External variables
133139
extern problemData problemOptions[];
134140

141+
// -----------------------------------------------------------------------------
142+
// Auxiliary functions for cube face (panel) charts
143+
// -----------------------------------------------------------------------------
144+
145+
// Auxiliary function to determine if nodes belong to cube faces (panels)
146+
PetscErrorCode FindPanelEdgeNodes(DM dm, CeedInt ncomp, EdgeNode *edgenodes);
147+
135148
// -----------------------------------------------------------------------------
136149
// Setup DM functions
137150
// -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)