152d6035fSJeremy L Thompson /// @file 26227f746SJeremy L Thompson /// Test creation, action, and destruction for composite mass matrix operator 36227f746SJeremy L Thompson /// \test Test creation, action, and destruction for composite mass matrix operator 452d6035fSJeremy L Thompson #include <ceed.h> 552d6035fSJeremy L Thompson #include <math.h> 6*2b730f8bSJeremy L Thompson #include <stdlib.h> 7*2b730f8bSJeremy L Thompson 852bfb9bbSJeremy L Thompson #include "t320-basis.h" 9a05f9790Sjeremylt #include "t510-operator.h" 104d537eeaSYohann 1152d6035fSJeremy L Thompson /* The mesh comprises of two rows of 3 quadralaterals followed by one row 1252d6035fSJeremy L Thompson of 6 triangles: 1352d6035fSJeremy L Thompson _ _ _ 1452d6035fSJeremy L Thompson |_|_|_| 1552d6035fSJeremy L Thompson |_|_|_| 1652d6035fSJeremy L Thompson |/|/|/| 1752d6035fSJeremy L Thompson 1852d6035fSJeremy L Thompson */ 1952d6035fSJeremy L Thompson 2052d6035fSJeremy L Thompson int main(int argc, char **argv) { 2152d6035fSJeremy L Thompson Ceed ceed; 22*2b730f8bSJeremy L Thompson CeedElemRestriction elem_restr_x_tet, elem_restr_u_tet, elem_restr_qd_i_tet, elem_restr_x_hex, elem_restr_u_hex, elem_restr_qd_i_hex; 23*2b730f8bSJeremy L Thompson CeedBasis basis_x_tet, basis_u_tet, basis_x_hex, basis_u_hex; 24*2b730f8bSJeremy L Thompson CeedQFunction qf_setup_tet, qf_mass_tet, qf_setup_hex, qf_mass_hex; 25*2b730f8bSJeremy L Thompson CeedOperator op_setup_tet, op_mass_tet, op_setup_hex, op_mass_hex, op_setup, op_mass; 26d1d35e2fSjeremylt CeedVector q_data_tet, q_data_hex, X, U, V; 2752d6035fSJeremy L Thompson const CeedScalar *hv; 28*2b730f8bSJeremy L Thompson CeedInt num_elem_tet = 6, P_tet = 6, Q_tet = 4, num_elem_hex = 6, P_hex = 3, Q_hex = 4, dim = 2; 29*2b730f8bSJeremy L Thompson CeedInt n_x = 3, n_y = 3, n_x_tet = 3, n_y_tet = 1, n_x_hex = 3; 3052d6035fSJeremy L Thompson CeedInt row, col, offset; 31*2b730f8bSJeremy L Thompson CeedInt num_dofs = (n_x * 2 + 1) * (n_y * 2 + 1), num_qpts_tet = num_elem_tet * Q_tet, num_qpts_hex = num_elem_hex * Q_hex * Q_hex; 32*2b730f8bSJeremy L Thompson CeedInt ind_x_tet[num_elem_tet * P_tet], ind_x_hex[num_elem_hex * P_hex * P_hex]; 33d1d35e2fSjeremylt CeedScalar x[dim * num_dofs]; 34d1d35e2fSjeremylt CeedScalar q_ref[dim * Q_tet], q_weight[Q_tet]; 35d1d35e2fSjeremylt CeedScalar interp[P_tet * Q_tet], grad[dim * P_tet * Q_tet]; 3652d6035fSJeremy L Thompson 3752d6035fSJeremy L Thompson CeedInit(argv[1], &ceed); 3852d6035fSJeremy L Thompson 3952d6035fSJeremy L Thompson // DoF Coordinates 40*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < n_y * 2 + 1; i++) { 41d1d35e2fSjeremylt for (CeedInt j = 0; j < n_x * 2 + 1; j++) { 42d1d35e2fSjeremylt x[i + j * (n_y * 2 + 1) + 0 * num_dofs] = (CeedScalar)i / (2 * n_y); 43d1d35e2fSjeremylt x[i + j * (n_y * 2 + 1) + 1 * num_dofs] = (CeedScalar)j / (2 * n_x); 4452d6035fSJeremy L Thompson } 45*2b730f8bSJeremy L Thompson } 46d1d35e2fSjeremylt CeedVectorCreate(ceed, dim * num_dofs, &X); 4752d6035fSJeremy L Thompson CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x); 4852d6035fSJeremy L Thompson 4952d6035fSJeremy L Thompson // Qdata Vectors 50d1d35e2fSjeremylt CeedVectorCreate(ceed, num_qpts_tet, &q_data_tet); 51d1d35e2fSjeremylt CeedVectorCreate(ceed, num_qpts_hex, &q_data_hex); 5252d6035fSJeremy L Thompson 5352d6035fSJeremy L Thompson // Set up Tet Elements 54d1d35e2fSjeremylt for (CeedInt i = 0; i < num_elem_tet / 2; i++) { 55d1d35e2fSjeremylt col = i % n_x_tet; 56d1d35e2fSjeremylt row = i / n_x_tet; 57d1d35e2fSjeremylt offset = col * 2 + row * (n_x_tet * 2 + 1) * 2; 5852d6035fSJeremy L Thompson 59d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 0] = 2 + offset; 60d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 1] = 9 + offset; 61d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 2] = 16 + offset; 62d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 3] = 1 + offset; 63d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 4] = 8 + offset; 64d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 5] = 0 + offset; 6552d6035fSJeremy L Thompson 66d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 6] = 14 + offset; 67d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 7] = 7 + offset; 68d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 8] = 0 + offset; 69d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 9] = 15 + offset; 70d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 10] = 8 + offset; 71d1d35e2fSjeremylt ind_x_tet[i * 2 * P_tet + 11] = 16 + offset; 7252d6035fSJeremy L Thompson } 7352d6035fSJeremy L Thompson 7452d6035fSJeremy L Thompson // -- Restrictions 75*2b730f8bSJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem_tet, P_tet, dim, num_dofs, dim * num_dofs, CEED_MEM_HOST, CEED_USE_POINTER, ind_x_tet, &elem_restr_x_tet); 7652d6035fSJeremy L Thompson 77*2b730f8bSJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem_tet, P_tet, 1, 1, num_dofs, CEED_MEM_HOST, CEED_USE_POINTER, ind_x_tet, &elem_restr_u_tet); 78d1d35e2fSjeremylt CeedInt strides_qd_tet[3] = {1, Q_tet, Q_tet}; 79*2b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem_tet, Q_tet, 1, num_qpts_tet, strides_qd_tet, &elem_restr_qd_i_tet); 8052d6035fSJeremy L Thompson 8152d6035fSJeremy L Thompson // -- Bases 82d1d35e2fSjeremylt buildmats(q_ref, q_weight, interp, grad); 83*2b730f8bSJeremy L Thompson CeedBasisCreateH1(ceed, CEED_TOPOLOGY_TRIANGLE, dim, P_tet, Q_tet, interp, grad, q_ref, q_weight, &basis_x_tet); 8452d6035fSJeremy L Thompson 85d1d35e2fSjeremylt buildmats(q_ref, q_weight, interp, grad); 86*2b730f8bSJeremy L Thompson CeedBasisCreateH1(ceed, CEED_TOPOLOGY_TRIANGLE, 1, P_tet, Q_tet, interp, grad, q_ref, q_weight, &basis_u_tet); 8752d6035fSJeremy L Thompson 8852d6035fSJeremy L Thompson // -- QFunctions 89d1d35e2fSjeremylt CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_setup_tet); 90d1d35e2fSjeremylt CeedQFunctionAddInput(qf_setup_tet, "_weight", 1, CEED_EVAL_WEIGHT); 91d1d35e2fSjeremylt CeedQFunctionAddInput(qf_setup_tet, "dx", dim * dim, CEED_EVAL_GRAD); 92d1d35e2fSjeremylt CeedQFunctionAddOutput(qf_setup_tet, "rho", 1, CEED_EVAL_NONE); 9352d6035fSJeremy L Thompson 94d1d35e2fSjeremylt CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_mass_tet); 95d1d35e2fSjeremylt CeedQFunctionAddInput(qf_mass_tet, "rho", 1, CEED_EVAL_NONE); 96d1d35e2fSjeremylt CeedQFunctionAddInput(qf_mass_tet, "u", 1, CEED_EVAL_INTERP); 97d1d35e2fSjeremylt CeedQFunctionAddOutput(qf_mass_tet, "v", 1, CEED_EVAL_INTERP); 9852d6035fSJeremy L Thompson 9952d6035fSJeremy L Thompson // -- Operators 10052d6035fSJeremy L Thompson // ---- Setup Tet 101*2b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_tet, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_tet); 102*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_tet, "_weight", CEED_ELEMRESTRICTION_NONE, basis_x_tet, CEED_VECTOR_NONE); 103*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_tet, "dx", elem_restr_x_tet, basis_x_tet, CEED_VECTOR_ACTIVE); 104*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_tet, "rho", elem_restr_qd_i_tet, CEED_BASIS_COLLOCATED, q_data_tet); 10552d6035fSJeremy L Thompson // ---- Mass Tet 106*2b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_mass_tet, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_mass_tet); 107*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_mass_tet, "rho", elem_restr_qd_i_tet, CEED_BASIS_COLLOCATED, q_data_tet); 108*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_mass_tet, "u", elem_restr_u_tet, basis_u_tet, CEED_VECTOR_ACTIVE); 109*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_mass_tet, "v", elem_restr_u_tet, basis_u_tet, CEED_VECTOR_ACTIVE); 11052d6035fSJeremy L Thompson 11152d6035fSJeremy L Thompson // Set up Hex Elements 112d1d35e2fSjeremylt for (CeedInt i = 0; i < num_elem_hex; i++) { 113d1d35e2fSjeremylt col = i % n_x_hex; 114d1d35e2fSjeremylt row = i / n_x_hex; 115d1d35e2fSjeremylt offset = (n_x_tet * 2 + 1) * (n_y_tet * 2) * (1 + row) + col * 2; 116*2b730f8bSJeremy L Thompson for (CeedInt j = 0; j < P_hex; j++) { 117*2b730f8bSJeremy L Thompson for (CeedInt k = 0; k < P_hex; k++) ind_x_hex[P_hex * (P_hex * i + k) + j] = offset + k * (n_x_hex * 2 + 1) + j; 118*2b730f8bSJeremy L Thompson } 11952d6035fSJeremy L Thompson } 12052d6035fSJeremy L Thompson 12152d6035fSJeremy L Thompson // -- Restrictions 122*2b730f8bSJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem_hex, P_hex * P_hex, dim, num_dofs, dim * num_dofs, CEED_MEM_HOST, CEED_USE_POINTER, ind_x_hex, 123d1d35e2fSjeremylt &elem_restr_x_hex); 12452d6035fSJeremy L Thompson 125*2b730f8bSJeremy L Thompson CeedElemRestrictionCreate(ceed, num_elem_hex, P_hex * P_hex, 1, 1, num_dofs, CEED_MEM_HOST, CEED_USE_POINTER, ind_x_hex, &elem_restr_u_hex); 126d1d35e2fSjeremylt CeedInt strides_qd_hex[3] = {1, Q_hex * Q_hex, Q_hex * Q_hex}; 127*2b730f8bSJeremy L Thompson CeedElemRestrictionCreateStrided(ceed, num_elem_hex, Q_hex * Q_hex, 1, num_qpts_hex, strides_qd_hex, &elem_restr_qd_i_hex); 12852d6035fSJeremy L Thompson 12952d6035fSJeremy L Thompson // -- Bases 130*2b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, dim, P_hex, Q_hex, CEED_GAUSS, &basis_x_hex); 131*2b730f8bSJeremy L Thompson CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, P_hex, Q_hex, CEED_GAUSS, &basis_u_hex); 13252d6035fSJeremy L Thompson 13352d6035fSJeremy L Thompson // -- QFunctions 134d1d35e2fSjeremylt CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_setup_hex); 135a61c78d6SJeremy L Thompson CeedQFunctionAddInput(qf_setup_hex, "weight", 1, CEED_EVAL_WEIGHT); 136d1d35e2fSjeremylt CeedQFunctionAddInput(qf_setup_hex, "dx", dim * dim, CEED_EVAL_GRAD); 137d1d35e2fSjeremylt CeedQFunctionAddOutput(qf_setup_hex, "rho", 1, CEED_EVAL_NONE); 13852d6035fSJeremy L Thompson 139d1d35e2fSjeremylt CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_mass_hex); 140d1d35e2fSjeremylt CeedQFunctionAddInput(qf_mass_hex, "rho", 1, CEED_EVAL_NONE); 141d1d35e2fSjeremylt CeedQFunctionAddInput(qf_mass_hex, "u", 1, CEED_EVAL_INTERP); 142d1d35e2fSjeremylt CeedQFunctionAddOutput(qf_mass_hex, "v", 1, CEED_EVAL_INTERP); 14352d6035fSJeremy L Thompson 14452d6035fSJeremy L Thompson // -- Operators 145*2b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_setup_hex, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup_hex); 146*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_hex, "weight", CEED_ELEMRESTRICTION_NONE, basis_x_hex, CEED_VECTOR_NONE); 147*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_hex, "dx", elem_restr_x_hex, basis_x_hex, CEED_VECTOR_ACTIVE); 148*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_setup_hex, "rho", elem_restr_qd_i_hex, CEED_BASIS_COLLOCATED, q_data_hex); 14952d6035fSJeremy L Thompson 150*2b730f8bSJeremy L Thompson CeedOperatorCreate(ceed, qf_mass_hex, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_mass_hex); 151*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_mass_hex, "rho", elem_restr_qd_i_hex, CEED_BASIS_COLLOCATED, q_data_hex); 152*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_mass_hex, "u", elem_restr_u_hex, basis_u_hex, CEED_VECTOR_ACTIVE); 153*2b730f8bSJeremy L Thompson CeedOperatorSetField(op_mass_hex, "v", elem_restr_u_hex, basis_u_hex, CEED_VECTOR_ACTIVE); 15452d6035fSJeremy L Thompson 15552d6035fSJeremy L Thompson // Set up Composite Operators 15652d6035fSJeremy L Thompson // -- Create 15752d6035fSJeremy L Thompson CeedCompositeOperatorCreate(ceed, &op_setup); 15852d6035fSJeremy L Thompson // -- Add SubOperators 159d1d35e2fSjeremylt CeedCompositeOperatorAddSub(op_setup, op_setup_tet); 160d1d35e2fSjeremylt CeedCompositeOperatorAddSub(op_setup, op_setup_hex); 16152d6035fSJeremy L Thompson 16252d6035fSJeremy L Thompson // -- Create 16352d6035fSJeremy L Thompson CeedCompositeOperatorCreate(ceed, &op_mass); 16452d6035fSJeremy L Thompson // -- Add SubOperators 165d1d35e2fSjeremylt CeedCompositeOperatorAddSub(op_mass, op_mass_tet); 166d1d35e2fSjeremylt CeedCompositeOperatorAddSub(op_mass, op_mass_hex); 16752d6035fSJeremy L Thompson 16852d6035fSJeremy L Thompson // Apply Setup Operator 169e97ff134Sjeremylt CeedOperatorApply(op_setup, X, CEED_VECTOR_NONE, CEED_REQUEST_IMMEDIATE); 17052d6035fSJeremy L Thompson 17152d6035fSJeremy L Thompson // Apply Mass Operator 172d1d35e2fSjeremylt CeedVectorCreate(ceed, num_dofs, &U); 17352d6035fSJeremy L Thompson CeedVectorSetValue(U, 0.0); 174d1d35e2fSjeremylt CeedVectorCreate(ceed, num_dofs, &V); 17552d6035fSJeremy L Thompson 17652d6035fSJeremy L Thompson CeedOperatorApply(op_mass, U, V, CEED_REQUEST_IMMEDIATE); 17752d6035fSJeremy L Thompson 17852d6035fSJeremy L Thompson // Check output 17952d6035fSJeremy L Thompson CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv); 180*2b730f8bSJeremy L Thompson for (CeedInt i = 0; i < num_dofs; i++) { 181600b7929SJeremy L Thompson if (fabs(hv[i]) > 1e-14) printf("[%" CeedInt_FMT "] v %g != 0.0\n", i, hv[i]); 182*2b730f8bSJeremy L Thompson } 18352d6035fSJeremy L Thompson CeedVectorRestoreArrayRead(V, &hv); 18452d6035fSJeremy L Thompson 18552d6035fSJeremy L Thompson // Cleanup 186d1d35e2fSjeremylt CeedQFunctionDestroy(&qf_setup_tet); 187d1d35e2fSjeremylt CeedQFunctionDestroy(&qf_mass_tet); 188d1d35e2fSjeremylt CeedOperatorDestroy(&op_setup_tet); 189d1d35e2fSjeremylt CeedOperatorDestroy(&op_mass_tet); 190d1d35e2fSjeremylt CeedQFunctionDestroy(&qf_setup_hex); 191d1d35e2fSjeremylt CeedQFunctionDestroy(&qf_mass_hex); 192d1d35e2fSjeremylt CeedOperatorDestroy(&op_setup_hex); 193d1d35e2fSjeremylt CeedOperatorDestroy(&op_mass_hex); 19452d6035fSJeremy L Thompson CeedOperatorDestroy(&op_setup); 19552d6035fSJeremy L Thompson CeedOperatorDestroy(&op_mass); 196d1d35e2fSjeremylt CeedElemRestrictionDestroy(&elem_restr_u_tet); 197d1d35e2fSjeremylt CeedElemRestrictionDestroy(&elem_restr_x_tet); 198d1d35e2fSjeremylt CeedElemRestrictionDestroy(&elem_restr_qd_i_tet); 199d1d35e2fSjeremylt CeedElemRestrictionDestroy(&elem_restr_u_hex); 200d1d35e2fSjeremylt CeedElemRestrictionDestroy(&elem_restr_x_hex); 201d1d35e2fSjeremylt CeedElemRestrictionDestroy(&elem_restr_qd_i_hex); 202d1d35e2fSjeremylt CeedBasisDestroy(&basis_u_tet); 203d1d35e2fSjeremylt CeedBasisDestroy(&basis_x_tet); 204d1d35e2fSjeremylt CeedBasisDestroy(&basis_u_hex); 205d1d35e2fSjeremylt CeedBasisDestroy(&basis_x_hex); 20652d6035fSJeremy L Thompson CeedVectorDestroy(&X); 20752d6035fSJeremy L Thompson CeedVectorDestroy(&U); 20852d6035fSJeremy L Thompson CeedVectorDestroy(&V); 209d1d35e2fSjeremylt CeedVectorDestroy(&q_data_tet); 210d1d35e2fSjeremylt CeedVectorDestroy(&q_data_hex); 21152d6035fSJeremy L Thompson CeedDestroy(&ceed); 21252d6035fSJeremy L Thompson return 0; 21352d6035fSJeremy L Thompson } 214