xref: /libCEED/tests/t598-operator.c (revision b9dba57961c4bee4d006e10b0dea9ee486515aa0)
1*99641342SJeremy L Thompson /// @file
2*99641342SJeremy L Thompson /// Test creation, action, and destruction for mass matrix operator AtPoints
3*99641342SJeremy L Thompson /// \test Test creation, action, and destruction for mass matrix operator AtPoints
4*99641342SJeremy L Thompson #include "t591-operator.h"
5*99641342SJeremy L Thompson 
6*99641342SJeremy L Thompson #include <ceed.h>
7*99641342SJeremy L Thompson #include <math.h>
8*99641342SJeremy L Thompson #include <stdio.h>
9*99641342SJeremy L Thompson #include <stdlib.h>
10*99641342SJeremy L Thompson 
main(int argc,char ** argv)11*99641342SJeremy L Thompson int main(int argc, char **argv) {
12*99641342SJeremy L Thompson   Ceed                ceed;
13*99641342SJeremy L Thompson   CeedInt             num_elem_1d = 3, num_elem = num_elem_1d * num_elem_1d, dim = 2, p_coarse = 2, p_fine = 3, q = 5;
14*99641342SJeremy L Thompson   CeedInt             num_points_per_elem = 4, num_points = num_elem * num_points_per_elem;
15*99641342SJeremy L Thompson   CeedInt             num_nodes_coarse = (num_elem_1d * (p_coarse - 1) + 1) * (num_elem_1d * (p_coarse - 1) + 1);
16*99641342SJeremy L Thompson   CeedInt             num_nodes_fine   = (num_elem_1d * (p_fine - 1) + 1) * (num_elem_1d * (p_fine - 1) + 1);
17*99641342SJeremy L Thompson   CeedVector          x_points, x_elem, q_data, u_coarse, u_fine, v_coarse, v_fine, p_mult_fine;
18*99641342SJeremy L Thompson   CeedElemRestriction elem_restriction_x_points, elem_restriction_q_data, elem_restriction_x, elem_restriction_u_coarse, elem_restriction_u_fine;
19*99641342SJeremy L Thompson   CeedBasis           basis_x, basis_u_coarse, basis_u_fine;
20*99641342SJeremy L Thompson   CeedQFunction       qf_setup, qf_mass;
21*99641342SJeremy L Thompson   CeedOperator        op_setup, op_mass_coarse, op_mass_fine, op_prolong, op_restrict;
22*99641342SJeremy L Thompson 
23*99641342SJeremy L Thompson   CeedInit(argv[1], &ceed);
24*99641342SJeremy L Thompson 
25*99641342SJeremy L Thompson   // Point reference coordinates
26*99641342SJeremy L Thompson   CeedVectorCreate(ceed, dim * num_points, &x_points);
27*99641342SJeremy L Thompson   {
28*99641342SJeremy L Thompson     CeedScalar x_array[dim * num_points];
29*99641342SJeremy L Thompson 
30*99641342SJeremy L Thompson     for (CeedInt e = 0; e < num_elem; e++) {
31*99641342SJeremy L Thompson       for (CeedInt d = 0; d < dim; d++) {
32*99641342SJeremy L Thompson         x_array[num_points_per_elem * (e * dim + d) + 0] = 0.25;
33*99641342SJeremy L Thompson         x_array[num_points_per_elem * (e * dim + d) + 1] = d == 0 ? -0.25 : 0.25;
34*99641342SJeremy L Thompson         x_array[num_points_per_elem * (e * dim + d) + 2] = d == 0 ? 0.25 : -0.25;
35*99641342SJeremy L Thompson         x_array[num_points_per_elem * (e * dim + d) + 3] = 0.25;
36*99641342SJeremy L Thompson       }
37*99641342SJeremy L Thompson     }
38*99641342SJeremy L Thompson     CeedVectorSetArray(x_points, CEED_MEM_HOST, CEED_COPY_VALUES, x_array);
39*99641342SJeremy L Thompson   }
40*99641342SJeremy L Thompson   {
41*99641342SJeremy L Thompson     CeedInt ind_x[num_elem + 1 + num_points];
42*99641342SJeremy L Thompson 
43*99641342SJeremy L Thompson     for (CeedInt i = 0; i <= num_elem; i++) ind_x[i] = num_elem + 1 + i * num_points_per_elem;
44*99641342SJeremy L Thompson     for (CeedInt i = 0; i < num_points; i++) ind_x[num_elem + 1 + i] = i;
45*99641342SJeremy L Thompson     CeedElemRestrictionCreateAtPoints(ceed, num_elem, num_points, dim, num_points * dim, CEED_MEM_HOST, CEED_COPY_VALUES, ind_x,
46*99641342SJeremy L Thompson                                       &elem_restriction_x_points);
47*99641342SJeremy L Thompson     CeedElemRestrictionCreateAtPoints(ceed, num_elem, num_points, 1, num_points, CEED_MEM_HOST, CEED_COPY_VALUES, ind_x, &elem_restriction_q_data);
48*99641342SJeremy L Thompson   }
49*99641342SJeremy L Thompson 
50*99641342SJeremy L Thompson   // Q data
51*99641342SJeremy L Thompson   CeedVectorCreate(ceed, num_points, &q_data);
52*99641342SJeremy L Thompson 
53*99641342SJeremy L Thompson   // Cell coordinates
54*99641342SJeremy L Thompson   {
55*99641342SJeremy L Thompson     CeedInt p = 2, num_nodes = (num_elem_1d * (p - 1) + 1) * (num_elem_1d * (p - 1) + 1);
56*99641342SJeremy L Thompson     CeedInt ind_x[num_elem * p * p];
57*99641342SJeremy L Thompson 
58*99641342SJeremy L Thompson     for (CeedInt e = 0; e < num_elem; e++) {
59*99641342SJeremy L Thompson       CeedInt elem_xy[2] = {1, 1}, n_d[2] = {0, 0};
60*99641342SJeremy L Thompson 
61*99641342SJeremy L Thompson       for (CeedInt d = 0; d < dim; d++) n_d[d] = num_elem_1d * (p - 1) + 1;
62*99641342SJeremy L Thompson       {
63*99641342SJeremy L Thompson         CeedInt r_e = e;
64*99641342SJeremy L Thompson 
65*99641342SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) {
66*99641342SJeremy L Thompson           elem_xy[d] = r_e % num_elem_1d;
67*99641342SJeremy L Thompson           r_e /= num_elem_1d;
68*99641342SJeremy L Thompson         }
69*99641342SJeremy L Thompson       }
70*99641342SJeremy L Thompson       CeedInt num_nodes_in_elem = p * p, *elem_nodes = ind_x + e * num_nodes_in_elem;
71*99641342SJeremy L Thompson 
72*99641342SJeremy L Thompson       for (CeedInt n = 0; n < num_nodes_in_elem; n++) {
73*99641342SJeremy L Thompson         CeedInt g_node = 0, g_node_stride = 1, r_node = n;
74*99641342SJeremy L Thompson 
75*99641342SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) {
76*99641342SJeremy L Thompson           g_node += (elem_xy[d] * (p - 1) + r_node % p) * g_node_stride;
77*99641342SJeremy L Thompson           g_node_stride *= n_d[d];
78*99641342SJeremy L Thompson           r_node /= p;
79*99641342SJeremy L Thompson         }
80*99641342SJeremy L Thompson         elem_nodes[n] = p * g_node;
81*99641342SJeremy L Thompson       }
82*99641342SJeremy L Thompson     }
83*99641342SJeremy L Thompson     CeedElemRestrictionCreate(ceed, num_elem, p * p, dim, 1, dim * num_nodes, CEED_MEM_HOST, CEED_COPY_VALUES, ind_x, &elem_restriction_x);
84*99641342SJeremy L Thompson     CeedVectorCreate(ceed, dim * num_nodes, &x_elem);
85*99641342SJeremy L Thompson     {
86*99641342SJeremy L Thompson       CeedScalar x_array[dim * num_nodes];
87*99641342SJeremy L Thompson 
88*99641342SJeremy L Thompson       for (CeedInt i = 0; i <= num_elem_1d; i++) {
89*99641342SJeremy L Thompson         for (CeedInt j = 0; j <= num_elem_1d; j++) {
90*99641342SJeremy L Thompson           x_array[(i * (num_elem_1d + 1) + j) * dim + 0] = j;
91*99641342SJeremy L Thompson           x_array[(i * (num_elem_1d + 1) + j) * dim + 1] = i;
92*99641342SJeremy L Thompson         }
93*99641342SJeremy L Thompson       }
94*99641342SJeremy L Thompson       CeedVectorSetArray(x_elem, CEED_MEM_HOST, CEED_COPY_VALUES, x_array);
95*99641342SJeremy L Thompson     }
96*99641342SJeremy L Thompson   }
97*99641342SJeremy L Thompson 
98*99641342SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, dim, dim, 2, q, CEED_GAUSS, &basis_x);
99*99641342SJeremy L Thompson 
100*99641342SJeremy L Thompson   // Cell solution
101*99641342SJeremy L Thompson   {
102*99641342SJeremy L Thompson     CeedInt ind_u[num_elem * p_coarse * p_coarse];
103*99641342SJeremy L Thompson 
104*99641342SJeremy L Thompson     for (CeedInt e = 0; e < num_elem; e++) {
105*99641342SJeremy L Thompson       CeedInt elem_xy[2] = {1, 1}, n_d[2] = {0, 0};
106*99641342SJeremy L Thompson 
107*99641342SJeremy L Thompson       for (CeedInt d = 0; d < dim; d++) n_d[d] = num_elem_1d * (p_coarse - 1) + 1;
108*99641342SJeremy L Thompson       {
109*99641342SJeremy L Thompson         CeedInt r_e = e;
110*99641342SJeremy L Thompson 
111*99641342SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) {
112*99641342SJeremy L Thompson           elem_xy[d] = r_e % num_elem_1d;
113*99641342SJeremy L Thompson           r_e /= num_elem_1d;
114*99641342SJeremy L Thompson         }
115*99641342SJeremy L Thompson       }
116*99641342SJeremy L Thompson       CeedInt num_nodes_in_elem = p_coarse * p_coarse, *elem_nodes = ind_u + e * num_nodes_in_elem;
117*99641342SJeremy L Thompson 
118*99641342SJeremy L Thompson       for (CeedInt n = 0; n < num_nodes_in_elem; n++) {
119*99641342SJeremy L Thompson         CeedInt g_node = 0, g_node_stride = 1, r_node = n;
120*99641342SJeremy L Thompson 
121*99641342SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) {
122*99641342SJeremy L Thompson           g_node += (elem_xy[d] * (p_coarse - 1) + r_node % p_coarse) * g_node_stride;
123*99641342SJeremy L Thompson           g_node_stride *= n_d[d];
124*99641342SJeremy L Thompson           r_node /= p_coarse;
125*99641342SJeremy L Thompson         }
126*99641342SJeremy L Thompson         elem_nodes[n] = g_node;
127*99641342SJeremy L Thompson       }
128*99641342SJeremy L Thompson     }
129*99641342SJeremy L Thompson     CeedElemRestrictionCreate(ceed, num_elem, p_coarse * p_coarse, 1, 1, num_nodes_coarse, CEED_MEM_HOST, CEED_COPY_VALUES, ind_u,
130*99641342SJeremy L Thompson                               &elem_restriction_u_coarse);
131*99641342SJeremy L Thompson   }
132*99641342SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, p_coarse, q, CEED_GAUSS, &basis_u_coarse);
133*99641342SJeremy L Thompson   {
134*99641342SJeremy L Thompson     CeedInt ind_u[num_elem * p_fine * p_fine];
135*99641342SJeremy L Thompson 
136*99641342SJeremy L Thompson     for (CeedInt e = 0; e < num_elem; e++) {
137*99641342SJeremy L Thompson       CeedInt elem_xy[2] = {1, 1}, n_d[2] = {0, 0};
138*99641342SJeremy L Thompson 
139*99641342SJeremy L Thompson       for (CeedInt d = 0; d < dim; d++) n_d[d] = num_elem_1d * (p_fine - 1) + 1;
140*99641342SJeremy L Thompson       {
141*99641342SJeremy L Thompson         CeedInt r_e = e;
142*99641342SJeremy L Thompson 
143*99641342SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) {
144*99641342SJeremy L Thompson           elem_xy[d] = r_e % num_elem_1d;
145*99641342SJeremy L Thompson           r_e /= num_elem_1d;
146*99641342SJeremy L Thompson         }
147*99641342SJeremy L Thompson       }
148*99641342SJeremy L Thompson       CeedInt num_nodes_in_elem = p_fine * p_fine, *elem_nodes = ind_u + e * num_nodes_in_elem;
149*99641342SJeremy L Thompson 
150*99641342SJeremy L Thompson       for (CeedInt n = 0; n < num_nodes_in_elem; n++) {
151*99641342SJeremy L Thompson         CeedInt g_node = 0, g_node_stride = 1, r_node = n;
152*99641342SJeremy L Thompson 
153*99641342SJeremy L Thompson         for (CeedInt d = 0; d < dim; d++) {
154*99641342SJeremy L Thompson           g_node += (elem_xy[d] * (p_fine - 1) + r_node % p_fine) * g_node_stride;
155*99641342SJeremy L Thompson           g_node_stride *= n_d[d];
156*99641342SJeremy L Thompson           r_node /= p_fine;
157*99641342SJeremy L Thompson         }
158*99641342SJeremy L Thompson         elem_nodes[n] = g_node;
159*99641342SJeremy L Thompson       }
160*99641342SJeremy L Thompson     }
161*99641342SJeremy L Thompson     CeedElemRestrictionCreate(ceed, num_elem, p_fine * p_fine, 1, 1, num_nodes_fine, CEED_MEM_HOST, CEED_COPY_VALUES, ind_u,
162*99641342SJeremy L Thompson                               &elem_restriction_u_fine);
163*99641342SJeremy L Thompson   }
164*99641342SJeremy L Thompson   CeedBasisCreateTensorH1Lagrange(ceed, dim, 1, p_fine, q, CEED_GAUSS, &basis_u_fine);
165*99641342SJeremy L Thompson 
166*99641342SJeremy L Thompson   // Setup geometric scaling
167*99641342SJeremy L Thompson   CeedQFunctionCreateInterior(ceed, 1, setup, setup_loc, &qf_setup);
168*99641342SJeremy L Thompson   CeedQFunctionAddInput(qf_setup, "x", dim * dim, CEED_EVAL_GRAD);
169*99641342SJeremy L Thompson   CeedQFunctionAddInput(qf_setup, "weight", 1, CEED_EVAL_WEIGHT);
170*99641342SJeremy L Thompson   CeedQFunctionAddOutput(qf_setup, "rho", 1, CEED_EVAL_NONE);
171*99641342SJeremy L Thompson 
172*99641342SJeremy L Thompson   CeedOperatorCreateAtPoints(ceed, qf_setup, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_setup);
173*99641342SJeremy L Thompson   CeedOperatorSetField(op_setup, "x", elem_restriction_x, basis_x, CEED_VECTOR_ACTIVE);
174*99641342SJeremy L Thompson   CeedOperatorSetField(op_setup, "weight", CEED_ELEMRESTRICTION_NONE, basis_x, CEED_VECTOR_NONE);
175*99641342SJeremy L Thompson   CeedOperatorSetField(op_setup, "rho", elem_restriction_q_data, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE);
176*99641342SJeremy L Thompson   CeedOperatorAtPointsSetPoints(op_setup, elem_restriction_x_points, x_points);
177*99641342SJeremy L Thompson 
178*99641342SJeremy L Thompson   CeedOperatorApply(op_setup, x_elem, q_data, CEED_REQUEST_IMMEDIATE);
179*99641342SJeremy L Thompson 
180*99641342SJeremy L Thompson   // Mass operator
181*99641342SJeremy L Thompson   CeedQFunctionCreateInterior(ceed, 1, mass, mass_loc, &qf_mass);
182*99641342SJeremy L Thompson   CeedQFunctionAddInput(qf_mass, "u", 1, CEED_EVAL_INTERP);
183*99641342SJeremy L Thompson   CeedQFunctionAddInput(qf_mass, "rho", 1, CEED_EVAL_NONE);
184*99641342SJeremy L Thompson   CeedQFunctionAddOutput(qf_mass, "v", 1, CEED_EVAL_INTERP);
185*99641342SJeremy L Thompson 
186*99641342SJeremy L Thompson   CeedOperatorCreateAtPoints(ceed, qf_mass, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_mass_fine);
187*99641342SJeremy L Thompson   CeedOperatorSetField(op_mass_fine, "u", elem_restriction_u_fine, basis_u_fine, CEED_VECTOR_ACTIVE);
188*99641342SJeremy L Thompson   CeedOperatorSetField(op_mass_fine, "rho", elem_restriction_q_data, CEED_BASIS_NONE, q_data);
189*99641342SJeremy L Thompson   CeedOperatorSetField(op_mass_fine, "v", elem_restriction_u_fine, basis_u_fine, CEED_VECTOR_ACTIVE);
190*99641342SJeremy L Thompson   CeedOperatorAtPointsSetPoints(op_mass_fine, elem_restriction_x_points, x_points);
191*99641342SJeremy L Thompson 
192*99641342SJeremy L Thompson   CeedVectorCreate(ceed, num_nodes_fine, &u_fine);
193*99641342SJeremy L Thompson   CeedVectorCreate(ceed, num_nodes_fine, &v_fine);
194*99641342SJeremy L Thompson   CeedVectorCreate(ceed, num_nodes_fine, &p_mult_fine);
195*99641342SJeremy L Thompson   CeedVectorCreate(ceed, num_nodes_coarse, &u_coarse);
196*99641342SJeremy L Thompson   CeedVectorCreate(ceed, num_nodes_coarse, &v_coarse);
197*99641342SJeremy L Thompson 
198*99641342SJeremy L Thompson   // Create multigrid level
199*99641342SJeremy L Thompson   CeedVectorSetValue(p_mult_fine, 1.0);
200*99641342SJeremy L Thompson   CeedOperatorMultigridLevelCreate(op_mass_fine, p_mult_fine, elem_restriction_u_coarse, basis_u_coarse, &op_mass_coarse, &op_prolong, &op_restrict);
201*99641342SJeremy L Thompson 
202*99641342SJeremy L Thompson   // Coarse problem
203*99641342SJeremy L Thompson   CeedVectorSetValue(u_coarse, 1.0);
204*99641342SJeremy L Thompson   CeedOperatorApply(op_mass_coarse, u_coarse, v_coarse, CEED_REQUEST_IMMEDIATE);
205*99641342SJeremy L Thompson 
206*99641342SJeremy L Thompson   // Check output
207*99641342SJeremy L Thompson   {
208*99641342SJeremy L Thompson     const CeedScalar *v_array;
209*99641342SJeremy L Thompson     CeedScalar        sum = 0.;
210*99641342SJeremy L Thompson 
211*99641342SJeremy L Thompson     CeedVectorGetArrayRead(v_coarse, CEED_MEM_HOST, &v_array);
212*99641342SJeremy L Thompson     for (CeedInt i = 0; i < num_nodes_coarse; i++) {
213*99641342SJeremy L Thompson       sum += v_array[i];
214*99641342SJeremy L Thompson     }
215*99641342SJeremy L Thompson     CeedVectorRestoreArrayRead(v_coarse, &v_array);
216*99641342SJeremy L Thompson     if (fabs(sum - num_elem) > 1000. * CEED_EPSILON) printf("Computed Area Coarse Grid: %f != True Area: 2.0\n", sum);
217*99641342SJeremy L Thompson   }
218*99641342SJeremy L Thompson 
219*99641342SJeremy L Thompson   // Prolong coarse u
220*99641342SJeremy L Thompson   CeedOperatorApply(op_prolong, u_coarse, u_fine, CEED_REQUEST_IMMEDIATE);
221*99641342SJeremy L Thompson 
222*99641342SJeremy L Thompson   // Fine problem
223*99641342SJeremy L Thompson   CeedOperatorApply(op_mass_fine, u_fine, v_fine, CEED_REQUEST_IMMEDIATE);
224*99641342SJeremy L Thompson 
225*99641342SJeremy L Thompson   // Check output
226*99641342SJeremy L Thompson   {
227*99641342SJeremy L Thompson     const CeedScalar *v_array;
228*99641342SJeremy L Thompson     CeedScalar        sum = 0.;
229*99641342SJeremy L Thompson 
230*99641342SJeremy L Thompson     CeedVectorGetArrayRead(v_fine, CEED_MEM_HOST, &v_array);
231*99641342SJeremy L Thompson     for (CeedInt i = 0; i < num_nodes_fine; i++) {
232*99641342SJeremy L Thompson       sum += v_array[i];
233*99641342SJeremy L Thompson     }
234*99641342SJeremy L Thompson     CeedVectorRestoreArrayRead(v_fine, &v_array);
235*99641342SJeremy L Thompson 
236*99641342SJeremy L Thompson     if (fabs(sum - num_elem) > 1000. * CEED_EPSILON) printf("Computed Area Fine Grid: %f != True Area: 2.0\n", sum);
237*99641342SJeremy L Thompson   }
238*99641342SJeremy L Thompson   // Restrict state to coarse grid
239*99641342SJeremy L Thompson   CeedOperatorApply(op_restrict, v_fine, v_coarse, CEED_REQUEST_IMMEDIATE);
240*99641342SJeremy L Thompson 
241*99641342SJeremy L Thompson   // Check output
242*99641342SJeremy L Thompson   {
243*99641342SJeremy L Thompson     const CeedScalar *v_array;
244*99641342SJeremy L Thompson     CeedScalar        sum = 0.;
245*99641342SJeremy L Thompson 
246*99641342SJeremy L Thompson     CeedVectorGetArrayRead(v_coarse, CEED_MEM_HOST, &v_array);
247*99641342SJeremy L Thompson     for (CeedInt i = 0; i < num_nodes_coarse; i++) {
248*99641342SJeremy L Thompson       sum += v_array[i];
249*99641342SJeremy L Thompson     }
250*99641342SJeremy L Thompson     CeedVectorRestoreArrayRead(v_coarse, &v_array);
251*99641342SJeremy L Thompson     if (fabs(sum - num_elem) > 1000. * CEED_EPSILON) printf("Computed Area Coarse Grid: %f != True Area: 2.0\n", sum);
252*99641342SJeremy L Thompson   }
253*99641342SJeremy L Thompson 
254*99641342SJeremy L Thompson   CeedVectorDestroy(&x_points);
255*99641342SJeremy L Thompson   CeedVectorDestroy(&q_data);
256*99641342SJeremy L Thompson   CeedVectorDestroy(&x_elem);
257*99641342SJeremy L Thompson   CeedVectorDestroy(&u_coarse);
258*99641342SJeremy L Thompson   CeedVectorDestroy(&u_fine);
259*99641342SJeremy L Thompson   CeedVectorDestroy(&v_fine);
260*99641342SJeremy L Thompson   CeedVectorDestroy(&v_coarse);
261*99641342SJeremy L Thompson   CeedVectorDestroy(&p_mult_fine);
262*99641342SJeremy L Thompson   CeedElemRestrictionDestroy(&elem_restriction_x_points);
263*99641342SJeremy L Thompson   CeedElemRestrictionDestroy(&elem_restriction_q_data);
264*99641342SJeremy L Thompson   CeedElemRestrictionDestroy(&elem_restriction_x);
265*99641342SJeremy L Thompson   CeedElemRestrictionDestroy(&elem_restriction_u_coarse);
266*99641342SJeremy L Thompson   CeedElemRestrictionDestroy(&elem_restriction_u_fine);
267*99641342SJeremy L Thompson   CeedBasisDestroy(&basis_x);
268*99641342SJeremy L Thompson   CeedBasisDestroy(&basis_u_coarse);
269*99641342SJeremy L Thompson   CeedBasisDestroy(&basis_u_fine);
270*99641342SJeremy L Thompson   CeedQFunctionDestroy(&qf_setup);
271*99641342SJeremy L Thompson   CeedQFunctionDestroy(&qf_mass);
272*99641342SJeremy L Thompson   CeedOperatorDestroy(&op_setup);
273*99641342SJeremy L Thompson   CeedOperatorDestroy(&op_mass_coarse);
274*99641342SJeremy L Thompson   CeedOperatorDestroy(&op_mass_fine);
275*99641342SJeremy L Thompson   CeedOperatorDestroy(&op_prolong);
276*99641342SJeremy L Thompson   CeedOperatorDestroy(&op_restrict);
277*99641342SJeremy L Thompson   CeedDestroy(&ceed);
278*99641342SJeremy L Thompson   return 0;
279*99641342SJeremy L Thompson }
280