xref: /libCEED/tests/t501-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 
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], *dxdX = in[1];
16*a8de75f0Sjeremylt   CeedScalar *rho = out[0];
17*a8de75f0Sjeremylt   for (CeedInt i=0; i<Q; i++) {
18*a8de75f0Sjeremylt     rho[i] = weight[i] * dxdX[i];
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 = 15, P = 5, Q = 8;
42*a8de75f0Sjeremylt   CeedInt Nx = nelem+1, Nu = nelem*(P-1)+1;
43*a8de75f0Sjeremylt   CeedInt indx[nelem*2], indu[nelem*P];
44*a8de75f0Sjeremylt   CeedScalar x[Nx];
45*a8de75f0Sjeremylt   CeedScalar sum;
46*a8de75f0Sjeremylt 
47*a8de75f0Sjeremylt   CeedInit(argv[1], &ceed);
48*a8de75f0Sjeremylt   for (CeedInt i=0; i<Nx; i++) x[i] = (CeedScalar) i / (Nx - 1);
49*a8de75f0Sjeremylt   for (CeedInt i=0; i<nelem; i++) {
50*a8de75f0Sjeremylt     indx[2*i+0] = i;
51*a8de75f0Sjeremylt     indx[2*i+1] = i+1;
52*a8de75f0Sjeremylt   }
53*a8de75f0Sjeremylt   // Restrictions
54*a8de75f0Sjeremylt   CeedElemRestrictionCreate(ceed, nelem, 2, Nx, 1, CEED_MEM_HOST,
55*a8de75f0Sjeremylt                             CEED_USE_POINTER, indx, &Erestrictx);
56*a8de75f0Sjeremylt   CeedElemRestrictionCreateIdentity(ceed, nelem, 2, nelem*2, 1, &Erestrictxi);
57*a8de75f0Sjeremylt 
58*a8de75f0Sjeremylt   for (CeedInt i=0; i<nelem; i++) {
59*a8de75f0Sjeremylt     for (CeedInt j=0; j<P; j++) {
60*a8de75f0Sjeremylt       indu[P*i+j] = i*(P-1) + j;
61*a8de75f0Sjeremylt     }
62*a8de75f0Sjeremylt   }
63*a8de75f0Sjeremylt   CeedElemRestrictionCreate(ceed, nelem, P, Nu, 1, CEED_MEM_HOST,
64*a8de75f0Sjeremylt                             CEED_USE_POINTER, indu, &Erestrictu);
65*a8de75f0Sjeremylt   CeedElemRestrictionCreateIdentity(ceed, nelem, Q, Q*nelem, 1, &Erestrictui);
66*a8de75f0Sjeremylt 
67*a8de75f0Sjeremylt   // Bases
68*a8de75f0Sjeremylt   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, 2, Q, CEED_GAUSS, &bx);
69*a8de75f0Sjeremylt   CeedBasisCreateTensorH1Lagrange(ceed, 1, 1, P, Q, CEED_GAUSS, &bu);
70*a8de75f0Sjeremylt 
71*a8de75f0Sjeremylt   // QFunctions
72*a8de75f0Sjeremylt   CeedQFunctionCreateInterior(ceed, 1, setup, __FILE__ ":setup", &qf_setup);
73*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_setup, "_weight", 1, CEED_EVAL_WEIGHT);
74*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_setup, "x", 1, CEED_EVAL_GRAD);
75*a8de75f0Sjeremylt   CeedQFunctionAddOutput(qf_setup, "rho", 1, CEED_EVAL_NONE);
76*a8de75f0Sjeremylt 
77*a8de75f0Sjeremylt   CeedQFunctionCreateInterior(ceed, 1, mass, __FILE__ ":mass", &qf_mass);
78*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_mass, "rho", 1, CEED_EVAL_NONE);
79*a8de75f0Sjeremylt   CeedQFunctionAddInput(qf_mass, "u", 1, CEED_EVAL_INTERP);
80*a8de75f0Sjeremylt   CeedQFunctionAddOutput(qf_mass, "v", 1, CEED_EVAL_INTERP);
81*a8de75f0Sjeremylt 
82*a8de75f0Sjeremylt   // Operators
83*a8de75f0Sjeremylt   CeedOperatorCreate(ceed, qf_setup, NULL, NULL, &op_setup);
84*a8de75f0Sjeremylt 
85*a8de75f0Sjeremylt   CeedOperatorCreate(ceed, qf_mass, NULL, NULL, &op_mass);
86*a8de75f0Sjeremylt 
87*a8de75f0Sjeremylt   CeedVectorCreate(ceed, Nx, &X);
88*a8de75f0Sjeremylt   CeedVectorSetArray(X, CEED_MEM_HOST, CEED_USE_POINTER, x);
89*a8de75f0Sjeremylt   CeedVectorCreate(ceed, nelem*Q, &qdata);
90*a8de75f0Sjeremylt 
91*a8de75f0Sjeremylt   CeedOperatorSetField(op_setup, "_weight", Erestrictxi, bx,
92*a8de75f0Sjeremylt                        CEED_VECTOR_NONE);
93*a8de75f0Sjeremylt   CeedOperatorSetField(op_setup, "x", Erestrictx, bx, CEED_VECTOR_ACTIVE);
94*a8de75f0Sjeremylt   CeedOperatorSetField(op_setup, "rho", Erestrictui,
95*a8de75f0Sjeremylt                        CEED_BASIS_COLLOCATED, CEED_VECTOR_ACTIVE);
96*a8de75f0Sjeremylt 
97*a8de75f0Sjeremylt   CeedOperatorSetField(op_mass, "rho", Erestrictui,
98*a8de75f0Sjeremylt                        CEED_BASIS_COLLOCATED, qdata);
99*a8de75f0Sjeremylt   CeedOperatorSetField(op_mass, "u", Erestrictu, bu, CEED_VECTOR_ACTIVE);
100*a8de75f0Sjeremylt   CeedOperatorSetField(op_mass, "v", Erestrictu, bu, CEED_VECTOR_ACTIVE);
101*a8de75f0Sjeremylt 
102*a8de75f0Sjeremylt   CeedOperatorApply(op_setup, X, qdata, CEED_REQUEST_IMMEDIATE);
103*a8de75f0Sjeremylt 
104*a8de75f0Sjeremylt   CeedVectorCreate(ceed, Nu, &U);
105*a8de75f0Sjeremylt   CeedVectorSetValue(U, 1.0);
106*a8de75f0Sjeremylt   CeedVectorCreate(ceed, Nu, &V);
107*a8de75f0Sjeremylt   CeedOperatorApply(op_mass, U, V, CEED_REQUEST_IMMEDIATE);
108*a8de75f0Sjeremylt 
109*a8de75f0Sjeremylt   // Check output
110*a8de75f0Sjeremylt   CeedVectorGetArrayRead(V, CEED_MEM_HOST, &hv);
111*a8de75f0Sjeremylt   sum = 0.;
112*a8de75f0Sjeremylt   for (CeedInt i=0; i<Nu; i++)
113*a8de75f0Sjeremylt     sum += hv[i];
114*a8de75f0Sjeremylt   if (fabs(sum-1.)>1e-10) printf("Computed Area: %f != True Area: 1.0\n", sum);
115*a8de75f0Sjeremylt   CeedVectorRestoreArrayRead(V, &hv);
116*a8de75f0Sjeremylt 
117*a8de75f0Sjeremylt   CeedQFunctionDestroy(&qf_setup);
118*a8de75f0Sjeremylt   CeedQFunctionDestroy(&qf_mass);
119*a8de75f0Sjeremylt   CeedOperatorDestroy(&op_setup);
120*a8de75f0Sjeremylt   CeedOperatorDestroy(&op_mass);
121*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictu);
122*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictx);
123*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictui);
124*a8de75f0Sjeremylt   CeedElemRestrictionDestroy(&Erestrictxi);
125*a8de75f0Sjeremylt   CeedBasisDestroy(&bu);
126*a8de75f0Sjeremylt   CeedBasisDestroy(&bx);
127*a8de75f0Sjeremylt   CeedVectorDestroy(&X);
128*a8de75f0Sjeremylt   CeedVectorDestroy(&U);
129*a8de75f0Sjeremylt   CeedVectorDestroy(&V);
130*a8de75f0Sjeremylt   CeedVectorDestroy(&qdata);
131*a8de75f0Sjeremylt   CeedDestroy(&ceed);
132*a8de75f0Sjeremylt   return 0;
133*a8de75f0Sjeremylt }
134