xref: /libCEED/examples/petsc/qfunctions/bps/bp2sphere.h (revision c9c2c07970382857cc7b4a28d359710237b91a3e)
13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3ed264d09SValeria Barra //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5ed264d09SValeria Barra //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
7ed264d09SValeria Barra 
8ed264d09SValeria Barra /// @file
9ed264d09SValeria Barra /// libCEED QFunctions for mass operator example for a vector field on the sphere using PETSc
10ed264d09SValeria Barra 
11f6b55d2cSvaleriabarra #ifndef bp2sphere_h
12f6b55d2cSvaleriabarra #define bp2sphere_h
13f6b55d2cSvaleriabarra 
14*c9c2c079SJeremy L Thompson #include <ceed.h>
15ed264d09SValeria Barra #include <math.h>
16ed264d09SValeria Barra 
17e83e87a5Sjeremylt // -----------------------------------------------------------------------------
18ed264d09SValeria Barra // This QFunction sets up the rhs and true solution for the problem
19ed264d09SValeria Barra // -----------------------------------------------------------------------------
20ed264d09SValeria Barra CEED_QFUNCTION(SetupMassRhs3)(void *ctx, const CeedInt Q,
21ed264d09SValeria Barra                              const CeedScalar *const *in,
22ed264d09SValeria Barra                              CeedScalar *const *out) {
23ed264d09SValeria Barra   // Inputs
249b072555Sjeremylt   const CeedScalar *X = in[0], *q_data = in[1];
25ed264d09SValeria Barra   // Outputs
26ed264d09SValeria Barra   CeedScalar *true_soln = out[0], *rhs = out[1];
27ed264d09SValeria Barra 
28ed264d09SValeria Barra   // Context
29ed264d09SValeria Barra   const CeedScalar *context = (const CeedScalar*)ctx;
30ed264d09SValeria Barra   const CeedScalar R        = context[0];
31ed264d09SValeria Barra 
32ed264d09SValeria Barra   // Quadrature Point Loop
33ed264d09SValeria Barra   CeedPragmaSIMD
34ed264d09SValeria Barra   for (CeedInt i=0; i<Q; i++) {
35ed264d09SValeria Barra     // Compute latitude
36ed264d09SValeria Barra     const CeedScalar theta =  asin(X[i+2*Q] / R);
37ed264d09SValeria Barra 
389b072555Sjeremylt     // Use absolute value of latitude for true solution
39ed264d09SValeria Barra     // Component 1
40ed264d09SValeria Barra     true_soln[i+0*Q] = fabs(theta);
41ed264d09SValeria Barra     // Component 2
42ed264d09SValeria Barra     true_soln[i+1*Q] = 2 * true_soln[i+0*Q];
43ed264d09SValeria Barra     // Component 3
44ed264d09SValeria Barra     true_soln[i+2*Q] = 3 * true_soln[i+0*Q];
45ed264d09SValeria Barra 
46ed264d09SValeria Barra     // Component 1
479b072555Sjeremylt     rhs[i+0*Q] = q_data[i] * true_soln[i];
48ed264d09SValeria Barra     // Component 2
49ed264d09SValeria Barra     rhs[i+1*Q] = 2 * rhs[i+0*Q];
50ed264d09SValeria Barra     // Component 3
51ed264d09SValeria Barra     rhs[i+2*Q] = 3 * rhs[i+0*Q];
52ed264d09SValeria Barra   } // End of Quadrature Point Loop
53ed264d09SValeria Barra 
54ed264d09SValeria Barra   return 0;
55ed264d09SValeria Barra }
56ed264d09SValeria Barra 
57e83e87a5Sjeremylt // -----------------------------------------------------------------------------
58ed264d09SValeria Barra // This QFunction applies the mass operator for a vector field of 3 components.
59ed264d09SValeria Barra //
60ed264d09SValeria Barra // Inputs:
61ed264d09SValeria Barra //   u     - Input vector at quadrature points
629b072555Sjeremylt //   q_data - Geometric factors
63ed264d09SValeria Barra //
64ed264d09SValeria Barra // Output:
65ed264d09SValeria Barra //   v     - Output vector (test functions) at quadrature points
66ed264d09SValeria Barra //
67ed264d09SValeria Barra // -----------------------------------------------------------------------------
68ed264d09SValeria Barra CEED_QFUNCTION(Mass3)(void *ctx, const CeedInt Q,
69ed264d09SValeria Barra                       const CeedScalar *const *in, CeedScalar *const *out) {
709b072555Sjeremylt   const CeedScalar *u = in[0], *q_data = in[1];
71ed264d09SValeria Barra   CeedScalar *v = out[0];
72ed264d09SValeria Barra 
73ed264d09SValeria Barra   // Quadrature Point Loop
74ed264d09SValeria Barra   CeedPragmaSIMD
75ed264d09SValeria Barra   for (CeedInt i=0; i<Q; i++) {
76ed264d09SValeria Barra     // Component 1
779b072555Sjeremylt     v[i+0*Q] = q_data[i] * u[i+0*Q];
78ed264d09SValeria Barra     // Component 2
799b072555Sjeremylt     v[i+1*Q] = q_data[i] * u[i+1*Q];
80ed264d09SValeria Barra     // Component 3
819b072555Sjeremylt     v[i+2*Q] = q_data[i] * u[i+2*Q];
82ed264d09SValeria Barra   } // End of Quadrature Point Loop
83ed264d09SValeria Barra 
84ed264d09SValeria Barra   return 0;
85ed264d09SValeria Barra }
86ed264d09SValeria Barra // -----------------------------------------------------------------------------
87f6b55d2cSvaleriabarra 
88f6b55d2cSvaleriabarra #endif // bp2sphere_h
89