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