1*5aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, 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 char *kernel_name_copy; 212ca5eadf8SJeremy L Thompson 213ca5eadf8SJeremy L Thompson if (qf->user_source) { 214ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 215ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 216ca5eadf8SJeremy L Thompson 2172b730f8bSJeremy L Thompson CeedCall(CeedCalloc(kernel_name_len + 1, &kernel_name_copy)); 218ca5eadf8SJeremy L Thompson memcpy(kernel_name_copy, kernel_name, kernel_name_len); 219ca5eadf8SJeremy L Thompson } else { 2202b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &kernel_name_copy)); 221ca5eadf8SJeremy L Thompson } 222ca5eadf8SJeremy L Thompson qf->kernel_name = kernel_name_copy; 223ca5eadf8SJeremy L Thompson } 224ca5eadf8SJeremy L Thompson 2257d023984SJeremy L Thompson *kernel_name = qf->kernel_name; 22643e1b16fSJeremy L Thompson return CEED_ERROR_SUCCESS; 22743e1b16fSJeremy L Thompson } 22843e1b16fSJeremy L Thompson 22943e1b16fSJeremy L Thompson /** 230ca94c3ddSJeremy L Thompson @brief Get the source path string for a `CeedQFunction` 23143e1b16fSJeremy L Thompson 232ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 23343e1b16fSJeremy L Thompson @param[out] source_path Variable to store source path string 23443e1b16fSJeremy L Thompson 23543e1b16fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23643e1b16fSJeremy L Thompson 23743e1b16fSJeremy L Thompson @ref Backend 23843e1b16fSJeremy L Thompson **/ 23934ffed21SJeremy L Thompson int CeedQFunctionGetSourcePath(CeedQFunction qf, const char **source_path) { 240ca5eadf8SJeremy L Thompson if (!qf->source_path && qf->user_source) { 241ca5eadf8SJeremy L Thompson Ceed ceed; 242ca5eadf8SJeremy L Thompson bool is_absolute_path; 24322070f95SJeremy L Thompson char *source_path_copy; 24422070f95SJeremy L Thompson const char *absolute_path; 245ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 246ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 247ca5eadf8SJeremy L Thompson 2482b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 2492b730f8bSJeremy L Thompson CeedCall(CeedCheckFilePath(ceed, qf->user_source, &is_absolute_path)); 250ca5eadf8SJeremy L Thompson if (is_absolute_path) { 251ca5eadf8SJeremy L Thompson absolute_path = (char *)qf->user_source; 252ca5eadf8SJeremy L Thompson } else { 2532b730f8bSJeremy L Thompson CeedCall(CeedGetJitAbsolutePath(ceed, qf->user_source, &absolute_path)); 254ca5eadf8SJeremy L Thompson } 255ca5eadf8SJeremy L Thompson 256ca5eadf8SJeremy L Thompson size_t source_len = strlen(absolute_path) - kernel_name_len - 1; 2571c66c397SJeremy L Thompson 2582b730f8bSJeremy L Thompson CeedCall(CeedCalloc(source_len + 1, &source_path_copy)); 259ca5eadf8SJeremy L Thompson memcpy(source_path_copy, absolute_path, source_len); 260ca5eadf8SJeremy L Thompson qf->source_path = source_path_copy; 261ca5eadf8SJeremy L Thompson 2622b730f8bSJeremy L Thompson if (!is_absolute_path) CeedCall(CeedFree(&absolute_path)); 263ca5eadf8SJeremy L Thompson } 264ca5eadf8SJeremy L Thompson 26543e1b16fSJeremy L Thompson *source_path = (char *)qf->source_path; 266e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2677a982d89SJeremy L. Thompson } 2687a982d89SJeremy L. Thompson 2697a982d89SJeremy L. Thompson /** 270ca94c3ddSJeremy L Thompson @brief Initialize and load `CeedQFunction` source file into string buffer, including full text of local files in place of `#include "local.h"`. 2714385fb7fSSebastian Grimberg 272ca94c3ddSJeremy L Thompson The `buffer` is set to `NULL` if there is no `CeedQFunction` source file. 2734385fb7fSSebastian Grimberg 274f8d308faSJed Brown Note: This function may as well return a mutable buffer, but all current uses 275f8d308faSJed Brown do not modify it. (This is just a downside of `const` semantics with output 276f8d308faSJed Brown arguments instead of returns.) 277f8d308faSJed Brown 278ca94c3ddSJeremy L Thompson Note: Caller is responsible for freeing the string buffer with @ref CeedFree(). 2793d3250a0SJeremy L Thompson 280ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 281f74ec584SJeremy L Thompson @param[out] source_buffer String buffer for source file contents 2823d3250a0SJeremy L Thompson 2833d3250a0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2843d3250a0SJeremy L Thompson 2853d3250a0SJeremy L Thompson @ref Backend 2863d3250a0SJeremy L Thompson **/ 287f8d308faSJed Brown int CeedQFunctionLoadSourceToBuffer(CeedQFunction qf, const char **source_buffer) { 28834ffed21SJeremy L Thompson const char *source_path; 2893d3250a0SJeremy L Thompson 2902b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetSourcePath(qf, &source_path)); 2913d3250a0SJeremy L Thompson *source_buffer = NULL; 2923d3250a0SJeremy L Thompson if (source_path) { 2931203703bSJeremy L Thompson Ceed ceed; 294f8d308faSJed Brown char *buffer = NULL; 2951203703bSJeremy L Thompson 2961203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 297f8d308faSJed Brown CeedCall(CeedLoadSourceToBuffer(ceed, source_path, &buffer)); 298f8d308faSJed Brown *source_buffer = buffer; 2993d3250a0SJeremy L Thompson } 3003d3250a0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3013d3250a0SJeremy L Thompson } 3023d3250a0SJeremy L Thompson 3033d3250a0SJeremy L Thompson /** 304ca94c3ddSJeremy L Thompson @brief Get the User Function for a `CeedQFunction` 3057a982d89SJeremy L. Thompson 306ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 3077a982d89SJeremy L. Thompson @param[out] f Variable to store user function 3087a982d89SJeremy L. Thompson 3097a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3107a982d89SJeremy L. Thompson 3117a982d89SJeremy L. Thompson @ref Backend 3127a982d89SJeremy L. Thompson **/ 3137a982d89SJeremy L. Thompson int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) { 3147a982d89SJeremy L. Thompson *f = qf->function; 315e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3167a982d89SJeremy L. Thompson } 3177a982d89SJeremy L. Thompson 3187a982d89SJeremy L. Thompson /** 319ca94c3ddSJeremy L Thompson @brief Get global context for a `CeedQFunction`. 3204385fb7fSSebastian Grimberg 321ca94c3ddSJeremy L Thompson Note: For `CeedQFunction` from the Fortran interface, this function will return the Fortran context `CeedQFunctionContext`. 3227a982d89SJeremy L. Thompson 323ea61e9acSJeremy L Thompson @param[in] qf CeedQFunction 324777ff853SJeremy L Thompson @param[out] ctx Variable to store CeedQFunctionContext 3257a982d89SJeremy L. Thompson 3267a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3277a982d89SJeremy L. Thompson 3287a982d89SJeremy L. Thompson @ref Backend 3297a982d89SJeremy L. Thompson **/ 330777ff853SJeremy L Thompson int CeedQFunctionGetContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 3317a982d89SJeremy L. Thompson *ctx = qf->ctx; 332e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3337a982d89SJeremy L. Thompson } 3347a982d89SJeremy L. Thompson 3357a982d89SJeremy L. Thompson /** 336ca94c3ddSJeremy L Thompson @brief Get context data of a `CeedQFunction` 337441428dfSJeremy L Thompson 338ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 339ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 340ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 341441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 342441428dfSJeremy L Thompson 343441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 344441428dfSJeremy L Thompson 345441428dfSJeremy L Thompson @ref Backend 346441428dfSJeremy L Thompson **/ 3472b730f8bSJeremy L Thompson int CeedQFunctionGetContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 348441428dfSJeremy L Thompson bool is_writable; 349441428dfSJeremy L Thompson CeedQFunctionContext ctx; 350441428dfSJeremy L Thompson 3512b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 352441428dfSJeremy L Thompson if (ctx) { 3532b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 354441428dfSJeremy L Thompson if (is_writable) { 3552b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 356441428dfSJeremy L Thompson } else { 3572b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 358441428dfSJeremy L Thompson } 359441428dfSJeremy L Thompson } else { 360441428dfSJeremy L Thompson *(void **)data = NULL; 361441428dfSJeremy L Thompson } 362441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 363441428dfSJeremy L Thompson } 364441428dfSJeremy L Thompson 365441428dfSJeremy L Thompson /** 366ca94c3ddSJeremy L Thompson @brief Restore context data of a `CeedQFunction` 367441428dfSJeremy L Thompson 368ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 369ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 370441428dfSJeremy L Thompson 371441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 372441428dfSJeremy L Thompson 373441428dfSJeremy L Thompson @ref Backend 374441428dfSJeremy L Thompson **/ 375441428dfSJeremy L Thompson int CeedQFunctionRestoreContextData(CeedQFunction qf, void *data) { 376441428dfSJeremy L Thompson bool is_writable; 377441428dfSJeremy L Thompson CeedQFunctionContext ctx; 378441428dfSJeremy L Thompson 3792b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 380441428dfSJeremy L Thompson if (ctx) { 3812b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 382441428dfSJeremy L Thompson if (is_writable) { 3832b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 384441428dfSJeremy L Thompson } else { 3852b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 386441428dfSJeremy L Thompson } 387441428dfSJeremy L Thompson } 3885f249b39SJeremy L Thompson *(void **)data = NULL; 389441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 390441428dfSJeremy L Thompson } 391441428dfSJeremy L Thompson 392441428dfSJeremy L Thompson /** 393ca94c3ddSJeremy L Thompson @brief Get true user context for a `CeedQFunction` 3944385fb7fSSebastian Grimberg 395ca94c3ddSJeremy L Thompson Note: For all `CeedQFunction` this function will return the user `CeedQFunctionContext` and not interface context `CeedQFunctionContext`, if any such object exists. 3967a982d89SJeremy L. Thompson 397ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 398ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 3997a982d89SJeremy L. Thompson 4007a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4017a982d89SJeremy L. Thompson @ref Backend 4027a982d89SJeremy L. Thompson **/ 403777ff853SJeremy L Thompson int CeedQFunctionGetInnerContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 4041203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 4051203703bSJeremy L Thompson 4061203703bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &qf_ctx)); 407f04ea552SJeremy L Thompson if (qf->is_fortran) { 408d1d35e2fSjeremylt CeedFortranContext fortran_ctx = NULL; 4091c66c397SJeremy L Thompson 4101203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(qf_ctx, CEED_MEM_HOST, &fortran_ctx)); 4118cb0412aSJeremy L Thompson *ctx = fortran_ctx->inner_ctx; 4129a25c351SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(qf_ctx, &fortran_ctx)); 4137a982d89SJeremy L. Thompson } else { 4141203703bSJeremy L Thompson *ctx = qf_ctx; 4157a982d89SJeremy L. Thompson } 416e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4177a982d89SJeremy L. Thompson } 4187a982d89SJeremy L. Thompson 4197a982d89SJeremy L. Thompson /** 420ca94c3ddSJeremy L Thompson @brief Get inner context data of a `CeedQFunction` 421441428dfSJeremy L Thompson 422ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 423ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 424ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 425441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 426441428dfSJeremy L Thompson 427441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 428441428dfSJeremy L Thompson 429441428dfSJeremy L Thompson @ref Backend 430441428dfSJeremy L Thompson **/ 4312b730f8bSJeremy L Thompson int CeedQFunctionGetInnerContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 432441428dfSJeremy L Thompson bool is_writable; 433441428dfSJeremy L Thompson CeedQFunctionContext ctx; 434441428dfSJeremy L Thompson 4352b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 436441428dfSJeremy L Thompson if (ctx) { 4372b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 438441428dfSJeremy L Thompson if (is_writable) { 4392b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 440441428dfSJeremy L Thompson } else { 4412b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 442441428dfSJeremy L Thompson } 443441428dfSJeremy L Thompson } else { 444441428dfSJeremy L Thompson *(void **)data = NULL; 445441428dfSJeremy L Thompson } 446441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 447441428dfSJeremy L Thompson } 448441428dfSJeremy L Thompson 449441428dfSJeremy L Thompson /** 450ca94c3ddSJeremy L Thompson @brief Restore inner context data of a `CeedQFunction` 451441428dfSJeremy L Thompson 452ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 453ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 454441428dfSJeremy L Thompson 455441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 456441428dfSJeremy L Thompson 457441428dfSJeremy L Thompson @ref Backend 458441428dfSJeremy L Thompson **/ 459441428dfSJeremy L Thompson int CeedQFunctionRestoreInnerContextData(CeedQFunction qf, void *data) { 460441428dfSJeremy L Thompson bool is_writable; 461441428dfSJeremy L Thompson CeedQFunctionContext ctx; 462441428dfSJeremy L Thompson 4632b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 464441428dfSJeremy L Thompson if (ctx) { 4652b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 466441428dfSJeremy L Thompson if (is_writable) { 4672b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 468441428dfSJeremy L Thompson } else { 4692b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 470441428dfSJeremy L Thompson } 471441428dfSJeremy L Thompson } 4725f249b39SJeremy L Thompson *(void **)data = NULL; 473441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 474441428dfSJeremy L Thompson } 475441428dfSJeremy L Thompson 476441428dfSJeremy L Thompson /** 477ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunction` is identity 4787a982d89SJeremy L. Thompson 479ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 480d1d35e2fSjeremylt @param[out] is_identity Variable to store identity status 4817a982d89SJeremy L. Thompson 4827a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4837a982d89SJeremy L. Thompson 4847a982d89SJeremy L. Thompson @ref Backend 4857a982d89SJeremy L. Thompson **/ 486d1d35e2fSjeremylt int CeedQFunctionIsIdentity(CeedQFunction qf, bool *is_identity) { 487f04ea552SJeremy L Thompson *is_identity = qf->is_identity; 488e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4897a982d89SJeremy L. Thompson } 4907a982d89SJeremy L. Thompson 4917a982d89SJeremy L. Thompson /** 492ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunctionContext` is writable 493441428dfSJeremy L Thompson 494ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 495ea61e9acSJeremy L Thompson @param[out] is_writable Variable to store context writeable status 496441428dfSJeremy L Thompson 497441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 498441428dfSJeremy L Thompson 499441428dfSJeremy L Thompson @ref Backend 500441428dfSJeremy L Thompson **/ 501441428dfSJeremy L Thompson int CeedQFunctionIsContextWritable(CeedQFunction qf, bool *is_writable) { 502441428dfSJeremy L Thompson *is_writable = qf->is_context_writable; 503441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 504441428dfSJeremy L Thompson } 505441428dfSJeremy L Thompson 506441428dfSJeremy L Thompson /** 507ca94c3ddSJeremy L Thompson @brief Get backend data of a `CeedQFunction` 5087a982d89SJeremy L. Thompson 509ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 5107a982d89SJeremy L. Thompson @param[out] data Variable to store data 5117a982d89SJeremy L. Thompson 5127a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5137a982d89SJeremy L. Thompson 5147a982d89SJeremy L. Thompson @ref Backend 5157a982d89SJeremy L. Thompson **/ 516777ff853SJeremy L Thompson int CeedQFunctionGetData(CeedQFunction qf, void *data) { 517777ff853SJeremy L Thompson *(void **)data = qf->data; 518e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5197a982d89SJeremy L. Thompson } 5207a982d89SJeremy L. Thompson 5217a982d89SJeremy L. Thompson /** 522ca94c3ddSJeremy L Thompson @brief Set backend data of a `CeedQFunction` 5237a982d89SJeremy L. Thompson 524ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 525ea61e9acSJeremy L Thompson @param[in] data Data to set 5267a982d89SJeremy L. Thompson 5277a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5287a982d89SJeremy L. Thompson 5297a982d89SJeremy L. Thompson @ref Backend 5307a982d89SJeremy L. Thompson **/ 531777ff853SJeremy L Thompson int CeedQFunctionSetData(CeedQFunction qf, void *data) { 532777ff853SJeremy L Thompson qf->data = data; 533e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5347a982d89SJeremy L. Thompson } 5357a982d89SJeremy L. Thompson 5367a982d89SJeremy L. Thompson /** 5371203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedQFunction` is immutable 5381203703bSJeremy L Thompson 5391203703bSJeremy L Thompson @param[in] qf `CeedOperator` 5401203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 5411203703bSJeremy L Thompson 5421203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5431203703bSJeremy L Thompson 5441203703bSJeremy L Thompson @ref Backend 5451203703bSJeremy L Thompson **/ 5461203703bSJeremy L Thompson int CeedQFunctionIsImmutable(CeedQFunction qf, bool *is_immutable) { 5471203703bSJeremy L Thompson *is_immutable = qf->is_immutable; 5481203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5491203703bSJeremy L Thompson } 5501203703bSJeremy L Thompson 5511203703bSJeremy L Thompson /** 5521203703bSJeremy L Thompson @brief Set the immutable flag of a `CeedQFunction` to `true` 5531203703bSJeremy L Thompson 5541203703bSJeremy L Thompson @param[in,out] qf `CeedQFunction` 5551203703bSJeremy L Thompson 5561203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5571203703bSJeremy L Thompson 5581203703bSJeremy L Thompson @ref Backend 5591203703bSJeremy L Thompson **/ 5601203703bSJeremy L Thompson int CeedQFunctionSetImmutable(CeedQFunction qf) { 5611203703bSJeremy L Thompson qf->is_immutable = true; 5621203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5631203703bSJeremy L Thompson } 5641203703bSJeremy L Thompson 5651203703bSJeremy L Thompson /** 566ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedQFunction` 56734359f16Sjeremylt 568ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to increment the reference counter 56934359f16Sjeremylt 57034359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 57134359f16Sjeremylt 57234359f16Sjeremylt @ref Backend 57334359f16Sjeremylt **/ 5749560d06aSjeremylt int CeedQFunctionReference(CeedQFunction qf) { 57534359f16Sjeremylt qf->ref_count++; 57634359f16Sjeremylt return CEED_ERROR_SUCCESS; 57734359f16Sjeremylt } 57834359f16Sjeremylt 5796e15d496SJeremy L Thompson /** 580ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs per quadrature required to apply `CeedQFunction` 5816e15d496SJeremy L Thompson 582ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 583ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5846e15d496SJeremy L Thompson 5856e15d496SJeremy L Thompson @ref Backend 5866e15d496SJeremy L Thompson **/ 5879d36ca50SJeremy L Thompson int CeedQFunctionGetFlopsEstimate(CeedQFunction qf, CeedSize *flops) { 5886e15d496SJeremy L Thompson *flops = qf->user_flop_estimate; 5896e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5906e15d496SJeremy L Thompson } 5916e15d496SJeremy L Thompson 5927a982d89SJeremy L. Thompson /// @} 5937a982d89SJeremy L. Thompson 5947a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5957a982d89SJeremy L. Thompson /// CeedQFunction Public API 5967a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5977a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 5987a982d89SJeremy L. Thompson /// @{ 5997a982d89SJeremy L. Thompson 6007a982d89SJeremy L. Thompson /** 601ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms 6027a982d89SJeremy L. Thompson 603ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 604ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 605ca94c3ddSJeremy L Thompson Caller must ensure that number of quadrature points is a multiple of `vec_length`. 606ea61e9acSJeremy L Thompson @param[in] f Function pointer to evaluate action at quadrature points. 607ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 608ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunctionUser`, "\abs_path\file.h:function_name". 609ca94c3ddSJeremy 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.). 6104ada38baSJames Wright The entire contents of this file and all locally included files are used during JiT compilation for GPU backends. 6114ada38baSJames Wright All source files must be at the provided filepath at runtime for JiT to function. 612ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 6137a982d89SJeremy L. Thompson 6147a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6157a982d89SJeremy L. Thompson 616ca94c3ddSJeremy L Thompson See \ref CeedQFunctionUser for details on the call-back function `f` arguments. 6177a982d89SJeremy L. Thompson 6187a982d89SJeremy L. Thompson @ref User 6197a982d89SJeremy L. Thompson **/ 6202b730f8bSJeremy L Thompson int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length, CeedQFunctionUser f, const char *source, CeedQFunction *qf) { 621ca5eadf8SJeremy L Thompson char *user_source_copy; 6227a982d89SJeremy L. Thompson 6237a982d89SJeremy L. Thompson if (!ceed->QFunctionCreate) { 6247a982d89SJeremy L. Thompson Ceed delegate; 6256574a04fSJeremy L Thompson 6262b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "QFunction")); 627ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionCreateInterior"); 6282b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(delegate, vec_length, f, source, qf)); 629e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6307a982d89SJeremy L. Thompson } 6317a982d89SJeremy L. Thompson 6326574a04fSJeremy L Thompson CeedCheck(!strlen(source) || strrchr(source, ':'), ceed, CEED_ERROR_INCOMPLETE, 6336574a04fSJeremy L Thompson "Provided path to source does not include function name. Provided: \"%s\"\nRequired: \"\\abs_path\\file.h:function_name\"", source); 63443e1b16fSJeremy L Thompson 6352b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, qf)); 636db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*qf)->ceed)); 637d1d35e2fSjeremylt (*qf)->ref_count = 1; 638d1d35e2fSjeremylt (*qf)->vec_length = vec_length; 639f04ea552SJeremy L Thompson (*qf)->is_identity = false; 640441428dfSJeremy L Thompson (*qf)->is_context_writable = true; 6417a982d89SJeremy L. Thompson (*qf)->function = f; 6426e15d496SJeremy L Thompson (*qf)->user_flop_estimate = -1; 64343e1b16fSJeremy L Thompson if (strlen(source)) { 644ca5eadf8SJeremy L Thompson size_t user_source_len = strlen(source); 645ee5a26f2SJeremy L Thompson 6462b730f8bSJeremy L Thompson CeedCall(CeedCalloc(user_source_len + 1, &user_source_copy)); 647ca5eadf8SJeremy L Thompson memcpy(user_source_copy, source, user_source_len); 648ca5eadf8SJeremy L Thompson (*qf)->user_source = user_source_copy; 64943e1b16fSJeremy L Thompson } 6502b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->input_fields)); 6512b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->output_fields)); 6522b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionCreate(*qf)); 653e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6547a982d89SJeremy L. Thompson } 6557a982d89SJeremy L. Thompson 6567a982d89SJeremy L. Thompson /** 657ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms by name 658288c0443SJeremy L Thompson 659ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 660ca94c3ddSJeremy L Thompson @param[in] name Name of `CeedQFunction` to use from gallery 661ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 662288c0443SJeremy L Thompson 663288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 664288c0443SJeremy L Thompson 6657a982d89SJeremy L. Thompson @ref User 666288c0443SJeremy L Thompson **/ 6672b730f8bSJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name, CeedQFunction *qf) { 668f7e22acaSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX; 669288c0443SJeremy L Thompson 6702b730f8bSJeremy L Thompson CeedCall(CeedQFunctionRegisterAll()); 671288c0443SJeremy L Thompson // Find matching backend 672ca94c3ddSJeremy L Thompson CeedCheck(name, ceed, CEED_ERROR_INCOMPLETE, "No CeedQFunction name provided"); 673288c0443SJeremy L Thompson for (size_t i = 0; i < num_qfunctions; i++) { 674288c0443SJeremy L Thompson size_t n; 675d1d35e2fSjeremylt const char *curr_name = gallery_qfunctions[i].name; 6762b730f8bSJeremy L Thompson for (n = 0; curr_name[n] && curr_name[n] == name[n]; n++) { 6772b730f8bSJeremy L Thompson } 678d1d35e2fSjeremylt if (n > match_len) { 679d1d35e2fSjeremylt match_len = n; 680f7e22acaSJeremy L Thompson match_index = i; 681288c0443SJeremy L Thompson } 682288c0443SJeremy L Thompson } 683ca94c3ddSJeremy L Thompson CeedCheck(match_len > 0, ceed, CEED_ERROR_UNSUPPORTED, "No suitable gallery CeedQFunction"); 684288c0443SJeremy L Thompson 685288c0443SJeremy L Thompson // Create QFunction 6862b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(ceed, gallery_qfunctions[match_index].vec_length, gallery_qfunctions[match_index].f, 6872b730f8bSJeremy L Thompson gallery_qfunctions[match_index].source, qf)); 688288c0443SJeremy L Thompson 689288c0443SJeremy L Thompson // QFunction specific setup 6902b730f8bSJeremy L Thompson CeedCall(gallery_qfunctions[match_index].init(ceed, name, *qf)); 691288c0443SJeremy L Thompson 69275affc3bSjeremylt // Copy name 6932b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(name, (char **)&(*qf)->gallery_name)); 69443e1b16fSJeremy L Thompson (*qf)->is_gallery = true; 695e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 696288c0443SJeremy L Thompson } 697288c0443SJeremy L Thompson 698288c0443SJeremy L Thompson /** 699ca94c3ddSJeremy L Thompson @brief Create an identity `CeedQFunction`. 7004385fb7fSSebastian Grimberg 701ea61e9acSJeremy L Thompson Inputs are written into outputs in the order given. 702ca94c3ddSJeremy 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. 703ca94c3ddSJeremy 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. 7040219ea01SJeremy L Thompson 705ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 706ca94c3ddSJeremy L Thompson @param[in] size Size of the `CeedQFunction` fields 707ca94c3ddSJeremy L Thompson @param[in] in_mode @ref CeedEvalMode for input to `CeedQFunction` 708ca94c3ddSJeremy L Thompson @param[in] out_mode @ref CeedEvalMode for output to `CeedQFunction` 709ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 7100219ea01SJeremy L Thompson 7110219ea01SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7120219ea01SJeremy L Thompson 7137a982d89SJeremy L. Thompson @ref User 7140219ea01SJeremy L Thompson **/ 7152b730f8bSJeremy L Thompson int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf) { 7161c66c397SJeremy L Thompson CeedQFunctionContext ctx; 7171c66c397SJeremy L Thompson CeedContextFieldLabel size_label; 7181c66c397SJeremy L Thompson 7192b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInteriorByName(ceed, "Identity", qf)); 7202b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddInput(*qf, "input", size, in_mode)); 7212b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddOutput(*qf, "output", size, out_mode)); 7220219ea01SJeremy L Thompson 723f04ea552SJeremy L Thompson (*qf)->is_identity = true; 724547dbd6fSJeremy L Thompson 7252b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(*qf, &ctx)); 7262b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, "size", &size_label)); 7272b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetInt32(ctx, size_label, &size)); 728e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7290219ea01SJeremy L Thompson } 7300219ea01SJeremy L Thompson 7310219ea01SJeremy L Thompson /** 732ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedQFunction`. 7334385fb7fSSebastian Grimberg 734ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedQFunctionDestroy(). 735512bb800SJeremy L Thompson 736ca94c3ddSJeremy 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`. 737ca94c3ddSJeremy L Thompson This `CeedQFunction` will be destroyed if `*qf_copy` is the only reference to this `CeedQFunction`. 7389560d06aSjeremylt 739ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to copy reference to 7409560d06aSjeremylt @param[out] qf_copy Variable to store copied reference 7419560d06aSjeremylt 7429560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7439560d06aSjeremylt 7449560d06aSjeremylt @ref User 7459560d06aSjeremylt **/ 7469560d06aSjeremylt int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy) { 7472b730f8bSJeremy L Thompson CeedCall(CeedQFunctionReference(qf)); 7482b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(qf_copy)); 7499560d06aSjeremylt *qf_copy = qf; 7509560d06aSjeremylt return CEED_ERROR_SUCCESS; 7519560d06aSjeremylt } 7529560d06aSjeremylt 7539560d06aSjeremylt /** 754ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` input 755b11c1e72Sjeremylt 756ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 757ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 758ca94c3ddSJeremy 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. 759ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 760ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 761ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 762ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 763ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 764b11c1e72Sjeremylt 765b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 766dfdf5a53Sjeremylt 7677a982d89SJeremy L. Thompson @ref User 768b11c1e72Sjeremylt **/ 7692b730f8bSJeremy L Thompson int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 7701203703bSJeremy L Thompson bool is_immutable; 7711203703bSJeremy L Thompson Ceed ceed; 7721203703bSJeremy L Thompson 7731203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 7741203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 7751203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "QFunction cannot be changed after set as immutable"); 7761203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT || size == 1, ceed, CEED_ERROR_DIMENSION, "CEED_EVAL_WEIGHT should have size 1"); 777643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 7781203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 779643fbb69SJeremy L Thompson } 780643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 7811203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 782643fbb69SJeremy L Thompson } 7832b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->input_fields[qf->num_input_fields], field_name, size, eval_mode)); 784d1d35e2fSjeremylt qf->num_input_fields++; 785e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 786d7b241e6Sjeremylt } 787d7b241e6Sjeremylt 788b11c1e72Sjeremylt /** 789ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` output 790b11c1e72Sjeremylt 791ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 792ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 793ca94c3ddSJeremy 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. 794ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 795ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 796ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 797ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 798ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl. 799b11c1e72Sjeremylt 800b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 801dfdf5a53Sjeremylt 8027a982d89SJeremy L. Thompson @ref User 803b11c1e72Sjeremylt **/ 8042b730f8bSJeremy L Thompson int CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 8051203703bSJeremy L Thompson bool is_immutable; 8061203703bSJeremy L Thompson Ceed ceed; 8071203703bSJeremy L Thompson 8081203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 8091203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 8101203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "CeedQFunction cannot be changed after set as immutable"); 8111203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT, ceed, CEED_ERROR_DIMENSION, "Cannot create CeedQFunction output with CEED_EVAL_WEIGHT"); 812643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 8131203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 814643fbb69SJeremy L Thompson } 815643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 8161203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 817643fbb69SJeremy L Thompson } 8182b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->output_fields[qf->num_output_fields], field_name, size, eval_mode)); 819d1d35e2fSjeremylt qf->num_output_fields++; 820e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 821d7b241e6Sjeremylt } 822d7b241e6Sjeremylt 823dfdf5a53Sjeremylt /** 824ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunctionField` of a `CeedQFunction` 82543bbe138SJeremy L Thompson 826ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 827f04ea552SJeremy L Thompson 828ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 829f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 830f74ec584SJeremy L Thompson @param[out] input_fields Variable to store input fields 831f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 832f74ec584SJeremy L Thompson @param[out] output_fields Variable to store output fields 83343bbe138SJeremy L Thompson 83443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83543bbe138SJeremy L Thompson 836e9b533fbSJeremy L Thompson @ref Advanced 83743bbe138SJeremy L Thompson **/ 8382b730f8bSJeremy L Thompson int CeedQFunctionGetFields(CeedQFunction qf, CeedInt *num_input_fields, CeedQFunctionField **input_fields, CeedInt *num_output_fields, 83943bbe138SJeremy L Thompson CeedQFunctionField **output_fields) { 8401203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 84143bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = qf->num_input_fields; 84243bbe138SJeremy L Thompson if (input_fields) *input_fields = qf->input_fields; 84343bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = qf->num_output_fields; 84443bbe138SJeremy L Thompson if (output_fields) *output_fields = qf->output_fields; 84543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84643bbe138SJeremy L Thompson } 84743bbe138SJeremy L Thompson 84843bbe138SJeremy L Thompson /** 849ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedQFunctionField` 85043bbe138SJeremy L Thompson 851ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 85243bbe138SJeremy L Thompson @param[out] field_name Variable to store the field name 85343bbe138SJeremy L Thompson 85443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85543bbe138SJeremy L Thompson 856e9b533fbSJeremy L Thompson @ref Advanced 85743bbe138SJeremy L Thompson **/ 8586f8994e9SJeremy L Thompson int CeedQFunctionFieldGetName(CeedQFunctionField qf_field, const char **field_name) { 8596f8994e9SJeremy L Thompson *field_name = qf_field->field_name; 86043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 86143bbe138SJeremy L Thompson } 86243bbe138SJeremy L Thompson 86343bbe138SJeremy L Thompson /** 864ca94c3ddSJeremy L Thompson @brief Get the number of components of a `CeedQFunctionField` 86543bbe138SJeremy L Thompson 866ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 86743bbe138SJeremy L Thompson @param[out] size Variable to store the size of the field 86843bbe138SJeremy L Thompson 86943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87043bbe138SJeremy L Thompson 871e9b533fbSJeremy L Thompson @ref Advanced 87243bbe138SJeremy L Thompson **/ 87343bbe138SJeremy L Thompson int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field, CeedInt *size) { 87443bbe138SJeremy L Thompson *size = qf_field->size; 87543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87643bbe138SJeremy L Thompson } 87743bbe138SJeremy L Thompson 87843bbe138SJeremy L Thompson /** 879ca94c3ddSJeremy L Thompson @brief Get the @ref CeedEvalMode of a `CeedQFunctionField` 88043bbe138SJeremy L Thompson 881ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 88243bbe138SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 88343bbe138SJeremy L Thompson 88443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88543bbe138SJeremy L Thompson 886e9b533fbSJeremy L Thompson @ref Advanced 88743bbe138SJeremy L Thompson **/ 8882b730f8bSJeremy L Thompson int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field, CeedEvalMode *eval_mode) { 88943bbe138SJeremy L Thompson *eval_mode = qf_field->eval_mode; 89043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 89143bbe138SJeremy L Thompson } 89243bbe138SJeremy L Thompson 89343bbe138SJeremy L Thompson /** 894ab747706SJeremy L Thompson @brief Get the data of a `CeedQFunctionField`. 895ab747706SJeremy L Thompson 896ab747706SJeremy L Thompson Any arguments set as `NULL` are ignored. 897ab747706SJeremy L Thompson 898ab747706SJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 899ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 900ab747706SJeremy L Thompson @param[out] size Variable to store the size of the field 901ab747706SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 902ab747706SJeremy L Thompson 903ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 904ab747706SJeremy L Thompson 905ab747706SJeremy L Thompson @ref Advanced 906ab747706SJeremy L Thompson **/ 9076f8994e9SJeremy L Thompson int CeedQFunctionFieldGetData(CeedQFunctionField qf_field, const char **field_name, CeedInt *size, CeedEvalMode *eval_mode) { 908ab747706SJeremy L Thompson if (field_name) CeedCall(CeedQFunctionFieldGetName(qf_field, field_name)); 909ab747706SJeremy L Thompson if (size) CeedCall(CeedQFunctionFieldGetSize(qf_field, size)); 910ab747706SJeremy L Thompson if (eval_mode) CeedCall(CeedQFunctionFieldGetEvalMode(qf_field, eval_mode)); 911ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 912ab747706SJeremy L Thompson } 913ab747706SJeremy L Thompson 914ab747706SJeremy L Thompson /** 915ca94c3ddSJeremy L Thompson @brief Set global context for a `CeedQFunction` 916b11c1e72Sjeremylt 917ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 918ea61e9acSJeremy L Thompson @param[in] ctx Context data to set 919b11c1e72Sjeremylt 920b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 921dfdf5a53Sjeremylt 9227a982d89SJeremy L. Thompson @ref User 923b11c1e72Sjeremylt **/ 924777ff853SJeremy L Thompson int CeedQFunctionSetContext(CeedQFunction qf, CeedQFunctionContext ctx) { 9252b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&qf->ctx)); 926d7b241e6Sjeremylt qf->ctx = ctx; 927db002c03SJeremy L Thompson if (ctx) CeedCall(CeedQFunctionContextReference(ctx)); 928e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 929d7b241e6Sjeremylt } 930d7b241e6Sjeremylt 931b11c1e72Sjeremylt /** 932ca94c3ddSJeremy L Thompson @brief Set writability of `CeedQFunctionContext` when calling the `CeedQFunctionUser`. 9334385fb7fSSebastian Grimberg 934859c15bbSJames Wright The default value is `is_writable == true`. 935441428dfSJeremy L Thompson 936ca94c3ddSJeremy L Thompson Setting `is_writable == true` indicates the `CeedQFunctionUser` writes into the `CeedQFunctionContext` and requires memory synchronization after calling @ref CeedQFunctionApply(). 937441428dfSJeremy L Thompson 938ca94c3ddSJeremy L Thompson Setting 'is_writable == false' asserts that `CeedQFunctionUser` does not modify the `CeedQFunctionContext`. 939ea61e9acSJeremy L Thompson Violating this assertion may lead to inconsistent data. 940441428dfSJeremy L Thompson 941441428dfSJeremy L Thompson Setting `is_writable == false` may offer a performance improvement on GPU backends. 942441428dfSJeremy L Thompson 943ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 944ca94c3ddSJeremy L Thompson @param[in] is_writable Boolean flag for writability status 945441428dfSJeremy L Thompson 946441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 947441428dfSJeremy L Thompson 948441428dfSJeremy L Thompson @ref User 949441428dfSJeremy L Thompson **/ 950441428dfSJeremy L Thompson int CeedQFunctionSetContextWritable(CeedQFunction qf, bool is_writable) { 951441428dfSJeremy L Thompson qf->is_context_writable = is_writable; 952441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 953441428dfSJeremy L Thompson } 954441428dfSJeremy L Thompson 955441428dfSJeremy L Thompson /** 956ca94c3ddSJeremy L Thompson @brief Set estimated number of FLOPs per quadrature required to apply `CeedQFunction` 9576e15d496SJeremy L Thompson 958ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 959ea61e9acSJeremy L Thompson @param[out] flops FLOPs per quadrature point estimate 9606e15d496SJeremy L Thompson 9616e15d496SJeremy L Thompson @ref Backend 9626e15d496SJeremy L Thompson **/ 9639d36ca50SJeremy L Thompson int CeedQFunctionSetUserFlopsEstimate(CeedQFunction qf, CeedSize flops) { 9646e536b99SJeremy L Thompson CeedCheck(flops >= 0, CeedQFunctionReturnCeed(qf), CEED_ERROR_INCOMPATIBLE, "Must set non-negative FLOPs estimate"); 9656e15d496SJeremy L Thompson qf->user_flop_estimate = flops; 9666e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 9676e15d496SJeremy L Thompson } 9686e15d496SJeremy L Thompson 9696e15d496SJeremy L Thompson /** 970ca94c3ddSJeremy L Thompson @brief View a `CeedQFunction` 97175affc3bSjeremylt 972ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to view 973ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 97475affc3bSjeremylt 97575affc3bSjeremylt @return Error code: 0 - success, otherwise - failure 97675affc3bSjeremylt 9777a982d89SJeremy L. Thompson @ref User 97875affc3bSjeremylt **/ 97975affc3bSjeremylt int CeedQFunctionView(CeedQFunction qf, FILE *stream) { 9807d023984SJeremy L Thompson const char *kernel_name; 98175affc3bSjeremylt 9822b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetKernelName(qf, &kernel_name)); 9832b730f8bSJeremy L Thompson fprintf(stream, "%sCeedQFunction - %s\n", qf->is_gallery ? "Gallery " : "User ", qf->is_gallery ? qf->gallery_name : kernel_name); 98475affc3bSjeremylt 9852b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " input field%s:\n", qf->num_input_fields, qf->num_input_fields > 1 ? "s" : ""); 986d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_input_fields; i++) { 9872b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->input_fields[i], i, 1, stream)); 98875affc3bSjeremylt } 98975affc3bSjeremylt 9902b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " output field%s:\n", qf->num_output_fields, qf->num_output_fields > 1 ? "s" : ""); 991d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_output_fields; i++) { 9922b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->output_fields[i], i, 0, stream)); 99375affc3bSjeremylt } 994e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 99575affc3bSjeremylt } 99675affc3bSjeremylt 99775affc3bSjeremylt /** 998ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedQFunction` 999b7c9bbdaSJeremy L Thompson 1000ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 1001ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store`Ceed` 1002b7c9bbdaSJeremy L Thompson 1003b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1004b7c9bbdaSJeremy L Thompson 1005b7c9bbdaSJeremy L Thompson @ref Advanced 1006b7c9bbdaSJeremy L Thompson **/ 1007b7c9bbdaSJeremy L Thompson int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 10086e536b99SJeremy L Thompson *ceed = CeedQFunctionReturnCeed(qf); 1009b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1010b7c9bbdaSJeremy L Thompson } 1011b7c9bbdaSJeremy L Thompson 1012b7c9bbdaSJeremy L Thompson /** 10136e536b99SJeremy L Thompson @brief Return the `Ceed` associated with a `CeedQFunction` 10146e536b99SJeremy L Thompson 10156e536b99SJeremy L Thompson @param[in] qf `CeedQFunction` 10166e536b99SJeremy L Thompson 10176e536b99SJeremy L Thompson @return `Ceed` associated with the `qf` 10186e536b99SJeremy L Thompson 10196e536b99SJeremy L Thompson @ref Advanced 10206e536b99SJeremy L Thompson **/ 10216e536b99SJeremy L Thompson Ceed CeedQFunctionReturnCeed(CeedQFunction qf) { return qf->ceed; } 10226e536b99SJeremy L Thompson 10236e536b99SJeremy L Thompson /** 1024ca94c3ddSJeremy L Thompson @brief Apply the action of a `CeedQFunction` 1025b11c1e72Sjeremylt 1026ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 1027f04ea552SJeremy L Thompson 1028ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 1029ea61e9acSJeremy L Thompson @param[in] Q Number of quadrature points 1030ca94c3ddSJeremy L Thompson @param[in] u Array of input `CeedVector` 1031ca94c3ddSJeremy L Thompson @param[out] v Array of output `CeedVector` 1032b11c1e72Sjeremylt 1033b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1034dfdf5a53Sjeremylt 10357a982d89SJeremy L. Thompson @ref User 1036b11c1e72Sjeremylt **/ 10372b730f8bSJeremy L Thompson int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, CeedVector *u, CeedVector *v) { 10381203703bSJeremy L Thompson CeedInt vec_length; 10391203703bSJeremy L Thompson Ceed ceed; 10401203703bSJeremy L Thompson 10411203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 10421203703bSJeremy L Thompson CeedCheck(qf->Apply, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionApply"); 10431203703bSJeremy L Thompson CeedCall(CeedQFunctionGetVectorLength(qf, &vec_length)); 10441203703bSJeremy 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, 10451203703bSJeremy L Thompson qf->vec_length); 10461203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 10472b730f8bSJeremy L Thompson CeedCall(qf->Apply(qf, Q, u, v)); 1048e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1049d7b241e6Sjeremylt } 1050d7b241e6Sjeremylt 1051b11c1e72Sjeremylt /** 1052ca94c3ddSJeremy L Thompson @brief Destroy a `CeedQFunction` 1053b11c1e72Sjeremylt 1054ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to destroy 1055b11c1e72Sjeremylt 1056b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1057dfdf5a53Sjeremylt 10587a982d89SJeremy L. Thompson @ref User 1059b11c1e72Sjeremylt **/ 1060d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) { 1061ad6481ceSJeremy L Thompson if (!*qf || --(*qf)->ref_count > 0) { 1062ad6481ceSJeremy L Thompson *qf = NULL; 1063ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1064ad6481ceSJeremy L Thompson } 1065fe2413ffSjeremylt // Backend destroy 1066d7b241e6Sjeremylt if ((*qf)->Destroy) { 10672b730f8bSJeremy L Thompson CeedCall((*qf)->Destroy(*qf)); 1068d7b241e6Sjeremylt } 1069fe2413ffSjeremylt // Free fields 107092ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_input_fields; i++) { 10712b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->input_fields[i]).field_name)); 10722b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields[i])); 1073fe2413ffSjeremylt } 107492ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_output_fields; i++) { 10752b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->output_fields[i]).field_name)); 10762b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields[i])); 1077fe2413ffSjeremylt } 10782b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields)); 10792b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields)); 1080777ff853SJeremy L Thompson 1081777ff853SJeremy L Thompson // User context data object 10822b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&(*qf)->ctx)); 1083fe2413ffSjeremylt 10842b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->user_source)); 10852b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->source_path)); 10862b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->gallery_name)); 10872b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->kernel_name)); 10882b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*qf)->ceed)); 10892b730f8bSJeremy L Thompson CeedCall(CeedFree(qf)); 1090e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1091d7b241e6Sjeremylt } 1092d7b241e6Sjeremylt 1093d7b241e6Sjeremylt /// @} 1094