1*ed264d09SValeria Barra // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2*ed264d09SValeria Barra // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3*ed264d09SValeria Barra // reserved. See files LICENSE and NOTICE for details. 4*ed264d09SValeria Barra // 5*ed264d09SValeria Barra // This file is part of CEED, a collection of benchmarks, miniapps, software 6*ed264d09SValeria Barra // libraries and APIs for efficient high-order finite element and spectral 7*ed264d09SValeria Barra // element discretizations for exascale applications. For more information and 8*ed264d09SValeria Barra // source code availability see http://github.com/ceed. 9*ed264d09SValeria Barra // 10*ed264d09SValeria Barra // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*ed264d09SValeria Barra // a collaborative effort of two U.S. Department of Energy organizations (Office 12*ed264d09SValeria Barra // of Science and the National Nuclear Security Administration) responsible for 13*ed264d09SValeria Barra // the planning and preparation of a capable exascale ecosystem, including 14*ed264d09SValeria Barra // software, applications, hardware, advanced system engineering and early 15*ed264d09SValeria Barra // testbed platforms, in support of the nation's exascale computing imperative. 16*ed264d09SValeria Barra 17*ed264d09SValeria Barra /// @file 18*ed264d09SValeria Barra /// libCEED QFunctions for mass operator example for a vector field on the sphere using PETSc 19*ed264d09SValeria Barra 20*ed264d09SValeria Barra #ifndef __CUDACC__ 21*ed264d09SValeria Barra # include <math.h> 22*ed264d09SValeria Barra #endif 23*ed264d09SValeria Barra 24*ed264d09SValeria Barra // ***************************************************************************** 25*ed264d09SValeria Barra // This QFunction sets up the rhs and true solution for the problem 26*ed264d09SValeria Barra // ***************************************************************************** 27*ed264d09SValeria Barra 28*ed264d09SValeria Barra // ----------------------------------------------------------------------------- 29*ed264d09SValeria Barra CEED_QFUNCTION(SetupDiffRhs3)(void *ctx, const CeedInt Q, 30*ed264d09SValeria Barra const CeedScalar *const *in, 31*ed264d09SValeria Barra CeedScalar *const *out) { 32*ed264d09SValeria Barra // Inputs 33*ed264d09SValeria Barra const CeedScalar *X = in[0], *qdata = in[1]; 34*ed264d09SValeria Barra // Outputs 35*ed264d09SValeria Barra CeedScalar *true_soln = out[0], *rhs = out[1]; 36*ed264d09SValeria Barra 37*ed264d09SValeria Barra // Context 38*ed264d09SValeria Barra const CeedScalar *context = (const CeedScalar*)ctx; 39*ed264d09SValeria Barra const CeedScalar R = context[0]; 40*ed264d09SValeria Barra 41*ed264d09SValeria Barra // Quadrature Point Loop 42*ed264d09SValeria Barra CeedPragmaSIMD 43*ed264d09SValeria Barra for (CeedInt i=0; i<Q; i++) { 44*ed264d09SValeria Barra // Read global Cartesian coordinates 45*ed264d09SValeria Barra CeedScalar x = X[i+Q*0], y = X[i+Q*1], z = X[i+Q*2]; 46*ed264d09SValeria Barra // Normalize quadrature point coordinates to sphere 47*ed264d09SValeria Barra CeedScalar rad = sqrt(x*x + y*y + z*z); 48*ed264d09SValeria Barra x *= R / rad; 49*ed264d09SValeria Barra y *= R / rad; 50*ed264d09SValeria Barra z *= R / rad; 51*ed264d09SValeria Barra // Compute latitude and longitude 52*ed264d09SValeria Barra const CeedScalar theta = asin(z / R); // latitude 53*ed264d09SValeria Barra const CeedScalar lambda = atan2(y, x); // longitude 54*ed264d09SValeria Barra 55*ed264d09SValeria Barra // Use absolute value of latitute for true solution 56*ed264d09SValeria Barra // Component 1 57*ed264d09SValeria Barra true_soln[i+0*Q] = sin(lambda) * cos(theta); 58*ed264d09SValeria Barra // Component 2 59*ed264d09SValeria Barra true_soln[i+1*Q] = 2 * true_soln[i+0*Q]; 60*ed264d09SValeria Barra // Component 3 61*ed264d09SValeria Barra true_soln[i+2*Q] = 3 * true_soln[i+0*Q]; 62*ed264d09SValeria Barra 63*ed264d09SValeria Barra // Component 1 64*ed264d09SValeria Barra rhs[i+0*Q] = qdata[i+Q*0] * 2 * sin(lambda)*cos(theta) / (R*R); 65*ed264d09SValeria Barra // Component 2 66*ed264d09SValeria Barra rhs[i+1*Q] = 2 * rhs[i+0*Q]; 67*ed264d09SValeria Barra // Component 3 68*ed264d09SValeria Barra rhs[i+2*Q] = 3 * rhs[i+0*Q]; 69*ed264d09SValeria Barra } // End of Quadrature Point Loop 70*ed264d09SValeria Barra 71*ed264d09SValeria Barra return 0; 72*ed264d09SValeria Barra } 73*ed264d09SValeria Barra 74*ed264d09SValeria Barra // ***************************************************************************** 75*ed264d09SValeria Barra // This QFunction applies the diffusion operator for a vector field of 3 components. 76*ed264d09SValeria Barra // 77*ed264d09SValeria Barra // Inputs: 78*ed264d09SValeria Barra // ug - Input vector Jacobian at quadrature points 79*ed264d09SValeria Barra // qdata - Geometric factors 80*ed264d09SValeria Barra // 81*ed264d09SValeria Barra // Output: 82*ed264d09SValeria Barra // vJ - Output vector (test functions) Jacobian at quadrature points 83*ed264d09SValeria Barra // 84*ed264d09SValeria Barra // ***************************************************************************** 85*ed264d09SValeria Barra 86*ed264d09SValeria Barra // ----------------------------------------------------------------------------- 87*ed264d09SValeria Barra CEED_QFUNCTION(Diff3)(void *ctx, const CeedInt Q, 88*ed264d09SValeria Barra const CeedScalar *const *in, CeedScalar *const *out) { 89*ed264d09SValeria Barra const CeedScalar *ug = in[0], *qdata = in[1]; 90*ed264d09SValeria Barra CeedScalar *vJ = out[0]; 91*ed264d09SValeria Barra 92*ed264d09SValeria Barra // Quadrature Point Loop 93*ed264d09SValeria Barra CeedPragmaSIMD 94*ed264d09SValeria Barra for (CeedInt i=0; i<Q; i++) { 95*ed264d09SValeria Barra // Read spatial derivatives of u 96*ed264d09SValeria Barra const CeedScalar uJ[3][2] = {{ug[i+(0+0*3)*Q], 97*ed264d09SValeria Barra ug[i+(0+1*3)*Q]}, 98*ed264d09SValeria Barra {ug[i+(1+0*3)*Q], 99*ed264d09SValeria Barra ug[i+(1+1*3)*Q]}, 100*ed264d09SValeria Barra {ug[i+(2+0*3)*Q], 101*ed264d09SValeria Barra ug[i+(2+1*3)*Q]} 102*ed264d09SValeria Barra }; 103*ed264d09SValeria Barra // Read qdata 104*ed264d09SValeria Barra const CeedScalar wJ = qdata[i+Q*0]; 105*ed264d09SValeria Barra // -- Grad-to-Grad qdata 106*ed264d09SValeria Barra // ---- dXdx_j,k * dXdx_k,j 107*ed264d09SValeria Barra const CeedScalar dXdxdXdxT[2][2] = {{qdata[i+Q*1], 108*ed264d09SValeria Barra qdata[i+Q*3]}, 109*ed264d09SValeria Barra {qdata[i+Q*3], 110*ed264d09SValeria Barra qdata[i+Q*2]} 111*ed264d09SValeria Barra }; 112*ed264d09SValeria Barra 113*ed264d09SValeria Barra for (int k=0; k<3; k++) // k = component 114*ed264d09SValeria Barra for (int j=0; j<2; j++) // j = direction of vg 115*ed264d09SValeria Barra vJ[i+(k+j*3)*Q] = wJ * (uJ[k][0] * dXdxdXdxT[0][j] + 116*ed264d09SValeria Barra uJ[k][1] * dXdxdXdxT[1][j]); 117*ed264d09SValeria Barra 118*ed264d09SValeria Barra } // End of Quadrature Point Loop 119*ed264d09SValeria Barra 120*ed264d09SValeria Barra return 0; 121*ed264d09SValeria Barra } 122*ed264d09SValeria Barra // ----------------------------------------------------------------------------- 123