xref: /libCEED/interface/ceed-qfunction.c (revision 4d537eea83dd2f1011134892241345b6ac537f56)
1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details.
4d7b241e6Sjeremylt //
5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral
7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and
8d7b241e6Sjeremylt // source code availability see http://github.com/ceed.
9d7b241e6Sjeremylt //
10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for
13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including
14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early
15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
16d7b241e6Sjeremylt 
17d7b241e6Sjeremylt #include <ceed-impl.h>
18d863ab9bSjeremylt #include <ceed-backend.h>
19d7b241e6Sjeremylt #include <string.h>
20d7b241e6Sjeremylt 
21dfdf5a53Sjeremylt /// @file
22dfdf5a53Sjeremylt /// Implementation of public CeedQFunction interfaces
23dfdf5a53Sjeremylt ///
24dfdf5a53Sjeremylt /// @addtogroup CeedQFunction
25dfdf5a53Sjeremylt /// @{
26d7b241e6Sjeremylt 
27d7b241e6Sjeremylt /**
28d7b241e6Sjeremylt   @brief Create a CeedQFunction for evaluating interior (volumetric) terms.
29d7b241e6Sjeremylt 
30b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedQFunction will be created
31d7b241e6Sjeremylt   @param vlength    Vector length.  Caller must ensure that number of quadrature
32d7b241e6Sjeremylt                     points is a multiple of vlength.
33d7b241e6Sjeremylt   @param f          Function pointer to evaluate action at quadrature points.
349f0427d9SYohann                     See \ref CeedQFunctionUser.
35d7b241e6Sjeremylt   @param focca      OCCA identifier "file.c:function_name" for definition of `f`
36b11c1e72Sjeremylt   @param[out] qf    Address of the variable where the newly created
37b11c1e72Sjeremylt                      CeedQFunction will be stored
38b11c1e72Sjeremylt 
39b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
40d7b241e6Sjeremylt 
418795c945Sjeremylt   See \ref CeedQFunctionUser for details on the call-back function @a f's
428795c945Sjeremylt     arguments.
43d7b241e6Sjeremylt 
44dfdf5a53Sjeremylt   @ref Basic
45dfdf5a53Sjeremylt **/
46d7b241e6Sjeremylt int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vlength,
479f0427d9SYohann                                 CeedQFunctionUser f,
48d7b241e6Sjeremylt                                 const char *focca, CeedQFunction *qf) {
49d7b241e6Sjeremylt   int ierr;
50d7b241e6Sjeremylt   char *focca_copy;
51d7b241e6Sjeremylt 
525fe0d4faSjeremylt   if (!ceed->QFunctionCreate) {
535fe0d4faSjeremylt     Ceed delegate;
54aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "QFunction"); CeedChk(ierr);
555fe0d4faSjeremylt 
565fe0d4faSjeremylt     if (!delegate)
57d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support QFunctionCreate");
585fe0d4faSjeremylt 
591dfeef1dSjeremylt     ierr = CeedQFunctionCreateInterior(delegate, vlength, f, focca, qf);
601dfeef1dSjeremylt     CeedChk(ierr);
615fe0d4faSjeremylt     return 0;
625fe0d4faSjeremylt   }
635fe0d4faSjeremylt 
64d7b241e6Sjeremylt   ierr = CeedCalloc(1,qf); CeedChk(ierr);
65d7b241e6Sjeremylt   (*qf)->ceed = ceed;
66d7b241e6Sjeremylt   ceed->refcount++;
67d7b241e6Sjeremylt   (*qf)->refcount = 1;
68d7b241e6Sjeremylt   (*qf)->vlength = vlength;
69d7b241e6Sjeremylt   (*qf)->function = f;
70d7b241e6Sjeremylt   ierr = CeedCalloc(strlen(focca)+1, &focca_copy); CeedChk(ierr);
71409ab9adSjeremylt   strncpy(focca_copy, focca, strlen(focca)+1);
72d7b241e6Sjeremylt   (*qf)->focca = focca_copy;
73fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*qf)->inputfields); CeedChk(ierr);
74fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*qf)->outputfields); CeedChk(ierr);
75d7b241e6Sjeremylt   ierr = ceed->QFunctionCreate(*qf); CeedChk(ierr);
76d7b241e6Sjeremylt   return 0;
77d7b241e6Sjeremylt }
78d7b241e6Sjeremylt 
79b11c1e72Sjeremylt /**
80a0a97fcfSJed Brown   @brief Set a CeedQFunction field, used by CeedQFunctionAddInput/Output
81b11c1e72Sjeremylt 
82b11c1e72Sjeremylt   @param f          CeedQFunctionField
83b11c1e72Sjeremylt   @param fieldname  Name of QFunction field
84*4d537eeaSYohann   @param size       Size of QFunction field, ncomp * (dim for CEED_EVAL_GRAD or
85*4d537eeaSYohann                       1 for CEED_EVAL_NONE and CEED_EVAL_INTERP)
86b11c1e72Sjeremylt   @param emode      \ref CEED_EVAL_NONE to use values directly,
87b11c1e72Sjeremylt                       \ref CEED_EVAL_INTERP to use interpolated values,
88b11c1e72Sjeremylt                       \ref CEED_EVAL_GRAD to use gradients.
89b11c1e72Sjeremylt 
90b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
91dfdf5a53Sjeremylt 
92dfdf5a53Sjeremylt   @ref Developer
93b11c1e72Sjeremylt **/
94fe2413ffSjeremylt static int CeedQFunctionFieldSet(CeedQFunctionField *f,const char *fieldname,
95*4d537eeaSYohann                                  CeedInt size, CeedEvalMode emode) {
96d7b241e6Sjeremylt   size_t len = strlen(fieldname);
97d7b241e6Sjeremylt   char *tmp;
98fe2413ffSjeremylt   int ierr;
99fe2413ffSjeremylt   ierr = CeedCalloc(1,f); CeedChk(ierr);
100fe2413ffSjeremylt 
101fe2413ffSjeremylt   ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr);
102d7b241e6Sjeremylt   memcpy(tmp, fieldname, len+1);
103fe2413ffSjeremylt   (*f)->fieldname = tmp;
104*4d537eeaSYohann   (*f)->size = size;
105fe2413ffSjeremylt   (*f)->emode = emode;
106d7b241e6Sjeremylt   return 0;
107d7b241e6Sjeremylt }
108d7b241e6Sjeremylt 
109b11c1e72Sjeremylt /**
110a0a97fcfSJed Brown   @brief Add a CeedQFunction input
111b11c1e72Sjeremylt 
112b11c1e72Sjeremylt   @param qf         CeedQFunction
113b11c1e72Sjeremylt   @param fieldname  Name of QFunction field
114*4d537eeaSYohann   @param size       Size of QFunction field, ncomp * (dim for CEED_EVAL_GRAD or
115*4d537eeaSYohann                       1 for CEED_EVAL_NONE and CEED_EVAL_INTERP)
116b11c1e72Sjeremylt   @param emode      \ref CEED_EVAL_NONE to use values directly,
117b11c1e72Sjeremylt                       \ref CEED_EVAL_INTERP to use interpolated values,
118b11c1e72Sjeremylt                       \ref CEED_EVAL_GRAD to use gradients.
119b11c1e72Sjeremylt 
120b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
121dfdf5a53Sjeremylt 
122dfdf5a53Sjeremylt   @ref Basic
123b11c1e72Sjeremylt **/
124d7b241e6Sjeremylt int CeedQFunctionAddInput(CeedQFunction qf, const char *fieldname,
125*4d537eeaSYohann                           CeedInt size, CeedEvalMode emode) {
126fe2413ffSjeremylt   int ierr = CeedQFunctionFieldSet(&qf->inputfields[qf->numinputfields],
127*4d537eeaSYohann                                    fieldname, size, emode);
128fe2413ffSjeremylt   CeedChk(ierr);
129fe2413ffSjeremylt   qf->numinputfields++;
130d7b241e6Sjeremylt   return 0;
131d7b241e6Sjeremylt }
132d7b241e6Sjeremylt 
133b11c1e72Sjeremylt /**
134a0a97fcfSJed Brown   @brief Add a CeedQFunction output
135b11c1e72Sjeremylt 
136b11c1e72Sjeremylt   @param qf         CeedQFunction
137b11c1e72Sjeremylt   @param fieldname  Name of QFunction field
138*4d537eeaSYohann   @param size       Size of QFunction field, ncomp * (dim for CEED_EVAL_GRAD or
139*4d537eeaSYohann                       1 for CEED_EVAL_NONE and CEED_EVAL_INTERP)
140b11c1e72Sjeremylt   @param emode      \ref CEED_EVAL_NONE to use values directly,
141b11c1e72Sjeremylt                       \ref CEED_EVAL_INTERP to use interpolated values,
142b11c1e72Sjeremylt                       \ref CEED_EVAL_GRAD to use gradients.
143b11c1e72Sjeremylt 
144b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
145dfdf5a53Sjeremylt 
146dfdf5a53Sjeremylt   @ref Basic
147b11c1e72Sjeremylt **/
148d7b241e6Sjeremylt int CeedQFunctionAddOutput(CeedQFunction qf, const char *fieldname,
149*4d537eeaSYohann                            CeedInt size, CeedEvalMode emode) {
150d7b241e6Sjeremylt   if (emode == CEED_EVAL_WEIGHT)
151d7b241e6Sjeremylt     return CeedError(qf->ceed, 1,
1528c91a0c9SJeremy L Thompson                      "Cannot create QFunction output with CEED_EVAL_WEIGHT");
153fe2413ffSjeremylt   int ierr = CeedQFunctionFieldSet(&qf->outputfields[qf->numoutputfields],
154*4d537eeaSYohann                                    fieldname, size, emode);
155fe2413ffSjeremylt   CeedChk(ierr);
156fe2413ffSjeremylt   qf->numoutputfields++;
157d7b241e6Sjeremylt   return 0;
158d7b241e6Sjeremylt }
159d7b241e6Sjeremylt 
160dfdf5a53Sjeremylt /**
1614ce2993fSjeremylt   @brief Get the Ceed associated with a CeedQFunction
1624ce2993fSjeremylt 
1634ce2993fSjeremylt   @param qf              CeedQFunction
1644ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
1654ce2993fSjeremylt 
1664ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
1674ce2993fSjeremylt 
16823617272Sjeremylt   @ref Advanced
1694ce2993fSjeremylt **/
1704ce2993fSjeremylt 
1714ce2993fSjeremylt int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) {
1724ce2993fSjeremylt   *ceed = qf->ceed;
1734ce2993fSjeremylt   return 0;
1744ce2993fSjeremylt }
1754ce2993fSjeremylt 
1764ce2993fSjeremylt /**
1774ce2993fSjeremylt   @brief Get the vector length of a CeedQFunction
1784ce2993fSjeremylt 
1794ce2993fSjeremylt   @param qf              CeedQFunction
1804ce2993fSjeremylt   @param[out] veclength  Variable to store vector length
1814ce2993fSjeremylt 
1824ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
1834ce2993fSjeremylt 
18423617272Sjeremylt   @ref Advanced
1854ce2993fSjeremylt **/
1864ce2993fSjeremylt 
1874ce2993fSjeremylt int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vlength) {
1884ce2993fSjeremylt   *vlength = qf->vlength;
1894ce2993fSjeremylt   return 0;
1904ce2993fSjeremylt }
1914ce2993fSjeremylt 
1924ce2993fSjeremylt /**
193dfdf5a53Sjeremylt   @brief Get the number of inputs and outputs to a CeedQFunction
194dfdf5a53Sjeremylt 
195dfdf5a53Sjeremylt   @param qf              CeedQFunction
1964ce2993fSjeremylt   @param[out] numinput   Variable to store number of input fields
1974ce2993fSjeremylt   @param[out] numoutput  Variable to store number of output fields
198dfdf5a53Sjeremylt 
199dfdf5a53Sjeremylt   @return An error code: 0 - success, otherwise - failure
200dfdf5a53Sjeremylt 
20123617272Sjeremylt   @ref Advanced
202dfdf5a53Sjeremylt **/
203dfdf5a53Sjeremylt 
204d7b241e6Sjeremylt int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *numinput,
205d7b241e6Sjeremylt                             CeedInt *numoutput) {
2061a4ead9bSjeremylt   if (numinput) *numinput = qf->numinputfields;
2071a4ead9bSjeremylt   if (numoutput) *numoutput = qf->numoutputfields;
208d7b241e6Sjeremylt   return 0;
209d7b241e6Sjeremylt }
210d7b241e6Sjeremylt 
211d7b241e6Sjeremylt /**
2124ce2993fSjeremylt   @brief Get the FOCCA string for a CeedQFunction
2134ce2993fSjeremylt 
2144ce2993fSjeremylt   @param qf              CeedQFunction
2154ce2993fSjeremylt   @param[out] focca      Variable to store focca string
2164ce2993fSjeremylt 
2174ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2184ce2993fSjeremylt 
21923617272Sjeremylt   @ref Advanced
2204ce2993fSjeremylt **/
2214ce2993fSjeremylt 
2224ce2993fSjeremylt int CeedQFunctionGetFOCCA(CeedQFunction qf, char* *focca) {
2234ce2993fSjeremylt   *focca = (char *) qf->focca;
2244ce2993fSjeremylt   return 0;
2254ce2993fSjeremylt }
2264ce2993fSjeremylt 
2274ce2993fSjeremylt /**
228fe2413ffSjeremylt   @brief Get the User Function for a CeedQFunction
229fe2413ffSjeremylt 
230fe2413ffSjeremylt   @param qf              CeedQFunction
231fe2413ffSjeremylt   @param[out] f          Variable to store user function
232fe2413ffSjeremylt 
233fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
234fe2413ffSjeremylt 
235fe2413ffSjeremylt   @ref Advanced
236fe2413ffSjeremylt **/
237fe2413ffSjeremylt 
23828d161eeSjeremylt int CeedQFunctionGetUserFunction(CeedQFunction qf, int (**f)()) {
23928d161eeSjeremylt   *f = (int (*)())qf->function;
240fe2413ffSjeremylt   return 0;
241fe2413ffSjeremylt }
242fe2413ffSjeremylt 
243fe2413ffSjeremylt /**
2444ce2993fSjeremylt   @brief Get global context size for a CeedQFunction
2454ce2993fSjeremylt 
2464ce2993fSjeremylt   @param qf              CeedQFunction
2474ce2993fSjeremylt   @param[out] ctxsize    Variable to store size of context data values
2484ce2993fSjeremylt 
2494ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2504ce2993fSjeremylt 
25123617272Sjeremylt   @ref Advanced
2524ce2993fSjeremylt **/
2534ce2993fSjeremylt 
2544ce2993fSjeremylt int CeedQFunctionGetContextSize(CeedQFunction qf, size_t *ctxsize) {
255069aeabaSjeremylt   if (qf->fortranstatus) {
256069aeabaSjeremylt     fContext *fctx = qf->ctx;
257069aeabaSjeremylt     *ctxsize = fctx->innerctxsize;
258069aeabaSjeremylt   } else {
2594ce2993fSjeremylt     *ctxsize = qf->ctxsize;
260069aeabaSjeremylt   }
2614ce2993fSjeremylt   return 0;
2624ce2993fSjeremylt }
2634ce2993fSjeremylt 
2644ce2993fSjeremylt /**
2654ce2993fSjeremylt   @brief Get global context for a CeedQFunction
2664ce2993fSjeremylt 
2674ce2993fSjeremylt   @param qf              CeedQFunction
2684ce2993fSjeremylt   @param[out] ctx        Variable to store context data values
2694ce2993fSjeremylt 
2704ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2714ce2993fSjeremylt 
27223617272Sjeremylt   @ref Advanced
2734ce2993fSjeremylt **/
2744ce2993fSjeremylt 
2754ce2993fSjeremylt int CeedQFunctionGetContext(CeedQFunction qf, void* *ctx) {
2764ce2993fSjeremylt   *ctx = qf->ctx;
2774ce2993fSjeremylt   return 0;
2784ce2993fSjeremylt }
2794ce2993fSjeremylt 
2804ce2993fSjeremylt /**
281418fb8c2Sjeremylt   @brief Determine if Fortran interface was used
282418fb8c2Sjeremylt 
283418fb8c2Sjeremylt   @param qf                  CeedQFunction
284418fb8c2Sjeremylt   @param[out] fortranstatus  Variable to store Fortran status
285418fb8c2Sjeremylt 
286418fb8c2Sjeremylt   @return An error code: 0 - success, otherwise - failure
287418fb8c2Sjeremylt 
288418fb8c2Sjeremylt   @ref Advanced
289418fb8c2Sjeremylt **/
290418fb8c2Sjeremylt 
291418fb8c2Sjeremylt int CeedQFunctionGetFortranStatus(CeedQFunction qf, bool *fortranstatus) {
292418fb8c2Sjeremylt   *fortranstatus = qf->fortranstatus;
293418fb8c2Sjeremylt   return 0;
294418fb8c2Sjeremylt }
295418fb8c2Sjeremylt 
296418fb8c2Sjeremylt /**
29714922b2aSjeremylt   @brief Get true user context for a CeedQFunction
298069aeabaSjeremylt 
299069aeabaSjeremylt   @param qf              CeedQFunction
300069aeabaSjeremylt   @param[out] ctx        Variable to store context data values
301069aeabaSjeremylt 
302069aeabaSjeremylt   @return An error code: 0 - success, otherwise - failure
303069aeabaSjeremylt 
304069aeabaSjeremylt   @ref Advanced
305069aeabaSjeremylt **/
306069aeabaSjeremylt 
30714922b2aSjeremylt int CeedQFunctionGetInnerContext(CeedQFunction qf, void* *ctx) {
30814922b2aSjeremylt   if (qf->fortranstatus) {
309069aeabaSjeremylt     fContext *fctx = qf->ctx;
310069aeabaSjeremylt     *ctx = fctx->innerctx;
31114922b2aSjeremylt   } else {
31214922b2aSjeremylt     *ctx = qf->ctx;
31314922b2aSjeremylt   }
31414922b2aSjeremylt 
3159f0427d9SYohann 
316069aeabaSjeremylt   return 0;
317069aeabaSjeremylt }
318069aeabaSjeremylt 
319069aeabaSjeremylt /**
3204ce2993fSjeremylt   @brief Get backend data of a CeedQFunction
3214ce2993fSjeremylt 
3224ce2993fSjeremylt   @param qf              CeedQFunction
3234ce2993fSjeremylt   @param[out] data       Variable to store data
3244ce2993fSjeremylt 
3254ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3264ce2993fSjeremylt 
32723617272Sjeremylt   @ref Advanced
3284ce2993fSjeremylt **/
3294ce2993fSjeremylt 
3304ce2993fSjeremylt int CeedQFunctionGetData(CeedQFunction qf, void* *data) {
3314ce2993fSjeremylt   *data = qf->data;
3324ce2993fSjeremylt   return 0;
3334ce2993fSjeremylt }
3344ce2993fSjeremylt 
3354ce2993fSjeremylt /**
336fe2413ffSjeremylt   @brief Set backend data of a CeedQFunction
337fe2413ffSjeremylt 
338fe2413ffSjeremylt   @param[out] qf         CeedQFunction
339fe2413ffSjeremylt   @param data            Data to set
340fe2413ffSjeremylt 
341fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
342fe2413ffSjeremylt 
343fe2413ffSjeremylt   @ref Advanced
344fe2413ffSjeremylt **/
345fe2413ffSjeremylt 
346fe2413ffSjeremylt int CeedQFunctionSetData(CeedQFunction qf, void* *data) {
347fe2413ffSjeremylt   qf->data = *data;
348fe2413ffSjeremylt   return 0;
349fe2413ffSjeremylt }
350fe2413ffSjeremylt 
351fe2413ffSjeremylt /**
3524ce2993fSjeremylt   @brief Set global context for a CeedQFunction
353b11c1e72Sjeremylt 
354b11c1e72Sjeremylt   @param qf       CeedQFunction
355b11c1e72Sjeremylt   @param ctx      Context data to set
356b11c1e72Sjeremylt   @param ctxsize  Size of context data values
357b11c1e72Sjeremylt 
358b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
359dfdf5a53Sjeremylt 
360dfdf5a53Sjeremylt   @ref Basic
361b11c1e72Sjeremylt **/
362d7b241e6Sjeremylt int CeedQFunctionSetContext(CeedQFunction qf, void *ctx, size_t ctxsize) {
363d7b241e6Sjeremylt   qf->ctx = ctx;
364d7b241e6Sjeremylt   qf->ctxsize = ctxsize;
365d7b241e6Sjeremylt   return 0;
366d7b241e6Sjeremylt }
367d7b241e6Sjeremylt 
368b11c1e72Sjeremylt /**
369b11c1e72Sjeremylt   @brief Apply the action of a CeedQFunction
370b11c1e72Sjeremylt 
371b11c1e72Sjeremylt   @param qf      CeedQFunction
372b11c1e72Sjeremylt   @param Q       Number of quadrature points
373b11c1e72Sjeremylt   @param[in] u   Array of input data arrays
374b11c1e72Sjeremylt   @param[out] v  Array of output data arrays
375b11c1e72Sjeremylt 
376b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
377dfdf5a53Sjeremylt 
378dfdf5a53Sjeremylt   @ref Advanced
379b11c1e72Sjeremylt **/
380d7b241e6Sjeremylt int CeedQFunctionApply(CeedQFunction qf, CeedInt Q,
381aedaa0e5Sjeremylt                        CeedVector *u, CeedVector *v) {
382d7b241e6Sjeremylt   int ierr;
383d7b241e6Sjeremylt   if (!qf->Apply)
384d7b241e6Sjeremylt     return CeedError(qf->ceed, 1, "Backend does not support QFunctionApply");
385d7b241e6Sjeremylt   if (Q % qf->vlength)
386d7b241e6Sjeremylt     return CeedError(qf->ceed, 2,
387d7b241e6Sjeremylt                      "Number of quadrature points %d must be a multiple of %d",
388d7b241e6Sjeremylt                      Q, qf->vlength);
389d7b241e6Sjeremylt   ierr = qf->Apply(qf, Q, u, v); CeedChk(ierr);
390d7b241e6Sjeremylt   return 0;
391d7b241e6Sjeremylt }
392d7b241e6Sjeremylt 
393b11c1e72Sjeremylt /**
394d1bcdac9Sjeremylt   @brief Get the CeedQFunctionFields of a CeedQFunction
395d1bcdac9Sjeremylt 
396d1bcdac9Sjeremylt   @param qf                 CeedQFunction
397d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
398d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
399d1bcdac9Sjeremylt 
400d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
401d1bcdac9Sjeremylt 
402d1bcdac9Sjeremylt   @ref Advanced
403d1bcdac9Sjeremylt **/
404d1bcdac9Sjeremylt 
405d1bcdac9Sjeremylt int CeedQFunctionGetFields(CeedQFunction qf,
406d1bcdac9Sjeremylt                            CeedQFunctionField* *inputfields,
407d1bcdac9Sjeremylt                            CeedQFunctionField* *outputfields) {
408d1bcdac9Sjeremylt   if (inputfields) *inputfields = qf->inputfields;
409d1bcdac9Sjeremylt   if (outputfields) *outputfields = qf->outputfields;
410d1bcdac9Sjeremylt   return 0;
411d1bcdac9Sjeremylt }
412d1bcdac9Sjeremylt 
413d1bcdac9Sjeremylt /**
414fe2413ffSjeremylt   @brief Get the name of a CeedQFunctionField
415fe2413ffSjeremylt 
416fe2413ffSjeremylt   @param qffield         CeedQFunctionField
417fe2413ffSjeremylt   @param[out] fieldname  Variable to store the field name
418fe2413ffSjeremylt 
419fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
420fe2413ffSjeremylt 
421fe2413ffSjeremylt   @ref Advanced
422fe2413ffSjeremylt **/
423fe2413ffSjeremylt 
424fe2413ffSjeremylt int CeedQFunctionFieldGetName(CeedQFunctionField qffield,
425fe2413ffSjeremylt                               char* *fieldname) {
426fe2413ffSjeremylt   *fieldname = (char *)qffield->fieldname;
427fe2413ffSjeremylt   return 0;
428fe2413ffSjeremylt }
429fe2413ffSjeremylt 
430fe2413ffSjeremylt /**
431d1bcdac9Sjeremylt   @brief Get the number of components of a CeedQFunctionField
432d1bcdac9Sjeremylt 
433d1bcdac9Sjeremylt   @param qffield    CeedQFunctionField
434*4d537eeaSYohann   @param[out] size  Variable to store the size of the field
435d1bcdac9Sjeremylt 
436d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
437d1bcdac9Sjeremylt 
438d1bcdac9Sjeremylt   @ref Advanced
439d1bcdac9Sjeremylt **/
440d1bcdac9Sjeremylt 
441*4d537eeaSYohann int CeedQFunctionFieldGetSize(CeedQFunctionField qffield, CeedInt *size) {
442*4d537eeaSYohann   *size = qffield->size;
443d1bcdac9Sjeremylt   return 0;
444d1bcdac9Sjeremylt }
445d1bcdac9Sjeremylt 
446d1bcdac9Sjeremylt /**
447d1bcdac9Sjeremylt   @brief Get the CeedEvalMode of a CeedQFunctionField
448d1bcdac9Sjeremylt 
449d1bcdac9Sjeremylt   @param qffield         CeedQFunctionField
450d1bcdac9Sjeremylt   @param[out] vec        Variable to store the number of components
451d1bcdac9Sjeremylt 
452d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
453d1bcdac9Sjeremylt 
454d1bcdac9Sjeremylt   @ref Advanced
455d1bcdac9Sjeremylt **/
456d1bcdac9Sjeremylt 
457d1bcdac9Sjeremylt int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qffield,
458d1bcdac9Sjeremylt                                   CeedEvalMode *emode) {
459fe2413ffSjeremylt   *emode = qffield->emode;
460d1bcdac9Sjeremylt   return 0;
461d1bcdac9Sjeremylt }
462d1bcdac9Sjeremylt 
463d1bcdac9Sjeremylt /**
464b11c1e72Sjeremylt   @brief Destroy a CeedQFunction
465b11c1e72Sjeremylt 
466b11c1e72Sjeremylt   @param qf CeedQFunction to destroy
467b11c1e72Sjeremylt 
468b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
469dfdf5a53Sjeremylt 
470dfdf5a53Sjeremylt   @ref Basic
471b11c1e72Sjeremylt **/
472d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) {
473d7b241e6Sjeremylt   int ierr;
474d7b241e6Sjeremylt 
475d7b241e6Sjeremylt   if (!*qf || --(*qf)->refcount > 0) return 0;
476fe2413ffSjeremylt   // Backend destroy
477d7b241e6Sjeremylt   if ((*qf)->Destroy) {
478d7b241e6Sjeremylt     ierr = (*qf)->Destroy(*qf); CeedChk(ierr);
479d7b241e6Sjeremylt   }
480fe2413ffSjeremylt   // Free fields
481fe2413ffSjeremylt   for (int i=0; i<(*qf)->numinputfields; i++) {
482fe2413ffSjeremylt     ierr = CeedFree(&(*(*qf)->inputfields[i]).fieldname); CeedChk(ierr);
483fe2413ffSjeremylt     ierr = CeedFree(&(*qf)->inputfields[i]); CeedChk(ierr);
484fe2413ffSjeremylt   }
485fe2413ffSjeremylt   for (int i=0; i<(*qf)->numoutputfields; i++) {
486fe2413ffSjeremylt     ierr = CeedFree(&(*(*qf)->outputfields[i]).fieldname); CeedChk(ierr);
487fe2413ffSjeremylt     ierr = CeedFree(&(*qf)->outputfields[i]); CeedChk(ierr);
488fe2413ffSjeremylt   }
489fe2413ffSjeremylt   ierr = CeedFree(&(*qf)->inputfields); CeedChk(ierr);
490fe2413ffSjeremylt   ierr = CeedFree(&(*qf)->outputfields); CeedChk(ierr);
491fe2413ffSjeremylt 
492d7b241e6Sjeremylt   ierr = CeedFree(&(*qf)->focca); CeedChk(ierr);
493d7b241e6Sjeremylt   ierr = CeedDestroy(&(*qf)->ceed); CeedChk(ierr);
494d7b241e6Sjeremylt   ierr = CeedFree(qf); CeedChk(ierr);
495d7b241e6Sjeremylt   return 0;
496d7b241e6Sjeremylt }
497d7b241e6Sjeremylt 
498d7b241e6Sjeremylt /// @}
499