1 // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3 //
4 // SPDX-License-Identifier: BSD-2-Clause
5 //
6 // This file is part of CEED: http://github.com/ceed
7
8 #include <ceed-impl.h>
9 #include <ceed.h>
10 #include <ceed/backend.h>
11 #include <stdbool.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <string.h>
15
16 /// @file
17 /// Implementation of public CeedQFunctionContext interfaces
18
19 /// ----------------------------------------------------------------------------
20 /// CeedQFunctionContext Library Internal Functions
21 /// ----------------------------------------------------------------------------
22 /// @addtogroup CeedQFunctionDeveloper
23 /// @{
24
25 /**
26 @brief Get index for `CeedQFunctionContext` field
27
28 @param[in] ctx `CeedQFunctionContext`
29 @param[in] field_name Name of field
30 @param[out] field_index Index of field, or `-1` if field is not registered
31
32 @return An error code: 0 - success, otherwise - failure
33
34 @ref Developer
35 **/
CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx,const char * field_name,CeedInt * field_index)36 int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) {
37 *field_index = -1;
38 for (CeedInt i = 0; i < ctx->num_fields; i++) {
39 if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i;
40 }
41 return CEED_ERROR_SUCCESS;
42 }
43
44 /**
45 @brief Common function for registering `CeedQFunctionContext` fields
46
47 @param[in,out] ctx `CeedQFunctionContext`
48 @param[in] field_name Name of field to register
49 @param[in] field_offset Offset of field to register
50 @param[in] field_description Description of field, or `NULL` for none
51 @param[in] field_type @ref CeedContextFieldType
52 @param[in] num_values Number of values to register, must be contiguous in memory
53
54 @return An error code: 0 - success, otherwise - failure
55
56 @ref Developer
57 **/
CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx,const char * field_name,size_t field_offset,const char * field_description,CeedContextFieldType field_type,size_t num_values)58 int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description,
59 CeedContextFieldType field_type, size_t num_values) {
60 size_t field_size = 0;
61 CeedInt field_index = -1;
62
63 // Check for duplicate
64 CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
65 CeedCheck(field_index == -1, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
66 "QFunctionContext field with name \"%s\" already registered", field_name);
67
68 // Allocate space for field data
69 if (ctx->num_fields == 0) {
70 CeedCall(CeedCalloc(1, &ctx->field_labels));
71 ctx->max_fields = 1;
72 } else if (ctx->num_fields == ctx->max_fields) {
73 CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels));
74 ctx->max_fields *= 2;
75 }
76 CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields]));
77
78 // Compute field size
79 switch (field_type) {
80 case CEED_CONTEXT_FIELD_DOUBLE:
81 field_size = sizeof(double);
82 break;
83 case CEED_CONTEXT_FIELD_INT32:
84 field_size = sizeof(int);
85 break;
86 case CEED_CONTEXT_FIELD_BOOL:
87 field_size = sizeof(bool);
88 break;
89 }
90
91 // Copy field data
92 CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name));
93 CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description));
94 ctx->field_labels[ctx->num_fields]->type = field_type;
95 ctx->field_labels[ctx->num_fields]->offset = field_offset;
96 ctx->field_labels[ctx->num_fields]->size = field_size * num_values;
97 ctx->field_labels[ctx->num_fields]->num_values = num_values;
98 ctx->num_fields++;
99 return CEED_ERROR_SUCCESS;
100 }
101
102 /**
103 @brief Destroy user data held by `CeedQFunctionContext`, using function set by @ref CeedQFunctionContextSetDataDestroy(), if applicable
104
105 @param[in,out] ctx `CeedQFunctionContext` to destroy user data
106
107 @return An error code: 0 - success, otherwise - failure
108
109 @ref Developer
110 **/
CeedQFunctionContextDestroyData(CeedQFunctionContext ctx)111 static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) {
112 if (ctx->DataDestroy) {
113 CeedCall(ctx->DataDestroy(ctx));
114 } else {
115 CeedMemType data_destroy_mem_type;
116 CeedQFunctionContextDataDestroyUser data_destroy_function;
117
118 CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function));
119 if (data_destroy_function) {
120 void *data;
121
122 CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data));
123 CeedCall(data_destroy_function(data));
124 CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
125 }
126 }
127 return CEED_ERROR_SUCCESS;
128 }
129
130 /**
131 @brief View a `CeedQFunctionContext` passed as a `CeedObject`
132
133 @param[in] ctx `CeedQFunctionContext` to view
134 @param[in] stream Filestream to write to
135
136 @return An error code: 0 - success, otherwise - failure
137
138 @ref Developer
139 **/
CeedQFunctionContextView_Object(CeedObject ctx,FILE * stream)140 static int CeedQFunctionContextView_Object(CeedObject ctx, FILE *stream) {
141 CeedCall(CeedQFunctionContextView((CeedQFunctionContext)ctx, stream));
142 return CEED_ERROR_SUCCESS;
143 }
144
145 /**
146 @brief Destroy a `CeedQFunctionContext` passed as a `CeedObject`
147
148 @param[in,out] ctx Address of `CeedQFunctionContext` to destroy
149
150 @return An error code: 0 - success, otherwise - failure
151
152 @ref Developer
153 **/
CeedQFunctionContextDestroy_Object(CeedObject * ctx)154 static int CeedQFunctionContextDestroy_Object(CeedObject *ctx) {
155 CeedCall(CeedQFunctionContextDestroy((CeedQFunctionContext *)ctx));
156 return CEED_ERROR_SUCCESS;
157 }
158
159 /// @}
160
161 /// ----------------------------------------------------------------------------
162 /// CeedQFunctionContext Backend API
163 /// ----------------------------------------------------------------------------
164 /// @addtogroup CeedQFunctionBackend
165 /// @{
166
167 /**
168 @brief Get the `Ceed` associated with a `CeedQFunctionContext`
169
170 @param[in] ctx `CeedQFunctionContext`
171 @param[out] ceed Variable to store `Ceed`
172
173 @return An error code: 0 - success, otherwise - failure
174
175 @ref Backend
176 **/
CeedQFunctionContextGetCeed(CeedQFunctionContext ctx,Ceed * ceed)177 int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
178 CeedCall(CeedObjectGetCeed((CeedObject)ctx, ceed));
179 return CEED_ERROR_SUCCESS;
180 }
181
182 /**
183 @brief Return the `Ceed` associated with a `CeedQFunctionContext`
184
185 @param[in] ctx `CeedQFunctionContext`
186
187 @return `Ceed` associated with `ctx`
188
189 @ref Backend
190 **/
CeedQFunctionContextReturnCeed(CeedQFunctionContext ctx)191 Ceed CeedQFunctionContextReturnCeed(CeedQFunctionContext ctx) { return CeedObjectReturnCeed((CeedObject)ctx); }
192
193 /**
194 @brief Check for valid data in a `CeedQFunctionContext`
195
196 @param[in] ctx `CeedQFunctionContext` to check validity
197 @param[out] has_valid_data Variable to store validity
198
199 @return An error code: 0 - success, otherwise - failure
200
201 @ref Backend
202 **/
CeedQFunctionContextHasValidData(CeedQFunctionContext ctx,bool * has_valid_data)203 int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) {
204 CeedCheck(ctx->HasValidData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
205 "Backend does not support CeedQFunctionContextHasValidData");
206 CeedCall(ctx->HasValidData(ctx, has_valid_data));
207 return CEED_ERROR_SUCCESS;
208 }
209
210 /**
211 @brief Check for borrowed data of a specific @ref CeedMemType in a `CeedQFunctionContext`
212
213 @param[in] ctx `CeedQFunctionContext` to check
214 @param[in] mem_type Memory type to check
215 @param[out] has_borrowed_data_of_type Variable to store result
216
217 @return An error code: 0 - success, otherwise - failure
218
219 @ref Backend
220 **/
CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx,CeedMemType mem_type,bool * has_borrowed_data_of_type)221 int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) {
222 CeedCheck(ctx->HasBorrowedDataOfType, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
223 "Backend does not support CeedQFunctionContextHasBorrowedDataOfType");
224 CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type));
225 return CEED_ERROR_SUCCESS;
226 }
227
228 /**
229 @brief Get the state of a `CeedQFunctionContext`
230
231 @param[in] ctx `CeedQFunctionContext` to retrieve state
232 @param[out] state Variable to store state
233
234 @return An error code: 0 - success, otherwise - failure
235
236 @ref Backend
237 **/
CeedQFunctionContextGetState(CeedQFunctionContext ctx,uint64_t * state)238 int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
239 *state = ctx->state;
240 return CEED_ERROR_SUCCESS;
241 }
242
243 /**
244 @brief Get backend data of a `CeedQFunctionContext`
245
246 @param[in] ctx `CeedQFunctionContext`
247 @param[out] data Variable to store data
248
249 @return An error code: 0 - success, otherwise - failure
250
251 @ref Backend
252 **/
CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx,void * data)253 int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
254 *(void **)data = ctx->data;
255 return CEED_ERROR_SUCCESS;
256 }
257
258 /**
259 @brief Set backend data of a `CeedQFunctionContext`
260
261 @param[in,out] ctx `CeedQFunctionContext`
262 @param[in] data Data to set
263
264 @return An error code: 0 - success, otherwise - failure
265
266 @ref Backend
267 **/
CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx,void * data)268 int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
269 ctx->data = data;
270 return CEED_ERROR_SUCCESS;
271 }
272
273 /**
274 @brief Get label for a registered `CeedQFunctionContext` field, or `NULL` if no field has been registered with this `field_name`
275
276 @param[in] ctx `CeedQFunctionContext`
277 @param[in] field_name Name of field to retrieve label
278 @param[out] field_label Variable to field label
279
280 @return An error code: 0 - success, otherwise - failure
281
282 @ref Backend
283 **/
CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx,const char * field_name,CeedContextFieldLabel * field_label)284 int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) {
285 CeedInt field_index;
286
287 CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index));
288
289 if (field_index != -1) {
290 *field_label = ctx->field_labels[field_index];
291 } else {
292 *field_label = NULL;
293 }
294 return CEED_ERROR_SUCCESS;
295 }
296
297 /**
298 @brief Set `CeedQFunctionContext` field
299
300 @param[in,out] ctx `CeedQFunctionContext`
301 @param[in] field_label Label of field to set
302 @param[in] field_type Type of field to set
303 @param[in] values Value to set
304
305 @return An error code: 0 - success, otherwise - failure
306
307 @ref Backend
308 **/
CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,CeedContextFieldType field_type,void * values)309 int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) {
310 bool is_different;
311 char *data;
312
313 // Check field type
314 CeedCheck(field_label->type == field_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
315 "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
316 CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
317
318 CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
319 is_different = memcmp(&data[field_label->offset], values, field_label->size);
320 CeedCall(CeedQFunctionContextRestoreDataRead(ctx, &data));
321 if (is_different) {
322 CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data));
323 memcpy(&data[field_label->offset], values, field_label->size);
324 CeedCall(CeedQFunctionContextRestoreData(ctx, &data));
325 }
326 return CEED_ERROR_SUCCESS;
327 }
328
329 /**
330 @brief Get `CeedQFunctionContext` field data, read-only
331
332 @param[in] ctx `CeedQFunctionContext`
333 @param[in] field_label Label of field to read
334 @param[in] field_type Type of field to read
335 @param[out] num_values Number of values in the field label
336 @param[out] values Pointer to context values
337
338 @return An error code: 0 - success, otherwise - failure
339
340 @ref Backend
341 **/
CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,CeedContextFieldType field_type,size_t * num_values,void * values)342 int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
343 size_t *num_values, void *values) {
344 char *data;
345
346 // Check field type
347 CeedCheck(field_label->type == field_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
348 "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
349 CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
350
351 CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data));
352 *(void **)values = &data[field_label->offset];
353 switch (field_type) {
354 case CEED_CONTEXT_FIELD_INT32:
355 *num_values = field_label->size / sizeof(int);
356 break;
357 case CEED_CONTEXT_FIELD_DOUBLE:
358 *num_values = field_label->size / sizeof(double);
359 break;
360 case CEED_CONTEXT_FIELD_BOOL:
361 *num_values = field_label->size / sizeof(bool);
362 break;
363 }
364 return CEED_ERROR_SUCCESS;
365 }
366
367 /**
368 @brief Restore `CeedQFunctionContext` field data, read-only
369
370 @param[in] ctx `CeedQFunctionContext`
371 @param[in] field_label Label of field to restore
372 @param[in] field_type Type of field to restore
373 @param[out] values Pointer to context values
374
375 @return An error code: 0 - success, otherwise - failure
376
377 @ref Backend
378 **/
CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,CeedContextFieldType field_type,void * values)379 int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type,
380 void *values) {
381 // Check field type
382 CeedCheck(field_label->type == field_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
383 "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", field_label->name,
384 CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]);
385
386 CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values));
387 return CEED_ERROR_SUCCESS;
388 }
389
390 /**
391 @brief Set `CeedQFunctionContext` field holding double precision values
392
393 @param[in,out] ctx `CeedQFunctionContext`
394 @param[in] field_label Label for field to set
395 @param[in] values Values to set
396
397 @return An error code: 0 - success, otherwise - failure
398
399 @ref Backend
400 **/
CeedQFunctionContextSetDouble(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,double * values)401 int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) {
402 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
403 CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
404 return CEED_ERROR_SUCCESS;
405 }
406
407 /**
408 @brief Get `CeedQFunctionContext` field holding double precision values, read-only
409
410 @param[in] ctx `CeedQFunctionContext`
411 @param[in] field_label Label for field to get
412 @param[out] num_values Number of values in the field label
413 @param[out] values Pointer to context values
414
415 @return An error code: 0 - success, otherwise - failure
416
417 @ref Backend
418 **/
CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,size_t * num_values,const double ** values)419 int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) {
420 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
421 CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values));
422 return CEED_ERROR_SUCCESS;
423 }
424
425 /**
426 @brief Restore `CeedQFunctionContext` field holding double precision values, read-only
427
428 @param[in] ctx `CeedQFunctionContext`
429 @param[in] field_label Label for field to restore
430 @param[out] values Pointer to context values
431
432 @return An error code: 0 - success, otherwise - failure
433
434 @ref Backend
435 **/
CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,const double ** values)436 int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) {
437 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
438 CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values));
439 return CEED_ERROR_SUCCESS;
440 }
441
442 /**
443 @brief Set CeedQFunctionContext field holding `int32` values
444
445 @param[in,out] ctx CeedQFunctionContext
446 @param[in] field_label Label for field to set
447 @param[in] values Values to set
448
449 @return An error code: 0 - success, otherwise - failure
450
451 @ref Backend
452 **/
CeedQFunctionContextSetInt32(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,int32_t * values)453 int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int32_t *values) {
454 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
455 CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
456 return CEED_ERROR_SUCCESS;
457 }
458
459 /**
460 @brief Get `CeedQFunctionContext` field holding `int32` values, read-only
461
462 @param[in] ctx `CeedQFunctionContext`
463 @param[in] field_label Label for field to get
464 @param[out] num_values Number of values in the field label
465 @param[out] values Pointer to context values
466
467 @return An error code: 0 - success, otherwise - failure
468
469 @ref Backend
470 **/
CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,size_t * num_values,const int32_t ** values)471 int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int32_t **values) {
472 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
473 CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values));
474 return CEED_ERROR_SUCCESS;
475 }
476
477 /**
478 @brief Restore `CeedQFunctionContext` field holding `int32` values, read-only
479
480 @param[in] ctx `CeedQFunctionContext`
481 @param[in] field_label Label for field to restore
482 @param[out] values Pointer to context values
483
484 @return An error code: 0 - success, otherwise - failure
485
486 @ref Backend
487 **/
CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,const int32_t ** values)488 int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int32_t **values) {
489 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
490 CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values));
491 return CEED_ERROR_SUCCESS;
492 }
493
494 /**
495 @brief Set `CeedQFunctionContext` field holding boolean values
496
497 @param[in,out] ctx `CeedQFunctionContext`
498 @param[in] field_label Label for field to set
499 @param[in] values Values to set
500
501 @return An error code: 0 - success, otherwise - failure
502
503 @ref Backend
504 **/
CeedQFunctionContextSetBoolean(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,bool * values)505 int CeedQFunctionContextSetBoolean(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, bool *values) {
506 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
507 CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
508 return CEED_ERROR_SUCCESS;
509 }
510
511 /**
512 @brief Get `CeedQFunctionContext` field holding boolean values, read-only
513
514 @param[in] ctx `CeedQFunctionContext`
515 @param[in] field_label Label for field to get
516 @param[out] num_values Number of values in the field label
517 @param[out] values Pointer to context values
518
519 @return An error code: 0 - success, otherwise - failure
520
521 @ref Backend
522 **/
CeedQFunctionContextGetBooleanRead(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,size_t * num_values,const bool ** values)523 int CeedQFunctionContextGetBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const bool **values) {
524 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
525 CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, num_values, values));
526 return CEED_ERROR_SUCCESS;
527 }
528
529 /**
530 @brief Restore `CeedQFunctionContext` field holding boolean values, read-only
531
532 @param[in] ctx `CeedQFunctionContext`
533 @param[in] field_label Label for field to restore
534 @param[out] values Pointer to context values
535
536 @return An error code: 0 - success, otherwise - failure
537
538 @ref Backend
539 **/
CeedQFunctionContextRestoreBooleanRead(CeedQFunctionContext ctx,CeedContextFieldLabel field_label,const bool ** values)540 int CeedQFunctionContextRestoreBooleanRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const bool **values) {
541 CeedCheck(field_label, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Invalid field label");
542 CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_BOOL, values));
543 return CEED_ERROR_SUCCESS;
544 }
545
546 /**
547 @brief Get additional destroy routine for `CeedQFunctionContext` user data
548
549 @param[in] ctx `CeedQFunctionContext` to get user destroy function
550 @param[out] f_mem_type Memory type to use when passing data into `f`
551 @param[out] f Additional routine to use to destroy user data
552
553 @return An error code: 0 - success, otherwise - failure
554
555 @ref Backend
556 **/
CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx,CeedMemType * f_mem_type,CeedQFunctionContextDataDestroyUser * f)557 int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) {
558 if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type;
559 if (f) *f = ctx->data_destroy_function;
560 return CEED_ERROR_SUCCESS;
561 }
562
563 /**
564 @brief Increment the reference counter for a `CeedQFunctionContext`
565
566 @param[in,out] ctx `CeedQFunctionContext` to increment the reference counter
567
568 @return An error code: 0 - success, otherwise - failure
569
570 @ref Backend
571 **/
CeedQFunctionContextReference(CeedQFunctionContext ctx)572 int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
573 CeedCall(CeedObjectReference((CeedObject)ctx));
574 return CEED_ERROR_SUCCESS;
575 }
576
577 /// @}
578
579 /// ----------------------------------------------------------------------------
580 /// CeedQFunctionContext Public API
581 /// ----------------------------------------------------------------------------
582 /// @addtogroup CeedQFunctionUser
583 /// @{
584
585 /**
586 @brief Create a `CeedQFunctionContext` for storing `CeedQFunctionContext` user context data
587
588 @param[in] ceed `Ceed` object used to create the `CeedQFunctionContext`
589 @param[out] ctx Address of the variable where the newly created `CeedQFunctionContext` will be stored
590
591 @return An error code: 0 - success, otherwise - failure
592
593 @ref User
594 **/
CeedQFunctionContextCreate(Ceed ceed,CeedQFunctionContext * ctx)595 int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
596 if (!ceed->QFunctionContextCreate) {
597 Ceed delegate;
598
599 CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context"));
600 CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement CeedQFunctionContextCreate");
601 CeedCall(CeedQFunctionContextCreate(delegate, ctx));
602 CeedCall(CeedDestroy(&delegate));
603 return CEED_ERROR_SUCCESS;
604 }
605
606 CeedCall(CeedCalloc(1, ctx));
607 CeedCall(CeedObjectCreate(ceed, CeedQFunctionContextView_Object, CeedQFunctionContextDestroy_Object, &(*ctx)->obj));
608 CeedCall(ceed->QFunctionContextCreate(*ctx));
609 return CEED_ERROR_SUCCESS;
610 }
611
612 /**
613 @brief Copy the pointer to a `CeedQFunctionContext`.
614
615 Both pointers should be destroyed with @ref CeedQFunctionContextDestroy().
616
617 Note: If the value of `*ctx_copy` passed to this function is non-`NULL`, then it is assumed that `*ctx_copy` is a pointer to a `CeedQFunctionContext`.
618 This `CeedQFunctionContext` will be destroyed if `*ctx_copy` is the only reference to this `CeedQFunctionContext`.
619
620 @param[in] ctx CeedQFunctionContext to copy reference to
621 @param[in,out] ctx_copy Variable to store copied reference
622
623 @return An error code: 0 - success, otherwise - failure
624
625 @ref User
626 **/
CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,CeedQFunctionContext * ctx_copy)627 int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) {
628 CeedCall(CeedQFunctionContextReference(ctx));
629 CeedCall(CeedQFunctionContextDestroy(ctx_copy));
630 *ctx_copy = ctx;
631 return CEED_ERROR_SUCCESS;
632 }
633
634 /**
635 @brief Set the data used by a `CeedQFunctionContext`, freeing any previously allocated data if applicable.
636
637 The backend may copy values to a different @ref CeedMemType, such as during @ref CeedQFunctionApply().
638 See also @ref CeedQFunctionContextTakeData().
639
640 @param[in,out] ctx `CeedQFunctionContext`
641 @param[in] mem_type Memory type of the data being passed
642 @param[in] copy_mode Copy mode for the data
643 @param[in] size Size of data, in bytes
644 @param[in] data Data to be used
645
646 @return An error code: 0 - success, otherwise - failure
647
648 @ref User
649 **/
CeedQFunctionContextSetData(CeedQFunctionContext ctx,CeedMemType mem_type,CeedCopyMode copy_mode,size_t size,void * data)650 int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) {
651 CeedCheck(ctx->SetData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextSetData");
652 CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
653 "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
654
655 CeedCall(CeedQFunctionContextDestroyData(ctx));
656 ctx->ctx_size = size;
657 CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data));
658 ctx->state += 2;
659 return CEED_ERROR_SUCCESS;
660 }
661
662 /**
663 @brief Take ownership of the data in a `CeedQFunctionContext` via the specified memory type.
664
665 The caller is responsible for managing and freeing the memory.
666
667 @param[in] ctx `CeedQFunctionContext` to access
668 @param[in] mem_type Memory type on which to access the data.
669 If the backend uses a different memory type, this will perform a copy.
670 @param[out] data Data on memory type mem_type
671
672 @return An error code: 0 - success, otherwise - failure
673
674 @ref User
675 **/
CeedQFunctionContextTakeData(CeedQFunctionContext ctx,CeedMemType mem_type,void * data)676 int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
677 void *temp_data = NULL;
678 bool has_valid_data = true, has_borrowed_data_of_type = true;
679
680 CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
681 CeedCheck(has_valid_data, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data");
682
683 CeedCheck(ctx->TakeData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextTakeData");
684 CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
685 "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
686
687 CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type));
688 CeedCheck(has_borrowed_data_of_type, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND,
689 "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", CeedMemTypes[mem_type]);
690
691 CeedCall(ctx->TakeData(ctx, mem_type, &temp_data));
692 if (data) (*(void **)data) = temp_data;
693 return CEED_ERROR_SUCCESS;
694 }
695
696 /**
697 @brief Get read/write access to a `CeedQFunctionContext` via the specified memory type.
698
699 Restore access with @ref CeedQFunctionContextRestoreData().
700
701 @param[in] ctx `CeedQFunctionContext` to access
702 @param[in] mem_type Memory type on which to access the data.
703 If the backend uses a different memory type, this will perform a copy.
704 @param[out] data Data on memory type mem_type
705
706 @note The @ref CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory space.
707 Pairing get/restore allows the `CeedQFunctionContext` to track access.
708
709 @return An error code: 0 - success, otherwise - failure
710
711 @ref User
712 **/
CeedQFunctionContextGetData(CeedQFunctionContext ctx,CeedMemType mem_type,void * data)713 int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
714 bool has_valid_data = true;
715
716 CeedCheck(ctx->GetData, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionContextGetData");
717 CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
718 "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
719 CeedCheck(ctx->num_readers == 0, CeedQFunctionContextReturnCeed(ctx), 1,
720 "Cannot grant CeedQFunctionContext data access, a process has read access");
721
722 CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
723 CeedCheck(has_valid_data, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
724
725 CeedCall(ctx->GetData(ctx, mem_type, data));
726 ctx->state++;
727 return CEED_ERROR_SUCCESS;
728 }
729
730 /**
731 @brief Get read only access to a `CeedQFunctionContext` via the specified memory type.
732
733 Restore access with @ref CeedQFunctionContextRestoreData().
734
735 @param[in] ctx `CeedQFunctionContext` to access
736 @param[in] mem_type Memory type on which to access the data.
737 If the backend uses a different memory type, this will perform a copy.
738 @param[out] data Data on memory type mem_type
739
740 @note The @ref CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired memory space.
741 Pairing get/restore allows the `CeedQFunctionContext` to track access.
742
743 @return An error code: 0 - success, otherwise - failure
744
745 @ref User
746 **/
CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx,CeedMemType mem_type,void * data)747 int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) {
748 bool has_valid_data = true;
749
750 CeedCheck(ctx->GetDataRead, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_UNSUPPORTED,
751 "Backend does not support CeedQFunctionContextGetDataRead");
752 CeedCheck(ctx->state % 2 == 0, CeedQFunctionContextReturnCeed(ctx), 1,
753 "Cannot grant CeedQFunctionContext data access, the access lock is already in use");
754
755 CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
756 CeedCheck(has_valid_data, CeedQFunctionContextReturnCeed(ctx), CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data");
757
758 CeedCall(ctx->GetDataRead(ctx, mem_type, data));
759 ctx->num_readers++;
760 return CEED_ERROR_SUCCESS;
761 }
762
763 /**
764 @brief Restore data obtained using @ref CeedQFunctionContextGetData()
765
766 @param[in] ctx `CeedQFunctionContext` to restore
767 @param[in,out] data Data to restore
768
769 @return An error code: 0 - success, otherwise - failure
770
771 @ref User
772 **/
CeedQFunctionContextRestoreData(CeedQFunctionContext ctx,void * data)773 int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
774 CeedCheck(ctx->state % 2 == 1, CeedQFunctionContextReturnCeed(ctx), 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
775
776 if (ctx->RestoreData) CeedCall(ctx->RestoreData(ctx));
777 *(void **)data = NULL;
778 ctx->state++;
779 return CEED_ERROR_SUCCESS;
780 }
781
782 /**
783 @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead()
784
785 @param[in] ctx `CeedQFunctionContext` to restore
786 @param[in,out] data Data to restore
787
788 @return An error code: 0 - success, otherwise - failure
789
790 @ref User
791 **/
CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx,void * data)792 int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) {
793 CeedCheck(ctx->num_readers > 0, CeedQFunctionContextReturnCeed(ctx), 1, "Cannot restore CeedQFunctionContext array access, access was not granted");
794
795 ctx->num_readers--;
796 if (ctx->num_readers == 0 && ctx->RestoreDataRead) CeedCall(ctx->RestoreDataRead(ctx));
797 *(void **)data = NULL;
798 return CEED_ERROR_SUCCESS;
799 }
800
801 /**
802 @brief Register a `CeedQFunctionContext` field holding double precision values
803
804 @param[in,out] ctx `CeedQFunctionContext`
805 @param[in] field_name Name of field to register
806 @param[in] field_offset Offset of field to register
807 @param[in] num_values Number of values to register, must be contiguous in memory
808 @param[in] field_description Description of field, or `NULL` for none
809
810 @return An error code: 0 - success, otherwise - failure
811
812 @ref User
813 **/
CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx,const char * field_name,size_t field_offset,size_t num_values,const char * field_description)814 int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
815 const char *field_description) {
816 return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, num_values);
817 }
818
819 /**
820 @brief Register a `CeedQFunctionContext` field holding `int32` values
821
822 @param[in,out] ctx CeedQFunctionContext
823 @param[in] field_name Name of field to register
824 @param[in] field_offset Offset of field to register
825 @param[in] num_values Number of values to register, must be contiguous in memory
826 @param[in] field_description Description of field, or `NULL` for none
827
828 @return An error code: 0 - success, otherwise - failure
829
830 @ref User
831 **/
CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx,const char * field_name,size_t field_offset,size_t num_values,const char * field_description)832 int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
833 const char *field_description) {
834 return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, num_values);
835 }
836
837 /**
838 @brief Register a `CeedQFunctionContext` field holding boolean values
839
840 @param[in,out] ctx `CeedQFunctionContext`
841 @param[in] field_name Name of field to register
842 @param[in] field_offset Offset of field to register
843 @param[in] num_values Number of values to register, must be contiguous in memory
844 @param[in] field_description Description of field, or `NULL` for none
845
846 @return An error code: 0 - success, otherwise - failure
847
848 @ref User
849 **/
CeedQFunctionContextRegisterBoolean(CeedQFunctionContext ctx,const char * field_name,size_t field_offset,size_t num_values,const char * field_description)850 int CeedQFunctionContextRegisterBoolean(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values,
851 const char *field_description) {
852 return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_BOOL, num_values);
853 }
854
855 /**
856 @brief Get labels for all registered `CeedQFunctionContext` fields
857
858 @param[in] ctx `CeedQFunctionContext`
859 @param[out] field_labels Variable to hold array of field labels
860 @param[out] num_fields Length of field descriptions array
861
862 @return An error code: 0 - success, otherwise - failure
863
864 @ref User
865 **/
CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx,const CeedContextFieldLabel ** field_labels,CeedInt * num_fields)866 int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) {
867 *field_labels = ctx->field_labels;
868 *num_fields = ctx->num_fields;
869 return CEED_ERROR_SUCCESS;
870 }
871
872 /**
873 @brief Get the descriptive information about a `CeedContextFieldLabel`
874
875 @param[in] label @ref CeedContextFieldLabel
876 @param[out] field_name Name of labeled field
877 @param[out] field_offset Offset of field registered
878 @param[out] num_values Number of values registered
879 @param[out] field_description Description of field, or NULL for none
880 @param[out] field_type @ref CeedContextFieldType
881
882 @return An error code: 0 - success, otherwise - failure
883
884 @ref User
885 **/
CeedContextFieldLabelGetDescription(CeedContextFieldLabel label,const char ** field_name,size_t * field_offset,size_t * num_values,const char ** field_description,CeedContextFieldType * field_type)886 int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, size_t *field_offset, size_t *num_values,
887 const char **field_description, CeedContextFieldType *field_type) {
888 if (field_name) *field_name = label->name;
889 if (field_offset) *field_offset = label->offset;
890 if (num_values) *num_values = label->num_values;
891 if (field_description) *field_description = label->description;
892 if (field_type) *field_type = label->type;
893 return CEED_ERROR_SUCCESS;
894 }
895
896 /**
897 @brief Get data size for a Context
898
899 @param[in] ctx `CeedQFunctionContext`
900 @param[out] ctx_size Variable to store size of context data values
901
902 @return An error code: 0 - success, otherwise - failure
903
904 @ref User
905 **/
CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,size_t * ctx_size)906 int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) {
907 *ctx_size = ctx->ctx_size;
908 return CEED_ERROR_SUCCESS;
909 }
910
911 /**
912 @brief Set the number of tabs to indent for @ref CeedQFunctionContextView() output
913
914 @param[in] ctx `CeedQFunctionContext` to set the number of view tabs
915 @param[in] num_tabs Number of view tabs to set
916
917 @return Error code: 0 - success, otherwise - failure
918
919 @ref User
920 **/
CeedQFunctionContextSetNumViewTabs(CeedQFunctionContext ctx,CeedInt num_tabs)921 int CeedQFunctionContextSetNumViewTabs(CeedQFunctionContext ctx, CeedInt num_tabs) {
922 CeedCall(CeedObjectSetNumViewTabs((CeedObject)ctx, num_tabs));
923 return CEED_ERROR_SUCCESS;
924 }
925
926 /**
927 @brief Get the number of tabs to indent for @ref CeedQFunctionContextView() output
928
929 @param[in] ctx `CeedQFunctionContext` to get the number of view tabs
930 @param[out] num_tabs Number of view tabs
931
932 @return Error code: 0 - success, otherwise - failure
933
934 @ref User
935 **/
CeedQFunctionContextGetNumViewTabs(CeedQFunctionContext ctx,CeedInt * num_tabs)936 int CeedQFunctionContextGetNumViewTabs(CeedQFunctionContext ctx, CeedInt *num_tabs) {
937 CeedCall(CeedObjectGetNumViewTabs((CeedObject)ctx, num_tabs));
938 return CEED_ERROR_SUCCESS;
939 }
940
941 /**
942 @brief View a `CeedQFunctionContext`
943
944 @param[in] ctx `CeedQFunctionContext` to view
945 @param[in] stream Filestream to write to
946
947 @return An error code: 0 - success, otherwise - failure
948
949 @ref User
950 **/
CeedQFunctionContextView(CeedQFunctionContext ctx,FILE * stream)951 int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
952 char *tabs = NULL;
953
954 {
955 CeedInt num_tabs = 0;
956
957 CeedCall(CeedQFunctionContextGetNumViewTabs(ctx, &num_tabs));
958 CeedCall(CeedCalloc(CEED_TAB_WIDTH * num_tabs + 1, &tabs));
959 for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' ';
960 }
961
962 fprintf(stream, "%sCeedQFunctionContext\n", tabs);
963 fprintf(stream, "%s Context Data Size: %zu\n", tabs, ctx->ctx_size);
964 for (CeedInt i = 0; i < ctx->num_fields; i++) {
965 fprintf(stream, "%s Labeled %s field: %s\n", tabs, CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name);
966 }
967 CeedCall(CeedFree(&tabs));
968 return CEED_ERROR_SUCCESS;
969 }
970
971 /**
972 @brief Set additional destroy routine for `CeedQFunctionContext` user data
973
974 @param[in,out] ctx `CeedQFunctionContext` to set user destroy function
975 @param[in] f_mem_type Memory type to use when passing data into `f`
976 @param[in] f Additional routine to use to destroy user data
977
978 @return An error code: 0 - success, otherwise - failure
979
980 @ref User
981 **/
CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx,CeedMemType f_mem_type,CeedQFunctionContextDataDestroyUser f)982 int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) {
983 CeedCheck(f, CeedQFunctionContextReturnCeed(ctx), 1, "Must provide valid callback function for destroying user data");
984 ctx->data_destroy_mem_type = f_mem_type;
985 ctx->data_destroy_function = f;
986 return CEED_ERROR_SUCCESS;
987 }
988
989 /**
990 @brief Destroy a `CeedQFunctionContext`
991
992 @param[in,out] ctx `CeedQFunctionContext` to destroy
993
994 @return An error code: 0 - success, otherwise - failure
995
996 @ref User
997 **/
CeedQFunctionContextDestroy(CeedQFunctionContext * ctx)998 int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
999 if (!*ctx || CeedObjectDereference((CeedObject)*ctx) > 0) {
1000 *ctx = NULL;
1001 return CEED_ERROR_SUCCESS;
1002 }
1003 CeedCheck(((*ctx)->state % 2) == 0, CeedQFunctionContextReturnCeed(*ctx), 1, "Cannot destroy CeedQFunctionContext, the access lock is in use");
1004
1005 CeedCall(CeedQFunctionContextDestroyData(*ctx));
1006 if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx));
1007 for (CeedInt i = 0; i < (*ctx)->num_fields; i++) {
1008 CeedCall(CeedFree(&(*ctx)->field_labels[i]->name));
1009 CeedCall(CeedFree(&(*ctx)->field_labels[i]->description));
1010 CeedCall(CeedFree(&(*ctx)->field_labels[i]));
1011 }
1012 CeedCall(CeedFree(&(*ctx)->field_labels));
1013 CeedCall(CeedObjectDestroy_Private(&(*ctx)->obj));
1014 CeedCall(CeedFree(ctx));
1015 return CEED_ERROR_SUCCESS;
1016 }
1017
1018 /// @}
1019