Skip to content

Commit a41b89a

Browse files
committed
SWE: WIP geometric factors local to panel coord systems
1 parent 903deb0 commit a41b89a

File tree

1 file changed

+68
-101
lines changed

1 file changed

+68
-101
lines changed

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

Lines changed: 68 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -77,125 +77,92 @@ CEED_QFUNCTION(SetupGeo)(void *ctx, CeedInt Q,
7777
CeedScalar (*qdata)[CEED_Q_VLA] = (CeedScalar(*)[CEED_Q_VLA])out[0];
7878
// *INDENT-ON*
7979

80+
CeedInt panel = -1;
81+
8082
CeedPragmaSIMD
81-
// Quadrature Point Loop to determine on which panel the element belongs to
83+
// Quadrature point loop to determine which panel the element belongs to
8284
for (CeedInt i=0; i<Q; i++) {
83-
// Read local panel coordinates and relative panel index
84-
const CeedScalar x[2] = {X[0][i],
85-
X[1][i]
86-
};
8785
const CeedScalar pidx = X[2][i];
88-
if (pidx )
86+
if (pidx != -1)
87+
panel = pidx;
8988
break;
9089
}
9190

91+
// Check that we found nodes panel
92+
if (panel == -1)
93+
return -1;
94+
9295
CeedPragmaSIMD
93-
// Quadrature Point Loop for metric factors
96+
// Quadrature point loop for metric factors
9497
for (CeedInt i=0; i<Q; i++) {
9598
// Read local panel coordinates and relative panel index
96-
const CeedScalar x[2] = {X[0][i],
97-
X[1][i]
98-
};
99+
CeedScalar x[2] = {X[0][i],
100+
X[1][i]
101+
};
99102
const CeedScalar pidx = X[2][i];
100-
// Read dxxdX Jacobian entries, stored in columns
103+
104+
if (pidx != panel) {
105+
const CeedScalar theta = X[0][i];
106+
const CeedScalar lambda = X[1][i];
107+
108+
CeedScalar T_inv[2][2];
109+
110+
switch (panel) {
111+
case 0:
112+
case 1:
113+
case 2:
114+
case 3:
115+
// For P_0 (front), P_1 (east), P_2 (back), P_3 (west):
116+
T_inv[0][0] = 1./(cos(theta)*cos(lambda)) * (1./cos(lambda));
117+
T_inv[0][1] = 1./(cos(theta)*cos(lambda)) * 0.;
118+
T_inv[1][0] = 1./(cos(theta)*cos(lambda)) * tan(theta)*tan(lambda);
119+
T_inv[1][1] = 1./(cos(theta)*cos(lambda)) * (1./cos(theta));
120+
break;
121+
case 4:
122+
// For P4 (north):
123+
T_inv[0][0] = 1./(sin(theta)*sin(theta)) * sin(theta)*cos(lambda);
124+
T_inv[0][1] = 1./(sin(theta)*sin(theta)) * (-sin(lambda));
125+
T_inv[1][0] = 1./(sin(theta)*sin(theta)) * sin(theta)*sin(lambda);
126+
T_inv[1][1] = 1./(sin(theta)*sin(theta)) * cos(lambda);
127+
break;
128+
case 5:
129+
// For P5 (south):
130+
T_inv[0][0] = 1./(sin(theta)*sin(theta)) * (-sin(theta)*cos(lambda));
131+
T_inv[0][1] = 1./(sin(theta)*sin(theta)) * sin(lambda);
132+
T_inv[1][0] = 1./(sin(theta)*sin(theta)) * sin(theta)*sin(lambda);
133+
T_inv[1][1] = 1./(sin(theta)*sin(theta)) * cos(lambda);
134+
break;
135+
}
136+
x[0] = T_inv[0][0]*theta + T_inv[0][1]*lambda;
137+
x[1] = T_inv[1][0]*theta + T_inv[1][1]*lambda;
138+
}
139+
140+
const CeedScalar xxT[2][2] = {{x[0]*x[0],
141+
x[0]*x[1]},
142+
{x[1]*x[0],
143+
x[1]*x[1]}
144+
};
145+
146+
// Read dxdX Jacobian entries, stored in columns
101147
// J_00 J_10
102148
// J_01 J_11
103-
// J_02 J_12
104-
const CeedScalar dxxdX[3][2] = {{J[0][0][i],
105-
J[1][0][i]},
106-
{J[0][1][i],
107-
J[1][1][i]},
108-
{J[0][2][i],
109-
J[1][2][i]}
110-
};
111-
// Setup
112-
// x = xx (xx^T xx)^{-1/2}
113-
// dx/dxx = I (xx^T xx)^{-1/2} - xx xx^T (xx^T xx)^{-3/2}
114-
const CeedScalar modxxsq = x[0]*x[0]+x[1]*x[1];
115-
CeedScalar xxsq[3][3];
116-
for (int j=0; j<3; j++)
117-
for (int k=0; k<3; k++)
118-
xxsq[j][k] = x[j]*x[k] / (sqrt(modxxsq) * modxxsq);
119-
120-
const CeedScalar dxdxx[3][3] = {{1./sqrt(modxxsq) - xxsq[0][0],
121-
-xxsq[0][1],
122-
-xxsq[0][2]},
123-
{-xxsq[1][0],
124-
1./sqrt(modxxsq) - xxsq[1][1],
125-
-xxsq[1][2]},
126-
{-xxsq[2][0],
127-
-xxsq[2][1],
128-
1./sqrt(modxxsq) - xxsq[2][2]}
149+
const CeedScalar dxdX[2][2] = {{J[0][0][i],
150+
J[1][0][i]},
151+
{J[0][1][i],
152+
J[1][1][i]}
129153
};
130154

131-
CeedScalar dxdX[3][2];
132-
for (CeedInt j=0; j<3; j++) {
133-
for (CeedInt k=0; k<2; k++) {
134-
dxdX[j][k] = 0;
135-
for (CeedInt l=0; l<3; l++)
136-
dxdX[j][k] += dxdxx[j][l]*dxxdX[l][k];
155+
CeedScalar dxxdX[2][2];
156+
for (int j=0; j<2; j++)
157+
for (int k=0; k<2; k++) {
158+
dxxdX[j][k] = 0;
159+
for (int l=0; l<2; l++)
160+
dxxdX[j][k] += xxT[j][l]*dxdX[l][k];
137161
}
138-
}
139-
// J is given by the cross product of the columns of dxdX
140-
const CeedScalar J[3] = {dxdX[1][0]*dxdX[2][1] - dxdX[2][0]*dxdX[1][1],
141-
dxdX[2][0]*dxdX[0][1] - dxdX[0][0]*dxdX[2][1],
142-
dxdX[0][0]*dxdX[1][1] - dxdX[1][0]*dxdX[0][1]
143-
};
144-
145-
// Use the magnitude of J as our detJ (volume scaling factor)
146-
const CeedScalar modJ = sqrt(J[0]*J[0]+J[1]*J[1]+J[2]*J[2]);
147162

148163
// Interp-to-Interp qdata
149-
qdata[0][i] = modJ * w[i];
150-
151-
// dxdX_k,j * dxdX_j,k
152-
CeedScalar dxdXTdxdX[2][2];
153-
for (CeedInt j=0; j<2; j++) {
154-
for (CeedInt k=0; k<2; k++) {
155-
dxdXTdxdX[j][k] = 0;
156-
for (CeedInt l=0; l<3; l++)
157-
dxdXTdxdX[j][k] += dxdX[l][j]*dxdX[l][k];
158-
}
159-
}
160-
const CeedScalar detdxdXTdxdX = dxdXTdxdX[0][0] * dxdXTdxdX[1][1]
161-
-dxdXTdxdX[1][0] * dxdXTdxdX[0][1];
162-
163-
// Compute inverse of dxdXTdxdX, needed for the pseudoinverse. This is also
164-
// equivalent to the 2x2 metric tensor g^{ij}, needed for the
165-
// Grad-to-Grad qdata (pseudodXdx * pseudodXdxT, which simplifies to
166-
// dxdXTdxdXinv)
167-
CeedScalar dxdXTdxdXinv[2][2];
168-
dxdXTdxdXinv[0][0] = dxdXTdxdX[1][1] / detdxdXTdxdX;
169-
dxdXTdxdXinv[0][1] = -dxdXTdxdX[0][1] / detdxdXTdxdX;
170-
dxdXTdxdXinv[1][0] = -dxdXTdxdX[1][0] / detdxdXTdxdX;
171-
dxdXTdxdXinv[1][1] = dxdXTdxdX[0][0] / detdxdXTdxdX;
172-
173-
// Compute the pseudo inverse of dxdX
174-
CeedScalar pseudodXdx[2][3];
175-
for (CeedInt j=0; j<2; j++) {
176-
for (CeedInt k=0; k<3; k++) {
177-
pseudodXdx[j][k] = 0;
178-
for (CeedInt l=0; l<2; l++)
179-
pseudodXdx[j][k] += dxdXTdxdXinv[j][l]*dxdX[k][l];
180-
}
181-
}
164+
qdata[0][i] = (dxxdX[0][0]*dxxdX[1][1] - dxxdX[0][1]*dxxdX[1][0]) * w[i];
182165

183-
// Interp-to-Grad qdata
184-
// Pseudo inverse of dxdX: (x_i,j)+ = X_i,j
185-
qdata[1][i] = pseudodXdx[0][0];
186-
qdata[2][i] = pseudodXdx[0][1];
187-
qdata[3][i] = pseudodXdx[0][2];
188-
qdata[4][i] = pseudodXdx[1][0];
189-
qdata[5][i] = pseudodXdx[1][1];
190-
qdata[6][i] = pseudodXdx[1][2];
191-
192-
// Grad-to-Grad qdata stored in Voigt convention
193-
qdata[7][i] = dxdXTdxdXinv[0][0];
194-
qdata[8][i] = dxdXTdxdXinv[1][1];
195-
qdata[9][i] = dxdXTdxdXinv[0][1];
196-
197-
// Terrain topography, hs
198-
qdata[10][i] = sin(x[0]) + cos(x[1]); // put 0 for constant flat topography
199166
} // End of Quadrature Point Loop
200167

201168
// Return

0 commit comments

Comments
 (0)