xref: /libCEED/tests/t511-operator.c (revision a8de75f0ba69dfecd93c7d0093c041c0285ffd21)
1*a8de75f0Sjeremylt /// @file
2*a8de75f0Sjeremylt /// Test creation creation, action, and destruction for mass matrix operator
3*a8de75f0Sjeremylt /// \test Test creation creation, action, and destruction for mass matrix operator
4*a8de75f0Sjeremylt #include <ceed.h>
5*a8de75f0Sjeremylt #include <stdlib.h>
6*a8de75f0Sjeremylt #include <math.h>
7*a8de75f0Sjeremylt #include "t310-basis.h"
8*a8de75f0Sjeremylt 
9*a8de75f0Sjeremylt static int setup(void *ctx, CeedInt Q, const CeedScalar *const *in,
10*a8de75f0Sjeremylt                  CeedScalar *const *out);
11*a8de75f0Sjeremylt static int mass(void *ctx, CeedInt Q, const CeedScalar *const *in,
12*a8de75f0Sjeremylt                 CeedScalar *const *out);
13*a8de75f0Sjeremylt 
14*a8de75f0Sjeremylt static int setup(void *ctx, CeedInt Q, const CeedScalar *const *in,
15*a8de75f0Sjeremylt                  CeedScalar *const *out) {
16*a8de75f0Sjeremylt   const CeedScalar *weight = in[0], *J = in[1];
17*a8de75f0Sjeremylt   CeedScalar *rho = out[0];
18*a8de75f0Sjeremylt   for (CeedInt i=0; i<Q; i++) {
19*a8de75f0Sjeremylt     rho[i] = weight[i] * (J[i+Q*0]*J[i+Q*3] - J[i+Q*1]*J[i+Q*2]);
20*a8de75f0Sjeremylt   }
21*a8de75f0Sjeremylt   return 0;
22*a8de75f0Sjeremylt }
23*a8de75f0Sjeremylt 
24*a8de75f0Sjeremylt static int mass(void *ctx, CeedInt Q, const CeedScalar *const *in,
25*a8de75f0Sjeremylt                 CeedScalar *const *out) {
26*a8de75f0Sjeremylt   const CeedScalar *rho = in[0], *u = in[1];
27*a8de75f0Sjeremylt   CeedScalar *v = out[0];
28*a8de75f0Sjeremylt   for (CeedInt i=0; i<Q; i++) {
29*a8de75f0Sjeremylt     v[i] = rho[i] * u[i];
30*a8de75f0Sjeremylt   }
31*a8de75f0Sjeremylt   return 0;
32*a8de75f0Sjeremylt }
33*a8de75f0Sjeremylt 
34*a8de75f0Sjeremylt int main(int argc, char **argv) {
35*a8de75f0Sjeremylt   Ceed ceed;
36*a8de75f0Sjeremylt   CeedElemRestriction Erestrictx, Erestrictu, Erestrictxi, Erestrictui;
37*a8de75f0Sjeremylt   CeedBasis bx, bu;
38*a8de75f0Sjeremylt   CeedQFunction qf_setup, qf_mass;
39*a8de75f0Sjeremylt   CeedOperator op_setup, op_mass;
40*a8de75f0Sjeremylt   CeedVector qdata, X, U, V;
41*a8de75f0Sjeremylt   const CeedScalar *hv;
42*a8de75f0Sjeremylt   CeedInt nelem = 12, dim = 2, P = 6, Q = 4;
43*a8de75f0Sjeremylt   CeedInt nx = 3, ny = 2;
44*a8de75f0Sjeremylt   CeedInt row, col, offset;
45*a8de75f0Sjeremylt   CeedInt Ndofs = (nx*2+1)*(ny*2+1), Nqpts = nelem*Q;
46*a8de75f0Sjeremylt   CeedInt indx[nelem*P];
47*a8de75f0Sjeremylt   CeedScalar x[dim*Ndofs];
48*a8de75f0Sjeremylt   CeedScalar qref[dim*Q], qweight[Q];
49*a8de75f0Sjeremylt   CeedScalar interp[P*Q], grad[dim*P*Q];
50*a8de75f0Sjeremylt   CeedScalar sum;
51*a8de75f0Sjeremylt 
52*a8de75f0Sjeremylt   CeedInit(argv[1], &ceed);
53*a8de75f0Sjeremylt 
54*a8de75f0Sjeremylt   for (CeedInt i=0; i<Ndofs; i++) {
55*a8de75f0Sjeremylt     x[i] = (1. / (nx*2)) * (CeedScalar) (i % (nx*2+1));
56*a8de75f0Sjeremylt     x[i+Ndofs] = (1. / (ny*2)) * (CeedScalar) (i / (nx*2+1));
57*a8de75f0Sjeremylt   }
58*a8de75f0Sjeremylt   for (CeedInt i=0; i<nelem/2; i++) {
59*a8de75f0Sjeremylt     col = i % nx;
60*a8de75f0Sjeremylt     row = i / nx;
61*a8de75f0Sjeremylt     offset = col*2 + row*(nx*2+1)*2;
62*a8de75f0Sjeremylt 
63*a8de75f0Sjeremylt     indx[i*2*P +  0] =  2 + offset;
64*a8de75f0Sjeremylt     indx[i*2*P +  1] =  9 + offset;
65*a8de75f0Sjeremylt     indx[i*2*P +  2] = 16 + offset;
66*a8de75f0Sjeremylt     indx[i*2*P +  3] =  1 + offset;
67*a8de75f0Sjeremylt     indx[i*2*P +  4] =  8 + offset;
68*a8de75f0Sjeremylt     indx[i*2*P +  5] =  0 + offset;
69*a8de75f0Sjeremylt 
70*a8de75f0Sjeremylt     indx[i*2*P +  6] = 14 + offset;
71*a8de75f0Sjeremylt     indx[i*2*P +  7] =  7 + offset;
72*a8de75f0Sjeremylt     indx[i*2*P +  8] =  0 + offset;
73*a8de75f0Sjeremylt     indx[i*2*P +  9] = 15 + offset;
74*a8de75f0Sjeremylt     indx[i*2*P + 10] =  8 + offset;
75*a8de75f0Sjeremylt     indx[i*2*P + 11] = 16 + offset;
76*a8de75f0Sjeremylt   }
77*a8de75f0Sjeremylt 
78*a8de75f0Sjeremylt   // Restrictions
79*a8de75f0Sjeremylt   CeedElemRestrictionCreate(ceed, nelem, P, Ndofs, dim, CEED_MEM_HOST,
80*a8de75f0Sjeremylt                             CEED_USE_POINTER, indx, &Erestrictx);
81*a8de75f0Sjeremylt   CeedElemRestrictionCreateIdentity(ceed, nelem, P, nelem*P, dim, &Erestrictxi);
82*a8de75f0Sjeremylt 
83*a8de75f0Sjeremylt   CeedElemRestrictionCreate(ceed, nelem, P, Ndofs, 1, CEED_MEM_HOST,
84*a8de75f0Sjeremylt                             CEED_USE_POINTER, indx, &Erestrictu);
85*a8de75f0Sjeremylt   CeedElemRestrictionCreateIdentity(ceed, nelem, Q, Nqpts, 1, &Erestrictui);
86*a8de75f0Sjeremylt 
87*a8de75f0Sjeremylt 
88*a8de75f0Sjeremylt   // Bases
89*a8de75f0Sjeremylt   buildmats(qref, qweight, interp, grad);
90*a8de75f0Sjeremylt   CeedBasisCreateH1(ceed, CEED_TRIANGLE, dim, P, Q, interp, grad, qref,
91*a8de75f0Sjeremylt                     qweight, &bx);
92*a8de75f0Sjeremylt 
93*a8de75f0Sjeremylt   buildmats(qref, qweight, interp, grad);
94*a8de75f0Sjeremylt   CeedBasisCreateH1(ceed, CEED_TRIANGLE, 1, P, Q, interp, grad, qref,
95*a8de75f0Sjeremylt                     qweight, &bu);
96*a8de75f0Sjeremylt 
97*a8de75f0Sjeremylt   // QFunctions
98*a8de75f0Sjeremylt   CeedQFunctionCreateInterior(ceed, 1, setup, __FILE__ ":setup", &qf_setup);
99*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_setup, "_weight", 1, CEED_EVAL_WEIGHT);
100*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_setup, "x", dim, CEED_EVAL_GRAD);
101*a8de75f0Sjeremylt   CeedQFunctionAddOutput(qf_setup, "rho", 1, CEED_EVAL_NONE);
102*a8de75f0Sjeremylt 
103*a8de75f0Sjeremylt   CeedQFunctionCreateInterior(ceed, 1, mass, __FILE__ ":mass", &qf_mass);
104*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_mass, "rho", 1, CEED_EVAL_NONE);
105*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_mass, "u", 1, CEED_EVAL_INTERP);
106*a8de75f0Sjeremylt   CeedQFunctionAddOutput(qf_mass, "v", 1, CEED_EVAL_INTERP);
107*a8de75f0Sjeremylt 
108*a8de75f0Sjeremylt   // Operators
109*a8de75f0Sjeremylt   CeedOperatorCreate(ceed, qf_setup, NULL, NULL, &op_setup);
110*a8de75f0Sjeremylt 
111*a8de75f0Sjeremylt   CeedOperatorCreate(ceed, qf_mass, NULL, NULL, &op_mass);
112*a8de75f0Sjeremylt 
113*a8de75f0Sjeremylt   CeedVectorCreate(ceed, dim*Ndofs, &X);
114*a8de75f0Sjeremylt   CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x);
115*a8de75f0Sjeremylt   CeedVectorCreate(ceed, Nqpts, &qdata);
116*a8de75f0Sjeremylt 
117*a8de75f0Sjeremylt   CeedOperatorSetField(op_setup, "_weight", Erestrictxi, bx,
118*a8de75f0Sjeremylt                        CEED_VECTOR_NONE);
119*a8de75f0Sjeremylt   CeedOperatorSetField(op_setup, "x", Erestrictx, bx, CEED_VECTOR_ACTIVE);
120*a8de75f0Sjeremylt   CeedOperatorSetField(op_setup, "rho", Erestrictui,
121*a8de75f0Sjeremylt                        CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE);
122*a8de75f0Sjeremylt 
123*a8de75f0Sjeremylt   CeedOperatorSetField(op_mass, "rho", Erestrictui,
124*a8de75f0Sjeremylt                        CEED_BASIS_COLLOCATED, qdata);
125*a8de75f0Sjeremylt   CeedOperatorSetField(op_mass, "u", Erestrictu, bu, CEED_VECTOR_ACTIVE);
126*a8de75f0Sjeremylt   CeedOperatorSetField(op_mass, "v", Erestrictu, bu, CEED_VECTOR_ACTIVE);
127*a8de75f0Sjeremylt 
128*a8de75f0Sjeremylt   CeedOperatorApply(op_setup, X, qdata, CEED_REQUEST_IMMEDIATE);
129*a8de75f0Sjeremylt 
130*a8de75f0Sjeremylt   CeedVectorCreate(ceed, Ndofs, &U);
131*a8de75f0Sjeremylt   CeedVectorSetValue(U, 1.0);
132*a8de75f0Sjeremylt   CeedVectorCreate(ceed, Ndofs, &V);
133*a8de75f0Sjeremylt 
134*a8de75f0Sjeremylt   CeedOperatorApply(op_mass, U, V, CEED_REQUEST_IMMEDIATE);
135*a8de75f0Sjeremylt 
136*a8de75f0Sjeremylt   // Check output
137*a8de75f0Sjeremylt   CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv);
138*a8de75f0Sjeremylt   sum = 0.;
139*a8de75f0Sjeremylt   for (CeedInt i=0; i<Ndofs; i++)
140*a8de75f0Sjeremylt     sum += hv[i];
141*a8de75f0Sjeremylt   if (fabs(sum-1.)>1e-10) printf("Computed Area: %f != True Area: 1.0\n", sum);
142*a8de75f0Sjeremylt   CeedVectorRestoreArrayRead(V, &hv);
143*a8de75f0Sjeremylt 
144*a8de75f0Sjeremylt   CeedQFunctionDestroy(&qf_setup);
145*a8de75f0Sjeremylt   CeedQFunctionDestroy(&qf_mass);
146*a8de75f0Sjeremylt   CeedOperatorDestroy(&op_setup);
147*a8de75f0Sjeremylt   CeedOperatorDestroy(&op_mass);
148*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictu);
149*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictx);
150*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictui);
151*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictxi);
152*a8de75f0Sjeremylt   CeedBasisDestroy(&bu);
153*a8de75f0Sjeremylt   CeedBasisDestroy(&bx);
154*a8de75f0Sjeremylt   CeedVectorDestroy(&X);
155*a8de75f0Sjeremylt   CeedVectorDestroy(&U);
156*a8de75f0Sjeremylt   CeedVectorDestroy(&V);
157*a8de75f0Sjeremylt   CeedVectorDestroy(&qdata);
158*a8de75f0Sjeremylt   CeedDestroy(&ceed);
159*a8de75f0Sjeremylt   return 0;
160*a8de75f0Sjeremylt }
161