15b3ccac8Sjeremylt /// @file 25b3ccac8Sjeremylt /// Test creation reuse of the same QFunction for multiple operators 35b3ccac8Sjeremylt /// \test Test creation reuse of the same QFunction for multiple operators 45b3ccac8Sjeremylt #include <ceed.h> 55b3ccac8Sjeremylt #include <math.h> 649aac155SJeremy L Thompson #include <stdio.h> 72b730f8bSJeremy L Thompson #include <stdlib.h> 82b730f8bSJeremy L Thompson 95b3ccac8Sjeremylt #include "t502-operator.h" 105b3ccac8Sjeremylt 115b3ccac8Sjeremylt int main(int argc, char **argv) { 125b3ccac8Sjeremylt Ceed ceed; 134fee36f0SJeremy L Thompson CeedElemRestriction elem_restriction_x, elem_restriction_u, elem_restriction_q_data_small, elem_restriction_q_data_large; 14d1d35e2fSjeremylt CeedBasis basis_x_small, basis_x_large, basis_u_small, basis_u_large; 155b3ccac8Sjeremylt CeedQFunction qf_setup, qf_mass; 162b730f8bSJeremy L Thompson CeedOperator op_setup_small, op_mass_small, op_setup_large, op_mass_large; 174fee36f0SJeremy L Thompson CeedVector q_data_small, q_data_large, x, u, v; 184fee36f0SJeremy L Thompson CeedInt num_elem = 15, p = 5, q = 8, scale = 3; 194fee36f0SJeremy L Thompson CeedInt num_nodes_x = num_elem + 1, num_nodes_u = num_elem * (p - 1) + 1; 204fee36f0SJeremy L Thompson CeedInt ind_x[num_elem * 2], ind_u[num_elem * p]; 215b3ccac8Sjeremylt 225b3ccac8Sjeremylt CeedInit(argv[1], &ceed); 234fee36f0SJeremy L Thompson 244fee36f0SJeremy L Thompson CeedVectorCreate(ceed, num_nodes_x, &x); 254fee36f0SJeremy L Thompson { 264fee36f0SJeremy L Thompson CeedScalar x_array[num_nodes_x]; 274fee36f0SJeremy L Thompson 284fee36f0SJeremy L Thompson for (CeedInt i = 0; i < num_nodes_x; i++) x_array[i] = (CeedScalar)i / (num_nodes_x - 1); 294fee36f0SJeremy L Thompson CeedVectorSetArray(x, CEED_MEM_HOST, CEED_COPY_VALUES, x_array); 304fee36f0SJeremy L Thompson } 314fee36f0SJeremy L Thompson CeedVectorCreate(ceed, 2 * num_nodes_u, &u); 324fee36f0SJeremy L Thompson CeedVectorCreate(ceed, 2 * num_nodes_u, &v); 334fee36f0SJeremy L Thompson CeedVectorCreate(ceed, num_elem * q, &q_data_small); 344fee36f0SJeremy L Thompson CeedVectorCreate(ceed, num_elem * q * scale, &q_data_large); 354fee36f0SJeremy L Thompson 364fee36f0SJeremy L Thompson // Restrictions 37d1d35e2fSjeremylt for (CeedInt i = 0; i < num_elem; i++) { 38d1d35e2fSjeremylt ind_x[2 * i + 0] = i; 39d1d35e2fSjeremylt ind_x[2 * i + 1] = i + 1; 405b3ccac8Sjeremylt } 414fee36f0SJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem, 2, 1, 1, num_nodes_x, CEED_MEM_HOST, CEED_USE_POINTER, ind_x, &elem_restriction_x); 425b3ccac8Sjeremylt 43d1d35e2fSjeremylt for (CeedInt i = 0; i < num_elem; i++) { 444fee36f0SJeremy L Thompson for (CeedInt j = 0; j < p; j++) { 454fee36f0SJeremy L Thompson ind_u[p * i + j] = 2 * (i * (p - 1) + j); 465b3ccac8Sjeremylt } 475b3ccac8Sjeremylt } 484fee36f0SJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem, p, 2, 1, 2 * num_nodes_u, CEED_MEM_HOST, CEED_USE_POINTER, ind_u, &elem_restriction_u); 494fee36f0SJeremy L Thompson 504fee36f0SJeremy L Thompson CeedInt strides_q_data_small[3] = {1, q, q}; 514fee36f0SJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, q, 1, q * num_elem, strides_q_data_small, &elem_restriction_q_data_small); 524fee36f0SJeremy L Thompson 534fee36f0SJeremy L Thompson CeedInt strides_q_data_large[3] = {1, q * scale, q * scale}; 544fee36f0SJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem, q * scale, 1, q * num_elem * scale, strides_q_data_large, &elem_restriction_q_data_large); 555b3ccac8Sjeremylt 565b3ccac8Sjeremylt // Bases 574fee36f0SJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, 2, q, CEED_GAUSS, &basis_x_small); 584fee36f0SJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, 1, 2, p, q, CEED_GAUSS, &basis_u_small); 594fee36f0SJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, 2, q * scale, CEED_GAUSS, &basis_x_large); 604fee36f0SJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, 1, 2, p, q * scale, CEED_GAUSS, &basis_u_large); 615b3ccac8Sjeremylt 625b3ccac8Sjeremylt // QFunctions 635b3ccac8Sjeremylt CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_setup); 64a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_setup, "weight", 1, CEED_EVAL_WEIGHT); 655b3ccac8Sjeremylt CeedQFunctionAddInput(qf_setup, "x", 1, CEED_EVAL_GRAD); 665b3ccac8Sjeremylt CeedQFunctionAddOutput(qf_setup, "rho", 1, CEED_EVAL_NONE); 675b3ccac8Sjeremylt 685b3ccac8Sjeremylt CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_mass); 695b3ccac8Sjeremylt CeedQFunctionAddInput(qf_mass, "rho", 1, CEED_EVAL_NONE); 705b3ccac8Sjeremylt CeedQFunctionAddInput(qf_mass, "u", 2, CEED_EVAL_INTERP); 715b3ccac8Sjeremylt CeedQFunctionAddOutput(qf_mass, "v", 2, CEED_EVAL_INTERP); 725b3ccac8Sjeremylt 735b3ccac8Sjeremylt // 'Small' Operators 742b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_small); 752b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_small, "weight", CEED_ELEMRESTRICTION_NONE, basis_x_small, CEED_VECTOR_NONE); 764fee36f0SJeremy L Thompson CeedOperatorSetField(op_setup_small, "x", elem_restriction_x, basis_x_small, CEED_VECTOR_ACTIVE); 77*356036faSJeremy L Thompson CeedOperatorSetField(op_setup_small, "rho", elem_restriction_q_data_small, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 785b3ccac8Sjeremylt 794fee36f0SJeremy L Thompson CeedOperatorCreate(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_mass_small); 80*356036faSJeremy L Thompson CeedOperatorSetField(op_mass_small, "rho", elem_restriction_q_data_small, CEED_BASIS_NONE, q_data_small); 814fee36f0SJeremy L Thompson CeedOperatorSetField(op_mass_small, "u", elem_restriction_u, basis_u_small, CEED_VECTOR_ACTIVE); 824fee36f0SJeremy L Thompson CeedOperatorSetField(op_mass_small, "v", elem_restriction_u, basis_u_small, CEED_VECTOR_ACTIVE); 835b3ccac8Sjeremylt 845b3ccac8Sjeremylt // 'Large' operators 852b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_large); 862b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_large, "weight", CEED_ELEMRESTRICTION_NONE, basis_x_large, CEED_VECTOR_NONE); 874fee36f0SJeremy L Thompson CeedOperatorSetField(op_setup_large, "x", elem_restriction_x, basis_x_large, CEED_VECTOR_ACTIVE); 88*356036faSJeremy L Thompson CeedOperatorSetField(op_setup_large, "rho", elem_restriction_q_data_large, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 895b3ccac8Sjeremylt 904fee36f0SJeremy L Thompson CeedOperatorCreate(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_mass_large); 91*356036faSJeremy L Thompson CeedOperatorSetField(op_mass_large, "rho", elem_restriction_q_data_large, CEED_BASIS_NONE, q_data_large); 924fee36f0SJeremy L Thompson CeedOperatorSetField(op_mass_large, "u", elem_restriction_u, basis_u_large, CEED_VECTOR_ACTIVE); 934fee36f0SJeremy L Thompson CeedOperatorSetField(op_mass_large, "v", elem_restriction_u, basis_u_large, CEED_VECTOR_ACTIVE); 945b3ccac8Sjeremylt 955b3ccac8Sjeremylt // Setup 964fee36f0SJeremy L Thompson CeedOperatorApply(op_setup_small, x, q_data_small, CEED_REQUEST_IMMEDIATE); 974fee36f0SJeremy L Thompson CeedOperatorApply(op_setup_large, x, q_data_large, CEED_REQUEST_IMMEDIATE); 985b3ccac8Sjeremylt 994fee36f0SJeremy L Thompson { 1004fee36f0SJeremy L Thompson CeedScalar *u_array; 1014fee36f0SJeremy L Thompson 1024fee36f0SJeremy L Thompson CeedVectorGetArrayWrite(u, CEED_MEM_HOST, &u_array); 103d1d35e2fSjeremylt for (int i = 0; i < num_nodes_u; i++) { 1044fee36f0SJeremy L Thompson u_array[2 * i] = 1.0; 1054fee36f0SJeremy L Thompson u_array[2 * i + 1] = 2.0; 1065b3ccac8Sjeremylt } 1074fee36f0SJeremy L Thompson CeedVectorRestoreArray(u, &u_array); 1084fee36f0SJeremy L Thompson } 1095b3ccac8Sjeremylt 1105b3ccac8Sjeremylt // 'Small' operator 1114fee36f0SJeremy L Thompson CeedOperatorApply(op_mass_small, u, v, CEED_REQUEST_IMMEDIATE); 1125b3ccac8Sjeremylt 1135b3ccac8Sjeremylt // Check output 1144fee36f0SJeremy L Thompson { 1154fee36f0SJeremy L Thompson const CeedScalar *v_array; 1164fee36f0SJeremy L Thompson CeedScalar sum_1 = 0., sum_2 = 0.; 1174fee36f0SJeremy L Thompson 1184fee36f0SJeremy L Thompson CeedVectorGetArrayRead(v, CEED_MEM_HOST, &v_array); 119d1d35e2fSjeremylt for (CeedInt i = 0; i < num_nodes_u; i++) { 1204fee36f0SJeremy L Thompson sum_1 += v_array[2 * i]; 1214fee36f0SJeremy L Thompson sum_2 += v_array[2 * i + 1]; 1225b3ccac8Sjeremylt } 1234fee36f0SJeremy L Thompson CeedVectorRestoreArrayRead(v, &v_array); 1242b730f8bSJeremy L Thompson if (fabs(sum_1 - 1.) > 1000. * CEED_EPSILON) printf("Computed Area: %f != True Area: 1.0\n", sum_1); 1252b730f8bSJeremy L Thompson if (fabs(sum_2 - 2.) > 1000. * CEED_EPSILON) printf("Computed Area: %f != True Area: 2.0\n", sum_2); 1264fee36f0SJeremy L Thompson } 1275b3ccac8Sjeremylt 1285b3ccac8Sjeremylt // 'Large' operator 1294fee36f0SJeremy L Thompson CeedOperatorApply(op_mass_large, u, v, CEED_REQUEST_IMMEDIATE); 1305b3ccac8Sjeremylt 1315b3ccac8Sjeremylt // Check output 1324fee36f0SJeremy L Thompson { 1334fee36f0SJeremy L Thompson const CeedScalar *v_array; 1344fee36f0SJeremy L Thompson CeedScalar sum_1 = 0., sum_2 = 0.; 1354fee36f0SJeremy L Thompson 1364fee36f0SJeremy L Thompson CeedVectorGetArrayRead(v, CEED_MEM_HOST, &v_array); 137d1d35e2fSjeremylt for (CeedInt i = 0; i < num_nodes_u; i++) { 1384fee36f0SJeremy L Thompson sum_1 += v_array[2 * i]; 1394fee36f0SJeremy L Thompson sum_2 += v_array[2 * i + 1]; 1405b3ccac8Sjeremylt } 1414fee36f0SJeremy L Thompson CeedVectorRestoreArrayRead(v, &v_array); 1424fee36f0SJeremy L Thompson 1432b730f8bSJeremy L Thompson if (fabs(sum_1 - 1.) > 1000. * CEED_EPSILON) printf("Computed Area: %f != True Area: 1.0\n", sum_1); 1442b730f8bSJeremy L Thompson if (fabs(sum_2 - 2.) > 1000. * CEED_EPSILON) printf("Computed Area: %f != True Area: 2.0\n", sum_2); 1454fee36f0SJeremy L Thompson } 1465b3ccac8Sjeremylt 1474fee36f0SJeremy L Thompson CeedVectorDestroy(&x); 1484fee36f0SJeremy L Thompson CeedVectorDestroy(&u); 1494fee36f0SJeremy L Thompson CeedVectorDestroy(&v); 1504fee36f0SJeremy L Thompson CeedVectorDestroy(&q_data_small); 1514fee36f0SJeremy L Thompson CeedVectorDestroy(&q_data_large); 1524fee36f0SJeremy L Thompson CeedElemRestrictionDestroy(&elem_restriction_u); 1534fee36f0SJeremy L Thompson CeedElemRestrictionDestroy(&elem_restriction_x); 1544fee36f0SJeremy L Thompson CeedElemRestrictionDestroy(&elem_restriction_q_data_small); 1554fee36f0SJeremy L Thompson CeedElemRestrictionDestroy(&elem_restriction_q_data_large); 1564fee36f0SJeremy L Thompson CeedBasisDestroy(&basis_u_small); 1574fee36f0SJeremy L Thompson CeedBasisDestroy(&basis_x_small); 1584fee36f0SJeremy L Thompson CeedBasisDestroy(&basis_u_large); 1594fee36f0SJeremy L Thompson CeedBasisDestroy(&basis_x_large); 1605b3ccac8Sjeremylt CeedQFunctionDestroy(&qf_setup); 1615b3ccac8Sjeremylt CeedQFunctionDestroy(&qf_mass); 1625b3ccac8Sjeremylt CeedOperatorDestroy(&op_setup_small); 1635b3ccac8Sjeremylt CeedOperatorDestroy(&op_mass_small); 1645b3ccac8Sjeremylt CeedOperatorDestroy(&op_setup_large); 1655b3ccac8Sjeremylt CeedOperatorDestroy(&op_mass_large); 1665b3ccac8Sjeremylt CeedDestroy(&ceed); 1675b3ccac8Sjeremylt return 0; 1685b3ccac8Sjeremylt } 169