13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3d7b241e6Sjeremylt // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5d7b241e6Sjeremylt // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7d7b241e6Sjeremylt 83d576824SJeremy L Thompson #include <ceed-impl.h> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 112b730f8bSJeremy L Thompson #include <ceed/jit-tools.h> 12288c0443SJeremy L Thompson #include <limits.h> 133d576824SJeremy L Thompson #include <stdbool.h> 143d576824SJeremy L Thompson #include <stdio.h> 153d576824SJeremy L Thompson #include <string.h> 16288c0443SJeremy L Thompson 177a982d89SJeremy L. Thompson /// @file 187a982d89SJeremy L. Thompson /// Implementation of public CeedQFunction interfaces 197a982d89SJeremy L. Thompson 20288c0443SJeremy L Thompson /// @cond DOXYGEN_SKIP 21442e7f0bSjeremylt static struct CeedQFunction_private ceed_qfunction_none; 22442e7f0bSjeremylt /// @endcond 23442e7f0bSjeremylt 247a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 257a982d89SJeremy L. Thompson /// @{ 267a982d89SJeremy L. Thompson 27ca94c3ddSJeremy L Thompson // Indicate that no `CeedQFunction` is provided by the user 287a982d89SJeremy L. Thompson const CeedQFunction CEED_QFUNCTION_NONE = &ceed_qfunction_none; 297a982d89SJeremy L. Thompson 307a982d89SJeremy L. Thompson /// @} 317a982d89SJeremy L. Thompson 32442e7f0bSjeremylt /// @cond DOXYGEN_SKIP 33288c0443SJeremy L Thompson static struct { 34288c0443SJeremy L Thompson char name[CEED_MAX_RESOURCE_LEN]; 35288c0443SJeremy L Thompson char source[CEED_MAX_RESOURCE_LEN]; 36d1d35e2fSjeremylt CeedInt vec_length; 37288c0443SJeremy L Thompson CeedQFunctionUser f; 38288c0443SJeremy L Thompson int (*init)(Ceed ceed, const char *name, CeedQFunction qf); 39d1d35e2fSjeremylt } gallery_qfunctions[1024]; 40288c0443SJeremy L Thompson static size_t num_qfunctions; 41288c0443SJeremy L Thompson /// @endcond 42d7b241e6Sjeremylt 43777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 44777ff853SJeremy L Thompson /// CeedQFunction Library Internal Functions 45777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 46777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper 47777ff853SJeremy L Thompson /// @{ 48777ff853SJeremy L Thompson 49b11c1e72Sjeremylt /** 50ca94c3ddSJeremy L Thompson @brief Register a gallery `CeedQFunction` 51288c0443SJeremy L Thompson 52ea61e9acSJeremy L Thompson @param[in] name Name for this backend to respond to 53ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunction`, "\path\CEED_DIR\gallery\folder\file.h:function_name" 54ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 55ca94c3ddSJeremy L Thompson Caller must ensure that number of quadrature points is a multiple of `vec_length`. 56ea61e9acSJeremy L Thompson @param[in] f Function pointer to evaluate action at quadrature points. 57ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 58ca94c3ddSJeremy L Thompson @param[in] init Initialization function called by @ref CeedQFunctionCreateInteriorByName() when the `CeedQFunction` is selected. 59288c0443SJeremy L Thompson 60288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 61288c0443SJeremy L Thompson 627a982d89SJeremy L. Thompson @ref Developer 63288c0443SJeremy L Thompson **/ 642b730f8bSJeremy L Thompson int CeedQFunctionRegister(const char *name, const char *source, CeedInt vec_length, CeedQFunctionUser f, 65288c0443SJeremy L Thompson int (*init)(Ceed, const char *, CeedQFunction)) { 661c66c397SJeremy L Thompson const char *relative_file_path; 6758c07c4fSSebastian Grimberg int ierr = 0; 68c042f62fSJeremy L Thompson 698ccf1006SJeremy L Thompson CeedDebugEnv("Gallery Register: %s", name); 702b730f8bSJeremy L Thompson CeedCall(CeedGetJitRelativePath(source, &relative_file_path)); 7158c07c4fSSebastian Grimberg CeedPragmaCritical(CeedQFunctionRegister) { 7258c07c4fSSebastian Grimberg if (num_qfunctions < sizeof(gallery_qfunctions) / sizeof(gallery_qfunctions[0])) { 73d1d35e2fSjeremylt strncpy(gallery_qfunctions[num_qfunctions].name, name, CEED_MAX_RESOURCE_LEN); 74d1d35e2fSjeremylt gallery_qfunctions[num_qfunctions].name[CEED_MAX_RESOURCE_LEN - 1] = 0; 752b730f8bSJeremy L Thompson strncpy(gallery_qfunctions[num_qfunctions].source, relative_file_path, CEED_MAX_RESOURCE_LEN); 76d1d35e2fSjeremylt gallery_qfunctions[num_qfunctions].source[CEED_MAX_RESOURCE_LEN - 1] = 0; 77d1d35e2fSjeremylt gallery_qfunctions[num_qfunctions].vec_length = vec_length; 78d1d35e2fSjeremylt gallery_qfunctions[num_qfunctions].f = f; 79d1d35e2fSjeremylt gallery_qfunctions[num_qfunctions].init = init; 80288c0443SJeremy L Thompson num_qfunctions++; 8158c07c4fSSebastian Grimberg } else { 8258c07c4fSSebastian Grimberg ierr = 1; 8358c07c4fSSebastian Grimberg } 8458c07c4fSSebastian Grimberg } 85ca94c3ddSJeremy L Thompson CeedCheck(ierr == 0, NULL, CEED_ERROR_MAJOR, "Too many gallery CeedQFunctions"); 86e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 87288c0443SJeremy L Thompson } 88288c0443SJeremy L Thompson 89288c0443SJeremy L Thompson /** 90ca94c3ddSJeremy L Thompson @brief Set a `CeedQFunction` field, used by @ref CeedQFunctionAddInput() and @ref CeedQFunctionAddOutput() 917a982d89SJeremy L. Thompson 92ca94c3ddSJeremy L Thompson @param[out] f `CeedQFunctionField` 93ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 94ca94c3ddSJeremy L Thompson @param[in] size Size of `CeedQFunction` field, (`num_comp * 1`) for @ref CEED_EVAL_NONE and @ref CEED_EVAL_WEIGHT, (`num_comp * 1`) for @ref CEED_EVAL_INTERP for an \f$H^1\f$ space or (`num_comp * dim`) for an \f$H(\mathrm{div})\f$ or \f$H(\mathrm{curl})\f$ space, (`num_comp * dim`) for @ref CEED_EVAL_GRAD, or (num_comp * 1) for @ref CEED_EVAL_DIV, and (`num_comp * curl_dim`) with `curl_dim = 1` if `dim < 3` and `curl_dim = dim` for @ref CEED_EVAL_CURL. 95ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 96ca94c3ddSJeremy L Thompson @ref CEED_EVAL_WEIGHT to use quadrature weights, 97ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 98ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 99ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 100ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 1017a982d89SJeremy L. Thompson 1027a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1037a982d89SJeremy L. Thompson 1047a982d89SJeremy L. Thompson @ref Developer 1057a982d89SJeremy L. Thompson **/ 1062b730f8bSJeremy L Thompson static int CeedQFunctionFieldSet(CeedQFunctionField *f, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 1072b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, f)); 1082b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&(*f)->field_name)); 1097a982d89SJeremy L. Thompson (*f)->size = size; 110d1d35e2fSjeremylt (*f)->eval_mode = eval_mode; 111e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1127a982d89SJeremy L. Thompson } 1137a982d89SJeremy L. Thompson 1147a982d89SJeremy L. Thompson /** 115ca94c3ddSJeremy L Thompson @brief View a field of a `CeedQFunction` 1167a982d89SJeremy L. Thompson 117ca94c3ddSJeremy L Thompson @param[in] field `CeedQFunction` field to view 118d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1194c4400c7SValeria Barra @param[in] in true for input field, false for output 120ca94c3ddSJeremy L Thompson @param[in] stream Stream to view to, e.g., `stdout` 1217a982d89SJeremy L. Thompson 1227a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1237a982d89SJeremy L. Thompson 1247a982d89SJeremy L. Thompson @ref Utility 1257a982d89SJeremy L. Thompson **/ 1262b730f8bSJeremy L Thompson static int CeedQFunctionFieldView(CeedQFunctionField field, CeedInt field_number, bool in, FILE *stream) { 1277a982d89SJeremy L. Thompson const char *inout = in ? "Input" : "Output"; 1288229195eSjeremylt char *field_name; 1298229195eSjeremylt CeedInt size; 1308229195eSjeremylt CeedEvalMode eval_mode; 1311c66c397SJeremy L Thompson 1321c66c397SJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(field, &field_name)); 1331c66c397SJeremy L Thompson CeedCall(CeedQFunctionFieldGetSize(field, &size)); 1342b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(field, &eval_mode)); 1352b730f8bSJeremy L Thompson fprintf(stream, 1362b730f8bSJeremy L Thompson " %s field %" CeedInt_FMT 1372b730f8bSJeremy L Thompson ":\n" 1387a982d89SJeremy L. Thompson " Name: \"%s\"\n" 1392b730f8bSJeremy L Thompson " Size: %" CeedInt_FMT 1402b730f8bSJeremy L Thompson "\n" 1417a982d89SJeremy L. Thompson " EvalMode: \"%s\"\n", 1428229195eSjeremylt inout, field_number, field_name, size, CeedEvalModes[eval_mode]); 143e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1447a982d89SJeremy L. Thompson } 1457a982d89SJeremy L. Thompson 146777ff853SJeremy L Thompson /** 147777ff853SJeremy L Thompson @brief Set flag to determine if Fortran interface is used 148777ff853SJeremy L Thompson 149ea61e9acSJeremy L Thompson @param[in,out] qf CeedQFunction 150ea61e9acSJeremy L Thompson @param[in] status Boolean value to set as Fortran status 151777ff853SJeremy L Thompson 152777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 153777ff853SJeremy L Thompson 154777ff853SJeremy L Thompson @ref Backend 155777ff853SJeremy L Thompson **/ 156777ff853SJeremy L Thompson int CeedQFunctionSetFortranStatus(CeedQFunction qf, bool status) { 157f04ea552SJeremy L Thompson qf->is_fortran = status; 158e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 159777ff853SJeremy L Thompson } 160777ff853SJeremy L Thompson 1617a982d89SJeremy L. Thompson /// @} 1627a982d89SJeremy L. Thompson 1637a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1647a982d89SJeremy L. Thompson /// CeedQFunction Backend API 1657a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1667a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionBackend 1677a982d89SJeremy L. Thompson /// @{ 1687a982d89SJeremy L. Thompson 1697a982d89SJeremy L. Thompson /** 170ca94c3ddSJeremy L Thompson @brief Get the vector length of a `CeedQFunction` 1717a982d89SJeremy L. Thompson 172ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 173d1d35e2fSjeremylt @param[out] vec_length Variable to store vector length 1747a982d89SJeremy L. Thompson 1757a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1767a982d89SJeremy L. Thompson 1777a982d89SJeremy L. Thompson @ref Backend 1787a982d89SJeremy L. Thompson **/ 179d1d35e2fSjeremylt int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vec_length) { 180d1d35e2fSjeremylt *vec_length = qf->vec_length; 181e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1827a982d89SJeremy L. Thompson } 1837a982d89SJeremy L. Thompson 1847a982d89SJeremy L. Thompson /** 185ca94c3ddSJeremy L Thompson @brief Get the number of inputs and outputs to a `CeedQFunction` 1867a982d89SJeremy L. Thompson 187ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 188d1d35e2fSjeremylt @param[out] num_input Variable to store number of input fields 189d1d35e2fSjeremylt @param[out] num_output Variable to store number of output fields 1907a982d89SJeremy L. Thompson 1917a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1927a982d89SJeremy L. Thompson 1937a982d89SJeremy L. Thompson @ref Backend 1947a982d89SJeremy L. Thompson **/ 1952b730f8bSJeremy L Thompson int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *num_input, CeedInt *num_output) { 196d1d35e2fSjeremylt if (num_input) *num_input = qf->num_input_fields; 197d1d35e2fSjeremylt if (num_output) *num_output = qf->num_output_fields; 198e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1997a982d89SJeremy L. Thompson } 2007a982d89SJeremy L. Thompson 2017a982d89SJeremy L. Thompson /** 202ca94c3ddSJeremy L Thompson @brief Get the name of the user function for a `CeedQFunction` 2037a982d89SJeremy L. Thompson 204ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 20543e1b16fSJeremy L Thompson @param[out] kernel_name Variable to store source path string 2067a982d89SJeremy L. Thompson 2077a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2087a982d89SJeremy L. Thompson 2097a982d89SJeremy L. Thompson @ref Backend 2107a982d89SJeremy L. Thompson **/ 21143e1b16fSJeremy L Thompson int CeedQFunctionGetKernelName(CeedQFunction qf, char **kernel_name) { 212ca5eadf8SJeremy L Thompson if (!qf->kernel_name) { 213ca5eadf8SJeremy L Thompson Ceed ceed; 214ca5eadf8SJeremy L Thompson char *kernel_name_copy; 215ca5eadf8SJeremy L Thompson 2161c66c397SJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 217ca5eadf8SJeremy L Thompson if (qf->user_source) { 218ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 219ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 220ca5eadf8SJeremy L Thompson 2212b730f8bSJeremy L Thompson CeedCall(CeedCalloc(kernel_name_len + 1, &kernel_name_copy)); 222ca5eadf8SJeremy L Thompson memcpy(kernel_name_copy, kernel_name, kernel_name_len); 223ca5eadf8SJeremy L Thompson } else { 2242b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &kernel_name_copy)); 225ca5eadf8SJeremy L Thompson } 226ca5eadf8SJeremy L Thompson qf->kernel_name = kernel_name_copy; 227ca5eadf8SJeremy L Thompson } 228ca5eadf8SJeremy L Thompson 22943e1b16fSJeremy L Thompson *kernel_name = (char *)qf->kernel_name; 23043e1b16fSJeremy L Thompson return CEED_ERROR_SUCCESS; 23143e1b16fSJeremy L Thompson } 23243e1b16fSJeremy L Thompson 23343e1b16fSJeremy L Thompson /** 234ca94c3ddSJeremy L Thompson @brief Get the source path string for a `CeedQFunction` 23543e1b16fSJeremy L Thompson 236ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 23743e1b16fSJeremy L Thompson @param[out] source_path Variable to store source path string 23843e1b16fSJeremy L Thompson 23943e1b16fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 24043e1b16fSJeremy L Thompson 24143e1b16fSJeremy L Thompson @ref Backend 24243e1b16fSJeremy L Thompson **/ 24343e1b16fSJeremy L Thompson int CeedQFunctionGetSourcePath(CeedQFunction qf, char **source_path) { 244ca5eadf8SJeremy L Thompson if (!qf->source_path && qf->user_source) { 245ca5eadf8SJeremy L Thompson Ceed ceed; 246ca5eadf8SJeremy L Thompson bool is_absolute_path; 247ca5eadf8SJeremy L Thompson char *absolute_path, *source_path_copy; 248ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 249ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 250ca5eadf8SJeremy L Thompson 2512b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 2522b730f8bSJeremy L Thompson CeedCall(CeedCheckFilePath(ceed, qf->user_source, &is_absolute_path)); 253ca5eadf8SJeremy L Thompson if (is_absolute_path) { 254ca5eadf8SJeremy L Thompson absolute_path = (char *)qf->user_source; 255ca5eadf8SJeremy L Thompson } else { 2562b730f8bSJeremy L Thompson CeedCall(CeedGetJitAbsolutePath(ceed, qf->user_source, &absolute_path)); 257ca5eadf8SJeremy L Thompson } 258ca5eadf8SJeremy L Thompson 259ca5eadf8SJeremy L Thompson size_t source_len = strlen(absolute_path) - kernel_name_len - 1; 2601c66c397SJeremy L Thompson 2612b730f8bSJeremy L Thompson CeedCall(CeedCalloc(source_len + 1, &source_path_copy)); 262ca5eadf8SJeremy L Thompson memcpy(source_path_copy, absolute_path, source_len); 263ca5eadf8SJeremy L Thompson qf->source_path = source_path_copy; 264ca5eadf8SJeremy L Thompson 2652b730f8bSJeremy L Thompson if (!is_absolute_path) CeedCall(CeedFree(&absolute_path)); 266ca5eadf8SJeremy L Thompson } 267ca5eadf8SJeremy L Thompson 26843e1b16fSJeremy L Thompson *source_path = (char *)qf->source_path; 269e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2707a982d89SJeremy L. Thompson } 2717a982d89SJeremy L. Thompson 2727a982d89SJeremy L. Thompson /** 273ca94c3ddSJeremy L Thompson @brief Initialize and load `CeedQFunction` source file into string buffer, including full text of local files in place of `#include "local.h"`. 2744385fb7fSSebastian Grimberg 275ca94c3ddSJeremy L Thompson The `buffer` is set to `NULL` if there is no `CeedQFunction` source file. 2764385fb7fSSebastian Grimberg 277ca94c3ddSJeremy L Thompson Note: Caller is responsible for freeing the string buffer with @ref CeedFree(). 2783d3250a0SJeremy L Thompson 279ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 280f74ec584SJeremy L Thompson @param[out] source_buffer String buffer for source file contents 2813d3250a0SJeremy L Thompson 2823d3250a0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2833d3250a0SJeremy L Thompson 2843d3250a0SJeremy L Thompson @ref Backend 2853d3250a0SJeremy L Thompson **/ 2863d3250a0SJeremy L Thompson int CeedQFunctionLoadSourceToBuffer(CeedQFunction qf, char **source_buffer) { 2873d3250a0SJeremy L Thompson char *source_path; 2883d3250a0SJeremy L Thompson 2892b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetSourcePath(qf, &source_path)); 2903d3250a0SJeremy L Thompson *source_buffer = NULL; 2913d3250a0SJeremy L Thompson if (source_path) { 292*1203703bSJeremy L Thompson Ceed ceed; 293*1203703bSJeremy L Thompson 294*1203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 295*1203703bSJeremy L Thompson CeedCall(CeedLoadSourceToBuffer(ceed, source_path, source_buffer)); 2963d3250a0SJeremy L Thompson } 2973d3250a0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2983d3250a0SJeremy L Thompson } 2993d3250a0SJeremy L Thompson 3003d3250a0SJeremy L Thompson /** 301ca94c3ddSJeremy L Thompson @brief Get the User Function for a `CeedQFunction` 3027a982d89SJeremy L. Thompson 303ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 3047a982d89SJeremy L. Thompson @param[out] f Variable to store user function 3057a982d89SJeremy L. Thompson 3067a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3077a982d89SJeremy L. Thompson 3087a982d89SJeremy L. Thompson @ref Backend 3097a982d89SJeremy L. Thompson **/ 3107a982d89SJeremy L. Thompson int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) { 3117a982d89SJeremy L. Thompson *f = qf->function; 312e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3137a982d89SJeremy L. Thompson } 3147a982d89SJeremy L. Thompson 3157a982d89SJeremy L. Thompson /** 316ca94c3ddSJeremy L Thompson @brief Get global context for a `CeedQFunction`. 3174385fb7fSSebastian Grimberg 318ca94c3ddSJeremy L Thompson Note: For `CeedQFunction` from the Fortran interface, this function will return the Fortran context `CeedQFunctionContext`. 3197a982d89SJeremy L. Thompson 320ea61e9acSJeremy L Thompson @param[in] qf CeedQFunction 321777ff853SJeremy L Thompson @param[out] ctx Variable to store CeedQFunctionContext 3227a982d89SJeremy L. Thompson 3237a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3247a982d89SJeremy L. Thompson 3257a982d89SJeremy L. Thompson @ref Backend 3267a982d89SJeremy L. Thompson **/ 327777ff853SJeremy L Thompson int CeedQFunctionGetContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 3287a982d89SJeremy L. Thompson *ctx = qf->ctx; 329e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3307a982d89SJeremy L. Thompson } 3317a982d89SJeremy L. Thompson 3327a982d89SJeremy L. Thompson /** 333ca94c3ddSJeremy L Thompson @brief Get context data of a `CeedQFunction` 334441428dfSJeremy L Thompson 335ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 336ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 337ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 338441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 339441428dfSJeremy L Thompson 340441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 341441428dfSJeremy L Thompson 342441428dfSJeremy L Thompson @ref Backend 343441428dfSJeremy L Thompson **/ 3442b730f8bSJeremy L Thompson int CeedQFunctionGetContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 345441428dfSJeremy L Thompson bool is_writable; 346441428dfSJeremy L Thompson CeedQFunctionContext ctx; 347441428dfSJeremy L Thompson 3482b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 349441428dfSJeremy L Thompson if (ctx) { 3502b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 351441428dfSJeremy L Thompson if (is_writable) { 3522b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 353441428dfSJeremy L Thompson } else { 3542b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 355441428dfSJeremy L Thompson } 356441428dfSJeremy L Thompson } else { 357441428dfSJeremy L Thompson *(void **)data = NULL; 358441428dfSJeremy L Thompson } 359441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 360441428dfSJeremy L Thompson } 361441428dfSJeremy L Thompson 362441428dfSJeremy L Thompson /** 363ca94c3ddSJeremy L Thompson @brief Restore context data of a `CeedQFunction` 364441428dfSJeremy L Thompson 365ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 366ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 367441428dfSJeremy L Thompson 368441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 369441428dfSJeremy L Thompson 370441428dfSJeremy L Thompson @ref Backend 371441428dfSJeremy L Thompson **/ 372441428dfSJeremy L Thompson int CeedQFunctionRestoreContextData(CeedQFunction qf, void *data) { 373441428dfSJeremy L Thompson bool is_writable; 374441428dfSJeremy L Thompson CeedQFunctionContext ctx; 375441428dfSJeremy L Thompson 3762b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 377441428dfSJeremy L Thompson if (ctx) { 3782b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 379441428dfSJeremy L Thompson if (is_writable) { 3802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 381441428dfSJeremy L Thompson } else { 3822b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 383441428dfSJeremy L Thompson } 384441428dfSJeremy L Thompson } 3855f249b39SJeremy L Thompson *(void **)data = NULL; 386441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 387441428dfSJeremy L Thompson } 388441428dfSJeremy L Thompson 389441428dfSJeremy L Thompson /** 390ca94c3ddSJeremy L Thompson @brief Get true user context for a `CeedQFunction` 3914385fb7fSSebastian Grimberg 392ca94c3ddSJeremy L Thompson Note: For all `CeedQFunction` this function will return the user `CeedQFunctionContext` and not interface context `CeedQFunctionContext`, if any such object exists. 3937a982d89SJeremy L. Thompson 394ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 395ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 3967a982d89SJeremy L. Thompson 3977a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3987a982d89SJeremy L. Thompson @ref Backend 3997a982d89SJeremy L. Thompson **/ 400777ff853SJeremy L Thompson int CeedQFunctionGetInnerContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 401*1203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 402*1203703bSJeremy L Thompson 403*1203703bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &qf_ctx)); 404f04ea552SJeremy L Thompson if (qf->is_fortran) { 405d1d35e2fSjeremylt CeedFortranContext fortran_ctx = NULL; 4061c66c397SJeremy L Thompson 407*1203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(qf_ctx, CEED_MEM_HOST, &fortran_ctx)); 4088cb0412aSJeremy L Thompson *ctx = fortran_ctx->inner_ctx; 409*1203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(qf_ctx, (void *)&fortran_ctx)); 4107a982d89SJeremy L. Thompson } else { 411*1203703bSJeremy L Thompson *ctx = qf_ctx; 4127a982d89SJeremy L. Thompson } 413e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4147a982d89SJeremy L. Thompson } 4157a982d89SJeremy L. Thompson 4167a982d89SJeremy L. Thompson /** 417ca94c3ddSJeremy L Thompson @brief Get inner context data of a `CeedQFunction` 418441428dfSJeremy L Thompson 419ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 420ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 421ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 422441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 423441428dfSJeremy L Thompson 424441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 425441428dfSJeremy L Thompson 426441428dfSJeremy L Thompson @ref Backend 427441428dfSJeremy L Thompson **/ 4282b730f8bSJeremy L Thompson int CeedQFunctionGetInnerContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 429441428dfSJeremy L Thompson bool is_writable; 430441428dfSJeremy L Thompson CeedQFunctionContext ctx; 431441428dfSJeremy L Thompson 4322b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 433441428dfSJeremy L Thompson if (ctx) { 4342b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 435441428dfSJeremy L Thompson if (is_writable) { 4362b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 437441428dfSJeremy L Thompson } else { 4382b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 439441428dfSJeremy L Thompson } 440441428dfSJeremy L Thompson } else { 441441428dfSJeremy L Thompson *(void **)data = NULL; 442441428dfSJeremy L Thompson } 443441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 444441428dfSJeremy L Thompson } 445441428dfSJeremy L Thompson 446441428dfSJeremy L Thompson /** 447ca94c3ddSJeremy L Thompson @brief Restore inner context data of a `CeedQFunction` 448441428dfSJeremy L Thompson 449ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 450ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 451441428dfSJeremy L Thompson 452441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 453441428dfSJeremy L Thompson 454441428dfSJeremy L Thompson @ref Backend 455441428dfSJeremy L Thompson **/ 456441428dfSJeremy L Thompson int CeedQFunctionRestoreInnerContextData(CeedQFunction qf, void *data) { 457441428dfSJeremy L Thompson bool is_writable; 458441428dfSJeremy L Thompson CeedQFunctionContext ctx; 459441428dfSJeremy L Thompson 4602b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 461441428dfSJeremy L Thompson if (ctx) { 4622b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 463441428dfSJeremy L Thompson if (is_writable) { 4642b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 465441428dfSJeremy L Thompson } else { 4662b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 467441428dfSJeremy L Thompson } 468441428dfSJeremy L Thompson } 4695f249b39SJeremy L Thompson *(void **)data = NULL; 470441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 471441428dfSJeremy L Thompson } 472441428dfSJeremy L Thompson 473441428dfSJeremy L Thompson /** 474ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunction` is identity 4757a982d89SJeremy L. Thompson 476ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 477d1d35e2fSjeremylt @param[out] is_identity Variable to store identity status 4787a982d89SJeremy L. Thompson 4797a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4807a982d89SJeremy L. Thompson 4817a982d89SJeremy L. Thompson @ref Backend 4827a982d89SJeremy L. Thompson **/ 483d1d35e2fSjeremylt int CeedQFunctionIsIdentity(CeedQFunction qf, bool *is_identity) { 484f04ea552SJeremy L Thompson *is_identity = qf->is_identity; 485e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4867a982d89SJeremy L. Thompson } 4877a982d89SJeremy L. Thompson 4887a982d89SJeremy L. Thompson /** 489ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunctionContext` is writable 490441428dfSJeremy L Thompson 491ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 492ea61e9acSJeremy L Thompson @param[out] is_writable Variable to store context writeable status 493441428dfSJeremy L Thompson 494441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 495441428dfSJeremy L Thompson 496441428dfSJeremy L Thompson @ref Backend 497441428dfSJeremy L Thompson **/ 498441428dfSJeremy L Thompson int CeedQFunctionIsContextWritable(CeedQFunction qf, bool *is_writable) { 499441428dfSJeremy L Thompson *is_writable = qf->is_context_writable; 500441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 501441428dfSJeremy L Thompson } 502441428dfSJeremy L Thompson 503441428dfSJeremy L Thompson /** 504ca94c3ddSJeremy L Thompson @brief Get backend data of a `CeedQFunction` 5057a982d89SJeremy L. Thompson 506ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 5077a982d89SJeremy L. Thompson @param[out] data Variable to store data 5087a982d89SJeremy L. Thompson 5097a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5107a982d89SJeremy L. Thompson 5117a982d89SJeremy L. Thompson @ref Backend 5127a982d89SJeremy L. Thompson **/ 513777ff853SJeremy L Thompson int CeedQFunctionGetData(CeedQFunction qf, void *data) { 514777ff853SJeremy L Thompson *(void **)data = qf->data; 515e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5167a982d89SJeremy L. Thompson } 5177a982d89SJeremy L. Thompson 5187a982d89SJeremy L. Thompson /** 519ca94c3ddSJeremy L Thompson @brief Set backend data of a `CeedQFunction` 5207a982d89SJeremy L. Thompson 521ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 522ea61e9acSJeremy L Thompson @param[in] data Data to set 5237a982d89SJeremy L. Thompson 5247a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5257a982d89SJeremy L. Thompson 5267a982d89SJeremy L. Thompson @ref Backend 5277a982d89SJeremy L. Thompson **/ 528777ff853SJeremy L Thompson int CeedQFunctionSetData(CeedQFunction qf, void *data) { 529777ff853SJeremy L Thompson qf->data = data; 530e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5317a982d89SJeremy L. Thompson } 5327a982d89SJeremy L. Thompson 5337a982d89SJeremy L. Thompson /** 534*1203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedQFunction` is immutable 535*1203703bSJeremy L Thompson 536*1203703bSJeremy L Thompson @param[in] qf `CeedOperator` 537*1203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 538*1203703bSJeremy L Thompson 539*1203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 540*1203703bSJeremy L Thompson 541*1203703bSJeremy L Thompson @ref Backend 542*1203703bSJeremy L Thompson **/ 543*1203703bSJeremy L Thompson int CeedQFunctionIsImmutable(CeedQFunction qf, bool *is_immutable) { 544*1203703bSJeremy L Thompson *is_immutable = qf->is_immutable; 545*1203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 546*1203703bSJeremy L Thompson } 547*1203703bSJeremy L Thompson 548*1203703bSJeremy L Thompson /** 549*1203703bSJeremy L Thompson @brief Set the immutable flag of a `CeedQFunction` to `true` 550*1203703bSJeremy L Thompson 551*1203703bSJeremy L Thompson @param[in,out] qf `CeedQFunction` 552*1203703bSJeremy L Thompson 553*1203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 554*1203703bSJeremy L Thompson 555*1203703bSJeremy L Thompson @ref Backend 556*1203703bSJeremy L Thompson **/ 557*1203703bSJeremy L Thompson int CeedQFunctionSetImmutable(CeedQFunction qf) { 558*1203703bSJeremy L Thompson qf->is_immutable = true; 559*1203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 560*1203703bSJeremy L Thompson } 561*1203703bSJeremy L Thompson 562*1203703bSJeremy L Thompson /** 563ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedQFunction` 56434359f16Sjeremylt 565ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to increment the reference counter 56634359f16Sjeremylt 56734359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 56834359f16Sjeremylt 56934359f16Sjeremylt @ref Backend 57034359f16Sjeremylt **/ 5719560d06aSjeremylt int CeedQFunctionReference(CeedQFunction qf) { 57234359f16Sjeremylt qf->ref_count++; 57334359f16Sjeremylt return CEED_ERROR_SUCCESS; 57434359f16Sjeremylt } 57534359f16Sjeremylt 5766e15d496SJeremy L Thompson /** 577ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs per quadrature required to apply `CeedQFunction` 5786e15d496SJeremy L Thompson 579ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 580ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5816e15d496SJeremy L Thompson 5826e15d496SJeremy L Thompson @ref Backend 5836e15d496SJeremy L Thompson **/ 5849d36ca50SJeremy L Thompson int CeedQFunctionGetFlopsEstimate(CeedQFunction qf, CeedSize *flops) { 5856e15d496SJeremy L Thompson *flops = qf->user_flop_estimate; 5866e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5876e15d496SJeremy L Thompson } 5886e15d496SJeremy L Thompson 5897a982d89SJeremy L. Thompson /// @} 5907a982d89SJeremy L. Thompson 5917a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5927a982d89SJeremy L. Thompson /// CeedQFunction Public API 5937a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5947a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 5957a982d89SJeremy L. Thompson /// @{ 5967a982d89SJeremy L. Thompson 5977a982d89SJeremy L. Thompson /** 598ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms 5997a982d89SJeremy L. Thompson 600ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 601ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 602ca94c3ddSJeremy L Thompson Caller must ensure that number of quadrature points is a multiple of `vec_length`. 603ea61e9acSJeremy L Thompson @param[in] f Function pointer to evaluate action at quadrature points. 604ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 605ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunctionUser`, "\abs_path\file.h:function_name". 606ca94c3ddSJeremy L Thompson The entire source file must only contain constructs supported by all targeted backends (i.e. CUDA for `/gpu/cuda`, OpenCL/SYCL for `/gpu/sycl`, etc.). 6074ada38baSJames Wright The entire contents of this file and all locally included files are used during JiT compilation for GPU backends. 6084ada38baSJames Wright All source files must be at the provided filepath at runtime for JiT to function. 609ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 6107a982d89SJeremy L. Thompson 6117a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6127a982d89SJeremy L. Thompson 613ca94c3ddSJeremy L Thompson See \ref CeedQFunctionUser for details on the call-back function `f` arguments. 6147a982d89SJeremy L. Thompson 6157a982d89SJeremy L. Thompson @ref User 6167a982d89SJeremy L. Thompson **/ 6172b730f8bSJeremy L Thompson int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length, CeedQFunctionUser f, const char *source, CeedQFunction *qf) { 618ca5eadf8SJeremy L Thompson char *user_source_copy; 6197a982d89SJeremy L. Thompson 6207a982d89SJeremy L. Thompson if (!ceed->QFunctionCreate) { 6217a982d89SJeremy L. Thompson Ceed delegate; 6226574a04fSJeremy L Thompson 6232b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "QFunction")); 624ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionCreateInterior"); 6252b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(delegate, vec_length, f, source, qf)); 626e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6277a982d89SJeremy L. Thompson } 6287a982d89SJeremy L. Thompson 6296574a04fSJeremy L Thompson CeedCheck(!strlen(source) || strrchr(source, ':'), ceed, CEED_ERROR_INCOMPLETE, 6306574a04fSJeremy L Thompson "Provided path to source does not include function name. Provided: \"%s\"\nRequired: \"\\abs_path\\file.h:function_name\"", source); 63143e1b16fSJeremy L Thompson 6322b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, qf)); 633db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*qf)->ceed)); 634d1d35e2fSjeremylt (*qf)->ref_count = 1; 635d1d35e2fSjeremylt (*qf)->vec_length = vec_length; 636f04ea552SJeremy L Thompson (*qf)->is_identity = false; 637441428dfSJeremy L Thompson (*qf)->is_context_writable = true; 6387a982d89SJeremy L. Thompson (*qf)->function = f; 6396e15d496SJeremy L Thompson (*qf)->user_flop_estimate = -1; 64043e1b16fSJeremy L Thompson if (strlen(source)) { 641ca5eadf8SJeremy L Thompson size_t user_source_len = strlen(source); 642ee5a26f2SJeremy L Thompson 6432b730f8bSJeremy L Thompson CeedCall(CeedCalloc(user_source_len + 1, &user_source_copy)); 644ca5eadf8SJeremy L Thompson memcpy(user_source_copy, source, user_source_len); 645ca5eadf8SJeremy L Thompson (*qf)->user_source = user_source_copy; 64643e1b16fSJeremy L Thompson } 6472b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->input_fields)); 6482b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->output_fields)); 6492b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionCreate(*qf)); 650e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6517a982d89SJeremy L. Thompson } 6527a982d89SJeremy L. Thompson 6537a982d89SJeremy L. Thompson /** 654ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms by name 655288c0443SJeremy L Thompson 656ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 657ca94c3ddSJeremy L Thompson @param[in] name Name of `CeedQFunction` to use from gallery 658ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 659288c0443SJeremy L Thompson 660288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 661288c0443SJeremy L Thompson 6627a982d89SJeremy L. Thompson @ref User 663288c0443SJeremy L Thompson **/ 6642b730f8bSJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name, CeedQFunction *qf) { 665f7e22acaSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX; 666288c0443SJeremy L Thompson 6672b730f8bSJeremy L Thompson CeedCall(CeedQFunctionRegisterAll()); 668288c0443SJeremy L Thompson // Find matching backend 669ca94c3ddSJeremy L Thompson CeedCheck(name, ceed, CEED_ERROR_INCOMPLETE, "No CeedQFunction name provided"); 670288c0443SJeremy L Thompson for (size_t i = 0; i < num_qfunctions; i++) { 671288c0443SJeremy L Thompson size_t n; 672d1d35e2fSjeremylt const char *curr_name = gallery_qfunctions[i].name; 6732b730f8bSJeremy L Thompson for (n = 0; curr_name[n] && curr_name[n] == name[n]; n++) { 6742b730f8bSJeremy L Thompson } 675d1d35e2fSjeremylt if (n > match_len) { 676d1d35e2fSjeremylt match_len = n; 677f7e22acaSJeremy L Thompson match_index = i; 678288c0443SJeremy L Thompson } 679288c0443SJeremy L Thompson } 680ca94c3ddSJeremy L Thompson CeedCheck(match_len > 0, ceed, CEED_ERROR_UNSUPPORTED, "No suitable gallery CeedQFunction"); 681288c0443SJeremy L Thompson 682288c0443SJeremy L Thompson // Create QFunction 6832b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(ceed, gallery_qfunctions[match_index].vec_length, gallery_qfunctions[match_index].f, 6842b730f8bSJeremy L Thompson gallery_qfunctions[match_index].source, qf)); 685288c0443SJeremy L Thompson 686288c0443SJeremy L Thompson // QFunction specific setup 6872b730f8bSJeremy L Thompson CeedCall(gallery_qfunctions[match_index].init(ceed, name, *qf)); 688288c0443SJeremy L Thompson 68975affc3bSjeremylt // Copy name 6902b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(name, (char **)&(*qf)->gallery_name)); 69143e1b16fSJeremy L Thompson (*qf)->is_gallery = true; 692e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 693288c0443SJeremy L Thompson } 694288c0443SJeremy L Thompson 695288c0443SJeremy L Thompson /** 696ca94c3ddSJeremy L Thompson @brief Create an identity `CeedQFunction`. 6974385fb7fSSebastian Grimberg 698ea61e9acSJeremy L Thompson Inputs are written into outputs in the order given. 699ca94c3ddSJeremy L Thompson This is useful for `CeedOperator that can be represented with only the action of a `CeedElemRestriction` and `CeedBasis`, such as restriction and prolongation operators for p-multigrid. 700ca94c3ddSJeremy L Thompson Backends may optimize `CeedOperator` with this `CeedQFunction` to avoid the copy of input data to output fields by using the same memory location for both. 7010219ea01SJeremy L Thompson 702ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 703ca94c3ddSJeremy L Thompson @param[in] size Size of the `CeedQFunction` fields 704ca94c3ddSJeremy L Thompson @param[in] in_mode @ref CeedEvalMode for input to `CeedQFunction` 705ca94c3ddSJeremy L Thompson @param[in] out_mode @ref CeedEvalMode for output to `CeedQFunction` 706ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 7070219ea01SJeremy L Thompson 7080219ea01SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7090219ea01SJeremy L Thompson 7107a982d89SJeremy L. Thompson @ref User 7110219ea01SJeremy L Thompson **/ 7122b730f8bSJeremy L Thompson int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf) { 7131c66c397SJeremy L Thompson CeedQFunctionContext ctx; 7141c66c397SJeremy L Thompson CeedContextFieldLabel size_label; 7151c66c397SJeremy L Thompson 7162b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInteriorByName(ceed, "Identity", qf)); 7172b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddInput(*qf, "input", size, in_mode)); 7182b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddOutput(*qf, "output", size, out_mode)); 7190219ea01SJeremy L Thompson 720f04ea552SJeremy L Thompson (*qf)->is_identity = true; 721547dbd6fSJeremy L Thompson 7222b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(*qf, &ctx)); 7232b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, "size", &size_label)); 7242b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetInt32(ctx, size_label, &size)); 725e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7260219ea01SJeremy L Thompson } 7270219ea01SJeremy L Thompson 7280219ea01SJeremy L Thompson /** 729ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedQFunction`. 7304385fb7fSSebastian Grimberg 731ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedQFunctionDestroy(). 732512bb800SJeremy L Thompson 733ca94c3ddSJeremy L Thompson Note: If the value of `*qf_copy` passed to this function is non-NULL, then it is assumed that `*qf_copy` is a pointer to a `CeedQFunction`. 734ca94c3ddSJeremy L Thompson This `CeedQFunction` will be destroyed if `*qf_copy` is the only reference to this `CeedQFunction`. 7359560d06aSjeremylt 736ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to copy reference to 7379560d06aSjeremylt @param[out] qf_copy Variable to store copied reference 7389560d06aSjeremylt 7399560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7409560d06aSjeremylt 7419560d06aSjeremylt @ref User 7429560d06aSjeremylt **/ 7439560d06aSjeremylt int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy) { 7442b730f8bSJeremy L Thompson CeedCall(CeedQFunctionReference(qf)); 7452b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(qf_copy)); 7469560d06aSjeremylt *qf_copy = qf; 7479560d06aSjeremylt return CEED_ERROR_SUCCESS; 7489560d06aSjeremylt } 7499560d06aSjeremylt 7509560d06aSjeremylt /** 751ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` input 752b11c1e72Sjeremylt 753ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 754ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 755ca94c3ddSJeremy L Thompson @param[in] size Size of `CeedQFunction` field, (`num_comp * 1`) for @ref CEED_EVAL_NONE, (`num_comp * 1`) for @ref CEED_EVAL_INTERP for an \f$H^1\f$ space or (`num_comp * dim`) for an \f$H(\mathrm{div})\f$ or \f$H(\mathrm{curl})\f$ space, (`num_comp * dim`) for @ref CEED_EVAL_GRAD, or (`num_comp * 1`) for @ref CEED_EVAL_DIV, and (`num_comp * curl_dim`) with `curl_dim = 1` if `dim < 3` otherwise `curl_dim = dim` for @ref CEED_EVAL_CURL. 756ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 757ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 758ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 759ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 760ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 761b11c1e72Sjeremylt 762b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 763dfdf5a53Sjeremylt 7647a982d89SJeremy L. Thompson @ref User 765b11c1e72Sjeremylt **/ 7662b730f8bSJeremy L Thompson int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 767*1203703bSJeremy L Thompson bool is_immutable; 768*1203703bSJeremy L Thompson Ceed ceed; 769*1203703bSJeremy L Thompson 770*1203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 771*1203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 772*1203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "QFunction cannot be changed after set as immutable"); 773*1203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT || size == 1, ceed, CEED_ERROR_DIMENSION, "CEED_EVAL_WEIGHT should have size 1"); 774643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 775*1203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 776643fbb69SJeremy L Thompson } 777643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 778*1203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 779643fbb69SJeremy L Thompson } 7802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->input_fields[qf->num_input_fields], field_name, size, eval_mode)); 781d1d35e2fSjeremylt qf->num_input_fields++; 782e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 783d7b241e6Sjeremylt } 784d7b241e6Sjeremylt 785b11c1e72Sjeremylt /** 786ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` output 787b11c1e72Sjeremylt 788ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 789ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 790ca94c3ddSJeremy L Thompson @param[in] size Size of `CeedQFunction` field, (`num_comp * 1`) for @ref CEED_EVAL_NONE, (`num_comp * 1`) for @ref CEED_EVAL_INTERP for an \f$H^1\f$ space or (`num_comp * dim`) for an \f$H(\mathrm{div})\f$ or \f$H(\mathrm{curl})\f$ space, (`num_comp * dim`) for @ref CEED_EVAL_GRAD, or (`num_comp * 1`) for @ref CEED_EVAL_DIV, and (`num_comp * curl_dim`) with `curl_dim = 1` if `dim < 3` else dim for @ref CEED_EVAL_CURL. 791ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 792ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 793ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 794ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 795ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl. 796b11c1e72Sjeremylt 797b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 798dfdf5a53Sjeremylt 7997a982d89SJeremy L. Thompson @ref User 800b11c1e72Sjeremylt **/ 8012b730f8bSJeremy L Thompson int CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 802*1203703bSJeremy L Thompson bool is_immutable; 803*1203703bSJeremy L Thompson Ceed ceed; 804*1203703bSJeremy L Thompson 805*1203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 806*1203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 807*1203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "CeedQFunction cannot be changed after set as immutable"); 808*1203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT, ceed, CEED_ERROR_DIMENSION, "Cannot create CeedQFunction output with CEED_EVAL_WEIGHT"); 809643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 810*1203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 811643fbb69SJeremy L Thompson } 812643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 813*1203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 814643fbb69SJeremy L Thompson } 8152b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->output_fields[qf->num_output_fields], field_name, size, eval_mode)); 816d1d35e2fSjeremylt qf->num_output_fields++; 817e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 818d7b241e6Sjeremylt } 819d7b241e6Sjeremylt 820dfdf5a53Sjeremylt /** 821ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunctionField` of a `CeedQFunction` 82243bbe138SJeremy L Thompson 823ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 824f04ea552SJeremy L Thompson 825ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 826f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 827f74ec584SJeremy L Thompson @param[out] input_fields Variable to store input fields 828f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 829f74ec584SJeremy L Thompson @param[out] output_fields Variable to store output fields 83043bbe138SJeremy L Thompson 83143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83243bbe138SJeremy L Thompson 833e9b533fbSJeremy L Thompson @ref Advanced 83443bbe138SJeremy L Thompson **/ 8352b730f8bSJeremy L Thompson int CeedQFunctionGetFields(CeedQFunction qf, CeedInt *num_input_fields, CeedQFunctionField **input_fields, CeedInt *num_output_fields, 83643bbe138SJeremy L Thompson CeedQFunctionField **output_fields) { 837*1203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 83843bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = qf->num_input_fields; 83943bbe138SJeremy L Thompson if (input_fields) *input_fields = qf->input_fields; 84043bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = qf->num_output_fields; 84143bbe138SJeremy L Thompson if (output_fields) *output_fields = qf->output_fields; 84243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84343bbe138SJeremy L Thompson } 84443bbe138SJeremy L Thompson 84543bbe138SJeremy L Thompson /** 846ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedQFunctionField` 84743bbe138SJeremy L Thompson 848ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 84943bbe138SJeremy L Thompson @param[out] field_name Variable to store the field name 85043bbe138SJeremy L Thompson 85143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85243bbe138SJeremy L Thompson 853e9b533fbSJeremy L Thompson @ref Advanced 85443bbe138SJeremy L Thompson **/ 85543bbe138SJeremy L Thompson int CeedQFunctionFieldGetName(CeedQFunctionField qf_field, char **field_name) { 85643bbe138SJeremy L Thompson *field_name = (char *)qf_field->field_name; 85743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 85843bbe138SJeremy L Thompson } 85943bbe138SJeremy L Thompson 86043bbe138SJeremy L Thompson /** 861ca94c3ddSJeremy L Thompson @brief Get the number of components of a `CeedQFunctionField` 86243bbe138SJeremy L Thompson 863ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 86443bbe138SJeremy L Thompson @param[out] size Variable to store the size of the field 86543bbe138SJeremy L Thompson 86643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 86743bbe138SJeremy L Thompson 868e9b533fbSJeremy L Thompson @ref Advanced 86943bbe138SJeremy L Thompson **/ 87043bbe138SJeremy L Thompson int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field, CeedInt *size) { 87143bbe138SJeremy L Thompson *size = qf_field->size; 87243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87343bbe138SJeremy L Thompson } 87443bbe138SJeremy L Thompson 87543bbe138SJeremy L Thompson /** 876ca94c3ddSJeremy L Thompson @brief Get the @ref CeedEvalMode of a `CeedQFunctionField` 87743bbe138SJeremy L Thompson 878ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 87943bbe138SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 88043bbe138SJeremy L Thompson 88143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88243bbe138SJeremy L Thompson 883e9b533fbSJeremy L Thompson @ref Advanced 88443bbe138SJeremy L Thompson **/ 8852b730f8bSJeremy L Thompson int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field, CeedEvalMode *eval_mode) { 88643bbe138SJeremy L Thompson *eval_mode = qf_field->eval_mode; 88743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 88843bbe138SJeremy L Thompson } 88943bbe138SJeremy L Thompson 89043bbe138SJeremy L Thompson /** 891ca94c3ddSJeremy L Thompson @brief Set global context for a `CeedQFunction` 892b11c1e72Sjeremylt 893ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 894ea61e9acSJeremy L Thompson @param[in] ctx Context data to set 895b11c1e72Sjeremylt 896b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 897dfdf5a53Sjeremylt 8987a982d89SJeremy L. Thompson @ref User 899b11c1e72Sjeremylt **/ 900777ff853SJeremy L Thompson int CeedQFunctionSetContext(CeedQFunction qf, CeedQFunctionContext ctx) { 9012b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&qf->ctx)); 902d7b241e6Sjeremylt qf->ctx = ctx; 903db002c03SJeremy L Thompson if (ctx) CeedCall(CeedQFunctionContextReference(ctx)); 904e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 905d7b241e6Sjeremylt } 906d7b241e6Sjeremylt 907b11c1e72Sjeremylt /** 908ca94c3ddSJeremy L Thompson @brief Set writability of `CeedQFunctionContext` when calling the `CeedQFunctionUser`. 9094385fb7fSSebastian Grimberg 910859c15bbSJames Wright The default value is `is_writable == true`. 911441428dfSJeremy L Thompson 912ca94c3ddSJeremy L Thompson Setting `is_writable == true` indicates the `CeedQFunctionUser` writes into the `CeedQFunctionContext` and requires memory synchronization after calling @ref CeedQFunctionApply(). 913441428dfSJeremy L Thompson 914ca94c3ddSJeremy L Thompson Setting 'is_writable == false' asserts that `CeedQFunctionUser` does not modify the `CeedQFunctionContext`. 915ea61e9acSJeremy L Thompson Violating this assertion may lead to inconsistent data. 916441428dfSJeremy L Thompson 917441428dfSJeremy L Thompson Setting `is_writable == false` may offer a performance improvement on GPU backends. 918441428dfSJeremy L Thompson 919ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 920ca94c3ddSJeremy L Thompson @param[in] is_writable Boolean flag for writability status 921441428dfSJeremy L Thompson 922441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 923441428dfSJeremy L Thompson 924441428dfSJeremy L Thompson @ref User 925441428dfSJeremy L Thompson **/ 926441428dfSJeremy L Thompson int CeedQFunctionSetContextWritable(CeedQFunction qf, bool is_writable) { 927441428dfSJeremy L Thompson qf->is_context_writable = is_writable; 928441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 929441428dfSJeremy L Thompson } 930441428dfSJeremy L Thompson 931441428dfSJeremy L Thompson /** 932ca94c3ddSJeremy L Thompson @brief Set estimated number of FLOPs per quadrature required to apply `CeedQFunction` 9336e15d496SJeremy L Thompson 934ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 935ea61e9acSJeremy L Thompson @param[out] flops FLOPs per quadrature point estimate 9366e15d496SJeremy L Thompson 9376e15d496SJeremy L Thompson @ref Backend 9386e15d496SJeremy L Thompson **/ 9399d36ca50SJeremy L Thompson int CeedQFunctionSetUserFlopsEstimate(CeedQFunction qf, CeedSize flops) { 940*1203703bSJeremy L Thompson Ceed ceed; 941*1203703bSJeremy L Thompson 942*1203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 943*1203703bSJeremy L Thompson CeedCheck(flops >= 0, ceed, CEED_ERROR_INCOMPATIBLE, "Must set non-negative FLOPs estimate"); 9446e15d496SJeremy L Thompson qf->user_flop_estimate = flops; 9456e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 9466e15d496SJeremy L Thompson } 9476e15d496SJeremy L Thompson 9486e15d496SJeremy L Thompson /** 949ca94c3ddSJeremy L Thompson @brief View a `CeedQFunction` 95075affc3bSjeremylt 951ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to view 952ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 95375affc3bSjeremylt 95475affc3bSjeremylt @return Error code: 0 - success, otherwise - failure 95575affc3bSjeremylt 9567a982d89SJeremy L. Thompson @ref User 95775affc3bSjeremylt **/ 95875affc3bSjeremylt int CeedQFunctionView(CeedQFunction qf, FILE *stream) { 959ca5eadf8SJeremy L Thompson char *kernel_name; 96075affc3bSjeremylt 9612b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetKernelName(qf, &kernel_name)); 9622b730f8bSJeremy L Thompson fprintf(stream, "%sCeedQFunction - %s\n", qf->is_gallery ? "Gallery " : "User ", qf->is_gallery ? qf->gallery_name : kernel_name); 96375affc3bSjeremylt 9642b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " input field%s:\n", qf->num_input_fields, qf->num_input_fields > 1 ? "s" : ""); 965d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_input_fields; i++) { 9662b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->input_fields[i], i, 1, stream)); 96775affc3bSjeremylt } 96875affc3bSjeremylt 9692b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " output field%s:\n", qf->num_output_fields, qf->num_output_fields > 1 ? "s" : ""); 970d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_output_fields; i++) { 9712b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->output_fields[i], i, 0, stream)); 97275affc3bSjeremylt } 973e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 97475affc3bSjeremylt } 97575affc3bSjeremylt 97675affc3bSjeremylt /** 977ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedQFunction` 978b7c9bbdaSJeremy L Thompson 979ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 980ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store`Ceed` 981b7c9bbdaSJeremy L Thompson 982b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 983b7c9bbdaSJeremy L Thompson 984b7c9bbdaSJeremy L Thompson @ref Advanced 985b7c9bbdaSJeremy L Thompson **/ 986b7c9bbdaSJeremy L Thompson int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 987b7c9bbdaSJeremy L Thompson *ceed = qf->ceed; 988b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 989b7c9bbdaSJeremy L Thompson } 990b7c9bbdaSJeremy L Thompson 991b7c9bbdaSJeremy L Thompson /** 992ca94c3ddSJeremy L Thompson @brief Apply the action of a `CeedQFunction` 993b11c1e72Sjeremylt 994ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 995f04ea552SJeremy L Thompson 996ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 997ea61e9acSJeremy L Thompson @param[in] Q Number of quadrature points 998ca94c3ddSJeremy L Thompson @param[in] u Array of input `CeedVector` 999ca94c3ddSJeremy L Thompson @param[out] v Array of output `CeedVector` 1000b11c1e72Sjeremylt 1001b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1002dfdf5a53Sjeremylt 10037a982d89SJeremy L. Thompson @ref User 1004b11c1e72Sjeremylt **/ 10052b730f8bSJeremy L Thompson int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, CeedVector *u, CeedVector *v) { 1006*1203703bSJeremy L Thompson CeedInt vec_length; 1007*1203703bSJeremy L Thompson Ceed ceed; 1008*1203703bSJeremy L Thompson 1009*1203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 1010*1203703bSJeremy L Thompson CeedCheck(qf->Apply, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionApply"); 1011*1203703bSJeremy L Thompson CeedCall(CeedQFunctionGetVectorLength(qf, &vec_length)); 1012*1203703bSJeremy L Thompson CeedCheck(Q % vec_length == 0, ceed, CEED_ERROR_DIMENSION, "Number of quadrature points %" CeedInt_FMT " must be a multiple of %" CeedInt_FMT, Q, 1013*1203703bSJeremy L Thompson qf->vec_length); 1014*1203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 10152b730f8bSJeremy L Thompson CeedCall(qf->Apply(qf, Q, u, v)); 1016e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1017d7b241e6Sjeremylt } 1018d7b241e6Sjeremylt 1019b11c1e72Sjeremylt /** 1020ca94c3ddSJeremy L Thompson @brief Destroy a `CeedQFunction` 1021b11c1e72Sjeremylt 1022ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to destroy 1023b11c1e72Sjeremylt 1024b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1025dfdf5a53Sjeremylt 10267a982d89SJeremy L. Thompson @ref User 1027b11c1e72Sjeremylt **/ 1028d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) { 1029ad6481ceSJeremy L Thompson if (!*qf || --(*qf)->ref_count > 0) { 1030ad6481ceSJeremy L Thompson *qf = NULL; 1031ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1032ad6481ceSJeremy L Thompson } 1033fe2413ffSjeremylt // Backend destroy 1034d7b241e6Sjeremylt if ((*qf)->Destroy) { 10352b730f8bSJeremy L Thompson CeedCall((*qf)->Destroy(*qf)); 1036d7b241e6Sjeremylt } 1037fe2413ffSjeremylt // Free fields 103892ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_input_fields; i++) { 10392b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->input_fields[i]).field_name)); 10402b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields[i])); 1041fe2413ffSjeremylt } 104292ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_output_fields; i++) { 10432b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->output_fields[i]).field_name)); 10442b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields[i])); 1045fe2413ffSjeremylt } 10462b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields)); 10472b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields)); 1048777ff853SJeremy L Thompson 1049777ff853SJeremy L Thompson // User context data object 10502b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&(*qf)->ctx)); 1051fe2413ffSjeremylt 10522b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->user_source)); 10532b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->source_path)); 10542b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->gallery_name)); 10552b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->kernel_name)); 10562b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*qf)->ceed)); 10572b730f8bSJeremy L Thompson CeedCall(CeedFree(qf)); 1058e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1059d7b241e6Sjeremylt } 1060d7b241e6Sjeremylt 1061d7b241e6Sjeremylt /// @} 1062