@@ -117,15 +117,18 @@ int main(int argc, const char *argv[]) {
117117
118118 // Select appropriate backend and logical device based on the (-ceed) command line argument.
119119 Ceed ceed ;
120+
120121 CeedInit (ceed_spec , & ceed );
121122
122123 // Construct the mesh and solution bases.
123124 CeedBasis mesh_basis , sol_basis ;
125+
124126 CeedBasisCreateTensorH1Lagrange (ceed , dim , num_comp_x , mesh_degree + 1 , num_qpts , CEED_GAUSS , & mesh_basis );
125127 CeedBasisCreateTensorH1Lagrange (ceed , dim , 1 , sol_degree + 1 , num_qpts , CEED_GAUSS , & sol_basis );
126128
127129 // Determine the mesh size based on the given approximate problem size.
128130 CeedInt num_xyz [dim ];
131+
129132 GetCartesianMeshSize (dim , sol_degree , prob_size , num_xyz );
130133 if (!test ) {
131134 // LCOV_EXCL_START
@@ -139,6 +142,7 @@ int main(int argc, const char *argv[]) {
139142 // Build CeedElemRestriction objects describing the mesh and solution discrete representations.
140143 CeedInt mesh_size , sol_size ;
141144 CeedElemRestriction mesh_restriction , sol_restriction , q_data_restriction ;
145+
142146 BuildCartesianRestriction (ceed , dim , num_xyz , mesh_degree , num_comp_x , & mesh_size , num_qpts , & mesh_restriction , NULL );
143147 BuildCartesianRestriction (ceed , dim , num_xyz , sol_degree , 1 , & sol_size , num_qpts , & sol_restriction , & q_data_restriction );
144148 if (!test ) {
@@ -150,6 +154,7 @@ int main(int argc, const char *argv[]) {
150154
151155 // Create a CeedVector with the mesh coordinates.
152156 CeedVector mesh_coords ;
157+
153158 CeedVectorCreate (ceed , mesh_size , & mesh_coords );
154159 SetCartesianMeshCoords (dim , num_xyz , mesh_degree , mesh_coords );
155160
@@ -159,12 +164,14 @@ int main(int argc, const char *argv[]) {
159164 // Context data to be passed to the 'build_mass' QFunction.
160165 CeedQFunctionContext build_ctx ;
161166 struct BuildContext build_ctx_data ;
167+
162168 build_ctx_data .dim = build_ctx_data .space_dim = dim ;
163169 CeedQFunctionContextCreate (ceed , & build_ctx );
164170 CeedQFunctionContextSetData (build_ctx , CEED_MEM_HOST , CEED_USE_POINTER , sizeof (build_ctx_data ), & build_ctx_data );
165171
166172 // Create the QFunction that builds the mass operator (i.e. computes its quadrature data) and set its context data.
167173 CeedQFunction qf_build ;
174+
168175 if (gallery ) {
169176 // This creates the QFunction via the gallery.
170177 char name [13 ] = "" ;
@@ -181,6 +188,7 @@ int main(int argc, const char *argv[]) {
181188
182189 // Create the operator that builds the quadrature data for the mass operator.
183190 CeedOperator op_build ;
191+
184192 CeedOperatorCreate (ceed , qf_build , CEED_QFUNCTION_NONE , CEED_QFUNCTION_NONE , & op_build );
185193 CeedOperatorSetField (op_build , "dx" , mesh_restriction , mesh_basis , CEED_VECTOR_ACTIVE );
186194 CeedOperatorSetField (op_build , "weights" , CEED_ELEMRESTRICTION_NONE , mesh_basis , CEED_VECTOR_NONE );
@@ -190,12 +198,14 @@ int main(int argc, const char *argv[]) {
190198 CeedVector q_data ;
191199 CeedInt elem_qpts = CeedIntPow (num_qpts , dim );
192200 CeedInt num_elem = 1 ;
201+
193202 for (CeedInt d = 0 ; d < dim ; d ++ ) num_elem *= num_xyz [d ];
194203 CeedVectorCreate (ceed , num_elem * elem_qpts , & q_data );
195204 CeedOperatorApply (op_build , mesh_coords , q_data , CEED_REQUEST_IMMEDIATE );
196205
197206 // Create the QFunction that defines the action of the mass operator.
198207 CeedQFunction qf_apply ;
208+
199209 if (gallery ) {
200210 // This creates the QFunction via the gallery.
201211 CeedQFunctionCreateInteriorByName (ceed , "MassApply" , & qf_apply );
@@ -209,13 +219,15 @@ int main(int argc, const char *argv[]) {
209219
210220 // Create the mass operator.
211221 CeedOperator op_apply ;
222+
212223 CeedOperatorCreate (ceed , qf_apply , CEED_QFUNCTION_NONE , CEED_QFUNCTION_NONE , & op_apply );
213224 CeedOperatorSetField (op_apply , "u" , sol_restriction , sol_basis , CEED_VECTOR_ACTIVE );
214225 CeedOperatorSetField (op_apply , "qdata" , q_data_restriction , CEED_BASIS_NONE , q_data );
215226 CeedOperatorSetField (op_apply , "v" , sol_restriction , sol_basis , CEED_VECTOR_ACTIVE );
216227
217228 // Create auxiliary solution-size vectors.
218229 CeedVector u , v ;
230+
219231 CeedVectorCreate (ceed , sol_size , & u );
220232 CeedVectorCreate (ceed , sol_size , & v );
221233
@@ -239,8 +251,10 @@ int main(int argc, const char *argv[]) {
239251
240252 // Compute and print the sum of the entries of 'v' giving the mesh volume.
241253 CeedScalar volume = 0. ;
254+
242255 {
243256 const CeedScalar * v_array ;
257+
244258 CeedVectorGetArrayRead (v , CEED_MEM_HOST , & v_array );
245259 for (CeedInt i = 0 ; i < sol_size ; i ++ ) volume += v_array [i ];
246260 CeedVectorRestoreArrayRead (v , & v_array );
@@ -254,6 +268,7 @@ int main(int argc, const char *argv[]) {
254268 // LCOV_EXCL_STOP
255269 } else {
256270 CeedScalar tol = (dim == 1 ? 200. * CEED_EPSILON : dim == 2 ? 1E-5 : 1E-5 );
271+
257272 if (fabs (volume - exact_volume ) > tol ) printf ("Volume error : % .1e\n" , volume - exact_volume );
258273 }
259274
@@ -281,13 +296,16 @@ int GetCartesianMeshSize(CeedInt dim, CeedInt degree, CeedInt prob_size, CeedInt
281296 // prob_size ~ num_elem * degree^dim
282297 CeedInt num_elem = prob_size / CeedIntPow (degree , dim );
283298 CeedInt s = 0 ; // find s: num_elem/2 < 2^s <= num_elem
299+
284300 while (num_elem > 1 ) {
285301 num_elem /= 2 ;
286302 s ++ ;
287303 }
288304 CeedInt r = s % dim ;
305+
289306 for (CeedInt d = 0 ; d < dim ; d ++ ) {
290307 CeedInt sd = s / dim ;
308+
291309 if (r > 0 ) {
292310 sd ++ ;
293311 r -- ;
@@ -303,6 +321,7 @@ int BuildCartesianRestriction(Ceed ceed, CeedInt dim, CeedInt num_xyz[dim], Ceed
303321 CeedInt num_nodes = CeedIntPow (p , dim ); // number of scalar nodes per element
304322 CeedInt elem_qpts = CeedIntPow (num_qpts , dim ); // number of qpts per element
305323 CeedInt nd [3 ], num_elem = 1 , scalar_size = 1 ;
324+
306325 for (CeedInt d = 0 ; d < dim ; d ++ ) {
307326 num_elem *= num_xyz [d ];
308327 nd [d ] = num_xyz [d ] * (p - 1 ) + 1 ;
@@ -313,15 +332,19 @@ int BuildCartesianRestriction(Ceed ceed, CeedInt dim, CeedInt num_xyz[dim], Ceed
313332 // |---*-...-*---|---*-...-*---|- ... -|--...--|
314333 // num_nodes: 0 1 p-1 p p+1 2*p n*p
315334 CeedInt * elem_nodes = malloc (sizeof (CeedInt ) * num_elem * num_nodes );
335+
316336 for (CeedInt e = 0 ; e < num_elem ; e ++ ) {
317337 CeedInt e_xyz [3 ] = {1 , 1 , 1 }, re = e ;
338+
318339 for (CeedInt d = 0 ; d < dim ; d ++ ) {
319340 e_xyz [d ] = re % num_xyz [d ];
320341 re /= num_xyz [d ];
321342 }
322343 CeedInt * local_elem_nodes = elem_nodes + e * num_nodes ;
344+
323345 for (CeedInt l_nodes = 0 ; l_nodes < num_nodes ; l_nodes ++ ) {
324346 CeedInt g_nodes = 0 , g_nodes_stride = 1 , r_nodes = l_nodes ;
347+
325348 for (CeedInt d = 0 ; d < dim ; d ++ ) {
326349 g_nodes += (e_xyz [d ] * (p - 1 ) + r_nodes % p ) * g_nodes_stride ;
327350 g_nodes_stride *= nd [d ];
@@ -342,20 +365,25 @@ int BuildCartesianRestriction(Ceed ceed, CeedInt dim, CeedInt num_xyz[dim], Ceed
342365int SetCartesianMeshCoords (CeedInt dim , CeedInt num_xyz [dim ], CeedInt mesh_degree , CeedVector mesh_coords ) {
343366 CeedInt p = mesh_degree + 1 ;
344367 CeedInt nd [3 ], scalar_size = 1 ;
368+
345369 for (CeedInt d = 0 ; d < dim ; d ++ ) {
346370 nd [d ] = num_xyz [d ] * (p - 1 ) + 1 ;
347371 scalar_size *= nd [d ];
348372 }
349373 CeedScalar * coords ;
374+
350375 CeedVectorGetArrayWrite (mesh_coords , CEED_MEM_HOST , & coords );
351376 CeedScalar * nodes = malloc (sizeof (CeedScalar ) * p );
377+
352378 // The H1 basis uses Lobatto quadrature points as nodes.
353379 CeedLobattoQuadrature (p , nodes , NULL ); // nodes are in [-1,1]
354380 for (CeedInt i = 0 ; i < p ; i ++ ) nodes [i ] = 0.5 + 0.5 * nodes [i ];
355381 for (CeedInt gs_nodes = 0 ; gs_nodes < scalar_size ; gs_nodes ++ ) {
356382 CeedInt r_nodes = gs_nodes ;
383+
357384 for (CeedInt d = 0 ; d < dim ; d ++ ) {
358- CeedInt d_1d = r_nodes % nd [d ];
385+ CeedInt d_1d = r_nodes % nd [d ];
386+
359387 coords [gs_nodes + scalar_size * d ] = ((d_1d / (p - 1 )) + nodes [d_1d % (p - 1 )]) / num_xyz [d ];
360388 r_nodes /= nd [d ];
361389 }
@@ -373,6 +401,7 @@ int SetCartesianMeshCoords(CeedInt dim, CeedInt num_xyz[dim], CeedInt mesh_degre
373401CeedScalar TransformMeshCoords (CeedInt dim , CeedInt mesh_size , CeedVector mesh_coords ) {
374402 CeedScalar exact_volume ;
375403 CeedScalar * coords ;
404+
376405 CeedVectorGetArray (mesh_coords , CEED_MEM_HOST , & coords );
377406 if (dim == 1 ) {
378407 for (CeedInt i = 0 ; i < mesh_size ; i ++ ) {
@@ -382,10 +411,12 @@ CeedScalar TransformMeshCoords(CeedInt dim, CeedInt mesh_size, CeedVector mesh_c
382411 exact_volume = 1. ;
383412 } else {
384413 CeedInt num_nodes = mesh_size / dim ;
414+
385415 for (CeedInt i = 0 ; i < num_nodes ; i ++ ) {
386416 // map (x,y) from [0,1]x[0,1] to the quarter annulus with polar
387417 // coordinates, (r,phi) in [1,2]x[0,pi/2] with area = 3/4*pi
388418 CeedScalar u = coords [i ], v = coords [i + num_nodes ];
419+
389420 u = 1. + u ;
390421 v = M_PI_2 * v ;
391422 coords [i ] = u * cos (v );
0 commit comments