xref: /libCEED/tests/t553-operator.c (revision d99fa3c5cd91a1690aedf0679cbf290d44fec74c)
1*d99fa3c5SJeremy L Thompson /// @file
2*d99fa3c5SJeremy L Thompson /// Test creation, action, and destruction for mass matrix operator with multigrid level, nontensor basis
3*d99fa3c5SJeremy L Thompson /// \test Test creation, action, and destruction for mass matrix operator with multigrid level, nontensor basis
4*d99fa3c5SJeremy L Thompson #include <ceed.h>
5*d99fa3c5SJeremy L Thompson #include <stdlib.h>
6*d99fa3c5SJeremy L Thompson #include <math.h>
7*d99fa3c5SJeremy L Thompson 
8*d99fa3c5SJeremy L Thompson int main(int argc, char **argv) {
9*d99fa3c5SJeremy L Thompson   Ceed ceed;
10*d99fa3c5SJeremy L Thompson   CeedElemRestriction Erestrictx, Erestrictui,
11*d99fa3c5SJeremy L Thompson                       ErestrictuCoarse, ErestrictuFine;
12*d99fa3c5SJeremy L Thompson   CeedBasis bx, bu;
13*d99fa3c5SJeremy L Thompson   CeedQFunction qf_setup, qf_mass;
14*d99fa3c5SJeremy L Thompson   CeedOperator op_setup, op_massCoarse, op_massFine,
15*d99fa3c5SJeremy L Thompson                op_prolong, op_restrict;
16*d99fa3c5SJeremy L Thompson   CeedVector qdata, X, Ucoarse, Ufine,
17*d99fa3c5SJeremy L Thompson              Vcoarse, Vfine, PMultFine;
18*d99fa3c5SJeremy L Thompson   const CeedScalar *hv;
19*d99fa3c5SJeremy L Thompson   CeedInt nelem = 15, Pcoarse = 3, Pfine = 5, Q = 8;
20*d99fa3c5SJeremy L Thompson   CeedInt Nx = nelem+1, NuCoarse = nelem*(Pcoarse-1)+1,
21*d99fa3c5SJeremy L Thompson           NuFine = nelem*(Pfine-1)+1;
22*d99fa3c5SJeremy L Thompson   CeedInt induCoarse[nelem*Pcoarse], induFine[nelem*Pfine],
23*d99fa3c5SJeremy L Thompson           indx[nelem*2];
24*d99fa3c5SJeremy L Thompson   CeedScalar x[Nx];
25*d99fa3c5SJeremy L Thompson   CeedScalar sum;
26*d99fa3c5SJeremy L Thompson 
27*d99fa3c5SJeremy L Thompson   CeedInit(argv[1], &ceed);
28*d99fa3c5SJeremy L Thompson 
29*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<Nx; i++)
30*d99fa3c5SJeremy L Thompson     x[i] = (CeedScalar) i / (Nx - 1);
31*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<nelem; i++) {
32*d99fa3c5SJeremy L Thompson     indx[2*i+0] = i;
33*d99fa3c5SJeremy L Thompson     indx[2*i+1] = i+1;
34*d99fa3c5SJeremy L Thompson   }
35*d99fa3c5SJeremy L Thompson   // Restrictions
36*d99fa3c5SJeremy L Thompson   CeedElemRestrictionCreate(ceed, nelem, 2, 1, 1, Nx, CEED_MEM_HOST,
37*d99fa3c5SJeremy L Thompson                             CEED_USE_POINTER, indx, &Erestrictx);
38*d99fa3c5SJeremy L Thompson 
39*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<nelem; i++) {
40*d99fa3c5SJeremy L Thompson     for (CeedInt j=0; j<Pcoarse; j++) {
41*d99fa3c5SJeremy L Thompson       induCoarse[Pcoarse*i+j] = i*(Pcoarse-1) + j;
42*d99fa3c5SJeremy L Thompson     }
43*d99fa3c5SJeremy L Thompson   }
44*d99fa3c5SJeremy L Thompson   CeedElemRestrictionCreate(ceed, nelem, Pcoarse, 1, 1, NuCoarse, CEED_MEM_HOST,
45*d99fa3c5SJeremy L Thompson                             CEED_USE_POINTER, induCoarse, &ErestrictuCoarse);
46*d99fa3c5SJeremy L Thompson 
47*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<nelem; i++) {
48*d99fa3c5SJeremy L Thompson     for (CeedInt j=0; j<Pfine; j++) {
49*d99fa3c5SJeremy L Thompson       induFine[Pfine*i+j] = i*(Pfine-1) + j;
50*d99fa3c5SJeremy L Thompson     }
51*d99fa3c5SJeremy L Thompson   }
52*d99fa3c5SJeremy L Thompson   CeedElemRestrictionCreate(ceed, nelem, Pfine, 1, 1, NuFine, CEED_MEM_HOST,
53*d99fa3c5SJeremy L Thompson                             CEED_USE_POINTER, induFine, &ErestrictuFine);
54*d99fa3c5SJeremy L Thompson 
55*d99fa3c5SJeremy L Thompson   CeedInt stridesu[3] = {1, Q, Q};
56*d99fa3c5SJeremy L Thompson   CeedElemRestrictionCreateStrided(ceed, nelem, Q, 1, Q*nelem, stridesu,
57*d99fa3c5SJeremy L Thompson                                    &Erestrictui);
58*d99fa3c5SJeremy L Thompson 
59*d99fa3c5SJeremy L Thompson   // Bases
60*d99fa3c5SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, 2, Q, CEED_GAUSS, &bx);
61*d99fa3c5SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, Pfine, Q, CEED_GAUSS, &bu);
62*d99fa3c5SJeremy L Thompson 
63*d99fa3c5SJeremy L Thompson   // QFunctions
64*d99fa3c5SJeremy L Thompson   CeedQFunctionCreateInteriorByName(ceed, "Mass1DBuild", &qf_setup);
65*d99fa3c5SJeremy L Thompson   CeedQFunctionCreateInteriorByName(ceed, "MassApply", &qf_mass);
66*d99fa3c5SJeremy L Thompson 
67*d99fa3c5SJeremy L Thompson   // Operators
68*d99fa3c5SJeremy L Thompson   CeedOperatorCreate(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE,
69*d99fa3c5SJeremy L Thompson                      &op_setup);
70*d99fa3c5SJeremy L Thompson   CeedOperatorCreate(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE,
71*d99fa3c5SJeremy L Thompson                      &op_massFine);
72*d99fa3c5SJeremy L Thompson 
73*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, Nx, &X);
74*d99fa3c5SJeremy L Thompson   CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x);
75*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, nelem*Q, &qdata);
76*d99fa3c5SJeremy L Thompson 
77*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_setup, "weights", CEED_ELEMRESTRICTION_NONE, bx,
78*d99fa3c5SJeremy L Thompson                        CEED_VECTOR_NONE);
79*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_setup, "dx", Erestrictx, bx, CEED_VECTOR_ACTIVE);
80*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_setup, "qdata", Erestrictui, CEED_BASIS_COLLOCATED,
81*d99fa3c5SJeremy L Thompson                        CEED_VECTOR_ACTIVE);
82*d99fa3c5SJeremy L Thompson 
83*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_massFine, "qdata", Erestrictui, CEED_BASIS_COLLOCATED,
84*d99fa3c5SJeremy L Thompson                        qdata);
85*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_massFine, "u", ErestrictuFine, bu, CEED_VECTOR_ACTIVE);
86*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_massFine, "v", ErestrictuFine, bu, CEED_VECTOR_ACTIVE);
87*d99fa3c5SJeremy L Thompson 
88*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_setup, X, qdata, CEED_REQUEST_IMMEDIATE);
89*d99fa3c5SJeremy L Thompson 
90*d99fa3c5SJeremy L Thompson   // Create multigrid level
91*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, NuFine, &PMultFine);
92*d99fa3c5SJeremy L Thompson   CeedVectorSetValue(PMultFine, 1.0);
93*d99fa3c5SJeremy L Thompson   CeedBasis buCoarse, bCtoF;
94*d99fa3c5SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, Pcoarse, Q, CEED_GAUSS, &buCoarse);
95*d99fa3c5SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, Pcoarse, Pfine, CEED_GAUSS_LOBATTO,
96*d99fa3c5SJeremy L Thompson                                   &bCtoF);
97*d99fa3c5SJeremy L Thompson   const CeedScalar *interpCtoF;
98*d99fa3c5SJeremy L Thompson   CeedBasisGetInterp1D(bCtoF, &interpCtoF);
99*d99fa3c5SJeremy L Thompson   CeedOperatorMultigridLevelCreateH1(op_massFine, PMultFine, ErestrictuCoarse,
100*d99fa3c5SJeremy L Thompson                                      buCoarse, interpCtoF, &op_massCoarse,
101*d99fa3c5SJeremy L Thompson                                      &op_prolong, &op_restrict);
102*d99fa3c5SJeremy L Thompson 
103*d99fa3c5SJeremy L Thompson   // Coarse problem
104*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, NuCoarse, &Ucoarse);
105*d99fa3c5SJeremy L Thompson   CeedVectorSetValue(Ucoarse, 1.0);
106*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, NuCoarse, &Vcoarse);
107*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_massCoarse, Ucoarse, Vcoarse, CEED_REQUEST_IMMEDIATE);
108*d99fa3c5SJeremy L Thompson 
109*d99fa3c5SJeremy L Thompson   // Check output
110*d99fa3c5SJeremy L Thompson   CeedVectorGetArrayRead(Vcoarse, CEED_MEM_HOST, &hv);
111*d99fa3c5SJeremy L Thompson   sum = 0.;
112*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<NuCoarse; i++) {
113*d99fa3c5SJeremy L Thompson     sum += hv[i];
114*d99fa3c5SJeremy L Thompson   }
115*d99fa3c5SJeremy L Thompson   if (fabs(sum-1.)>1e-10)
116*d99fa3c5SJeremy L Thompson     // LCOV_EXCL_START
117*d99fa3c5SJeremy L Thompson     printf("Computed Area Coarse Grid: %f != True Area: 1.0\n", sum);
118*d99fa3c5SJeremy L Thompson   // LCOV_EXCL_STOP
119*d99fa3c5SJeremy L Thompson   CeedVectorRestoreArrayRead(Vcoarse, &hv);
120*d99fa3c5SJeremy L Thompson 
121*d99fa3c5SJeremy L Thompson   // Prolong coarse u
122*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, NuFine, &Ufine);
123*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_prolong, Ucoarse, Ufine, CEED_REQUEST_IMMEDIATE);
124*d99fa3c5SJeremy L Thompson 
125*d99fa3c5SJeremy L Thompson   // Fine problem
126*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, NuFine, &Vfine);
127*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_massFine, Ufine, Vfine, CEED_REQUEST_IMMEDIATE);
128*d99fa3c5SJeremy L Thompson 
129*d99fa3c5SJeremy L Thompson   // Check output
130*d99fa3c5SJeremy L Thompson   CeedVectorGetArrayRead(Vfine, CEED_MEM_HOST, &hv);
131*d99fa3c5SJeremy L Thompson   sum = 0.;
132*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<NuFine; i++) {
133*d99fa3c5SJeremy L Thompson     sum += hv[i];
134*d99fa3c5SJeremy L Thompson   }
135*d99fa3c5SJeremy L Thompson   if (fabs(sum-1.)>1e-10)
136*d99fa3c5SJeremy L Thompson     // LCOV_EXCL_START
137*d99fa3c5SJeremy L Thompson     printf("Computed Area Fine Grid: %f != True Area: 1.0\n", sum);
138*d99fa3c5SJeremy L Thompson   // LCOV_EXCL_STOP
139*d99fa3c5SJeremy L Thompson   CeedVectorRestoreArrayRead(Vfine, &hv);
140*d99fa3c5SJeremy L Thompson 
141*d99fa3c5SJeremy L Thompson   // Restrict state to coarse grid
142*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_restrict, Vfine, Vcoarse, CEED_REQUEST_IMMEDIATE);
143*d99fa3c5SJeremy L Thompson 
144*d99fa3c5SJeremy L Thompson   // Check output
145*d99fa3c5SJeremy L Thompson   CeedVectorGetArrayRead(Vcoarse, CEED_MEM_HOST, &hv);
146*d99fa3c5SJeremy L Thompson   sum = 0.;
147*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<NuCoarse; i++) {
148*d99fa3c5SJeremy L Thompson     sum += hv[i];
149*d99fa3c5SJeremy L Thompson   }
150*d99fa3c5SJeremy L Thompson   if (fabs(sum-1.)>1e-10)
151*d99fa3c5SJeremy L Thompson     // LCOV_EXCL_START
152*d99fa3c5SJeremy L Thompson     printf("Computed Area Coarse Grid: %f != True Area: 1.0\n", sum);
153*d99fa3c5SJeremy L Thompson   // LCOV_EXCL_STOP
154*d99fa3c5SJeremy L Thompson   CeedVectorRestoreArrayRead(Vcoarse, &hv);
155*d99fa3c5SJeremy L Thompson 
156*d99fa3c5SJeremy L Thompson   // Cleanup
157*d99fa3c5SJeremy L Thompson   CeedQFunctionDestroy(&qf_setup);
158*d99fa3c5SJeremy L Thompson   CeedQFunctionDestroy(&qf_mass);
159*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_setup);
160*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_massCoarse);
161*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_massFine);
162*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_prolong);
163*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_restrict);
164*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&ErestrictuCoarse);
165*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&ErestrictuFine);
166*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&Erestrictx);
167*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&Erestrictui);
168*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bu);
169*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&buCoarse);
170*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bCtoF);
171*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bx);
172*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&X);
173*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Ucoarse);
174*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Ufine);
175*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Vcoarse);
176*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Vfine);
177*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&PMultFine);
178*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&qdata);
179*d99fa3c5SJeremy L Thompson   CeedDestroy(&ceed);
180*d99fa3c5SJeremy L Thompson   return 0;
181*d99fa3c5SJeremy L Thompson }
182