xref: /libCEED/include/ceed/ceed.h (revision 3047f7896db8a74672e0eaf4fe2741a47841cabb)
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 <stdarg.h>
123 #include <stdbool.h>
124 #include <stddef.h>
125 #include <stdint.h>
126 #include <stdio.h>
127 
128 /// Integer type, used for indexing
129 /// @ingroup Ceed
130 typedef int32_t CeedInt;
131 
132 /// Scalar (floating point) types
133 ///
134 /// @ingroup Ceed
135 typedef enum {
136   /// Single precision
137   CEED_SCALAR_FP32,
138   /// Double precision
139   CEED_SCALAR_FP64
140 } CeedScalarType;
141 /// Base scalar type for the library to use: change which header is
142 /// included to change the precision.
143 #include "ceed-f64.h"
144 
145 /// Library context created by CeedInit()
146 /// @ingroup CeedUser
147 typedef struct Ceed_private *Ceed;
148 /// Non-blocking Ceed interfaces return a CeedRequest.
149 /// To perform an operation immediately, pass \ref CEED_REQUEST_IMMEDIATE instead.
150 /// @ingroup CeedUser
151 typedef struct CeedRequest_private *CeedRequest;
152 /// Handle for vectors over the field \ref CeedScalar
153 /// @ingroup CeedVectorUser
154 typedef struct CeedVector_private *CeedVector;
155 /// Handle for object describing restriction to elements
156 /// @ingroup CeedElemRestrictionUser
157 typedef struct CeedElemRestriction_private *CeedElemRestriction;
158 /// Handle for object describing discrete finite element evaluations
159 /// @ingroup CeedBasisUser
160 typedef struct CeedBasis_private *CeedBasis;
161 /// Handle for object describing CeedQFunction fields
162 /// @ingroup CeedQFunctionBackend
163 typedef struct CeedQFunctionField_private *CeedQFunctionField;
164 /// Handle for object describing functions evaluated independently at quadrature points
165 /// @ingroup CeedQFunctionUser
166 typedef struct CeedQFunction_private *CeedQFunction;
167 /// Handle for object describing CeedOperator fields
168 /// @ingroup CeedOperatorBackend
169 typedef struct CeedOperatorField_private *CeedOperatorField;
170 /// Handle for object describing context data for CeedQFunctions
171 /// @ingroup CeedQFunctionUser
172 typedef struct CeedQFunctionContext_private *CeedQFunctionContext;
173 /// Handle for object describing registered fields for CeedQFunctionContext
174 /// @ingroup CeedQFunctionUser
175 typedef struct CeedContextFieldLabel_private *CeedContextFieldLabel;
176 /// Handle for object describing FE-type operators acting on vectors
177 ///
178 /// Given an element restriction \f$E\f$, basis evaluator \f$B\f$, and
179 ///   quadrature function\f$f\f$, a CeedOperator expresses operations of the form
180 ///   $$ E^T B^T f(B E u) $$
181 ///   acting on the vector \f$u\f$.
182 /// @ingroup CeedOperatorUser
183 typedef struct CeedOperator_private *CeedOperator;
184 
185 CEED_EXTERN int CeedRegistryGetList(size_t *n, char ***const resources, CeedInt **array);
186 CEED_EXTERN int CeedInit(const char *resource, Ceed *ceed);
187 CEED_EXTERN int CeedReferenceCopy(Ceed ceed, Ceed *ceed_copy);
188 CEED_EXTERN int CeedGetResource(Ceed ceed, const char **resource);
189 CEED_EXTERN int CeedIsDeterministic(Ceed ceed, bool *is_deterministic);
190 CEED_EXTERN int CeedView(Ceed ceed, FILE *stream);
191 CEED_EXTERN int CeedDestroy(Ceed *ceed);
192 
193 CEED_EXTERN int CeedErrorImpl(Ceed, const char *, int, const char *, int,
194                               const char *, ...);
195 /// Raise an error on ceed object
196 ///
197 /// @param ceed Ceed library context or NULL
198 /// @param ecode Error code (int)
199 /// @param ... printf-style format string followed by arguments as needed
200 ///
201 /// @ingroup Ceed
202 /// @sa CeedSetErrorHandler()
203 #if defined(__clang__)
204 /// Use nonstandard ternary to convince the compiler/clang-tidy that this
205 /// function never returns zero.
206 #  define CeedError(ceed, ecode, ...)                                     \
207   (CeedErrorImpl((ceed), __FILE__, __LINE__, __func__, (ecode), __VA_ARGS__), (ecode))
208 #else
209 #  define CeedError(ceed, ecode, ...)                                     \
210   CeedErrorImpl((ceed), __FILE__, __LINE__, __func__, (ecode), __VA_ARGS__) ?: (ecode)
211 #endif
212 
213 /// Ceed error handlers
214 CEED_EXTERN int CeedErrorReturn(Ceed, const char *, int, const char *, int,
215                                 const char *, va_list *);
216 CEED_EXTERN int CeedErrorStore(Ceed, const char *, int, const char *, int,
217                                const char *, va_list *);
218 CEED_EXTERN int CeedErrorAbort(Ceed, const char *, int, const char *, int,
219                                const char *, va_list *);
220 CEED_EXTERN int CeedErrorExit(Ceed, const char *, int, const char *, int,
221                               const char *, va_list *);
222 typedef int (*CeedErrorHandler)(Ceed, const char *, int,
223                                 const char *, int, const char *,
224                                 va_list *);
225 CEED_EXTERN int CeedSetErrorHandler(Ceed ceed, CeedErrorHandler eh);
226 CEED_EXTERN int CeedGetErrorMessage(Ceed, const char **err_msg);
227 CEED_EXTERN int CeedResetErrorMessage(Ceed, const char **err_msg);
228 
229 /// libCEED library version numbering
230 /// @ingroup Ceed
231 #define CEED_VERSION_MAJOR 0
232 #define CEED_VERSION_MINOR 9
233 #define CEED_VERSION_PATCH 0
234 #define CEED_VERSION_RELEASE false
235 
236 /// Compile-time check that the the current library version is at least as
237 /// recent as the specified version. This macro is typically used in
238 /// @code
239 /// #if CEED_VERSION_GE(0, 8, 0)
240 ///   code path that needs at least 0.8.0
241 /// #else
242 ///   fallback code for older versions
243 /// #endif
244 /// @endcode
245 ///
246 /// A non-release version always compares as positive infinity.
247 ///
248 /// @param major   Major version
249 /// @param minor   Minor version
250 /// @param patch   Patch (subminor) version
251 ///
252 /// @ingroup Ceed
253 /// @sa CeedGetVersion()
254 #define CEED_VERSION_GE(major, minor, patch)                                   \
255   (!CEED_VERSION_RELEASE ||                                                    \
256    (CEED_VERSION_MAJOR > major ||                                              \
257     (CEED_VERSION_MAJOR == major &&                                            \
258      (CEED_VERSION_MINOR > minor ||                                            \
259       (CEED_VERSION_MINOR == minor && CEED_VERSION_PATCH >= patch)))))
260 
261 CEED_EXTERN int CeedGetVersion(int *major, int *minor, int *patch,
262                                bool *release);
263 
264 CEED_EXTERN int CeedGetScalarType(CeedScalarType *scalar_type);
265 
266 /// Ceed Errors
267 ///
268 /// This enum is used to specify the type of error returned by a function.
269 /// A zero error code is success, negative error codes indicate terminal errors
270 /// and positive error codes indicate nonterminal errors. With nonterminal errors
271 /// the object state has not been modifiend, but with terminal errors the object
272 /// data is likely modified or corrupted.
273 /// @ingroup Ceed
274 typedef enum {
275   /// Success error code
276   CEED_ERROR_SUCCESS      = 0,
277   /// Minor error, generic
278   CEED_ERROR_MINOR        = 1,
279   /// Minor error, dimension mismatch in inputs
280   CEED_ERROR_DIMENSION    = 2,
281   /// Minor error, incomplete object setup
282   CEED_ERROR_INCOMPLETE   = 3,
283   /// Minor error, incompatible arguments/configuration
284   CEED_ERROR_INCOMPATIBLE = 4,
285   /// Minor error, access lock problem
286   CEED_ERROR_ACCESS       = 5,
287   /// Major error, generic
288   CEED_ERROR_MAJOR        = -1,
289   /// Major error, internal backend error
290   CEED_ERROR_BACKEND      = -2,
291   /// Major error, operation unsupported by current backend
292   CEED_ERROR_UNSUPPORTED  = -3,
293 } CeedErrorType;
294 CEED_EXTERN const char *const *CeedErrorTypes;
295 
296 /// Specify memory type
297 ///
298 /// Many Ceed interfaces take or return pointers to memory.  This enum is used to
299 /// specify where the memory being provided or requested must reside.
300 /// @ingroup Ceed
301 typedef enum {
302   /// Memory resides on the host
303   CEED_MEM_HOST,
304   /// Memory resides on a device (corresponding to \ref Ceed resource)
305   CEED_MEM_DEVICE,
306 } CeedMemType;
307 CEED_EXTERN const char *const CeedMemTypes[];
308 
309 CEED_EXTERN int CeedGetPreferredMemType(Ceed ceed, CeedMemType *type);
310 
311 /// Conveys ownership status of arrays passed to Ceed interfaces.
312 /// @ingroup Ceed
313 typedef enum {
314   /// Implementation will copy the values and not store the passed pointer.
315   CEED_COPY_VALUES,
316   /// Implementation can use and modify the data provided by the user, but does
317   /// not take ownership.
318   CEED_USE_POINTER,
319   /// Implementation takes ownership of the pointer and will free using
320   /// CeedFree() when done using it.  The user should not assume that the
321   /// pointer remains valid after ownership has been transferred.  Note that
322   /// arrays allocated using C++ operator new or other allocators cannot
323   /// generally be freed using CeedFree().  CeedFree() is capable of freeing any
324   /// memory that can be freed using free(3).
325   CEED_OWN_POINTER,
326 } CeedCopyMode;
327 CEED_EXTERN const char *const CeedCopyModes[];
328 
329 /// Denotes type of vector norm to be computed
330 /// @ingroup CeedVector
331 typedef enum {
332   /// L_1 norm: sum_i |x_i|
333   CEED_NORM_1,
334   /// L_2 norm: sqrt(sum_i |x_i|^2)
335   CEED_NORM_2,
336   /// L_Infinity norm: max_i |x_i|
337   CEED_NORM_MAX,
338 } CeedNormType;
339 
340 CEED_EXTERN int CeedVectorCreate(Ceed ceed, CeedInt len, CeedVector *vec);
341 CEED_EXTERN int CeedVectorReferenceCopy(CeedVector vec, CeedVector *vec_copy);
342 CEED_EXTERN int CeedVectorSetArray(CeedVector vec, CeedMemType mem_type,
343                                    CeedCopyMode copy_mode, CeedScalar *array);
344 CEED_EXTERN int CeedVectorSetValue(CeedVector vec, CeedScalar value);
345 CEED_EXTERN int CeedVectorSyncArray(CeedVector vec, CeedMemType mem_type);
346 CEED_EXTERN int CeedVectorTakeArray(CeedVector vec, CeedMemType mem_type,
347                                     CeedScalar **array);
348 CEED_EXTERN int CeedVectorGetArray(CeedVector vec, CeedMemType mem_type,
349                                    CeedScalar **array);
350 CEED_EXTERN int CeedVectorGetArrayRead(CeedVector vec, CeedMemType mem_type,
351                                        const CeedScalar **array);
352 CEED_EXTERN int CeedVectorGetArrayWrite(CeedVector vec, CeedMemType mem_type,
353                                         CeedScalar **array);
354 CEED_EXTERN int CeedVectorRestoreArray(CeedVector vec, CeedScalar **array);
355 CEED_EXTERN int CeedVectorRestoreArrayRead(CeedVector vec,
356     const CeedScalar **array);
357 CEED_EXTERN int CeedVectorNorm(CeedVector vec, CeedNormType type,
358                                CeedScalar *norm);
359 CEED_EXTERN int CeedVectorScale(CeedVector x, CeedScalar alpha);
360 CEED_EXTERN int CeedVectorAXPY(CeedVector y, CeedScalar alpha, CeedVector x);
361 CEED_EXTERN int CeedVectorPointwiseMult(CeedVector w, CeedVector x, CeedVector y);
362 CEED_EXTERN int CeedVectorReciprocal(CeedVector vec);
363 CEED_EXTERN int CeedVectorView(CeedVector vec, const char *fp_fmt, FILE *stream);
364 CEED_EXTERN int CeedVectorGetCeed(CeedVector vec, Ceed *ceed);
365 CEED_EXTERN int CeedVectorGetLength(CeedVector vec, CeedInt *length);
366 CEED_EXTERN int CeedVectorDestroy(CeedVector *vec);
367 
368 CEED_EXTERN CeedRequest *const CEED_REQUEST_IMMEDIATE;
369 CEED_EXTERN CeedRequest *const CEED_REQUEST_ORDERED;
370 CEED_EXTERN int CeedRequestWait(CeedRequest *req);
371 
372 /// Argument for CeedOperatorSetField that vector is collocated with
373 /// quadrature points, used with QFunction eval mode CEED_EVAL_NONE
374 /// or CEED_EVAL_INTERP only, not with CEED_EVAL_GRAD, CEED_EVAL_DIV,
375 /// or CEED_EVAL_CURL
376 /// @ingroup CeedBasis
377 CEED_EXTERN const CeedBasis CEED_BASIS_COLLOCATED;
378 
379 /// Argument for CeedOperatorSetField to use active input or output
380 /// @ingroup CeedVector
381 CEED_EXTERN const CeedVector CEED_VECTOR_ACTIVE;
382 
383 /// Argument for CeedOperatorSetField to use no vector, used with
384 /// qfunction input with eval mode CEED_EVAL_WEIGHT
385 /// @ingroup CeedVector
386 CEED_EXTERN const CeedVector CEED_VECTOR_NONE;
387 
388 /// Argument for CeedOperatorSetField to use no ElemRestriction, only used with
389 /// eval mode CEED_EVAL_WEIGHT.
390 /// @ingroup CeedElemRestriction
391 CEED_EXTERN const CeedElemRestriction CEED_ELEMRESTRICTION_NONE;
392 
393 /// Argument for CeedOperatorCreate that QFunction is not created by user.
394 /// Only used for QFunctions dqf and dqfT. If implemented, a backend may
395 /// attempt to provide the action of these QFunctions.
396 /// @ingroup CeedQFunction
397 CEED_EXTERN const CeedQFunction CEED_QFUNCTION_NONE;
398 
399 /// Denotes whether a linear transformation or its transpose should be applied
400 /// @ingroup CeedBasis
401 typedef enum {
402   /// Apply the linear transformation
403   CEED_NOTRANSPOSE,
404   /// Apply the transpose
405   CEED_TRANSPOSE
406 } CeedTransposeMode;
407 CEED_EXTERN const char *const CeedTransposeModes[];
408 
409 /// Argument for CeedElemRestrictionCreateStrided that L-vector is in
410 /// the Ceed backend's preferred layout. This argument should only be used
411 /// with vectors created by a Ceed backend.
412 /// @ingroup CeedElemRestriction
413 CEED_EXTERN const CeedInt CEED_STRIDES_BACKEND[3];
414 
415 CEED_EXTERN int CeedElemRestrictionCreate(Ceed ceed, CeedInt num_elem,
416     CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedInt l_size,
417     CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets,
418     CeedElemRestriction *rstr);
419 CEED_EXTERN int CeedElemRestrictionCreateOriented(Ceed ceed, CeedInt num_elem,
420     CeedInt elem_size, CeedInt num_comp, CeedInt comp_stride, CeedInt l_size,
421     CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets,
422     const bool *orient, CeedElemRestriction *rstr);
423 CEED_EXTERN int CeedElemRestrictionCreateStrided(Ceed ceed,
424     CeedInt num_elem, CeedInt elem_size, CeedInt num_comp, CeedInt l_size,
425     const CeedInt strides[3], CeedElemRestriction *rstr);
426 CEED_EXTERN int CeedElemRestrictionCreateBlocked(Ceed ceed, CeedInt num_elem,
427     CeedInt elem_size, CeedInt blk_size, CeedInt num_comp, CeedInt comp_stride,
428     CeedInt l_size, CeedMemType mem_type, CeedCopyMode copy_mode,
429     const CeedInt *offsets, CeedElemRestriction *rstr);
430 CEED_EXTERN int CeedElemRestrictionCreateBlockedStrided(Ceed ceed,
431     CeedInt num_elem, CeedInt elem_size, CeedInt blk_size, CeedInt num_comp,
432     CeedInt l_size, const CeedInt strides[3], CeedElemRestriction *rstr);
433 CEED_EXTERN int CeedElemRestrictionReferenceCopy(CeedElemRestriction rstr,
434     CeedElemRestriction *rstr_copy);
435 CEED_EXTERN int CeedElemRestrictionCreateVector(CeedElemRestriction rstr,
436     CeedVector *lvec, CeedVector *evec);
437 CEED_EXTERN int CeedElemRestrictionApply(CeedElemRestriction rstr,
438     CeedTransposeMode t_mode, CeedVector u, CeedVector ru, CeedRequest *request);
439 CEED_EXTERN int CeedElemRestrictionApplyBlock(CeedElemRestriction rstr,
440     CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector ru,
441     CeedRequest *request);
442 CEED_EXTERN int CeedElemRestrictionGetCeed(CeedElemRestriction rstr,
443     Ceed *ceed);
444 CEED_EXTERN int CeedElemRestrictionGetCompStride(CeedElemRestriction rstr,
445     CeedInt *comp_stride);
446 CEED_EXTERN int CeedElemRestrictionGetNumElements(CeedElemRestriction rstr,
447     CeedInt *num_elem);
448 CEED_EXTERN int CeedElemRestrictionGetElementSize(CeedElemRestriction rstr,
449     CeedInt *elem_size);
450 CEED_EXTERN int CeedElemRestrictionGetLVectorSize(CeedElemRestriction rstr,
451     CeedInt *l_size);
452 CEED_EXTERN int CeedElemRestrictionGetNumComponents(CeedElemRestriction rstr,
453     CeedInt *num_comp);
454 CEED_EXTERN int CeedElemRestrictionGetNumBlocks(CeedElemRestriction rstr,
455     CeedInt *num_blk);
456 CEED_EXTERN int CeedElemRestrictionGetBlockSize(CeedElemRestriction rstr,
457     CeedInt *blk_size);
458 CEED_EXTERN int CeedElemRestrictionGetMultiplicity(CeedElemRestriction rstr,
459     CeedVector mult);
460 CEED_EXTERN int CeedElemRestrictionView(CeedElemRestriction rstr, FILE *stream);
461 CEED_EXTERN int CeedElemRestrictionDestroy(CeedElemRestriction *rstr);
462 
463 // The formalism here is that we have the structure
464 //  \int_\Omega v^T f_0(u, \nabla u, qdata) + (\nabla v)^T f_1(u, \nabla u, qdata)
465 // where gradients are with respect to the reference element.
466 
467 /// Basis evaluation mode
468 ///
469 /// Modes can be bitwise ORed when passing to most functions.
470 /// @ingroup CeedBasis
471 typedef enum {
472   /// Perform no evaluation (either because there is no data or it is already at
473   /// quadrature points)
474   CEED_EVAL_NONE   = 0,
475   /// Interpolate from nodes to quadrature points
476   CEED_EVAL_INTERP = 1,
477   /// Evaluate gradients at quadrature points from input in a nodal basis
478   CEED_EVAL_GRAD   = 2,
479   /// Evaluate divergence at quadrature points from input in a nodal basis
480   CEED_EVAL_DIV    = 4,
481   /// Evaluate curl at quadrature points from input in a nodal basis
482   CEED_EVAL_CURL   = 8,
483   /// Using no input, evaluate quadrature weights on the reference element
484   CEED_EVAL_WEIGHT = 16,
485 } CeedEvalMode;
486 CEED_EXTERN const char *const CeedEvalModes[];
487 
488 /// Type of quadrature; also used for location of nodes
489 /// @ingroup CeedBasis
490 typedef enum {
491   /// Gauss-Legendre quadrature
492   CEED_GAUSS         = 0,
493   /// Gauss-Legendre-Lobatto quadrature
494   CEED_GAUSS_LOBATTO = 1,
495 } CeedQuadMode;
496 CEED_EXTERN const char *const CeedQuadModes[];
497 
498 /// Type of basis shape to create non-tensor H1 element basis
499 ///
500 /// Dimension can be extracted with bitwise AND
501 /// (CeedElemTopology & 2**(dim + 2)) == TRUE
502 /// @ingroup CeedBasis
503 typedef enum {
504   /// Line
505   CEED_TOPOLOGY_LINE     = 1 << 16 | 0,
506   /// Triangle - 2D shape
507   CEED_TOPOLOGY_TRIANGLE = 2 << 16 | 1,
508   /// Quadralateral - 2D shape
509   CEED_TOPOLOGY_QUAD     = 2 << 16 | 2,
510   /// Tetrahedron - 3D shape
511   CEED_TOPOLOGY_TET      = 3 << 16 | 3,
512   /// Pyramid - 3D shape
513   CEED_TOPOLOGY_PYRAMID  = 3 << 16 | 4,
514   /// Prism - 3D shape
515   CEED_TOPOLOGY_PRISM    = 3 << 16 | 5,
516   /// Hexehedron - 3D shape
517   CEED_TOPOLOGY_HEX      = 3 << 16 | 6,
518 } CeedElemTopology;
519 CEED_EXTERN const char *const CeedElemTopologies[];
520 
521 CEED_EXTERN int CeedBasisCreateTensorH1Lagrange(Ceed ceed, CeedInt dim,
522     CeedInt num_comp, CeedInt P, CeedInt Q, CeedQuadMode quad_mode, CeedBasis *basis);
523 CEED_EXTERN int CeedBasisCreateTensorH1(Ceed ceed, CeedInt dim, CeedInt num_comp,
524                                         CeedInt P_1d, CeedInt Q_1d,
525                                         const CeedScalar *interp_1d,
526                                         const CeedScalar *grad_1d,
527                                         const CeedScalar *q_ref_1d,
528                                         const CeedScalar *q_weight_1d,
529                                         CeedBasis *basis);
530 CEED_EXTERN int CeedBasisCreateH1(Ceed ceed, CeedElemTopology topo,
531                                   CeedInt num_comp,
532                                   CeedInt num_nodes, CeedInt nqpts,
533                                   const CeedScalar *interp,
534                                   const CeedScalar *grad,
535                                   const CeedScalar *q_ref,
536                                   const CeedScalar *q_weights, CeedBasis *basis);
537 CEED_EXTERN int CeedBasisCreateHdiv(Ceed ceed, CeedElemTopology topo,
538                                     CeedInt num_comp,
539                                     CeedInt num_nodes, CeedInt nqpts,
540                                     const CeedScalar *interp,
541                                     const CeedScalar *div,
542                                     const CeedScalar *q_ref,
543                                     const CeedScalar *q_weights, CeedBasis *basis);
544 CEED_EXTERN int CeedBasisReferenceCopy(CeedBasis basis, CeedBasis *basis_copy);
545 CEED_EXTERN int CeedBasisView(CeedBasis basis, FILE *stream);
546 CEED_EXTERN int CeedBasisApply(CeedBasis basis, CeedInt num_elem,
547                                CeedTransposeMode t_mode,
548                                CeedEvalMode eval_mode, CeedVector u, CeedVector v);
549 CEED_EXTERN int CeedBasisGetCeed(CeedBasis basis, Ceed *ceed);
550 CEED_EXTERN int CeedBasisGetDimension(CeedBasis basis, CeedInt *dim);
551 CEED_EXTERN int CeedBasisGetTopology(CeedBasis basis, CeedElemTopology *topo);
552 CEED_EXTERN int CeedBasisGetNumQuadratureComponents(CeedBasis basis, CeedInt *Q_comp);
553 CEED_EXTERN int CeedBasisGetNumComponents(CeedBasis basis, CeedInt *num_comp);
554 CEED_EXTERN int CeedBasisGetNumNodes(CeedBasis basis, CeedInt *P);
555 CEED_EXTERN int CeedBasisGetNumNodes1D(CeedBasis basis, CeedInt *P_1d);
556 CEED_EXTERN int CeedBasisGetNumQuadraturePoints(CeedBasis basis, CeedInt *Q);
557 CEED_EXTERN int CeedBasisGetNumQuadraturePoints1D(CeedBasis basis,
558     CeedInt *Q_1d);
559 CEED_EXTERN int CeedBasisGetQRef(CeedBasis basis, const CeedScalar **q_ref);
560 CEED_EXTERN int CeedBasisGetQWeights(CeedBasis basis,
561                                      const CeedScalar **q_weights);
562 CEED_EXTERN int CeedBasisGetInterp(CeedBasis basis, const CeedScalar **interp);
563 CEED_EXTERN int CeedBasisGetInterp1D(CeedBasis basis,
564                                      const CeedScalar **interp_1d);
565 CEED_EXTERN int CeedBasisGetGrad(CeedBasis basis, const CeedScalar **grad);
566 CEED_EXTERN int CeedBasisGetGrad1D(CeedBasis basis, const CeedScalar **grad_1d);
567 CEED_EXTERN int CeedBasisGetDiv(CeedBasis basis, const CeedScalar **div);
568 CEED_EXTERN int CeedBasisDestroy(CeedBasis *basis);
569 
570 CEED_EXTERN int CeedGaussQuadrature(CeedInt Q, CeedScalar *q_ref_1d,
571                                     CeedScalar *q_weight_1d);
572 CEED_EXTERN int CeedLobattoQuadrature(CeedInt Q, CeedScalar *q_ref_1d,
573                                       CeedScalar *q_weight_1d);
574 CEED_EXTERN int CeedQRFactorization(Ceed ceed, CeedScalar *mat, CeedScalar *tau,
575                                     CeedInt m, CeedInt n);
576 CEED_EXTERN int CeedSymmetricSchurDecomposition(Ceed ceed, CeedScalar *mat,
577     CeedScalar *lambda, CeedInt n);
578 CEED_EXTERN int CeedSimultaneousDiagonalization(Ceed ceed, CeedScalar *mat_A,
579     CeedScalar *mat_B, CeedScalar *x, CeedScalar *lambda, CeedInt n);
580 
581 /** Handle for the user provided CeedQFunction callback function
582 
583  @param[in,out] ctx  User-defined context set using CeedQFunctionSetContext() or NULL
584  @param[in] Q        Number of quadrature points at which to evaluate
585  @param[in] in       Array of pointers to each input argument in the order provided
586                        by the user in CeedQFunctionAddInput().  Each array has shape
587                        `[dim, num_comp, Q]` where `dim` is the geometric dimension for
588                        \ref CEED_EVAL_GRAD (`dim=1` for \ref CEED_EVAL_INTERP) and
589                        `num_comp` is the number of field components (`num_comp=1` for
590                        scalar fields).  This results in indexing the `i`th input at
591                        quadrature point `j` as `in[i][(d*num_comp + c)*Q + j]`.
592  @param[out]   out   Array of pointers to each output array in the order provided
593                        using CeedQFunctionAddOutput().  The shapes are as above for
594                        \a in.
595 
596  @return An error code: 0 - success, otherwise - failure
597 
598  @ingroup CeedQFunction
599 **/
600 typedef int (*CeedQFunctionUser)(void *ctx, const CeedInt Q,
601                                  const CeedScalar *const *in,
602                                  CeedScalar *const *out);
603 
604 CEED_EXTERN int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length,
605     CeedQFunctionUser f, const char *source, CeedQFunction *qf);
606 CEED_EXTERN int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name,
607     CeedQFunction *qf);
608 CEED_EXTERN int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size,
609     CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf);
610 CEED_EXTERN int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy);
611 CEED_EXTERN int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name,
612                                       CeedInt size, CeedEvalMode eval_mode);
613 CEED_EXTERN int CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name,
614                                        CeedInt size, CeedEvalMode eval_mode);
615 CEED_EXTERN int CeedQFunctionGetFields(CeedQFunction qf,
616                                        CeedInt *num_input_fields,
617                                        CeedQFunctionField **input_fields,
618                                        CeedInt *num_output_fields,
619                                        CeedQFunctionField **output_fields);
620 CEED_EXTERN int CeedQFunctionSetContext(CeedQFunction qf,
621                                         CeedQFunctionContext ctx);
622 CEED_EXTERN int CeedQFunctionSetContextWritable(CeedQFunction qf, bool is_writable);
623 CEED_EXTERN int CeedQFunctionView(CeedQFunction qf, FILE *stream);
624 CEED_EXTERN int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed);
625 CEED_EXTERN int CeedQFunctionApply(CeedQFunction qf, CeedInt Q,
626                                    CeedVector *u, CeedVector *v);
627 CEED_EXTERN int CeedQFunctionDestroy(CeedQFunction *qf);
628 
629 CEED_EXTERN int CeedQFunctionFieldGetName(CeedQFunctionField qf_field,
630     char **field_name);
631 CEED_EXTERN int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field,
632     CeedInt *size);
633 CEED_EXTERN int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field,
634     CeedEvalMode *eval_mode);
635 
636 /// Denotes type of data stored in a CeedQFunctionContext field
637 /// @ingroup CeedQFunction
638 typedef enum {
639   /// Double precision value
640   CEED_CONTEXT_FIELD_DOUBLE = 1,
641   /// 32 bit integer value
642   CEED_CONTEXT_FIELD_INT32  = 2,
643 } CeedContextFieldType;
644 CEED_EXTERN const char *const CeedContextFieldTypes[];
645 
646 CEED_EXTERN int CeedQFunctionContextCreate(Ceed ceed,
647     CeedQFunctionContext *ctx);
648 CEED_EXTERN int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
649     CeedQFunctionContext *ctx_copy);
650 CEED_EXTERN int CeedQFunctionContextSetData(CeedQFunctionContext ctx,
651     CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data);
652 CEED_EXTERN int CeedQFunctionContextTakeData(CeedQFunctionContext ctx,
653     CeedMemType mem_type, void *data);
654 CEED_EXTERN int CeedQFunctionContextGetData(CeedQFunctionContext ctx,
655     CeedMemType mem_type, void *data);
656 CEED_EXTERN int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx,
657     CeedMemType mem_type, void *data);
658 CEED_EXTERN int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx,
659     void *data);
660 CEED_EXTERN int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx,
661     void *data);
662 CEED_EXTERN int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,
663     const char *field_name, size_t field_offset, size_t num_values,
664     const char *field_description);
665 CEED_EXTERN int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,
666     const char *field_name, size_t field_offset, size_t num_values,
667     const char *field_description);
668 CEED_EXTERN int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx,
669     const char *field_name, CeedContextFieldLabel *field_label);
670 CEED_EXTERN int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx,
671     const CeedContextFieldLabel **field_labels, CeedInt *num_fields);
672 CEED_EXTERN int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label,
673     const char **field_name, const char **field_description, size_t *num_values,
674     CeedContextFieldType *field_type);
675 CEED_EXTERN int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,
676     CeedContextFieldLabel field_label, double *values);
677 CEED_EXTERN int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,
678     CeedContextFieldLabel field_label, int *values);
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      ptrdiff_t *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 CeedOperatorContextGetFieldLabel(CeedOperator op,
736     const char *field_name, CeedContextFieldLabel *field_label);
737 CEED_EXTERN int CeedOperatorContextSetDouble(CeedOperator op,
738     CeedContextFieldLabel field_label, double *values);
739 CEED_EXTERN int CeedOperatorContextSetInt32(CeedOperator op,
740     CeedContextFieldLabel field_label, int *values);
741 CEED_EXTERN int CeedOperatorApply(CeedOperator op, CeedVector in,
742                                   CeedVector out, CeedRequest *request);
743 CEED_EXTERN int CeedOperatorApplyAdd(CeedOperator op, CeedVector in,
744                                      CeedVector out, CeedRequest *request);
745 CEED_EXTERN int CeedOperatorDestroy(CeedOperator *op);
746 
747 CEED_EXTERN int CeedOperatorFieldGetName(CeedOperatorField op_field,
748     char **field_name);
749 CEED_EXTERN int CeedOperatorFieldGetElemRestriction(CeedOperatorField op_field,
750     CeedElemRestriction *rstr);
751 CEED_EXTERN int CeedOperatorFieldGetBasis(CeedOperatorField op_field,
752     CeedBasis *basis);
753 CEED_EXTERN int CeedOperatorFieldGetVector(CeedOperatorField op_field,
754     CeedVector *vec);
755 
756 /**
757   @brief Return integer power
758 
759   @param[in] base   The base to exponentiate
760   @param[in] power  The power to raise the base to
761 
762   @return base^power
763 
764   @ref Utility
765 **/
766 static inline CeedInt CeedIntPow(CeedInt base, CeedInt power) {
767   CeedInt result = 1;
768   while (power) {
769     if (power & 1) result *= base;
770     power >>= 1;
771     base *= base;
772   }
773   return result;
774 }
775 
776 /**
777   @brief Return minimum 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 minimum of the two integers
783 
784   @ref Utility
785 **/
786 static inline CeedInt CeedIntMin(CeedInt a, CeedInt b) { return a < b ? a : b; }
787 
788 /**
789   @brief Return maximum of two integers
790 
791   @param[in] a  The first integer to compare
792   @param[in] b  The second integer to compare
793 
794   @return The maximum of the two integers
795 
796   @ref Utility
797 **/
798 static inline CeedInt CeedIntMax(CeedInt a, CeedInt b) { return a > b ? a : b; }
799 
800 // Used to ensure initialization before CeedInit()
801 CEED_EXTERN int CeedRegisterAll(void);
802 // Used to ensure initialization before CeedQFunctionCreate*()
803 CEED_EXTERN int CeedQFunctionRegisterAll(void);
804 
805 #endif
806