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