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