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