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