1*57c64913Sjeremylt // Test grad in multiple dimensions 2*57c64913Sjeremylt #include <ceed.h> 3*57c64913Sjeremylt #include <math.h> 4*57c64913Sjeremylt 5*57c64913Sjeremylt static CeedScalar Eval(CeedInt dim, const CeedScalar x[]) { 6*57c64913Sjeremylt CeedScalar result = tanh(x[0] + 0.1); 7*57c64913Sjeremylt if (dim > 1) result += atan(x[1] + 0.2); 8*57c64913Sjeremylt if (dim > 2) result += exp(-(x[2] + 0.3)*(x[2] + 0.3)); 9*57c64913Sjeremylt return result; 10*57c64913Sjeremylt } 11*57c64913Sjeremylt 12*57c64913Sjeremylt int main(int argc, char **argv) { 13*57c64913Sjeremylt Ceed ceed; 14*57c64913Sjeremylt 15*57c64913Sjeremylt CeedInit(argv[1], &ceed); 16*57c64913Sjeremylt for (CeedInt dim=1; dim<=3; dim++) { 17*57c64913Sjeremylt CeedBasis bxl, bug; 18*57c64913Sjeremylt CeedInt P = 8, Q = 10, Pdim = CeedPowInt(P, dim), Qdim = CeedPowInt(Q, dim), 19*57c64913Sjeremylt Xdim = CeedPowInt(2, dim); 20*57c64913Sjeremylt CeedScalar x[Xdim*dim], ones[dim*Qdim], gtposeones[Pdim]; 21*57c64913Sjeremylt CeedScalar xq[Pdim*dim], uq[dim*Qdim], u[Pdim], sum1 = 0, sum2 = 0; 22*57c64913Sjeremylt 23*57c64913Sjeremylt for (CeedInt i=0; i<dim*Qdim; i++) ones[i] = 1; 24*57c64913Sjeremylt for (CeedInt d=0; d<dim; d++) { 25*57c64913Sjeremylt for (CeedInt i=0; i<Xdim; i++) { 26*57c64913Sjeremylt x[d*Xdim + i] = (i % CeedPowInt(2, dim-d)) / CeedPowInt(2, dim-d-1) ? 1 : -1; 27*57c64913Sjeremylt } 28*57c64913Sjeremylt } 29*57c64913Sjeremylt 30*57c64913Sjeremylt // Get function values at quadrature points 31*57c64913Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, dim, dim, 2, P, CEED_GAUSS_LOBATTO, &bxl); 32*57c64913Sjeremylt CeedBasisApply(bxl, 1, CEED_NOTRANSPOSE, CEED_EVAL_INTERP, x, xq); 33*57c64913Sjeremylt for (CeedInt i=0; i<Pdim; i++) { 34*57c64913Sjeremylt CeedScalar xx[dim]; 35*57c64913Sjeremylt for (CeedInt d=0; d<dim; d++) xx[d] = xq[d*Pdim + i]; 36*57c64913Sjeremylt u[i] = Eval(dim, xx); 37*57c64913Sjeremylt } 38*57c64913Sjeremylt 39*57c64913Sjeremylt // Calculate G u at quadrature points, G' * 1 at dofs 40*57c64913Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, P, Q, CEED_GAUSS, &bug); 41*57c64913Sjeremylt CeedBasisApply(bug, 1, CEED_NOTRANSPOSE, CEED_EVAL_GRAD, u, uq); 42*57c64913Sjeremylt CeedBasisApply(bug, 1, CEED_TRANSPOSE, CEED_EVAL_GRAD, ones, gtposeones); 43*57c64913Sjeremylt 44*57c64913Sjeremylt // Check if 1' * G * u = u' * (G' * 1) 45*57c64913Sjeremylt for (CeedInt i=0; i<Pdim; i++) { 46*57c64913Sjeremylt sum1 += gtposeones[i]*u[i]; 47*57c64913Sjeremylt } 48*57c64913Sjeremylt for (CeedInt i=0; i<dim*Qdim; i++) { 49*57c64913Sjeremylt sum2 += uq[i]; 50*57c64913Sjeremylt } 51*57c64913Sjeremylt if (fabs(sum1 - sum2) > 1e-10) { 52*57c64913Sjeremylt printf("[%d] %f != %f\n", dim, sum1, sum2); 53*57c64913Sjeremylt } 54*57c64913Sjeremylt 55*57c64913Sjeremylt CeedBasisDestroy(&bxl); 56*57c64913Sjeremylt CeedBasisDestroy(&bug); 57*57c64913Sjeremylt } 58*57c64913Sjeremylt CeedDestroy(&ceed); 59*57c64913Sjeremylt return 0; 60*57c64913Sjeremylt } 61