1*5b3ccac8Sjeremylt /// @file 2*5b3ccac8Sjeremylt /// Test creation reuse of the same QFunction for multiple operators 3*5b3ccac8Sjeremylt /// \test Test creation reuse of the same QFunction for multiple operators 4*5b3ccac8Sjeremylt #include <ceed.h> 5*5b3ccac8Sjeremylt #include <stdlib.h> 6*5b3ccac8Sjeremylt #include <math.h> 7*5b3ccac8Sjeremylt #include "t502-operator.h" 8*5b3ccac8Sjeremylt 9*5b3ccac8Sjeremylt int main(int argc, char **argv) { 10*5b3ccac8Sjeremylt Ceed ceed; 11*5b3ccac8Sjeremylt CeedInterlaceMode imode = CEED_NONINTERLACED, 12*5b3ccac8Sjeremylt imodeu = CEED_INTERLACED;; 13*5b3ccac8Sjeremylt CeedElemRestriction Erestrictx, Erestrictu, 14*5b3ccac8Sjeremylt Erestrictui_small, Erestrictui_large; 15*5b3ccac8Sjeremylt CeedBasis bx_small, bx_large, bu_small, bu_large; 16*5b3ccac8Sjeremylt CeedQFunction qf_setup, qf_mass; 17*5b3ccac8Sjeremylt CeedOperator op_setup_small, op_mass_small, 18*5b3ccac8Sjeremylt op_setup_large, op_mass_large; 19*5b3ccac8Sjeremylt CeedVector qdata_small, qdata_large, X, U, V; 20*5b3ccac8Sjeremylt CeedScalar *hu; 21*5b3ccac8Sjeremylt const CeedScalar *hv; 22*5b3ccac8Sjeremylt CeedInt nelem = 15, P = 5, Q = 8, scale = 3; 23*5b3ccac8Sjeremylt CeedInt Nx = nelem+1, Nu = nelem*(P-1)+1; 24*5b3ccac8Sjeremylt CeedInt indx[nelem*2], indu[nelem*P]; 25*5b3ccac8Sjeremylt CeedScalar x[Nx]; 26*5b3ccac8Sjeremylt CeedScalar sum1, sum2; 27*5b3ccac8Sjeremylt 28*5b3ccac8Sjeremylt CeedInit(argv[1], &ceed); 29*5b3ccac8Sjeremylt for (CeedInt i=0; i<Nx; i++) x[i] = (CeedScalar) i / (Nx - 1); 30*5b3ccac8Sjeremylt for (CeedInt i=0; i<nelem; i++) { 31*5b3ccac8Sjeremylt indx[2*i+0] = i; 32*5b3ccac8Sjeremylt indx[2*i+1] = i+1; 33*5b3ccac8Sjeremylt } 34*5b3ccac8Sjeremylt // Restrictions 35*5b3ccac8Sjeremylt CeedElemRestrictionCreate(ceed, imode, nelem, 2, Nx, 1, CEED_MEM_HOST, 36*5b3ccac8Sjeremylt CEED_USE_POINTER, indx, &Erestrictx); 37*5b3ccac8Sjeremylt 38*5b3ccac8Sjeremylt for (CeedInt i=0; i<nelem; i++) { 39*5b3ccac8Sjeremylt for (CeedInt j=0; j<P; j++) { 40*5b3ccac8Sjeremylt indu[P*i+j] = i*(P-1) + j; 41*5b3ccac8Sjeremylt } 42*5b3ccac8Sjeremylt } 43*5b3ccac8Sjeremylt CeedElemRestrictionCreate(ceed, imodeu, nelem, P, Nu, 2, CEED_MEM_HOST, 44*5b3ccac8Sjeremylt CEED_USE_POINTER, indu, &Erestrictu); 45*5b3ccac8Sjeremylt CeedInt stridesu_small[3] = {1, Q, Q}; 46*5b3ccac8Sjeremylt CeedElemRestrictionCreateStrided(ceed, nelem, Q, Q*nelem, 1, stridesu_small, 47*5b3ccac8Sjeremylt &Erestrictui_small); 48*5b3ccac8Sjeremylt CeedInt stridesu_large[3] = {1, Q*scale, Q*scale}; 49*5b3ccac8Sjeremylt CeedElemRestrictionCreateStrided(ceed, nelem, Q*scale, Q*nelem*scale, 1, 50*5b3ccac8Sjeremylt stridesu_large, &Erestrictui_large); 51*5b3ccac8Sjeremylt 52*5b3ccac8Sjeremylt // Bases 53*5b3ccac8Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, 2, Q, CEED_GAUSS, &bx_small); 54*5b3ccac8Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, 1, 2, P, Q, CEED_GAUSS, &bu_small); 55*5b3ccac8Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, 2, Q*scale, CEED_GAUSS, &bx_large); 56*5b3ccac8Sjeremylt CeedBasisCreateTensorH1Lagrange(ceed, 1, 2, P, Q*scale, CEED_GAUSS, &bu_large); 57*5b3ccac8Sjeremylt 58*5b3ccac8Sjeremylt // QFunctions 59*5b3ccac8Sjeremylt CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_setup); 60*5b3ccac8Sjeremylt CeedQFunctionAddInput(qf_setup, "_weight", 1, CEED_EVAL_WEIGHT); 61*5b3ccac8Sjeremylt CeedQFunctionAddInput(qf_setup, "x", 1, CEED_EVAL_GRAD); 62*5b3ccac8Sjeremylt CeedQFunctionAddOutput(qf_setup, "rho", 1, CEED_EVAL_NONE); 63*5b3ccac8Sjeremylt 64*5b3ccac8Sjeremylt CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_mass); 65*5b3ccac8Sjeremylt CeedQFunctionAddInput(qf_mass, "rho", 1, CEED_EVAL_NONE); 66*5b3ccac8Sjeremylt CeedQFunctionAddInput(qf_mass, "u", 2, CEED_EVAL_INTERP); 67*5b3ccac8Sjeremylt CeedQFunctionAddOutput(qf_mass, "v", 2, CEED_EVAL_INTERP); 68*5b3ccac8Sjeremylt 69*5b3ccac8Sjeremylt // Input vector 70*5b3ccac8Sjeremylt CeedVectorCreate(ceed, Nx, &X); 71*5b3ccac8Sjeremylt CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x); 72*5b3ccac8Sjeremylt 73*5b3ccac8Sjeremylt // 'Small' Operators 74*5b3ccac8Sjeremylt CeedOperatorCreate(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 75*5b3ccac8Sjeremylt &op_setup_small); 76*5b3ccac8Sjeremylt CeedOperatorCreate(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 77*5b3ccac8Sjeremylt &op_mass_small); 78*5b3ccac8Sjeremylt 79*5b3ccac8Sjeremylt CeedVectorCreate(ceed, nelem*Q, &qdata_small); 80*5b3ccac8Sjeremylt 81*5b3ccac8Sjeremylt CeedOperatorSetField(op_setup_small, "_weight", CEED_ELEMRESTRICTION_NONE, 82*5b3ccac8Sjeremylt bx_small, CEED_VECTOR_NONE); 83*5b3ccac8Sjeremylt CeedOperatorSetField(op_setup_small, "x", Erestrictx, 84*5b3ccac8Sjeremylt bx_small, CEED_VECTOR_ACTIVE); 85*5b3ccac8Sjeremylt CeedOperatorSetField(op_setup_small, "rho", Erestrictui_small, 86*5b3ccac8Sjeremylt CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 87*5b3ccac8Sjeremylt 88*5b3ccac8Sjeremylt CeedOperatorSetField(op_mass_small, "rho", Erestrictui_small, 89*5b3ccac8Sjeremylt CEED_BASIS_COLLOCATED, qdata_small); 90*5b3ccac8Sjeremylt CeedOperatorSetField(op_mass_small, "u", Erestrictu, 91*5b3ccac8Sjeremylt bu_small, CEED_VECTOR_ACTIVE); 92*5b3ccac8Sjeremylt CeedOperatorSetField(op_mass_small, "v", Erestrictu, 93*5b3ccac8Sjeremylt bu_small, CEED_VECTOR_ACTIVE); 94*5b3ccac8Sjeremylt 95*5b3ccac8Sjeremylt // 'Large' operators 96*5b3ccac8Sjeremylt CeedOperatorCreate(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 97*5b3ccac8Sjeremylt &op_setup_large); 98*5b3ccac8Sjeremylt CeedOperatorCreate(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 99*5b3ccac8Sjeremylt &op_mass_large); 100*5b3ccac8Sjeremylt 101*5b3ccac8Sjeremylt CeedVectorCreate(ceed, nelem*Q*scale, &qdata_large); 102*5b3ccac8Sjeremylt 103*5b3ccac8Sjeremylt CeedOperatorSetField(op_setup_large, "_weight", CEED_ELEMRESTRICTION_NONE, 104*5b3ccac8Sjeremylt bx_large, CEED_VECTOR_NONE); 105*5b3ccac8Sjeremylt CeedOperatorSetField(op_setup_large, "x", Erestrictx, 106*5b3ccac8Sjeremylt bx_large, CEED_VECTOR_ACTIVE); 107*5b3ccac8Sjeremylt CeedOperatorSetField(op_setup_large, "rho", Erestrictui_large, 108*5b3ccac8Sjeremylt CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 109*5b3ccac8Sjeremylt 110*5b3ccac8Sjeremylt CeedOperatorSetField(op_mass_large, "rho", Erestrictui_large, 111*5b3ccac8Sjeremylt CEED_BASIS_COLLOCATED, qdata_large); 112*5b3ccac8Sjeremylt CeedOperatorSetField(op_mass_large, "u", Erestrictu, 113*5b3ccac8Sjeremylt bu_large, CEED_VECTOR_ACTIVE); 114*5b3ccac8Sjeremylt CeedOperatorSetField(op_mass_large, "v", Erestrictu, 115*5b3ccac8Sjeremylt bu_large, CEED_VECTOR_ACTIVE); 116*5b3ccac8Sjeremylt 117*5b3ccac8Sjeremylt // Setup 118*5b3ccac8Sjeremylt CeedOperatorApply(op_setup_small, X, qdata_small, CEED_REQUEST_IMMEDIATE); 119*5b3ccac8Sjeremylt CeedOperatorApply(op_setup_large, X, qdata_large, CEED_REQUEST_IMMEDIATE); 120*5b3ccac8Sjeremylt 121*5b3ccac8Sjeremylt CeedVectorCreate(ceed, 2*Nu, &U); 122*5b3ccac8Sjeremylt CeedVectorGetArray(U, CEED_MEM_HOST, &hu); 123*5b3ccac8Sjeremylt for (int i = 0; i < Nu; i++) { 124*5b3ccac8Sjeremylt hu[2*i] = 1.0; 125*5b3ccac8Sjeremylt hu[2*i+1] = 2.0; 126*5b3ccac8Sjeremylt } 127*5b3ccac8Sjeremylt CeedVectorRestoreArray(U, &hu); 128*5b3ccac8Sjeremylt CeedVectorCreate(ceed, 2*Nu, &V); 129*5b3ccac8Sjeremylt 130*5b3ccac8Sjeremylt // 'Small' operator 131*5b3ccac8Sjeremylt CeedOperatorApply(op_mass_small, U, V, CEED_REQUEST_IMMEDIATE); 132*5b3ccac8Sjeremylt 133*5b3ccac8Sjeremylt // Check output 134*5b3ccac8Sjeremylt CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv); 135*5b3ccac8Sjeremylt sum1 = 0.; sum2 = 0.; 136*5b3ccac8Sjeremylt for (CeedInt i=0; i<Nu; i++) { 137*5b3ccac8Sjeremylt sum1 += hv[2*i]; 138*5b3ccac8Sjeremylt sum2 += hv[2*i+1]; 139*5b3ccac8Sjeremylt } 140*5b3ccac8Sjeremylt if (fabs(sum1-1.)>1e-10) printf("Computed Area: %f != True Area: 1.0\n", sum1); 141*5b3ccac8Sjeremylt if (fabs(sum2-2.)>1e-10) printf("Computed Area: %f != True Area: 2.0\n", sum2); 142*5b3ccac8Sjeremylt CeedVectorRestoreArrayRead(V, &hv); 143*5b3ccac8Sjeremylt 144*5b3ccac8Sjeremylt // 'Large' operator 145*5b3ccac8Sjeremylt CeedOperatorApply(op_mass_large, U, V, CEED_REQUEST_IMMEDIATE); 146*5b3ccac8Sjeremylt 147*5b3ccac8Sjeremylt // Check output 148*5b3ccac8Sjeremylt CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv); 149*5b3ccac8Sjeremylt sum1 = 0.; sum2 = 0.; 150*5b3ccac8Sjeremylt for (CeedInt i=0; i<Nu; i++) { 151*5b3ccac8Sjeremylt sum1 += hv[2*i]; 152*5b3ccac8Sjeremylt sum2 += hv[2*i+1]; 153*5b3ccac8Sjeremylt } 154*5b3ccac8Sjeremylt if (fabs(sum1-1.)>1e-10) printf("Computed Area: %f != True Area: 1.0\n", sum1); 155*5b3ccac8Sjeremylt if (fabs(sum2-2.)>1e-10) printf("Computed Area: %f != True Area: 2.0\n", sum2); 156*5b3ccac8Sjeremylt CeedVectorRestoreArrayRead(V, &hv); 157*5b3ccac8Sjeremylt 158*5b3ccac8Sjeremylt CeedQFunctionDestroy(&qf_setup); 159*5b3ccac8Sjeremylt CeedQFunctionDestroy(&qf_mass); 160*5b3ccac8Sjeremylt CeedOperatorDestroy(&op_setup_small); 161*5b3ccac8Sjeremylt CeedOperatorDestroy(&op_mass_small); 162*5b3ccac8Sjeremylt CeedOperatorDestroy(&op_setup_large); 163*5b3ccac8Sjeremylt CeedOperatorDestroy(&op_mass_large); 164*5b3ccac8Sjeremylt CeedElemRestrictionDestroy(&Erestrictu); 165*5b3ccac8Sjeremylt CeedElemRestrictionDestroy(&Erestrictx); 166*5b3ccac8Sjeremylt CeedElemRestrictionDestroy(&Erestrictui_small); 167*5b3ccac8Sjeremylt CeedElemRestrictionDestroy(&Erestrictui_large); 168*5b3ccac8Sjeremylt CeedBasisDestroy(&bu_small); 169*5b3ccac8Sjeremylt CeedBasisDestroy(&bx_small); 170*5b3ccac8Sjeremylt CeedBasisDestroy(&bu_large); 171*5b3ccac8Sjeremylt CeedBasisDestroy(&bx_large); 172*5b3ccac8Sjeremylt CeedVectorDestroy(&X); 173*5b3ccac8Sjeremylt CeedVectorDestroy(&U); 174*5b3ccac8Sjeremylt CeedVectorDestroy(&V); 175*5b3ccac8Sjeremylt CeedVectorDestroy(&qdata_small); 176*5b3ccac8Sjeremylt CeedVectorDestroy(&qdata_large); 177*5b3ccac8Sjeremylt CeedDestroy(&ceed); 178*5b3ccac8Sjeremylt return 0; 179*5b3ccac8Sjeremylt } 180