xref: /libCEED/rust/libceed-sys/c-src/include/ceed/ceed.h (revision 883ab9ae5213a0a56646ac93559f89cdfadd465a)
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_LINE = 1 << 16 | 0,
498   /// Triangle - 2D shape
499   CEED_TRIANGLE = 2 << 16 | 1,
500   /// Quadralateral - 2D shape
501   CEED_QUAD = 2 << 16 | 2,
502   /// Tetrahedron - 3D shape
503   CEED_TET = 3 << 16 | 3,
504   /// Pyramid - 3D shape
505   CEED_PYRAMID = 3 << 16 | 4,
506   /// Prism - 3D shape
507   CEED_PRISM = 3 << 16 | 5,
508   /// Hexehedron - 3D shape
509   CEED_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 CeedBasisReferenceCopy(CeedBasis basis, CeedBasis *basis_copy);
530 CEED_EXTERN int CeedBasisView(CeedBasis basis, FILE *stream);
531 CEED_EXTERN int CeedBasisApply(CeedBasis basis, CeedInt num_elem,
532                                CeedTransposeMode t_mode,
533                                CeedEvalMode eval_mode, CeedVector u, CeedVector v);
534 CEED_EXTERN int CeedBasisGetCeed(CeedBasis basis, Ceed *ceed);
535 CEED_EXTERN int CeedBasisGetDimension(CeedBasis basis, CeedInt *dim);
536 CEED_EXTERN int CeedBasisGetTopology(CeedBasis basis, CeedElemTopology *topo);
537 CEED_EXTERN int CeedBasisGetNumComponents(CeedBasis basis, CeedInt *num_comp);
538 CEED_EXTERN int CeedBasisGetNumNodes(CeedBasis basis, CeedInt *P);
539 CEED_EXTERN int CeedBasisGetNumNodes1D(CeedBasis basis, CeedInt *P_1d);
540 CEED_EXTERN int CeedBasisGetNumQuadraturePoints(CeedBasis basis, CeedInt *Q);
541 CEED_EXTERN int CeedBasisGetNumQuadraturePoints1D(CeedBasis basis,
542     CeedInt *Q_1d);
543 CEED_EXTERN int CeedBasisGetQRef(CeedBasis basis, const CeedScalar **q_ref);
544 CEED_EXTERN int CeedBasisGetQWeights(CeedBasis basis,
545                                      const CeedScalar **q_weights);
546 CEED_EXTERN int CeedBasisGetInterp(CeedBasis basis, const CeedScalar **interp);
547 CEED_EXTERN int CeedBasisGetInterp1D(CeedBasis basis,
548                                      const CeedScalar **interp_1d);
549 CEED_EXTERN int CeedBasisGetGrad(CeedBasis basis, const CeedScalar **grad);
550 CEED_EXTERN int CeedBasisGetGrad1D(CeedBasis basis, const CeedScalar **grad_1d);
551 CEED_EXTERN int CeedBasisDestroy(CeedBasis *basis);
552 
553 CEED_EXTERN int CeedGaussQuadrature(CeedInt Q, CeedScalar *q_ref_1d,
554                                     CeedScalar *q_weight_1d);
555 CEED_EXTERN int CeedLobattoQuadrature(CeedInt Q, CeedScalar *q_ref_1d,
556                                       CeedScalar *q_weight_1d);
557 CEED_EXTERN int CeedQRFactorization(Ceed ceed, CeedScalar *mat, CeedScalar *tau,
558                                     CeedInt m, CeedInt n);
559 CEED_EXTERN int CeedSymmetricSchurDecomposition(Ceed ceed, CeedScalar *mat,
560     CeedScalar *lambda, CeedInt n);
561 CEED_EXTERN int CeedSimultaneousDiagonalization(Ceed ceed, CeedScalar *mat_A,
562     CeedScalar *mat_B, CeedScalar *x, CeedScalar *lambda, CeedInt n);
563 
564 /** Handle for the user provided CeedQFunction callback function
565 
566  @param[in,out] ctx  User-defined context set using CeedQFunctionSetContext() or NULL
567  @param[in] Q        Number of quadrature points at which to evaluate
568  @param[in] in       Array of pointers to each input argument in the order provided
569                        by the user in CeedQFunctionAddInput().  Each array has shape
570                        `[dim, num_comp, Q]` where `dim` is the geometric dimension for
571                        \ref CEED_EVAL_GRAD (`dim=1` for \ref CEED_EVAL_INTERP) and
572                        `num_comp` is the number of field components (`num_comp=1` for
573                        scalar fields).  This results in indexing the `i`th input at
574                        quadrature point `j` as `in[i][(d*num_comp + c)*Q + j]`.
575  @param[out]   out   Array of pointers to each output array in the order provided
576                        using CeedQFunctionAddOutput().  The shapes are as above for
577                        \a in.
578 
579  @return An error code: 0 - success, otherwise - failure
580 
581  @ingroup CeedQFunction
582 **/
583 typedef int (*CeedQFunctionUser)(void *ctx, const CeedInt Q,
584                                  const CeedScalar *const *in,
585                                  CeedScalar *const *out);
586 
587 CEED_EXTERN int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length,
588     CeedQFunctionUser f, const char *source, CeedQFunction *qf);
589 CEED_EXTERN int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name,
590     CeedQFunction *qf);
591 CEED_EXTERN int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size,
592     CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf);
593 CEED_EXTERN int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy);
594 CEED_EXTERN int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name,
595                                       CeedInt size, CeedEvalMode eval_mode);
596 CEED_EXTERN int CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name,
597                                        CeedInt size, CeedEvalMode eval_mode);
598 CEED_EXTERN int CeedQFunctionGetFields(CeedQFunction qf,
599                                        CeedInt *num_input_fields,
600                                        CeedQFunctionField **input_fields,
601                                        CeedInt *num_output_fields,
602                                        CeedQFunctionField **output_fields);
603 CEED_EXTERN int CeedQFunctionSetContext(CeedQFunction qf,
604                                         CeedQFunctionContext ctx);
605 CEED_EXTERN int CeedQFunctionView(CeedQFunction qf, FILE *stream);
606 CEED_EXTERN int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed);
607 CEED_EXTERN int CeedQFunctionApply(CeedQFunction qf, CeedInt Q,
608                                    CeedVector *u, CeedVector *v);
609 CEED_EXTERN int CeedQFunctionDestroy(CeedQFunction *qf);
610 
611 CEED_EXTERN int CeedQFunctionFieldGetName(CeedQFunctionField qf_field,
612     char **field_name);
613 CEED_EXTERN int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field,
614     CeedInt *size);
615 CEED_EXTERN int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field,
616     CeedEvalMode *eval_mode);
617 
618 /// Denotes type of data stored in a CeedQFunctionContext field
619 /// @ingroup CeedQFunction
620 typedef enum {
621   /// Double precision value
622   CEED_CONTEXT_FIELD_DOUBLE,
623   /// 32 bit integer value
624   CEED_CONTEXT_FIELD_INT32
625 } CeedContextFieldType;
626 CEED_EXTERN const char *const CeedContextFieldTypes[];
627 
628 /// Handle for object describing CeedQFunctionContext fields
629 /// @ingroup CeedQFunction
630 typedef struct {
631   const char *name;
632   const char *description;
633   CeedContextFieldType type;
634   size_t size;
635   size_t offset;
636 } CeedQFunctionContextFieldDescription;
637 
638 CEED_EXTERN int CeedQFunctionContextCreate(Ceed ceed,
639     CeedQFunctionContext *ctx);
640 CEED_EXTERN int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
641     CeedQFunctionContext *ctx_copy);
642 CEED_EXTERN int CeedQFunctionContextSetData(CeedQFunctionContext ctx,
643     CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data);
644 CEED_EXTERN int CeedQFunctionContextTakeData(CeedQFunctionContext ctx,
645     CeedMemType mem_type, void *data);
646 CEED_EXTERN int CeedQFunctionContextGetData(CeedQFunctionContext ctx,
647     CeedMemType mem_type, void *data);
648 CEED_EXTERN int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx,
649     void *data);
650 CEED_EXTERN int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,
651     const char *field_name, size_t field_offset, const char *field_description);
652 CEED_EXTERN int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,
653     const char *field_name, size_t field_offset, const char *field_description);
654 CEED_EXTERN int CeedQFunctionContextGetFieldDescriptions(CeedQFunctionContext ctx,
655     const CeedQFunctionContextFieldDescription **field_descriptions, CeedInt *num_fields);
656 CEED_EXTERN int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,
657     const char *field_name, double value);
658 CEED_EXTERN int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,
659     const char *field_name, int value);
660 CEED_EXTERN int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
661     size_t *ctx_size);
662 CEED_EXTERN int CeedQFunctionContextView(CeedQFunctionContext ctx,
663     FILE *stream);
664 CEED_EXTERN int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx);
665 
666 CEED_EXTERN int CeedOperatorCreate(Ceed ceed, CeedQFunction qf,
667                                    CeedQFunction dqf, CeedQFunction dqfT,
668                                    CeedOperator *op);
669 CEED_EXTERN int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op);
670 CEED_EXTERN int CeedOperatorReferenceCopy(CeedOperator op, CeedOperator *op_copy);
671 CEED_EXTERN int CeedOperatorSetField(CeedOperator op, const char *field_name,
672                                      CeedElemRestriction r, CeedBasis b,
673                                      CeedVector v);
674 CEED_EXTERN int CeedOperatorGetFields(CeedOperator op,
675                                       CeedInt *num_input_fields,
676                                       CeedOperatorField **input_fields,
677                                       CeedInt *num_output_fields,
678                                       CeedOperatorField **output_fields);
679 CEED_EXTERN int CeedCompositeOperatorAddSub(CeedOperator composite_op,
680     CeedOperator sub_op);
681 CEED_EXTERN int CeedOperatorCheckReady(CeedOperator op);
682 CEED_EXTERN int CeedOperatorLinearAssembleQFunction(CeedOperator op,
683     CeedVector *assembled, CeedElemRestriction *rstr, CeedRequest *request);
684 CEED_EXTERN int CeedOperatorLinearAssembleQFunctionBuildOrUpdate(CeedOperator op,
685     CeedVector *assembled, CeedElemRestriction *rstr, CeedRequest *request);
686 CEED_EXTERN int CeedOperatorLinearAssembleDiagonal(CeedOperator op,
687     CeedVector assembled, CeedRequest *request);
688 CEED_EXTERN int CeedOperatorLinearAssembleAddDiagonal(CeedOperator op,
689     CeedVector assembled, CeedRequest *request);
690 CEED_EXTERN int CeedOperatorLinearAssemblePointBlockDiagonal(CeedOperator op,
691     CeedVector assembled, CeedRequest *request);
692 CEED_EXTERN int CeedOperatorLinearAssembleAddPointBlockDiagonal(CeedOperator op,
693     CeedVector assembled, CeedRequest *request);
694 CEED_EXTERN int CeedOperatorLinearAssembleSymbolic(CeedOperator op,
695     CeedInt *num_entries, CeedInt **rows, CeedInt **cols);
696 CEED_EXTERN int CeedOperatorLinearAssemble(CeedOperator op, CeedVector values);
697 CEED_EXTERN int CeedOperatorMultigridLevelCreate(CeedOperator op_fine,
698     CeedVector p_mult_fine, CeedElemRestriction rstr_coarse, CeedBasis basis_coarse,
699     CeedOperator *op_coarse, CeedOperator *op_prolong, CeedOperator *op_restrict);
700 CEED_EXTERN int CeedOperatorMultigridLevelCreateTensorH1(
701   CeedOperator op_fine, CeedVector p_mult_fine, CeedElemRestriction rstr_coarse,
702   CeedBasis basis_coarse, const CeedScalar *interp_c_to_f, CeedOperator *op_coarse,
703   CeedOperator *op_prolong, CeedOperator *op_restrict);
704 CEED_EXTERN int CeedOperatorMultigridLevelCreateH1(CeedOperator op_fine,
705     CeedVector p_mult_fine, CeedElemRestriction rstr_coarse, CeedBasis basis_coarse,
706     const CeedScalar *interp_c_to_f, CeedOperator *op_coarse,
707     CeedOperator *op_prolong, CeedOperator *op_restrict);
708 CEED_EXTERN int CeedOperatorCreateFDMElementInverse(CeedOperator op,
709     CeedOperator *fdm_inv, CeedRequest *request);
710 CEED_EXTERN int CeedOperatorSetNumQuadraturePoints(CeedOperator op, CeedInt num_qpts);
711 CEED_EXTERN int CeedOperatorView(CeedOperator op, FILE *stream);
712 CEED_EXTERN int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed);
713 CEED_EXTERN int CeedOperatorGetNumElements(CeedOperator op, CeedInt *num_elem);
714 CEED_EXTERN int CeedOperatorGetNumQuadraturePoints(CeedOperator op,
715     CeedInt *num_qpts);
716 CEED_EXTERN int CeedOperatorContextSetDouble(CeedOperator op, const char *field_name,
717     double value);
718 CEED_EXTERN int CeedOperatorContextSetInt32(CeedOperator op, const char *field_name,
719     int value);
720 CEED_EXTERN int CeedOperatorApply(CeedOperator op, CeedVector in,
721                                   CeedVector out, CeedRequest *request);
722 CEED_EXTERN int CeedOperatorApplyAdd(CeedOperator op, CeedVector in,
723                                      CeedVector out, CeedRequest *request);
724 CEED_EXTERN int CeedOperatorDestroy(CeedOperator *op);
725 
726 CEED_EXTERN int CeedOperatorFieldGetName(CeedOperatorField op_field,
727     char **field_name);
728 CEED_EXTERN int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field,
729     CeedElemRestriction *rstr);
730 CEED_EXTERN int CeedOperatorFieldGetBasis(CeedOperatorField op_field,
731     CeedBasis *basis);
732 CEED_EXTERN int CeedOperatorFieldGetVector(CeedOperatorField op_field,
733     CeedVector *vec);
734 
735 /**
736   @brief Return integer power
737 
738   @param[in] base   The base to exponentiate
739   @param[in] power  The power to raise the base to
740 
741   @return base^power
742 
743   @ref Utility
744 **/
745 static inline CeedInt CeedIntPow(CeedInt base, CeedInt power) {
746   CeedInt result = 1;
747   while (power) {
748     if (power & 1) result *= base;
749     power >>= 1;
750     base *= base;
751   }
752   return result;
753 }
754 
755 /**
756   @brief Return minimum of two integers
757 
758   @param[in] a  The first integer to compare
759   @param[in] b  The second integer to compare
760 
761   @return The minimum of the two integers
762 
763   @ref Utility
764 **/
765 static inline CeedInt CeedIntMin(CeedInt a, CeedInt b) { return a < b ? a : b; }
766 
767 /**
768   @brief Return maximum of two integers
769 
770   @param[in] a  The first integer to compare
771   @param[in] b  The second integer to compare
772 
773   @return The maximum of the two integers
774 
775   @ref Utility
776 **/
777 static inline CeedInt CeedIntMax(CeedInt a, CeedInt b) { return a > b ? a : b; }
778 
779 // Used to ensure initialization before CeedInit()
780 CEED_EXTERN int CeedRegisterAll(void);
781 // Used to ensure initialization before CeedQFunctionCreate*()
782 CEED_EXTERN int CeedQFunctionRegisterAll(void);
783 
784 #endif
785