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