xref: /libCEED/examples/petsc/qfunctions/bps/bp4.h (revision 3d8e882215d238700cdceb37404f76ca7fa24eaa)
1 // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3 //
4 // SPDX-License-Identifier: BSD-2-Clause
5 //
6 // This file is part of CEED:  http://github.com/ceed
7 
8 /// @file
9 /// libCEED QFunctions for diffusion operator example using PETSc
10 
11 #ifndef bp4_h
12 #define bp4_h
13 
14 #include <math.h>
15 
16 // -----------------------------------------------------------------------------
17 // This QFunction sets up the rhs and true solution for the problem
18 // -----------------------------------------------------------------------------
19 CEED_QFUNCTION(SetupDiffRhs3)(void *ctx, CeedInt Q,
20                               const CeedScalar *const *in,
21                               CeedScalar *const *out) {
22 #ifndef M_PI
23 #  define M_PI    3.14159265358979323846
24 #endif
25   const CeedScalar *x = in[0], *w = in[1];
26   CeedScalar *true_soln = out[0], *rhs = out[1];
27 
28   // Quadrature Point Loop
29   CeedPragmaSIMD
30   for (CeedInt i=0; i<Q; i++) {
31     const CeedScalar c[3] = { 0, 1., 2. };
32     const CeedScalar k[3] = { 1., 2., 3. };
33 
34     // Component 1
35     true_soln[i+0*Q] = sin(M_PI*(c[0] + k[0]*x[i+Q*0])) *
36                        sin(M_PI*(c[1] + k[1]*x[i+Q*1])) *
37                        sin(M_PI*(c[2] + k[2]*x[i+Q*2]));
38     // Component 2
39     true_soln[i+1*Q] = 2 * true_soln[i+0*Q];
40     // Component 3
41     true_soln[i+2*Q] = 3 * true_soln[i+0*Q];
42 
43     // Component 1
44     rhs[i+0*Q] = w[i+Q*6] * M_PI*M_PI * (k[0]*k[0] + k[1]*k[1] + k[2]*k[2]) *
45                  true_soln[i+0*Q];
46     // Component 2
47     rhs[i+1*Q] = 2 * rhs[i+0*Q];
48     // Component 3
49     rhs[i+2*Q] = 3 * rhs[i+0*Q];
50   } // End of Quadrature Point Loop
51 
52   return 0;
53 }
54 
55 // -----------------------------------------------------------------------------
56 // This QFunction applies the diffusion operator for a vector field of 3 components.
57 //
58 // Inputs:
59 //   ug     - Input vector Jacobian at quadrature points
60 //   q_data  - Geometric factors
61 //
62 // Output:
63 //   vJ     - Output vector (test functions) Jacobian at quadrature points
64 //
65 // -----------------------------------------------------------------------------
66 CEED_QFUNCTION(Diff3)(void *ctx, CeedInt Q,
67                      const CeedScalar *const *in, CeedScalar *const *out) {
68   const CeedScalar *ug = in[0], *qd = in[1];
69   CeedScalar *vg = out[0];
70 
71   // Quadrature Point Loop
72   CeedPragmaSIMD
73   for (CeedInt i=0; i<Q; i++) {
74     // Read spatial derivatives of u components
75     const CeedScalar uJ[3][3]         = {{ug[i+(0+0*3)*Q],
76                                           ug[i+(0+1*3)*Q],
77                                           ug[i+(0+2*3)*Q]},
78                                          {ug[i+(1+0*3)*Q],
79                                           ug[i+(1+1*3)*Q],
80                                           ug[i+(1+2*3)*Q]},
81                                          {ug[i+(2+0*3)*Q],
82                                           ug[i+(2+1*3)*Q],
83                                           ug[i+(2+2*3)*Q]}
84                                         };
85     // Read q_data (dXdxdXdx_T symmetric matrix)
86     const CeedScalar dXdxdXdx_T[3][3] = {{qd[i+0*Q],
87                                           qd[i+1*Q],
88                                           qd[i+2*Q]},
89                                          {qd[i+1*Q],
90                                           qd[i+3*Q],
91                                           qd[i+4*Q]},
92                                          {qd[i+2*Q],
93                                           qd[i+4*Q],
94                                           qd[i+5*Q]}
95                                         };
96 
97     for (int k=0; k<3; k++) // k = component
98       for (int j=0; j<3; j++) // j = direction of vg
99         vg[i+(k+j*3)*Q] = (uJ[k][0] * dXdxdXdx_T[0][j] +
100                            uJ[k][1] * dXdxdXdx_T[1][j] +
101                            uJ[k][2] * dXdxdXdx_T[2][j]);
102   } // End of Quadrature Point Loop
103 
104   return 0;
105 }
106 // -----------------------------------------------------------------------------
107 
108 #endif // bp4_h
109