xref: /libCEED/tests/t505-operator.c (revision 2b730f8b5a9c809740a0b3b302db43a719c636b1)
1cae8b89aSjeremylt /// @file
2cae8b89aSjeremylt /// Test CeedOperatorApplyAdd
3cae8b89aSjeremylt /// \test Test CeedOperatorApplyAdd
4cae8b89aSjeremylt #include <ceed.h>
5cae8b89aSjeremylt #include <math.h>
6*2b730f8bSJeremy L Thompson #include <stdlib.h>
7cae8b89aSjeremylt 
8cae8b89aSjeremylt #include "t500-operator.h"
9cae8b89aSjeremylt 
10cae8b89aSjeremylt int main(int argc, char **argv) {
11cae8b89aSjeremylt   Ceed                ceed;
12d1d35e2fSjeremylt   CeedElemRestriction elem_restr_x, elem_restr_u, elem_restr_qd_i;
13d1d35e2fSjeremylt   CeedBasis           basis_x, basis_u;
14cae8b89aSjeremylt   CeedQFunction       qf_setup, qf_mass;
15cae8b89aSjeremylt   CeedOperator        op_setup, op_mass;
16d1d35e2fSjeremylt   CeedVector          q_data, X, U, V;
17cae8b89aSjeremylt   const CeedScalar   *hv;
18d1d35e2fSjeremylt   CeedInt             num_elem = 15, P = 5, Q = 8;
19d1d35e2fSjeremylt   CeedInt             num_nodes_x = num_elem + 1, num_nodes_u = num_elem * (P - 1) + 1;
20d1d35e2fSjeremylt   CeedInt             ind_x[num_elem * 2], ind_u[num_elem * P];
21d1d35e2fSjeremylt   CeedScalar          x[num_nodes_x];
22cae8b89aSjeremylt   CeedScalar          sum;
23cae8b89aSjeremylt 
24cae8b89aSjeremylt   CeedInit(argv[1], &ceed);
25cae8b89aSjeremylt 
26*2b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < num_nodes_x; i++) x[i] = (CeedScalar)i / (num_nodes_x - 1);
27d1d35e2fSjeremylt   for (CeedInt i = 0; i < num_elem; i++) {
28d1d35e2fSjeremylt     ind_x[2 * i + 0] = i;
29d1d35e2fSjeremylt     ind_x[2 * i + 1] = i + 1;
30cae8b89aSjeremylt   }
31cae8b89aSjeremylt   // Restrictions
32*2b730f8bSJeremy L Thompson   CeedElemRestrictionCreate(ceed, num_elem, 2, 1, 1, num_nodes_x, CEED_MEM_HOST, CEED_USE_POINTER, ind_x, &elem_restr_x);
3315910d16Sjeremylt 
34d1d35e2fSjeremylt   for (CeedInt i = 0; i < num_elem; i++) {
35cae8b89aSjeremylt     for (CeedInt j = 0; j < P; j++) {
36d1d35e2fSjeremylt       ind_u[P * i + j] = i * (P - 1) + j;
37cae8b89aSjeremylt     }
38cae8b89aSjeremylt   }
39*2b730f8bSJeremy L Thompson   CeedElemRestrictionCreate(ceed, num_elem, P, 1, 1, num_nodes_u, CEED_MEM_HOST, CEED_USE_POINTER, ind_u, &elem_restr_u);
40d1d35e2fSjeremylt   CeedInt strides_qd[3] = {1, Q, Q};
41*2b730f8bSJeremy L Thompson   CeedElemRestrictionCreateStrided(ceed, num_elem, Q, 1, Q * num_elem, strides_qd, &elem_restr_qd_i);
42cae8b89aSjeremylt 
43cae8b89aSjeremylt   // Bases
44d1d35e2fSjeremylt   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, 2, Q, CEED_GAUSS, &basis_x);
45d1d35e2fSjeremylt   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, P, Q, CEED_GAUSS, &basis_u);
46cae8b89aSjeremylt 
47cae8b89aSjeremylt   // QFunctions
48cae8b89aSjeremylt   CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_setup);
49a61c78d6SJeremy L Thompson   CeedQFunctionAddInput(qf_setup, "weight", 1, CEED_EVAL_WEIGHT);
50cae8b89aSjeremylt   CeedQFunctionAddInput(qf_setup, "dx", 1, CEED_EVAL_GRAD);
51cae8b89aSjeremylt   CeedQFunctionAddOutput(qf_setup, "rho", 1, CEED_EVAL_NONE);
52cae8b89aSjeremylt 
53cae8b89aSjeremylt   CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_mass);
54cae8b89aSjeremylt   CeedQFunctionAddInput(qf_mass, "rho", 1, CEED_EVAL_NONE);
55cae8b89aSjeremylt   CeedQFunctionAddInput(qf_mass, "u", 1, CEED_EVAL_INTERP);
56cae8b89aSjeremylt   CeedQFunctionAddOutput(qf_mass, "v", 1, CEED_EVAL_INTERP);
57cae8b89aSjeremylt 
58cae8b89aSjeremylt   // Operators
59*2b730f8bSJeremy L Thompson   CeedOperatorCreate(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup);
60cae8b89aSjeremylt 
61*2b730f8bSJeremy L Thompson   CeedOperatorCreate(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_mass);
62cae8b89aSjeremylt 
63d1d35e2fSjeremylt   CeedVectorCreate(ceed, num_nodes_x, &X);
64cae8b89aSjeremylt   CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x);
65d1d35e2fSjeremylt   CeedVectorCreate(ceed, num_elem * Q, &q_data);
66cae8b89aSjeremylt 
67*2b730f8bSJeremy L Thompson   CeedOperatorSetField(op_setup, "weight", CEED_ELEMRESTRICTION_NONE, basis_x, CEED_VECTOR_NONE);
68d1d35e2fSjeremylt   CeedOperatorSetField(op_setup, "dx", elem_restr_x, basis_x, CEED_VECTOR_ACTIVE);
69*2b730f8bSJeremy L Thompson   CeedOperatorSetField(op_setup, "rho", elem_restr_qd_i, CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE);
70cae8b89aSjeremylt 
71*2b730f8bSJeremy L Thompson   CeedOperatorSetField(op_mass, "rho", elem_restr_qd_i, CEED_BASIS_COLLOCATED, q_data);
72d1d35e2fSjeremylt   CeedOperatorSetField(op_mass, "u", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE);
73d1d35e2fSjeremylt   CeedOperatorSetField(op_mass, "v", elem_restr_u, basis_u, CEED_VECTOR_ACTIVE);
74cae8b89aSjeremylt 
75d1d35e2fSjeremylt   CeedOperatorApply(op_setup, X, q_data, CEED_REQUEST_IMMEDIATE);
76cae8b89aSjeremylt 
77d1d35e2fSjeremylt   CeedVectorCreate(ceed, num_nodes_u, &U);
78cae8b89aSjeremylt   CeedVectorSetValue(U, 1.0);
79d1d35e2fSjeremylt   CeedVectorCreate(ceed, num_nodes_u, &V);
80cae8b89aSjeremylt   CeedVectorSetValue(V, 0.0);
81cae8b89aSjeremylt 
82cae8b89aSjeremylt   // Apply with V = 0
83cae8b89aSjeremylt   CeedOperatorApplyAdd(op_mass, U, V, CEED_REQUEST_IMMEDIATE);
84cae8b89aSjeremylt 
85cae8b89aSjeremylt   // Check output
86cae8b89aSjeremylt   CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv);
87cae8b89aSjeremylt   sum = 0.;
88*2b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < num_nodes_u; i++) sum += hv[i];
89*2b730f8bSJeremy L Thompson   if (fabs(sum - 1.) > 1000. * CEED_EPSILON) printf("Computed Area: %f != True Area: 1.0\n", sum);
90cae8b89aSjeremylt   CeedVectorRestoreArrayRead(V, &hv);
91cae8b89aSjeremylt 
92cae8b89aSjeremylt   // Apply with V = 1
93cae8b89aSjeremylt   CeedVectorSetValue(V, 1.0);
94cae8b89aSjeremylt   CeedOperatorApplyAdd(op_mass, U, V, CEED_REQUEST_IMMEDIATE);
95cae8b89aSjeremylt 
96cae8b89aSjeremylt   // Check output
97cae8b89aSjeremylt   CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv);
98d1d35e2fSjeremylt   sum = -num_nodes_u;
99*2b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < num_nodes_u; i++) sum += hv[i];
100*2b730f8bSJeremy L Thompson   if (fabs(sum - (1.)) > 1000. * CEED_EPSILON) printf("Computed Area: %f != True Area: 1.0\n", sum);
101cae8b89aSjeremylt   CeedVectorRestoreArrayRead(V, &hv);
102cae8b89aSjeremylt 
103cae8b89aSjeremylt   CeedQFunctionDestroy(&qf_setup);
104cae8b89aSjeremylt   CeedQFunctionDestroy(&qf_mass);
105cae8b89aSjeremylt   CeedOperatorDestroy(&op_setup);
106cae8b89aSjeremylt   CeedOperatorDestroy(&op_mass);
107d1d35e2fSjeremylt   CeedElemRestrictionDestroy(&elem_restr_u);
108d1d35e2fSjeremylt   CeedElemRestrictionDestroy(&elem_restr_x);
109d1d35e2fSjeremylt   CeedElemRestrictionDestroy(&elem_restr_qd_i);
110d1d35e2fSjeremylt   CeedBasisDestroy(&basis_u);
111d1d35e2fSjeremylt   CeedBasisDestroy(&basis_x);
112cae8b89aSjeremylt   CeedVectorDestroy(&X);
113cae8b89aSjeremylt   CeedVectorDestroy(&U);
114cae8b89aSjeremylt   CeedVectorDestroy(&V);
115d1d35e2fSjeremylt   CeedVectorDestroy(&q_data);
116cae8b89aSjeremylt   CeedDestroy(&ceed);
117cae8b89aSjeremylt   return 0;
118cae8b89aSjeremylt }
119