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