xref: /libCEED/include/ceed/ceed.h (revision ec3da8bcb94d9f0073544b37b5081a06981a86f7)
1*ec3da8bcSJed Brown /// Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2*ec3da8bcSJed Brown /// the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3*ec3da8bcSJed Brown /// reserved. See files LICENSE and NOTICE for details.
4*ec3da8bcSJed Brown ///
5*ec3da8bcSJed Brown /// This file is part of CEED, a collection of benchmarks, miniapps, software
6*ec3da8bcSJed Brown /// libraries and APIs for efficient high-order finite element and spectral
7*ec3da8bcSJed Brown /// element discretizations for exascale applications. For more information and
8*ec3da8bcSJed Brown /// source code availability see http://github.com/ceed.
9*ec3da8bcSJed Brown ///
10*ec3da8bcSJed Brown /// The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11*ec3da8bcSJed Brown /// a collaborative effort of two U.S. Department of Energy organizations (Office
12*ec3da8bcSJed Brown /// of Science and the National Nuclear Security Administration) responsible for
13*ec3da8bcSJed Brown /// the planning and preparation of a capable exascale ecosystem, including
14*ec3da8bcSJed Brown /// software, applications, hardware, advanced system engineering and early
15*ec3da8bcSJed Brown /// testbed platforms, in support of the nation's exascale computing imperative.
16*ec3da8bcSJed Brown 
17*ec3da8bcSJed Brown /// @file
18*ec3da8bcSJed Brown /// Public header for user and utility components of libCEED
19*ec3da8bcSJed Brown #ifndef _ceed_h
20*ec3da8bcSJed Brown #define _ceed_h
21*ec3da8bcSJed Brown 
22*ec3da8bcSJed Brown /// @defgroup Ceed Ceed: core components
23*ec3da8bcSJed Brown /// @defgroup CeedVector CeedVector: storing and manipulating vectors
24*ec3da8bcSJed Brown /// @defgroup CeedElemRestriction CeedElemRestriction: restriction from local vectors to elements
25*ec3da8bcSJed Brown /// @defgroup CeedBasis CeedBasis: fully discrete finite element-like objects
26*ec3da8bcSJed Brown /// @defgroup CeedQFunction CeedQFunction: independent operations at quadrature points
27*ec3da8bcSJed Brown /// @defgroup CeedOperator CeedOperator: composed FE-type operations on vectors
28*ec3da8bcSJed Brown ///
29*ec3da8bcSJed Brown /// @page FunctionCategories libCEED: Types of Functions
30*ec3da8bcSJed Brown ///    libCEED provides three different header files depending upon the type of
31*ec3da8bcSJed Brown ///    functions a user requires.
32*ec3da8bcSJed Brown /// @section Utility Utility Functions
33*ec3da8bcSJed Brown ///    These functions are intended general utilities that may be useful to
34*ec3da8bcSJed Brown ///    libCEED developers and users. These functions can generally be found in
35*ec3da8bcSJed Brown ///    "ceed.h".
36*ec3da8bcSJed Brown /// @section User User Functions
37*ec3da8bcSJed Brown ///    These functions are intended to be used by general users of libCEED
38*ec3da8bcSJed Brown ///    and can generally be found in "ceed.h".
39*ec3da8bcSJed Brown /// @section Backend Backend Developer Functions
40*ec3da8bcSJed Brown ///    These functions are intended to be used by backend developers of
41*ec3da8bcSJed Brown ///    libCEED and can generally be found in "ceed-backend.h".
42*ec3da8bcSJed Brown /// @section Developer Library Developer Functions
43*ec3da8bcSJed Brown ///    These functions are intended to be used by library developers of
44*ec3da8bcSJed Brown ///    libCEED and can generally be found in "ceed-impl.h".
45*ec3da8bcSJed Brown 
46*ec3da8bcSJed Brown /**
47*ec3da8bcSJed Brown   CEED_EXTERN is used in this header to denote all publicly visible symbols.
48*ec3da8bcSJed Brown 
49*ec3da8bcSJed Brown   No other file should declare publicly visible symbols, thus it should never be
50*ec3da8bcSJed Brown   used outside ceed.h.
51*ec3da8bcSJed Brown  */
52*ec3da8bcSJed Brown #ifdef __cplusplus
53*ec3da8bcSJed Brown #  define CEED_EXTERN extern "C"
54*ec3da8bcSJed Brown #else
55*ec3da8bcSJed Brown #  define CEED_EXTERN extern
56*ec3da8bcSJed Brown #endif
57*ec3da8bcSJed Brown 
58*ec3da8bcSJed Brown /**
59*ec3da8bcSJed Brown   @ingroup CeedQFunction
60*ec3da8bcSJed Brown   This macro populates the correct function annotations for User QFunction
61*ec3da8bcSJed Brown     source for code generation backends or populates default values for CPU
62*ec3da8bcSJed Brown     backends.
63*ec3da8bcSJed Brown **/
64*ec3da8bcSJed Brown #ifndef CEED_QFUNCTION
65*ec3da8bcSJed Brown #define CEED_QFUNCTION(name) \
66*ec3da8bcSJed Brown   static const char name ## _loc[] = __FILE__ ":" #name;        \
67*ec3da8bcSJed Brown   static int name
68*ec3da8bcSJed Brown #endif
69*ec3da8bcSJed Brown 
70*ec3da8bcSJed Brown /**
71*ec3da8bcSJed Brown   @ingroup CeedQFunction
72*ec3da8bcSJed Brown   Using VLA syntax to reshape User QFunction inputs and outputs can make
73*ec3da8bcSJed Brown     user code more readable. VLA is a C99 feature that is not supported by
74*ec3da8bcSJed Brown     the C++ dialect used by CUDA. This macro allows users to use the VLA
75*ec3da8bcSJed Brown     syntax with the CUDA backends.
76*ec3da8bcSJed Brown **/
77*ec3da8bcSJed Brown #ifndef CEED_Q_VLA
78*ec3da8bcSJed Brown #  define CEED_Q_VLA Q
79*ec3da8bcSJed Brown #endif
80*ec3da8bcSJed Brown 
81*ec3da8bcSJed Brown /**
82*ec3da8bcSJed Brown   @ingroup Ceed
83*ec3da8bcSJed Brown   This macro provides the appropriate SIMD Pragma for the compilation
84*ec3da8bcSJed Brown     environment. Code generation backends may redefine this macro, as needed.
85*ec3da8bcSJed Brown **/
86*ec3da8bcSJed Brown #ifndef CeedPragmaSIMD
87*ec3da8bcSJed Brown #  if defined(__INTEL_COMPILER)
88*ec3da8bcSJed Brown #    define CeedPragmaSIMD _Pragma("vector")
89*ec3da8bcSJed Brown // Cannot use Intel pragma ivdep because it miscompiles unpacking symmetric tensors, as in
90*ec3da8bcSJed Brown // Poisson2DApply, where the SIMD loop body contains temporaries such as the following.
91*ec3da8bcSJed Brown //
92*ec3da8bcSJed Brown //     const CeedScalar dXdxdXdxT[2][2] = {{qd[i+0*Q], qd[i+2*Q]},
93*ec3da8bcSJed Brown //                                         {qd[i+2*Q], qd[i+1*Q]}};
94*ec3da8bcSJed Brown //     for (int j=0; j<2; j++)
95*ec3da8bcSJed Brown //        vg[i+j*Q] = (du[0] * dXdxdXdxT[0][j] + du[1] * dXdxdXdxT[1][j]);
96*ec3da8bcSJed Brown //
97*ec3da8bcSJed Brown // Miscompilation with pragma ivdep observed with icc (ICC) 19.0.5.281 20190815
98*ec3da8bcSJed Brown // at -O2 and above.
99*ec3da8bcSJed Brown #  elif defined(__GNUC__) && __GNUC__ >= 5
100*ec3da8bcSJed Brown #    define CeedPragmaSIMD _Pragma("GCC ivdep")
101*ec3da8bcSJed Brown #  elif defined(_OPENMP) && _OPENMP >= 201307 // OpenMP-4.0 (July, 2013)
102*ec3da8bcSJed Brown #    define CeedPragmaSIMD _Pragma("omp simd")
103*ec3da8bcSJed Brown #  else
104*ec3da8bcSJed Brown #    define CeedPragmaSIMD
105*ec3da8bcSJed Brown #  endif
106*ec3da8bcSJed Brown #endif
107*ec3da8bcSJed Brown 
108*ec3da8bcSJed Brown #include <stdint.h>
109*ec3da8bcSJed Brown #include <stdarg.h>
110*ec3da8bcSJed Brown #include <stdio.h>
111*ec3da8bcSJed Brown #include <stdbool.h>
112*ec3da8bcSJed Brown 
113*ec3da8bcSJed Brown /// Integer type, used for indexing
114*ec3da8bcSJed Brown /// @ingroup Ceed
115*ec3da8bcSJed Brown typedef int32_t CeedInt;
116*ec3da8bcSJed Brown /// Scalar (floating point) type
117*ec3da8bcSJed Brown /// @ingroup Ceed
118*ec3da8bcSJed Brown typedef double CeedScalar;
119*ec3da8bcSJed Brown 
120*ec3da8bcSJed Brown /// Library context created by CeedInit()
121*ec3da8bcSJed Brown /// @ingroup CeedUser
122*ec3da8bcSJed Brown typedef struct Ceed_private *Ceed;
123*ec3da8bcSJed Brown /// Non-blocking Ceed interfaces return a CeedRequest.
124*ec3da8bcSJed Brown /// To perform an operation immediately, pass \ref CEED_REQUEST_IMMEDIATE instead.
125*ec3da8bcSJed Brown /// @ingroup CeedUser
126*ec3da8bcSJed Brown typedef struct CeedRequest_private *CeedRequest;
127*ec3da8bcSJed Brown /// Handle for vectors over the field \ref CeedScalar
128*ec3da8bcSJed Brown /// @ingroup CeedVectorUser
129*ec3da8bcSJed Brown typedef struct CeedVector_private *CeedVector;
130*ec3da8bcSJed Brown /// Handle for object describing restriction to elements
131*ec3da8bcSJed Brown /// @ingroup CeedElemRestrictionUser
132*ec3da8bcSJed Brown typedef struct CeedElemRestriction_private *CeedElemRestriction;
133*ec3da8bcSJed Brown /// Handle for object describing discrete finite element evaluations
134*ec3da8bcSJed Brown /// @ingroup CeedBasisUser
135*ec3da8bcSJed Brown typedef struct CeedBasis_private *CeedBasis;
136*ec3da8bcSJed Brown /// Handle for object describing functions evaluated independently at quadrature points
137*ec3da8bcSJed Brown /// @ingroup CeedQFunctionUser
138*ec3da8bcSJed Brown typedef struct CeedQFunction_private *CeedQFunction;
139*ec3da8bcSJed Brown /// Handle for object describing context data for CeedQFunctions
140*ec3da8bcSJed Brown /// @ingroup CeedQFunctionUser
141*ec3da8bcSJed Brown typedef struct CeedQFunctionContext_private *CeedQFunctionContext;
142*ec3da8bcSJed Brown /// Handle for object describing FE-type operators acting on vectors
143*ec3da8bcSJed Brown ///
144*ec3da8bcSJed Brown /// Given an element restriction \f$E\f$, basis evaluator \f$B\f$, and
145*ec3da8bcSJed Brown ///   quadrature function\f$f\f$, a CeedOperator expresses operations of the form
146*ec3da8bcSJed Brown ///   $$ E^T B^T f(B E u) $$
147*ec3da8bcSJed Brown ///   acting on the vector \f$u\f$.
148*ec3da8bcSJed Brown /// @ingroup CeedOperatorUser
149*ec3da8bcSJed Brown typedef struct CeedOperator_private *CeedOperator;
150*ec3da8bcSJed Brown 
151*ec3da8bcSJed Brown CEED_EXTERN int CeedInit(const char *resource, Ceed *ceed);
152*ec3da8bcSJed Brown CEED_EXTERN int CeedGetResource(Ceed ceed, const char **resource);
153*ec3da8bcSJed Brown CEED_EXTERN int CeedIsDeterministic(Ceed ceed, bool *isDeterministic);
154*ec3da8bcSJed Brown CEED_EXTERN int CeedView(Ceed ceed, FILE *stream);
155*ec3da8bcSJed Brown CEED_EXTERN int CeedDestroy(Ceed *ceed);
156*ec3da8bcSJed Brown 
157*ec3da8bcSJed Brown CEED_EXTERN int CeedErrorImpl(Ceed, const char *, int, const char *, int,
158*ec3da8bcSJed Brown                               const char *, ...);
159*ec3da8bcSJed Brown /// Raise an error on ceed object
160*ec3da8bcSJed Brown ///
161*ec3da8bcSJed Brown /// @param ceed Ceed library context or NULL
162*ec3da8bcSJed Brown /// @param ecode Error code (int)
163*ec3da8bcSJed Brown /// @param ... printf-style format string followed by arguments as needed
164*ec3da8bcSJed Brown ///
165*ec3da8bcSJed Brown /// @ingroup Ceed
166*ec3da8bcSJed Brown /// @sa CeedSetErrorHandler()
167*ec3da8bcSJed Brown #if defined(__clang__)
168*ec3da8bcSJed Brown /// Use nonstandard ternary to convince the compiler/clang-tidy that this
169*ec3da8bcSJed Brown /// function never returns zero.
170*ec3da8bcSJed Brown #  define CeedError(ceed, ecode, ...)                                     \
171*ec3da8bcSJed Brown   (CeedErrorImpl((ceed), __FILE__, __LINE__, __func__, (ecode), __VA_ARGS__) ?: (ecode))
172*ec3da8bcSJed Brown #else
173*ec3da8bcSJed Brown #  define CeedError(ceed, ecode, ...)                                     \
174*ec3da8bcSJed Brown   CeedErrorImpl((ceed), __FILE__, __LINE__, __func__, (ecode), __VA_ARGS__) ?: (ecode)
175*ec3da8bcSJed Brown #endif
176*ec3da8bcSJed Brown 
177*ec3da8bcSJed Brown /// Ceed error handlers
178*ec3da8bcSJed Brown CEED_EXTERN int CeedErrorReturn(Ceed, const char *, int, const char *, int,
179*ec3da8bcSJed Brown                                 const char *, va_list *);
180*ec3da8bcSJed Brown CEED_EXTERN int CeedErrorStore(Ceed, const char *, int, const char *, int,
181*ec3da8bcSJed Brown                                const char *, va_list *);
182*ec3da8bcSJed Brown CEED_EXTERN int CeedErrorAbort(Ceed, const char *, int, const char *, int,
183*ec3da8bcSJed Brown                                const char *, va_list *);
184*ec3da8bcSJed Brown CEED_EXTERN int CeedErrorExit(Ceed, const char *, int, const char *, int,
185*ec3da8bcSJed Brown                               const char *, va_list *);
186*ec3da8bcSJed Brown typedef int (*CeedErrorHandler)(Ceed, const char *, int,
187*ec3da8bcSJed Brown                                 const char *, int, const char *,
188*ec3da8bcSJed Brown                                 va_list *);
189*ec3da8bcSJed Brown CEED_EXTERN int CeedSetErrorHandler(Ceed ceed, CeedErrorHandler eh);
190*ec3da8bcSJed Brown CEED_EXTERN int CeedGetErrorMessage(Ceed, const char **errmsg);
191*ec3da8bcSJed Brown CEED_EXTERN int CeedResetErrorMessage(Ceed, const char **errmsg);
192*ec3da8bcSJed Brown 
193*ec3da8bcSJed Brown /// libCEED library version numbering
194*ec3da8bcSJed Brown /// @ingroup Ceed
195*ec3da8bcSJed Brown #define CEED_VERSION_MAJOR 0
196*ec3da8bcSJed Brown #define CEED_VERSION_MINOR 7
197*ec3da8bcSJed Brown #define CEED_VERSION_PATCH 0
198*ec3da8bcSJed Brown #define CEED_VERSION_RELEASE false
199*ec3da8bcSJed Brown 
200*ec3da8bcSJed Brown /// Compile-time check that the the current library version is at least as
201*ec3da8bcSJed Brown /// recent as the specified version. This macro is typically used in
202*ec3da8bcSJed Brown /// @code
203*ec3da8bcSJed Brown /// #if CEED_VERSION_GE(0, 8, 0)
204*ec3da8bcSJed Brown ///   code path that needs at least 0.8.0
205*ec3da8bcSJed Brown /// #else
206*ec3da8bcSJed Brown ///   fallback code for older versions
207*ec3da8bcSJed Brown /// #endif
208*ec3da8bcSJed Brown /// @endcode
209*ec3da8bcSJed Brown ///
210*ec3da8bcSJed Brown /// A non-release version always compares as positive infinity.
211*ec3da8bcSJed Brown ///
212*ec3da8bcSJed Brown /// @param major   Major version
213*ec3da8bcSJed Brown /// @param minor   Minor version
214*ec3da8bcSJed Brown /// @param patch   Patch (subminor) version
215*ec3da8bcSJed Brown ///
216*ec3da8bcSJed Brown /// @ingroup Ceed
217*ec3da8bcSJed Brown /// @sa CeedGetVersion()
218*ec3da8bcSJed Brown #define CEED_VERSION_GE(major, minor, patch)                                   \
219*ec3da8bcSJed Brown   (!CEED_VERSION_RELEASE ||                                                    \
220*ec3da8bcSJed Brown    (CEED_VERSION_MAJOR > major ||                                              \
221*ec3da8bcSJed Brown     (CEED_VERSION_MAJOR == major &&                                            \
222*ec3da8bcSJed Brown      (CEED_VERSION_MINOR > minor ||                                            \
223*ec3da8bcSJed Brown       (CEED_VERSION_MINOR == minor && CEED_VERSION_PATCH >= patch)))))
224*ec3da8bcSJed Brown 
225*ec3da8bcSJed Brown CEED_EXTERN int CeedGetVersion(int *major, int *minor, int *patch,
226*ec3da8bcSJed Brown                                bool *release);
227*ec3da8bcSJed Brown 
228*ec3da8bcSJed Brown /// Ceed Errors
229*ec3da8bcSJed Brown ///
230*ec3da8bcSJed Brown /// This enum is used to specify the type of error returned by a function.
231*ec3da8bcSJed Brown /// A zero error code is success, negative error codes indicate terminal errors
232*ec3da8bcSJed Brown /// and positive error codes indicate nonterminal errors. With nonterminal errors
233*ec3da8bcSJed Brown /// the object state has not been modifiend, but with terminal errors the object
234*ec3da8bcSJed Brown /// data is likely modified or corrupted.
235*ec3da8bcSJed Brown /// @ingroup Ceed
236*ec3da8bcSJed Brown typedef enum {
237*ec3da8bcSJed Brown   /// Sucess error code
238*ec3da8bcSJed Brown   CEED_ERROR_SUCCESS     = 0,
239*ec3da8bcSJed Brown   /// Minor error, generic
240*ec3da8bcSJed Brown   CEED_ERROR_MINOR       = 1,
241*ec3da8bcSJed Brown   /// Minor error, dimension mismatch in inputs
242*ec3da8bcSJed Brown   CEED_ERROR_DIMENSION   = 2,
243*ec3da8bcSJed Brown   /// Minor error, incomplete object setup
244*ec3da8bcSJed Brown   CEED_ERROR_INCOMPLETE  = 3,
245*ec3da8bcSJed Brown   /// Minor error, incompatible arguments/configuration
246*ec3da8bcSJed Brown   CEED_ERROR_INCOMPATIBLE = 4,
247*ec3da8bcSJed Brown   /// Minor error, access lock problem
248*ec3da8bcSJed Brown   CEED_ERROR_ACCESS      = 5,
249*ec3da8bcSJed Brown   /// Major error, generic
250*ec3da8bcSJed Brown   CEED_ERROR_MAJOR       = -1,
251*ec3da8bcSJed Brown   /// Major error, internal backend error
252*ec3da8bcSJed Brown   CEED_ERROR_BACKEND     = -2,
253*ec3da8bcSJed Brown   /// Major error, operation unsupported by current backend
254*ec3da8bcSJed Brown   CEED_ERROR_UNSUPPORTED = -3,
255*ec3da8bcSJed Brown } CeedErrorType;
256*ec3da8bcSJed Brown 
257*ec3da8bcSJed Brown CEED_EXTERN const char *const *CeedErrorTypes;
258*ec3da8bcSJed Brown 
259*ec3da8bcSJed Brown /// Specify memory type
260*ec3da8bcSJed Brown ///
261*ec3da8bcSJed Brown /// Many Ceed interfaces take or return pointers to memory.  This enum is used to
262*ec3da8bcSJed Brown /// specify where the memory being provided or requested must reside.
263*ec3da8bcSJed Brown /// @ingroup Ceed
264*ec3da8bcSJed Brown typedef enum {
265*ec3da8bcSJed Brown   /// Memory resides on the host
266*ec3da8bcSJed Brown   CEED_MEM_HOST,
267*ec3da8bcSJed Brown   /// Memory resides on a device (corresponding to \ref Ceed resource)
268*ec3da8bcSJed Brown   CEED_MEM_DEVICE,
269*ec3da8bcSJed Brown } CeedMemType;
270*ec3da8bcSJed Brown 
271*ec3da8bcSJed Brown CEED_EXTERN const char *const CeedMemTypes[];
272*ec3da8bcSJed Brown 
273*ec3da8bcSJed Brown CEED_EXTERN int CeedGetPreferredMemType(Ceed ceed, CeedMemType *type);
274*ec3da8bcSJed Brown 
275*ec3da8bcSJed Brown /// Conveys ownership status of arrays passed to Ceed interfaces.
276*ec3da8bcSJed Brown /// @ingroup Ceed
277*ec3da8bcSJed Brown typedef enum {
278*ec3da8bcSJed Brown   /// Implementation will copy the values and not store the passed pointer.
279*ec3da8bcSJed Brown   CEED_COPY_VALUES,
280*ec3da8bcSJed Brown   /// Implementation can use and modify the data provided by the user, but does
281*ec3da8bcSJed Brown   /// not take ownership.
282*ec3da8bcSJed Brown   CEED_USE_POINTER,
283*ec3da8bcSJed Brown   /// Implementation takes ownership of the pointer and will free using
284*ec3da8bcSJed Brown   /// CeedFree() when done using it.  The user should not assume that the
285*ec3da8bcSJed Brown   /// pointer remains valid after ownership has been transferred.  Note that
286*ec3da8bcSJed Brown   /// arrays allocated using C++ operator new or other allocators cannot
287*ec3da8bcSJed Brown   /// generally be freed using CeedFree().  CeedFree() is capable of freeing any
288*ec3da8bcSJed Brown   /// memory that can be freed using free(3).
289*ec3da8bcSJed Brown   CEED_OWN_POINTER,
290*ec3da8bcSJed Brown } CeedCopyMode;
291*ec3da8bcSJed Brown 
292*ec3da8bcSJed Brown /// Denotes type of vector norm to be computed
293*ec3da8bcSJed Brown /// @ingroup CeedVector
294*ec3da8bcSJed Brown typedef enum {
295*ec3da8bcSJed Brown   /// L_1 norm: sum_i |x_i|
296*ec3da8bcSJed Brown   CEED_NORM_1,
297*ec3da8bcSJed Brown   /// L_2 norm: sqrt(sum_i |x_i|^2)
298*ec3da8bcSJed Brown   CEED_NORM_2,
299*ec3da8bcSJed Brown   /// L_Infinity norm: max_i |x_i|
300*ec3da8bcSJed Brown   CEED_NORM_MAX,
301*ec3da8bcSJed Brown } CeedNormType;
302*ec3da8bcSJed Brown 
303*ec3da8bcSJed Brown CEED_EXTERN const char *const CeedCopyModes[];
304*ec3da8bcSJed Brown 
305*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorCreate(Ceed ceed, CeedInt len, CeedVector *vec);
306*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorSetArray(CeedVector vec, CeedMemType mtype,
307*ec3da8bcSJed Brown                                    CeedCopyMode cmode, CeedScalar *array);
308*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorSetValue(CeedVector vec, CeedScalar value);
309*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorSyncArray(CeedVector vec, CeedMemType mtype);
310*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorTakeArray(CeedVector vec, CeedMemType mtype,
311*ec3da8bcSJed Brown                                     CeedScalar **array);
312*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorGetArray(CeedVector vec, CeedMemType mtype,
313*ec3da8bcSJed Brown                                    CeedScalar **array);
314*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorGetArrayRead(CeedVector vec, CeedMemType mtype,
315*ec3da8bcSJed Brown                                        const CeedScalar **array);
316*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorRestoreArray(CeedVector vec, CeedScalar **array);
317*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorRestoreArrayRead(CeedVector vec,
318*ec3da8bcSJed Brown     const CeedScalar **array);
319*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorNorm(CeedVector vec, CeedNormType type,
320*ec3da8bcSJed Brown                                CeedScalar *norm);
321*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorReciprocal(CeedVector vec);
322*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorView(CeedVector vec, const char *fpfmt, FILE *stream);
323*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorGetLength(CeedVector vec, CeedInt *length);
324*ec3da8bcSJed Brown CEED_EXTERN int CeedVectorDestroy(CeedVector *vec);
325*ec3da8bcSJed Brown 
326*ec3da8bcSJed Brown CEED_EXTERN CeedRequest *const CEED_REQUEST_IMMEDIATE;
327*ec3da8bcSJed Brown CEED_EXTERN CeedRequest *const CEED_REQUEST_ORDERED;
328*ec3da8bcSJed Brown CEED_EXTERN int CeedRequestWait(CeedRequest *req);
329*ec3da8bcSJed Brown 
330*ec3da8bcSJed Brown /// Argument for CeedOperatorSetField that vector is collocated with
331*ec3da8bcSJed Brown /// quadrature points, used with QFunction eval mode CEED_EVAL_NONE
332*ec3da8bcSJed Brown /// or CEED_EVAL_INTERP only, not with CEED_EVAL_GRAD, CEED_EVAL_DIV,
333*ec3da8bcSJed Brown /// or CEED_EVAL_CURL
334*ec3da8bcSJed Brown /// @ingroup CeedBasis
335*ec3da8bcSJed Brown CEED_EXTERN const CeedBasis CEED_BASIS_COLLOCATED;
336*ec3da8bcSJed Brown 
337*ec3da8bcSJed Brown /// Argument for CeedOperatorSetField to use active input or output
338*ec3da8bcSJed Brown /// @ingroup CeedVector
339*ec3da8bcSJed Brown CEED_EXTERN const CeedVector CEED_VECTOR_ACTIVE;
340*ec3da8bcSJed Brown 
341*ec3da8bcSJed Brown /// Argument for CeedOperatorSetField to use no vector, used with
342*ec3da8bcSJed Brown /// qfunction input with eval mode CEED_EVAL_WEIGHT
343*ec3da8bcSJed Brown /// @ingroup CeedVector
344*ec3da8bcSJed Brown CEED_EXTERN const CeedVector CEED_VECTOR_NONE;
345*ec3da8bcSJed Brown 
346*ec3da8bcSJed Brown /// Argument for CeedOperatorSetField to use no ElemRestriction, only used with
347*ec3da8bcSJed Brown /// eval mode CEED_EVAL_WEIGHT.
348*ec3da8bcSJed Brown /// @ingroup CeedElemRestriction
349*ec3da8bcSJed Brown CEED_EXTERN const CeedElemRestriction CEED_ELEMRESTRICTION_NONE;
350*ec3da8bcSJed Brown 
351*ec3da8bcSJed Brown /// Argument for CeedOperatorCreate that QFunction is not created by user.
352*ec3da8bcSJed Brown /// Only used for QFunctions dqf and dqfT. If implemented, a backend may
353*ec3da8bcSJed Brown /// attempt to provide the action of these QFunctions.
354*ec3da8bcSJed Brown /// @ingroup CeedQFunction
355*ec3da8bcSJed Brown CEED_EXTERN const CeedQFunction CEED_QFUNCTION_NONE;
356*ec3da8bcSJed Brown 
357*ec3da8bcSJed Brown /// Denotes whether a linear transformation or its transpose should be applied
358*ec3da8bcSJed Brown /// @ingroup CeedBasis
359*ec3da8bcSJed Brown typedef enum {
360*ec3da8bcSJed Brown   /// Apply the linear transformation
361*ec3da8bcSJed Brown   CEED_NOTRANSPOSE,
362*ec3da8bcSJed Brown   /// Apply the transpose
363*ec3da8bcSJed Brown   CEED_TRANSPOSE
364*ec3da8bcSJed Brown } CeedTransposeMode;
365*ec3da8bcSJed Brown 
366*ec3da8bcSJed Brown CEED_EXTERN const char *const CeedTransposeModes[];
367*ec3da8bcSJed Brown 
368*ec3da8bcSJed Brown /// Argument for CeedElemRestrictionCreateStrided that L-vector is in
369*ec3da8bcSJed Brown /// the Ceed backend's preferred layout. This argument should only be used
370*ec3da8bcSJed Brown /// with vectors created by a Ceed backend.
371*ec3da8bcSJed Brown /// @ingroup CeedElemRestriction
372*ec3da8bcSJed Brown CEED_EXTERN const CeedInt CEED_STRIDES_BACKEND[3];
373*ec3da8bcSJed Brown 
374*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionCreate(Ceed ceed, CeedInt nelem,
375*ec3da8bcSJed Brown     CeedInt elemsize, CeedInt ncomp, CeedInt compstride, CeedInt lsize,
376*ec3da8bcSJed Brown     CeedMemType mtype, CeedCopyMode cmode, const CeedInt *offsets,
377*ec3da8bcSJed Brown     CeedElemRestriction *rstr);
378*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionCreateStrided(Ceed ceed,
379*ec3da8bcSJed Brown     CeedInt nelem, CeedInt elemsize, CeedInt ncomp, CeedInt lsize,
380*ec3da8bcSJed Brown     const CeedInt strides[3], CeedElemRestriction *rstr);
381*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt nelem,
382*ec3da8bcSJed Brown     CeedInt elemsize, CeedInt blksize, CeedInt ncomp, CeedInt compstride,
383*ec3da8bcSJed Brown     CeedInt lsize, CeedMemType mtype, CeedCopyMode cmode,
384*ec3da8bcSJed Brown     const CeedInt *offsets, CeedElemRestriction *rstr);
385*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionCreateBlockedStrided(Ceed ceed,
386*ec3da8bcSJed Brown     CeedInt nelem, CeedInt elemsize, CeedInt blksize, CeedInt ncomp,
387*ec3da8bcSJed Brown     CeedInt lsize, const CeedInt strides[3], CeedElemRestriction *rstr);
388*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionCreateVector(CeedElemRestriction rstr,
389*ec3da8bcSJed Brown     CeedVector *lvec, CeedVector *evec);
390*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionApply(CeedElemRestriction rstr,
391*ec3da8bcSJed Brown     CeedTransposeMode tmode, CeedVector u, CeedVector ru, CeedRequest *request);
392*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr,
393*ec3da8bcSJed Brown     CeedInt block, CeedTransposeMode tmode, CeedVector u, CeedVector ru,
394*ec3da8bcSJed Brown     CeedRequest *request);
395*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
396*ec3da8bcSJed Brown     CeedInt *compstride);
397*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
398*ec3da8bcSJed Brown     CeedInt *numelem);
399*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
400*ec3da8bcSJed Brown     CeedInt *elemsize);
401*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
402*ec3da8bcSJed Brown     CeedInt *lsize);
403*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
404*ec3da8bcSJed Brown     CeedInt *numcomp);
405*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
406*ec3da8bcSJed Brown     CeedInt *numblk);
407*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
408*ec3da8bcSJed Brown     CeedInt *blksize);
409*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
410*ec3da8bcSJed Brown     CeedVector mult);
411*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream);
412*ec3da8bcSJed Brown CEED_EXTERN int CeedElemRestrictionDestroy(CeedElemRestriction *rstr);
413*ec3da8bcSJed Brown 
414*ec3da8bcSJed Brown // The formalism here is that we have the structure
415*ec3da8bcSJed Brown //  \int_\Omega v^T f_0(u, \nabla u, qdata) + (\nabla v)^T f_1(u, \nabla u, qdata)
416*ec3da8bcSJed Brown // where gradients are with respect to the reference element.
417*ec3da8bcSJed Brown 
418*ec3da8bcSJed Brown /// Basis evaluation mode
419*ec3da8bcSJed Brown ///
420*ec3da8bcSJed Brown /// Modes can be bitwise ORed when passing to most functions.
421*ec3da8bcSJed Brown /// @ingroup CeedBasis
422*ec3da8bcSJed Brown typedef enum {
423*ec3da8bcSJed Brown   /// Perform no evaluation (either because there is no data or it is already at
424*ec3da8bcSJed Brown   /// quadrature points)
425*ec3da8bcSJed Brown   CEED_EVAL_NONE   = 0,
426*ec3da8bcSJed Brown   /// Interpolate from nodes to quadrature points
427*ec3da8bcSJed Brown   CEED_EVAL_INTERP = 1,
428*ec3da8bcSJed Brown   /// Evaluate gradients at quadrature points from input in a nodal basis
429*ec3da8bcSJed Brown   CEED_EVAL_GRAD   = 2,
430*ec3da8bcSJed Brown   /// Evaluate divergence at quadrature points from input in a nodal basis
431*ec3da8bcSJed Brown   CEED_EVAL_DIV    = 4,
432*ec3da8bcSJed Brown   /// Evaluate curl at quadrature points from input in a nodal basis
433*ec3da8bcSJed Brown   CEED_EVAL_CURL   = 8,
434*ec3da8bcSJed Brown   /// Using no input, evaluate quadrature weights on the reference element
435*ec3da8bcSJed Brown   CEED_EVAL_WEIGHT = 16,
436*ec3da8bcSJed Brown } CeedEvalMode;
437*ec3da8bcSJed Brown 
438*ec3da8bcSJed Brown CEED_EXTERN const char *const CeedEvalModes[];
439*ec3da8bcSJed Brown 
440*ec3da8bcSJed Brown /// Type of quadrature; also used for location of nodes
441*ec3da8bcSJed Brown /// @ingroup CeedBasis
442*ec3da8bcSJed Brown typedef enum {
443*ec3da8bcSJed Brown   /// Gauss-Legendre quadrature
444*ec3da8bcSJed Brown   CEED_GAUSS = 0,
445*ec3da8bcSJed Brown   /// Gauss-Legendre-Lobatto quadrature
446*ec3da8bcSJed Brown   CEED_GAUSS_LOBATTO = 1,
447*ec3da8bcSJed Brown } CeedQuadMode;
448*ec3da8bcSJed Brown 
449*ec3da8bcSJed Brown CEED_EXTERN const char *const CeedQuadModes[];
450*ec3da8bcSJed Brown 
451*ec3da8bcSJed Brown /// Type of basis shape to create non-tensor H1 element basis
452*ec3da8bcSJed Brown ///
453*ec3da8bcSJed Brown /// Dimension can be extracted with bitwise AND
454*ec3da8bcSJed Brown /// (CeedElemTopology & 2**(dim + 2)) == TRUE
455*ec3da8bcSJed Brown /// @ingroup CeedBasis
456*ec3da8bcSJed Brown typedef enum {
457*ec3da8bcSJed Brown   /// Line
458*ec3da8bcSJed Brown   CEED_LINE = 1 << 16 | 0,
459*ec3da8bcSJed Brown   /// Triangle - 2D shape
460*ec3da8bcSJed Brown   CEED_TRIANGLE = 2 << 16 | 1,
461*ec3da8bcSJed Brown   /// Quadralateral - 2D shape
462*ec3da8bcSJed Brown   CEED_QUAD = 2 << 16 | 2,
463*ec3da8bcSJed Brown   /// Tetrahedron - 3D shape
464*ec3da8bcSJed Brown   CEED_TET = 3 << 16 | 3,
465*ec3da8bcSJed Brown   /// Pyramid - 3D shape
466*ec3da8bcSJed Brown   CEED_PYRAMID = 3 << 16 | 4,
467*ec3da8bcSJed Brown   /// Prism - 3D shape
468*ec3da8bcSJed Brown   CEED_PRISM = 3 << 16 | 5,
469*ec3da8bcSJed Brown   /// Hexehedron - 3D shape
470*ec3da8bcSJed Brown   CEED_HEX = 3 << 16 | 6,
471*ec3da8bcSJed Brown } CeedElemTopology;
472*ec3da8bcSJed Brown 
473*ec3da8bcSJed Brown CEED_EXTERN const char *const CeedElemTopologies[];
474*ec3da8bcSJed Brown 
475*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisCreateTensorH1Lagrange(Ceed ceed, CeedInt dim,
476*ec3da8bcSJed Brown     CeedInt ncomp, CeedInt P, CeedInt Q, CeedQuadMode qmode, CeedBasis *basis);
477*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisCreateTensorH1(Ceed ceed, CeedInt dim, CeedInt ncomp,
478*ec3da8bcSJed Brown                                         CeedInt P1d, CeedInt Q1d,
479*ec3da8bcSJed Brown                                         const CeedScalar *interp1d,
480*ec3da8bcSJed Brown                                         const CeedScalar *grad1d,
481*ec3da8bcSJed Brown                                         const CeedScalar *qref1d,
482*ec3da8bcSJed Brown                                         const CeedScalar *qweight1d,
483*ec3da8bcSJed Brown                                         CeedBasis *basis);
484*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisCreateH1(Ceed ceed, CeedElemTopology topo,
485*ec3da8bcSJed Brown                                   CeedInt ncomp,
486*ec3da8bcSJed Brown                                   CeedInt nnodes, CeedInt nqpts,
487*ec3da8bcSJed Brown                                   const CeedScalar *interp,
488*ec3da8bcSJed Brown                                   const CeedScalar *grad,
489*ec3da8bcSJed Brown                                   const CeedScalar *qref,
490*ec3da8bcSJed Brown                                   const CeedScalar *qweight, CeedBasis *basis);
491*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisView(CeedBasis basis, FILE *stream);
492*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisApply(CeedBasis basis, CeedInt nelem,
493*ec3da8bcSJed Brown                                CeedTransposeMode tmode,
494*ec3da8bcSJed Brown                                CeedEvalMode emode, CeedVector u, CeedVector v);
495*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetDimension(CeedBasis basis, CeedInt *dim);
496*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetTopology(CeedBasis basis, CeedElemTopology *topo);
497*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetNumComponents(CeedBasis basis, CeedInt *numcomp);
498*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetNumNodes(CeedBasis basis, CeedInt *P);
499*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetNumNodes1D(CeedBasis basis, CeedInt *P1d);
500*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetNumQuadraturePoints(CeedBasis basis, CeedInt *Q);
501*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetNumQuadraturePoints1D(CeedBasis basis,
502*ec3da8bcSJed Brown     CeedInt *Q1d);
503*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetQRef(CeedBasis basis, const CeedScalar **qref);
504*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetQWeights(CeedBasis basis,
505*ec3da8bcSJed Brown                                      const CeedScalar **qweight);
506*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetInterp(CeedBasis basis, const CeedScalar **interp);
507*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetInterp1D(CeedBasis basis,
508*ec3da8bcSJed Brown                                      const CeedScalar **interp1d);
509*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetGrad(CeedBasis basis, const CeedScalar **grad);
510*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisGetGrad1D(CeedBasis basis, const CeedScalar **grad1d);
511*ec3da8bcSJed Brown CEED_EXTERN int CeedBasisDestroy(CeedBasis *basis);
512*ec3da8bcSJed Brown 
513*ec3da8bcSJed Brown CEED_EXTERN int CeedGaussQuadrature(CeedInt Q, CeedScalar *qref1d,
514*ec3da8bcSJed Brown                                     CeedScalar *qweight1d);
515*ec3da8bcSJed Brown CEED_EXTERN int CeedLobattoQuadrature(CeedInt Q, CeedScalar *qref1d,
516*ec3da8bcSJed Brown                                       CeedScalar *qweight1d);
517*ec3da8bcSJed Brown CEED_EXTERN int CeedQRFactorization(Ceed ceed, CeedScalar *mat, CeedScalar *tau,
518*ec3da8bcSJed Brown                                     CeedInt m, CeedInt n);
519*ec3da8bcSJed Brown CEED_EXTERN int CeedSymmetricSchurDecomposition(Ceed ceed, CeedScalar *mat,
520*ec3da8bcSJed Brown     CeedScalar *lambda, CeedInt n);
521*ec3da8bcSJed Brown CEED_EXTERN int CeedSimultaneousDiagonalization(Ceed ceed, CeedScalar *matA,
522*ec3da8bcSJed Brown     CeedScalar *matB, CeedScalar *x, CeedScalar *lambda, CeedInt n);
523*ec3da8bcSJed Brown 
524*ec3da8bcSJed Brown /** Handle for the object describing the user CeedQFunction
525*ec3da8bcSJed Brown 
526*ec3da8bcSJed Brown  @param ctx user-defined context set using CeedQFunctionSetContext() or NULL
527*ec3da8bcSJed Brown 
528*ec3da8bcSJed Brown  @param Q   number of quadrature points at which to evaluate
529*ec3da8bcSJed Brown 
530*ec3da8bcSJed Brown  @param in  array of pointers to each input argument in the order provided
531*ec3da8bcSJed Brown               by the user in CeedQFunctionAddInput().  Each array has shape
532*ec3da8bcSJed Brown               `[dim, ncomp, Q]` where `dim` is the geometric dimension for
533*ec3da8bcSJed Brown               \ref CEED_EVAL_GRAD (`dim=1` for \ref CEED_EVAL_INTERP) and
534*ec3da8bcSJed Brown               `ncomp` is the number of field components (`ncomp=1` for
535*ec3da8bcSJed Brown               scalar fields).  This results in indexing the `i`th input at
536*ec3da8bcSJed Brown               quadrature point `j` as `in[i][(d*ncomp + c)*Q + j]`.
537*ec3da8bcSJed Brown 
538*ec3da8bcSJed Brown  @param out array of pointers to each output array in the order provided
539*ec3da8bcSJed Brown               using CeedQFunctionAddOutput().  The shapes are as above for
540*ec3da8bcSJed Brown               \a in.
541*ec3da8bcSJed Brown 
542*ec3da8bcSJed Brown  @return An error code: 0 - success, otherwise - failure
543*ec3da8bcSJed Brown 
544*ec3da8bcSJed Brown  @ingroup CeedQFunction
545*ec3da8bcSJed Brown **/
546*ec3da8bcSJed Brown typedef int (*CeedQFunctionUser)(void *ctx, const CeedInt Q,
547*ec3da8bcSJed Brown                                  const CeedScalar *const *in,
548*ec3da8bcSJed Brown                                  CeedScalar *const *out);
549*ec3da8bcSJed Brown 
550*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vlength,
551*ec3da8bcSJed Brown     CeedQFunctionUser f, const char *source, CeedQFunction *qf);
552*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name,
553*ec3da8bcSJed Brown     CeedQFunction *qf);
554*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size,
555*ec3da8bcSJed Brown     CeedEvalMode inmode, CeedEvalMode outmode, CeedQFunction *qf);
556*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionAddInput(CeedQFunction qf, const char *fieldname,
557*ec3da8bcSJed Brown                                       CeedInt size, CeedEvalMode emode);
558*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionAddOutput(CeedQFunction qf, const char *fieldname,
559*ec3da8bcSJed Brown                                        CeedInt size, CeedEvalMode emode);
560*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionSetContext(CeedQFunction qf,
561*ec3da8bcSJed Brown                                         CeedQFunctionContext ctx);
562*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionView(CeedQFunction qf, FILE *stream);
563*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionApply(CeedQFunction qf, CeedInt Q,
564*ec3da8bcSJed Brown                                    CeedVector *u, CeedVector *v);
565*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionDestroy(CeedQFunction *qf);
566*ec3da8bcSJed Brown 
567*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionContextCreate(Ceed ceed,
568*ec3da8bcSJed Brown     CeedQFunctionContext *ctx);
569*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionContextSetData(CeedQFunctionContext ctx,
570*ec3da8bcSJed Brown     CeedMemType mtype, CeedCopyMode cmode, size_t size, void *data);
571*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionContextGetData(CeedQFunctionContext ctx,
572*ec3da8bcSJed Brown     CeedMemType mtype,
573*ec3da8bcSJed Brown     void *data);
574*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx,
575*ec3da8bcSJed Brown     void *data);
576*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionContextView(CeedQFunctionContext ctx,
577*ec3da8bcSJed Brown     FILE *stream);
578*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx);
579*ec3da8bcSJed Brown 
580*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorCreate(Ceed ceed, CeedQFunction qf,
581*ec3da8bcSJed Brown                                    CeedQFunction dqf, CeedQFunction dqfT,
582*ec3da8bcSJed Brown                                    CeedOperator *op);
583*ec3da8bcSJed Brown CEED_EXTERN int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op);
584*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorSetField(CeedOperator op, const char *fieldname,
585*ec3da8bcSJed Brown                                      CeedElemRestriction r, CeedBasis b,
586*ec3da8bcSJed Brown                                      CeedVector v);
587*ec3da8bcSJed Brown CEED_EXTERN int CeedCompositeOperatorAddSub(CeedOperator compositeop,
588*ec3da8bcSJed Brown     CeedOperator subop);
589*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorLinearAssembleQFunction(CeedOperator op,
590*ec3da8bcSJed Brown     CeedVector *assembled, CeedElemRestriction *rstr, CeedRequest *request);
591*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorLinearAssembleDiagonal(CeedOperator op,
592*ec3da8bcSJed Brown     CeedVector assembled, CeedRequest *request);
593*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorLinearAssembleAddDiagonal(CeedOperator op,
594*ec3da8bcSJed Brown     CeedVector assembled, CeedRequest *request);
595*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorLinearAssemblePointBlockDiagonal(CeedOperator op,
596*ec3da8bcSJed Brown     CeedVector assembled, CeedRequest *request);
597*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorLinearAssembleAddPointBlockDiagonal(CeedOperator op,
598*ec3da8bcSJed Brown     CeedVector assembled, CeedRequest *request);
599*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorLinearAssembleSymbolic(CeedOperator op,
600*ec3da8bcSJed Brown     CeedInt *nentries, CeedInt **rows, CeedInt **cols);
601*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorLinearAssemble(CeedOperator op, CeedVector values);
602*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorMultigridLevelCreate(CeedOperator opFine,
603*ec3da8bcSJed Brown     CeedVector PMultFine, CeedElemRestriction rstrCoarse, CeedBasis basisCoarse,
604*ec3da8bcSJed Brown     CeedOperator *opCoarse, CeedOperator *opProlong, CeedOperator *opRestrict);
605*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorMultigridLevelCreateTensorH1(
606*ec3da8bcSJed Brown   CeedOperator opFine, CeedVector PMultFine, CeedElemRestriction rstrCoarse,
607*ec3da8bcSJed Brown   CeedBasis basisCoarse, const CeedScalar *interpCtoF, CeedOperator *opCoarse,
608*ec3da8bcSJed Brown   CeedOperator *opProlong, CeedOperator *opRestrict);
609*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorMultigridLevelCreateH1(CeedOperator opFine,
610*ec3da8bcSJed Brown     CeedVector PMultFine, CeedElemRestriction rstrCoarse, CeedBasis basisCoarse,
611*ec3da8bcSJed Brown     const CeedScalar *interpCtoF, CeedOperator *opCoarse,
612*ec3da8bcSJed Brown     CeedOperator *opProlong, CeedOperator *opRestrict);
613*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorCreateFDMElementInverse(CeedOperator op,
614*ec3da8bcSJed Brown     CeedOperator *fdminv, CeedRequest *request);
615*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorView(CeedOperator op, FILE *stream);
616*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorApply(CeedOperator op, CeedVector in,
617*ec3da8bcSJed Brown                                   CeedVector out, CeedRequest *request);
618*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorApplyAdd(CeedOperator op, CeedVector in,
619*ec3da8bcSJed Brown                                      CeedVector out, CeedRequest *request);
620*ec3da8bcSJed Brown CEED_EXTERN int CeedOperatorDestroy(CeedOperator *op);
621*ec3da8bcSJed Brown 
622*ec3da8bcSJed Brown /**
623*ec3da8bcSJed Brown   @brief Return integer power
624*ec3da8bcSJed Brown 
625*ec3da8bcSJed Brown   @param[in] base   The base to exponentiate
626*ec3da8bcSJed Brown   @param[in] power  The power to raise the base to
627*ec3da8bcSJed Brown 
628*ec3da8bcSJed Brown   @return base^power
629*ec3da8bcSJed Brown 
630*ec3da8bcSJed Brown   @ref Utility
631*ec3da8bcSJed Brown **/
632*ec3da8bcSJed Brown static inline CeedInt CeedIntPow(CeedInt base, CeedInt power) {
633*ec3da8bcSJed Brown   CeedInt result = 1;
634*ec3da8bcSJed Brown   while (power) {
635*ec3da8bcSJed Brown     if (power & 1) result *= base;
636*ec3da8bcSJed Brown     power >>= 1;
637*ec3da8bcSJed Brown     base *= base;
638*ec3da8bcSJed Brown   }
639*ec3da8bcSJed Brown   return result;
640*ec3da8bcSJed Brown }
641*ec3da8bcSJed Brown 
642*ec3da8bcSJed Brown /**
643*ec3da8bcSJed Brown   @brief Return minimum of two integers
644*ec3da8bcSJed Brown 
645*ec3da8bcSJed Brown   @param[in] a  The first integer to compare
646*ec3da8bcSJed Brown   @param[in] b  The second integer to compare
647*ec3da8bcSJed Brown 
648*ec3da8bcSJed Brown   @return The minimum of the two integers
649*ec3da8bcSJed Brown 
650*ec3da8bcSJed Brown   @ref Utility
651*ec3da8bcSJed Brown **/
652*ec3da8bcSJed Brown static inline CeedInt CeedIntMin(CeedInt a, CeedInt b) { return a < b ? a : b; }
653*ec3da8bcSJed Brown 
654*ec3da8bcSJed Brown /**
655*ec3da8bcSJed Brown   @brief Return maximum of two integers
656*ec3da8bcSJed Brown 
657*ec3da8bcSJed Brown   @param[in] a  The first integer to compare
658*ec3da8bcSJed Brown   @param[in] b  The second integer to compare
659*ec3da8bcSJed Brown 
660*ec3da8bcSJed Brown   @return The maximum of the two integers
661*ec3da8bcSJed Brown 
662*ec3da8bcSJed Brown   @ref Utility
663*ec3da8bcSJed Brown **/
664*ec3da8bcSJed Brown static inline CeedInt CeedIntMax(CeedInt a, CeedInt b) { return a > b ? a : b; }
665*ec3da8bcSJed Brown 
666*ec3da8bcSJed Brown // Used to ensure initialization before CeedInit()
667*ec3da8bcSJed Brown CEED_EXTERN int CeedRegisterAll(void);
668*ec3da8bcSJed Brown // Used to ensure initialization before CeedQFunctionCreate*()
669*ec3da8bcSJed Brown CEED_EXTERN int CeedQFunctionRegisterAll(void);
670*ec3da8bcSJed Brown 
671*ec3da8bcSJed Brown #endif
672