2626
2727// *****************************************************************************
2828// This QFunction sets up the geometric factors required for integration and
29- // coordinate transformations
29+ // coordinate transformations. See ref: "A Discontinuous Galerkin Transport
30+ // Scheme on the Cubed Sphere", by Nair et al. (2004).
3031//
31- // Reference (parent) 2D coordinates: X \in [-1, 1]^2
32+ // Reference (parent) 2D coordinates: X \in [-1, 1]^2.
3233//
33- // Global 3D physical coordinates given by the mesh: xx \in [-R, R]^3
34- // with R radius of the sphere
34+ // Local 2D physical coordinates on the 2D manifold: x \in [-l, l]^2
35+ // with l half edge of the cube inscribed in the sphere. These coordinate
36+ // systems vary locally on each face (or panel) of the cube.
3537//
36- // Local 3D physical coordinates on the 2D manifold: x \in [-l, l]^3
37- // with l half edge of the cube inscribed in the sphere
38+ // (theta, lambda) represnt latitude and longitude coordinates.
3839//
39- // Change of coordinates matrix computed by the library:
40- // (physical 3D coords relative to reference 2D coords)
41- // dxx_j/dX_i (indicial notation) [3 * 2]
40+ // Change of coordinates from x (on the 2D manifold) to xx (phyisical 3D on
41+ // the sphere), i.e., "cube-to-sphere" A, with equidistant central projection:
4242//
43- // Change of coordinates x (on the 2D manifold) relative to xx (phyisical 3D):
44- // dx_i/dxx_j (indicial notation) [3 * 3]
43+ // For lateral panels (P0-P3):
44+ // A = R cos(theta)cos(lambda) / l * [cos(lambda) 0]
45+ // [-sin(theta)sin(lambda) cos(theta)]
4546//
46- // Change of coordinates x (on the 2D manifold) relative to X (reference 2D ):
47- // (by chain rule)
48- // dx_i/dX_j [3 * 2] = dx_i/dxx_k [3 * 3] * dxx_k/dX_j [3 * 2 ]
47+ // For top panel (P4 ):
48+ // A = R sin(theta) / l * [cos(lambda) sin(lambda)]
49+ // [-sin(theta)sin(lambda) sin(theta)cos(lambda) ]
4950//
50- // modJ is given by the magnitude of the cross product of the columns of dx_i/dX_j
51+ // For bottom panel(P5):
52+ // A = R sin(theta) / l * [-cos(lambda) sin(lambda)]
53+ // [sin(theta)sin(lambda) sin(theta)cos(lambda)]
54+ //
55+ // The inverse of A, A^{-1}, is the "sphere-to-cube" change of coordinates.
56+ //
57+ // The metric tensor g_{ij} = A^TA, and its inverse,
58+ // g^{ij} = g_{ij}^{-1} = A^{-1}A^{-T}
59+ //
60+ // modJ represents the magnitude of the cross product of the columns of A, i.e.,
61+ // J = det(g_{ij})
5162//
5263// The quadrature data is stored in the array qdata.
5364//
5465// We require the determinant of the Jacobian to properly compute integrals of
55- // the form: int( u v )
56- //
57- // Qdata: modJ * w
66+ // the form: int( u v ).
5867//
5968// *****************************************************************************
6069CEED_QFUNCTION (SetupGeo )(void * ctx , CeedInt Q ,
@@ -69,13 +78,25 @@ CEED_QFUNCTION(SetupGeo)(void *ctx, CeedInt Q,
6978 // *INDENT-ON*
7079
7180 CeedPragmaSIMD
72- // Quadrature Point Loop
81+ // Quadrature Point Loop to determine on which panel the element belongs to
7382 for (CeedInt i = 0 ; i < Q ; i ++ ) {
74- // Read global Cartesian coordinates
75- const CeedScalar xx [3 ] = {X [0 ][i ],
76- X [1 ][i ],
77- X [2 ][i ]
78- };
83+ // Read local panel coordinates and relative panel index
84+ const CeedScalar x [2 ] = {X [0 ][i ],
85+ X [1 ][i ]
86+ };
87+ const CeedScalar pidx = X [2 ][i ];
88+ if (pidx )
89+ break ;
90+ }
91+
92+ CeedPragmaSIMD
93+ // Quadrature Point Loop for metric factors
94+ for (CeedInt i = 0 ; i < Q ; i ++ ) {
95+ // Read local panel coordinates and relative panel index
96+ const CeedScalar x [2 ] = {X [0 ][i ],
97+ X [1 ][i ]
98+ };
99+ const CeedScalar pidx = X [2 ][i ];
79100 // Read dxxdX Jacobian entries, stored in columns
80101 // J_00 J_10
81102 // J_01 J_11
@@ -90,11 +111,11 @@ CEED_QFUNCTION(SetupGeo)(void *ctx, CeedInt Q,
90111 // Setup
91112 // x = xx (xx^T xx)^{-1/2}
92113 // dx/dxx = I (xx^T xx)^{-1/2} - xx xx^T (xx^T xx)^{-3/2}
93- const CeedScalar modxxsq = xx [0 ]* xx [0 ]+ xx [1 ]* xx [ 1 ] + xx [ 2 ] * xx [ 2 ];
114+ const CeedScalar modxxsq = x [0 ]* x [0 ]+ x [1 ]* x [ 1 ];
94115 CeedScalar xxsq [3 ][3 ];
95116 for (int j = 0 ; j < 3 ; j ++ )
96117 for (int k = 0 ; k < 3 ; k ++ )
97- xxsq [j ][k ] = xx [j ]* xx [k ] / (sqrt (modxxsq ) * modxxsq );
118+ xxsq [j ][k ] = x [j ]* x [k ] / (sqrt (modxxsq ) * modxxsq );
98119
99120 const CeedScalar dxdxx [3 ][3 ] = {{1. /sqrt (modxxsq ) - xxsq [0 ][0 ],
100121 - xxsq [0 ][1 ],
@@ -174,7 +195,7 @@ CEED_QFUNCTION(SetupGeo)(void *ctx, CeedInt Q,
174195 qdata [9 ][i ] = dxdXTdxdXinv [0 ][1 ];
175196
176197 // Terrain topography, hs
177- qdata [10 ][i ] = sin (xx [0 ]) + cos (xx [1 ]); // put 0 for constant flat topography
198+ qdata [10 ][i ] = sin (x [0 ]) + cos (x [1 ]); // put 0 for constant flat topography
178199 } // End of Quadrature Point Loop
179200
180201 // Return
0 commit comments