@@ -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