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 27*ca94c3ddSJeremy 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 /** 50*ca94c3ddSJeremy L Thompson @brief Register a gallery `CeedQFunction` 51288c0443SJeremy L Thompson 52ea61e9acSJeremy L Thompson @param[in] name Name for this backend to respond to 53*ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunction`, "\path\CEED_DIR\gallery\folder\file.h:function_name" 54*ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 55*ca94c3ddSJeremy 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. 57*ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 58*ca94c3ddSJeremy 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 } 8558c07c4fSSebastian Grimberg // LCOV_EXCL_START 86*ca94c3ddSJeremy L Thompson CeedCheck(ierr == 0, NULL, CEED_ERROR_MAJOR, "Too many gallery CeedQFunctions"); 8758c07c4fSSebastian Grimberg // LCOV_EXCL_STOP 88e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 89288c0443SJeremy L Thompson } 90288c0443SJeremy L Thompson 91288c0443SJeremy L Thompson /** 92*ca94c3ddSJeremy L Thompson @brief Set a `CeedQFunction` field, used by @ref CeedQFunctionAddInput() and @ref CeedQFunctionAddOutput() 937a982d89SJeremy L. Thompson 94*ca94c3ddSJeremy L Thompson @param[out] f `CeedQFunctionField` 95*ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 96*ca94c3ddSJeremy 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. 97*ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 98*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_WEIGHT to use quadrature weights, 99*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 100*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 101*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 102*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 1037a982d89SJeremy L. Thompson 1047a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1057a982d89SJeremy L. Thompson 1067a982d89SJeremy L. Thompson @ref Developer 1077a982d89SJeremy L. Thompson **/ 1082b730f8bSJeremy L Thompson static int CeedQFunctionFieldSet(CeedQFunctionField *f, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 1092b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, f)); 1102b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&(*f)->field_name)); 1117a982d89SJeremy L. Thompson (*f)->size = size; 112d1d35e2fSjeremylt (*f)->eval_mode = eval_mode; 113e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1147a982d89SJeremy L. Thompson } 1157a982d89SJeremy L. Thompson 1167a982d89SJeremy L. Thompson /** 117*ca94c3ddSJeremy L Thompson @brief View a field of a `CeedQFunction` 1187a982d89SJeremy L. Thompson 119*ca94c3ddSJeremy L Thompson @param[in] field `CeedQFunction` field to view 120d1d35e2fSjeremylt @param[in] field_number Number of field being viewed 1214c4400c7SValeria Barra @param[in] in true for input field, false for output 122*ca94c3ddSJeremy L Thompson @param[in] stream Stream to view to, e.g., `stdout` 1237a982d89SJeremy L. Thompson 1247a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1257a982d89SJeremy L. Thompson 1267a982d89SJeremy L. Thompson @ref Utility 1277a982d89SJeremy L. Thompson **/ 1282b730f8bSJeremy L Thompson static int CeedQFunctionFieldView(CeedQFunctionField field, CeedInt field_number, bool in, FILE *stream) { 1297a982d89SJeremy L. Thompson const char *inout = in ? "Input" : "Output"; 1308229195eSjeremylt char *field_name; 1318229195eSjeremylt CeedInt size; 1328229195eSjeremylt CeedEvalMode eval_mode; 1331c66c397SJeremy L Thompson 1341c66c397SJeremy L Thompson CeedCall(CeedQFunctionFieldGetName(field, &field_name)); 1351c66c397SJeremy L Thompson CeedCall(CeedQFunctionFieldGetSize(field, &size)); 1362b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldGetEvalMode(field, &eval_mode)); 1372b730f8bSJeremy L Thompson fprintf(stream, 1382b730f8bSJeremy L Thompson " %s field %" CeedInt_FMT 1392b730f8bSJeremy L Thompson ":\n" 1407a982d89SJeremy L. Thompson " Name: \"%s\"\n" 1412b730f8bSJeremy L Thompson " Size: %" CeedInt_FMT 1422b730f8bSJeremy L Thompson "\n" 1437a982d89SJeremy L. Thompson " EvalMode: \"%s\"\n", 1448229195eSjeremylt inout, field_number, field_name, size, CeedEvalModes[eval_mode]); 145e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1467a982d89SJeremy L. Thompson } 1477a982d89SJeremy L. Thompson 148777ff853SJeremy L Thompson /** 149777ff853SJeremy L Thompson @brief Set flag to determine if Fortran interface is used 150777ff853SJeremy L Thompson 151ea61e9acSJeremy L Thompson @param[in,out] qf CeedQFunction 152ea61e9acSJeremy L Thompson @param[in] status Boolean value to set as Fortran status 153777ff853SJeremy L Thompson 154777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 155777ff853SJeremy L Thompson 156777ff853SJeremy L Thompson @ref Backend 157777ff853SJeremy L Thompson **/ 158777ff853SJeremy L Thompson int CeedQFunctionSetFortranStatus(CeedQFunction qf, bool status) { 159f04ea552SJeremy L Thompson qf->is_fortran = status; 160e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 161777ff853SJeremy L Thompson } 162777ff853SJeremy L Thompson 1637a982d89SJeremy L. Thompson /// @} 1647a982d89SJeremy L. Thompson 1657a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1667a982d89SJeremy L. Thompson /// CeedQFunction Backend API 1677a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1687a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionBackend 1697a982d89SJeremy L. Thompson /// @{ 1707a982d89SJeremy L. Thompson 1717a982d89SJeremy L. Thompson /** 172*ca94c3ddSJeremy L Thompson @brief Get the vector length of a `CeedQFunction` 1737a982d89SJeremy L. Thompson 174*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 175d1d35e2fSjeremylt @param[out] vec_length Variable to store vector length 1767a982d89SJeremy L. Thompson 1777a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1787a982d89SJeremy L. Thompson 1797a982d89SJeremy L. Thompson @ref Backend 1807a982d89SJeremy L. Thompson **/ 181d1d35e2fSjeremylt int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vec_length) { 182d1d35e2fSjeremylt *vec_length = qf->vec_length; 183e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1847a982d89SJeremy L. Thompson } 1857a982d89SJeremy L. Thompson 1867a982d89SJeremy L. Thompson /** 187*ca94c3ddSJeremy L Thompson @brief Get the number of inputs and outputs to a `CeedQFunction` 1887a982d89SJeremy L. Thompson 189*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 190d1d35e2fSjeremylt @param[out] num_input Variable to store number of input fields 191d1d35e2fSjeremylt @param[out] num_output Variable to store number of output fields 1927a982d89SJeremy L. Thompson 1937a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 1947a982d89SJeremy L. Thompson 1957a982d89SJeremy L. Thompson @ref Backend 1967a982d89SJeremy L. Thompson **/ 1972b730f8bSJeremy L Thompson int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *num_input, CeedInt *num_output) { 198d1d35e2fSjeremylt if (num_input) *num_input = qf->num_input_fields; 199d1d35e2fSjeremylt if (num_output) *num_output = qf->num_output_fields; 200e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2017a982d89SJeremy L. Thompson } 2027a982d89SJeremy L. Thompson 2037a982d89SJeremy L. Thompson /** 204*ca94c3ddSJeremy L Thompson @brief Get the name of the user function for a `CeedQFunction` 2057a982d89SJeremy L. Thompson 206*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 20743e1b16fSJeremy L Thompson @param[out] kernel_name Variable to store source path string 2087a982d89SJeremy L. Thompson 2097a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 2107a982d89SJeremy L. Thompson 2117a982d89SJeremy L. Thompson @ref Backend 2127a982d89SJeremy L. Thompson **/ 21343e1b16fSJeremy L Thompson int CeedQFunctionGetKernelName(CeedQFunction qf, char **kernel_name) { 214ca5eadf8SJeremy L Thompson if (!qf->kernel_name) { 215ca5eadf8SJeremy L Thompson Ceed ceed; 216ca5eadf8SJeremy L Thompson char *kernel_name_copy; 217ca5eadf8SJeremy L Thompson 2181c66c397SJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 219ca5eadf8SJeremy L Thompson if (qf->user_source) { 220ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 221ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 222ca5eadf8SJeremy L Thompson 2232b730f8bSJeremy L Thompson CeedCall(CeedCalloc(kernel_name_len + 1, &kernel_name_copy)); 224ca5eadf8SJeremy L Thompson memcpy(kernel_name_copy, kernel_name, kernel_name_len); 225ca5eadf8SJeremy L Thompson } else { 2262b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &kernel_name_copy)); 227ca5eadf8SJeremy L Thompson } 228ca5eadf8SJeremy L Thompson qf->kernel_name = kernel_name_copy; 229ca5eadf8SJeremy L Thompson } 230ca5eadf8SJeremy L Thompson 23143e1b16fSJeremy L Thompson *kernel_name = (char *)qf->kernel_name; 23243e1b16fSJeremy L Thompson return CEED_ERROR_SUCCESS; 23343e1b16fSJeremy L Thompson } 23443e1b16fSJeremy L Thompson 23543e1b16fSJeremy L Thompson /** 236*ca94c3ddSJeremy L Thompson @brief Get the source path string for a `CeedQFunction` 23743e1b16fSJeremy L Thompson 238*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 23943e1b16fSJeremy L Thompson @param[out] source_path Variable to store source path string 24043e1b16fSJeremy L Thompson 24143e1b16fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 24243e1b16fSJeremy L Thompson 24343e1b16fSJeremy L Thompson @ref Backend 24443e1b16fSJeremy L Thompson **/ 24543e1b16fSJeremy L Thompson int CeedQFunctionGetSourcePath(CeedQFunction qf, char **source_path) { 246ca5eadf8SJeremy L Thompson if (!qf->source_path && qf->user_source) { 247ca5eadf8SJeremy L Thompson Ceed ceed; 248ca5eadf8SJeremy L Thompson bool is_absolute_path; 249ca5eadf8SJeremy L Thompson char *absolute_path, *source_path_copy; 250ca5eadf8SJeremy L Thompson const char *kernel_name = strrchr(qf->user_source, ':') + 1; 251ca5eadf8SJeremy L Thompson size_t kernel_name_len = strlen(kernel_name); 252ca5eadf8SJeremy L Thompson 2532b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetCeed(qf, &ceed)); 2542b730f8bSJeremy L Thompson CeedCall(CeedCheckFilePath(ceed, qf->user_source, &is_absolute_path)); 255ca5eadf8SJeremy L Thompson if (is_absolute_path) { 256ca5eadf8SJeremy L Thompson absolute_path = (char *)qf->user_source; 257ca5eadf8SJeremy L Thompson } else { 2582b730f8bSJeremy L Thompson CeedCall(CeedGetJitAbsolutePath(ceed, qf->user_source, &absolute_path)); 259ca5eadf8SJeremy L Thompson } 260ca5eadf8SJeremy L Thompson 261ca5eadf8SJeremy L Thompson size_t source_len = strlen(absolute_path) - kernel_name_len - 1; 2621c66c397SJeremy L Thompson 2632b730f8bSJeremy L Thompson CeedCall(CeedCalloc(source_len + 1, &source_path_copy)); 264ca5eadf8SJeremy L Thompson memcpy(source_path_copy, absolute_path, source_len); 265ca5eadf8SJeremy L Thompson qf->source_path = source_path_copy; 266ca5eadf8SJeremy L Thompson 2672b730f8bSJeremy L Thompson if (!is_absolute_path) CeedCall(CeedFree(&absolute_path)); 268ca5eadf8SJeremy L Thompson } 269ca5eadf8SJeremy L Thompson 27043e1b16fSJeremy L Thompson *source_path = (char *)qf->source_path; 271e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2727a982d89SJeremy L. Thompson } 2737a982d89SJeremy L. Thompson 2747a982d89SJeremy L. Thompson /** 275*ca94c3ddSJeremy L Thompson @brief Initialize and load `CeedQFunction` source file into string buffer, including full text of local files in place of `#include "local.h"`. 2764385fb7fSSebastian Grimberg 277*ca94c3ddSJeremy L Thompson The `buffer` is set to `NULL` if there is no `CeedQFunction` source file. 2784385fb7fSSebastian Grimberg 279*ca94c3ddSJeremy L Thompson Note: Caller is responsible for freeing the string buffer with @ref CeedFree(). 2803d3250a0SJeremy L Thompson 281*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 282f74ec584SJeremy L Thompson @param[out] source_buffer String buffer for source file contents 2833d3250a0SJeremy L Thompson 2843d3250a0SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2853d3250a0SJeremy L Thompson 2863d3250a0SJeremy L Thompson @ref Backend 2873d3250a0SJeremy L Thompson **/ 2883d3250a0SJeremy L Thompson int CeedQFunctionLoadSourceToBuffer(CeedQFunction qf, char **source_buffer) { 2893d3250a0SJeremy L Thompson char *source_path; 2903d3250a0SJeremy L Thompson 2912b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetSourcePath(qf, &source_path)); 2923d3250a0SJeremy L Thompson *source_buffer = NULL; 2933d3250a0SJeremy L Thompson if (source_path) { 2942b730f8bSJeremy L Thompson CeedCall(CeedLoadSourceToBuffer(qf->ceed, source_path, source_buffer)); 2953d3250a0SJeremy L Thompson } 2963d3250a0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2973d3250a0SJeremy L Thompson } 2983d3250a0SJeremy L Thompson 2993d3250a0SJeremy L Thompson /** 300*ca94c3ddSJeremy L Thompson @brief Get the User Function for a `CeedQFunction` 3017a982d89SJeremy L. Thompson 302*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 3037a982d89SJeremy L. Thompson @param[out] f Variable to store user function 3047a982d89SJeremy L. Thompson 3057a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3067a982d89SJeremy L. Thompson 3077a982d89SJeremy L. Thompson @ref Backend 3087a982d89SJeremy L. Thompson **/ 3097a982d89SJeremy L. Thompson int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) { 3107a982d89SJeremy L. Thompson *f = qf->function; 311e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3127a982d89SJeremy L. Thompson } 3137a982d89SJeremy L. Thompson 3147a982d89SJeremy L. Thompson /** 315*ca94c3ddSJeremy L Thompson @brief Get global context for a `CeedQFunction`. 3164385fb7fSSebastian Grimberg 317*ca94c3ddSJeremy L Thompson Note: For `CeedQFunction` from the Fortran interface, this function will return the Fortran context `CeedQFunctionContext`. 3187a982d89SJeremy L. Thompson 319ea61e9acSJeremy L Thompson @param[in] qf CeedQFunction 320777ff853SJeremy L Thompson @param[out] ctx Variable to store CeedQFunctionContext 3217a982d89SJeremy L. Thompson 3227a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3237a982d89SJeremy L. Thompson 3247a982d89SJeremy L. Thompson @ref Backend 3257a982d89SJeremy L. Thompson **/ 326777ff853SJeremy L Thompson int CeedQFunctionGetContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 3277a982d89SJeremy L. Thompson *ctx = qf->ctx; 328e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3297a982d89SJeremy L. Thompson } 3307a982d89SJeremy L. Thompson 3317a982d89SJeremy L. Thompson /** 332*ca94c3ddSJeremy L Thompson @brief Get context data of a `CeedQFunction` 333441428dfSJeremy L Thompson 334*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 335ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 336ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 337441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 338441428dfSJeremy L Thompson 339441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 340441428dfSJeremy L Thompson 341441428dfSJeremy L Thompson @ref Backend 342441428dfSJeremy L Thompson **/ 3432b730f8bSJeremy L Thompson int CeedQFunctionGetContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 344441428dfSJeremy L Thompson bool is_writable; 345441428dfSJeremy L Thompson CeedQFunctionContext ctx; 346441428dfSJeremy L Thompson 3472b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 348441428dfSJeremy L Thompson if (ctx) { 3492b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 350441428dfSJeremy L Thompson if (is_writable) { 3512b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 352441428dfSJeremy L Thompson } else { 3532b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 354441428dfSJeremy L Thompson } 355441428dfSJeremy L Thompson } else { 356441428dfSJeremy L Thompson *(void **)data = NULL; 357441428dfSJeremy L Thompson } 358441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 359441428dfSJeremy L Thompson } 360441428dfSJeremy L Thompson 361441428dfSJeremy L Thompson /** 362*ca94c3ddSJeremy L Thompson @brief Restore context data of a `CeedQFunction` 363441428dfSJeremy L Thompson 364*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 365ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 366441428dfSJeremy L Thompson 367441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 368441428dfSJeremy L Thompson 369441428dfSJeremy L Thompson @ref Backend 370441428dfSJeremy L Thompson **/ 371441428dfSJeremy L Thompson int CeedQFunctionRestoreContextData(CeedQFunction qf, void *data) { 372441428dfSJeremy L Thompson bool is_writable; 373441428dfSJeremy L Thompson CeedQFunctionContext ctx; 374441428dfSJeremy L Thompson 3752b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(qf, &ctx)); 376441428dfSJeremy L Thompson if (ctx) { 3772b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 378441428dfSJeremy L Thompson if (is_writable) { 3792b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 380441428dfSJeremy L Thompson } else { 3812b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 382441428dfSJeremy L Thompson } 383441428dfSJeremy L Thompson } 3845f249b39SJeremy L Thompson *(void **)data = NULL; 385441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 386441428dfSJeremy L Thompson } 387441428dfSJeremy L Thompson 388441428dfSJeremy L Thompson /** 389*ca94c3ddSJeremy L Thompson @brief Get true user context for a `CeedQFunction` 3904385fb7fSSebastian Grimberg 391*ca94c3ddSJeremy L Thompson Note: For all `CeedQFunction` this function will return the user `CeedQFunctionContext` and not interface context `CeedQFunctionContext`, if any such object exists. 3927a982d89SJeremy L. Thompson 393*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 394*ca94c3ddSJeremy L Thompson @param[out] ctx Variable to store `CeedQFunctionContext` 3957a982d89SJeremy L. Thompson 3967a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 3977a982d89SJeremy L. Thompson @ref Backend 3987a982d89SJeremy L. Thompson **/ 399777ff853SJeremy L Thompson int CeedQFunctionGetInnerContext(CeedQFunction qf, CeedQFunctionContext *ctx) { 400f04ea552SJeremy L Thompson if (qf->is_fortran) { 401d1d35e2fSjeremylt CeedFortranContext fortran_ctx = NULL; 4021c66c397SJeremy L Thompson 4032b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(qf->ctx, CEED_MEM_HOST, &fortran_ctx)); 4048cb0412aSJeremy L Thompson *ctx = fortran_ctx->inner_ctx; 4052b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(qf->ctx, (void *)&fortran_ctx)); 4067a982d89SJeremy L. Thompson } else { 4077a982d89SJeremy L. Thompson *ctx = qf->ctx; 4087a982d89SJeremy L. Thompson } 409e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4107a982d89SJeremy L. Thompson } 4117a982d89SJeremy L. Thompson 4127a982d89SJeremy L. Thompson /** 413*ca94c3ddSJeremy L Thompson @brief Get inner context data of a `CeedQFunction` 414441428dfSJeremy L Thompson 415*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 416ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 417ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 418441428dfSJeremy L Thompson @param[out] data Data on memory type mem_type 419441428dfSJeremy L Thompson 420441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 421441428dfSJeremy L Thompson 422441428dfSJeremy L Thompson @ref Backend 423441428dfSJeremy L Thompson **/ 4242b730f8bSJeremy L Thompson int CeedQFunctionGetInnerContextData(CeedQFunction qf, CeedMemType mem_type, void *data) { 425441428dfSJeremy L Thompson bool is_writable; 426441428dfSJeremy L Thompson CeedQFunctionContext ctx; 427441428dfSJeremy L Thompson 4282b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 429441428dfSJeremy L Thompson if (ctx) { 4302b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 431441428dfSJeremy L Thompson if (is_writable) { 4322b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, mem_type, data)); 433441428dfSJeremy L Thompson } else { 4342b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, mem_type, data)); 435441428dfSJeremy L Thompson } 436441428dfSJeremy L Thompson } else { 437441428dfSJeremy L Thompson *(void **)data = NULL; 438441428dfSJeremy L Thompson } 439441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 440441428dfSJeremy L Thompson } 441441428dfSJeremy L Thompson 442441428dfSJeremy L Thompson /** 443*ca94c3ddSJeremy L Thompson @brief Restore inner context data of a `CeedQFunction` 444441428dfSJeremy L Thompson 445*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 446ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 447441428dfSJeremy L Thompson 448441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 449441428dfSJeremy L Thompson 450441428dfSJeremy L Thompson @ref Backend 451441428dfSJeremy L Thompson **/ 452441428dfSJeremy L Thompson int CeedQFunctionRestoreInnerContextData(CeedQFunction qf, void *data) { 453441428dfSJeremy L Thompson bool is_writable; 454441428dfSJeremy L Thompson CeedQFunctionContext ctx; 455441428dfSJeremy L Thompson 4562b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetInnerContext(qf, &ctx)); 457441428dfSJeremy L Thompson if (ctx) { 4582b730f8bSJeremy L Thompson CeedCall(CeedQFunctionIsContextWritable(qf, &is_writable)); 459441428dfSJeremy L Thompson if (is_writable) { 4602b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, data)); 461441428dfSJeremy L Thompson } else { 4622b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, data)); 463441428dfSJeremy L Thompson } 464441428dfSJeremy L Thompson } 4655f249b39SJeremy L Thompson *(void **)data = NULL; 466441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 467441428dfSJeremy L Thompson } 468441428dfSJeremy L Thompson 469441428dfSJeremy L Thompson /** 470*ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunction` is identity 4717a982d89SJeremy L. Thompson 472*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 473d1d35e2fSjeremylt @param[out] is_identity Variable to store identity status 4747a982d89SJeremy L. Thompson 4757a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4767a982d89SJeremy L. Thompson 4777a982d89SJeremy L. Thompson @ref Backend 4787a982d89SJeremy L. Thompson **/ 479d1d35e2fSjeremylt int CeedQFunctionIsIdentity(CeedQFunction qf, bool *is_identity) { 480f04ea552SJeremy L Thompson *is_identity = qf->is_identity; 481e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4827a982d89SJeremy L. Thompson } 4837a982d89SJeremy L. Thompson 4847a982d89SJeremy L. Thompson /** 485*ca94c3ddSJeremy L Thompson @brief Determine if `CeedQFunctionContext` is writable 486441428dfSJeremy L Thompson 487*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 488ea61e9acSJeremy L Thompson @param[out] is_writable Variable to store context writeable status 489441428dfSJeremy L Thompson 490441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 491441428dfSJeremy L Thompson 492441428dfSJeremy L Thompson @ref Backend 493441428dfSJeremy L Thompson **/ 494441428dfSJeremy L Thompson int CeedQFunctionIsContextWritable(CeedQFunction qf, bool *is_writable) { 495441428dfSJeremy L Thompson *is_writable = qf->is_context_writable; 496441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 497441428dfSJeremy L Thompson } 498441428dfSJeremy L Thompson 499441428dfSJeremy L Thompson /** 500*ca94c3ddSJeremy L Thompson @brief Get backend data of a `CeedQFunction` 5017a982d89SJeremy L. Thompson 502*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 5037a982d89SJeremy L. Thompson @param[out] data Variable to store data 5047a982d89SJeremy L. Thompson 5057a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5067a982d89SJeremy L. Thompson 5077a982d89SJeremy L. Thompson @ref Backend 5087a982d89SJeremy L. Thompson **/ 509777ff853SJeremy L Thompson int CeedQFunctionGetData(CeedQFunction qf, void *data) { 510777ff853SJeremy L Thompson *(void **)data = qf->data; 511e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5127a982d89SJeremy L. Thompson } 5137a982d89SJeremy L. Thompson 5147a982d89SJeremy L. Thompson /** 515*ca94c3ddSJeremy L Thompson @brief Set backend data of a `CeedQFunction` 5167a982d89SJeremy L. Thompson 517*ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 518ea61e9acSJeremy L Thompson @param[in] data Data to set 5197a982d89SJeremy L. Thompson 5207a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5217a982d89SJeremy L. Thompson 5227a982d89SJeremy L. Thompson @ref Backend 5237a982d89SJeremy L. Thompson **/ 524777ff853SJeremy L Thompson int CeedQFunctionSetData(CeedQFunction qf, void *data) { 525777ff853SJeremy L Thompson qf->data = data; 526e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5277a982d89SJeremy L. Thompson } 5287a982d89SJeremy L. Thompson 5297a982d89SJeremy L. Thompson /** 530*ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `CeedQFunction` 53134359f16Sjeremylt 532*ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to increment the reference counter 53334359f16Sjeremylt 53434359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 53534359f16Sjeremylt 53634359f16Sjeremylt @ref Backend 53734359f16Sjeremylt **/ 5389560d06aSjeremylt int CeedQFunctionReference(CeedQFunction qf) { 53934359f16Sjeremylt qf->ref_count++; 54034359f16Sjeremylt return CEED_ERROR_SUCCESS; 54134359f16Sjeremylt } 54234359f16Sjeremylt 5436e15d496SJeremy L Thompson /** 544*ca94c3ddSJeremy L Thompson @brief Estimate number of FLOPs per quadrature required to apply `CeedQFunction` 5456e15d496SJeremy L Thompson 546*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 547ea61e9acSJeremy L Thompson @param[out] flops Address of variable to hold FLOPs estimate 5486e15d496SJeremy L Thompson 5496e15d496SJeremy L Thompson @ref Backend 5506e15d496SJeremy L Thompson **/ 5519d36ca50SJeremy L Thompson int CeedQFunctionGetFlopsEstimate(CeedQFunction qf, CeedSize *flops) { 5526574a04fSJeremy L Thompson CeedCheck(qf->user_flop_estimate > -1, qf->ceed, CEED_ERROR_INCOMPLETE, "Must set FLOPs estimate with CeedQFunctionSetUserFlopsEstimate"); 5536e15d496SJeremy L Thompson *flops = qf->user_flop_estimate; 5546e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 5556e15d496SJeremy L Thompson } 5566e15d496SJeremy L Thompson 5577a982d89SJeremy L. Thompson /// @} 5587a982d89SJeremy L. Thompson 5597a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5607a982d89SJeremy L. Thompson /// CeedQFunction Public API 5617a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 5627a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 5637a982d89SJeremy L. Thompson /// @{ 5647a982d89SJeremy L. Thompson 5657a982d89SJeremy L. Thompson /** 566*ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms 5677a982d89SJeremy L. Thompson 568*ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 569*ca94c3ddSJeremy L Thompson @param[in] vec_length Vector length. 570*ca94c3ddSJeremy L Thompson Caller must ensure that number of quadrature points is a multiple of `vec_length`. 571ea61e9acSJeremy L Thompson @param[in] f Function pointer to evaluate action at quadrature points. 572*ca94c3ddSJeremy L Thompson See `CeedQFunctionUser`. 573*ca94c3ddSJeremy L Thompson @param[in] source Absolute path to source of `CeedQFunctionUser`, "\abs_path\file.h:function_name". 574*ca94c3ddSJeremy 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.). 5754ada38baSJames Wright The entire contents of this file and all locally included files are used during JiT compilation for GPU backends. 5764ada38baSJames Wright All source files must be at the provided filepath at runtime for JiT to function. 577*ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 5787a982d89SJeremy L. Thompson 5797a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5807a982d89SJeremy L. Thompson 581*ca94c3ddSJeremy L Thompson See \ref CeedQFunctionUser for details on the call-back function `f` arguments. 5827a982d89SJeremy L. Thompson 5837a982d89SJeremy L. Thompson @ref User 5847a982d89SJeremy L. Thompson **/ 5852b730f8bSJeremy L Thompson int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vec_length, CeedQFunctionUser f, const char *source, CeedQFunction *qf) { 586ca5eadf8SJeremy L Thompson char *user_source_copy; 5877a982d89SJeremy L. Thompson 5887a982d89SJeremy L. Thompson if (!ceed->QFunctionCreate) { 5897a982d89SJeremy L. Thompson Ceed delegate; 5906574a04fSJeremy L Thompson 5912b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "QFunction")); 592*ca94c3ddSJeremy L Thompson CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionCreateInterior"); 5932b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(delegate, vec_length, f, source, qf)); 594e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5957a982d89SJeremy L. Thompson } 5967a982d89SJeremy L. Thompson 5976574a04fSJeremy L Thompson CeedCheck(!strlen(source) || strrchr(source, ':'), ceed, CEED_ERROR_INCOMPLETE, 5986574a04fSJeremy L Thompson "Provided path to source does not include function name. Provided: \"%s\"\nRequired: \"\\abs_path\\file.h:function_name\"", source); 59943e1b16fSJeremy L Thompson 6002b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, qf)); 601db002c03SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, &(*qf)->ceed)); 602d1d35e2fSjeremylt (*qf)->ref_count = 1; 603d1d35e2fSjeremylt (*qf)->vec_length = vec_length; 604f04ea552SJeremy L Thompson (*qf)->is_identity = false; 605441428dfSJeremy L Thompson (*qf)->is_context_writable = true; 6067a982d89SJeremy L. Thompson (*qf)->function = f; 6076e15d496SJeremy L Thompson (*qf)->user_flop_estimate = -1; 60843e1b16fSJeremy L Thompson if (strlen(source)) { 609ca5eadf8SJeremy L Thompson size_t user_source_len = strlen(source); 610ee5a26f2SJeremy L Thompson 6112b730f8bSJeremy L Thompson CeedCall(CeedCalloc(user_source_len + 1, &user_source_copy)); 612ca5eadf8SJeremy L Thompson memcpy(user_source_copy, source, user_source_len); 613ca5eadf8SJeremy L Thompson (*qf)->user_source = user_source_copy; 61443e1b16fSJeremy L Thompson } 6152b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->input_fields)); 6162b730f8bSJeremy L Thompson CeedCall(CeedCalloc(CEED_FIELD_MAX, &(*qf)->output_fields)); 6172b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionCreate(*qf)); 618e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6197a982d89SJeremy L. Thompson } 6207a982d89SJeremy L. Thompson 6217a982d89SJeremy L. Thompson /** 622*ca94c3ddSJeremy L Thompson @brief Create a `CeedQFunction` for evaluating interior (volumetric) terms by name 623288c0443SJeremy L Thompson 624*ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 625*ca94c3ddSJeremy L Thompson @param[in] name Name of `CeedQFunction` to use from gallery 626*ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 627288c0443SJeremy L Thompson 628288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 629288c0443SJeremy L Thompson 6307a982d89SJeremy L. Thompson @ref User 631288c0443SJeremy L Thompson **/ 6322b730f8bSJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name, CeedQFunction *qf) { 633f7e22acaSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX; 634288c0443SJeremy L Thompson 6352b730f8bSJeremy L Thompson CeedCall(CeedQFunctionRegisterAll()); 636288c0443SJeremy L Thompson // Find matching backend 637*ca94c3ddSJeremy L Thompson CeedCheck(name, ceed, CEED_ERROR_INCOMPLETE, "No CeedQFunction name provided"); 638288c0443SJeremy L Thompson for (size_t i = 0; i < num_qfunctions; i++) { 639288c0443SJeremy L Thompson size_t n; 640d1d35e2fSjeremylt const char *curr_name = gallery_qfunctions[i].name; 6412b730f8bSJeremy L Thompson for (n = 0; curr_name[n] && curr_name[n] == name[n]; n++) { 6422b730f8bSJeremy L Thompson } 643d1d35e2fSjeremylt if (n > match_len) { 644d1d35e2fSjeremylt match_len = n; 645f7e22acaSJeremy L Thompson match_index = i; 646288c0443SJeremy L Thompson } 647288c0443SJeremy L Thompson } 648*ca94c3ddSJeremy L Thompson CeedCheck(match_len > 0, ceed, CEED_ERROR_UNSUPPORTED, "No suitable gallery CeedQFunction"); 649288c0443SJeremy L Thompson 650288c0443SJeremy L Thompson // Create QFunction 6512b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInterior(ceed, gallery_qfunctions[match_index].vec_length, gallery_qfunctions[match_index].f, 6522b730f8bSJeremy L Thompson gallery_qfunctions[match_index].source, qf)); 653288c0443SJeremy L Thompson 654288c0443SJeremy L Thompson // QFunction specific setup 6552b730f8bSJeremy L Thompson CeedCall(gallery_qfunctions[match_index].init(ceed, name, *qf)); 656288c0443SJeremy L Thompson 65775affc3bSjeremylt // Copy name 6582b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(name, (char **)&(*qf)->gallery_name)); 65943e1b16fSJeremy L Thompson (*qf)->is_gallery = true; 660e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 661288c0443SJeremy L Thompson } 662288c0443SJeremy L Thompson 663288c0443SJeremy L Thompson /** 664*ca94c3ddSJeremy L Thompson @brief Create an identity `CeedQFunction`. 6654385fb7fSSebastian Grimberg 666ea61e9acSJeremy L Thompson Inputs are written into outputs in the order given. 667*ca94c3ddSJeremy 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. 668*ca94c3ddSJeremy 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. 6690219ea01SJeremy L Thompson 670*ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` object used to create the `CeedQFunction` 671*ca94c3ddSJeremy L Thompson @param[in] size Size of the `CeedQFunction` fields 672*ca94c3ddSJeremy L Thompson @param[in] in_mode @ref CeedEvalMode for input to `CeedQFunction` 673*ca94c3ddSJeremy L Thompson @param[in] out_mode @ref CeedEvalMode for output to `CeedQFunction` 674*ca94c3ddSJeremy L Thompson @param[out] qf Address of the variable where the newly created `CeedQFunction` will be stored 6750219ea01SJeremy L Thompson 6760219ea01SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6770219ea01SJeremy L Thompson 6787a982d89SJeremy L. Thompson @ref User 6790219ea01SJeremy L Thompson **/ 6802b730f8bSJeremy L Thompson int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode in_mode, CeedEvalMode out_mode, CeedQFunction *qf) { 6811c66c397SJeremy L Thompson CeedQFunctionContext ctx; 6821c66c397SJeremy L Thompson CeedContextFieldLabel size_label; 6831c66c397SJeremy L Thompson 6842b730f8bSJeremy L Thompson CeedCall(CeedQFunctionCreateInteriorByName(ceed, "Identity", qf)); 6852b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddInput(*qf, "input", size, in_mode)); 6862b730f8bSJeremy L Thompson CeedCall(CeedQFunctionAddOutput(*qf, "output", size, out_mode)); 6870219ea01SJeremy L Thompson 688f04ea552SJeremy L Thompson (*qf)->is_identity = true; 689547dbd6fSJeremy L Thompson 6902b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetContext(*qf, &ctx)); 6912b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldLabel(ctx, "size", &size_label)); 6922b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetInt32(ctx, size_label, &size)); 693e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6940219ea01SJeremy L Thompson } 6950219ea01SJeremy L Thompson 6960219ea01SJeremy L Thompson /** 697*ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `CeedQFunction`. 6984385fb7fSSebastian Grimberg 699*ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedQFunctionDestroy(). 700512bb800SJeremy L Thompson 701*ca94c3ddSJeremy 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`. 702*ca94c3ddSJeremy L Thompson This `CeedQFunction` will be destroyed if `*qf_copy` is the only reference to this `CeedQFunction`. 7039560d06aSjeremylt 704*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to copy reference to 7059560d06aSjeremylt @param[out] qf_copy Variable to store copied reference 7069560d06aSjeremylt 7079560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 7089560d06aSjeremylt 7099560d06aSjeremylt @ref User 7109560d06aSjeremylt **/ 7119560d06aSjeremylt int CeedQFunctionReferenceCopy(CeedQFunction qf, CeedQFunction *qf_copy) { 7122b730f8bSJeremy L Thompson CeedCall(CeedQFunctionReference(qf)); 7132b730f8bSJeremy L Thompson CeedCall(CeedQFunctionDestroy(qf_copy)); 7149560d06aSjeremylt *qf_copy = qf; 7159560d06aSjeremylt return CEED_ERROR_SUCCESS; 7169560d06aSjeremylt } 7179560d06aSjeremylt 7189560d06aSjeremylt /** 719*ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` input 720b11c1e72Sjeremylt 721*ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 722*ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 723*ca94c3ddSJeremy 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. 724*ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 725*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 726*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 727*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 728*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_CURL to use curl 729b11c1e72Sjeremylt 730b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 731dfdf5a53Sjeremylt 7327a982d89SJeremy L. Thompson @ref User 733b11c1e72Sjeremylt **/ 7342b730f8bSJeremy L Thompson int CeedQFunctionAddInput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 7356574a04fSJeremy L Thompson CeedCheck(!qf->is_immutable, qf->ceed, CEED_ERROR_MAJOR, "QFunction cannot be changed after set as immutable"); 7366574a04fSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT || size == 1, qf->ceed, CEED_ERROR_DIMENSION, "CEED_EVAL_WEIGHT should have size 1"); 737643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 7386574a04fSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), qf->ceed, CEED_ERROR_MINOR, "QFunction field names must be unique"); 739643fbb69SJeremy L Thompson } 740643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 7416574a04fSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), qf->ceed, CEED_ERROR_MINOR, "QFunction field names must be unique"); 742643fbb69SJeremy L Thompson } 7432b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->input_fields[qf->num_input_fields], field_name, size, eval_mode)); 744d1d35e2fSjeremylt qf->num_input_fields++; 745e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 746d7b241e6Sjeremylt } 747d7b241e6Sjeremylt 748b11c1e72Sjeremylt /** 749*ca94c3ddSJeremy L Thompson @brief Add a `CeedQFunction` output 750b11c1e72Sjeremylt 751*ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 752*ca94c3ddSJeremy L Thompson @param[in] field_name Name of `CeedQFunction` field 753*ca94c3ddSJeremy 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. 754*ca94c3ddSJeremy L Thompson @param[in] eval_mode @ref CEED_EVAL_NONE to use values directly, 755*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_INTERP to use interpolated values, 756*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_GRAD to use gradients, 757*ca94c3ddSJeremy L Thompson @ref CEED_EVAL_DIV to use divergence, 758*ca94c3ddSJeremy 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 CeedQFunctionAddOutput(CeedQFunction qf, const char *field_name, CeedInt size, CeedEvalMode eval_mode) { 765*ca94c3ddSJeremy L Thompson CeedCheck(!qf->is_immutable, qf->ceed, CEED_ERROR_MAJOR, "CeedQFunction cannot be changed after set as immutable"); 766*ca94c3ddSJeremy L Thompson CeedCheck(eval_mode != CEED_EVAL_WEIGHT, qf->ceed, CEED_ERROR_DIMENSION, "Cannot create CeedQFunction output with CEED_EVAL_WEIGHT"); 767643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_input_fields; i++) { 768*ca94c3ddSJeremy L Thompson CeedCheck(strcmp(field_name, qf->input_fields[i]->field_name), qf->ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 769643fbb69SJeremy L Thompson } 770643fbb69SJeremy L Thompson for (CeedInt i = 0; i < qf->num_output_fields; i++) { 771*ca94c3ddSJeremy L Thompson CeedCheck(strcmp(field_name, qf->output_fields[i]->field_name), qf->ceed, CEED_ERROR_MINOR, "CeedQFunction field names must be unique"); 772643fbb69SJeremy L Thompson } 7732b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldSet(&qf->output_fields[qf->num_output_fields], field_name, size, eval_mode)); 774d1d35e2fSjeremylt qf->num_output_fields++; 775e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 776d7b241e6Sjeremylt } 777d7b241e6Sjeremylt 778dfdf5a53Sjeremylt /** 779*ca94c3ddSJeremy L Thompson @brief Get the `CeedQFunctionField` of a `CeedQFunction` 78043bbe138SJeremy L Thompson 781*ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 782f04ea552SJeremy L Thompson 783*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 784f74ec584SJeremy L Thompson @param[out] num_input_fields Variable to store number of input fields 785f74ec584SJeremy L Thompson @param[out] input_fields Variable to store input fields 786f74ec584SJeremy L Thompson @param[out] num_output_fields Variable to store number of output fields 787f74ec584SJeremy L Thompson @param[out] output_fields Variable to store output fields 78843bbe138SJeremy L Thompson 78943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 79043bbe138SJeremy L Thompson 791e9b533fbSJeremy L Thompson @ref Advanced 79243bbe138SJeremy L Thompson **/ 7932b730f8bSJeremy L Thompson int CeedQFunctionGetFields(CeedQFunction qf, CeedInt *num_input_fields, CeedQFunctionField **input_fields, CeedInt *num_output_fields, 79443bbe138SJeremy L Thompson CeedQFunctionField **output_fields) { 795f04ea552SJeremy L Thompson qf->is_immutable = true; 79643bbe138SJeremy L Thompson if (num_input_fields) *num_input_fields = qf->num_input_fields; 79743bbe138SJeremy L Thompson if (input_fields) *input_fields = qf->input_fields; 79843bbe138SJeremy L Thompson if (num_output_fields) *num_output_fields = qf->num_output_fields; 79943bbe138SJeremy L Thompson if (output_fields) *output_fields = qf->output_fields; 80043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 80143bbe138SJeremy L Thompson } 80243bbe138SJeremy L Thompson 80343bbe138SJeremy L Thompson /** 804*ca94c3ddSJeremy L Thompson @brief Get the name of a `CeedQFunctionField` 80543bbe138SJeremy L Thompson 806*ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 80743bbe138SJeremy L Thompson @param[out] field_name Variable to store the field name 80843bbe138SJeremy L Thompson 80943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 81043bbe138SJeremy L Thompson 811e9b533fbSJeremy L Thompson @ref Advanced 81243bbe138SJeremy L Thompson **/ 81343bbe138SJeremy L Thompson int CeedQFunctionFieldGetName(CeedQFunctionField qf_field, char **field_name) { 81443bbe138SJeremy L Thompson *field_name = (char *)qf_field->field_name; 81543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 81643bbe138SJeremy L Thompson } 81743bbe138SJeremy L Thompson 81843bbe138SJeremy L Thompson /** 819*ca94c3ddSJeremy L Thompson @brief Get the number of components of a `CeedQFunctionField` 82043bbe138SJeremy L Thompson 821*ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 82243bbe138SJeremy L Thompson @param[out] size Variable to store the size of the field 82343bbe138SJeremy L Thompson 82443bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 82543bbe138SJeremy L Thompson 826e9b533fbSJeremy L Thompson @ref Advanced 82743bbe138SJeremy L Thompson **/ 82843bbe138SJeremy L Thompson int CeedQFunctionFieldGetSize(CeedQFunctionField qf_field, CeedInt *size) { 82943bbe138SJeremy L Thompson *size = qf_field->size; 83043bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 83143bbe138SJeremy L Thompson } 83243bbe138SJeremy L Thompson 83343bbe138SJeremy L Thompson /** 834*ca94c3ddSJeremy L Thompson @brief Get the @ref CeedEvalMode of a `CeedQFunctionField` 83543bbe138SJeremy L Thompson 836*ca94c3ddSJeremy L Thompson @param[in] qf_field `CeedQFunctionField` 83743bbe138SJeremy L Thompson @param[out] eval_mode Variable to store the field evaluation mode 83843bbe138SJeremy L Thompson 83943bbe138SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 84043bbe138SJeremy L Thompson 841e9b533fbSJeremy L Thompson @ref Advanced 84243bbe138SJeremy L Thompson **/ 8432b730f8bSJeremy L Thompson int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qf_field, CeedEvalMode *eval_mode) { 84443bbe138SJeremy L Thompson *eval_mode = qf_field->eval_mode; 84543bbe138SJeremy L Thompson return CEED_ERROR_SUCCESS; 84643bbe138SJeremy L Thompson } 84743bbe138SJeremy L Thompson 84843bbe138SJeremy L Thompson /** 849*ca94c3ddSJeremy L Thompson @brief Set global context for a `CeedQFunction` 850b11c1e72Sjeremylt 851*ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 852ea61e9acSJeremy L Thompson @param[in] ctx Context data to set 853b11c1e72Sjeremylt 854b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 855dfdf5a53Sjeremylt 8567a982d89SJeremy L. Thompson @ref User 857b11c1e72Sjeremylt **/ 858777ff853SJeremy L Thompson int CeedQFunctionSetContext(CeedQFunction qf, CeedQFunctionContext ctx) { 8592b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&qf->ctx)); 860d7b241e6Sjeremylt qf->ctx = ctx; 861db002c03SJeremy L Thompson if (ctx) CeedCall(CeedQFunctionContextReference(ctx)); 862e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 863d7b241e6Sjeremylt } 864d7b241e6Sjeremylt 865b11c1e72Sjeremylt /** 866*ca94c3ddSJeremy L Thompson @brief Set writability of `CeedQFunctionContext` when calling the `CeedQFunctionUser`. 8674385fb7fSSebastian Grimberg 868859c15bbSJames Wright The default value is `is_writable == true`. 869441428dfSJeremy L Thompson 870*ca94c3ddSJeremy L Thompson Setting `is_writable == true` indicates the `CeedQFunctionUser` writes into the `CeedQFunctionContext` and requires memory synchronization after calling @ref CeedQFunctionApply(). 871441428dfSJeremy L Thompson 872*ca94c3ddSJeremy L Thompson Setting 'is_writable == false' asserts that `CeedQFunctionUser` does not modify the `CeedQFunctionContext`. 873ea61e9acSJeremy L Thompson Violating this assertion may lead to inconsistent data. 874441428dfSJeremy L Thompson 875441428dfSJeremy L Thompson Setting `is_writable == false` may offer a performance improvement on GPU backends. 876441428dfSJeremy L Thompson 877*ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` 878*ca94c3ddSJeremy L Thompson @param[in] is_writable Boolean flag for writability status 879441428dfSJeremy L Thompson 880441428dfSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 881441428dfSJeremy L Thompson 882441428dfSJeremy L Thompson @ref User 883441428dfSJeremy L Thompson **/ 884441428dfSJeremy L Thompson int CeedQFunctionSetContextWritable(CeedQFunction qf, bool is_writable) { 885441428dfSJeremy L Thompson qf->is_context_writable = is_writable; 886441428dfSJeremy L Thompson return CEED_ERROR_SUCCESS; 887441428dfSJeremy L Thompson } 888441428dfSJeremy L Thompson 889441428dfSJeremy L Thompson /** 890*ca94c3ddSJeremy L Thompson @brief Set estimated number of FLOPs per quadrature required to apply `CeedQFunction` 8916e15d496SJeremy L Thompson 892*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to estimate FLOPs for 893ea61e9acSJeremy L Thompson @param[out] flops FLOPs per quadrature point estimate 8946e15d496SJeremy L Thompson 8956e15d496SJeremy L Thompson @ref Backend 8966e15d496SJeremy L Thompson **/ 8979d36ca50SJeremy L Thompson int CeedQFunctionSetUserFlopsEstimate(CeedQFunction qf, CeedSize flops) { 8986574a04fSJeremy L Thompson CeedCheck(flops >= 0, qf->ceed, CEED_ERROR_INCOMPATIBLE, "Must set non-negative FLOPs estimate"); 8996e15d496SJeremy L Thompson qf->user_flop_estimate = flops; 9006e15d496SJeremy L Thompson return CEED_ERROR_SUCCESS; 9016e15d496SJeremy L Thompson } 9026e15d496SJeremy L Thompson 9036e15d496SJeremy L Thompson /** 904*ca94c3ddSJeremy L Thompson @brief View a `CeedQFunction` 90575affc3bSjeremylt 906*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` to view 907*ca94c3ddSJeremy L Thompson @param[in] stream Stream to write; typically `stdout` or a file 90875affc3bSjeremylt 90975affc3bSjeremylt @return Error code: 0 - success, otherwise - failure 91075affc3bSjeremylt 9117a982d89SJeremy L. Thompson @ref User 91275affc3bSjeremylt **/ 91375affc3bSjeremylt int CeedQFunctionView(CeedQFunction qf, FILE *stream) { 914ca5eadf8SJeremy L Thompson char *kernel_name; 91575affc3bSjeremylt 9162b730f8bSJeremy L Thompson CeedCall(CeedQFunctionGetKernelName(qf, &kernel_name)); 9172b730f8bSJeremy L Thompson fprintf(stream, "%sCeedQFunction - %s\n", qf->is_gallery ? "Gallery " : "User ", qf->is_gallery ? qf->gallery_name : kernel_name); 91875affc3bSjeremylt 9192b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " input field%s:\n", qf->num_input_fields, qf->num_input_fields > 1 ? "s" : ""); 920d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_input_fields; i++) { 9212b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->input_fields[i], i, 1, stream)); 92275affc3bSjeremylt } 92375affc3bSjeremylt 9242b730f8bSJeremy L Thompson fprintf(stream, " %" CeedInt_FMT " output field%s:\n", qf->num_output_fields, qf->num_output_fields > 1 ? "s" : ""); 925d1d35e2fSjeremylt for (CeedInt i = 0; i < qf->num_output_fields; i++) { 9262b730f8bSJeremy L Thompson CeedCall(CeedQFunctionFieldView(qf->output_fields[i], i, 0, stream)); 92775affc3bSjeremylt } 928e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 92975affc3bSjeremylt } 93075affc3bSjeremylt 93175affc3bSjeremylt /** 932*ca94c3ddSJeremy L Thompson @brief Get the `Ceed` associated with a `CeedQFunction` 933b7c9bbdaSJeremy L Thompson 934*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 935*ca94c3ddSJeremy L Thompson @param[out] ceed Variable to store`Ceed` 936b7c9bbdaSJeremy L Thompson 937b7c9bbdaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 938b7c9bbdaSJeremy L Thompson 939b7c9bbdaSJeremy L Thompson @ref Advanced 940b7c9bbdaSJeremy L Thompson **/ 941b7c9bbdaSJeremy L Thompson int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 942b7c9bbdaSJeremy L Thompson *ceed = qf->ceed; 943b7c9bbdaSJeremy L Thompson return CEED_ERROR_SUCCESS; 944b7c9bbdaSJeremy L Thompson } 945b7c9bbdaSJeremy L Thompson 946b7c9bbdaSJeremy L Thompson /** 947*ca94c3ddSJeremy L Thompson @brief Apply the action of a `CeedQFunction` 948b11c1e72Sjeremylt 949*ca94c3ddSJeremy L Thompson Note: Calling this function asserts that setup is complete and sets the `CeedQFunction` as immutable. 950f04ea552SJeremy L Thompson 951*ca94c3ddSJeremy L Thompson @param[in] qf `CeedQFunction` 952ea61e9acSJeremy L Thompson @param[in] Q Number of quadrature points 953*ca94c3ddSJeremy L Thompson @param[in] u Array of input `CeedVector` 954*ca94c3ddSJeremy L Thompson @param[out] v Array of output `CeedVector` 955b11c1e72Sjeremylt 956b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 957dfdf5a53Sjeremylt 9587a982d89SJeremy L. Thompson @ref User 959b11c1e72Sjeremylt **/ 9602b730f8bSJeremy L Thompson int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, CeedVector *u, CeedVector *v) { 961*ca94c3ddSJeremy L Thompson CeedCheck(qf->Apply, qf->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support CeedQFunctionApply"); 9626574a04fSJeremy L Thompson CeedCheck(Q % qf->vec_length == 0, qf->ceed, CEED_ERROR_DIMENSION, 9636574a04fSJeremy L Thompson "Number of quadrature points %" CeedInt_FMT " must be a multiple of %" CeedInt_FMT, Q, qf->vec_length); 964f04ea552SJeremy L Thompson qf->is_immutable = true; 9652b730f8bSJeremy L Thompson CeedCall(qf->Apply(qf, Q, u, v)); 966e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 967d7b241e6Sjeremylt } 968d7b241e6Sjeremylt 969b11c1e72Sjeremylt /** 970*ca94c3ddSJeremy L Thompson @brief Destroy a `CeedQFunction` 971b11c1e72Sjeremylt 972*ca94c3ddSJeremy L Thompson @param[in,out] qf `CeedQFunction` to destroy 973b11c1e72Sjeremylt 974b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 975dfdf5a53Sjeremylt 9767a982d89SJeremy L. Thompson @ref User 977b11c1e72Sjeremylt **/ 978d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) { 979ad6481ceSJeremy L Thompson if (!*qf || --(*qf)->ref_count > 0) { 980ad6481ceSJeremy L Thompson *qf = NULL; 981ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 982ad6481ceSJeremy L Thompson } 983fe2413ffSjeremylt // Backend destroy 984d7b241e6Sjeremylt if ((*qf)->Destroy) { 9852b730f8bSJeremy L Thompson CeedCall((*qf)->Destroy(*qf)); 986d7b241e6Sjeremylt } 987fe2413ffSjeremylt // Free fields 98892ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_input_fields; i++) { 9892b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->input_fields[i]).field_name)); 9902b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields[i])); 991fe2413ffSjeremylt } 99292ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*qf)->num_output_fields; i++) { 9932b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*(*qf)->output_fields[i]).field_name)); 9942b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields[i])); 995fe2413ffSjeremylt } 9962b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->input_fields)); 9972b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->output_fields)); 998777ff853SJeremy L Thompson 999777ff853SJeremy L Thompson // User context data object 10002b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(&(*qf)->ctx)); 1001fe2413ffSjeremylt 10022b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->user_source)); 10032b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->source_path)); 10042b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->gallery_name)); 10052b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*qf)->kernel_name)); 10062b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*qf)->ceed)); 10072b730f8bSJeremy L Thompson CeedCall(CeedFree(qf)); 1008e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1009d7b241e6Sjeremylt } 1010d7b241e6Sjeremylt 1011d7b241e6Sjeremylt /// @} 1012