ceed-qfunction.c (38d0029a08e84b16bbdde77c27446234f5f09cf2) ceed-qfunction.c (7a982d89c751e293e39d23a7c44a161cef1fcd06)
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.

--- 5 unchanged lines hidden (view full) ---

14// software, applications, hardware, advanced system engineering and early
15// testbed platforms, in support of the nation's exascale computing imperative.
16
17#include <ceed-impl.h>
18#include <ceed-backend.h>
19#include <string.h>
20#include <limits.h>
21
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.

--- 5 unchanged lines hidden (view full) ---

14// software, applications, hardware, advanced system engineering and early
15// testbed platforms, in support of the nation's exascale computing imperative.
16
17#include <ceed-impl.h>
18#include <ceed-backend.h>
19#include <string.h>
20#include <limits.h>
21
22/// @file
23/// Implementation of public CeedQFunction interfaces
24
22/// @cond DOXYGEN_SKIP
23static struct CeedQFunction_private ceed_qfunction_none;
24/// @endcond
25
25/// @cond DOXYGEN_SKIP
26static struct CeedQFunction_private ceed_qfunction_none;
27/// @endcond
28
29/// @addtogroup CeedQFunctionUser
30/// @{
31
32// Indicate that no QFunction is provided by the user
33const CeedQFunction CEED_QFUNCTION_NONE = &ceed_qfunction_none;
34
35/// @}
36
26/// @cond DOXYGEN_SKIP
27static struct {
28 char name[CEED_MAX_RESOURCE_LEN];
29 char source[CEED_MAX_RESOURCE_LEN];
30 CeedInt vlength;
31 CeedQFunctionUser f;
32 int (*init)(Ceed ceed, const char *name, CeedQFunction qf);
33} qfunctions[1024];
34static size_t num_qfunctions;
35/// @endcond
36
37/// @cond DOXYGEN_SKIP
38static struct {
39 char name[CEED_MAX_RESOURCE_LEN];
40 char source[CEED_MAX_RESOURCE_LEN];
41 CeedInt vlength;
42 CeedQFunctionUser f;
43 int (*init)(Ceed ceed, const char *name, CeedQFunction qf);
44} qfunctions[1024];
45static size_t num_qfunctions;
46/// @endcond
47
37/// @file
38/// Implementation of public CeedQFunction interfaces
39///
40/// @addtogroup CeedQFunction
41/// @{
42
43/**
48/**
44 @brief Create a CeedQFunction for evaluating interior (volumetric) terms.
45
46 @param ceed A Ceed object where the CeedQFunction will be created
47 @param vlength Vector length. Caller must ensure that number of quadrature
48 points is a multiple of vlength.
49 @param f Function pointer to evaluate action at quadrature points.
50 See \ref CeedQFunctionUser.
51 @param source Absolute path to source of QFunction,
52 "\abs_path\file.h:function_name"
53 @param[out] qf Address of the variable where the newly created
54 CeedQFunction will be stored
55
56 @return An error code: 0 - success, otherwise - failure
57
58 See \ref CeedQFunctionUser for details on the call-back function @a f's
59 arguments.
60
61 @ref Basic
62**/
63int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vlength, CeedQFunctionUser f,
64 const char *source, CeedQFunction *qf) {
65 int ierr;
66 char *source_copy;
67
68 if (!f) return CeedError(ceed, 1, "Must pass valid function f");
69 if (!ceed->QFunctionCreate) {
70 Ceed delegate;
71 ierr = CeedGetObjectDelegate(ceed, &delegate, "QFunction"); CeedChk(ierr);
72
73 if (!delegate)
74 // LCOV_EXCL_START
75 return CeedError(ceed, 1, "Backend does not support QFunctionCreate");
76 // LCOV_EXCL_STOP
77
78 ierr = CeedQFunctionCreateInterior(delegate, vlength, f, source, qf);
79 CeedChk(ierr);
80 return 0;
81 }
82
83 ierr = CeedCalloc(1, qf); CeedChk(ierr);
84 (*qf)->ceed = ceed;
85 ceed->refcount++;
86 (*qf)->refcount = 1;
87 (*qf)->vlength = vlength;
88 (*qf)->identity = 0;
89 (*qf)->function = f;
90 (*qf)->sourcepath = NULL;
91 if (source) {
92 size_t slen = strlen(source) + 1;
93 ierr = CeedMalloc(slen, &source_copy); CeedChk(ierr);
94 memcpy(source_copy, source, slen);
95 (*qf)->sourcepath = source_copy;
96 }
97 ierr = CeedCalloc(16, &(*qf)->inputfields); CeedChk(ierr);
98 ierr = CeedCalloc(16, &(*qf)->outputfields); CeedChk(ierr);
99 ierr = ceed->QFunctionCreate(*qf); CeedChk(ierr);
100 return 0;
101}
102
103/**
104 @brief Register a gallery QFunction
105
106 @param name Name for this backend to respond to
107 @param source Absolute path to source of QFunction,
108 "\path\CEED_DIR\gallery\folder\file.h:function_name"
109 @param vlength Vector length. Caller must ensure that number of quadrature
110 points is a multiple of vlength.
111 @param f Function pointer to evaluate action at quadrature points.
112 See \ref CeedQFunctionUser.
113 @param init Initialization function called by CeedQFunctionInit() when the
114 QFunction is selected.
115
116 @return An error code: 0 - success, otherwise - failure
117
49 @brief Register a gallery QFunction
50
51 @param name Name for this backend to respond to
52 @param source Absolute path to source of QFunction,
53 "\path\CEED_DIR\gallery\folder\file.h:function_name"
54 @param vlength Vector length. Caller must ensure that number of quadrature
55 points is a multiple of vlength.
56 @param f Function pointer to evaluate action at quadrature points.
57 See \ref CeedQFunctionUser.
58 @param init Initialization function called by CeedQFunctionInit() when the
59 QFunction is selected.
60
61 @return An error code: 0 - success, otherwise - failure
62
118 @ref Advanced
63 @ref Developer
119**/
120int CeedQFunctionRegister(const char *name, const char *source,
121 CeedInt vlength, CeedQFunctionUser f,
122 int (*init)(Ceed, const char *, CeedQFunction)) {
123 if (num_qfunctions >= sizeof(qfunctions) / sizeof(qfunctions[0]))
124 // LCOV_EXCL_START
125 return CeedError(NULL, 1, "Too many gallery QFunctions");
126 // LCOV_EXCL_STOP

--- 5 unchanged lines hidden (view full) ---

132 qfunctions[num_qfunctions].vlength = vlength;
133 qfunctions[num_qfunctions].f = f;
134 qfunctions[num_qfunctions].init = init;
135 num_qfunctions++;
136 return 0;
137}
138
139/**
64**/
65int CeedQFunctionRegister(const char *name, const char *source,
66 CeedInt vlength, CeedQFunctionUser f,
67 int (*init)(Ceed, const char *, CeedQFunction)) {
68 if (num_qfunctions >= sizeof(qfunctions) / sizeof(qfunctions[0]))
69 // LCOV_EXCL_START
70 return CeedError(NULL, 1, "Too many gallery QFunctions");
71 // LCOV_EXCL_STOP

--- 5 unchanged lines hidden (view full) ---

77 qfunctions[num_qfunctions].vlength = vlength;
78 qfunctions[num_qfunctions].f = f;
79 qfunctions[num_qfunctions].init = init;
80 num_qfunctions++;
81 return 0;
82}
83
84/**
140 @brief Create a CeedQFunction for evaluating interior (volumetric) terms by name.
141
142 @param ceed A Ceed object where the CeedQFunction will be created
143 @param name Name of QFunction to use from gallery
144 @param[out] qf Address of the variable where the newly created
145 CeedQFunction will be stored
146
147 @return An error code: 0 - success, otherwise - failure
148
149 @ref Basic
150**/
151int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name,
152 CeedQFunction *qf) {
153 int ierr;
154 size_t matchlen = 0, matchidx = UINT_MAX;
155 char *name_copy;
156
157 // Find matching backend
158 if (!name) return CeedError(NULL, 1, "No QFunction name provided");
159 for (size_t i=0; i<num_qfunctions; i++) {
160 size_t n;
161 const char *currname = qfunctions[i].name;
162 for (n = 0; currname[n] && currname[n] == name[n]; n++) {}
163 if (n > matchlen) {
164 matchlen = n;
165 matchidx = i;
166 }
167 }
168 if (!matchlen)
169 // LCOV_EXCL_START
170 return CeedError(NULL, 1, "No suitable gallery QFunction");
171 // LCOV_EXCL_STOP
172
173 // Create QFunction
174 ierr = CeedQFunctionCreateInterior(ceed, qfunctions[matchidx].vlength,
175 qfunctions[matchidx].f,
176 qfunctions[matchidx].source, qf);
177 CeedChk(ierr);
178
179 // QFunction specific setup
180 ierr = qfunctions[matchidx].init(ceed, name, *qf); CeedChk(ierr);
181
182 // Copy name
183 size_t slen = strlen(name) + 1;
184 ierr = CeedMalloc(slen, &name_copy); CeedChk(ierr);
185 memcpy(name_copy, name, slen);
186 (*qf)->qfname = name_copy;
187
188 return 0;
189}
190
191/**
192 @brief Create an identity CeedQFunction. Inputs are written into outputs in
193 the order given. This is useful for CeedOperators that can be
194 represented with only the action of a CeedRestriction and CeedBasis,
195 such as restriction and prolongation operators for p-multigrid.
196 Backends may optimize CeedOperators with this CeedQFunction to avoid
197 the copy of input data to output fields by using the same memory
198 location for both.
199
200 @param ceed A Ceed object where the CeedQFunction will be created
201 @param[in] size Size of the qfunction fields
202 @param[in] inmode CeedEvalMode for input to CeedQFunction
203 @param[in] outmode CeedEvalMode for output to CeedQFunction
204 @param[out] qf Address of the variable where the newly created
205 CeedQFunction will be stored
206
207 @return An error code: 0 - success, otherwise - failure
208
209 @ref Basic
210**/
211int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode inmode,
212 CeedEvalMode outmode, CeedQFunction *qf) {
213 int ierr;
214
215 if (inmode == CEED_EVAL_NONE && outmode == CEED_EVAL_NONE)
216 // LCOV_EXCL_START
217 return CeedError(ceed, 1, "CEED_EVAL_NONE for a both the input and "
218 "output does not make sense with an identity QFunction");
219 // LCOV_EXCL_STOP
220
221 ierr = CeedQFunctionCreateInteriorByName(ceed, "Identity", qf); CeedChk(ierr);
222 ierr = CeedQFunctionAddInput(*qf, "input", 1, inmode); CeedChk(ierr);
223 ierr = CeedQFunctionAddOutput(*qf, "output", 1, outmode); CeedChk(ierr);
224
225 (*qf)->identity = 1;
226 if (size > 1) {
227 CeedInt *ctx;
228 ierr = CeedCalloc(1, &ctx); CeedChk(ierr);
229 ctx[0] = size;
230 ierr = CeedQFunctionSetContext(*qf, ctx, sizeof(ctx)); CeedChk(ierr);
231 (*qf)->inputfields[0]->size = size;
232 (*qf)->outputfields[0]->size = size;
233 }
234
235 return 0;
236}
237
238/**
239 @brief Set a CeedQFunction field, used by CeedQFunctionAddInput/Output
240
241 @param f CeedQFunctionField
242 @param fieldname Name of QFunction field
243 @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
244 (ncomp * 1) for CEED_EVAL_NONE, CEED_EVAL_INTERP, and CEED_EVAL_WEIGHT
245 @param emode \ref CEED_EVAL_NONE to use values directly,
246 \ref CEED_EVAL_INTERP to use interpolated values,

--- 15 unchanged lines hidden (view full) ---

262 memcpy(tmp, fieldname, len+1);
263 (*f)->fieldname = tmp;
264 (*f)->size = size;
265 (*f)->emode = emode;
266 return 0;
267}
268
269/**
85 @brief Set a CeedQFunction field, used by CeedQFunctionAddInput/Output
86
87 @param f CeedQFunctionField
88 @param fieldname Name of QFunction field
89 @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
90 (ncomp * 1) for CEED_EVAL_NONE, CEED_EVAL_INTERP, and CEED_EVAL_WEIGHT
91 @param emode \ref CEED_EVAL_NONE to use values directly,
92 \ref CEED_EVAL_INTERP to use interpolated values,

--- 15 unchanged lines hidden (view full) ---

108 memcpy(tmp, fieldname, len+1);
109 (*f)->fieldname = tmp;
110 (*f)->size = size;
111 (*f)->emode = emode;
112 return 0;
113}
114
115/**
270 @brief Add a CeedQFunction input
116 @brief View a field of a CeedQFunction
271
117
272 @param qf CeedQFunction
273 @param fieldname Name of QFunction field
274 @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
275 (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
276 @param emode \ref CEED_EVAL_NONE to use values directly,
277 \ref CEED_EVAL_INTERP to use interpolated values,
278 \ref CEED_EVAL_GRAD to use gradients.
118 @param[in] field QFunction field to view
119 @param[in] fieldnumber Number of field being viewed
120 @param[in] stream Stream to view to, e.g., stdout
279
280 @return An error code: 0 - success, otherwise - failure
281
121
122 @return An error code: 0 - success, otherwise - failure
123
282 @ref Basic
124 @ref Utility
283**/
125**/
284int CeedQFunctionAddInput(CeedQFunction qf, const char *fieldname, CeedInt size,
285 CeedEvalMode emode) {
286 int ierr = CeedQFunctionFieldSet(&qf->inputfields[qf->numinputfields],
287 fieldname, size, emode);
288 CeedChk(ierr);
289 qf->numinputfields++;
126static int CeedQFunctionFieldView(CeedQFunctionField field, CeedInt fieldnumber,
127 bool in, FILE *stream) {
128 const char *inout = in ? "Input" : "Output";
129 fprintf(stream, " %s Field [%d]:\n"
130 " Name: \"%s\"\n"
131 " Size: %d\n"
132 " EvalMode: \"%s\"\n",
133 inout, fieldnumber, field->fieldname, field->size,
134 CeedEvalModes[field->emode]);
135
290 return 0;
291}
292
136 return 0;
137}
138
293/**
294 @brief Add a CeedQFunction output
139/// @}
295
140
296 @param qf CeedQFunction
297 @param fieldname Name of QFunction field
298 @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
299 (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
300 @param emode \ref CEED_EVAL_NONE to use values directly,
301 \ref CEED_EVAL_INTERP to use interpolated values,
302 \ref CEED_EVAL_GRAD to use gradients.
141/// ----------------------------------------------------------------------------
142/// CeedQFunction Backend API
143/// ----------------------------------------------------------------------------
144/// @addtogroup CeedQFunctionBackend
145/// @{
303
146
304 @return An error code: 0 - success, otherwise - failure
305
306 @ref Basic
307**/
308int CeedQFunctionAddOutput(CeedQFunction qf, const char *fieldname,
309 CeedInt size, CeedEvalMode emode) {
310 if (emode == CEED_EVAL_WEIGHT)
311 // LCOV_EXCL_START
312 return CeedError(qf->ceed, 1, "Cannot create QFunction output with "
313 "CEED_EVAL_WEIGHT");
314 // LCOV_EXCL_STOP
315 int ierr = CeedQFunctionFieldSet(&qf->outputfields[qf->numoutputfields],
316 fieldname, size, emode);
317 CeedChk(ierr);
318 qf->numoutputfields++;
319 return 0;
320}
321
322/**
323 @brief Get the Ceed associated with a CeedQFunction
324
325 @param qf CeedQFunction
326 @param[out] ceed Variable to store Ceed
327
328 @return An error code: 0 - success, otherwise - failure
329
147/**
148 @brief Get the Ceed associated with a CeedQFunction
149
150 @param qf CeedQFunction
151 @param[out] ceed Variable to store Ceed
152
153 @return An error code: 0 - success, otherwise - failure
154
330 @ref Advanced
155 @ref Backend
331**/
332
333int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) {
334 *ceed = qf->ceed;
335 return 0;
336}
337
338/**
339 @brief Get the vector length of a CeedQFunction
340
341 @param qf CeedQFunction
342 @param[out] vlength Variable to store vector length
343
344 @return An error code: 0 - success, otherwise - failure
345
156**/
157
158int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) {
159 *ceed = qf->ceed;
160 return 0;
161}
162
163/**
164 @brief Get the vector length of a CeedQFunction
165
166 @param qf CeedQFunction
167 @param[out] vlength Variable to store vector length
168
169 @return An error code: 0 - success, otherwise - failure
170
346 @ref Advanced
171 @ref Backend
347**/
348
349int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vlength) {
350 *vlength = qf->vlength;
351 return 0;
352}
353
354/**
355 @brief Get the number of inputs and outputs to a CeedQFunction
356
357 @param qf CeedQFunction
358 @param[out] numinput Variable to store number of input fields
359 @param[out] numoutput Variable to store number of output fields
360
361 @return An error code: 0 - success, otherwise - failure
362
172**/
173
174int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vlength) {
175 *vlength = qf->vlength;
176 return 0;
177}
178
179/**
180 @brief Get the number of inputs and outputs to a CeedQFunction
181
182 @param qf CeedQFunction
183 @param[out] numinput Variable to store number of input fields
184 @param[out] numoutput Variable to store number of output fields
185
186 @return An error code: 0 - success, otherwise - failure
187
363 @ref Advanced
188 @ref Backend
364**/
365
366int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *numinput,
367 CeedInt *numoutput) {
368 if (numinput) *numinput = qf->numinputfields;
369 if (numoutput) *numoutput = qf->numoutputfields;
370 return 0;
371}
372
373/**
374 @brief Get the source path string for a CeedQFunction
375
376 @param qf CeedQFunction
377 @param[out] source Variable to store source path string
378
379 @return An error code: 0 - success, otherwise - failure
380
189**/
190
191int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *numinput,
192 CeedInt *numoutput) {
193 if (numinput) *numinput = qf->numinputfields;
194 if (numoutput) *numoutput = qf->numoutputfields;
195 return 0;
196}
197
198/**
199 @brief Get the source path string for a CeedQFunction
200
201 @param qf CeedQFunction
202 @param[out] source Variable to store source path string
203
204 @return An error code: 0 - success, otherwise - failure
205
381 @ref Advanced
206 @ref Backend
382**/
383
384int CeedQFunctionGetSourcePath(CeedQFunction qf, char **source) {
385 *source = (char *) qf->sourcepath;
386 return 0;
387}
388
389/**
390 @brief Get the User Function for a CeedQFunction
391
392 @param qf CeedQFunction
393 @param[out] f Variable to store user function
394
395 @return An error code: 0 - success, otherwise - failure
396
207**/
208
209int CeedQFunctionGetSourcePath(CeedQFunction qf, char **source) {
210 *source = (char *) qf->sourcepath;
211 return 0;
212}
213
214/**
215 @brief Get the User Function for a CeedQFunction
216
217 @param qf CeedQFunction
218 @param[out] f Variable to store user function
219
220 @return An error code: 0 - success, otherwise - failure
221
397 @ref Advanced
222 @ref Backend
398**/
399
400int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) {
401 *f = qf->function;
402 return 0;
403}
404
405/**
406 @brief Get global context size for a CeedQFunction
407
408 @param qf CeedQFunction
409 @param[out] ctxsize Variable to store size of context data values
410
411 @return An error code: 0 - success, otherwise - failure
412
223**/
224
225int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) {
226 *f = qf->function;
227 return 0;
228}
229
230/**
231 @brief Get global context size for a CeedQFunction
232
233 @param qf CeedQFunction
234 @param[out] ctxsize Variable to store size of context data values
235
236 @return An error code: 0 - success, otherwise - failure
237
413 @ref Advanced
238 @ref Backend
414**/
415
416int CeedQFunctionGetContextSize(CeedQFunction qf, size_t *ctxsize) {
417 if (qf->fortranstatus) {
418 fContext *fctx = qf->ctx;
419 *ctxsize = fctx->innerctxsize;
420 } else {
421 *ctxsize = qf->ctxsize;

--- 4 unchanged lines hidden (view full) ---

426/**
427 @brief Get global context for a CeedQFunction
428
429 @param qf CeedQFunction
430 @param[out] ctx Variable to store context data values
431
432 @return An error code: 0 - success, otherwise - failure
433
239**/
240
241int CeedQFunctionGetContextSize(CeedQFunction qf, size_t *ctxsize) {
242 if (qf->fortranstatus) {
243 fContext *fctx = qf->ctx;
244 *ctxsize = fctx->innerctxsize;
245 } else {
246 *ctxsize = qf->ctxsize;

--- 4 unchanged lines hidden (view full) ---

251/**
252 @brief Get global context for a CeedQFunction
253
254 @param qf CeedQFunction
255 @param[out] ctx Variable to store context data values
256
257 @return An error code: 0 - success, otherwise - failure
258
434 @ref Advanced
259 @ref Backend
435**/
436
437int CeedQFunctionGetContext(CeedQFunction qf, void **ctx) {
438 *ctx = qf->ctx;
439 return 0;
440}
441
442/**
260**/
261
262int CeedQFunctionGetContext(CeedQFunction qf, void **ctx) {
263 *ctx = qf->ctx;
264 return 0;
265}
266
267/**
268 @brief Get true user context for a CeedQFunction
269
270 @param qf CeedQFunction
271 @param[out] ctx Variable to store context data values
272
273 @return An error code: 0 - success, otherwise - failure
274
275 @ref Backend
276**/
277
278int CeedQFunctionGetInnerContext(CeedQFunction qf, void **ctx) {
279 if (qf->fortranstatus) {
280 fContext *fctx = qf->ctx;
281 *ctx = fctx->innerctx;
282 } else {
283 *ctx = qf->ctx;
284 }
285
286
287 return 0;
288}
289
290/**
443 @brief Determine if Fortran interface was used
444
445 @param qf CeedQFunction
446 @param[out] fortranstatus Variable to store Fortran status
447
448 @return An error code: 0 - success, otherwise - failure
449
291 @brief Determine if Fortran interface was used
292
293 @param qf CeedQFunction
294 @param[out] fortranstatus Variable to store Fortran status
295
296 @return An error code: 0 - success, otherwise - failure
297
450 @ref Advanced
298 @ref Backend
451**/
452
453int CeedQFunctionGetFortranStatus(CeedQFunction qf, bool *fortranstatus) {
454 *fortranstatus = qf->fortranstatus;
455 return 0;
456}
457
458/**
459 @brief Determine if QFunction is identity
460
461 @param qf CeedQFunction
462 @param[out] identity Variable to store identity status
463
464 @return An error code: 0 - success, otherwise - failure
465
299**/
300
301int CeedQFunctionGetFortranStatus(CeedQFunction qf, bool *fortranstatus) {
302 *fortranstatus = qf->fortranstatus;
303 return 0;
304}
305
306/**
307 @brief Determine if QFunction is identity
308
309 @param qf CeedQFunction
310 @param[out] identity Variable to store identity status
311
312 @return An error code: 0 - success, otherwise - failure
313
466 @ref Advanced
314 @ref Backend
467**/
468
469int CeedQFunctionGetIdentityStatus(CeedQFunction qf, bool *identity) {
470 *identity = qf->identity;
471 return 0;
472}
473
474/**
315**/
316
317int CeedQFunctionGetIdentityStatus(CeedQFunction qf, bool *identity) {
318 *identity = qf->identity;
319 return 0;
320}
321
322/**
475 @brief Get true user context for a CeedQFunction
323 @brief Get backend data of a CeedQFunction
476
477 @param qf CeedQFunction
324
325 @param qf CeedQFunction
478 @param[out] ctx Variable to store context data values
326 @param[out] data Variable to store data
479
480 @return An error code: 0 - success, otherwise - failure
481
327
328 @return An error code: 0 - success, otherwise - failure
329
482 @ref Advanced
330 @ref Backend
483**/
484
331**/
332
485int CeedQFunctionGetInnerContext(CeedQFunction qf, void **ctx) {
486 if (qf->fortranstatus) {
487 fContext *fctx = qf->ctx;
488 *ctx = fctx->innerctx;
489 } else {
490 *ctx = qf->ctx;
491 }
333int CeedQFunctionGetData(CeedQFunction qf, void **data) {
334 *data = qf->data;
335 return 0;
336}
492
337
338/**
339 @brief Set backend data of a CeedQFunction
493
340
341 @param[out] qf CeedQFunction
342 @param data Data to set
343
344 @return An error code: 0 - success, otherwise - failure
345
346 @ref Backend
347**/
348
349int CeedQFunctionSetData(CeedQFunction qf, void **data) {
350 qf->data = *data;
494 return 0;
495}
496
497/**
351 return 0;
352}
353
354/**
498 @brief Get backend data of a CeedQFunction
355 @brief Get the CeedQFunctionFields of a CeedQFunction
499
356
500 @param qf CeedQFunction
501 @param[out] data Variable to store data
357 @param qf CeedQFunction
358 @param[out] inputfields Variable to store inputfields
359 @param[out] outputfields Variable to store outputfields
502
503 @return An error code: 0 - success, otherwise - failure
504
360
361 @return An error code: 0 - success, otherwise - failure
362
505 @ref Advanced
363 @ref Backend
506**/
507
364**/
365
508int CeedQFunctionGetData(CeedQFunction qf, void **data) {
509 *data = qf->data;
366int CeedQFunctionGetFields(CeedQFunction qf, CeedQFunctionField **inputfields,
367 CeedQFunctionField **outputfields) {
368 if (inputfields)
369 *inputfields = qf->inputfields;
370 if (outputfields)
371 *outputfields = qf->outputfields;
510 return 0;
511}
512
513/**
372 return 0;
373}
374
375/**
514 @brief Set backend data of a CeedQFunction
376 @brief Get the name of a CeedQFunctionField
515
377
516 @param[out] qf CeedQFunction
517 @param data Data to set
378 @param qffield CeedQFunctionField
379 @param[out] fieldname Variable to store the field name
518
519 @return An error code: 0 - success, otherwise - failure
520
380
381 @return An error code: 0 - success, otherwise - failure
382
521 @ref Advanced
383 @ref Backend
522**/
523
384**/
385
524int CeedQFunctionSetData(CeedQFunction qf, void **data) {
525 qf->data = *data;
386int CeedQFunctionFieldGetName(CeedQFunctionField qffield, char **fieldname) {
387 *fieldname = (char *)qffield->fieldname;
526 return 0;
527}
528
529/**
388 return 0;
389}
390
391/**
530 @brief Set global context for a CeedQFunction
392 @brief Get the number of components of a CeedQFunctionField
531
393
532 @param qf CeedQFunction
533 @param ctx Context data to set
534 @param ctxsize Size of context data values
394 @param qffield CeedQFunctionField
395 @param[out] size Variable to store the size of the field
535
536 @return An error code: 0 - success, otherwise - failure
537
396
397 @return An error code: 0 - success, otherwise - failure
398
538 @ref Basic
399 @ref Backend
539**/
400**/
540int CeedQFunctionSetContext(CeedQFunction qf, void *ctx, size_t ctxsize) {
541 qf->ctx = ctx;
542 qf->ctxsize = ctxsize;
401
402int CeedQFunctionFieldGetSize(CeedQFunctionField qffield, CeedInt *size) {
403 *size = qffield->size;
543 return 0;
544}
545
546/**
404 return 0;
405}
406
407/**
547 @brief View a field of a CeedQFunction
408 @brief Get the CeedEvalMode of a CeedQFunctionField
548
409
549 @param[in] field QFunction field to view
550 @param[in] fieldnumber Number of field being viewed
551 @param[in] stream Stream to view to, e.g., stdout
410 @param qffield CeedQFunctionField
411 @param[out] emode Variable to store the field evaluation mode
552
553 @return An error code: 0 - success, otherwise - failure
554
412
413 @return An error code: 0 - success, otherwise - failure
414
555 @ref Utility
415 @ref Backend
556**/
416**/
557static int CeedQFunctionFieldView(CeedQFunctionField field, CeedInt fieldnumber,
558 bool in, FILE *stream) {
559 const char *inout = in ? "Input" : "Output";
560 fprintf(stream, " %s Field [%d]:\n"
561 " Name: \"%s\"\n"
562 " Size: %d\n"
563 " EvalMode: \"%s\"\n",
564 inout, fieldnumber, field->fieldname, field->size,
565 CeedEvalModes[field->emode]);
566
417
418int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qffield,
419 CeedEvalMode *emode) {
420 *emode = qffield->emode;
567 return 0;
568}
569
421 return 0;
422}
423
424/// @}
425
426/// ----------------------------------------------------------------------------
427/// CeedQFunction Public API
428/// ----------------------------------------------------------------------------
429/// @addtogroup CeedQFunctionUser
430/// @{
431
570/**
432/**
571 @brief View a CeedQFunction
433 @brief Create a CeedQFunction for evaluating interior (volumetric) terms.
572
434
573 @param[in] qf CeedQFunction to view
574 @param[in] stream Stream to write; typically stdout/stderr or a file
435 @param ceed A Ceed object where the CeedQFunction will be created
436 @param vlength Vector length. Caller must ensure that number of quadrature
437 points is a multiple of vlength.
438 @param f Function pointer to evaluate action at quadrature points.
439 See \ref CeedQFunctionUser.
440 @param source Absolute path to source of QFunction,
441 "\abs_path\file.h:function_name"
442 @param[out] qf Address of the variable where the newly created
443 CeedQFunction will be stored
575
444
576 @return Error code: 0 - success, otherwise - failure
445 @return An error code: 0 - success, otherwise - failure
577
446
578 @ref Utility
447 See \ref CeedQFunctionUser for details on the call-back function @a f's
448 arguments.
449
450 @ref User
579**/
451**/
580int CeedQFunctionView(CeedQFunction qf, FILE *stream) {
452int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vlength, CeedQFunctionUser f,
453 const char *source, CeedQFunction *qf) {
581 int ierr;
454 int ierr;
455 char *source_copy;
582
456
583 fprintf(stream, "%sCeedQFunction %s\n",
584 qf->qfname ? "Gallery " : "User ", qf->qfname ? qf->qfname : "");
457 if (!ceed->QFunctionCreate) {
458 Ceed delegate;
459 ierr = CeedGetObjectDelegate(ceed, &delegate, "QFunction"); CeedChk(ierr);
585
460
586 fprintf(stream, " %d Input Field%s:\n", qf->numinputfields,
587 qf->numinputfields>1 ? "s" : "");
588 for (CeedInt i=0; i<qf->numinputfields; i++) {
589 ierr = CeedQFunctionFieldView(qf->inputfields[i], i, 1, stream);
590 CeedChk(ierr);
591 }
461 if (!delegate)
462 // LCOV_EXCL_START
463 return CeedError(ceed, 1, "Backend does not support QFunctionCreate");
464 // LCOV_EXCL_STOP
592
465
593 fprintf(stream, " %d Output Field%s:\n", qf->numoutputfields,
594 qf->numoutputfields>1 ? "s" : "");
595 for (CeedInt i=0; i<qf->numoutputfields; i++) {
596 ierr = CeedQFunctionFieldView(qf->outputfields[i], i, 0, stream);
466 ierr = CeedQFunctionCreateInterior(delegate, vlength, f, source, qf);
597 CeedChk(ierr);
467 CeedChk(ierr);
468 return 0;
598 }
469 }
470
471 ierr = CeedCalloc(1, qf); CeedChk(ierr);
472 (*qf)->ceed = ceed;
473 ceed->refcount++;
474 (*qf)->refcount = 1;
475 (*qf)->vlength = vlength;
476 (*qf)->identity = 0;
477 (*qf)->function = f;
478 size_t slen = strlen(source) + 1;
479 ierr = CeedMalloc(slen, &source_copy); CeedChk(ierr);
480 memcpy(source_copy, source, slen);
481 (*qf)->sourcepath = source_copy;
482 ierr = CeedCalloc(16, &(*qf)->inputfields); CeedChk(ierr);
483 ierr = CeedCalloc(16, &(*qf)->outputfields); CeedChk(ierr);
484 ierr = ceed->QFunctionCreate(*qf); CeedChk(ierr);
599 return 0;
600}
601
602/**
485 return 0;
486}
487
488/**
603 @brief Apply the action of a CeedQFunction
489 @brief Create a CeedQFunction for evaluating interior (volumetric) terms by name.
604
490
605 @param qf CeedQFunction
606 @param Q Number of quadrature points
607 @param[in] u Array of input CeedVectors
608 @param[out] v Array of output CeedVectors
491 @param ceed A Ceed object where the CeedQFunction will be created
492 @param name Name of QFunction to use from gallery
493 @param[out] qf Address of the variable where the newly created
494 CeedQFunction will be stored
609
610 @return An error code: 0 - success, otherwise - failure
611
495
496 @return An error code: 0 - success, otherwise - failure
497
612 @ref Advanced
498 @ref User
613**/
499**/
614int CeedQFunctionApply(CeedQFunction qf, CeedInt Q,
615 CeedVector *u, CeedVector *v) {
500int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name,
501 CeedQFunction *qf) {
616 int ierr;
502 int ierr;
617 if (!qf->Apply)
503 size_t matchlen = 0, matchidx = UINT_MAX;
504 char *name_copy;
505
506 // Find matching backend
507 if (!name) return CeedError(NULL, 1, "No QFunction name provided");
508 for (size_t i=0; i<num_qfunctions; i++) {
509 size_t n;
510 const char *currname = qfunctions[i].name;
511 for (n = 0; currname[n] && currname[n] == name[n]; n++) {}
512 if (n > matchlen) {
513 matchlen = n;
514 matchidx = i;
515 }
516 }
517 if (!matchlen)
618 // LCOV_EXCL_START
518 // LCOV_EXCL_START
619 return CeedError(qf->ceed, 1, "Backend does not support QFunctionApply");
519 return CeedError(NULL, 1, "No suitable gallery QFunction");
620 // LCOV_EXCL_STOP
520 // LCOV_EXCL_STOP
621 if (Q % qf->vlength)
622 // LCOV_EXCL_START
623 return CeedError(qf->ceed, 2, "Number of quadrature points %d must be a "
624 "multiple of %d", Q, qf->vlength);
625 // LCOV_EXCL_STOP
626 ierr = qf->Apply(qf, Q, u, v); CeedChk(ierr);
521
522 // Create QFunction
523 ierr = CeedQFunctionCreateInterior(ceed, qfunctions[matchidx].vlength,
524 qfunctions[matchidx].f,
525 qfunctions[matchidx].source, qf);
526 CeedChk(ierr);
527
528 // QFunction specific setup
529 ierr = qfunctions[matchidx].init(ceed, name, *qf); CeedChk(ierr);
530
531 // Copy name
532 size_t slen = strlen(name) + 1;
533 ierr = CeedMalloc(slen, &name_copy); CeedChk(ierr);
534 memcpy(name_copy, name, slen);
535 (*qf)->qfname = name_copy;
536
627 return 0;
628}
629
630/**
537 return 0;
538}
539
540/**
631 @brief Get the CeedQFunctionFields of a CeedQFunction
541 @brief Create an identity CeedQFunction. Inputs are written into outputs in
542 the order given. This is useful for CeedOperators that can be
543 represented with only the action of a CeedRestriction and CeedBasis,
544 such as restriction and prolongation operators for p-multigrid.
545 Backends may optimize CeedOperators with this CeedQFunction to avoid
546 the copy of input data to output fields by using the same memory
547 location for both.
632
548
633 @param qf CeedQFunction
634 @param[out] inputfields Variable to store inputfields
635 @param[out] outputfields Variable to store outputfields
549 @param ceed A Ceed object where the CeedQFunction will be created
550 @param[in] size Size of the qfunction fields
551 @param[in] inmode CeedEvalMode for input to CeedQFunction
552 @param[in] outmode CeedEvalMode for output to CeedQFunction
553 @param[out] qf Address of the variable where the newly created
554 CeedQFunction will be stored
636
637 @return An error code: 0 - success, otherwise - failure
638
555
556 @return An error code: 0 - success, otherwise - failure
557
639 @ref Advanced
558 @ref User
640**/
559**/
560int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode inmode,
561 CeedEvalMode outmode, CeedQFunction *qf) {
562 int ierr;
641
563
642int CeedQFunctionGetFields(CeedQFunction qf, CeedQFunctionField **inputfields,
643 CeedQFunctionField **outputfields) {
644 if (inputfields)
645 *inputfields = qf->inputfields;
646 if (outputfields)
647 *outputfields = qf->outputfields;
564 if (inmode == CEED_EVAL_NONE && outmode == CEED_EVAL_NONE)
565 // LCOV_EXCL_START
566 return CeedError(ceed, 1, "CEED_EVAL_NONE for a both the input and "
567 "output does not make sense with an identity QFunction");
568 // LCOV_EXCL_STOP
569
570 ierr = CeedQFunctionCreateInteriorByName(ceed, "Identity", qf); CeedChk(ierr);
571 ierr = CeedQFunctionAddInput(*qf, "input", 1, inmode); CeedChk(ierr);
572 ierr = CeedQFunctionAddOutput(*qf, "output", 1, outmode); CeedChk(ierr);
573
574 (*qf)->identity = 1;
575 if (size > 1) {
576 CeedInt *ctx;
577 ierr = CeedCalloc(1, &ctx); CeedChk(ierr);
578 ctx[0] = size;
579 ierr = CeedQFunctionSetContext(*qf, ctx, sizeof(ctx)); CeedChk(ierr);
580 (*qf)->inputfields[0]->size = size;
581 (*qf)->outputfields[0]->size = size;
582 }
583
648 return 0;
649}
650
651/**
584 return 0;
585}
586
587/**
652 @brief Get the name of a CeedQFunctionField
588 @brief Add a CeedQFunction input
653
589
654 @param qffield CeedQFunctionField
655 @param[out] fieldname Variable to store the field name
590 @param qf CeedQFunction
591 @param fieldname Name of QFunction field
592 @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
593 (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
594 @param emode \ref CEED_EVAL_NONE to use values directly,
595 \ref CEED_EVAL_INTERP to use interpolated values,
596 \ref CEED_EVAL_GRAD to use gradients.
656
657 @return An error code: 0 - success, otherwise - failure
658
597
598 @return An error code: 0 - success, otherwise - failure
599
659 @ref Advanced
600 @ref User
660**/
601**/
602int CeedQFunctionAddInput(CeedQFunction qf, const char *fieldname, CeedInt size,
603 CeedEvalMode emode) {
604 int ierr = CeedQFunctionFieldSet(&qf->inputfields[qf->numinputfields],
605 fieldname, size, emode);
606 CeedChk(ierr);
607 qf->numinputfields++;
608 return 0;
609}
661
610
662int CeedQFunctionFieldGetName(CeedQFunctionField qffield, char **fieldname) {
663 *fieldname = (char *)qffield->fieldname;
611/**
612 @brief Add a CeedQFunction output
613
614 @param qf CeedQFunction
615 @param fieldname Name of QFunction field
616 @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or
617 (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP
618 @param emode \ref CEED_EVAL_NONE to use values directly,
619 \ref CEED_EVAL_INTERP to use interpolated values,
620 \ref CEED_EVAL_GRAD to use gradients.
621
622 @return An error code: 0 - success, otherwise - failure
623
624 @ref User
625**/
626int CeedQFunctionAddOutput(CeedQFunction qf, const char *fieldname,
627 CeedInt size, CeedEvalMode emode) {
628 if (emode == CEED_EVAL_WEIGHT)
629 // LCOV_EXCL_START
630 return CeedError(qf->ceed, 1, "Cannot create QFunction output with "
631 "CEED_EVAL_WEIGHT");
632 // LCOV_EXCL_STOP
633 int ierr = CeedQFunctionFieldSet(&qf->outputfields[qf->numoutputfields],
634 fieldname, size, emode);
635 CeedChk(ierr);
636 qf->numoutputfields++;
664 return 0;
665}
666
667/**
637 return 0;
638}
639
640/**
668 @brief Get the number of components of a CeedQFunctionField
641 @brief Set global context for a CeedQFunction
669
642
670 @param qffield CeedQFunctionField
671 @param[out] size Variable to store the size of the field
643 @param qf CeedQFunction
644 @param ctx Context data to set
645 @param ctxsize Size of context data values
672
673 @return An error code: 0 - success, otherwise - failure
674
646
647 @return An error code: 0 - success, otherwise - failure
648
675 @ref Advanced
649 @ref User
676**/
650**/
651int CeedQFunctionSetContext(CeedQFunction qf, void *ctx, size_t ctxsize) {
652 qf->ctx = ctx;
653 qf->ctxsize = ctxsize;
654 return 0;
655}
677
656
678int CeedQFunctionFieldGetSize(CeedQFunctionField qffield, CeedInt *size) {
679 *size = qffield->size;
657/**
658 @brief View a CeedQFunction
659
660 @param[in] qf CeedQFunction to view
661 @param[in] stream Stream to write; typically stdout/stderr or a file
662
663 @return Error code: 0 - success, otherwise - failure
664
665 @ref User
666**/
667int CeedQFunctionView(CeedQFunction qf, FILE *stream) {
668 int ierr;
669
670 fprintf(stream, "%sCeedQFunction %s\n",
671 qf->qfname ? "Gallery " : "User ", qf->qfname ? qf->qfname : "");
672
673 fprintf(stream, " %d Input Field%s:\n", qf->numinputfields,
674 qf->numinputfields>1 ? "s" : "");
675 for (CeedInt i=0; i<qf->numinputfields; i++) {
676 ierr = CeedQFunctionFieldView(qf->inputfields[i], i, 1, stream);
677 CeedChk(ierr);
678 }
679
680 fprintf(stream, " %d Output Field%s:\n", qf->numoutputfields,
681 qf->numoutputfields>1 ? "s" : "");
682 for (CeedInt i=0; i<qf->numoutputfields; i++) {
683 ierr = CeedQFunctionFieldView(qf->outputfields[i], i, 0, stream);
684 CeedChk(ierr);
685 }
680 return 0;
681}
682
683/**
686 return 0;
687}
688
689/**
684 @brief Get the CeedEvalMode of a CeedQFunctionField
690 @brief Apply the action of a CeedQFunction
685
691
686 @param qffield CeedQFunctionField
687 @param[out] emode Variable to store the field evaluation mode
692 @param qf CeedQFunction
693 @param Q Number of quadrature points
694 @param[in] u Array of input CeedVectors
695 @param[out] v Array of output CeedVectors
688
689 @return An error code: 0 - success, otherwise - failure
690
696
697 @return An error code: 0 - success, otherwise - failure
698
691 @ref Advanced
699 @ref User
692**/
700**/
693
694int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qffield,
695 CeedEvalMode *emode) {
696 *emode = qffield->emode;
701int CeedQFunctionApply(CeedQFunction qf, CeedInt Q,
702 CeedVector *u, CeedVector *v) {
703 int ierr;
704 if (!qf->Apply)
705 // LCOV_EXCL_START
706 return CeedError(qf->ceed, 1, "Backend does not support QFunctionApply");
707 // LCOV_EXCL_STOP
708 if (Q % qf->vlength)
709 // LCOV_EXCL_START
710 return CeedError(qf->ceed, 2, "Number of quadrature points %d must be a "
711 "multiple of %d", Q, qf->vlength);
712 // LCOV_EXCL_STOP
713 ierr = qf->Apply(qf, Q, u, v); CeedChk(ierr);
697 return 0;
698}
699
700/**
701 @brief Destroy a CeedQFunction
702
703 @param qf CeedQFunction to destroy
704
705 @return An error code: 0 - success, otherwise - failure
706
714 return 0;
715}
716
717/**
718 @brief Destroy a CeedQFunction
719
720 @param qf CeedQFunction to destroy
721
722 @return An error code: 0 - success, otherwise - failure
723
707 @ref Basic
724 @ref User
708**/
709int CeedQFunctionDestroy(CeedQFunction *qf) {
710 int ierr;
711
712 if (!*qf || --(*qf)->refcount > 0)
713 return 0;
714 // Backend destroy
715 if ((*qf)->Destroy) {

--- 17 unchanged lines hidden (view full) ---

733
734 ierr = CeedFree(&(*qf)->sourcepath); CeedChk(ierr);
735 ierr = CeedFree(&(*qf)->qfname); CeedChk(ierr);
736 ierr = CeedDestroy(&(*qf)->ceed); CeedChk(ierr);
737 ierr = CeedFree(qf); CeedChk(ierr);
738 return 0;
739}
740
725**/
726int CeedQFunctionDestroy(CeedQFunction *qf) {
727 int ierr;
728
729 if (!*qf || --(*qf)->refcount > 0)
730 return 0;
731 // Backend destroy
732 if ((*qf)->Destroy) {

--- 17 unchanged lines hidden (view full) ---

750
751 ierr = CeedFree(&(*qf)->sourcepath); CeedChk(ierr);
752 ierr = CeedFree(&(*qf)->qfname); CeedChk(ierr);
753 ierr = CeedDestroy(&(*qf)->ceed); CeedChk(ierr);
754 ierr = CeedFree(qf); CeedChk(ierr);
755 return 0;
756}
757
741/// @cond DOXYGEN_SKIP
742// Indicate that no QFunction is provided by the user
743const CeedQFunction CEED_QFUNCTION_NONE = &ceed_qfunction_none;
744/// @endcond
745/// @}
758/// @}