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"; 1286f8994e9SJeremy L Thompson const char *field_name; 1298229195eSjeremylt CeedInt size; 1308229195eSjeremylt CeedEvalMode eval_mode; 1311c66c397SJeremy L Thompson 132ab747706SJeremy L Thompson CeedCall(CeedQFunctionFieldGetData(field, &field_name, &size, &eval_mode)); 1332b730f8bSJeremy L Thompson fprintf(stream, 1342b730f8bSJeremy L Thompson " %s field %" CeedInt_FMT 1352b730f8bSJeremy L Thompson ":\n" 1367a982d89SJeremy L. Thompson " Name: \"%s\"\n" 1372b730f8bSJeremy L Thompson " Size: %" CeedInt_FMT 1382b730f8bSJeremy L Thompson "\n" 1397a982d89SJeremy L. Thompson " EvalMode: \"%s\"\n", 1408229195eSjeremylt inout, field_number, field_name, size, CeedEvalModes[eval_mode]); 141e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1427a982d89SJeremy L. Thompson } 1437a982d89SJeremy L. Thompson 144777ff853SJeremy L Thompson /** 145777ff853SJeremy L Thompson @brief Set flag to determine if Fortran interface is used 146777ff853SJeremy L Thompson 147ea61e9acSJeremy L Thompson @param[in,out] qf CeedQFunction 148ea61e9acSJeremy L Thompson @param[in] status Boolean value to set as Fortran status 149777ff853SJeremy L Thompson 150777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 151777ff853SJeremy L Thompson 152777ff853SJeremy L Thompson @ref Backend 153777ff853SJeremy L Thompson **/ 154777ff853SJeremy L Thompson int CeedQFunctionSetFortranStatus(CeedQFunction qf, bool status) { 155f04ea552SJeremy L Thompson qf->is_fortran = status; 156e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 157777ff853SJeremy L Thompson } 158777ff853SJeremy L Thompson 1597a982d89SJeremy L. Thompson /// @} 1607a982d89SJeremy L. Thompson 1617a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1627a982d89SJeremy L. Thompson /// CeedQFunction Backend API 1637a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1647a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionBackend 1657a982d89SJeremy L. Thompson /// @{ 1667a982d89SJeremy L. Thompson 1677a982d89SJeremy L. Thompson /** 168ca94c3ddSJeremy L Thompson @brief Get the vector length of a `CeedQFunction` 1697a982d89SJeremy L. Thompson 170ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 171d1d35e2fSjeremylt @param[out] vec_length Variable to store vector length 1727a982d89SJeremy L. Thompson 1737a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1747a982d89SJeremy L. Thompson 1757a982d89SJeremy L. Thompson @ref Backend 1767a982d89SJeremy L. Thompson **/ 177d1d35e2fSjeremylt int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vec_length) { 178d1d35e2fSjeremylt *vec_length = qf->vec_length; 179e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1807a982d89SJeremy L. Thompson } 1817a982d89SJeremy L. Thompson 1827a982d89SJeremy L. Thompson /** 183ca94c3ddSJeremy L Thompson @brief Get the number of inputs and outputs to a `CeedQFunction` 1847a982d89SJeremy L. Thompson 185ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 186d1d35e2fSjeremylt @param[out] num_input Variable to store number of input fields 187d1d35e2fSjeremylt @param[out] num_output Variable to store number of output fields 1887a982d89SJeremy L. Thompson 1897a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1907a982d89SJeremy L. Thompson 1917a982d89SJeremy L. Thompson @ref Backend 1927a982d89SJeremy L. Thompson **/ 1932b730f8bSJeremy L Thompson int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *num_input, CeedInt *num_output) { 194d1d35e2fSjeremylt if (num_input) *num_input = qf->num_input_fields; 195d1d35e2fSjeremylt if (num_output) *num_output = qf->num_output_fields; 196e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1977a982d89SJeremy L. Thompson } 1987a982d89SJeremy L. Thompson 1997a982d89SJeremy L. Thompson /** 200ca94c3ddSJeremy L Thompson @brief Get the name of the user function for a `CeedQFunction` 2017a982d89SJeremy L. Thompson 202ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 20343e1b16fSJeremy L Thompson @param[out] kernel_name Variable to store source path string 2047a982d89SJeremy L. Thompson 2057a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2067a982d89SJeremy L. Thompson 2077a982d89SJeremy L. Thompson @ref Backend 2087a982d89SJeremy L. Thompson **/ 2097d023984SJeremy L Thompson int CeedQFunctionGetKernelName(CeedQFunction qf, const char **kernel_name) { 210ca5eadf8SJeremy L Thompson if (!qf->kernel_name) { 211ca5eadf8SJeremy L Thompson Ceed ceed; 212ca5eadf8SJeremy L Thompson char *kernel_name_copy; 213ca5eadf8SJeremy L Thompson 2141c66c397SJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 215ca5eadf8SJeremy L Thompson if (qf->user_source) { 216ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 217ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 218ca5eadf8SJeremy L Thompson 2192b730f8bSJeremy L Thompson CeedCall(CeedCalloc(kernel_name_len + 1, &kernel_name_copy)); 220ca5eadf8SJeremy L Thompson memcpy(kernel_name_copy, kernel_name, kernel_name_len); 221ca5eadf8SJeremy L Thompson } else { 2222b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &kernel_name_copy)); 223ca5eadf8SJeremy L Thompson } 224ca5eadf8SJeremy L Thompson qf->kernel_name = kernel_name_copy; 225ca5eadf8SJeremy L Thompson } 226ca5eadf8SJeremy L Thompson 2277d023984SJeremy L Thompson *kernel_name = qf->kernel_name; 22843e1b16fSJeremy L Thompson return CEED_ERROR_SUCCESS; 22943e1b16fSJeremy L Thompson } 23043e1b16fSJeremy L Thompson 23143e1b16fSJeremy L Thompson /** 232ca94c3ddSJeremy L Thompson @brief Get the source path string for a `CeedQFunction` 23343e1b16fSJeremy L Thompson 234ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 23543e1b16fSJeremy L Thompson @param[out] source_path Variable to store source path string 23643e1b16fSJeremy L Thompson 23743e1b16fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23843e1b16fSJeremy L Thompson 23943e1b16fSJeremy L Thompson @ref Backend 24043e1b16fSJeremy L Thompson **/ 24134ffed21SJeremy L Thompson int CeedQFunctionGetSourcePath(CeedQFunction qf, const char **source_path) { 242ca5eadf8SJeremy L Thompson if (!qf->source_path && qf->user_source) { 243ca5eadf8SJeremy L Thompson Ceed ceed; 244ca5eadf8SJeremy L Thompson bool is_absolute_path; 245ca5eadf8SJeremy L Thompson char *absolute_path, *source_path_copy; 246ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 247ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 248ca5eadf8SJeremy L Thompson 2492b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 2502b730f8bSJeremy L Thompson CeedCall(CeedCheckFilePath(ceed, qf->user_source, &is_absolute_path)); 251ca5eadf8SJeremy L Thompson if (is_absolute_path) { 252ca5eadf8SJeremy L Thompson absolute_path = (char *)qf->user_source; 253ca5eadf8SJeremy L Thompson } else { 2542b730f8bSJeremy L Thompson CeedCall(CeedGetJitAbsolutePath(ceed, qf->user_source, &absolute_path)); 255ca5eadf8SJeremy L Thompson } 256ca5eadf8SJeremy L Thompson 257ca5eadf8SJeremy L Thompson size_t source_len = strlen(absolute_path) - kernel_name_len - 1; 2581c66c397SJeremy L Thompson 2592b730f8bSJeremy L Thompson CeedCall(CeedCalloc(source_len + 1, &source_path_copy)); 260ca5eadf8SJeremy L Thompson memcpy(source_path_copy, absolute_path, source_len); 261ca5eadf8SJeremy L Thompson qf->source_path = source_path_copy; 262ca5eadf8SJeremy L Thompson 2632b730f8bSJeremy L Thompson if (!is_absolute_path) CeedCall(CeedFree(&absolute_path)); 264ca5eadf8SJeremy L Thompson } 265ca5eadf8SJeremy L Thompson 26643e1b16fSJeremy L Thompson *source_path = (char *)qf->source_path; 267e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2687a982d89SJeremy L. Thompson } 2697a982d89SJeremy L. Thompson 2707a982d89SJeremy L. Thompson /** 271ca94c3ddSJeremy L Thompson @brief Initialize and load `CeedQFunction` source file into string buffer, including full text of local files in place of `#include "local.h"`. 2724385fb7fSSebastian Grimberg 273ca94c3ddSJeremy L Thompson The `buffer` is set to `NULL` if there is no `CeedQFunction` source file. 2744385fb7fSSebastian Grimberg 275*f8d308faSJed Brown Note: This function may as well return a mutable buffer, but all current uses 276*f8d308faSJed Brown do not modify it. (This is just a downside of `const` semantics with output 277*f8d308faSJed Brown arguments instead of returns.) 278*f8d308faSJed Brown 279ca94c3ddSJeremy L Thompson Note: Caller is responsible for freeing the string buffer with @ref CeedFree(). 2803d3250a0SJeremy L Thompson 281ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 282f74ec584SJeremy L Thompson @param[out] source_buffer String buffer for source file contents 2833d3250a0SJeremy L Thompson 2843d3250a0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2853d3250a0SJeremy L Thompson 2863d3250a0SJeremy L Thompson @ref Backend 2873d3250a0SJeremy L Thompson **/ 288*f8d308faSJed Brown int CeedQFunctionLoadSourceToBuffer(CeedQFunction qf, const char **source_buffer) { 28934ffed21SJeremy L Thompson const char *source_path; 2903d3250a0SJeremy L Thompson 2912b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetSourcePath(qf, &source_path)); 2923d3250a0SJeremy L Thompson *source_buffer = NULL; 2933d3250a0SJeremy L Thompson if (source_path) { 2941203703bSJeremy L Thompson Ceed ceed; 295*f8d308faSJed Brown char *buffer = NULL; 2961203703bSJeremy L Thompson 2971203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 298*f8d308faSJed Brown CeedCall(CeedLoadSourceToBuffer(ceed, source_path, &buffer)); 299*f8d308faSJed Brown *source_buffer = buffer; 3003d3250a0SJeremy L Thompson } 3013d3250a0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3023d3250a0SJeremy L Thompson } 3033d3250a0SJeremy L Thompson 3043d3250a0SJeremy L Thompson /** 305ca94c3ddSJeremy L Thompson @brief Get the User Function for a `CeedQFunction` 3067a982d89SJeremy L. Thompson 307ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 3087a982d89SJeremy L. Thompson @param[out] f Variable to store user function 3097a982d89SJeremy L. Thompson 3107a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3117a982d89SJeremy L. Thompson 3127a982d89SJeremy L. Thompson @ref Backend 3137a982d89SJeremy L. Thompson **/ 3147a982d89SJeremy L. Thompson int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) { 3157a982d89SJeremy L. Thompson *f = qf->function; 316e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3177a982d89SJeremy L. Thompson } 3187a982d89SJeremy L. Thompson 3197a982d89SJeremy L. Thompson /** 320ca94c3ddSJeremy L Thompson @brief Get global context for a `CeedQFunction`. 3214385fb7fSSebastian Grimberg 322ca94c3ddSJeremy L Thompson Note: For `CeedQFunction` from the Fortran interface, this function will return the Fortran context `CeedQFunctionContext`. 3237a982d89SJeremy L. Thompson 324ea61e9acSJeremy L Thompson @param[in] qf CeedQFunction 325777ff853SJeremy L Thompson @param[out] ctx Variable to store CeedQFunctionContext 3267a982d89SJeremy L. Thompson 3277a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3287a982d89SJeremy L. Thompson 3297a982d89SJeremy L. Thompson @ref Backend 3307a982d89SJeremy L. Thompson **/ 331777ff853SJeremy L Thompson int CeedQFunctionGetContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 3327a982d89SJeremy L. Thompson *ctx = qf->ctx; 333e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3347a982d89SJeremy L. Thompson } 3357a982d89SJeremy L. Thompson 3367a982d89SJeremy L. Thompson /** 337ca94c3ddSJeremy L Thompson @brief Get context data of a `CeedQFunction` 338441428dfSJeremy L Thompson 339ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 340ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 341ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 342441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 343441428dfSJeremy L Thompson 344441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 345441428dfSJeremy L Thompson 346441428dfSJeremy L Thompson @ref Backend 347441428dfSJeremy L Thompson **/ 3482b730f8bSJeremy L Thompson int CeedQFunctionGetContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 349441428dfSJeremy L Thompson bool is_writable; 350441428dfSJeremy L Thompson CeedQFunctionContext ctx; 351441428dfSJeremy L Thompson 3522b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 353441428dfSJeremy L Thompson if (ctx) { 3542b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 355441428dfSJeremy L Thompson if (is_writable) { 3562b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 357441428dfSJeremy L Thompson } else { 3582b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 359441428dfSJeremy L Thompson } 360441428dfSJeremy L Thompson } else { 361441428dfSJeremy L Thompson *(void **)data = NULL; 362441428dfSJeremy L Thompson } 363441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 364441428dfSJeremy L Thompson } 365441428dfSJeremy L Thompson 366441428dfSJeremy L Thompson /** 367ca94c3ddSJeremy L Thompson @brief Restore context data of a `CeedQFunction` 368441428dfSJeremy L Thompson 369ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 370ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 371441428dfSJeremy L Thompson 372441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 373441428dfSJeremy L Thompson 374441428dfSJeremy L Thompson @ref Backend 375441428dfSJeremy L Thompson **/ 376441428dfSJeremy L Thompson int CeedQFunctionRestoreContextData(CeedQFunction qf, void *data) { 377441428dfSJeremy L Thompson bool is_writable; 378441428dfSJeremy L Thompson CeedQFunctionContext ctx; 379441428dfSJeremy L Thompson 3802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 381441428dfSJeremy L Thompson if (ctx) { 3822b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 383441428dfSJeremy L Thompson if (is_writable) { 3842b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 385441428dfSJeremy L Thompson } else { 3862b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 387441428dfSJeremy L Thompson } 388441428dfSJeremy L Thompson } 3895f249b39SJeremy L Thompson *(void **)data = NULL; 390441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 391441428dfSJeremy L Thompson } 392441428dfSJeremy L Thompson 393441428dfSJeremy L Thompson /** 394ca94c3ddSJeremy L Thompson @brief Get true user context for a `CeedQFunction` 3954385fb7fSSebastian Grimberg 396ca94c3ddSJeremy L Thompson Note: For all `CeedQFunction` this function will return the user `CeedQFunctionContext` and not interface context `CeedQFunctionContext`, if any such object exists. 3977a982d89SJeremy L. Thompson 398ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 399ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 4007a982d89SJeremy L. Thompson 4017a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4027a982d89SJeremy L. Thompson @ref Backend 4037a982d89SJeremy L. Thompson **/ 404777ff853SJeremy L Thompson int CeedQFunctionGetInnerContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 4051203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 4061203703bSJeremy L Thompson 4071203703bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &qf_ctx)); 408f04ea552SJeremy L Thompson if (qf->is_fortran) { 409d1d35e2fSjeremylt CeedFortranContext fortran_ctx = NULL; 4101c66c397SJeremy L Thompson 4111203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(qf_ctx, CEED_MEM_HOST, &fortran_ctx)); 4128cb0412aSJeremy L Thompson *ctx = fortran_ctx->inner_ctx; 4131203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(qf_ctx, (void *)&fortran_ctx)); 4147a982d89SJeremy L. Thompson } else { 4151203703bSJeremy L Thompson *ctx = qf_ctx; 4167a982d89SJeremy L. Thompson } 417e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4187a982d89SJeremy L. Thompson } 4197a982d89SJeremy L. Thompson 4207a982d89SJeremy L. Thompson /** 421ca94c3ddSJeremy L Thompson @brief Get inner context data of a `CeedQFunction` 422441428dfSJeremy L Thompson 423ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 424ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 425ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 426441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 427441428dfSJeremy L Thompson 428441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 429441428dfSJeremy L Thompson 430441428dfSJeremy L Thompson @ref Backend 431441428dfSJeremy L Thompson **/ 4322b730f8bSJeremy L Thompson int CeedQFunctionGetInnerContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 433441428dfSJeremy L Thompson bool is_writable; 434441428dfSJeremy L Thompson CeedQFunctionContext ctx; 435441428dfSJeremy L Thompson 4362b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 437441428dfSJeremy L Thompson if (ctx) { 4382b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 439441428dfSJeremy L Thompson if (is_writable) { 4402b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 441441428dfSJeremy L Thompson } else { 4422b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 443441428dfSJeremy L Thompson } 444441428dfSJeremy L Thompson } else { 445441428dfSJeremy L Thompson *(void **)data = NULL; 446441428dfSJeremy L Thompson } 447441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 448441428dfSJeremy L Thompson } 449441428dfSJeremy L Thompson 450441428dfSJeremy L Thompson /** 451ca94c3ddSJeremy L Thompson @brief Restore inner context data of a `CeedQFunction` 452441428dfSJeremy L Thompson 453ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 454ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 455441428dfSJeremy L Thompson 456441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 457441428dfSJeremy L Thompson 458441428dfSJeremy L Thompson @ref Backend 459441428dfSJeremy L Thompson **/ 460441428dfSJeremy L Thompson int CeedQFunctionRestoreInnerContextData(CeedQFunction qf, void *data) { 461441428dfSJeremy L Thompson bool is_writable; 462441428dfSJeremy L Thompson CeedQFunctionContext ctx; 463441428dfSJeremy L Thompson 4642b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 465441428dfSJeremy L Thompson if (ctx) { 4662b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 467441428dfSJeremy L Thompson if (is_writable) { 4682b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 469441428dfSJeremy L Thompson } else { 4702b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 471441428dfSJeremy L Thompson } 472441428dfSJeremy L Thompson } 4735f249b39SJeremy L Thompson *(void **)data = NULL; 474441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 475441428dfSJeremy L Thompson } 476441428dfSJeremy L Thompson 477441428dfSJeremy L Thompson /** 478ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunction` is identity 4797a982d89SJeremy L. Thompson 480ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 481d1d35e2fSjeremylt @param[out] is_identity Variable to store identity status 4827a982d89SJeremy L. Thompson 4837a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4847a982d89SJeremy L. Thompson 4857a982d89SJeremy L. Thompson @ref Backend 4867a982d89SJeremy L. Thompson **/ 487d1d35e2fSjeremylt int CeedQFunctionIsIdentity(CeedQFunction qf, bool *is_identity) { 488f04ea552SJeremy L Thompson *is_identity = qf->is_identity; 489e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4907a982d89SJeremy L. Thompson } 4917a982d89SJeremy L. Thompson 4927a982d89SJeremy L. Thompson /** 493ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunctionContext` is writable 494441428dfSJeremy L Thompson 495ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 496ea61e9acSJeremy L Thompson @param[out] is_writable Variable to store context writeable status 497441428dfSJeremy L Thompson 498441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 499441428dfSJeremy L Thompson 500441428dfSJeremy L Thompson @ref Backend 501441428dfSJeremy L Thompson **/ 502441428dfSJeremy L Thompson int CeedQFunctionIsContextWritable(CeedQFunction qf, bool *is_writable) { 503441428dfSJeremy L Thompson *is_writable = qf->is_context_writable; 504441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 505441428dfSJeremy L Thompson } 506441428dfSJeremy L Thompson 507441428dfSJeremy L Thompson /** 508ca94c3ddSJeremy L Thompson @brief Get backend data of a `CeedQFunction` 5097a982d89SJeremy L. Thompson 510ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 5117a982d89SJeremy L. Thompson @param[out] data Variable to store data 5127a982d89SJeremy L. Thompson 5137a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5147a982d89SJeremy L. Thompson 5157a982d89SJeremy L. Thompson @ref Backend 5167a982d89SJeremy L. Thompson **/ 517777ff853SJeremy L Thompson int CeedQFunctionGetData(CeedQFunction qf, void *data) { 518777ff853SJeremy L Thompson *(void **)data = qf->data; 519e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5207a982d89SJeremy L. Thompson } 5217a982d89SJeremy L. Thompson 5227a982d89SJeremy L. Thompson /** 523ca94c3ddSJeremy L Thompson @brief Set backend data of a `CeedQFunction` 5247a982d89SJeremy L. Thompson 525ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 526ea61e9acSJeremy L Thompson @param[in] data Data to set 5277a982d89SJeremy L. Thompson 5287a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5297a982d89SJeremy L. Thompson 5307a982d89SJeremy L. Thompson @ref Backend 5317a982d89SJeremy L. Thompson **/ 532777ff853SJeremy L Thompson int CeedQFunctionSetData(CeedQFunction qf, void *data) { 533777ff853SJeremy L Thompson qf->data = data; 534e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5357a982d89SJeremy L. Thompson } 5367a982d89SJeremy L. Thompson 5377a982d89SJeremy L. Thompson /** 5381203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedQFunction` is immutable 5391203703bSJeremy L Thompson 5401203703bSJeremy L Thompson @param[in] qf `CeedOperator` 5411203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 5421203703bSJeremy L Thompson 5431203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5441203703bSJeremy L Thompson 5451203703bSJeremy L Thompson @ref Backend 5461203703bSJeremy L Thompson **/ 5471203703bSJeremy L Thompson int CeedQFunctionIsImmutable(CeedQFunction qf, bool *is_immutable) { 5481203703bSJeremy L Thompson *is_immutable = qf->is_immutable; 5491203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5501203703bSJeremy L Thompson } 5511203703bSJeremy L Thompson 5521203703bSJeremy L Thompson /** 5531203703bSJeremy L Thompson @brief Set the immutable flag of a `CeedQFunction` to `true` 5541203703bSJeremy L Thompson 5551203703bSJeremy L Thompson @param[in,out] qf `CeedQFunction` 5561203703bSJeremy L Thompson 5571203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5581203703bSJeremy L Thompson 5591203703bSJeremy L Thompson @ref Backend 5601203703bSJeremy L Thompson **/ 5611203703bSJeremy L Thompson int CeedQFunctionSetImmutable(CeedQFunction qf) { 5621203703bSJeremy L Thompson qf->is_immutable = true; 5631203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5641203703bSJeremy L Thompson } 5651203703bSJeremy L Thompson 5661203703bSJeremy L Thompson /** 567ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedQFunction` 56834359f16Sjeremylt 569ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to increment the reference counter 57034359f16Sjeremylt 57134359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 57234359f16Sjeremylt 57334359f16Sjeremylt @ref Backend 57434359f16Sjeremylt **/ 5759560d06aSjeremylt int CeedQFunctionReference(CeedQFunction qf) { 57634359f16Sjeremylt qf->ref_count++; 57734359f16Sjeremylt return CEED_ERROR_SUCCESS; 57834359f16Sjeremylt } 57934359f16Sjeremylt 5806e15d496SJeremy L Thompson /** 581ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs per quadrature required to apply `CeedQFunction` 5826e15d496SJeremy L Thompson 583ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 584ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5856e15d496SJeremy L Thompson 5866e15d496SJeremy L Thompson @ref Backend 5876e15d496SJeremy L Thompson **/ 5889d36ca50SJeremy L Thompson int CeedQFunctionGetFlopsEstimate(CeedQFunction qf, CeedSize *flops) { 5896e15d496SJeremy L Thompson *flops = qf->user_flop_estimate; 5906e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5916e15d496SJeremy L Thompson } 5926e15d496SJeremy L Thompson 5937a982d89SJeremy L. Thompson /// @} 5947a982d89SJeremy L. Thompson 5957a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5967a982d89SJeremy L. Thompson /// CeedQFunction Public API 5977a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5987a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 5997a982d89SJeremy L. Thompson /// @{ 6007a982d89SJeremy L. Thompson 6017a982d89SJeremy L. Thompson /** 602ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms 6037a982d89SJeremy L. Thompson 604ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 605ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 606ca94c3ddSJeremy L Thompson Caller must ensure that number of quadrature points is a multiple of `vec_length`. 607ea61e9acSJeremy L Thompson @param[in] f Function pointer to evaluate action at quadrature points. 608ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 609ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunctionUser`, "\abs_path\file.h:function_name". 610ca94c3ddSJeremy 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.). 6114ada38baSJames Wright The entire contents of this file and all locally included files are used during JiT compilation for GPU backends. 6124ada38baSJames Wright All source files must be at the provided filepath at runtime for JiT to function. 613ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 6147a982d89SJeremy L. Thompson 6157a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6167a982d89SJeremy L. Thompson 617ca94c3ddSJeremy L Thompson See \ref CeedQFunctionUser for details on the call-back function `f` arguments. 6187a982d89SJeremy L. Thompson 6197a982d89SJeremy L. Thompson @ref User 6207a982d89SJeremy L. Thompson **/ 6212b730f8bSJeremy L Thompson int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length, CeedQFunctionUser f, const char *source, CeedQFunction *qf) { 622ca5eadf8SJeremy L Thompson char *user_source_copy; 6237a982d89SJeremy L. Thompson 6247a982d89SJeremy L. Thompson if (!ceed->QFunctionCreate) { 6257a982d89SJeremy L. Thompson Ceed delegate; 6266574a04fSJeremy L Thompson 6272b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "QFunction")); 628ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionCreateInterior"); 6292b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(delegate, vec_length, f, source, qf)); 630e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6317a982d89SJeremy L. Thompson } 6327a982d89SJeremy L. Thompson 6336574a04fSJeremy L Thompson CeedCheck(!strlen(source) || strrchr(source, ':'), ceed, CEED_ERROR_INCOMPLETE, 6346574a04fSJeremy L Thompson "Provided path to source does not include function name. Provided: \"%s\"\nRequired: \"\\abs_path\\file.h:function_name\"", source); 63543e1b16fSJeremy L Thompson 6362b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, qf)); 637db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*qf)->ceed)); 638d1d35e2fSjeremylt (*qf)->ref_count = 1; 639d1d35e2fSjeremylt (*qf)->vec_length = vec_length; 640f04ea552SJeremy L Thompson (*qf)->is_identity = false; 641441428dfSJeremy L Thompson (*qf)->is_context_writable = true; 6427a982d89SJeremy L. Thompson (*qf)->function = f; 6436e15d496SJeremy L Thompson (*qf)->user_flop_estimate = -1; 64443e1b16fSJeremy L Thompson if (strlen(source)) { 645ca5eadf8SJeremy L Thompson size_t user_source_len = strlen(source); 646ee5a26f2SJeremy L Thompson 6472b730f8bSJeremy L Thompson CeedCall(CeedCalloc(user_source_len + 1, &user_source_copy)); 648ca5eadf8SJeremy L Thompson memcpy(user_source_copy, source, user_source_len); 649ca5eadf8SJeremy L Thompson (*qf)->user_source = user_source_copy; 65043e1b16fSJeremy L Thompson } 6512b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->input_fields)); 6522b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->output_fields)); 6532b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionCreate(*qf)); 654e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6557a982d89SJeremy L. Thompson } 6567a982d89SJeremy L. Thompson 6577a982d89SJeremy L. Thompson /** 658ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms by name 659288c0443SJeremy L Thompson 660ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 661ca94c3ddSJeremy L Thompson @param[in] name Name of `CeedQFunction` to use from gallery 662ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 663288c0443SJeremy L Thompson 664288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 665288c0443SJeremy L Thompson 6667a982d89SJeremy L. Thompson @ref User 667288c0443SJeremy L Thompson **/ 6682b730f8bSJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name, CeedQFunction *qf) { 669f7e22acaSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX; 670288c0443SJeremy L Thompson 6712b730f8bSJeremy L Thompson CeedCall(CeedQFunctionRegisterAll()); 672288c0443SJeremy L Thompson // Find matching backend 673ca94c3ddSJeremy L Thompson CeedCheck(name, ceed, CEED_ERROR_INCOMPLETE, "No CeedQFunction name provided"); 674288c0443SJeremy L Thompson for (size_t i = 0; i < num_qfunctions; i++) { 675288c0443SJeremy L Thompson size_t n; 676d1d35e2fSjeremylt const char *curr_name = gallery_qfunctions[i].name; 6772b730f8bSJeremy L Thompson for (n = 0; curr_name[n] && curr_name[n] == name[n]; n++) { 6782b730f8bSJeremy L Thompson } 679d1d35e2fSjeremylt if (n > match_len) { 680d1d35e2fSjeremylt match_len = n; 681f7e22acaSJeremy L Thompson match_index = i; 682288c0443SJeremy L Thompson } 683288c0443SJeremy L Thompson } 684ca94c3ddSJeremy L Thompson CeedCheck(match_len > 0, ceed, CEED_ERROR_UNSUPPORTED, "No suitable gallery CeedQFunction"); 685288c0443SJeremy L Thompson 686288c0443SJeremy L Thompson // Create QFunction 6872b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(ceed, gallery_qfunctions[match_index].vec_length, gallery_qfunctions[match_index].f, 6882b730f8bSJeremy L Thompson gallery_qfunctions[match_index].source, qf)); 689288c0443SJeremy L Thompson 690288c0443SJeremy L Thompson // QFunction specific setup 6912b730f8bSJeremy L Thompson CeedCall(gallery_qfunctions[match_index].init(ceed, name, *qf)); 692288c0443SJeremy L Thompson 69375affc3bSjeremylt // Copy name 6942b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(name, (char **)&(*qf)->gallery_name)); 69543e1b16fSJeremy L Thompson (*qf)->is_gallery = true; 696e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 697288c0443SJeremy L Thompson } 698288c0443SJeremy L Thompson 699288c0443SJeremy L Thompson /** 700ca94c3ddSJeremy L Thompson @brief Create an identity `CeedQFunction`. 7014385fb7fSSebastian Grimberg 702ea61e9acSJeremy L Thompson Inputs are written into outputs in the order given. 703ca94c3ddSJeremy 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. 704ca94c3ddSJeremy 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. 7050219ea01SJeremy L Thompson 706ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 707ca94c3ddSJeremy L Thompson @param[in] size Size of the `CeedQFunction` fields 708ca94c3ddSJeremy L Thompson @param[in] in_mode @ref CeedEvalMode for input to `CeedQFunction` 709ca94c3ddSJeremy L Thompson @param[in] out_mode @ref CeedEvalMode for output to `CeedQFunction` 710ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 7110219ea01SJeremy L Thompson 7120219ea01SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7130219ea01SJeremy L Thompson 7147a982d89SJeremy L. Thompson @ref User 7150219ea01SJeremy L Thompson **/ 7162b730f8bSJeremy L Thompson int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf) { 7171c66c397SJeremy L Thompson CeedQFunctionContext ctx; 7181c66c397SJeremy L Thompson CeedContextFieldLabel size_label; 7191c66c397SJeremy L Thompson 7202b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInteriorByName(ceed, "Identity", qf)); 7212b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddInput(*qf, "input", size, in_mode)); 7222b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddOutput(*qf, "output", size, out_mode)); 7230219ea01SJeremy L Thompson 724f04ea552SJeremy L Thompson (*qf)->is_identity = true; 725547dbd6fSJeremy L Thompson 7262b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(*qf, &ctx)); 7272b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, "size", &size_label)); 7282b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetInt32(ctx, size_label, &size)); 729e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7300219ea01SJeremy L Thompson } 7310219ea01SJeremy L Thompson 7320219ea01SJeremy L Thompson /** 733ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedQFunction`. 7344385fb7fSSebastian Grimberg 735ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedQFunctionDestroy(). 736512bb800SJeremy L Thompson 737ca94c3ddSJeremy 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`. 738ca94c3ddSJeremy L Thompson This `CeedQFunction` will be destroyed if `*qf_copy` is the only reference to this `CeedQFunction`. 7399560d06aSjeremylt 740ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to copy reference to 7419560d06aSjeremylt @param[out] qf_copy Variable to store copied reference 7429560d06aSjeremylt 7439560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7449560d06aSjeremylt 7459560d06aSjeremylt @ref User 7469560d06aSjeremylt **/ 7479560d06aSjeremylt int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy) { 7482b730f8bSJeremy L Thompson CeedCall(CeedQFunctionReference(qf)); 7492b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(qf_copy)); 7509560d06aSjeremylt *qf_copy = qf; 7519560d06aSjeremylt return CEED_ERROR_SUCCESS; 7529560d06aSjeremylt } 7539560d06aSjeremylt 7549560d06aSjeremylt /** 755ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` input 756b11c1e72Sjeremylt 757ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 758ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 759ca94c3ddSJeremy 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. 760ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 761ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 762ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 763ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 764ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 765b11c1e72Sjeremylt 766b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 767dfdf5a53Sjeremylt 7687a982d89SJeremy L. Thompson @ref User 769b11c1e72Sjeremylt **/ 7702b730f8bSJeremy L Thompson int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 7711203703bSJeremy L Thompson bool is_immutable; 7721203703bSJeremy L Thompson Ceed ceed; 7731203703bSJeremy L Thompson 7741203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 7751203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 7761203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "QFunction cannot be changed after set as immutable"); 7771203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT || size == 1, ceed, CEED_ERROR_DIMENSION, "CEED_EVAL_WEIGHT should have size 1"); 778643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 7791203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 780643fbb69SJeremy L Thompson } 781643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 7821203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 783643fbb69SJeremy L Thompson } 7842b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->input_fields[qf->num_input_fields], field_name, size, eval_mode)); 785d1d35e2fSjeremylt qf->num_input_fields++; 786e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 787d7b241e6Sjeremylt } 788d7b241e6Sjeremylt 789b11c1e72Sjeremylt /** 790ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` output 791b11c1e72Sjeremylt 792ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 793ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 794ca94c3ddSJeremy 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. 795ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 796ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 797ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 798ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 799ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl. 800b11c1e72Sjeremylt 801b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 802dfdf5a53Sjeremylt 8037a982d89SJeremy L. Thompson @ref User 804b11c1e72Sjeremylt **/ 8052b730f8bSJeremy L Thompson int CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 8061203703bSJeremy L Thompson bool is_immutable; 8071203703bSJeremy L Thompson Ceed ceed; 8081203703bSJeremy L Thompson 8091203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 8101203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 8111203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "CeedQFunction cannot be changed after set as immutable"); 8121203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT, ceed, CEED_ERROR_DIMENSION, "Cannot create CeedQFunction output with CEED_EVAL_WEIGHT"); 813643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 8141203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 815643fbb69SJeremy L Thompson } 816643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 8171203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 818643fbb69SJeremy L Thompson } 8192b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->output_fields[qf->num_output_fields], field_name, size, eval_mode)); 820d1d35e2fSjeremylt qf->num_output_fields++; 821e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 822d7b241e6Sjeremylt } 823d7b241e6Sjeremylt 824dfdf5a53Sjeremylt /** 825ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunctionField` of a `CeedQFunction` 82643bbe138SJeremy L Thompson 827ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 828f04ea552SJeremy L Thompson 829ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 830f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 831f74ec584SJeremy L Thompson @param[out] input_fields Variable to store input fields 832f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 833f74ec584SJeremy L Thompson @param[out] output_fields Variable to store output fields 83443bbe138SJeremy L Thompson 83543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83643bbe138SJeremy L Thompson 837e9b533fbSJeremy L Thompson @ref Advanced 83843bbe138SJeremy L Thompson **/ 8392b730f8bSJeremy L Thompson int CeedQFunctionGetFields(CeedQFunction qf, CeedInt *num_input_fields, CeedQFunctionField **input_fields, CeedInt *num_output_fields, 84043bbe138SJeremy L Thompson CeedQFunctionField **output_fields) { 8411203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 84243bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = qf->num_input_fields; 84343bbe138SJeremy L Thompson if (input_fields) *input_fields = qf->input_fields; 84443bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = qf->num_output_fields; 84543bbe138SJeremy L Thompson if (output_fields) *output_fields = qf->output_fields; 84643bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84743bbe138SJeremy L Thompson } 84843bbe138SJeremy L Thompson 84943bbe138SJeremy L Thompson /** 850ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedQFunctionField` 85143bbe138SJeremy L Thompson 852ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 85343bbe138SJeremy L Thompson @param[out] field_name Variable to store the field name 85443bbe138SJeremy L Thompson 85543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85643bbe138SJeremy L Thompson 857e9b533fbSJeremy L Thompson @ref Advanced 85843bbe138SJeremy L Thompson **/ 8596f8994e9SJeremy L Thompson int CeedQFunctionFieldGetName(CeedQFunctionField qf_field, const char **field_name) { 8606f8994e9SJeremy L Thompson *field_name = qf_field->field_name; 86143bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 86243bbe138SJeremy L Thompson } 86343bbe138SJeremy L Thompson 86443bbe138SJeremy L Thompson /** 865ca94c3ddSJeremy L Thompson @brief Get the number of components of a `CeedQFunctionField` 86643bbe138SJeremy L Thompson 867ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 86843bbe138SJeremy L Thompson @param[out] size Variable to store the size of the field 86943bbe138SJeremy L Thompson 87043bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87143bbe138SJeremy L Thompson 872e9b533fbSJeremy L Thompson @ref Advanced 87343bbe138SJeremy L Thompson **/ 87443bbe138SJeremy L Thompson int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field, CeedInt *size) { 87543bbe138SJeremy L Thompson *size = qf_field->size; 87643bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87743bbe138SJeremy L Thompson } 87843bbe138SJeremy L Thompson 87943bbe138SJeremy L Thompson /** 880ca94c3ddSJeremy L Thompson @brief Get the @ref CeedEvalMode of a `CeedQFunctionField` 88143bbe138SJeremy L Thompson 882ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 88343bbe138SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 88443bbe138SJeremy L Thompson 88543bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88643bbe138SJeremy L Thompson 887e9b533fbSJeremy L Thompson @ref Advanced 88843bbe138SJeremy L Thompson **/ 8892b730f8bSJeremy L Thompson int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field, CeedEvalMode *eval_mode) { 89043bbe138SJeremy L Thompson *eval_mode = qf_field->eval_mode; 89143bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 89243bbe138SJeremy L Thompson } 89343bbe138SJeremy L Thompson 89443bbe138SJeremy L Thompson /** 895ab747706SJeremy L Thompson @brief Get the data of a `CeedQFunctionField`. 896ab747706SJeremy L Thompson 897ab747706SJeremy L Thompson Any arguments set as `NULL` are ignored. 898ab747706SJeremy L Thompson 899ab747706SJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 900ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 901ab747706SJeremy L Thompson @param[out] size Variable to store the size of the field 902ab747706SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 903ab747706SJeremy L Thompson 904ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 905ab747706SJeremy L Thompson 906ab747706SJeremy L Thompson @ref Advanced 907ab747706SJeremy L Thompson **/ 9086f8994e9SJeremy L Thompson int CeedQFunctionFieldGetData(CeedQFunctionField qf_field, const char **field_name, CeedInt *size, CeedEvalMode *eval_mode) { 909ab747706SJeremy L Thompson if (field_name) CeedCall(CeedQFunctionFieldGetName(qf_field, field_name)); 910ab747706SJeremy L Thompson if (size) CeedCall(CeedQFunctionFieldGetSize(qf_field, size)); 911ab747706SJeremy L Thompson if (eval_mode) CeedCall(CeedQFunctionFieldGetEvalMode(qf_field, eval_mode)); 912ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 913ab747706SJeremy L Thompson } 914ab747706SJeremy L Thompson 915ab747706SJeremy L Thompson /** 916ca94c3ddSJeremy L Thompson @brief Set global context for a `CeedQFunction` 917b11c1e72Sjeremylt 918ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 919ea61e9acSJeremy L Thompson @param[in] ctx Context data to set 920b11c1e72Sjeremylt 921b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 922dfdf5a53Sjeremylt 9237a982d89SJeremy L. Thompson @ref User 924b11c1e72Sjeremylt **/ 925777ff853SJeremy L Thompson int CeedQFunctionSetContext(CeedQFunction qf, CeedQFunctionContext ctx) { 9262b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&qf->ctx)); 927d7b241e6Sjeremylt qf->ctx = ctx; 928db002c03SJeremy L Thompson if (ctx) CeedCall(CeedQFunctionContextReference(ctx)); 929e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 930d7b241e6Sjeremylt } 931d7b241e6Sjeremylt 932b11c1e72Sjeremylt /** 933ca94c3ddSJeremy L Thompson @brief Set writability of `CeedQFunctionContext` when calling the `CeedQFunctionUser`. 9344385fb7fSSebastian Grimberg 935859c15bbSJames Wright The default value is `is_writable == true`. 936441428dfSJeremy L Thompson 937ca94c3ddSJeremy L Thompson Setting `is_writable == true` indicates the `CeedQFunctionUser` writes into the `CeedQFunctionContext` and requires memory synchronization after calling @ref CeedQFunctionApply(). 938441428dfSJeremy L Thompson 939ca94c3ddSJeremy L Thompson Setting 'is_writable == false' asserts that `CeedQFunctionUser` does not modify the `CeedQFunctionContext`. 940ea61e9acSJeremy L Thompson Violating this assertion may lead to inconsistent data. 941441428dfSJeremy L Thompson 942441428dfSJeremy L Thompson Setting `is_writable == false` may offer a performance improvement on GPU backends. 943441428dfSJeremy L Thompson 944ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 945ca94c3ddSJeremy L Thompson @param[in] is_writable Boolean flag for writability status 946441428dfSJeremy L Thompson 947441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 948441428dfSJeremy L Thompson 949441428dfSJeremy L Thompson @ref User 950441428dfSJeremy L Thompson **/ 951441428dfSJeremy L Thompson int CeedQFunctionSetContextWritable(CeedQFunction qf, bool is_writable) { 952441428dfSJeremy L Thompson qf->is_context_writable = is_writable; 953441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 954441428dfSJeremy L Thompson } 955441428dfSJeremy L Thompson 956441428dfSJeremy L Thompson /** 957ca94c3ddSJeremy L Thompson @brief Set estimated number of FLOPs per quadrature required to apply `CeedQFunction` 9586e15d496SJeremy L Thompson 959ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 960ea61e9acSJeremy L Thompson @param[out] flops FLOPs per quadrature point estimate 9616e15d496SJeremy L Thompson 9626e15d496SJeremy L Thompson @ref Backend 9636e15d496SJeremy L Thompson **/ 9649d36ca50SJeremy L Thompson int CeedQFunctionSetUserFlopsEstimate(CeedQFunction qf, CeedSize flops) { 9651203703bSJeremy L Thompson Ceed ceed; 9661203703bSJeremy L Thompson 9671203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 9681203703bSJeremy L Thompson CeedCheck(flops >= 0, ceed, CEED_ERROR_INCOMPATIBLE, "Must set non-negative FLOPs estimate"); 9696e15d496SJeremy L Thompson qf->user_flop_estimate = flops; 9706e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 9716e15d496SJeremy L Thompson } 9726e15d496SJeremy L Thompson 9736e15d496SJeremy L Thompson /** 974ca94c3ddSJeremy L Thompson @brief View a `CeedQFunction` 97575affc3bSjeremylt 976ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to view 977ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 97875affc3bSjeremylt 97975affc3bSjeremylt @return Error code: 0 - success, otherwise - failure 98075affc3bSjeremylt 9817a982d89SJeremy L. Thompson @ref User 98275affc3bSjeremylt **/ 98375affc3bSjeremylt int CeedQFunctionView(CeedQFunction qf, FILE *stream) { 9847d023984SJeremy L Thompson const char *kernel_name; 98575affc3bSjeremylt 9862b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetKernelName(qf, &kernel_name)); 9872b730f8bSJeremy L Thompson fprintf(stream, "%sCeedQFunction - %s\n", qf->is_gallery ? "Gallery " : "User ", qf->is_gallery ? qf->gallery_name : kernel_name); 98875affc3bSjeremylt 9892b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " input field%s:\n", qf->num_input_fields, qf->num_input_fields > 1 ? "s" : ""); 990d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_input_fields; i++) { 9912b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->input_fields[i], i, 1, stream)); 99275affc3bSjeremylt } 99375affc3bSjeremylt 9942b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " output field%s:\n", qf->num_output_fields, qf->num_output_fields > 1 ? "s" : ""); 995d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_output_fields; i++) { 9962b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->output_fields[i], i, 0, stream)); 99775affc3bSjeremylt } 998e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 99975affc3bSjeremylt } 100075affc3bSjeremylt 100175affc3bSjeremylt /** 1002ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedQFunction` 1003b7c9bbdaSJeremy L Thompson 1004ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 1005ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store`Ceed` 1006b7c9bbdaSJeremy L Thompson 1007b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1008b7c9bbdaSJeremy L Thompson 1009b7c9bbdaSJeremy L Thompson @ref Advanced 1010b7c9bbdaSJeremy L Thompson **/ 1011b7c9bbdaSJeremy L Thompson int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 1012b7c9bbdaSJeremy L Thompson *ceed = qf->ceed; 1013b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1014b7c9bbdaSJeremy L Thompson } 1015b7c9bbdaSJeremy L Thompson 1016b7c9bbdaSJeremy L Thompson /** 1017ca94c3ddSJeremy L Thompson @brief Apply the action of a `CeedQFunction` 1018b11c1e72Sjeremylt 1019ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 1020f04ea552SJeremy L Thompson 1021ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 1022ea61e9acSJeremy L Thompson @param[in] Q Number of quadrature points 1023ca94c3ddSJeremy L Thompson @param[in] u Array of input `CeedVector` 1024ca94c3ddSJeremy L Thompson @param[out] v Array of output `CeedVector` 1025b11c1e72Sjeremylt 1026b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1027dfdf5a53Sjeremylt 10287a982d89SJeremy L. Thompson @ref User 1029b11c1e72Sjeremylt **/ 10302b730f8bSJeremy L Thompson int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, CeedVector *u, CeedVector *v) { 10311203703bSJeremy L Thompson CeedInt vec_length; 10321203703bSJeremy L Thompson Ceed ceed; 10331203703bSJeremy L Thompson 10341203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 10351203703bSJeremy L Thompson CeedCheck(qf->Apply, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionApply"); 10361203703bSJeremy L Thompson CeedCall(CeedQFunctionGetVectorLength(qf, &vec_length)); 10371203703bSJeremy 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, 10381203703bSJeremy L Thompson qf->vec_length); 10391203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 10402b730f8bSJeremy L Thompson CeedCall(qf->Apply(qf, Q, u, v)); 1041e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1042d7b241e6Sjeremylt } 1043d7b241e6Sjeremylt 1044b11c1e72Sjeremylt /** 1045ca94c3ddSJeremy L Thompson @brief Destroy a `CeedQFunction` 1046b11c1e72Sjeremylt 1047ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to destroy 1048b11c1e72Sjeremylt 1049b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1050dfdf5a53Sjeremylt 10517a982d89SJeremy L. Thompson @ref User 1052b11c1e72Sjeremylt **/ 1053d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) { 1054ad6481ceSJeremy L Thompson if (!*qf || --(*qf)->ref_count > 0) { 1055ad6481ceSJeremy L Thompson *qf = NULL; 1056ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1057ad6481ceSJeremy L Thompson } 1058fe2413ffSjeremylt // Backend destroy 1059d7b241e6Sjeremylt if ((*qf)->Destroy) { 10602b730f8bSJeremy L Thompson CeedCall((*qf)->Destroy(*qf)); 1061d7b241e6Sjeremylt } 1062fe2413ffSjeremylt // Free fields 106392ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_input_fields; i++) { 10642b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->input_fields[i]).field_name)); 10652b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields[i])); 1066fe2413ffSjeremylt } 106792ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_output_fields; i++) { 10682b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->output_fields[i]).field_name)); 10692b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields[i])); 1070fe2413ffSjeremylt } 10712b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields)); 10722b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields)); 1073777ff853SJeremy L Thompson 1074777ff853SJeremy L Thompson // User context data object 10752b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&(*qf)->ctx)); 1076fe2413ffSjeremylt 10772b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->user_source)); 10782b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->source_path)); 10792b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->gallery_name)); 10802b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->kernel_name)); 10812b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*qf)->ceed)); 10822b730f8bSJeremy L Thompson CeedCall(CeedFree(qf)); 1083e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1084d7b241e6Sjeremylt } 1085d7b241e6Sjeremylt 1086d7b241e6Sjeremylt /// @} 1087