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; 24522070f95SJeremy L Thompson char *source_path_copy; 24622070f95SJeremy L Thompson const char *absolute_path; 247ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 248ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 249ca5eadf8SJeremy L Thompson 2502b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 2512b730f8bSJeremy L Thompson CeedCall(CeedCheckFilePath(ceed, qf->user_source, &is_absolute_path)); 252ca5eadf8SJeremy L Thompson if (is_absolute_path) { 253ca5eadf8SJeremy L Thompson absolute_path = (char *)qf->user_source; 254ca5eadf8SJeremy L Thompson } else { 2552b730f8bSJeremy L Thompson CeedCall(CeedGetJitAbsolutePath(ceed, qf->user_source, &absolute_path)); 256ca5eadf8SJeremy L Thompson } 257ca5eadf8SJeremy L Thompson 258ca5eadf8SJeremy L Thompson size_t source_len = strlen(absolute_path) - kernel_name_len - 1; 2591c66c397SJeremy L Thompson 2602b730f8bSJeremy L Thompson CeedCall(CeedCalloc(source_len + 1, &source_path_copy)); 261ca5eadf8SJeremy L Thompson memcpy(source_path_copy, absolute_path, source_len); 262ca5eadf8SJeremy L Thompson qf->source_path = source_path_copy; 263ca5eadf8SJeremy L Thompson 2642b730f8bSJeremy L Thompson if (!is_absolute_path) CeedCall(CeedFree(&absolute_path)); 265ca5eadf8SJeremy L Thompson } 266ca5eadf8SJeremy L Thompson 26743e1b16fSJeremy L Thompson *source_path = (char *)qf->source_path; 268e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2697a982d89SJeremy L. Thompson } 2707a982d89SJeremy L. Thompson 2717a982d89SJeremy L. Thompson /** 272ca94c3ddSJeremy L Thompson @brief Initialize and load `CeedQFunction` source file into string buffer, including full text of local files in place of `#include "local.h"`. 2734385fb7fSSebastian Grimberg 274ca94c3ddSJeremy L Thompson The `buffer` is set to `NULL` if there is no `CeedQFunction` source file. 2754385fb7fSSebastian Grimberg 276f8d308faSJed Brown Note: This function may as well return a mutable buffer, but all current uses 277f8d308faSJed Brown do not modify it. (This is just a downside of `const` semantics with output 278f8d308faSJed Brown arguments instead of returns.) 279f8d308faSJed Brown 280ca94c3ddSJeremy L Thompson Note: Caller is responsible for freeing the string buffer with @ref CeedFree(). 2813d3250a0SJeremy L Thompson 282ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 283f74ec584SJeremy L Thompson @param[out] source_buffer String buffer for source file contents 2843d3250a0SJeremy L Thompson 2853d3250a0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2863d3250a0SJeremy L Thompson 2873d3250a0SJeremy L Thompson @ref Backend 2883d3250a0SJeremy L Thompson **/ 289f8d308faSJed Brown int CeedQFunctionLoadSourceToBuffer(CeedQFunction qf, const char **source_buffer) { 29034ffed21SJeremy L Thompson const char *source_path; 2913d3250a0SJeremy L Thompson 2922b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetSourcePath(qf, &source_path)); 2933d3250a0SJeremy L Thompson *source_buffer = NULL; 2943d3250a0SJeremy L Thompson if (source_path) { 2951203703bSJeremy L Thompson Ceed ceed; 296f8d308faSJed Brown char *buffer = NULL; 2971203703bSJeremy L Thompson 2981203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 299f8d308faSJed Brown CeedCall(CeedLoadSourceToBuffer(ceed, source_path, &buffer)); 300f8d308faSJed Brown *source_buffer = buffer; 3013d3250a0SJeremy L Thompson } 3023d3250a0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3033d3250a0SJeremy L Thompson } 3043d3250a0SJeremy L Thompson 3053d3250a0SJeremy L Thompson /** 306ca94c3ddSJeremy L Thompson @brief Get the User Function for a `CeedQFunction` 3077a982d89SJeremy L. Thompson 308ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 3097a982d89SJeremy L. Thompson @param[out] f Variable to store user function 3107a982d89SJeremy L. Thompson 3117a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3127a982d89SJeremy L. Thompson 3137a982d89SJeremy L. Thompson @ref Backend 3147a982d89SJeremy L. Thompson **/ 3157a982d89SJeremy L. Thompson int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) { 3167a982d89SJeremy L. Thompson *f = qf->function; 317e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3187a982d89SJeremy L. Thompson } 3197a982d89SJeremy L. Thompson 3207a982d89SJeremy L. Thompson /** 321ca94c3ddSJeremy L Thompson @brief Get global context for a `CeedQFunction`. 3224385fb7fSSebastian Grimberg 323ca94c3ddSJeremy L Thompson Note: For `CeedQFunction` from the Fortran interface, this function will return the Fortran context `CeedQFunctionContext`. 3247a982d89SJeremy L. Thompson 325ea61e9acSJeremy L Thompson @param[in] qf CeedQFunction 326777ff853SJeremy L Thompson @param[out] ctx Variable to store CeedQFunctionContext 3277a982d89SJeremy L. Thompson 3287a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3297a982d89SJeremy L. Thompson 3307a982d89SJeremy L. Thompson @ref Backend 3317a982d89SJeremy L. Thompson **/ 332777ff853SJeremy L Thompson int CeedQFunctionGetContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 3337a982d89SJeremy L. Thompson *ctx = qf->ctx; 334e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3357a982d89SJeremy L. Thompson } 3367a982d89SJeremy L. Thompson 3377a982d89SJeremy L. Thompson /** 338ca94c3ddSJeremy L Thompson @brief Get context data of a `CeedQFunction` 339441428dfSJeremy L Thompson 340ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 341ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 342ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 343441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 344441428dfSJeremy L Thompson 345441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 346441428dfSJeremy L Thompson 347441428dfSJeremy L Thompson @ref Backend 348441428dfSJeremy L Thompson **/ 3492b730f8bSJeremy L Thompson int CeedQFunctionGetContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 350441428dfSJeremy L Thompson bool is_writable; 351441428dfSJeremy L Thompson CeedQFunctionContext ctx; 352441428dfSJeremy L Thompson 3532b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 354441428dfSJeremy L Thompson if (ctx) { 3552b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 356441428dfSJeremy L Thompson if (is_writable) { 3572b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 358441428dfSJeremy L Thompson } else { 3592b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 360441428dfSJeremy L Thompson } 361441428dfSJeremy L Thompson } else { 362441428dfSJeremy L Thompson *(void **)data = NULL; 363441428dfSJeremy L Thompson } 364441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 365441428dfSJeremy L Thompson } 366441428dfSJeremy L Thompson 367441428dfSJeremy L Thompson /** 368ca94c3ddSJeremy L Thompson @brief Restore context data of a `CeedQFunction` 369441428dfSJeremy L Thompson 370ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 371ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 372441428dfSJeremy L Thompson 373441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 374441428dfSJeremy L Thompson 375441428dfSJeremy L Thompson @ref Backend 376441428dfSJeremy L Thompson **/ 377441428dfSJeremy L Thompson int CeedQFunctionRestoreContextData(CeedQFunction qf, void *data) { 378441428dfSJeremy L Thompson bool is_writable; 379441428dfSJeremy L Thompson CeedQFunctionContext ctx; 380441428dfSJeremy L Thompson 3812b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 382441428dfSJeremy L Thompson if (ctx) { 3832b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 384441428dfSJeremy L Thompson if (is_writable) { 3852b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 386441428dfSJeremy L Thompson } else { 3872b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 388441428dfSJeremy L Thompson } 389441428dfSJeremy L Thompson } 3905f249b39SJeremy L Thompson *(void **)data = NULL; 391441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 392441428dfSJeremy L Thompson } 393441428dfSJeremy L Thompson 394441428dfSJeremy L Thompson /** 395ca94c3ddSJeremy L Thompson @brief Get true user context for a `CeedQFunction` 3964385fb7fSSebastian Grimberg 397ca94c3ddSJeremy L Thompson Note: For all `CeedQFunction` this function will return the user `CeedQFunctionContext` and not interface context `CeedQFunctionContext`, if any such object exists. 3987a982d89SJeremy L. Thompson 399ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 400ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 4017a982d89SJeremy L. Thompson 4027a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4037a982d89SJeremy L. Thompson @ref Backend 4047a982d89SJeremy L. Thompson **/ 405777ff853SJeremy L Thompson int CeedQFunctionGetInnerContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 4061203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 4071203703bSJeremy L Thompson 4081203703bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &qf_ctx)); 409f04ea552SJeremy L Thompson if (qf->is_fortran) { 410d1d35e2fSjeremylt CeedFortranContext fortran_ctx = NULL; 4111c66c397SJeremy L Thompson 4121203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(qf_ctx, CEED_MEM_HOST, &fortran_ctx)); 4138cb0412aSJeremy L Thompson *ctx = fortran_ctx->inner_ctx; 414*9a25c351SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(qf_ctx, &fortran_ctx)); 4157a982d89SJeremy L. Thompson } else { 4161203703bSJeremy L Thompson *ctx = qf_ctx; 4177a982d89SJeremy L. Thompson } 418e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4197a982d89SJeremy L. Thompson } 4207a982d89SJeremy L. Thompson 4217a982d89SJeremy L. Thompson /** 422ca94c3ddSJeremy L Thompson @brief Get inner context data of a `CeedQFunction` 423441428dfSJeremy L Thompson 424ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 425ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 426ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 427441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 428441428dfSJeremy L Thompson 429441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 430441428dfSJeremy L Thompson 431441428dfSJeremy L Thompson @ref Backend 432441428dfSJeremy L Thompson **/ 4332b730f8bSJeremy L Thompson int CeedQFunctionGetInnerContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 434441428dfSJeremy L Thompson bool is_writable; 435441428dfSJeremy L Thompson CeedQFunctionContext ctx; 436441428dfSJeremy L Thompson 4372b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 438441428dfSJeremy L Thompson if (ctx) { 4392b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 440441428dfSJeremy L Thompson if (is_writable) { 4412b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 442441428dfSJeremy L Thompson } else { 4432b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 444441428dfSJeremy L Thompson } 445441428dfSJeremy L Thompson } else { 446441428dfSJeremy L Thompson *(void **)data = NULL; 447441428dfSJeremy L Thompson } 448441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 449441428dfSJeremy L Thompson } 450441428dfSJeremy L Thompson 451441428dfSJeremy L Thompson /** 452ca94c3ddSJeremy L Thompson @brief Restore inner context data of a `CeedQFunction` 453441428dfSJeremy L Thompson 454ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 455ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 456441428dfSJeremy L Thompson 457441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 458441428dfSJeremy L Thompson 459441428dfSJeremy L Thompson @ref Backend 460441428dfSJeremy L Thompson **/ 461441428dfSJeremy L Thompson int CeedQFunctionRestoreInnerContextData(CeedQFunction qf, void *data) { 462441428dfSJeremy L Thompson bool is_writable; 463441428dfSJeremy L Thompson CeedQFunctionContext ctx; 464441428dfSJeremy L Thompson 4652b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 466441428dfSJeremy L Thompson if (ctx) { 4672b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 468441428dfSJeremy L Thompson if (is_writable) { 4692b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 470441428dfSJeremy L Thompson } else { 4712b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 472441428dfSJeremy L Thompson } 473441428dfSJeremy L Thompson } 4745f249b39SJeremy L Thompson *(void **)data = NULL; 475441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 476441428dfSJeremy L Thompson } 477441428dfSJeremy L Thompson 478441428dfSJeremy L Thompson /** 479ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunction` is identity 4807a982d89SJeremy L. Thompson 481ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 482d1d35e2fSjeremylt @param[out] is_identity Variable to store identity status 4837a982d89SJeremy L. Thompson 4847a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4857a982d89SJeremy L. Thompson 4867a982d89SJeremy L. Thompson @ref Backend 4877a982d89SJeremy L. Thompson **/ 488d1d35e2fSjeremylt int CeedQFunctionIsIdentity(CeedQFunction qf, bool *is_identity) { 489f04ea552SJeremy L Thompson *is_identity = qf->is_identity; 490e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4917a982d89SJeremy L. Thompson } 4927a982d89SJeremy L. Thompson 4937a982d89SJeremy L. Thompson /** 494ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunctionContext` is writable 495441428dfSJeremy L Thompson 496ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 497ea61e9acSJeremy L Thompson @param[out] is_writable Variable to store context writeable status 498441428dfSJeremy L Thompson 499441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 500441428dfSJeremy L Thompson 501441428dfSJeremy L Thompson @ref Backend 502441428dfSJeremy L Thompson **/ 503441428dfSJeremy L Thompson int CeedQFunctionIsContextWritable(CeedQFunction qf, bool *is_writable) { 504441428dfSJeremy L Thompson *is_writable = qf->is_context_writable; 505441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 506441428dfSJeremy L Thompson } 507441428dfSJeremy L Thompson 508441428dfSJeremy L Thompson /** 509ca94c3ddSJeremy L Thompson @brief Get backend data of a `CeedQFunction` 5107a982d89SJeremy L. Thompson 511ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 5127a982d89SJeremy L. Thompson @param[out] data Variable to store data 5137a982d89SJeremy L. Thompson 5147a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5157a982d89SJeremy L. Thompson 5167a982d89SJeremy L. Thompson @ref Backend 5177a982d89SJeremy L. Thompson **/ 518777ff853SJeremy L Thompson int CeedQFunctionGetData(CeedQFunction qf, void *data) { 519777ff853SJeremy L Thompson *(void **)data = qf->data; 520e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5217a982d89SJeremy L. Thompson } 5227a982d89SJeremy L. Thompson 5237a982d89SJeremy L. Thompson /** 524ca94c3ddSJeremy L Thompson @brief Set backend data of a `CeedQFunction` 5257a982d89SJeremy L. Thompson 526ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 527ea61e9acSJeremy L Thompson @param[in] data Data to set 5287a982d89SJeremy L. Thompson 5297a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5307a982d89SJeremy L. Thompson 5317a982d89SJeremy L. Thompson @ref Backend 5327a982d89SJeremy L. Thompson **/ 533777ff853SJeremy L Thompson int CeedQFunctionSetData(CeedQFunction qf, void *data) { 534777ff853SJeremy L Thompson qf->data = data; 535e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5367a982d89SJeremy L. Thompson } 5377a982d89SJeremy L. Thompson 5387a982d89SJeremy L. Thompson /** 5391203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedQFunction` is immutable 5401203703bSJeremy L Thompson 5411203703bSJeremy L Thompson @param[in] qf `CeedOperator` 5421203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 5431203703bSJeremy L Thompson 5441203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5451203703bSJeremy L Thompson 5461203703bSJeremy L Thompson @ref Backend 5471203703bSJeremy L Thompson **/ 5481203703bSJeremy L Thompson int CeedQFunctionIsImmutable(CeedQFunction qf, bool *is_immutable) { 5491203703bSJeremy L Thompson *is_immutable = qf->is_immutable; 5501203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5511203703bSJeremy L Thompson } 5521203703bSJeremy L Thompson 5531203703bSJeremy L Thompson /** 5541203703bSJeremy L Thompson @brief Set the immutable flag of a `CeedQFunction` to `true` 5551203703bSJeremy L Thompson 5561203703bSJeremy L Thompson @param[in,out] qf `CeedQFunction` 5571203703bSJeremy L Thompson 5581203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5591203703bSJeremy L Thompson 5601203703bSJeremy L Thompson @ref Backend 5611203703bSJeremy L Thompson **/ 5621203703bSJeremy L Thompson int CeedQFunctionSetImmutable(CeedQFunction qf) { 5631203703bSJeremy L Thompson qf->is_immutable = true; 5641203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5651203703bSJeremy L Thompson } 5661203703bSJeremy L Thompson 5671203703bSJeremy L Thompson /** 568ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedQFunction` 56934359f16Sjeremylt 570ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to increment the reference counter 57134359f16Sjeremylt 57234359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 57334359f16Sjeremylt 57434359f16Sjeremylt @ref Backend 57534359f16Sjeremylt **/ 5769560d06aSjeremylt int CeedQFunctionReference(CeedQFunction qf) { 57734359f16Sjeremylt qf->ref_count++; 57834359f16Sjeremylt return CEED_ERROR_SUCCESS; 57934359f16Sjeremylt } 58034359f16Sjeremylt 5816e15d496SJeremy L Thompson /** 582ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs per quadrature required to apply `CeedQFunction` 5836e15d496SJeremy L Thompson 584ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 585ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5866e15d496SJeremy L Thompson 5876e15d496SJeremy L Thompson @ref Backend 5886e15d496SJeremy L Thompson **/ 5899d36ca50SJeremy L Thompson int CeedQFunctionGetFlopsEstimate(CeedQFunction qf, CeedSize *flops) { 5906e15d496SJeremy L Thompson *flops = qf->user_flop_estimate; 5916e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5926e15d496SJeremy L Thompson } 5936e15d496SJeremy L Thompson 5947a982d89SJeremy L. Thompson /// @} 5957a982d89SJeremy L. Thompson 5967a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5977a982d89SJeremy L. Thompson /// CeedQFunction Public API 5987a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5997a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 6007a982d89SJeremy L. Thompson /// @{ 6017a982d89SJeremy L. Thompson 6027a982d89SJeremy L. Thompson /** 603ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms 6047a982d89SJeremy L. Thompson 605ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 606ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 607ca94c3ddSJeremy L Thompson Caller must ensure that number of quadrature points is a multiple of `vec_length`. 608ea61e9acSJeremy L Thompson @param[in] f Function pointer to evaluate action at quadrature points. 609ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 610ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunctionUser`, "\abs_path\file.h:function_name". 611ca94c3ddSJeremy 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.). 6124ada38baSJames Wright The entire contents of this file and all locally included files are used during JiT compilation for GPU backends. 6134ada38baSJames Wright All source files must be at the provided filepath at runtime for JiT to function. 614ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 6157a982d89SJeremy L. Thompson 6167a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6177a982d89SJeremy L. Thompson 618ca94c3ddSJeremy L Thompson See \ref CeedQFunctionUser for details on the call-back function `f` arguments. 6197a982d89SJeremy L. Thompson 6207a982d89SJeremy L. Thompson @ref User 6217a982d89SJeremy L. Thompson **/ 6222b730f8bSJeremy L Thompson int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length, CeedQFunctionUser f, const char *source, CeedQFunction *qf) { 623ca5eadf8SJeremy L Thompson char *user_source_copy; 6247a982d89SJeremy L. Thompson 6257a982d89SJeremy L. Thompson if (!ceed->QFunctionCreate) { 6267a982d89SJeremy L. Thompson Ceed delegate; 6276574a04fSJeremy L Thompson 6282b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "QFunction")); 629ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionCreateInterior"); 6302b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(delegate, vec_length, f, source, qf)); 631e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6327a982d89SJeremy L. Thompson } 6337a982d89SJeremy L. Thompson 6346574a04fSJeremy L Thompson CeedCheck(!strlen(source) || strrchr(source, ':'), ceed, CEED_ERROR_INCOMPLETE, 6356574a04fSJeremy L Thompson "Provided path to source does not include function name. Provided: \"%s\"\nRequired: \"\\abs_path\\file.h:function_name\"", source); 63643e1b16fSJeremy L Thompson 6372b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, qf)); 638db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*qf)->ceed)); 639d1d35e2fSjeremylt (*qf)->ref_count = 1; 640d1d35e2fSjeremylt (*qf)->vec_length = vec_length; 641f04ea552SJeremy L Thompson (*qf)->is_identity = false; 642441428dfSJeremy L Thompson (*qf)->is_context_writable = true; 6437a982d89SJeremy L. Thompson (*qf)->function = f; 6446e15d496SJeremy L Thompson (*qf)->user_flop_estimate = -1; 64543e1b16fSJeremy L Thompson if (strlen(source)) { 646ca5eadf8SJeremy L Thompson size_t user_source_len = strlen(source); 647ee5a26f2SJeremy L Thompson 6482b730f8bSJeremy L Thompson CeedCall(CeedCalloc(user_source_len + 1, &user_source_copy)); 649ca5eadf8SJeremy L Thompson memcpy(user_source_copy, source, user_source_len); 650ca5eadf8SJeremy L Thompson (*qf)->user_source = user_source_copy; 65143e1b16fSJeremy L Thompson } 6522b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->input_fields)); 6532b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->output_fields)); 6542b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionCreate(*qf)); 655e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6567a982d89SJeremy L. Thompson } 6577a982d89SJeremy L. Thompson 6587a982d89SJeremy L. Thompson /** 659ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms by name 660288c0443SJeremy L Thompson 661ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 662ca94c3ddSJeremy L Thompson @param[in] name Name of `CeedQFunction` to use from gallery 663ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 664288c0443SJeremy L Thompson 665288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 666288c0443SJeremy L Thompson 6677a982d89SJeremy L. Thompson @ref User 668288c0443SJeremy L Thompson **/ 6692b730f8bSJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name, CeedQFunction *qf) { 670f7e22acaSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX; 671288c0443SJeremy L Thompson 6722b730f8bSJeremy L Thompson CeedCall(CeedQFunctionRegisterAll()); 673288c0443SJeremy L Thompson // Find matching backend 674ca94c3ddSJeremy L Thompson CeedCheck(name, ceed, CEED_ERROR_INCOMPLETE, "No CeedQFunction name provided"); 675288c0443SJeremy L Thompson for (size_t i = 0; i < num_qfunctions; i++) { 676288c0443SJeremy L Thompson size_t n; 677d1d35e2fSjeremylt const char *curr_name = gallery_qfunctions[i].name; 6782b730f8bSJeremy L Thompson for (n = 0; curr_name[n] && curr_name[n] == name[n]; n++) { 6792b730f8bSJeremy L Thompson } 680d1d35e2fSjeremylt if (n > match_len) { 681d1d35e2fSjeremylt match_len = n; 682f7e22acaSJeremy L Thompson match_index = i; 683288c0443SJeremy L Thompson } 684288c0443SJeremy L Thompson } 685ca94c3ddSJeremy L Thompson CeedCheck(match_len > 0, ceed, CEED_ERROR_UNSUPPORTED, "No suitable gallery CeedQFunction"); 686288c0443SJeremy L Thompson 687288c0443SJeremy L Thompson // Create QFunction 6882b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(ceed, gallery_qfunctions[match_index].vec_length, gallery_qfunctions[match_index].f, 6892b730f8bSJeremy L Thompson gallery_qfunctions[match_index].source, qf)); 690288c0443SJeremy L Thompson 691288c0443SJeremy L Thompson // QFunction specific setup 6922b730f8bSJeremy L Thompson CeedCall(gallery_qfunctions[match_index].init(ceed, name, *qf)); 693288c0443SJeremy L Thompson 69475affc3bSjeremylt // Copy name 6952b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(name, (char **)&(*qf)->gallery_name)); 69643e1b16fSJeremy L Thompson (*qf)->is_gallery = true; 697e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 698288c0443SJeremy L Thompson } 699288c0443SJeremy L Thompson 700288c0443SJeremy L Thompson /** 701ca94c3ddSJeremy L Thompson @brief Create an identity `CeedQFunction`. 7024385fb7fSSebastian Grimberg 703ea61e9acSJeremy L Thompson Inputs are written into outputs in the order given. 704ca94c3ddSJeremy 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. 705ca94c3ddSJeremy 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. 7060219ea01SJeremy L Thompson 707ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 708ca94c3ddSJeremy L Thompson @param[in] size Size of the `CeedQFunction` fields 709ca94c3ddSJeremy L Thompson @param[in] in_mode @ref CeedEvalMode for input to `CeedQFunction` 710ca94c3ddSJeremy L Thompson @param[in] out_mode @ref CeedEvalMode for output to `CeedQFunction` 711ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 7120219ea01SJeremy L Thompson 7130219ea01SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7140219ea01SJeremy L Thompson 7157a982d89SJeremy L. Thompson @ref User 7160219ea01SJeremy L Thompson **/ 7172b730f8bSJeremy L Thompson int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf) { 7181c66c397SJeremy L Thompson CeedQFunctionContext ctx; 7191c66c397SJeremy L Thompson CeedContextFieldLabel size_label; 7201c66c397SJeremy L Thompson 7212b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInteriorByName(ceed, "Identity", qf)); 7222b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddInput(*qf, "input", size, in_mode)); 7232b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddOutput(*qf, "output", size, out_mode)); 7240219ea01SJeremy L Thompson 725f04ea552SJeremy L Thompson (*qf)->is_identity = true; 726547dbd6fSJeremy L Thompson 7272b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(*qf, &ctx)); 7282b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, "size", &size_label)); 7292b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetInt32(ctx, size_label, &size)); 730e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7310219ea01SJeremy L Thompson } 7320219ea01SJeremy L Thompson 7330219ea01SJeremy L Thompson /** 734ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedQFunction`. 7354385fb7fSSebastian Grimberg 736ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedQFunctionDestroy(). 737512bb800SJeremy L Thompson 738ca94c3ddSJeremy 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`. 739ca94c3ddSJeremy L Thompson This `CeedQFunction` will be destroyed if `*qf_copy` is the only reference to this `CeedQFunction`. 7409560d06aSjeremylt 741ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to copy reference to 7429560d06aSjeremylt @param[out] qf_copy Variable to store copied reference 7439560d06aSjeremylt 7449560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7459560d06aSjeremylt 7469560d06aSjeremylt @ref User 7479560d06aSjeremylt **/ 7489560d06aSjeremylt int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy) { 7492b730f8bSJeremy L Thompson CeedCall(CeedQFunctionReference(qf)); 7502b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(qf_copy)); 7519560d06aSjeremylt *qf_copy = qf; 7529560d06aSjeremylt return CEED_ERROR_SUCCESS; 7539560d06aSjeremylt } 7549560d06aSjeremylt 7559560d06aSjeremylt /** 756ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` input 757b11c1e72Sjeremylt 758ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 759ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 760ca94c3ddSJeremy 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. 761ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 762ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 763ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 764ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 765ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 766b11c1e72Sjeremylt 767b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 768dfdf5a53Sjeremylt 7697a982d89SJeremy L. Thompson @ref User 770b11c1e72Sjeremylt **/ 7712b730f8bSJeremy L Thompson int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 7721203703bSJeremy L Thompson bool is_immutable; 7731203703bSJeremy L Thompson Ceed ceed; 7741203703bSJeremy L Thompson 7751203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 7761203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 7771203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "QFunction cannot be changed after set as immutable"); 7781203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT || size == 1, ceed, CEED_ERROR_DIMENSION, "CEED_EVAL_WEIGHT should have size 1"); 779643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 7801203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 781643fbb69SJeremy L Thompson } 782643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 7831203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 784643fbb69SJeremy L Thompson } 7852b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->input_fields[qf->num_input_fields], field_name, size, eval_mode)); 786d1d35e2fSjeremylt qf->num_input_fields++; 787e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 788d7b241e6Sjeremylt } 789d7b241e6Sjeremylt 790b11c1e72Sjeremylt /** 791ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` output 792b11c1e72Sjeremylt 793ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 794ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 795ca94c3ddSJeremy 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. 796ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 797ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 798ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 799ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 800ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl. 801b11c1e72Sjeremylt 802b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 803dfdf5a53Sjeremylt 8047a982d89SJeremy L. Thompson @ref User 805b11c1e72Sjeremylt **/ 8062b730f8bSJeremy L Thompson int CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 8071203703bSJeremy L Thompson bool is_immutable; 8081203703bSJeremy L Thompson Ceed ceed; 8091203703bSJeremy L Thompson 8101203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 8111203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 8121203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "CeedQFunction cannot be changed after set as immutable"); 8131203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT, ceed, CEED_ERROR_DIMENSION, "Cannot create CeedQFunction output with CEED_EVAL_WEIGHT"); 814643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 8151203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 816643fbb69SJeremy L Thompson } 817643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 8181203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 819643fbb69SJeremy L Thompson } 8202b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->output_fields[qf->num_output_fields], field_name, size, eval_mode)); 821d1d35e2fSjeremylt qf->num_output_fields++; 822e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 823d7b241e6Sjeremylt } 824d7b241e6Sjeremylt 825dfdf5a53Sjeremylt /** 826ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunctionField` of a `CeedQFunction` 82743bbe138SJeremy L Thompson 828ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 829f04ea552SJeremy L Thompson 830ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 831f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 832f74ec584SJeremy L Thompson @param[out] input_fields Variable to store input fields 833f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 834f74ec584SJeremy L Thompson @param[out] output_fields Variable to store output fields 83543bbe138SJeremy L Thompson 83643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83743bbe138SJeremy L Thompson 838e9b533fbSJeremy L Thompson @ref Advanced 83943bbe138SJeremy L Thompson **/ 8402b730f8bSJeremy L Thompson int CeedQFunctionGetFields(CeedQFunction qf, CeedInt *num_input_fields, CeedQFunctionField **input_fields, CeedInt *num_output_fields, 84143bbe138SJeremy L Thompson CeedQFunctionField **output_fields) { 8421203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 84343bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = qf->num_input_fields; 84443bbe138SJeremy L Thompson if (input_fields) *input_fields = qf->input_fields; 84543bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = qf->num_output_fields; 84643bbe138SJeremy L Thompson if (output_fields) *output_fields = qf->output_fields; 84743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84843bbe138SJeremy L Thompson } 84943bbe138SJeremy L Thompson 85043bbe138SJeremy L Thompson /** 851ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedQFunctionField` 85243bbe138SJeremy L Thompson 853ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 85443bbe138SJeremy L Thompson @param[out] field_name Variable to store the field name 85543bbe138SJeremy L Thompson 85643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85743bbe138SJeremy L Thompson 858e9b533fbSJeremy L Thompson @ref Advanced 85943bbe138SJeremy L Thompson **/ 8606f8994e9SJeremy L Thompson int CeedQFunctionFieldGetName(CeedQFunctionField qf_field, const char **field_name) { 8616f8994e9SJeremy L Thompson *field_name = qf_field->field_name; 86243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 86343bbe138SJeremy L Thompson } 86443bbe138SJeremy L Thompson 86543bbe138SJeremy L Thompson /** 866ca94c3ddSJeremy L Thompson @brief Get the number of components of a `CeedQFunctionField` 86743bbe138SJeremy L Thompson 868ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 86943bbe138SJeremy L Thompson @param[out] size Variable to store the size of the field 87043bbe138SJeremy L Thompson 87143bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87243bbe138SJeremy L Thompson 873e9b533fbSJeremy L Thompson @ref Advanced 87443bbe138SJeremy L Thompson **/ 87543bbe138SJeremy L Thompson int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field, CeedInt *size) { 87643bbe138SJeremy L Thompson *size = qf_field->size; 87743bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87843bbe138SJeremy L Thompson } 87943bbe138SJeremy L Thompson 88043bbe138SJeremy L Thompson /** 881ca94c3ddSJeremy L Thompson @brief Get the @ref CeedEvalMode of a `CeedQFunctionField` 88243bbe138SJeremy L Thompson 883ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 88443bbe138SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 88543bbe138SJeremy L Thompson 88643bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88743bbe138SJeremy L Thompson 888e9b533fbSJeremy L Thompson @ref Advanced 88943bbe138SJeremy L Thompson **/ 8902b730f8bSJeremy L Thompson int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field, CeedEvalMode *eval_mode) { 89143bbe138SJeremy L Thompson *eval_mode = qf_field->eval_mode; 89243bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 89343bbe138SJeremy L Thompson } 89443bbe138SJeremy L Thompson 89543bbe138SJeremy L Thompson /** 896ab747706SJeremy L Thompson @brief Get the data of a `CeedQFunctionField`. 897ab747706SJeremy L Thompson 898ab747706SJeremy L Thompson Any arguments set as `NULL` are ignored. 899ab747706SJeremy L Thompson 900ab747706SJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 901ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 902ab747706SJeremy L Thompson @param[out] size Variable to store the size of the field 903ab747706SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 904ab747706SJeremy L Thompson 905ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 906ab747706SJeremy L Thompson 907ab747706SJeremy L Thompson @ref Advanced 908ab747706SJeremy L Thompson **/ 9096f8994e9SJeremy L Thompson int CeedQFunctionFieldGetData(CeedQFunctionField qf_field, const char **field_name, CeedInt *size, CeedEvalMode *eval_mode) { 910ab747706SJeremy L Thompson if (field_name) CeedCall(CeedQFunctionFieldGetName(qf_field, field_name)); 911ab747706SJeremy L Thompson if (size) CeedCall(CeedQFunctionFieldGetSize(qf_field, size)); 912ab747706SJeremy L Thompson if (eval_mode) CeedCall(CeedQFunctionFieldGetEvalMode(qf_field, eval_mode)); 913ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 914ab747706SJeremy L Thompson } 915ab747706SJeremy L Thompson 916ab747706SJeremy L Thompson /** 917ca94c3ddSJeremy L Thompson @brief Set global context for a `CeedQFunction` 918b11c1e72Sjeremylt 919ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 920ea61e9acSJeremy L Thompson @param[in] ctx Context data to set 921b11c1e72Sjeremylt 922b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 923dfdf5a53Sjeremylt 9247a982d89SJeremy L. Thompson @ref User 925b11c1e72Sjeremylt **/ 926777ff853SJeremy L Thompson int CeedQFunctionSetContext(CeedQFunction qf, CeedQFunctionContext ctx) { 9272b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&qf->ctx)); 928d7b241e6Sjeremylt qf->ctx = ctx; 929db002c03SJeremy L Thompson if (ctx) CeedCall(CeedQFunctionContextReference(ctx)); 930e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 931d7b241e6Sjeremylt } 932d7b241e6Sjeremylt 933b11c1e72Sjeremylt /** 934ca94c3ddSJeremy L Thompson @brief Set writability of `CeedQFunctionContext` when calling the `CeedQFunctionUser`. 9354385fb7fSSebastian Grimberg 936859c15bbSJames Wright The default value is `is_writable == true`. 937441428dfSJeremy L Thompson 938ca94c3ddSJeremy L Thompson Setting `is_writable == true` indicates the `CeedQFunctionUser` writes into the `CeedQFunctionContext` and requires memory synchronization after calling @ref CeedQFunctionApply(). 939441428dfSJeremy L Thompson 940ca94c3ddSJeremy L Thompson Setting 'is_writable == false' asserts that `CeedQFunctionUser` does not modify the `CeedQFunctionContext`. 941ea61e9acSJeremy L Thompson Violating this assertion may lead to inconsistent data. 942441428dfSJeremy L Thompson 943441428dfSJeremy L Thompson Setting `is_writable == false` may offer a performance improvement on GPU backends. 944441428dfSJeremy L Thompson 945ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 946ca94c3ddSJeremy L Thompson @param[in] is_writable Boolean flag for writability status 947441428dfSJeremy L Thompson 948441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 949441428dfSJeremy L Thompson 950441428dfSJeremy L Thompson @ref User 951441428dfSJeremy L Thompson **/ 952441428dfSJeremy L Thompson int CeedQFunctionSetContextWritable(CeedQFunction qf, bool is_writable) { 953441428dfSJeremy L Thompson qf->is_context_writable = is_writable; 954441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 955441428dfSJeremy L Thompson } 956441428dfSJeremy L Thompson 957441428dfSJeremy L Thompson /** 958ca94c3ddSJeremy L Thompson @brief Set estimated number of FLOPs per quadrature required to apply `CeedQFunction` 9596e15d496SJeremy L Thompson 960ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 961ea61e9acSJeremy L Thompson @param[out] flops FLOPs per quadrature point estimate 9626e15d496SJeremy L Thompson 9636e15d496SJeremy L Thompson @ref Backend 9646e15d496SJeremy L Thompson **/ 9659d36ca50SJeremy L Thompson int CeedQFunctionSetUserFlopsEstimate(CeedQFunction qf, CeedSize flops) { 9661203703bSJeremy L Thompson Ceed ceed; 9671203703bSJeremy L Thompson 9681203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 9691203703bSJeremy L Thompson CeedCheck(flops >= 0, ceed, CEED_ERROR_INCOMPATIBLE, "Must set non-negative FLOPs estimate"); 9706e15d496SJeremy L Thompson qf->user_flop_estimate = flops; 9716e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 9726e15d496SJeremy L Thompson } 9736e15d496SJeremy L Thompson 9746e15d496SJeremy L Thompson /** 975ca94c3ddSJeremy L Thompson @brief View a `CeedQFunction` 97675affc3bSjeremylt 977ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to view 978ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 97975affc3bSjeremylt 98075affc3bSjeremylt @return Error code: 0 - success, otherwise - failure 98175affc3bSjeremylt 9827a982d89SJeremy L. Thompson @ref User 98375affc3bSjeremylt **/ 98475affc3bSjeremylt int CeedQFunctionView(CeedQFunction qf, FILE *stream) { 9857d023984SJeremy L Thompson const char *kernel_name; 98675affc3bSjeremylt 9872b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetKernelName(qf, &kernel_name)); 9882b730f8bSJeremy L Thompson fprintf(stream, "%sCeedQFunction - %s\n", qf->is_gallery ? "Gallery " : "User ", qf->is_gallery ? qf->gallery_name : kernel_name); 98975affc3bSjeremylt 9902b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " input field%s:\n", qf->num_input_fields, qf->num_input_fields > 1 ? "s" : ""); 991d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_input_fields; i++) { 9922b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->input_fields[i], i, 1, stream)); 99375affc3bSjeremylt } 99475affc3bSjeremylt 9952b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " output field%s:\n", qf->num_output_fields, qf->num_output_fields > 1 ? "s" : ""); 996d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_output_fields; i++) { 9972b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->output_fields[i], i, 0, stream)); 99875affc3bSjeremylt } 999e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 100075affc3bSjeremylt } 100175affc3bSjeremylt 100275affc3bSjeremylt /** 1003ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedQFunction` 1004b7c9bbdaSJeremy L Thompson 1005ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 1006ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store`Ceed` 1007b7c9bbdaSJeremy L Thompson 1008b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1009b7c9bbdaSJeremy L Thompson 1010b7c9bbdaSJeremy L Thompson @ref Advanced 1011b7c9bbdaSJeremy L Thompson **/ 1012b7c9bbdaSJeremy L Thompson int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 1013b7c9bbdaSJeremy L Thompson *ceed = qf->ceed; 1014b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1015b7c9bbdaSJeremy L Thompson } 1016b7c9bbdaSJeremy L Thompson 1017b7c9bbdaSJeremy L Thompson /** 1018ca94c3ddSJeremy L Thompson @brief Apply the action of a `CeedQFunction` 1019b11c1e72Sjeremylt 1020ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 1021f04ea552SJeremy L Thompson 1022ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 1023ea61e9acSJeremy L Thompson @param[in] Q Number of quadrature points 1024ca94c3ddSJeremy L Thompson @param[in] u Array of input `CeedVector` 1025ca94c3ddSJeremy L Thompson @param[out] v Array of output `CeedVector` 1026b11c1e72Sjeremylt 1027b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1028dfdf5a53Sjeremylt 10297a982d89SJeremy L. Thompson @ref User 1030b11c1e72Sjeremylt **/ 10312b730f8bSJeremy L Thompson int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, CeedVector *u, CeedVector *v) { 10321203703bSJeremy L Thompson CeedInt vec_length; 10331203703bSJeremy L Thompson Ceed ceed; 10341203703bSJeremy L Thompson 10351203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 10361203703bSJeremy L Thompson CeedCheck(qf->Apply, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionApply"); 10371203703bSJeremy L Thompson CeedCall(CeedQFunctionGetVectorLength(qf, &vec_length)); 10381203703bSJeremy 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, 10391203703bSJeremy L Thompson qf->vec_length); 10401203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 10412b730f8bSJeremy L Thompson CeedCall(qf->Apply(qf, Q, u, v)); 1042e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1043d7b241e6Sjeremylt } 1044d7b241e6Sjeremylt 1045b11c1e72Sjeremylt /** 1046ca94c3ddSJeremy L Thompson @brief Destroy a `CeedQFunction` 1047b11c1e72Sjeremylt 1048ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to destroy 1049b11c1e72Sjeremylt 1050b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1051dfdf5a53Sjeremylt 10527a982d89SJeremy L. Thompson @ref User 1053b11c1e72Sjeremylt **/ 1054d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) { 1055ad6481ceSJeremy L Thompson if (!*qf || --(*qf)->ref_count > 0) { 1056ad6481ceSJeremy L Thompson *qf = NULL; 1057ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1058ad6481ceSJeremy L Thompson } 1059fe2413ffSjeremylt // Backend destroy 1060d7b241e6Sjeremylt if ((*qf)->Destroy) { 10612b730f8bSJeremy L Thompson CeedCall((*qf)->Destroy(*qf)); 1062d7b241e6Sjeremylt } 1063fe2413ffSjeremylt // Free fields 106492ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_input_fields; i++) { 10652b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->input_fields[i]).field_name)); 10662b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields[i])); 1067fe2413ffSjeremylt } 106892ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_output_fields; i++) { 10692b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->output_fields[i]).field_name)); 10702b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields[i])); 1071fe2413ffSjeremylt } 10722b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields)); 10732b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields)); 1074777ff853SJeremy L Thompson 1075777ff853SJeremy L Thompson // User context data object 10762b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&(*qf)->ctx)); 1077fe2413ffSjeremylt 10782b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->user_source)); 10792b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->source_path)); 10802b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->gallery_name)); 10812b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->kernel_name)); 10822b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*qf)->ceed)); 10832b730f8bSJeremy L Thompson CeedCall(CeedFree(qf)); 1084e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1085d7b241e6Sjeremylt } 1086d7b241e6Sjeremylt 1087d7b241e6Sjeremylt /// @} 1088