xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-qfunction.c (revision 288c044332e33f37503f09b6484fec9d0a55fba1)
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>
20*288c0443SJeremy L Thompson #include <limits.h>
21*288c0443SJeremy L Thompson 
22*288c0443SJeremy L Thompson /// @cond DOXYGEN_SKIP
23*288c0443SJeremy L Thompson static struct {
24*288c0443SJeremy L Thompson   char name[CEED_MAX_RESOURCE_LEN];
25*288c0443SJeremy L Thompson   char source[CEED_MAX_RESOURCE_LEN];
26*288c0443SJeremy L Thompson   CeedInt vlength;
27*288c0443SJeremy L Thompson   CeedQFunctionUser f;
28*288c0443SJeremy L Thompson   int (*init)(Ceed ceed, const char *name, CeedQFunction qf);
29*288c0443SJeremy L Thompson } qfunctions[1024];
30*288c0443SJeremy L Thompson static size_t num_qfunctions;
31*288c0443SJeremy L Thompson /// @endcond
32d7b241e6Sjeremylt 
33dfdf5a53Sjeremylt /// @file
34dfdf5a53Sjeremylt /// Implementation of public CeedQFunction interfaces
35dfdf5a53Sjeremylt ///
36dfdf5a53Sjeremylt /// @addtogroup CeedQFunction
37dfdf5a53Sjeremylt /// @{
38d7b241e6Sjeremylt 
39d7b241e6Sjeremylt /**
40d7b241e6Sjeremylt   @brief Create a CeedQFunction for evaluating interior (volumetric) terms.
41d7b241e6Sjeremylt 
42b11c1e72Sjeremylt   @param ceed       A Ceed object where the CeedQFunction will be created
43d7b241e6Sjeremylt   @param vlength    Vector length.  Caller must ensure that number of quadrature
44d7b241e6Sjeremylt                     points is a multiple of vlength.
45d7b241e6Sjeremylt   @param f          Function pointer to evaluate action at quadrature points.
469f0427d9SYohann                     See \ref CeedQFunctionUser.
47*288c0443SJeremy L Thompson   @param source     Path to source of QFunction, "\path\file.h:function_name"
48b11c1e72Sjeremylt   @param[out] qf    Address of the variable where the newly created
49b11c1e72Sjeremylt                       CeedQFunction will be stored
50b11c1e72Sjeremylt 
51b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
52d7b241e6Sjeremylt 
538795c945Sjeremylt   See \ref CeedQFunctionUser for details on the call-back function @a f's
548795c945Sjeremylt     arguments.
55d7b241e6Sjeremylt 
56dfdf5a53Sjeremylt   @ref Basic
57dfdf5a53Sjeremylt **/
58d7b241e6Sjeremylt int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vlength,
599f0427d9SYohann                                 CeedQFunctionUser f,
60*288c0443SJeremy L Thompson                                 const char *source, CeedQFunction *qf) {
61d7b241e6Sjeremylt   int ierr;
62*288c0443SJeremy L Thompson   char *source_copy;
63d7b241e6Sjeremylt 
645fe0d4faSjeremylt   if (!ceed->QFunctionCreate) {
655fe0d4faSjeremylt     Ceed delegate;
66aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "QFunction"); CeedChk(ierr);
675fe0d4faSjeremylt 
685fe0d4faSjeremylt     if (!delegate)
69d7b241e6Sjeremylt       return CeedError(ceed, 1, "Backend does not support QFunctionCreate");
705fe0d4faSjeremylt 
71*288c0443SJeremy L Thompson     ierr = CeedQFunctionCreateInterior(delegate, vlength, f, source, qf);
721dfeef1dSjeremylt     CeedChk(ierr);
735fe0d4faSjeremylt     return 0;
745fe0d4faSjeremylt   }
755fe0d4faSjeremylt 
76d7b241e6Sjeremylt   ierr = CeedCalloc(1,qf); CeedChk(ierr);
77d7b241e6Sjeremylt   (*qf)->ceed = ceed;
78d7b241e6Sjeremylt   ceed->refcount++;
79d7b241e6Sjeremylt   (*qf)->refcount = 1;
80d7b241e6Sjeremylt   (*qf)->vlength = vlength;
81d7b241e6Sjeremylt   (*qf)->function = f;
82*288c0443SJeremy L Thompson   ierr = CeedCalloc(strlen(source)+1, &source_copy); CeedChk(ierr);
83*288c0443SJeremy L Thompson   strncpy(source_copy, source, strlen(source));
84*288c0443SJeremy L Thompson   (*qf)->sourcepath = source_copy;
85fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*qf)->inputfields); CeedChk(ierr);
86fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*qf)->outputfields); CeedChk(ierr);
87d7b241e6Sjeremylt   ierr = ceed->QFunctionCreate(*qf); CeedChk(ierr);
88d7b241e6Sjeremylt   return 0;
89d7b241e6Sjeremylt }
90d7b241e6Sjeremylt 
91b11c1e72Sjeremylt /**
92*288c0443SJeremy L Thompson   @brief Register a gallery QFunction
93*288c0443SJeremy L Thompson 
94*288c0443SJeremy L Thompson   @param name    Name for this backend to respond to
95*288c0443SJeremy L Thompson   @param source  Path to source of QFunction, "\path\file.h:function_name"
96*288c0443SJeremy L Thompson   @param vlength Vector length.  Caller must ensure that number of quadrature
97*288c0443SJeremy L Thompson                    points is a multiple of vlength.
98*288c0443SJeremy L Thompson   @param f       Function pointer to evaluate action at quadrature points.
99*288c0443SJeremy L Thompson                    See \ref CeedQFunctionUser.
100*288c0443SJeremy L Thompson   @param init    Initialization function called by CeedQFunctionInit() when the
101*288c0443SJeremy L Thompson                    QFunction is selected.
102*288c0443SJeremy L Thompson 
103*288c0443SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
104*288c0443SJeremy L Thompson 
105*288c0443SJeremy L Thompson   @ref Advanced
106*288c0443SJeremy L Thompson **/
107*288c0443SJeremy L Thompson int CeedQFunctionRegister(const char *name, const char *source,
108*288c0443SJeremy L Thompson                           CeedInt vlength, CeedQFunctionUser f,
109*288c0443SJeremy L Thompson                           int (*init)(Ceed, const char *, CeedQFunction)) {
110*288c0443SJeremy L Thompson   if (num_qfunctions >= sizeof(qfunctions) / sizeof(qfunctions[0])) {
111*288c0443SJeremy L Thompson     return CeedError(NULL, 1, "Too many gallery QFunctions");
112*288c0443SJeremy L Thompson   }
113*288c0443SJeremy L Thompson   strncpy(qfunctions[num_qfunctions].name, name, CEED_MAX_RESOURCE_LEN);
114*288c0443SJeremy L Thompson   qfunctions[num_qfunctions].name[CEED_MAX_RESOURCE_LEN-1] = 0;
115*288c0443SJeremy L Thompson   strncpy(qfunctions[num_qfunctions].source, source, CEED_MAX_RESOURCE_LEN);
116*288c0443SJeremy L Thompson   qfunctions[num_qfunctions].source[CEED_MAX_RESOURCE_LEN-1] = 0;
117*288c0443SJeremy L Thompson   qfunctions[num_qfunctions].vlength = vlength;
118*288c0443SJeremy L Thompson   qfunctions[num_qfunctions].f = f;
119*288c0443SJeremy L Thompson   qfunctions[num_qfunctions].init = init;
120*288c0443SJeremy L Thompson   num_qfunctions++;
121*288c0443SJeremy L Thompson   return 0;
122*288c0443SJeremy L Thompson }
123*288c0443SJeremy L Thompson 
124*288c0443SJeremy L Thompson /**
125*288c0443SJeremy L Thompson   @brief Create a CeedQFunction for evaluating interior (volumetric) terms by name.
126*288c0443SJeremy L Thompson 
127*288c0443SJeremy L Thompson   @param ceed       A Ceed object where the CeedQFunction will be created
128*288c0443SJeremy L Thompson   @param name       Name of QFunction to use from gallery
129*288c0443SJeremy L Thompson   @param[out] qf    Address of the variable where the newly created
130*288c0443SJeremy L Thompson                       CeedQFunction will be stored
131*288c0443SJeremy L Thompson 
132*288c0443SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
133*288c0443SJeremy L Thompson 
134*288c0443SJeremy L Thompson   @ref Basic
135*288c0443SJeremy L Thompson **/
136*288c0443SJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed,  const char *name,
137*288c0443SJeremy L Thompson                                       CeedQFunction *qf) {
138*288c0443SJeremy L Thompson   int ierr;
139*288c0443SJeremy L Thompson   size_t matchlen = 0, matchidx = UINT_MAX;
140*288c0443SJeremy L Thompson 
141*288c0443SJeremy L Thompson   // Find matching backend
142*288c0443SJeremy L Thompson   if (!name) return CeedError(NULL, 1, "No QFunction name provided");
143*288c0443SJeremy L Thompson   for (size_t i=0; i<num_qfunctions; i++) {
144*288c0443SJeremy L Thompson     size_t n;
145*288c0443SJeremy L Thompson     const char *currname = qfunctions[i].name;
146*288c0443SJeremy L Thompson     for (n = 0; currname[n] && currname[n] == name[n]; n++) {}
147*288c0443SJeremy L Thompson     if (n > matchlen) {
148*288c0443SJeremy L Thompson       matchlen = n;
149*288c0443SJeremy L Thompson       matchidx = i;
150*288c0443SJeremy L Thompson     }
151*288c0443SJeremy L Thompson   }
152*288c0443SJeremy L Thompson   if (!matchlen) return CeedError(NULL, 1, "No suitable gallery QFunction");
153*288c0443SJeremy L Thompson 
154*288c0443SJeremy L Thompson   // Create QFunction
155*288c0443SJeremy L Thompson   ierr = CeedQFunctionCreateInterior(ceed, qfunctions[matchidx].vlength,
156*288c0443SJeremy L Thompson                                      qfunctions[matchidx].f,
157*288c0443SJeremy L Thompson                                      qfunctions[matchidx].source, qf);
158*288c0443SJeremy L Thompson   CeedChk(ierr);
159*288c0443SJeremy L Thompson 
160*288c0443SJeremy L Thompson   // QFunction specific setup
161*288c0443SJeremy L Thompson   ierr = qfunctions[matchidx].init(ceed, name, *qf); CeedChk(ierr);
162*288c0443SJeremy L Thompson 
163*288c0443SJeremy L Thompson   return 0;
164*288c0443SJeremy L Thompson }
165*288c0443SJeremy L Thompson 
166*288c0443SJeremy L Thompson /**
167a0a97fcfSJed Brown   @brief Set a CeedQFunction field, used by CeedQFunctionAddInput/Output
168b11c1e72Sjeremylt 
169b11c1e72Sjeremylt   @param f          CeedQFunctionField
170b11c1e72Sjeremylt   @param fieldname  Name of QFunction field
1714d537eeaSYohann   @param size       Size of QFunction field, ncomp * (dim for CEED_EVAL_GRAD or
1724d537eeaSYohann                       1 for CEED_EVAL_NONE and CEED_EVAL_INTERP)
173b11c1e72Sjeremylt   @param emode      \ref CEED_EVAL_NONE to use values directly,
174b11c1e72Sjeremylt                       \ref CEED_EVAL_INTERP to use interpolated values,
175b11c1e72Sjeremylt                       \ref CEED_EVAL_GRAD to use gradients.
176b11c1e72Sjeremylt 
177b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
178dfdf5a53Sjeremylt 
179dfdf5a53Sjeremylt   @ref Developer
180b11c1e72Sjeremylt **/
181fe2413ffSjeremylt static int CeedQFunctionFieldSet(CeedQFunctionField *f,const char *fieldname,
1824d537eeaSYohann                                  CeedInt size, CeedEvalMode emode) {
183d7b241e6Sjeremylt   size_t len = strlen(fieldname);
184d7b241e6Sjeremylt   char *tmp;
185fe2413ffSjeremylt   int ierr;
186fe2413ffSjeremylt   ierr = CeedCalloc(1,f); CeedChk(ierr);
187fe2413ffSjeremylt 
188fe2413ffSjeremylt   ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr);
189d7b241e6Sjeremylt   memcpy(tmp, fieldname, len+1);
190fe2413ffSjeremylt   (*f)->fieldname = tmp;
1914d537eeaSYohann   (*f)->size = size;
192fe2413ffSjeremylt   (*f)->emode = emode;
193d7b241e6Sjeremylt   return 0;
194d7b241e6Sjeremylt }
195d7b241e6Sjeremylt 
196b11c1e72Sjeremylt /**
197a0a97fcfSJed Brown   @brief Add a CeedQFunction input
198b11c1e72Sjeremylt 
199b11c1e72Sjeremylt   @param qf         CeedQFunction
200b11c1e72Sjeremylt   @param fieldname  Name of QFunction field
2014d537eeaSYohann   @param size       Size of QFunction field, ncomp * (dim for CEED_EVAL_GRAD or
2024d537eeaSYohann                       1 for CEED_EVAL_NONE and CEED_EVAL_INTERP)
203b11c1e72Sjeremylt   @param emode      \ref CEED_EVAL_NONE to use values directly,
204b11c1e72Sjeremylt                       \ref CEED_EVAL_INTERP to use interpolated values,
205b11c1e72Sjeremylt                       \ref CEED_EVAL_GRAD to use gradients.
206b11c1e72Sjeremylt 
207b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
208dfdf5a53Sjeremylt 
209dfdf5a53Sjeremylt   @ref Basic
210b11c1e72Sjeremylt **/
211d7b241e6Sjeremylt int CeedQFunctionAddInput(CeedQFunction qf, const char *fieldname,
2124d537eeaSYohann                           CeedInt size, CeedEvalMode emode) {
213fe2413ffSjeremylt   int ierr = CeedQFunctionFieldSet(&qf->inputfields[qf->numinputfields],
2144d537eeaSYohann                                    fieldname, size, emode);
215fe2413ffSjeremylt   CeedChk(ierr);
216fe2413ffSjeremylt   qf->numinputfields++;
217d7b241e6Sjeremylt   return 0;
218d7b241e6Sjeremylt }
219d7b241e6Sjeremylt 
220b11c1e72Sjeremylt /**
221a0a97fcfSJed Brown   @brief Add a CeedQFunction output
222b11c1e72Sjeremylt 
223b11c1e72Sjeremylt   @param qf         CeedQFunction
224b11c1e72Sjeremylt   @param fieldname  Name of QFunction field
2254d537eeaSYohann   @param size       Size of QFunction field, ncomp * (dim for CEED_EVAL_GRAD or
2264d537eeaSYohann                       1 for CEED_EVAL_NONE and CEED_EVAL_INTERP)
227b11c1e72Sjeremylt   @param emode      \ref CEED_EVAL_NONE to use values directly,
228b11c1e72Sjeremylt                       \ref CEED_EVAL_INTERP to use interpolated values,
229b11c1e72Sjeremylt                       \ref CEED_EVAL_GRAD to use gradients.
230b11c1e72Sjeremylt 
231b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
232dfdf5a53Sjeremylt 
233dfdf5a53Sjeremylt   @ref Basic
234b11c1e72Sjeremylt **/
235d7b241e6Sjeremylt int CeedQFunctionAddOutput(CeedQFunction qf, const char *fieldname,
2364d537eeaSYohann                            CeedInt size, CeedEvalMode emode) {
237d7b241e6Sjeremylt   if (emode == CEED_EVAL_WEIGHT)
238d7b241e6Sjeremylt     return CeedError(qf->ceed, 1,
2398c91a0c9SJeremy L Thompson                      "Cannot create QFunction output with CEED_EVAL_WEIGHT");
240fe2413ffSjeremylt   int ierr = CeedQFunctionFieldSet(&qf->outputfields[qf->numoutputfields],
2414d537eeaSYohann                                    fieldname, size, emode);
242fe2413ffSjeremylt   CeedChk(ierr);
243fe2413ffSjeremylt   qf->numoutputfields++;
244d7b241e6Sjeremylt   return 0;
245d7b241e6Sjeremylt }
246d7b241e6Sjeremylt 
247dfdf5a53Sjeremylt /**
2484ce2993fSjeremylt   @brief Get the Ceed associated with a CeedQFunction
2494ce2993fSjeremylt 
2504ce2993fSjeremylt   @param qf              CeedQFunction
2514ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
2524ce2993fSjeremylt 
2534ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2544ce2993fSjeremylt 
25523617272Sjeremylt   @ref Advanced
2564ce2993fSjeremylt **/
2574ce2993fSjeremylt 
2584ce2993fSjeremylt int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) {
2594ce2993fSjeremylt   *ceed = qf->ceed;
2604ce2993fSjeremylt   return 0;
2614ce2993fSjeremylt }
2624ce2993fSjeremylt 
2634ce2993fSjeremylt /**
2644ce2993fSjeremylt   @brief Get the vector length of a CeedQFunction
2654ce2993fSjeremylt 
2664ce2993fSjeremylt   @param qf            CeedQFunction
267*288c0443SJeremy L Thompson   @param[out] vlength  Variable to store vector length
2684ce2993fSjeremylt 
2694ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2704ce2993fSjeremylt 
27123617272Sjeremylt   @ref Advanced
2724ce2993fSjeremylt **/
2734ce2993fSjeremylt 
2744ce2993fSjeremylt int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vlength) {
2754ce2993fSjeremylt   *vlength = qf->vlength;
2764ce2993fSjeremylt   return 0;
2774ce2993fSjeremylt }
2784ce2993fSjeremylt 
2794ce2993fSjeremylt /**
280dfdf5a53Sjeremylt   @brief Get the number of inputs and outputs to a CeedQFunction
281dfdf5a53Sjeremylt 
282dfdf5a53Sjeremylt   @param qf              CeedQFunction
2834ce2993fSjeremylt   @param[out] numinput   Variable to store number of input fields
2844ce2993fSjeremylt   @param[out] numoutput  Variable to store number of output fields
285dfdf5a53Sjeremylt 
286dfdf5a53Sjeremylt   @return An error code: 0 - success, otherwise - failure
287dfdf5a53Sjeremylt 
28823617272Sjeremylt   @ref Advanced
289dfdf5a53Sjeremylt **/
290dfdf5a53Sjeremylt 
291d7b241e6Sjeremylt int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *numinput,
292d7b241e6Sjeremylt                             CeedInt *numoutput) {
2931a4ead9bSjeremylt   if (numinput) *numinput = qf->numinputfields;
2941a4ead9bSjeremylt   if (numoutput) *numoutput = qf->numoutputfields;
295d7b241e6Sjeremylt   return 0;
296d7b241e6Sjeremylt }
297d7b241e6Sjeremylt 
298d7b241e6Sjeremylt /**
299*288c0443SJeremy L Thompson   @brief Get the source path string for a CeedQFunction
3004ce2993fSjeremylt 
3014ce2993fSjeremylt   @param qf              CeedQFunction
302*288c0443SJeremy L Thompson   @param[out] source     Variable to store source path string
3034ce2993fSjeremylt 
3044ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3054ce2993fSjeremylt 
30623617272Sjeremylt   @ref Advanced
3074ce2993fSjeremylt **/
3084ce2993fSjeremylt 
309*288c0443SJeremy L Thompson int CeedQFunctionGetSourcePath(CeedQFunction qf, char* *source) {
310*288c0443SJeremy L Thompson   *source = (char *) qf->sourcepath;
3114ce2993fSjeremylt   return 0;
3124ce2993fSjeremylt }
3134ce2993fSjeremylt 
3144ce2993fSjeremylt /**
315fe2413ffSjeremylt   @brief Get the User Function for a CeedQFunction
316fe2413ffSjeremylt 
317fe2413ffSjeremylt   @param qf              CeedQFunction
318fe2413ffSjeremylt   @param[out] f          Variable to store user function
319fe2413ffSjeremylt 
320fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
321fe2413ffSjeremylt 
322fe2413ffSjeremylt   @ref Advanced
323fe2413ffSjeremylt **/
324fe2413ffSjeremylt 
32528d161eeSjeremylt int CeedQFunctionGetUserFunction(CeedQFunction qf, int (**f)()) {
32628d161eeSjeremylt   *f = (int (*)())qf->function;
327fe2413ffSjeremylt   return 0;
328fe2413ffSjeremylt }
329fe2413ffSjeremylt 
330fe2413ffSjeremylt /**
3314ce2993fSjeremylt   @brief Get global context size for a CeedQFunction
3324ce2993fSjeremylt 
3334ce2993fSjeremylt   @param qf              CeedQFunction
3344ce2993fSjeremylt   @param[out] ctxsize    Variable to store size of context data values
3354ce2993fSjeremylt 
3364ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3374ce2993fSjeremylt 
33823617272Sjeremylt   @ref Advanced
3394ce2993fSjeremylt **/
3404ce2993fSjeremylt 
3414ce2993fSjeremylt int CeedQFunctionGetContextSize(CeedQFunction qf, size_t *ctxsize) {
342069aeabaSjeremylt   if (qf->fortranstatus) {
343069aeabaSjeremylt     fContext *fctx = qf->ctx;
344069aeabaSjeremylt     *ctxsize = fctx->innerctxsize;
345069aeabaSjeremylt   } else {
3464ce2993fSjeremylt     *ctxsize = qf->ctxsize;
347069aeabaSjeremylt   }
3484ce2993fSjeremylt   return 0;
3494ce2993fSjeremylt }
3504ce2993fSjeremylt 
3514ce2993fSjeremylt /**
3524ce2993fSjeremylt   @brief Get global context for a CeedQFunction
3534ce2993fSjeremylt 
3544ce2993fSjeremylt   @param qf              CeedQFunction
3554ce2993fSjeremylt   @param[out] ctx        Variable to store context data values
3564ce2993fSjeremylt 
3574ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3584ce2993fSjeremylt 
35923617272Sjeremylt   @ref Advanced
3604ce2993fSjeremylt **/
3614ce2993fSjeremylt 
3624ce2993fSjeremylt int CeedQFunctionGetContext(CeedQFunction qf, void* *ctx) {
3634ce2993fSjeremylt   *ctx = qf->ctx;
3644ce2993fSjeremylt   return 0;
3654ce2993fSjeremylt }
3664ce2993fSjeremylt 
3674ce2993fSjeremylt /**
368418fb8c2Sjeremylt   @brief Determine if Fortran interface was used
369418fb8c2Sjeremylt 
370418fb8c2Sjeremylt   @param qf                  CeedQFunction
371418fb8c2Sjeremylt   @param[out] fortranstatus  Variable to store Fortran status
372418fb8c2Sjeremylt 
373418fb8c2Sjeremylt   @return An error code: 0 - success, otherwise - failure
374418fb8c2Sjeremylt 
375418fb8c2Sjeremylt   @ref Advanced
376418fb8c2Sjeremylt **/
377418fb8c2Sjeremylt 
378418fb8c2Sjeremylt int CeedQFunctionGetFortranStatus(CeedQFunction qf, bool *fortranstatus) {
379418fb8c2Sjeremylt   *fortranstatus = qf->fortranstatus;
380418fb8c2Sjeremylt   return 0;
381418fb8c2Sjeremylt }
382418fb8c2Sjeremylt 
383418fb8c2Sjeremylt /**
38414922b2aSjeremylt   @brief Get true user context for a CeedQFunction
385069aeabaSjeremylt 
386069aeabaSjeremylt   @param qf              CeedQFunction
387069aeabaSjeremylt   @param[out] ctx        Variable to store context data values
388069aeabaSjeremylt 
389069aeabaSjeremylt   @return An error code: 0 - success, otherwise - failure
390069aeabaSjeremylt 
391069aeabaSjeremylt   @ref Advanced
392069aeabaSjeremylt **/
393069aeabaSjeremylt 
39414922b2aSjeremylt int CeedQFunctionGetInnerContext(CeedQFunction qf, void* *ctx) {
39514922b2aSjeremylt   if (qf->fortranstatus) {
396069aeabaSjeremylt     fContext *fctx = qf->ctx;
397069aeabaSjeremylt     *ctx = fctx->innerctx;
39814922b2aSjeremylt   } else {
39914922b2aSjeremylt     *ctx = qf->ctx;
40014922b2aSjeremylt   }
40114922b2aSjeremylt 
4029f0427d9SYohann 
403069aeabaSjeremylt   return 0;
404069aeabaSjeremylt }
405069aeabaSjeremylt 
406069aeabaSjeremylt /**
4074ce2993fSjeremylt   @brief Get backend data of a CeedQFunction
4084ce2993fSjeremylt 
4094ce2993fSjeremylt   @param qf              CeedQFunction
4104ce2993fSjeremylt   @param[out] data       Variable to store data
4114ce2993fSjeremylt 
4124ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4134ce2993fSjeremylt 
41423617272Sjeremylt   @ref Advanced
4154ce2993fSjeremylt **/
4164ce2993fSjeremylt 
4174ce2993fSjeremylt int CeedQFunctionGetData(CeedQFunction qf, void* *data) {
4184ce2993fSjeremylt   *data = qf->data;
4194ce2993fSjeremylt   return 0;
4204ce2993fSjeremylt }
4214ce2993fSjeremylt 
4224ce2993fSjeremylt /**
423fe2413ffSjeremylt   @brief Set backend data of a CeedQFunction
424fe2413ffSjeremylt 
425fe2413ffSjeremylt   @param[out] qf         CeedQFunction
426fe2413ffSjeremylt   @param data            Data to set
427fe2413ffSjeremylt 
428fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
429fe2413ffSjeremylt 
430fe2413ffSjeremylt   @ref Advanced
431fe2413ffSjeremylt **/
432fe2413ffSjeremylt 
433fe2413ffSjeremylt int CeedQFunctionSetData(CeedQFunction qf, void* *data) {
434fe2413ffSjeremylt   qf->data = *data;
435fe2413ffSjeremylt   return 0;
436fe2413ffSjeremylt }
437fe2413ffSjeremylt 
438fe2413ffSjeremylt /**
4394ce2993fSjeremylt   @brief Set global context for a CeedQFunction
440b11c1e72Sjeremylt 
441b11c1e72Sjeremylt   @param qf       CeedQFunction
442b11c1e72Sjeremylt   @param ctx      Context data to set
443b11c1e72Sjeremylt   @param ctxsize  Size of context data values
444b11c1e72Sjeremylt 
445b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
446dfdf5a53Sjeremylt 
447dfdf5a53Sjeremylt   @ref Basic
448b11c1e72Sjeremylt **/
449d7b241e6Sjeremylt int CeedQFunctionSetContext(CeedQFunction qf, void *ctx, size_t ctxsize) {
450d7b241e6Sjeremylt   qf->ctx = ctx;
451d7b241e6Sjeremylt   qf->ctxsize = ctxsize;
452d7b241e6Sjeremylt   return 0;
453d7b241e6Sjeremylt }
454d7b241e6Sjeremylt 
455b11c1e72Sjeremylt /**
456b11c1e72Sjeremylt   @brief Apply the action of a CeedQFunction
457b11c1e72Sjeremylt 
458b11c1e72Sjeremylt   @param qf      CeedQFunction
459b11c1e72Sjeremylt   @param Q       Number of quadrature points
460b11c1e72Sjeremylt   @param[in] u   Array of input data arrays
461b11c1e72Sjeremylt   @param[out] v  Array of output data arrays
462b11c1e72Sjeremylt 
463b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
464dfdf5a53Sjeremylt 
465dfdf5a53Sjeremylt   @ref Advanced
466b11c1e72Sjeremylt **/
467d7b241e6Sjeremylt int CeedQFunctionApply(CeedQFunction qf, CeedInt Q,
468aedaa0e5Sjeremylt                        CeedVector *u, CeedVector *v) {
469d7b241e6Sjeremylt   int ierr;
470d7b241e6Sjeremylt   if (!qf->Apply)
471d7b241e6Sjeremylt     return CeedError(qf->ceed, 1, "Backend does not support QFunctionApply");
472d7b241e6Sjeremylt   if (Q % qf->vlength)
473d7b241e6Sjeremylt     return CeedError(qf->ceed, 2,
474d7b241e6Sjeremylt                      "Number of quadrature points %d must be a multiple of %d",
475d7b241e6Sjeremylt                      Q, qf->vlength);
476d7b241e6Sjeremylt   ierr = qf->Apply(qf, Q, u, v); CeedChk(ierr);
477d7b241e6Sjeremylt   return 0;
478d7b241e6Sjeremylt }
479d7b241e6Sjeremylt 
480b11c1e72Sjeremylt /**
481d1bcdac9Sjeremylt   @brief Get the CeedQFunctionFields of a CeedQFunction
482d1bcdac9Sjeremylt 
483d1bcdac9Sjeremylt   @param qf                 CeedQFunction
484d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
485d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
486d1bcdac9Sjeremylt 
487d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
488d1bcdac9Sjeremylt 
489d1bcdac9Sjeremylt   @ref Advanced
490d1bcdac9Sjeremylt **/
491d1bcdac9Sjeremylt 
492d1bcdac9Sjeremylt int CeedQFunctionGetFields(CeedQFunction qf,
493d1bcdac9Sjeremylt                            CeedQFunctionField* *inputfields,
494d1bcdac9Sjeremylt                            CeedQFunctionField* *outputfields) {
495d1bcdac9Sjeremylt   if (inputfields) *inputfields = qf->inputfields;
496d1bcdac9Sjeremylt   if (outputfields) *outputfields = qf->outputfields;
497d1bcdac9Sjeremylt   return 0;
498d1bcdac9Sjeremylt }
499d1bcdac9Sjeremylt 
500d1bcdac9Sjeremylt /**
501fe2413ffSjeremylt   @brief Get the name of a CeedQFunctionField
502fe2413ffSjeremylt 
503fe2413ffSjeremylt   @param qffield         CeedQFunctionField
504fe2413ffSjeremylt   @param[out] fieldname  Variable to store the field name
505fe2413ffSjeremylt 
506fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
507fe2413ffSjeremylt 
508fe2413ffSjeremylt   @ref Advanced
509fe2413ffSjeremylt **/
510fe2413ffSjeremylt 
511fe2413ffSjeremylt int CeedQFunctionFieldGetName(CeedQFunctionField qffield,
512fe2413ffSjeremylt                               char* *fieldname) {
513fe2413ffSjeremylt   *fieldname = (char *)qffield->fieldname;
514fe2413ffSjeremylt   return 0;
515fe2413ffSjeremylt }
516fe2413ffSjeremylt 
517fe2413ffSjeremylt /**
518d1bcdac9Sjeremylt   @brief Get the number of components of a CeedQFunctionField
519d1bcdac9Sjeremylt 
520d1bcdac9Sjeremylt   @param qffield    CeedQFunctionField
5214d537eeaSYohann   @param[out] size  Variable to store the size of the field
522d1bcdac9Sjeremylt 
523d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
524d1bcdac9Sjeremylt 
525d1bcdac9Sjeremylt   @ref Advanced
526d1bcdac9Sjeremylt **/
527d1bcdac9Sjeremylt 
5284d537eeaSYohann int CeedQFunctionFieldGetSize(CeedQFunctionField qffield, CeedInt *size) {
5294d537eeaSYohann   *size = qffield->size;
530d1bcdac9Sjeremylt   return 0;
531d1bcdac9Sjeremylt }
532d1bcdac9Sjeremylt 
533d1bcdac9Sjeremylt /**
534d1bcdac9Sjeremylt   @brief Get the CeedEvalMode of a CeedQFunctionField
535d1bcdac9Sjeremylt 
536d1bcdac9Sjeremylt   @param qffield         CeedQFunctionField
537*288c0443SJeremy L Thompson   @param[out] emode      Variable to store the field evaluation mode
538d1bcdac9Sjeremylt 
539d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
540d1bcdac9Sjeremylt 
541d1bcdac9Sjeremylt   @ref Advanced
542d1bcdac9Sjeremylt **/
543d1bcdac9Sjeremylt 
544d1bcdac9Sjeremylt int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qffield,
545d1bcdac9Sjeremylt                                   CeedEvalMode *emode) {
546fe2413ffSjeremylt   *emode = qffield->emode;
547d1bcdac9Sjeremylt   return 0;
548d1bcdac9Sjeremylt }
549d1bcdac9Sjeremylt 
550d1bcdac9Sjeremylt /**
551b11c1e72Sjeremylt   @brief Destroy a CeedQFunction
552b11c1e72Sjeremylt 
553b11c1e72Sjeremylt   @param qf CeedQFunction to destroy
554b11c1e72Sjeremylt 
555b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
556dfdf5a53Sjeremylt 
557dfdf5a53Sjeremylt   @ref Basic
558b11c1e72Sjeremylt **/
559d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) {
560d7b241e6Sjeremylt   int ierr;
561d7b241e6Sjeremylt 
562d7b241e6Sjeremylt   if (!*qf || --(*qf)->refcount > 0) return 0;
563fe2413ffSjeremylt   // Backend destroy
564d7b241e6Sjeremylt   if ((*qf)->Destroy) {
565d7b241e6Sjeremylt     ierr = (*qf)->Destroy(*qf); CeedChk(ierr);
566d7b241e6Sjeremylt   }
567fe2413ffSjeremylt   // Free fields
568fe2413ffSjeremylt   for (int i=0; i<(*qf)->numinputfields; i++) {
569fe2413ffSjeremylt     ierr = CeedFree(&(*(*qf)->inputfields[i]).fieldname); CeedChk(ierr);
570fe2413ffSjeremylt     ierr = CeedFree(&(*qf)->inputfields[i]); CeedChk(ierr);
571fe2413ffSjeremylt   }
572fe2413ffSjeremylt   for (int i=0; i<(*qf)->numoutputfields; i++) {
573fe2413ffSjeremylt     ierr = CeedFree(&(*(*qf)->outputfields[i]).fieldname); CeedChk(ierr);
574fe2413ffSjeremylt     ierr = CeedFree(&(*qf)->outputfields[i]); CeedChk(ierr);
575fe2413ffSjeremylt   }
576fe2413ffSjeremylt   ierr = CeedFree(&(*qf)->inputfields); CeedChk(ierr);
577fe2413ffSjeremylt   ierr = CeedFree(&(*qf)->outputfields); CeedChk(ierr);
578fe2413ffSjeremylt 
579*288c0443SJeremy L Thompson   ierr = CeedFree(&(*qf)->sourcepath); CeedChk(ierr);
580d7b241e6Sjeremylt   ierr = CeedDestroy(&(*qf)->ceed); CeedChk(ierr);
581d7b241e6Sjeremylt   ierr = CeedFree(qf); CeedChk(ierr);
582d7b241e6Sjeremylt   return 0;
583d7b241e6Sjeremylt }
584d7b241e6Sjeremylt 
585d7b241e6Sjeremylt /// @}
586