Skip to content

Commit 4744864

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 4744864

File tree

4 files changed

+98
-7
lines changed

4 files changed

+98
-7
lines changed

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: 5 additions & 1 deletion
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;
@@ -65,7 +66,7 @@ int main(int argc, char **argv) {
6566
const CeedInt ncompx = 3;
6667
PetscInt viz_refine = 0;
6768
PetscBool read_mesh, simplex, test;
68-
PetscInt topodim = 2, ncompq = 3, lnodes;
69+
PetscInt topodim = 2, ncompq = 3, lnodes, nedgenodes;
6970
// libCEED context
7071
char ceedresource[PETSC_MAX_PATH_LEN] = "/cpu/self",
7172
filename[PETSC_MAX_PATH_LEN];
@@ -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, &nedgenodes, &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: 78 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,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
182255
PetscErrorCode 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);

examples/fluids/shallow-water/sw_headers.h

Lines changed: 14 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,14 @@ 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, PetscInt ncomp, PetscInt *nedgenodes,
147+
EdgeNode *edgenodes);
148+
135149
// -----------------------------------------------------------------------------
136150
// Setup DM functions
137151
// -----------------------------------------------------------------------------

0 commit comments

Comments
 (0)