13bd813ffSjeremylt /// @file 23bd813ffSjeremylt /// Test creation and use of FDM element inverse 33bd813ffSjeremylt /// \test Test creation and use of FDM element inverse 43bd813ffSjeremylt #include <ceed.h> 53bd813ffSjeremylt #include <stdlib.h> 63bd813ffSjeremylt #include <math.h> 73bd813ffSjeremylt #include "t540-operator.h" 83bd813ffSjeremylt 93bd813ffSjeremylt int main(int argc, char **argv) { 103bd813ffSjeremylt Ceed ceed; 11*a8d32208Sjeremylt CeedTransposeMode lmode = CEED_NOTRANSPOSE; 123bd813ffSjeremylt CeedElemRestriction Erestrictxi, Erestrictui, Erestrictqi; 133bd813ffSjeremylt CeedBasis bx, bu; 143bd813ffSjeremylt CeedQFunction qf_setup_mass, qf_apply; 153bd813ffSjeremylt CeedOperator op_setup_mass, op_apply, op_inv; 163bd813ffSjeremylt CeedVector qdata_mass, X, U, V; 173bd813ffSjeremylt CeedInt nelem = 1, P = 4, Q = 5, dim = 2; 183bd813ffSjeremylt CeedInt ndofs = P*P, nqpts = nelem*Q*Q; 193bd813ffSjeremylt CeedScalar x[dim*nelem*(2*2)]; 203bd813ffSjeremylt const CeedScalar *u; 213bd813ffSjeremylt 223bd813ffSjeremylt CeedInit(argv[1], &ceed); 233bd813ffSjeremylt 243bd813ffSjeremylt // DoF Coordinates 253bd813ffSjeremylt for (CeedInt i=0; i<2; i++) 263bd813ffSjeremylt for (CeedInt j=0; j<2; j++) { 273bd813ffSjeremylt x[i+j*2+0*4] = i; 283bd813ffSjeremylt x[i+j*2+1*4] = j; 293bd813ffSjeremylt } 303bd813ffSjeremylt CeedVectorCreate(ceed, dim*nelem*(2*2), &X); 313bd813ffSjeremylt CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x); 323bd813ffSjeremylt 333bd813ffSjeremylt // Qdata Vector 343bd813ffSjeremylt CeedVectorCreate(ceed, nqpts, &qdata_mass); 353bd813ffSjeremylt 363bd813ffSjeremylt // Element Setup 373bd813ffSjeremylt 383bd813ffSjeremylt // Restrictions 39*a8d32208Sjeremylt CeedElemRestrictionCreateIdentity(ceed, lmode, nelem, 2*2, nelem*2*2, dim, 403bd813ffSjeremylt &Erestrictxi); 413bd813ffSjeremylt 42*a8d32208Sjeremylt CeedElemRestrictionCreateIdentity(ceed, lmode, nelem, P*P, ndofs, 1, 43*a8d32208Sjeremylt &Erestrictui); 443bd813ffSjeremylt 45*a8d32208Sjeremylt CeedElemRestrictionCreateIdentity(ceed, lmode, nelem, Q*Q, nqpts, 1, 46*a8d32208Sjeremylt &Erestrictqi); 473bd813ffSjeremylt 483bd813ffSjeremylt // Bases 493bd813ffSjeremylt CeedBasisCreateTensorH1Lagrange(ceed, dim, dim, 2, Q, CEED_GAUSS, &bx); 503bd813ffSjeremylt CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, P, Q, CEED_GAUSS, &bu); 513bd813ffSjeremylt 523bd813ffSjeremylt // QFunction - setup mass 533bd813ffSjeremylt CeedQFunctionCreateInterior(ceed, 1, setup_mass, setup_mass_loc, 543bd813ffSjeremylt &qf_setup_mass); 553bd813ffSjeremylt CeedQFunctionAddInput(qf_setup_mass, "dx", dim*dim, CEED_EVAL_GRAD); 563bd813ffSjeremylt CeedQFunctionAddInput(qf_setup_mass, "_weight", 1, CEED_EVAL_WEIGHT); 573bd813ffSjeremylt CeedQFunctionAddOutput(qf_setup_mass, "qdata", 1, CEED_EVAL_NONE); 583bd813ffSjeremylt 593bd813ffSjeremylt // Operator - setup mass 603bd813ffSjeremylt CeedOperatorCreate(ceed, qf_setup_mass, CEED_QFUNCTION_NONE, 613bd813ffSjeremylt CEED_QFUNCTION_NONE, &op_setup_mass); 62*a8d32208Sjeremylt CeedOperatorSetField(op_setup_mass, "dx", Erestrictxi, bx, 633bd813ffSjeremylt CEED_VECTOR_ACTIVE); 64*a8d32208Sjeremylt CeedOperatorSetField(op_setup_mass, "_weight", Erestrictxi, bx, 65*a8d32208Sjeremylt CEED_VECTOR_NONE); 66*a8d32208Sjeremylt CeedOperatorSetField(op_setup_mass, "qdata", Erestrictqi, 673bd813ffSjeremylt CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE); 683bd813ffSjeremylt 693bd813ffSjeremylt // Apply Setup Operator 703bd813ffSjeremylt CeedOperatorApply(op_setup_mass, X, qdata_mass, CEED_REQUEST_IMMEDIATE); 713bd813ffSjeremylt 723bd813ffSjeremylt // QFunction - apply 733bd813ffSjeremylt CeedQFunctionCreateInterior(ceed, 1, apply, apply_loc, &qf_apply); 743bd813ffSjeremylt CeedQFunctionAddInput(qf_apply, "u", 1, CEED_EVAL_INTERP); 753bd813ffSjeremylt CeedQFunctionAddInput(qf_apply, "qdata_mass", 1, CEED_EVAL_NONE); 763bd813ffSjeremylt CeedQFunctionAddOutput(qf_apply, "v", 1, CEED_EVAL_INTERP); 773bd813ffSjeremylt 783bd813ffSjeremylt // Operator - apply 793bd813ffSjeremylt CeedOperatorCreate(ceed, qf_apply, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, 803bd813ffSjeremylt &op_apply); 81*a8d32208Sjeremylt CeedOperatorSetField(op_apply, "u", Erestrictui, bu, CEED_VECTOR_ACTIVE); 82*a8d32208Sjeremylt CeedOperatorSetField(op_apply, "qdata_mass", Erestrictqi, 833bd813ffSjeremylt CEED_BASIS_COLLOCATED, qdata_mass); 84*a8d32208Sjeremylt CeedOperatorSetField(op_apply, "v", Erestrictui, bu, CEED_VECTOR_ACTIVE); 853bd813ffSjeremylt 863bd813ffSjeremylt // Apply original operator 873bd813ffSjeremylt CeedVectorCreate(ceed, ndofs, &U); 883bd813ffSjeremylt CeedVectorSetValue(U, 1.0); 893bd813ffSjeremylt CeedVectorCreate(ceed, ndofs, &V); 903bd813ffSjeremylt CeedVectorSetValue(V, 0.0); 913bd813ffSjeremylt CeedOperatorApply(op_apply, U, V, CEED_REQUEST_IMMEDIATE); 923bd813ffSjeremylt 933bd813ffSjeremylt // Create FDM element inverse 943bd813ffSjeremylt CeedOperatorCreateFDMElementInverse(op_apply, &op_inv, CEED_REQUEST_IMMEDIATE); 953bd813ffSjeremylt 963bd813ffSjeremylt // Apply FDM element inverse 973bd813ffSjeremylt CeedOperatorApply(op_inv, V, U, CEED_REQUEST_IMMEDIATE); 983bd813ffSjeremylt 993bd813ffSjeremylt // Check output 1003bd813ffSjeremylt CeedVectorGetArrayRead(U, CEED_MEM_HOST, &u); 1013bd813ffSjeremylt for (int i=0; i<ndofs; i++) 1023bd813ffSjeremylt if (fabs(u[i] - 1.0) > 1E-14) 1033bd813ffSjeremylt // LCOV_EXCL_START 1043bd813ffSjeremylt printf("[%d] Error in inverse: %f != 1.0\n", i, u[i]); 1053bd813ffSjeremylt // LCOV_EXCL_STOP 1063bd813ffSjeremylt CeedVectorRestoreArrayRead(U, &u); 1073bd813ffSjeremylt 1083bd813ffSjeremylt // Cleanup 1093bd813ffSjeremylt CeedQFunctionDestroy(&qf_setup_mass); 1103bd813ffSjeremylt CeedQFunctionDestroy(&qf_apply); 1113bd813ffSjeremylt CeedOperatorDestroy(&op_setup_mass); 1123bd813ffSjeremylt CeedOperatorDestroy(&op_apply); 1133bd813ffSjeremylt CeedOperatorDestroy(&op_inv); 1143bd813ffSjeremylt CeedElemRestrictionDestroy(&Erestrictui); 1153bd813ffSjeremylt CeedElemRestrictionDestroy(&Erestrictxi); 1163bd813ffSjeremylt CeedElemRestrictionDestroy(&Erestrictqi); 1173bd813ffSjeremylt CeedBasisDestroy(&bu); 1183bd813ffSjeremylt CeedBasisDestroy(&bx); 1193bd813ffSjeremylt CeedVectorDestroy(&X); 1203bd813ffSjeremylt CeedVectorDestroy(&qdata_mass); 1213bd813ffSjeremylt CeedVectorDestroy(&U); 1223bd813ffSjeremylt CeedVectorDestroy(&V); 1233bd813ffSjeremylt CeedDestroy(&ceed); 1243bd813ffSjeremylt return 0; 1253bd813ffSjeremylt } 126