xref: /libCEED/tests/t551-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, non-tensor basis and interpolation basis generation
3*d99fa3c5SJeremy L Thompson /// \test Test creation, action, and destruction for mass matrix operator with multigrid level, non-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, bTemp, 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                                   &bTemp);
67*d99fa3c5SJeremy L Thompson   const CeedScalar *interp, *grad, *qref, *qweight;
68*d99fa3c5SJeremy L Thompson   CeedBasisGetInterp1D(bTemp, &interp);
69*d99fa3c5SJeremy L Thompson   CeedBasisGetGrad1D(bTemp, &grad);
70*d99fa3c5SJeremy L Thompson   CeedBasisGetQRef(bTemp, &qref);
71*d99fa3c5SJeremy L Thompson   CeedBasisGetQWeights(bTemp, &qweight);
72*d99fa3c5SJeremy L Thompson   CeedBasisCreateH1(ceed, CEED_LINE, ncomp, Pcoarse, Q, interp, grad, qref,
73*d99fa3c5SJeremy L Thompson                     qweight, &bCoarse);
74*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bTemp);
75*d99fa3c5SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, 1, ncomp, Pfine, Q, CEED_GAUSS, &bTemp);
76*d99fa3c5SJeremy L Thompson   CeedBasisGetInterp1D(bTemp, &interp);
77*d99fa3c5SJeremy L Thompson   CeedBasisGetGrad1D(bTemp, &grad);
78*d99fa3c5SJeremy L Thompson   CeedBasisGetQRef(bTemp, &qref);
79*d99fa3c5SJeremy L Thompson   CeedBasisGetQWeights(bTemp, &qweight);
80*d99fa3c5SJeremy L Thompson   CeedBasisCreateH1(ceed, CEED_LINE, ncomp, Pfine, Q, interp, grad, qref,
81*d99fa3c5SJeremy L Thompson                     qweight, &bFine);
82*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bTemp);
83*d99fa3c5SJeremy L Thompson 
84*d99fa3c5SJeremy L Thompson   // QFunctions
85*d99fa3c5SJeremy L Thompson   CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_setup);
86*d99fa3c5SJeremy L Thompson   CeedQFunctionAddInput(qf_setup, "weights", 1, CEED_EVAL_WEIGHT);
87*d99fa3c5SJeremy L Thompson   CeedQFunctionAddInput(qf_setup, "dx", 1*1, CEED_EVAL_GRAD);
88*d99fa3c5SJeremy L Thompson   CeedQFunctionAddOutput(qf_setup, "qdata", 1, CEED_EVAL_NONE);
89*d99fa3c5SJeremy L Thompson 
90*d99fa3c5SJeremy L Thompson   CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_mass);
91*d99fa3c5SJeremy L Thompson   CeedQFunctionAddInput(qf_mass, "qdata", 1, CEED_EVAL_NONE);
92*d99fa3c5SJeremy L Thompson   CeedQFunctionAddInput(qf_mass, "u", ncomp, CEED_EVAL_INTERP);
93*d99fa3c5SJeremy L Thompson   CeedQFunctionAddOutput(qf_mass, "v", ncomp, CEED_EVAL_INTERP);
94*d99fa3c5SJeremy L Thompson 
95*d99fa3c5SJeremy L Thompson   // Operators
96*d99fa3c5SJeremy L Thompson   CeedOperatorCreate(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE,
97*d99fa3c5SJeremy L Thompson                      &op_setup);
98*d99fa3c5SJeremy L Thompson   CeedOperatorCreate(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE,
99*d99fa3c5SJeremy L Thompson                      &op_massFine);
100*d99fa3c5SJeremy L Thompson 
101*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, Nx, &X);
102*d99fa3c5SJeremy L Thompson   CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x);
103*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, nelem*Q, &qdata);
104*d99fa3c5SJeremy L Thompson 
105*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_setup, "weights", CEED_ELEMRESTRICTION_NONE, bx,
106*d99fa3c5SJeremy L Thompson                        CEED_VECTOR_NONE);
107*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_setup, "dx", Erestrictx, bx, CEED_VECTOR_ACTIVE);
108*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_setup, "qdata", Erestrictui, CEED_BASIS_COLLOCATED,
109*d99fa3c5SJeremy L Thompson                        CEED_VECTOR_ACTIVE);
110*d99fa3c5SJeremy L Thompson 
111*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_massFine, "qdata", Erestrictui, CEED_BASIS_COLLOCATED,
112*d99fa3c5SJeremy L Thompson                        qdata);
113*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_massFine, "u", ErestrictuFine, bFine,
114*d99fa3c5SJeremy L Thompson                        CEED_VECTOR_ACTIVE);
115*d99fa3c5SJeremy L Thompson   CeedOperatorSetField(op_massFine, "v", ErestrictuFine, bFine,
116*d99fa3c5SJeremy L Thompson                        CEED_VECTOR_ACTIVE);
117*d99fa3c5SJeremy L Thompson 
118*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_setup, X, qdata, CEED_REQUEST_IMMEDIATE);
119*d99fa3c5SJeremy L Thompson 
120*d99fa3c5SJeremy L Thompson   // Create multigrid level
121*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, ncomp*NuFine, &PMultFine);
122*d99fa3c5SJeremy L Thompson   CeedVectorSetValue(PMultFine, 1.0);
123*d99fa3c5SJeremy L Thompson   CeedOperatorMultigridLevelCreate(op_massFine, PMultFine, ErestrictuCoarse,
124*d99fa3c5SJeremy L Thompson                                    bCoarse, &op_massCoarse, &op_prolong, &op_restrict);
125*d99fa3c5SJeremy L Thompson 
126*d99fa3c5SJeremy L Thompson   // Coarse problem
127*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, ncomp*NuCoarse, &Ucoarse);
128*d99fa3c5SJeremy L Thompson   CeedVectorSetValue(Ucoarse, 1.0);
129*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, ncomp*NuCoarse, &Vcoarse);
130*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_massCoarse, Ucoarse, Vcoarse, CEED_REQUEST_IMMEDIATE);
131*d99fa3c5SJeremy L Thompson 
132*d99fa3c5SJeremy L Thompson   // Check output
133*d99fa3c5SJeremy L Thompson   CeedVectorGetArrayRead(Vcoarse, CEED_MEM_HOST, &hv);
134*d99fa3c5SJeremy L Thompson   sum = 0.;
135*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<ncomp*NuCoarse; i++) {
136*d99fa3c5SJeremy L Thompson     sum += hv[i];
137*d99fa3c5SJeremy L Thompson   }
138*d99fa3c5SJeremy L Thompson   if (fabs(sum-2.)>1e-10)
139*d99fa3c5SJeremy L Thompson     // LCOV_EXCL_START
140*d99fa3c5SJeremy L Thompson     printf("Computed Area Coarse Grid: %f != True Area: 1.0\n", sum);
141*d99fa3c5SJeremy L Thompson   // LCOV_EXCL_STOP
142*d99fa3c5SJeremy L Thompson   CeedVectorRestoreArrayRead(Vcoarse, &hv);
143*d99fa3c5SJeremy L Thompson 
144*d99fa3c5SJeremy L Thompson   // Prolong coarse u
145*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, ncomp*NuFine, &Ufine);
146*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_prolong, Ucoarse, Ufine, CEED_REQUEST_IMMEDIATE);
147*d99fa3c5SJeremy L Thompson 
148*d99fa3c5SJeremy L Thompson   // Fine problem
149*d99fa3c5SJeremy L Thompson   CeedVectorCreate(ceed, ncomp*NuFine, &Vfine);
150*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_massFine, Ufine, Vfine, CEED_REQUEST_IMMEDIATE);
151*d99fa3c5SJeremy L Thompson 
152*d99fa3c5SJeremy L Thompson   // Check output
153*d99fa3c5SJeremy L Thompson   CeedVectorGetArrayRead(Vfine, CEED_MEM_HOST, &hv);
154*d99fa3c5SJeremy L Thompson   sum = 0.;
155*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<ncomp*NuFine; 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 Fine Grid: %f != True Area: 1.0\n", sum);
161*d99fa3c5SJeremy L Thompson   // LCOV_EXCL_STOP
162*d99fa3c5SJeremy L Thompson   CeedVectorRestoreArrayRead(Vfine, &hv);
163*d99fa3c5SJeremy L Thompson 
164*d99fa3c5SJeremy L Thompson   // Restrict state to coarse grid
165*d99fa3c5SJeremy L Thompson   CeedOperatorApply(op_restrict, Vfine, Vcoarse, CEED_REQUEST_IMMEDIATE);
166*d99fa3c5SJeremy L Thompson 
167*d99fa3c5SJeremy L Thompson   // Check output
168*d99fa3c5SJeremy L Thompson   CeedVectorGetArrayRead(Vcoarse, CEED_MEM_HOST, &hv);
169*d99fa3c5SJeremy L Thompson   sum = 0.;
170*d99fa3c5SJeremy L Thompson   for (CeedInt i=0; i<ncomp*NuCoarse; i++) {
171*d99fa3c5SJeremy L Thompson     sum += hv[i];
172*d99fa3c5SJeremy L Thompson   }
173*d99fa3c5SJeremy L Thompson   if (fabs(sum-2.)>1e-10)
174*d99fa3c5SJeremy L Thompson     // LCOV_EXCL_START
175*d99fa3c5SJeremy L Thompson     printf("Computed Area Coarse Grid: %f != True Area: 1.0\n", sum);
176*d99fa3c5SJeremy L Thompson   // LCOV_EXCL_STOP
177*d99fa3c5SJeremy L Thompson   CeedVectorRestoreArrayRead(Vcoarse, &hv);
178*d99fa3c5SJeremy L Thompson 
179*d99fa3c5SJeremy L Thompson   // Cleanup
180*d99fa3c5SJeremy L Thompson   CeedQFunctionDestroy(&qf_setup);
181*d99fa3c5SJeremy L Thompson   CeedQFunctionDestroy(&qf_mass);
182*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_setup);
183*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_massCoarse);
184*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_massFine);
185*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_prolong);
186*d99fa3c5SJeremy L Thompson   CeedOperatorDestroy(&op_restrict);
187*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&ErestrictuCoarse);
188*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&ErestrictuFine);
189*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&Erestrictx);
190*d99fa3c5SJeremy L Thompson   CeedElemRestrictionDestroy(&Erestrictui);
191*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bCoarse);
192*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bFine);
193*d99fa3c5SJeremy L Thompson   CeedBasisDestroy(&bx);
194*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&X);
195*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Ucoarse);
196*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Ufine);
197*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Vcoarse);
198*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&Vfine);
199*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&PMultFine);
200*d99fa3c5SJeremy L Thompson   CeedVectorDestroy(&qdata);
201*d99fa3c5SJeremy L Thompson   CeedDestroy(&ceed);
202*d99fa3c5SJeremy L Thompson   return 0;
203*d99fa3c5SJeremy L Thompson }
204