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