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 **/ 209*7d023984SJeremy 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 227*7d023984SJeremy 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 **/ 24143e1b16fSJeremy L Thompson int CeedQFunctionGetSourcePath(CeedQFunction qf, char **source_path) { 242ca5eadf8SJeremy L Thompson if (!qf->source_path && qf->user_source) { 243ca5eadf8SJeremy L Thompson Ceed ceed; 244ca5eadf8SJeremy L Thompson bool is_absolute_path; 245ca5eadf8SJeremy L Thompson char *absolute_path, *source_path_copy; 246ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 247ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 248ca5eadf8SJeremy L Thompson 2492b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 2502b730f8bSJeremy L Thompson CeedCall(CeedCheckFilePath(ceed, qf->user_source, &is_absolute_path)); 251ca5eadf8SJeremy L Thompson if (is_absolute_path) { 252ca5eadf8SJeremy L Thompson absolute_path = (char *)qf->user_source; 253ca5eadf8SJeremy L Thompson } else { 2542b730f8bSJeremy L Thompson CeedCall(CeedGetJitAbsolutePath(ceed, qf->user_source, &absolute_path)); 255ca5eadf8SJeremy L Thompson } 256ca5eadf8SJeremy L Thompson 257ca5eadf8SJeremy L Thompson size_t source_len = strlen(absolute_path) - kernel_name_len - 1; 2581c66c397SJeremy L Thompson 2592b730f8bSJeremy L Thompson CeedCall(CeedCalloc(source_len + 1, &source_path_copy)); 260ca5eadf8SJeremy L Thompson memcpy(source_path_copy, absolute_path, source_len); 261ca5eadf8SJeremy L Thompson qf->source_path = source_path_copy; 262ca5eadf8SJeremy L Thompson 2632b730f8bSJeremy L Thompson if (!is_absolute_path) CeedCall(CeedFree(&absolute_path)); 264ca5eadf8SJeremy L Thompson } 265ca5eadf8SJeremy L Thompson 26643e1b16fSJeremy L Thompson *source_path = (char *)qf->source_path; 267e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2687a982d89SJeremy L. Thompson } 2697a982d89SJeremy L. Thompson 2707a982d89SJeremy L. Thompson /** 271ca94c3ddSJeremy L Thompson @brief Initialize and load `CeedQFunction` source file into string buffer, including full text of local files in place of `#include "local.h"`. 2724385fb7fSSebastian Grimberg 273ca94c3ddSJeremy L Thompson The `buffer` is set to `NULL` if there is no `CeedQFunction` source file. 2744385fb7fSSebastian Grimberg 275ca94c3ddSJeremy L Thompson Note: Caller is responsible for freeing the string buffer with @ref CeedFree(). 2763d3250a0SJeremy L Thompson 277ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 278f74ec584SJeremy L Thompson @param[out] source_buffer String buffer for source file contents 2793d3250a0SJeremy L Thompson 2803d3250a0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2813d3250a0SJeremy L Thompson 2823d3250a0SJeremy L Thompson @ref Backend 2833d3250a0SJeremy L Thompson **/ 2843d3250a0SJeremy L Thompson int CeedQFunctionLoadSourceToBuffer(CeedQFunction qf, char **source_buffer) { 2853d3250a0SJeremy L Thompson char *source_path; 2863d3250a0SJeremy L Thompson 2872b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetSourcePath(qf, &source_path)); 2883d3250a0SJeremy L Thompson *source_buffer = NULL; 2893d3250a0SJeremy L Thompson if (source_path) { 2901203703bSJeremy L Thompson Ceed ceed; 2911203703bSJeremy L Thompson 2921203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 2931203703bSJeremy L Thompson CeedCall(CeedLoadSourceToBuffer(ceed, source_path, source_buffer)); 2943d3250a0SJeremy L Thompson } 2953d3250a0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2963d3250a0SJeremy L Thompson } 2973d3250a0SJeremy L Thompson 2983d3250a0SJeremy L Thompson /** 299ca94c3ddSJeremy L Thompson @brief Get the User Function for a `CeedQFunction` 3007a982d89SJeremy L. Thompson 301ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 3027a982d89SJeremy L. Thompson @param[out] f Variable to store user function 3037a982d89SJeremy L. Thompson 3047a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3057a982d89SJeremy L. Thompson 3067a982d89SJeremy L. Thompson @ref Backend 3077a982d89SJeremy L. Thompson **/ 3087a982d89SJeremy L. Thompson int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) { 3097a982d89SJeremy L. Thompson *f = qf->function; 310e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3117a982d89SJeremy L. Thompson } 3127a982d89SJeremy L. Thompson 3137a982d89SJeremy L. Thompson /** 314ca94c3ddSJeremy L Thompson @brief Get global context for a `CeedQFunction`. 3154385fb7fSSebastian Grimberg 316ca94c3ddSJeremy L Thompson Note: For `CeedQFunction` from the Fortran interface, this function will return the Fortran context `CeedQFunctionContext`. 3177a982d89SJeremy L. Thompson 318ea61e9acSJeremy L Thompson @param[in] qf CeedQFunction 319777ff853SJeremy L Thompson @param[out] ctx Variable to store CeedQFunctionContext 3207a982d89SJeremy L. Thompson 3217a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3227a982d89SJeremy L. Thompson 3237a982d89SJeremy L. Thompson @ref Backend 3247a982d89SJeremy L. Thompson **/ 325777ff853SJeremy L Thompson int CeedQFunctionGetContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 3267a982d89SJeremy L. Thompson *ctx = qf->ctx; 327e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3287a982d89SJeremy L. Thompson } 3297a982d89SJeremy L. Thompson 3307a982d89SJeremy L. Thompson /** 331ca94c3ddSJeremy L Thompson @brief Get context data of a `CeedQFunction` 332441428dfSJeremy L Thompson 333ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 334ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 335ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 336441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 337441428dfSJeremy L Thompson 338441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 339441428dfSJeremy L Thompson 340441428dfSJeremy L Thompson @ref Backend 341441428dfSJeremy L Thompson **/ 3422b730f8bSJeremy L Thompson int CeedQFunctionGetContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 343441428dfSJeremy L Thompson bool is_writable; 344441428dfSJeremy L Thompson CeedQFunctionContext ctx; 345441428dfSJeremy L Thompson 3462b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 347441428dfSJeremy L Thompson if (ctx) { 3482b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 349441428dfSJeremy L Thompson if (is_writable) { 3502b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 351441428dfSJeremy L Thompson } else { 3522b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 353441428dfSJeremy L Thompson } 354441428dfSJeremy L Thompson } else { 355441428dfSJeremy L Thompson *(void **)data = NULL; 356441428dfSJeremy L Thompson } 357441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 358441428dfSJeremy L Thompson } 359441428dfSJeremy L Thompson 360441428dfSJeremy L Thompson /** 361ca94c3ddSJeremy L Thompson @brief Restore context data of a `CeedQFunction` 362441428dfSJeremy L Thompson 363ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 364ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 365441428dfSJeremy L Thompson 366441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 367441428dfSJeremy L Thompson 368441428dfSJeremy L Thompson @ref Backend 369441428dfSJeremy L Thompson **/ 370441428dfSJeremy L Thompson int CeedQFunctionRestoreContextData(CeedQFunction qf, void *data) { 371441428dfSJeremy L Thompson bool is_writable; 372441428dfSJeremy L Thompson CeedQFunctionContext ctx; 373441428dfSJeremy L Thompson 3742b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 375441428dfSJeremy L Thompson if (ctx) { 3762b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 377441428dfSJeremy L Thompson if (is_writable) { 3782b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 379441428dfSJeremy L Thompson } else { 3802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 381441428dfSJeremy L Thompson } 382441428dfSJeremy L Thompson } 3835f249b39SJeremy L Thompson *(void **)data = NULL; 384441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 385441428dfSJeremy L Thompson } 386441428dfSJeremy L Thompson 387441428dfSJeremy L Thompson /** 388ca94c3ddSJeremy L Thompson @brief Get true user context for a `CeedQFunction` 3894385fb7fSSebastian Grimberg 390ca94c3ddSJeremy L Thompson Note: For all `CeedQFunction` this function will return the user `CeedQFunctionContext` and not interface context `CeedQFunctionContext`, if any such object exists. 3917a982d89SJeremy L. Thompson 392ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 393ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 3947a982d89SJeremy L. Thompson 3957a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3967a982d89SJeremy L. Thompson @ref Backend 3977a982d89SJeremy L. Thompson **/ 398777ff853SJeremy L Thompson int CeedQFunctionGetInnerContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 3991203703bSJeremy L Thompson CeedQFunctionContext qf_ctx; 4001203703bSJeremy L Thompson 4011203703bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &qf_ctx)); 402f04ea552SJeremy L Thompson if (qf->is_fortran) { 403d1d35e2fSjeremylt CeedFortranContext fortran_ctx = NULL; 4041c66c397SJeremy L Thompson 4051203703bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(qf_ctx, CEED_MEM_HOST, &fortran_ctx)); 4068cb0412aSJeremy L Thompson *ctx = fortran_ctx->inner_ctx; 4071203703bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(qf_ctx, (void *)&fortran_ctx)); 4087a982d89SJeremy L. Thompson } else { 4091203703bSJeremy L Thompson *ctx = qf_ctx; 4107a982d89SJeremy L. Thompson } 411e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4127a982d89SJeremy L. Thompson } 4137a982d89SJeremy L. Thompson 4147a982d89SJeremy L. Thompson /** 415ca94c3ddSJeremy L Thompson @brief Get inner context data of a `CeedQFunction` 416441428dfSJeremy L Thompson 417ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 418ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 419ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 420441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 421441428dfSJeremy L Thompson 422441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 423441428dfSJeremy L Thompson 424441428dfSJeremy L Thompson @ref Backend 425441428dfSJeremy L Thompson **/ 4262b730f8bSJeremy L Thompson int CeedQFunctionGetInnerContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 427441428dfSJeremy L Thompson bool is_writable; 428441428dfSJeremy L Thompson CeedQFunctionContext ctx; 429441428dfSJeremy L Thompson 4302b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 431441428dfSJeremy L Thompson if (ctx) { 4322b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 433441428dfSJeremy L Thompson if (is_writable) { 4342b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 435441428dfSJeremy L Thompson } else { 4362b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 437441428dfSJeremy L Thompson } 438441428dfSJeremy L Thompson } else { 439441428dfSJeremy L Thompson *(void **)data = NULL; 440441428dfSJeremy L Thompson } 441441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 442441428dfSJeremy L Thompson } 443441428dfSJeremy L Thompson 444441428dfSJeremy L Thompson /** 445ca94c3ddSJeremy L Thompson @brief Restore inner context data of a `CeedQFunction` 446441428dfSJeremy L Thompson 447ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 448ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 449441428dfSJeremy L Thompson 450441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 451441428dfSJeremy L Thompson 452441428dfSJeremy L Thompson @ref Backend 453441428dfSJeremy L Thompson **/ 454441428dfSJeremy L Thompson int CeedQFunctionRestoreInnerContextData(CeedQFunction qf, void *data) { 455441428dfSJeremy L Thompson bool is_writable; 456441428dfSJeremy L Thompson CeedQFunctionContext ctx; 457441428dfSJeremy L Thompson 4582b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 459441428dfSJeremy L Thompson if (ctx) { 4602b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 461441428dfSJeremy L Thompson if (is_writable) { 4622b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 463441428dfSJeremy L Thompson } else { 4642b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 465441428dfSJeremy L Thompson } 466441428dfSJeremy L Thompson } 4675f249b39SJeremy L Thompson *(void **)data = NULL; 468441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 469441428dfSJeremy L Thompson } 470441428dfSJeremy L Thompson 471441428dfSJeremy L Thompson /** 472ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunction` is identity 4737a982d89SJeremy L. Thompson 474ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 475d1d35e2fSjeremylt @param[out] is_identity Variable to store identity status 4767a982d89SJeremy L. Thompson 4777a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4787a982d89SJeremy L. Thompson 4797a982d89SJeremy L. Thompson @ref Backend 4807a982d89SJeremy L. Thompson **/ 481d1d35e2fSjeremylt int CeedQFunctionIsIdentity(CeedQFunction qf, bool *is_identity) { 482f04ea552SJeremy L Thompson *is_identity = qf->is_identity; 483e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4847a982d89SJeremy L. Thompson } 4857a982d89SJeremy L. Thompson 4867a982d89SJeremy L. Thompson /** 487ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunctionContext` is writable 488441428dfSJeremy L Thompson 489ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 490ea61e9acSJeremy L Thompson @param[out] is_writable Variable to store context writeable status 491441428dfSJeremy L Thompson 492441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 493441428dfSJeremy L Thompson 494441428dfSJeremy L Thompson @ref Backend 495441428dfSJeremy L Thompson **/ 496441428dfSJeremy L Thompson int CeedQFunctionIsContextWritable(CeedQFunction qf, bool *is_writable) { 497441428dfSJeremy L Thompson *is_writable = qf->is_context_writable; 498441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 499441428dfSJeremy L Thompson } 500441428dfSJeremy L Thompson 501441428dfSJeremy L Thompson /** 502ca94c3ddSJeremy L Thompson @brief Get backend data of a `CeedQFunction` 5037a982d89SJeremy L. Thompson 504ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 5057a982d89SJeremy L. Thompson @param[out] data Variable to store data 5067a982d89SJeremy L. Thompson 5077a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5087a982d89SJeremy L. Thompson 5097a982d89SJeremy L. Thompson @ref Backend 5107a982d89SJeremy L. Thompson **/ 511777ff853SJeremy L Thompson int CeedQFunctionGetData(CeedQFunction qf, void *data) { 512777ff853SJeremy L Thompson *(void **)data = qf->data; 513e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5147a982d89SJeremy L. Thompson } 5157a982d89SJeremy L. Thompson 5167a982d89SJeremy L. Thompson /** 517ca94c3ddSJeremy L Thompson @brief Set backend data of a `CeedQFunction` 5187a982d89SJeremy L. Thompson 519ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 520ea61e9acSJeremy L Thompson @param[in] data Data to set 5217a982d89SJeremy L. Thompson 5227a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5237a982d89SJeremy L. Thompson 5247a982d89SJeremy L. Thompson @ref Backend 5257a982d89SJeremy L. Thompson **/ 526777ff853SJeremy L Thompson int CeedQFunctionSetData(CeedQFunction qf, void *data) { 527777ff853SJeremy L Thompson qf->data = data; 528e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5297a982d89SJeremy L. Thompson } 5307a982d89SJeremy L. Thompson 5317a982d89SJeremy L. Thompson /** 5321203703bSJeremy L Thompson @brief Get a boolean value indicating if the `CeedQFunction` is immutable 5331203703bSJeremy L Thompson 5341203703bSJeremy L Thompson @param[in] qf `CeedOperator` 5351203703bSJeremy L Thompson @param[out] is_immutable Variable to store immutability status 5361203703bSJeremy L Thompson 5371203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5381203703bSJeremy L Thompson 5391203703bSJeremy L Thompson @ref Backend 5401203703bSJeremy L Thompson **/ 5411203703bSJeremy L Thompson int CeedQFunctionIsImmutable(CeedQFunction qf, bool *is_immutable) { 5421203703bSJeremy L Thompson *is_immutable = qf->is_immutable; 5431203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5441203703bSJeremy L Thompson } 5451203703bSJeremy L Thompson 5461203703bSJeremy L Thompson /** 5471203703bSJeremy L Thompson @brief Set the immutable flag of a `CeedQFunction` to `true` 5481203703bSJeremy L Thompson 5491203703bSJeremy L Thompson @param[in,out] qf `CeedQFunction` 5501203703bSJeremy L Thompson 5511203703bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5521203703bSJeremy L Thompson 5531203703bSJeremy L Thompson @ref Backend 5541203703bSJeremy L Thompson **/ 5551203703bSJeremy L Thompson int CeedQFunctionSetImmutable(CeedQFunction qf) { 5561203703bSJeremy L Thompson qf->is_immutable = true; 5571203703bSJeremy L Thompson return CEED_ERROR_SUCCESS; 5581203703bSJeremy L Thompson } 5591203703bSJeremy L Thompson 5601203703bSJeremy L Thompson /** 561ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedQFunction` 56234359f16Sjeremylt 563ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to increment the reference counter 56434359f16Sjeremylt 56534359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 56634359f16Sjeremylt 56734359f16Sjeremylt @ref Backend 56834359f16Sjeremylt **/ 5699560d06aSjeremylt int CeedQFunctionReference(CeedQFunction qf) { 57034359f16Sjeremylt qf->ref_count++; 57134359f16Sjeremylt return CEED_ERROR_SUCCESS; 57234359f16Sjeremylt } 57334359f16Sjeremylt 5746e15d496SJeremy L Thompson /** 575ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs per quadrature required to apply `CeedQFunction` 5766e15d496SJeremy L Thompson 577ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 578ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5796e15d496SJeremy L Thompson 5806e15d496SJeremy L Thompson @ref Backend 5816e15d496SJeremy L Thompson **/ 5829d36ca50SJeremy L Thompson int CeedQFunctionGetFlopsEstimate(CeedQFunction qf, CeedSize *flops) { 5836e15d496SJeremy L Thompson *flops = qf->user_flop_estimate; 5846e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5856e15d496SJeremy L Thompson } 5866e15d496SJeremy L Thompson 5877a982d89SJeremy L. Thompson /// @} 5887a982d89SJeremy L. Thompson 5897a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5907a982d89SJeremy L. Thompson /// CeedQFunction Public API 5917a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5927a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 5937a982d89SJeremy L. Thompson /// @{ 5947a982d89SJeremy L. Thompson 5957a982d89SJeremy L. Thompson /** 596ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms 5977a982d89SJeremy L. Thompson 598ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 599ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 600ca94c3ddSJeremy L Thompson Caller must ensure that number of quadrature points is a multiple of `vec_length`. 601ea61e9acSJeremy L Thompson @param[in] f Function pointer to evaluate action at quadrature points. 602ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 603ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunctionUser`, "\abs_path\file.h:function_name". 604ca94c3ddSJeremy 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.). 6054ada38baSJames Wright The entire contents of this file and all locally included files are used during JiT compilation for GPU backends. 6064ada38baSJames Wright All source files must be at the provided filepath at runtime for JiT to function. 607ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 6087a982d89SJeremy L. Thompson 6097a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6107a982d89SJeremy L. Thompson 611ca94c3ddSJeremy L Thompson See \ref CeedQFunctionUser for details on the call-back function `f` arguments. 6127a982d89SJeremy L. Thompson 6137a982d89SJeremy L. Thompson @ref User 6147a982d89SJeremy L. Thompson **/ 6152b730f8bSJeremy L Thompson int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length, CeedQFunctionUser f, const char *source, CeedQFunction *qf) { 616ca5eadf8SJeremy L Thompson char *user_source_copy; 6177a982d89SJeremy L. Thompson 6187a982d89SJeremy L. Thompson if (!ceed->QFunctionCreate) { 6197a982d89SJeremy L. Thompson Ceed delegate; 6206574a04fSJeremy L Thompson 6212b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "QFunction")); 622ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionCreateInterior"); 6232b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(delegate, vec_length, f, source, qf)); 624e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6257a982d89SJeremy L. Thompson } 6267a982d89SJeremy L. Thompson 6276574a04fSJeremy L Thompson CeedCheck(!strlen(source) || strrchr(source, ':'), ceed, CEED_ERROR_INCOMPLETE, 6286574a04fSJeremy L Thompson "Provided path to source does not include function name. Provided: \"%s\"\nRequired: \"\\abs_path\\file.h:function_name\"", source); 62943e1b16fSJeremy L Thompson 6302b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, qf)); 631db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*qf)->ceed)); 632d1d35e2fSjeremylt (*qf)->ref_count = 1; 633d1d35e2fSjeremylt (*qf)->vec_length = vec_length; 634f04ea552SJeremy L Thompson (*qf)->is_identity = false; 635441428dfSJeremy L Thompson (*qf)->is_context_writable = true; 6367a982d89SJeremy L. Thompson (*qf)->function = f; 6376e15d496SJeremy L Thompson (*qf)->user_flop_estimate = -1; 63843e1b16fSJeremy L Thompson if (strlen(source)) { 639ca5eadf8SJeremy L Thompson size_t user_source_len = strlen(source); 640ee5a26f2SJeremy L Thompson 6412b730f8bSJeremy L Thompson CeedCall(CeedCalloc(user_source_len + 1, &user_source_copy)); 642ca5eadf8SJeremy L Thompson memcpy(user_source_copy, source, user_source_len); 643ca5eadf8SJeremy L Thompson (*qf)->user_source = user_source_copy; 64443e1b16fSJeremy L Thompson } 6452b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->input_fields)); 6462b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->output_fields)); 6472b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionCreate(*qf)); 648e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6497a982d89SJeremy L. Thompson } 6507a982d89SJeremy L. Thompson 6517a982d89SJeremy L. Thompson /** 652ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms by name 653288c0443SJeremy L Thompson 654ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 655ca94c3ddSJeremy L Thompson @param[in] name Name of `CeedQFunction` to use from gallery 656ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 657288c0443SJeremy L Thompson 658288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 659288c0443SJeremy L Thompson 6607a982d89SJeremy L. Thompson @ref User 661288c0443SJeremy L Thompson **/ 6622b730f8bSJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name, CeedQFunction *qf) { 663f7e22acaSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX; 664288c0443SJeremy L Thompson 6652b730f8bSJeremy L Thompson CeedCall(CeedQFunctionRegisterAll()); 666288c0443SJeremy L Thompson // Find matching backend 667ca94c3ddSJeremy L Thompson CeedCheck(name, ceed, CEED_ERROR_INCOMPLETE, "No CeedQFunction name provided"); 668288c0443SJeremy L Thompson for (size_t i = 0; i < num_qfunctions; i++) { 669288c0443SJeremy L Thompson size_t n; 670d1d35e2fSjeremylt const char *curr_name = gallery_qfunctions[i].name; 6712b730f8bSJeremy L Thompson for (n = 0; curr_name[n] && curr_name[n] == name[n]; n++) { 6722b730f8bSJeremy L Thompson } 673d1d35e2fSjeremylt if (n > match_len) { 674d1d35e2fSjeremylt match_len = n; 675f7e22acaSJeremy L Thompson match_index = i; 676288c0443SJeremy L Thompson } 677288c0443SJeremy L Thompson } 678ca94c3ddSJeremy L Thompson CeedCheck(match_len > 0, ceed, CEED_ERROR_UNSUPPORTED, "No suitable gallery CeedQFunction"); 679288c0443SJeremy L Thompson 680288c0443SJeremy L Thompson // Create QFunction 6812b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(ceed, gallery_qfunctions[match_index].vec_length, gallery_qfunctions[match_index].f, 6822b730f8bSJeremy L Thompson gallery_qfunctions[match_index].source, qf)); 683288c0443SJeremy L Thompson 684288c0443SJeremy L Thompson // QFunction specific setup 6852b730f8bSJeremy L Thompson CeedCall(gallery_qfunctions[match_index].init(ceed, name, *qf)); 686288c0443SJeremy L Thompson 68775affc3bSjeremylt // Copy name 6882b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(name, (char **)&(*qf)->gallery_name)); 68943e1b16fSJeremy L Thompson (*qf)->is_gallery = true; 690e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 691288c0443SJeremy L Thompson } 692288c0443SJeremy L Thompson 693288c0443SJeremy L Thompson /** 694ca94c3ddSJeremy L Thompson @brief Create an identity `CeedQFunction`. 6954385fb7fSSebastian Grimberg 696ea61e9acSJeremy L Thompson Inputs are written into outputs in the order given. 697ca94c3ddSJeremy 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. 698ca94c3ddSJeremy 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. 6990219ea01SJeremy L Thompson 700ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 701ca94c3ddSJeremy L Thompson @param[in] size Size of the `CeedQFunction` fields 702ca94c3ddSJeremy L Thompson @param[in] in_mode @ref CeedEvalMode for input to `CeedQFunction` 703ca94c3ddSJeremy L Thompson @param[in] out_mode @ref CeedEvalMode for output to `CeedQFunction` 704ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 7050219ea01SJeremy L Thompson 7060219ea01SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7070219ea01SJeremy L Thompson 7087a982d89SJeremy L. Thompson @ref User 7090219ea01SJeremy L Thompson **/ 7102b730f8bSJeremy L Thompson int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf) { 7111c66c397SJeremy L Thompson CeedQFunctionContext ctx; 7121c66c397SJeremy L Thompson CeedContextFieldLabel size_label; 7131c66c397SJeremy L Thompson 7142b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInteriorByName(ceed, "Identity", qf)); 7152b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddInput(*qf, "input", size, in_mode)); 7162b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddOutput(*qf, "output", size, out_mode)); 7170219ea01SJeremy L Thompson 718f04ea552SJeremy L Thompson (*qf)->is_identity = true; 719547dbd6fSJeremy L Thompson 7202b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(*qf, &ctx)); 7212b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, "size", &size_label)); 7222b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetInt32(ctx, size_label, &size)); 723e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7240219ea01SJeremy L Thompson } 7250219ea01SJeremy L Thompson 7260219ea01SJeremy L Thompson /** 727ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedQFunction`. 7284385fb7fSSebastian Grimberg 729ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedQFunctionDestroy(). 730512bb800SJeremy L Thompson 731ca94c3ddSJeremy 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`. 732ca94c3ddSJeremy L Thompson This `CeedQFunction` will be destroyed if `*qf_copy` is the only reference to this `CeedQFunction`. 7339560d06aSjeremylt 734ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to copy reference to 7359560d06aSjeremylt @param[out] qf_copy Variable to store copied reference 7369560d06aSjeremylt 7379560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7389560d06aSjeremylt 7399560d06aSjeremylt @ref User 7409560d06aSjeremylt **/ 7419560d06aSjeremylt int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy) { 7422b730f8bSJeremy L Thompson CeedCall(CeedQFunctionReference(qf)); 7432b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(qf_copy)); 7449560d06aSjeremylt *qf_copy = qf; 7459560d06aSjeremylt return CEED_ERROR_SUCCESS; 7469560d06aSjeremylt } 7479560d06aSjeremylt 7489560d06aSjeremylt /** 749ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` input 750b11c1e72Sjeremylt 751ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 752ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 753ca94c3ddSJeremy 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. 754ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 755ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 756ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 757ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 758ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 759b11c1e72Sjeremylt 760b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 761dfdf5a53Sjeremylt 7627a982d89SJeremy L. Thompson @ref User 763b11c1e72Sjeremylt **/ 7642b730f8bSJeremy L Thompson int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 7651203703bSJeremy L Thompson bool is_immutable; 7661203703bSJeremy L Thompson Ceed ceed; 7671203703bSJeremy L Thompson 7681203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 7691203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 7701203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "QFunction cannot be changed after set as immutable"); 7711203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT || size == 1, ceed, CEED_ERROR_DIMENSION, "CEED_EVAL_WEIGHT should have size 1"); 772643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 7731203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 774643fbb69SJeremy L Thompson } 775643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 7761203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 777643fbb69SJeremy L Thompson } 7782b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->input_fields[qf->num_input_fields], field_name, size, eval_mode)); 779d1d35e2fSjeremylt qf->num_input_fields++; 780e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 781d7b241e6Sjeremylt } 782d7b241e6Sjeremylt 783b11c1e72Sjeremylt /** 784ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` output 785b11c1e72Sjeremylt 786ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 787ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 788ca94c3ddSJeremy 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. 789ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 790ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 791ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 792ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 793ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl. 794b11c1e72Sjeremylt 795b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 796dfdf5a53Sjeremylt 7977a982d89SJeremy L. Thompson @ref User 798b11c1e72Sjeremylt **/ 7992b730f8bSJeremy L Thompson int CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 8001203703bSJeremy L Thompson bool is_immutable; 8011203703bSJeremy L Thompson Ceed ceed; 8021203703bSJeremy L Thompson 8031203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 8041203703bSJeremy L Thompson CeedCall(CeedQFunctionIsImmutable(qf, &is_immutable)); 8051203703bSJeremy L Thompson CeedCheck(!is_immutable, ceed, CEED_ERROR_MAJOR, "CeedQFunction cannot be changed after set as immutable"); 8061203703bSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT, ceed, CEED_ERROR_DIMENSION, "Cannot create CeedQFunction output with CEED_EVAL_WEIGHT"); 807643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 8081203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 809643fbb69SJeremy L Thompson } 810643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 8111203703bSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 812643fbb69SJeremy L Thompson } 8132b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->output_fields[qf->num_output_fields], field_name, size, eval_mode)); 814d1d35e2fSjeremylt qf->num_output_fields++; 815e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 816d7b241e6Sjeremylt } 817d7b241e6Sjeremylt 818dfdf5a53Sjeremylt /** 819ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunctionField` of a `CeedQFunction` 82043bbe138SJeremy L Thompson 821ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 822f04ea552SJeremy L Thompson 823ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 824f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 825f74ec584SJeremy L Thompson @param[out] input_fields Variable to store input fields 826f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 827f74ec584SJeremy L Thompson @param[out] output_fields Variable to store output fields 82843bbe138SJeremy L Thompson 82943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83043bbe138SJeremy L Thompson 831e9b533fbSJeremy L Thompson @ref Advanced 83243bbe138SJeremy L Thompson **/ 8332b730f8bSJeremy L Thompson int CeedQFunctionGetFields(CeedQFunction qf, CeedInt *num_input_fields, CeedQFunctionField **input_fields, CeedInt *num_output_fields, 83443bbe138SJeremy L Thompson CeedQFunctionField **output_fields) { 8351203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 83643bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = qf->num_input_fields; 83743bbe138SJeremy L Thompson if (input_fields) *input_fields = qf->input_fields; 83843bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = qf->num_output_fields; 83943bbe138SJeremy L Thompson if (output_fields) *output_fields = qf->output_fields; 84043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84143bbe138SJeremy L Thompson } 84243bbe138SJeremy L Thompson 84343bbe138SJeremy L Thompson /** 844ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedQFunctionField` 84543bbe138SJeremy L Thompson 846ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 84743bbe138SJeremy L Thompson @param[out] field_name Variable to store the field name 84843bbe138SJeremy L Thompson 84943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85043bbe138SJeremy L Thompson 851e9b533fbSJeremy L Thompson @ref Advanced 85243bbe138SJeremy L Thompson **/ 8536f8994e9SJeremy L Thompson int CeedQFunctionFieldGetName(CeedQFunctionField qf_field, const char **field_name) { 8546f8994e9SJeremy L Thompson *field_name = qf_field->field_name; 85543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 85643bbe138SJeremy L Thompson } 85743bbe138SJeremy L Thompson 85843bbe138SJeremy L Thompson /** 859ca94c3ddSJeremy L Thompson @brief Get the number of components of a `CeedQFunctionField` 86043bbe138SJeremy L Thompson 861ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 86243bbe138SJeremy L Thompson @param[out] size Variable to store the size of the field 86343bbe138SJeremy L Thompson 86443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 86543bbe138SJeremy L Thompson 866e9b533fbSJeremy L Thompson @ref Advanced 86743bbe138SJeremy L Thompson **/ 86843bbe138SJeremy L Thompson int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field, CeedInt *size) { 86943bbe138SJeremy L Thompson *size = qf_field->size; 87043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 87143bbe138SJeremy L Thompson } 87243bbe138SJeremy L Thompson 87343bbe138SJeremy L Thompson /** 874ca94c3ddSJeremy L Thompson @brief Get the @ref CeedEvalMode of a `CeedQFunctionField` 87543bbe138SJeremy L Thompson 876ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 87743bbe138SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 87843bbe138SJeremy L Thompson 87943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 88043bbe138SJeremy L Thompson 881e9b533fbSJeremy L Thompson @ref Advanced 88243bbe138SJeremy L Thompson **/ 8832b730f8bSJeremy L Thompson int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field, CeedEvalMode *eval_mode) { 88443bbe138SJeremy L Thompson *eval_mode = qf_field->eval_mode; 88543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 88643bbe138SJeremy L Thompson } 88743bbe138SJeremy L Thompson 88843bbe138SJeremy L Thompson /** 889ab747706SJeremy L Thompson @brief Get the data of a `CeedQFunctionField`. 890ab747706SJeremy L Thompson 891ab747706SJeremy L Thompson Any arguments set as `NULL` are ignored. 892ab747706SJeremy L Thompson 893ab747706SJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 894ab747706SJeremy L Thompson @param[out] field_name Variable to store the field name 895ab747706SJeremy L Thompson @param[out] size Variable to store the size of the field 896ab747706SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 897ab747706SJeremy L Thompson 898ab747706SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 899ab747706SJeremy L Thompson 900ab747706SJeremy L Thompson @ref Advanced 901ab747706SJeremy L Thompson **/ 9026f8994e9SJeremy L Thompson int CeedQFunctionFieldGetData(CeedQFunctionField qf_field, const char **field_name, CeedInt *size, CeedEvalMode *eval_mode) { 903ab747706SJeremy L Thompson if (field_name) CeedCall(CeedQFunctionFieldGetName(qf_field, field_name)); 904ab747706SJeremy L Thompson if (size) CeedCall(CeedQFunctionFieldGetSize(qf_field, size)); 905ab747706SJeremy L Thompson if (eval_mode) CeedCall(CeedQFunctionFieldGetEvalMode(qf_field, eval_mode)); 906ab747706SJeremy L Thompson return CEED_ERROR_SUCCESS; 907ab747706SJeremy L Thompson } 908ab747706SJeremy L Thompson 909ab747706SJeremy L Thompson /** 910ca94c3ddSJeremy L Thompson @brief Set global context for a `CeedQFunction` 911b11c1e72Sjeremylt 912ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 913ea61e9acSJeremy L Thompson @param[in] ctx Context data to set 914b11c1e72Sjeremylt 915b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 916dfdf5a53Sjeremylt 9177a982d89SJeremy L. Thompson @ref User 918b11c1e72Sjeremylt **/ 919777ff853SJeremy L Thompson int CeedQFunctionSetContext(CeedQFunction qf, CeedQFunctionContext ctx) { 9202b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&qf->ctx)); 921d7b241e6Sjeremylt qf->ctx = ctx; 922db002c03SJeremy L Thompson if (ctx) CeedCall(CeedQFunctionContextReference(ctx)); 923e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 924d7b241e6Sjeremylt } 925d7b241e6Sjeremylt 926b11c1e72Sjeremylt /** 927ca94c3ddSJeremy L Thompson @brief Set writability of `CeedQFunctionContext` when calling the `CeedQFunctionUser`. 9284385fb7fSSebastian Grimberg 929859c15bbSJames Wright The default value is `is_writable == true`. 930441428dfSJeremy L Thompson 931ca94c3ddSJeremy L Thompson Setting `is_writable == true` indicates the `CeedQFunctionUser` writes into the `CeedQFunctionContext` and requires memory synchronization after calling @ref CeedQFunctionApply(). 932441428dfSJeremy L Thompson 933ca94c3ddSJeremy L Thompson Setting 'is_writable == false' asserts that `CeedQFunctionUser` does not modify the `CeedQFunctionContext`. 934ea61e9acSJeremy L Thompson Violating this assertion may lead to inconsistent data. 935441428dfSJeremy L Thompson 936441428dfSJeremy L Thompson Setting `is_writable == false` may offer a performance improvement on GPU backends. 937441428dfSJeremy L Thompson 938ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 939ca94c3ddSJeremy L Thompson @param[in] is_writable Boolean flag for writability status 940441428dfSJeremy L Thompson 941441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 942441428dfSJeremy L Thompson 943441428dfSJeremy L Thompson @ref User 944441428dfSJeremy L Thompson **/ 945441428dfSJeremy L Thompson int CeedQFunctionSetContextWritable(CeedQFunction qf, bool is_writable) { 946441428dfSJeremy L Thompson qf->is_context_writable = is_writable; 947441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 948441428dfSJeremy L Thompson } 949441428dfSJeremy L Thompson 950441428dfSJeremy L Thompson /** 951ca94c3ddSJeremy L Thompson @brief Set estimated number of FLOPs per quadrature required to apply `CeedQFunction` 9526e15d496SJeremy L Thompson 953ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 954ea61e9acSJeremy L Thompson @param[out] flops FLOPs per quadrature point estimate 9556e15d496SJeremy L Thompson 9566e15d496SJeremy L Thompson @ref Backend 9576e15d496SJeremy L Thompson **/ 9589d36ca50SJeremy L Thompson int CeedQFunctionSetUserFlopsEstimate(CeedQFunction qf, CeedSize flops) { 9591203703bSJeremy L Thompson Ceed ceed; 9601203703bSJeremy L Thompson 9611203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 9621203703bSJeremy L Thompson CeedCheck(flops >= 0, ceed, CEED_ERROR_INCOMPATIBLE, "Must set non-negative FLOPs estimate"); 9636e15d496SJeremy L Thompson qf->user_flop_estimate = flops; 9646e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 9656e15d496SJeremy L Thompson } 9666e15d496SJeremy L Thompson 9676e15d496SJeremy L Thompson /** 968ca94c3ddSJeremy L Thompson @brief View a `CeedQFunction` 96975affc3bSjeremylt 970ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to view 971ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 97275affc3bSjeremylt 97375affc3bSjeremylt @return Error code: 0 - success, otherwise - failure 97475affc3bSjeremylt 9757a982d89SJeremy L. Thompson @ref User 97675affc3bSjeremylt **/ 97775affc3bSjeremylt int CeedQFunctionView(CeedQFunction qf, FILE *stream) { 978*7d023984SJeremy L Thompson const char *kernel_name; 97975affc3bSjeremylt 9802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetKernelName(qf, &kernel_name)); 9812b730f8bSJeremy L Thompson fprintf(stream, "%sCeedQFunction - %s\n", qf->is_gallery ? "Gallery " : "User ", qf->is_gallery ? qf->gallery_name : kernel_name); 98275affc3bSjeremylt 9832b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " input field%s:\n", qf->num_input_fields, qf->num_input_fields > 1 ? "s" : ""); 984d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_input_fields; i++) { 9852b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->input_fields[i], i, 1, stream)); 98675affc3bSjeremylt } 98775affc3bSjeremylt 9882b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " output field%s:\n", qf->num_output_fields, qf->num_output_fields > 1 ? "s" : ""); 989d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_output_fields; i++) { 9902b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->output_fields[i], i, 0, stream)); 99175affc3bSjeremylt } 992e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 99375affc3bSjeremylt } 99475affc3bSjeremylt 99575affc3bSjeremylt /** 996ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedQFunction` 997b7c9bbdaSJeremy L Thompson 998ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 999ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store`Ceed` 1000b7c9bbdaSJeremy L Thompson 1001b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1002b7c9bbdaSJeremy L Thompson 1003b7c9bbdaSJeremy L Thompson @ref Advanced 1004b7c9bbdaSJeremy L Thompson **/ 1005b7c9bbdaSJeremy L Thompson int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 1006b7c9bbdaSJeremy L Thompson *ceed = qf->ceed; 1007b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 1008b7c9bbdaSJeremy L Thompson } 1009b7c9bbdaSJeremy L Thompson 1010b7c9bbdaSJeremy L Thompson /** 1011ca94c3ddSJeremy L Thompson @brief Apply the action of a `CeedQFunction` 1012b11c1e72Sjeremylt 1013ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 1014f04ea552SJeremy L Thompson 1015ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 1016ea61e9acSJeremy L Thompson @param[in] Q Number of quadrature points 1017ca94c3ddSJeremy L Thompson @param[in] u Array of input `CeedVector` 1018ca94c3ddSJeremy L Thompson @param[out] v Array of output `CeedVector` 1019b11c1e72Sjeremylt 1020b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1021dfdf5a53Sjeremylt 10227a982d89SJeremy L. Thompson @ref User 1023b11c1e72Sjeremylt **/ 10242b730f8bSJeremy L Thompson int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, CeedVector *u, CeedVector *v) { 10251203703bSJeremy L Thompson CeedInt vec_length; 10261203703bSJeremy L Thompson Ceed ceed; 10271203703bSJeremy L Thompson 10281203703bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 10291203703bSJeremy L Thompson CeedCheck(qf->Apply, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionApply"); 10301203703bSJeremy L Thompson CeedCall(CeedQFunctionGetVectorLength(qf, &vec_length)); 10311203703bSJeremy 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, 10321203703bSJeremy L Thompson qf->vec_length); 10331203703bSJeremy L Thompson CeedCall(CeedQFunctionSetImmutable(qf)); 10342b730f8bSJeremy L Thompson CeedCall(qf->Apply(qf, Q, u, v)); 1035e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1036d7b241e6Sjeremylt } 1037d7b241e6Sjeremylt 1038b11c1e72Sjeremylt /** 1039ca94c3ddSJeremy L Thompson @brief Destroy a `CeedQFunction` 1040b11c1e72Sjeremylt 1041ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to destroy 1042b11c1e72Sjeremylt 1043b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1044dfdf5a53Sjeremylt 10457a982d89SJeremy L. Thompson @ref User 1046b11c1e72Sjeremylt **/ 1047d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) { 1048ad6481ceSJeremy L Thompson if (!*qf || --(*qf)->ref_count > 0) { 1049ad6481ceSJeremy L Thompson *qf = NULL; 1050ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1051ad6481ceSJeremy L Thompson } 1052fe2413ffSjeremylt // Backend destroy 1053d7b241e6Sjeremylt if ((*qf)->Destroy) { 10542b730f8bSJeremy L Thompson CeedCall((*qf)->Destroy(*qf)); 1055d7b241e6Sjeremylt } 1056fe2413ffSjeremylt // Free fields 105792ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_input_fields; i++) { 10582b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->input_fields[i]).field_name)); 10592b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields[i])); 1060fe2413ffSjeremylt } 106192ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_output_fields; i++) { 10622b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->output_fields[i]).field_name)); 10632b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields[i])); 1064fe2413ffSjeremylt } 10652b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields)); 10662b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields)); 1067777ff853SJeremy L Thompson 1068777ff853SJeremy L Thompson // User context data object 10692b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&(*qf)->ctx)); 1070fe2413ffSjeremylt 10712b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->user_source)); 10722b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->source_path)); 10732b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->gallery_name)); 10742b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->kernel_name)); 10752b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*qf)->ceed)); 10762b730f8bSJeremy L Thompson CeedCall(CeedFree(qf)); 1077e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1078d7b241e6Sjeremylt } 1079d7b241e6Sjeremylt 1080d7b241e6Sjeremylt /// @} 1081