1*a8de75f0Sjeremylt /// @file 2*a8de75f0Sjeremylt /// Test creation creation, action, and destruction for mass matrix operator 3*a8de75f0Sjeremylt /// \test Test creation creation, action, and destruction for mass matrix operator 4*a8de75f0Sjeremylt #include <ceed.h> 5*a8de75f0Sjeremylt #include <stdlib.h> 6*a8de75f0Sjeremylt #include <math.h> 7*a8de75f0Sjeremylt #include "t310-basis.h" 8*a8de75f0Sjeremylt 9*a8de75f0Sjeremylt static int setup(void *ctx, CeedInt Q, const CeedScalar *const *in, 10*a8de75f0Sjeremylt CeedScalar *const *out); 11*a8de75f0Sjeremylt static int mass(void *ctx, CeedInt Q, const CeedScalar *const *in, 12*a8de75f0Sjeremylt CeedScalar *const *out); 13*a8de75f0Sjeremylt 14*a8de75f0Sjeremylt static int setup(void *ctx, CeedInt Q, const CeedScalar *const *in, 15*a8de75f0Sjeremylt CeedScalar *const *out) { 16*a8de75f0Sjeremylt const CeedScalar *weight = in[0], *J = in[1]; 17*a8de75f0Sjeremylt CeedScalar *rho = out[0]; 18*a8de75f0Sjeremylt for (CeedInt i=0; i<Q; i++) { 19*a8de75f0Sjeremylt rho[i] = weight[i] * (J[i+Q*0]*J[i+Q*3] - J[i+Q*1]*J[i+Q*2]); 20*a8de75f0Sjeremylt } 21*a8de75f0Sjeremylt return 0; 22*a8de75f0Sjeremylt } 23*a8de75f0Sjeremylt 24*a8de75f0Sjeremylt static int mass(void *ctx, CeedInt Q, const CeedScalar *const *in, 25*a8de75f0Sjeremylt CeedScalar *const *out) { 26*a8de75f0Sjeremylt const CeedScalar *rho = in[0], *u = in[1]; 27*a8de75f0Sjeremylt CeedScalar *v = out[0]; 28*a8de75f0Sjeremylt for (CeedInt i=0; i<Q; i++) { 29*a8de75f0Sjeremylt v[i] = rho[i] * u[i]; 30*a8de75f0Sjeremylt } 31*a8de75f0Sjeremylt return 0; 32*a8de75f0Sjeremylt } 33*a8de75f0Sjeremylt 34*a8de75f0Sjeremylt int main(int argc, char **argv) { 35*a8de75f0Sjeremylt Ceed ceed; 36*a8de75f0Sjeremylt CeedElemRestriction Erestrictx, Erestrictu, Erestrictxi, Erestrictui; 37*a8de75f0Sjeremylt CeedBasis bx, bu; 38*a8de75f0Sjeremylt CeedQFunction qf_setup, qf_mass; 39*a8de75f0Sjeremylt CeedOperator op_setup, op_mass; 40*a8de75f0Sjeremylt CeedVector qdata, X, U, V; 41*a8de75f0Sjeremylt const CeedScalar *hv; 42*a8de75f0Sjeremylt CeedInt nelem = 12, dim = 2, P = 6, Q = 4; 43*a8de75f0Sjeremylt CeedInt nx = 3, ny = 2; 44*a8de75f0Sjeremylt CeedInt row, col, offset; 45*a8de75f0Sjeremylt CeedInt Ndofs = (nx*2+1)*(ny*2+1), Nqpts = nelem*Q; 46*a8de75f0Sjeremylt CeedInt indx[nelem*P]; 47*a8de75f0Sjeremylt CeedScalar x[dim*Ndofs]; 48*a8de75f0Sjeremylt CeedScalar qref[dim*Q], qweight[Q]; 49*a8de75f0Sjeremylt CeedScalar interp[P*Q], grad[dim*P*Q]; 50*a8de75f0Sjeremylt CeedScalar sum; 51*a8de75f0Sjeremylt 52*a8de75f0Sjeremylt CeedInit(argv[1], &ceed); 53*a8de75f0Sjeremylt 54*a8de75f0Sjeremylt for (CeedInt i=0; i<Ndofs; i++) { 55*a8de75f0Sjeremylt x[i] = (1. / (nx*2)) * (CeedScalar) (i % (nx*2+1)); 56*a8de75f0Sjeremylt x[i+Ndofs] = (1. / (ny*2)) * (CeedScalar) (i / (nx*2+1)); 57*a8de75f0Sjeremylt } 58*a8de75f0Sjeremylt for (CeedInt i=0; i<nelem/2; i++) { 59*a8de75f0Sjeremylt col = i % nx; 60*a8de75f0Sjeremylt row = i / nx; 61*a8de75f0Sjeremylt offset = col*2 + row*(nx*2+1)*2; 62*a8de75f0Sjeremylt 63*a8de75f0Sjeremylt indx[i*2*P + 0] = 2 + offset; 64*a8de75f0Sjeremylt indx[i*2*P + 1] = 9 + offset; 65*a8de75f0Sjeremylt indx[i*2*P + 2] = 16 + offset; 66*a8de75f0Sjeremylt indx[i*2*P + 3] = 1 + offset; 67*a8de75f0Sjeremylt indx[i*2*P + 4] = 8 + offset; 68*a8de75f0Sjeremylt indx[i*2*P + 5] = 0 + offset; 69*a8de75f0Sjeremylt 70*a8de75f0Sjeremylt indx[i*2*P + 6] = 14 + offset; 71*a8de75f0Sjeremylt indx[i*2*P + 7] = 7 + offset; 72*a8de75f0Sjeremylt indx[i*2*P + 8] = 0 + offset; 73*a8de75f0Sjeremylt indx[i*2*P + 9] = 15 + offset; 74*a8de75f0Sjeremylt indx[i*2*P + 10] = 8 + offset; 75*a8de75f0Sjeremylt indx[i*2*P + 11] = 16 + offset; 76*a8de75f0Sjeremylt } 77*a8de75f0Sjeremylt 78*a8de75f0Sjeremylt // Restrictions 79*a8de75f0Sjeremylt CeedElemRestrictionCreate(ceed, nelem, P, Ndofs, dim, CEED_MEM_HOST, 80*a8de75f0Sjeremylt CEED_USE_POINTER, indx, &Erestrictx); 81*a8de75f0Sjeremylt CeedElemRestrictionCreateIdentity(ceed, nelem, P, nelem*P, dim, &Erestrictxi); 82*a8de75f0Sjeremylt 83*a8de75f0Sjeremylt CeedElemRestrictionCreate(ceed, nelem, P, Ndofs, 1, CEED_MEM_HOST, 84*a8de75f0Sjeremylt CEED_USE_POINTER, indx, &Erestrictu); 85*a8de75f0Sjeremylt CeedElemRestrictionCreateIdentity(ceed, nelem, Q, Nqpts, 1, &Erestrictui); 86*a8de75f0Sjeremylt 87*a8de75f0Sjeremylt 88*a8de75f0Sjeremylt // Bases 89*a8de75f0Sjeremylt buildmats(qref, qweight, interp, grad); 90*a8de75f0Sjeremylt CeedBasisCreateH1(ceed, CEED_TRIANGLE, dim, P, Q, interp, grad, qref, 91*a8de75f0Sjeremylt qweight, &bx); 92*a8de75f0Sjeremylt 93*a8de75f0Sjeremylt buildmats(qref, qweight, interp, grad); 94*a8de75f0Sjeremylt CeedBasisCreateH1(ceed, CEED_TRIANGLE, 1, P, Q, interp, grad, qref, 95*a8de75f0Sjeremylt qweight, &bu); 96*a8de75f0Sjeremylt 97*a8de75f0Sjeremylt // QFunctions 98*a8de75f0Sjeremylt CeedQFunctionCreateInterior(ceed, 1, setup, __FILE__ ":setup", &qf_setup); 99*a8de75f0Sjeremylt CeedQFunctionAddInput(qf_setup, "_weight", 1, CEED_EVAL_WEIGHT); 100*a8de75f0Sjeremylt CeedQFunctionAddInput(qf_setup, "x", dim, CEED_EVAL_GRAD); 101*a8de75f0Sjeremylt CeedQFunctionAddOutput(qf_setup, "rho", 1, CEED_EVAL_NONE); 102*a8de75f0Sjeremylt 103*a8de75f0Sjeremylt CeedQFunctionCreateInterior(ceed, 1, mass, __FILE__ ":mass", &qf_mass); 104*a8de75f0Sjeremylt CeedQFunctionAddInput(qf_mass, "rho", 1, CEED_EVAL_NONE); 105*a8de75f0Sjeremylt CeedQFunctionAddInput(qf_mass, "u", 1, CEED_EVAL_INTERP); 106*a8de75f0Sjeremylt CeedQFunctionAddOutput(qf_mass, "v", 1, CEED_EVAL_INTERP); 107*a8de75f0Sjeremylt 108*a8de75f0Sjeremylt // Operators 109*a8de75f0Sjeremylt CeedOperatorCreate(ceed, qf_setup, NULL, NULL, &op_setup); 110*a8de75f0Sjeremylt 111*a8de75f0Sjeremylt CeedOperatorCreate(ceed, qf_mass, NULL, NULL, &op_mass); 112*a8de75f0Sjeremylt 113*a8de75f0Sjeremylt CeedVectorCreate(ceed, dim*Ndofs, &X); 114*a8de75f0Sjeremylt CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x); 115*a8de75f0Sjeremylt CeedVectorCreate(ceed, Nqpts, &qdata); 116*a8de75f0Sjeremylt 117*a8de75f0Sjeremylt CeedOperatorSetField(op_setup, "_weight", Erestrictxi, bx, 118*a8de75f0Sjeremylt CEED_VECTOR_NONE); 119*a8de75f0Sjeremylt CeedOperatorSetField(op_setup, "x", Erestrictx, bx, CEED_VECTOR_ACTIVE); 120*a8de75f0Sjeremylt CeedOperatorSetField(op_setup, "rho", Erestrictui, 121*a8de75f0Sjeremylt CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 122*a8de75f0Sjeremylt 123*a8de75f0Sjeremylt CeedOperatorSetField(op_mass, "rho", Erestrictui, 124*a8de75f0Sjeremylt CEED_BASIS_COLLOCATED, qdata); 125*a8de75f0Sjeremylt CeedOperatorSetField(op_mass, "u", Erestrictu, bu, CEED_VECTOR_ACTIVE); 126*a8de75f0Sjeremylt CeedOperatorSetField(op_mass, "v", Erestrictu, bu, CEED_VECTOR_ACTIVE); 127*a8de75f0Sjeremylt 128*a8de75f0Sjeremylt CeedOperatorApply(op_setup, X, qdata, CEED_REQUEST_IMMEDIATE); 129*a8de75f0Sjeremylt 130*a8de75f0Sjeremylt CeedVectorCreate(ceed, Ndofs, &U); 131*a8de75f0Sjeremylt CeedVectorSetValue(U, 1.0); 132*a8de75f0Sjeremylt CeedVectorCreate(ceed, Ndofs, &V); 133*a8de75f0Sjeremylt 134*a8de75f0Sjeremylt CeedOperatorApply(op_mass, U, V, CEED_REQUEST_IMMEDIATE); 135*a8de75f0Sjeremylt 136*a8de75f0Sjeremylt // Check output 137*a8de75f0Sjeremylt CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv); 138*a8de75f0Sjeremylt sum = 0.; 139*a8de75f0Sjeremylt for (CeedInt i=0; i<Ndofs; i++) 140*a8de75f0Sjeremylt sum += hv[i]; 141*a8de75f0Sjeremylt if (fabs(sum-1.)>1e-10) printf("Computed Area: %f != True Area: 1.0\n", sum); 142*a8de75f0Sjeremylt CeedVectorRestoreArrayRead(V, &hv); 143*a8de75f0Sjeremylt 144*a8de75f0Sjeremylt CeedQFunctionDestroy(&qf_setup); 145*a8de75f0Sjeremylt CeedQFunctionDestroy(&qf_mass); 146*a8de75f0Sjeremylt CeedOperatorDestroy(&op_setup); 147*a8de75f0Sjeremylt CeedOperatorDestroy(&op_mass); 148*a8de75f0Sjeremylt CeedElemRestrictionDestroy(&Erestrictu); 149*a8de75f0Sjeremylt CeedElemRestrictionDestroy(&Erestrictx); 150*a8de75f0Sjeremylt CeedElemRestrictionDestroy(&Erestrictui); 151*a8de75f0Sjeremylt CeedElemRestrictionDestroy(&Erestrictxi); 152*a8de75f0Sjeremylt CeedBasisDestroy(&bu); 153*a8de75f0Sjeremylt CeedBasisDestroy(&bx); 154*a8de75f0Sjeremylt CeedVectorDestroy(&X); 155*a8de75f0Sjeremylt CeedVectorDestroy(&U); 156*a8de75f0Sjeremylt CeedVectorDestroy(&V); 157*a8de75f0Sjeremylt CeedVectorDestroy(&qdata); 158*a8de75f0Sjeremylt CeedDestroy(&ceed); 159*a8de75f0Sjeremylt return 0; 160*a8de75f0Sjeremylt } 161