1*3bd813ffSjeremylt /// @file 2*3bd813ffSjeremylt /// Test creation and use of FDM element inverse 3*3bd813ffSjeremylt /// \test Test creation and use of FDM element inverse 4*3bd813ffSjeremylt #include <ceed.h> 5*3bd813ffSjeremylt #include <stdlib.h> 6*3bd813ffSjeremylt #include <math.h> 7*3bd813ffSjeremylt #include "t540-operator.h" 8*3bd813ffSjeremylt 9*3bd813ffSjeremylt int main(int argc, char **argv) { 10*3bd813ffSjeremylt Ceed ceed; 11*3bd813ffSjeremylt CeedElemRestriction Erestrictxi, Erestrictui, Erestrictqi; 12*3bd813ffSjeremylt CeedBasis bx, bu; 13*3bd813ffSjeremylt CeedQFunction qf_setup_mass, qf_apply; 14*3bd813ffSjeremylt CeedOperator op_setup_mass, op_apply, op_inv; 15*3bd813ffSjeremylt CeedVector qdata_mass, X, U, V; 16*3bd813ffSjeremylt CeedInt nelem = 1, P = 4, Q = 5, dim = 2; 17*3bd813ffSjeremylt CeedInt ndofs = P*P, nqpts = nelem*Q*Q; 18*3bd813ffSjeremylt CeedScalar x[dim*nelem*(2*2)]; 19*3bd813ffSjeremylt const CeedScalar *u; 20*3bd813ffSjeremylt 21*3bd813ffSjeremylt CeedInit(argv[1], &ceed); 22*3bd813ffSjeremylt 23*3bd813ffSjeremylt // DoF Coordinates 24*3bd813ffSjeremylt for (CeedInt i=0; i<2; i++) 25*3bd813ffSjeremylt for (CeedInt j=0; j<2; j++) { 26*3bd813ffSjeremylt x[i+j*2+0*4] = i; 27*3bd813ffSjeremylt x[i+j*2+1*4] = j; 28*3bd813ffSjeremylt } 29*3bd813ffSjeremylt CeedVectorCreate(ceed, dim*nelem*(2*2), &X); 30*3bd813ffSjeremylt CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x); 31*3bd813ffSjeremylt 32*3bd813ffSjeremylt // Qdata Vector 33*3bd813ffSjeremylt CeedVectorCreate(ceed, nqpts, &qdata_mass); 34*3bd813ffSjeremylt 35*3bd813ffSjeremylt // Element Setup 36*3bd813ffSjeremylt 37*3bd813ffSjeremylt // Restrictions 38*3bd813ffSjeremylt CeedElemRestrictionCreateIdentity(ceed, nelem, 2*2, nelem*2*2, dim, 39*3bd813ffSjeremylt &Erestrictxi); 40*3bd813ffSjeremylt 41*3bd813ffSjeremylt CeedElemRestrictionCreateIdentity(ceed, nelem, P*P, ndofs, 1, &Erestrictui); 42*3bd813ffSjeremylt 43*3bd813ffSjeremylt CeedElemRestrictionCreateIdentity(ceed, nelem, Q*Q, nqpts, 1, &Erestrictqi); 44*3bd813ffSjeremylt 45*3bd813ffSjeremylt // Bases 46*3bd813ffSjeremylt CeedBasisCreateTensorH1Lagrange(ceed, dim, dim, 2, Q, CEED_GAUSS, &bx); 47*3bd813ffSjeremylt CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, P, Q, CEED_GAUSS, &bu); 48*3bd813ffSjeremylt 49*3bd813ffSjeremylt // QFunction - setup mass 50*3bd813ffSjeremylt CeedQFunctionCreateInterior(ceed, 1, setup_mass, setup_mass_loc, 51*3bd813ffSjeremylt &qf_setup_mass); 52*3bd813ffSjeremylt CeedQFunctionAddInput(qf_setup_mass, "dx", dim*dim, CEED_EVAL_GRAD); 53*3bd813ffSjeremylt CeedQFunctionAddInput(qf_setup_mass, "_weight", 1, CEED_EVAL_WEIGHT); 54*3bd813ffSjeremylt CeedQFunctionAddOutput(qf_setup_mass, "qdata", 1, CEED_EVAL_NONE); 55*3bd813ffSjeremylt 56*3bd813ffSjeremylt // Operator - setup mass 57*3bd813ffSjeremylt CeedOperatorCreate(ceed, qf_setup_mass, CEED_QFUNCTION_NONE, 58*3bd813ffSjeremylt CEED_QFUNCTION_NONE, &op_setup_mass); 59*3bd813ffSjeremylt CeedOperatorSetField(op_setup_mass, "dx", Erestrictxi, CEED_NOTRANSPOSE, bx, 60*3bd813ffSjeremylt CEED_VECTOR_ACTIVE); 61*3bd813ffSjeremylt CeedOperatorSetField(op_setup_mass, "_weight", Erestrictxi, CEED_NOTRANSPOSE, 62*3bd813ffSjeremylt bx, CEED_VECTOR_NONE); 63*3bd813ffSjeremylt CeedOperatorSetField(op_setup_mass, "qdata", Erestrictqi, CEED_NOTRANSPOSE, 64*3bd813ffSjeremylt CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 65*3bd813ffSjeremylt 66*3bd813ffSjeremylt // Apply Setup Operator 67*3bd813ffSjeremylt CeedOperatorApply(op_setup_mass, X, qdata_mass, CEED_REQUEST_IMMEDIATE); 68*3bd813ffSjeremylt 69*3bd813ffSjeremylt // QFunction - apply 70*3bd813ffSjeremylt CeedQFunctionCreateInterior(ceed, 1, apply, apply_loc, &qf_apply); 71*3bd813ffSjeremylt CeedQFunctionAddInput(qf_apply, "u", 1, CEED_EVAL_INTERP); 72*3bd813ffSjeremylt CeedQFunctionAddInput(qf_apply, "qdata_mass", 1, CEED_EVAL_NONE); 73*3bd813ffSjeremylt CeedQFunctionAddOutput(qf_apply, "v", 1, CEED_EVAL_INTERP); 74*3bd813ffSjeremylt 75*3bd813ffSjeremylt // Operator - apply 76*3bd813ffSjeremylt CeedOperatorCreate(ceed, qf_apply, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 77*3bd813ffSjeremylt &op_apply); 78*3bd813ffSjeremylt CeedOperatorSetField(op_apply, "u", Erestrictui, CEED_NOTRANSPOSE, bu, 79*3bd813ffSjeremylt CEED_VECTOR_ACTIVE); 80*3bd813ffSjeremylt CeedOperatorSetField(op_apply, "qdata_mass", Erestrictqi, CEED_NOTRANSPOSE, 81*3bd813ffSjeremylt CEED_BASIS_COLLOCATED, qdata_mass); 82*3bd813ffSjeremylt CeedOperatorSetField(op_apply, "v", Erestrictui, CEED_NOTRANSPOSE, bu, 83*3bd813ffSjeremylt CEED_VECTOR_ACTIVE); 84*3bd813ffSjeremylt 85*3bd813ffSjeremylt // Apply original operator 86*3bd813ffSjeremylt CeedVectorCreate(ceed, ndofs, &U); 87*3bd813ffSjeremylt CeedVectorSetValue(U, 1.0); 88*3bd813ffSjeremylt CeedVectorCreate(ceed, ndofs, &V); 89*3bd813ffSjeremylt CeedVectorSetValue(V, 0.0); 90*3bd813ffSjeremylt CeedOperatorApply(op_apply, U, V, CEED_REQUEST_IMMEDIATE); 91*3bd813ffSjeremylt 92*3bd813ffSjeremylt // Create FDM element inverse 93*3bd813ffSjeremylt CeedOperatorCreateFDMElementInverse(op_apply, &op_inv, CEED_REQUEST_IMMEDIATE); 94*3bd813ffSjeremylt 95*3bd813ffSjeremylt // Apply FDM element inverse 96*3bd813ffSjeremylt CeedOperatorApply(op_inv, V, U, CEED_REQUEST_IMMEDIATE); 97*3bd813ffSjeremylt 98*3bd813ffSjeremylt // Check output 99*3bd813ffSjeremylt CeedVectorGetArrayRead(U, CEED_MEM_HOST, &u); 100*3bd813ffSjeremylt for (int i=0; i<ndofs; i++) 101*3bd813ffSjeremylt if (fabs(u[i] - 1.0) > 1E-14) 102*3bd813ffSjeremylt // LCOV_EXCL_START 103*3bd813ffSjeremylt printf("[%d] Error in inverse: %f != 1.0\n", i, u[i]); 104*3bd813ffSjeremylt // LCOV_EXCL_STOP 105*3bd813ffSjeremylt CeedVectorRestoreArrayRead(U, &u); 106*3bd813ffSjeremylt 107*3bd813ffSjeremylt // Cleanup 108*3bd813ffSjeremylt CeedQFunctionDestroy(&qf_setup_mass); 109*3bd813ffSjeremylt CeedQFunctionDestroy(&qf_apply); 110*3bd813ffSjeremylt CeedOperatorDestroy(&op_setup_mass); 111*3bd813ffSjeremylt CeedOperatorDestroy(&op_apply); 112*3bd813ffSjeremylt CeedOperatorDestroy(&op_inv); 113*3bd813ffSjeremylt CeedElemRestrictionDestroy(&Erestrictui); 114*3bd813ffSjeremylt CeedElemRestrictionDestroy(&Erestrictxi); 115*3bd813ffSjeremylt CeedElemRestrictionDestroy(&Erestrictqi); 116*3bd813ffSjeremylt CeedBasisDestroy(&bu); 117*3bd813ffSjeremylt CeedBasisDestroy(&bx); 118*3bd813ffSjeremylt CeedVectorDestroy(&X); 119*3bd813ffSjeremylt CeedVectorDestroy(&qdata_mass); 120*3bd813ffSjeremylt CeedVectorDestroy(&U); 121*3bd813ffSjeremylt CeedVectorDestroy(&V); 122*3bd813ffSjeremylt CeedDestroy(&ceed); 123*3bd813ffSjeremylt return 0; 124*3bd813ffSjeremylt } 125