1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details. 4d7b241e6Sjeremylt // 5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and 8d7b241e6Sjeremylt // source code availability see http://github.com/ceed. 9d7b241e6Sjeremylt // 10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early 15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16d7b241e6Sjeremylt 17d7b241e6Sjeremylt #include <ceed-impl.h> 18d863ab9bSjeremylt #include <ceed-backend.h> 19d7b241e6Sjeremylt #include <string.h> 20288c0443SJeremy L Thompson #include <limits.h> 21288c0443SJeremy L Thompson 22*7a982d89SJeremy L. Thompson /// @file 23*7a982d89SJeremy L. Thompson /// Implementation of public CeedQFunction interfaces 24*7a982d89SJeremy L. Thompson 25288c0443SJeremy L Thompson /// @cond DOXYGEN_SKIP 26442e7f0bSjeremylt static struct CeedQFunction_private ceed_qfunction_none; 27442e7f0bSjeremylt /// @endcond 28442e7f0bSjeremylt 29*7a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 30*7a982d89SJeremy L. Thompson /// @{ 31*7a982d89SJeremy L. Thompson 32*7a982d89SJeremy L. Thompson // Indicate that no QFunction is provided by the user 33*7a982d89SJeremy L. Thompson const CeedQFunction CEED_QFUNCTION_NONE = &ceed_qfunction_none; 34*7a982d89SJeremy L. Thompson 35*7a982d89SJeremy L. Thompson /// @} 36*7a982d89SJeremy L. Thompson 37442e7f0bSjeremylt /// @cond DOXYGEN_SKIP 38288c0443SJeremy L Thompson static struct { 39288c0443SJeremy L Thompson char name[CEED_MAX_RESOURCE_LEN]; 40288c0443SJeremy L Thompson char source[CEED_MAX_RESOURCE_LEN]; 41288c0443SJeremy L Thompson CeedInt vlength; 42288c0443SJeremy L Thompson CeedQFunctionUser f; 43288c0443SJeremy L Thompson int (*init)(Ceed ceed, const char *name, CeedQFunction qf); 44288c0443SJeremy L Thompson } qfunctions[1024]; 45288c0443SJeremy L Thompson static size_t num_qfunctions; 46288c0443SJeremy L Thompson /// @endcond 47d7b241e6Sjeremylt 48b11c1e72Sjeremylt /** 49288c0443SJeremy L Thompson @brief Register a gallery QFunction 50288c0443SJeremy L Thompson 51288c0443SJeremy L Thompson @param name Name for this backend to respond to 521176cc3aSJeremy L Thompson @param source Absolute path to source of QFunction, 531176cc3aSJeremy L Thompson "\path\CEED_DIR\gallery\folder\file.h:function_name" 54288c0443SJeremy L Thompson @param vlength Vector length. Caller must ensure that number of quadrature 55288c0443SJeremy L Thompson points is a multiple of vlength. 56288c0443SJeremy L Thompson @param f Function pointer to evaluate action at quadrature points. 57288c0443SJeremy L Thompson See \ref CeedQFunctionUser. 58288c0443SJeremy L Thompson @param init Initialization function called by CeedQFunctionInit() when the 59288c0443SJeremy L Thompson QFunction is selected. 60288c0443SJeremy L Thompson 61288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 62288c0443SJeremy L Thompson 63*7a982d89SJeremy L. Thompson @ref Developer 64288c0443SJeremy L Thompson **/ 65288c0443SJeremy L Thompson int CeedQFunctionRegister(const char *name, const char *source, 66288c0443SJeremy L Thompson CeedInt vlength, CeedQFunctionUser f, 67288c0443SJeremy L Thompson int (*init)(Ceed, const char *, CeedQFunction)) { 68c042f62fSJeremy L Thompson if (num_qfunctions >= sizeof(qfunctions) / sizeof(qfunctions[0])) 69c042f62fSJeremy L Thompson // LCOV_EXCL_START 70288c0443SJeremy L Thompson return CeedError(NULL, 1, "Too many gallery QFunctions"); 71c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 72c042f62fSJeremy L Thompson 73288c0443SJeremy L Thompson strncpy(qfunctions[num_qfunctions].name, name, CEED_MAX_RESOURCE_LEN); 74288c0443SJeremy L Thompson qfunctions[num_qfunctions].name[CEED_MAX_RESOURCE_LEN-1] = 0; 75288c0443SJeremy L Thompson strncpy(qfunctions[num_qfunctions].source, source, CEED_MAX_RESOURCE_LEN); 76288c0443SJeremy L Thompson qfunctions[num_qfunctions].source[CEED_MAX_RESOURCE_LEN-1] = 0; 77288c0443SJeremy L Thompson qfunctions[num_qfunctions].vlength = vlength; 78288c0443SJeremy L Thompson qfunctions[num_qfunctions].f = f; 79288c0443SJeremy L Thompson qfunctions[num_qfunctions].init = init; 80288c0443SJeremy L Thompson num_qfunctions++; 81288c0443SJeremy L Thompson return 0; 82288c0443SJeremy L Thompson } 83288c0443SJeremy L Thompson 84288c0443SJeremy L Thompson /** 85*7a982d89SJeremy L. Thompson @brief Set a CeedQFunction field, used by CeedQFunctionAddInput/Output 86*7a982d89SJeremy L. Thompson 87*7a982d89SJeremy L. Thompson @param f CeedQFunctionField 88*7a982d89SJeremy L. Thompson @param fieldname Name of QFunction field 89*7a982d89SJeremy L. Thompson @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 90*7a982d89SJeremy L. Thompson (ncomp * 1) for CEED_EVAL_NONE, CEED_EVAL_INTERP, and CEED_EVAL_WEIGHT 91*7a982d89SJeremy L. Thompson @param emode \ref CEED_EVAL_NONE to use values directly, 92*7a982d89SJeremy L. Thompson \ref CEED_EVAL_INTERP to use interpolated values, 93*7a982d89SJeremy L. Thompson \ref CEED_EVAL_GRAD to use gradients, 94*7a982d89SJeremy L. Thompson \ref CEED_EVAL_WEIGHT to use quadrature weights. 95*7a982d89SJeremy L. Thompson 96*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 97*7a982d89SJeremy L. Thompson 98*7a982d89SJeremy L. Thompson @ref Developer 99*7a982d89SJeremy L. Thompson **/ 100*7a982d89SJeremy L. Thompson static int CeedQFunctionFieldSet(CeedQFunctionField *f,const char *fieldname, 101*7a982d89SJeremy L. Thompson CeedInt size, CeedEvalMode emode) { 102*7a982d89SJeremy L. Thompson size_t len = strlen(fieldname); 103*7a982d89SJeremy L. Thompson char *tmp; 104*7a982d89SJeremy L. Thompson int ierr; 105*7a982d89SJeremy L. Thompson ierr = CeedCalloc(1,f); CeedChk(ierr); 106*7a982d89SJeremy L. Thompson 107*7a982d89SJeremy L. Thompson ierr = CeedCalloc(len+1, &tmp); CeedChk(ierr); 108*7a982d89SJeremy L. Thompson memcpy(tmp, fieldname, len+1); 109*7a982d89SJeremy L. Thompson (*f)->fieldname = tmp; 110*7a982d89SJeremy L. Thompson (*f)->size = size; 111*7a982d89SJeremy L. Thompson (*f)->emode = emode; 112*7a982d89SJeremy L. Thompson return 0; 113*7a982d89SJeremy L. Thompson } 114*7a982d89SJeremy L. Thompson 115*7a982d89SJeremy L. Thompson /** 116*7a982d89SJeremy L. Thompson @brief View a field of a CeedQFunction 117*7a982d89SJeremy L. Thompson 118*7a982d89SJeremy L. Thompson @param[in] field QFunction field to view 119*7a982d89SJeremy L. Thompson @param[in] fieldnumber Number of field being viewed 120*7a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 121*7a982d89SJeremy L. Thompson 122*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 123*7a982d89SJeremy L. Thompson 124*7a982d89SJeremy L. Thompson @ref Utility 125*7a982d89SJeremy L. Thompson **/ 126*7a982d89SJeremy L. Thompson static int CeedQFunctionFieldView(CeedQFunctionField field, CeedInt fieldnumber, 127*7a982d89SJeremy L. Thompson bool in, FILE *stream) { 128*7a982d89SJeremy L. Thompson const char *inout = in ? "Input" : "Output"; 129*7a982d89SJeremy L. Thompson fprintf(stream, " %s Field [%d]:\n" 130*7a982d89SJeremy L. Thompson " Name: \"%s\"\n" 131*7a982d89SJeremy L. Thompson " Size: %d\n" 132*7a982d89SJeremy L. Thompson " EvalMode: \"%s\"\n", 133*7a982d89SJeremy L. Thompson inout, fieldnumber, field->fieldname, field->size, 134*7a982d89SJeremy L. Thompson CeedEvalModes[field->emode]); 135*7a982d89SJeremy L. Thompson 136*7a982d89SJeremy L. Thompson return 0; 137*7a982d89SJeremy L. Thompson } 138*7a982d89SJeremy L. Thompson 139*7a982d89SJeremy L. Thompson /// @} 140*7a982d89SJeremy L. Thompson 141*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 142*7a982d89SJeremy L. Thompson /// CeedQFunction Backend API 143*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 144*7a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionBackend 145*7a982d89SJeremy L. Thompson /// @{ 146*7a982d89SJeremy L. Thompson 147*7a982d89SJeremy L. Thompson /** 148*7a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedQFunction 149*7a982d89SJeremy L. Thompson 150*7a982d89SJeremy L. Thompson @param qf CeedQFunction 151*7a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 152*7a982d89SJeremy L. Thompson 153*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 154*7a982d89SJeremy L. Thompson 155*7a982d89SJeremy L. Thompson @ref Backend 156*7a982d89SJeremy L. Thompson **/ 157*7a982d89SJeremy L. Thompson 158*7a982d89SJeremy L. Thompson int CeedQFunctionGetCeed(CeedQFunction qf, Ceed *ceed) { 159*7a982d89SJeremy L. Thompson *ceed = qf->ceed; 160*7a982d89SJeremy L. Thompson return 0; 161*7a982d89SJeremy L. Thompson } 162*7a982d89SJeremy L. Thompson 163*7a982d89SJeremy L. Thompson /** 164*7a982d89SJeremy L. Thompson @brief Get the vector length of a CeedQFunction 165*7a982d89SJeremy L. Thompson 166*7a982d89SJeremy L. Thompson @param qf CeedQFunction 167*7a982d89SJeremy L. Thompson @param[out] vlength Variable to store vector length 168*7a982d89SJeremy L. Thompson 169*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 170*7a982d89SJeremy L. Thompson 171*7a982d89SJeremy L. Thompson @ref Backend 172*7a982d89SJeremy L. Thompson **/ 173*7a982d89SJeremy L. Thompson 174*7a982d89SJeremy L. Thompson int CeedQFunctionGetVectorLength(CeedQFunction qf, CeedInt *vlength) { 175*7a982d89SJeremy L. Thompson *vlength = qf->vlength; 176*7a982d89SJeremy L. Thompson return 0; 177*7a982d89SJeremy L. Thompson } 178*7a982d89SJeremy L. Thompson 179*7a982d89SJeremy L. Thompson /** 180*7a982d89SJeremy L. Thompson @brief Get the number of inputs and outputs to a CeedQFunction 181*7a982d89SJeremy L. Thompson 182*7a982d89SJeremy L. Thompson @param qf CeedQFunction 183*7a982d89SJeremy L. Thompson @param[out] numinput Variable to store number of input fields 184*7a982d89SJeremy L. Thompson @param[out] numoutput Variable to store number of output fields 185*7a982d89SJeremy L. Thompson 186*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 187*7a982d89SJeremy L. Thompson 188*7a982d89SJeremy L. Thompson @ref Backend 189*7a982d89SJeremy L. Thompson **/ 190*7a982d89SJeremy L. Thompson 191*7a982d89SJeremy L. Thompson int CeedQFunctionGetNumArgs(CeedQFunction qf, CeedInt *numinput, 192*7a982d89SJeremy L. Thompson CeedInt *numoutput) { 193*7a982d89SJeremy L. Thompson if (numinput) *numinput = qf->numinputfields; 194*7a982d89SJeremy L. Thompson if (numoutput) *numoutput = qf->numoutputfields; 195*7a982d89SJeremy L. Thompson return 0; 196*7a982d89SJeremy L. Thompson } 197*7a982d89SJeremy L. Thompson 198*7a982d89SJeremy L. Thompson /** 199*7a982d89SJeremy L. Thompson @brief Get the source path string for a CeedQFunction 200*7a982d89SJeremy L. Thompson 201*7a982d89SJeremy L. Thompson @param qf CeedQFunction 202*7a982d89SJeremy L. Thompson @param[out] source Variable to store source path string 203*7a982d89SJeremy L. Thompson 204*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 205*7a982d89SJeremy L. Thompson 206*7a982d89SJeremy L. Thompson @ref Backend 207*7a982d89SJeremy L. Thompson **/ 208*7a982d89SJeremy L. Thompson 209*7a982d89SJeremy L. Thompson int CeedQFunctionGetSourcePath(CeedQFunction qf, char **source) { 210*7a982d89SJeremy L. Thompson *source = (char *) qf->sourcepath; 211*7a982d89SJeremy L. Thompson return 0; 212*7a982d89SJeremy L. Thompson } 213*7a982d89SJeremy L. Thompson 214*7a982d89SJeremy L. Thompson /** 215*7a982d89SJeremy L. Thompson @brief Get the User Function for a CeedQFunction 216*7a982d89SJeremy L. Thompson 217*7a982d89SJeremy L. Thompson @param qf CeedQFunction 218*7a982d89SJeremy L. Thompson @param[out] f Variable to store user function 219*7a982d89SJeremy L. Thompson 220*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 221*7a982d89SJeremy L. Thompson 222*7a982d89SJeremy L. Thompson @ref Backend 223*7a982d89SJeremy L. Thompson **/ 224*7a982d89SJeremy L. Thompson 225*7a982d89SJeremy L. Thompson int CeedQFunctionGetUserFunction(CeedQFunction qf, CeedQFunctionUser *f) { 226*7a982d89SJeremy L. Thompson *f = qf->function; 227*7a982d89SJeremy L. Thompson return 0; 228*7a982d89SJeremy L. Thompson } 229*7a982d89SJeremy L. Thompson 230*7a982d89SJeremy L. Thompson /** 231*7a982d89SJeremy L. Thompson @brief Get global context size for a CeedQFunction 232*7a982d89SJeremy L. Thompson 233*7a982d89SJeremy L. Thompson @param qf CeedQFunction 234*7a982d89SJeremy L. Thompson @param[out] ctxsize Variable to store size of context data values 235*7a982d89SJeremy L. Thompson 236*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 237*7a982d89SJeremy L. Thompson 238*7a982d89SJeremy L. Thompson @ref Backend 239*7a982d89SJeremy L. Thompson **/ 240*7a982d89SJeremy L. Thompson 241*7a982d89SJeremy L. Thompson int CeedQFunctionGetContextSize(CeedQFunction qf, size_t *ctxsize) { 242*7a982d89SJeremy L. Thompson if (qf->fortranstatus) { 243*7a982d89SJeremy L. Thompson fContext *fctx = qf->ctx; 244*7a982d89SJeremy L. Thompson *ctxsize = fctx->innerctxsize; 245*7a982d89SJeremy L. Thompson } else { 246*7a982d89SJeremy L. Thompson *ctxsize = qf->ctxsize; 247*7a982d89SJeremy L. Thompson } 248*7a982d89SJeremy L. Thompson return 0; 249*7a982d89SJeremy L. Thompson } 250*7a982d89SJeremy L. Thompson 251*7a982d89SJeremy L. Thompson /** 252*7a982d89SJeremy L. Thompson @brief Get global context for a CeedQFunction 253*7a982d89SJeremy L. Thompson 254*7a982d89SJeremy L. Thompson @param qf CeedQFunction 255*7a982d89SJeremy L. Thompson @param[out] ctx Variable to store context data values 256*7a982d89SJeremy L. Thompson 257*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 258*7a982d89SJeremy L. Thompson 259*7a982d89SJeremy L. Thompson @ref Backend 260*7a982d89SJeremy L. Thompson **/ 261*7a982d89SJeremy L. Thompson 262*7a982d89SJeremy L. Thompson int CeedQFunctionGetContext(CeedQFunction qf, void **ctx) { 263*7a982d89SJeremy L. Thompson *ctx = qf->ctx; 264*7a982d89SJeremy L. Thompson return 0; 265*7a982d89SJeremy L. Thompson } 266*7a982d89SJeremy L. Thompson 267*7a982d89SJeremy L. Thompson /** 268*7a982d89SJeremy L. Thompson @brief Get true user context for a CeedQFunction 269*7a982d89SJeremy L. Thompson 270*7a982d89SJeremy L. Thompson @param qf CeedQFunction 271*7a982d89SJeremy L. Thompson @param[out] ctx Variable to store context data values 272*7a982d89SJeremy L. Thompson 273*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 274*7a982d89SJeremy L. Thompson 275*7a982d89SJeremy L. Thompson @ref Backend 276*7a982d89SJeremy L. Thompson **/ 277*7a982d89SJeremy L. Thompson 278*7a982d89SJeremy L. Thompson int CeedQFunctionGetInnerContext(CeedQFunction qf, void **ctx) { 279*7a982d89SJeremy L. Thompson if (qf->fortranstatus) { 280*7a982d89SJeremy L. Thompson fContext *fctx = qf->ctx; 281*7a982d89SJeremy L. Thompson *ctx = fctx->innerctx; 282*7a982d89SJeremy L. Thompson } else { 283*7a982d89SJeremy L. Thompson *ctx = qf->ctx; 284*7a982d89SJeremy L. Thompson } 285*7a982d89SJeremy L. Thompson 286*7a982d89SJeremy L. Thompson 287*7a982d89SJeremy L. Thompson return 0; 288*7a982d89SJeremy L. Thompson } 289*7a982d89SJeremy L. Thompson 290*7a982d89SJeremy L. Thompson /** 291*7a982d89SJeremy L. Thompson @brief Determine if Fortran interface was used 292*7a982d89SJeremy L. Thompson 293*7a982d89SJeremy L. Thompson @param qf CeedQFunction 294*7a982d89SJeremy L. Thompson @param[out] fortranstatus Variable to store Fortran status 295*7a982d89SJeremy L. Thompson 296*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 297*7a982d89SJeremy L. Thompson 298*7a982d89SJeremy L. Thompson @ref Backend 299*7a982d89SJeremy L. Thompson **/ 300*7a982d89SJeremy L. Thompson 301*7a982d89SJeremy L. Thompson int CeedQFunctionGetFortranStatus(CeedQFunction qf, bool *fortranstatus) { 302*7a982d89SJeremy L. Thompson *fortranstatus = qf->fortranstatus; 303*7a982d89SJeremy L. Thompson return 0; 304*7a982d89SJeremy L. Thompson } 305*7a982d89SJeremy L. Thompson 306*7a982d89SJeremy L. Thompson /** 307*7a982d89SJeremy L. Thompson @brief Determine if QFunction is identity 308*7a982d89SJeremy L. Thompson 309*7a982d89SJeremy L. Thompson @param qf CeedQFunction 310*7a982d89SJeremy L. Thompson @param[out] identity Variable to store identity status 311*7a982d89SJeremy L. Thompson 312*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 313*7a982d89SJeremy L. Thompson 314*7a982d89SJeremy L. Thompson @ref Backend 315*7a982d89SJeremy L. Thompson **/ 316*7a982d89SJeremy L. Thompson 317*7a982d89SJeremy L. Thompson int CeedQFunctionGetIdentityStatus(CeedQFunction qf, bool *identity) { 318*7a982d89SJeremy L. Thompson *identity = qf->identity; 319*7a982d89SJeremy L. Thompson return 0; 320*7a982d89SJeremy L. Thompson } 321*7a982d89SJeremy L. Thompson 322*7a982d89SJeremy L. Thompson /** 323*7a982d89SJeremy L. Thompson @brief Get backend data of a CeedQFunction 324*7a982d89SJeremy L. Thompson 325*7a982d89SJeremy L. Thompson @param qf CeedQFunction 326*7a982d89SJeremy L. Thompson @param[out] data Variable to store data 327*7a982d89SJeremy L. Thompson 328*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 329*7a982d89SJeremy L. Thompson 330*7a982d89SJeremy L. Thompson @ref Backend 331*7a982d89SJeremy L. Thompson **/ 332*7a982d89SJeremy L. Thompson 333*7a982d89SJeremy L. Thompson int CeedQFunctionGetData(CeedQFunction qf, void **data) { 334*7a982d89SJeremy L. Thompson *data = qf->data; 335*7a982d89SJeremy L. Thompson return 0; 336*7a982d89SJeremy L. Thompson } 337*7a982d89SJeremy L. Thompson 338*7a982d89SJeremy L. Thompson /** 339*7a982d89SJeremy L. Thompson @brief Set backend data of a CeedQFunction 340*7a982d89SJeremy L. Thompson 341*7a982d89SJeremy L. Thompson @param[out] qf CeedQFunction 342*7a982d89SJeremy L. Thompson @param data Data to set 343*7a982d89SJeremy L. Thompson 344*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 345*7a982d89SJeremy L. Thompson 346*7a982d89SJeremy L. Thompson @ref Backend 347*7a982d89SJeremy L. Thompson **/ 348*7a982d89SJeremy L. Thompson 349*7a982d89SJeremy L. Thompson int CeedQFunctionSetData(CeedQFunction qf, void **data) { 350*7a982d89SJeremy L. Thompson qf->data = *data; 351*7a982d89SJeremy L. Thompson return 0; 352*7a982d89SJeremy L. Thompson } 353*7a982d89SJeremy L. Thompson 354*7a982d89SJeremy L. Thompson /** 355*7a982d89SJeremy L. Thompson @brief Get the CeedQFunctionFields of a CeedQFunction 356*7a982d89SJeremy L. Thompson 357*7a982d89SJeremy L. Thompson @param qf CeedQFunction 358*7a982d89SJeremy L. Thompson @param[out] inputfields Variable to store inputfields 359*7a982d89SJeremy L. Thompson @param[out] outputfields Variable to store outputfields 360*7a982d89SJeremy L. Thompson 361*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 362*7a982d89SJeremy L. Thompson 363*7a982d89SJeremy L. Thompson @ref Backend 364*7a982d89SJeremy L. Thompson **/ 365*7a982d89SJeremy L. Thompson 366*7a982d89SJeremy L. Thompson int CeedQFunctionGetFields(CeedQFunction qf, CeedQFunctionField **inputfields, 367*7a982d89SJeremy L. Thompson CeedQFunctionField **outputfields) { 368*7a982d89SJeremy L. Thompson if (inputfields) 369*7a982d89SJeremy L. Thompson *inputfields = qf->inputfields; 370*7a982d89SJeremy L. Thompson if (outputfields) 371*7a982d89SJeremy L. Thompson *outputfields = qf->outputfields; 372*7a982d89SJeremy L. Thompson return 0; 373*7a982d89SJeremy L. Thompson } 374*7a982d89SJeremy L. Thompson 375*7a982d89SJeremy L. Thompson /** 376*7a982d89SJeremy L. Thompson @brief Get the name of a CeedQFunctionField 377*7a982d89SJeremy L. Thompson 378*7a982d89SJeremy L. Thompson @param qffield CeedQFunctionField 379*7a982d89SJeremy L. Thompson @param[out] fieldname Variable to store the field name 380*7a982d89SJeremy L. Thompson 381*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 382*7a982d89SJeremy L. Thompson 383*7a982d89SJeremy L. Thompson @ref Backend 384*7a982d89SJeremy L. Thompson **/ 385*7a982d89SJeremy L. Thompson 386*7a982d89SJeremy L. Thompson int CeedQFunctionFieldGetName(CeedQFunctionField qffield, char **fieldname) { 387*7a982d89SJeremy L. Thompson *fieldname = (char *)qffield->fieldname; 388*7a982d89SJeremy L. Thompson return 0; 389*7a982d89SJeremy L. Thompson } 390*7a982d89SJeremy L. Thompson 391*7a982d89SJeremy L. Thompson /** 392*7a982d89SJeremy L. Thompson @brief Get the number of components of a CeedQFunctionField 393*7a982d89SJeremy L. Thompson 394*7a982d89SJeremy L. Thompson @param qffield CeedQFunctionField 395*7a982d89SJeremy L. Thompson @param[out] size Variable to store the size of the field 396*7a982d89SJeremy L. Thompson 397*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 398*7a982d89SJeremy L. Thompson 399*7a982d89SJeremy L. Thompson @ref Backend 400*7a982d89SJeremy L. Thompson **/ 401*7a982d89SJeremy L. Thompson 402*7a982d89SJeremy L. Thompson int CeedQFunctionFieldGetSize(CeedQFunctionField qffield, CeedInt *size) { 403*7a982d89SJeremy L. Thompson *size = qffield->size; 404*7a982d89SJeremy L. Thompson return 0; 405*7a982d89SJeremy L. Thompson } 406*7a982d89SJeremy L. Thompson 407*7a982d89SJeremy L. Thompson /** 408*7a982d89SJeremy L. Thompson @brief Get the CeedEvalMode of a CeedQFunctionField 409*7a982d89SJeremy L. Thompson 410*7a982d89SJeremy L. Thompson @param qffield CeedQFunctionField 411*7a982d89SJeremy L. Thompson @param[out] emode Variable to store the field evaluation mode 412*7a982d89SJeremy L. Thompson 413*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 414*7a982d89SJeremy L. Thompson 415*7a982d89SJeremy L. Thompson @ref Backend 416*7a982d89SJeremy L. Thompson **/ 417*7a982d89SJeremy L. Thompson 418*7a982d89SJeremy L. Thompson int CeedQFunctionFieldGetEvalMode(CeedQFunctionField qffield, 419*7a982d89SJeremy L. Thompson CeedEvalMode *emode) { 420*7a982d89SJeremy L. Thompson *emode = qffield->emode; 421*7a982d89SJeremy L. Thompson return 0; 422*7a982d89SJeremy L. Thompson } 423*7a982d89SJeremy L. Thompson 424*7a982d89SJeremy L. Thompson /// @} 425*7a982d89SJeremy L. Thompson 426*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 427*7a982d89SJeremy L. Thompson /// CeedQFunction Public API 428*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 429*7a982d89SJeremy L. Thompson /// @addtogroup CeedQFunctionUser 430*7a982d89SJeremy L. Thompson /// @{ 431*7a982d89SJeremy L. Thompson 432*7a982d89SJeremy L. Thompson /** 433*7a982d89SJeremy L. Thompson @brief Create a CeedQFunction for evaluating interior (volumetric) terms. 434*7a982d89SJeremy L. Thompson 435*7a982d89SJeremy L. Thompson @param ceed A Ceed object where the CeedQFunction will be created 436*7a982d89SJeremy L. Thompson @param vlength Vector length. Caller must ensure that number of quadrature 437*7a982d89SJeremy L. Thompson points is a multiple of vlength. 438*7a982d89SJeremy L. Thompson @param f Function pointer to evaluate action at quadrature points. 439*7a982d89SJeremy L. Thompson See \ref CeedQFunctionUser. 440*7a982d89SJeremy L. Thompson @param source Absolute path to source of QFunction, 441*7a982d89SJeremy L. Thompson "\abs_path\file.h:function_name" 442*7a982d89SJeremy L. Thompson @param[out] qf Address of the variable where the newly created 443*7a982d89SJeremy L. Thompson CeedQFunction will be stored 444*7a982d89SJeremy L. Thompson 445*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 446*7a982d89SJeremy L. Thompson 447*7a982d89SJeremy L. Thompson See \ref CeedQFunctionUser for details on the call-back function @a f's 448*7a982d89SJeremy L. Thompson arguments. 449*7a982d89SJeremy L. Thompson 450*7a982d89SJeremy L. Thompson @ref User 451*7a982d89SJeremy L. Thompson **/ 452*7a982d89SJeremy L. Thompson int CeedQFunctionCreateInterior(Ceed ceed, CeedInt vlength, CeedQFunctionUser f, 453*7a982d89SJeremy L. Thompson const char *source, CeedQFunction *qf) { 454*7a982d89SJeremy L. Thompson int ierr; 455*7a982d89SJeremy L. Thompson char *source_copy; 456*7a982d89SJeremy L. Thompson 457*7a982d89SJeremy L. Thompson if (!ceed->QFunctionCreate) { 458*7a982d89SJeremy L. Thompson Ceed delegate; 459*7a982d89SJeremy L. Thompson ierr = CeedGetObjectDelegate(ceed, &delegate, "QFunction"); CeedChk(ierr); 460*7a982d89SJeremy L. Thompson 461*7a982d89SJeremy L. Thompson if (!delegate) 462*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 463*7a982d89SJeremy L. Thompson return CeedError(ceed, 1, "Backend does not support QFunctionCreate"); 464*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 465*7a982d89SJeremy L. Thompson 466*7a982d89SJeremy L. Thompson ierr = CeedQFunctionCreateInterior(delegate, vlength, f, source, qf); 467*7a982d89SJeremy L. Thompson CeedChk(ierr); 468*7a982d89SJeremy L. Thompson return 0; 469*7a982d89SJeremy L. Thompson } 470*7a982d89SJeremy L. Thompson 471*7a982d89SJeremy L. Thompson ierr = CeedCalloc(1, qf); CeedChk(ierr); 472*7a982d89SJeremy L. Thompson (*qf)->ceed = ceed; 473*7a982d89SJeremy L. Thompson ceed->refcount++; 474*7a982d89SJeremy L. Thompson (*qf)->refcount = 1; 475*7a982d89SJeremy L. Thompson (*qf)->vlength = vlength; 476*7a982d89SJeremy L. Thompson (*qf)->identity = 0; 477*7a982d89SJeremy L. Thompson (*qf)->function = f; 478*7a982d89SJeremy L. Thompson size_t slen = strlen(source) + 1; 479*7a982d89SJeremy L. Thompson ierr = CeedMalloc(slen, &source_copy); CeedChk(ierr); 480*7a982d89SJeremy L. Thompson memcpy(source_copy, source, slen); 481*7a982d89SJeremy L. Thompson (*qf)->sourcepath = source_copy; 482*7a982d89SJeremy L. Thompson ierr = CeedCalloc(16, &(*qf)->inputfields); CeedChk(ierr); 483*7a982d89SJeremy L. Thompson ierr = CeedCalloc(16, &(*qf)->outputfields); CeedChk(ierr); 484*7a982d89SJeremy L. Thompson ierr = ceed->QFunctionCreate(*qf); CeedChk(ierr); 485*7a982d89SJeremy L. Thompson return 0; 486*7a982d89SJeremy L. Thompson } 487*7a982d89SJeremy L. Thompson 488*7a982d89SJeremy L. Thompson /** 489288c0443SJeremy L Thompson @brief Create a CeedQFunction for evaluating interior (volumetric) terms by name. 490288c0443SJeremy L Thompson 491288c0443SJeremy L Thompson @param ceed A Ceed object where the CeedQFunction will be created 492288c0443SJeremy L Thompson @param name Name of QFunction to use from gallery 493288c0443SJeremy L Thompson @param[out] qf Address of the variable where the newly created 494288c0443SJeremy L Thompson CeedQFunction will be stored 495288c0443SJeremy L Thompson 496288c0443SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 497288c0443SJeremy L Thompson 498*7a982d89SJeremy L. Thompson @ref User 499288c0443SJeremy L Thompson **/ 500288c0443SJeremy L Thompson int CeedQFunctionCreateInteriorByName(Ceed ceed, const char *name, 501288c0443SJeremy L Thompson CeedQFunction *qf) { 502288c0443SJeremy L Thompson int ierr; 503288c0443SJeremy L Thompson size_t matchlen = 0, matchidx = UINT_MAX; 50475affc3bSjeremylt char *name_copy; 505288c0443SJeremy L Thompson 506288c0443SJeremy L Thompson // Find matching backend 507288c0443SJeremy L Thompson if (!name) return CeedError(NULL, 1, "No QFunction name provided"); 508288c0443SJeremy L Thompson for (size_t i=0; i<num_qfunctions; i++) { 509288c0443SJeremy L Thompson size_t n; 510288c0443SJeremy L Thompson const char *currname = qfunctions[i].name; 511288c0443SJeremy L Thompson for (n = 0; currname[n] && currname[n] == name[n]; n++) {} 512288c0443SJeremy L Thompson if (n > matchlen) { 513288c0443SJeremy L Thompson matchlen = n; 514288c0443SJeremy L Thompson matchidx = i; 515288c0443SJeremy L Thompson } 516288c0443SJeremy L Thompson } 5171d102b48SJeremy L Thompson if (!matchlen) 518138d4072Sjeremylt // LCOV_EXCL_START 5191d102b48SJeremy L Thompson return CeedError(NULL, 1, "No suitable gallery QFunction"); 520138d4072Sjeremylt // LCOV_EXCL_STOP 521288c0443SJeremy L Thompson 522288c0443SJeremy L Thompson // Create QFunction 523288c0443SJeremy L Thompson ierr = CeedQFunctionCreateInterior(ceed, qfunctions[matchidx].vlength, 524288c0443SJeremy L Thompson qfunctions[matchidx].f, 525288c0443SJeremy L Thompson qfunctions[matchidx].source, qf); 526288c0443SJeremy L Thompson CeedChk(ierr); 527288c0443SJeremy L Thompson 528288c0443SJeremy L Thompson // QFunction specific setup 529288c0443SJeremy L Thompson ierr = qfunctions[matchidx].init(ceed, name, *qf); CeedChk(ierr); 530288c0443SJeremy L Thompson 53175affc3bSjeremylt // Copy name 53275affc3bSjeremylt size_t slen = strlen(name) + 1; 53375affc3bSjeremylt ierr = CeedMalloc(slen, &name_copy); CeedChk(ierr); 53475affc3bSjeremylt memcpy(name_copy, name, slen); 53575affc3bSjeremylt (*qf)->qfname = name_copy; 53675affc3bSjeremylt 537288c0443SJeremy L Thompson return 0; 538288c0443SJeremy L Thompson } 539288c0443SJeremy L Thompson 540288c0443SJeremy L Thompson /** 5410219ea01SJeremy L Thompson @brief Create an identity CeedQFunction. Inputs are written into outputs in 5420219ea01SJeremy L Thompson the order given. This is useful for CeedOperators that can be 5430219ea01SJeremy L Thompson represented with only the action of a CeedRestriction and CeedBasis, 5440219ea01SJeremy L Thompson such as restriction and prolongation operators for p-multigrid. 5450219ea01SJeremy L Thompson Backends may optimize CeedOperators with this CeedQFunction to avoid 5460219ea01SJeremy L Thompson the copy of input data to output fields by using the same memory 5470219ea01SJeremy L Thompson location for both. 5480219ea01SJeremy L Thompson 5490219ea01SJeremy L Thompson @param ceed A Ceed object where the CeedQFunction will be created 55060f77c51Sjeremylt @param[in] size Size of the qfunction fields 55160f77c51Sjeremylt @param[in] inmode CeedEvalMode for input to CeedQFunction 55260f77c51Sjeremylt @param[in] outmode CeedEvalMode for output to CeedQFunction 5530219ea01SJeremy L Thompson @param[out] qf Address of the variable where the newly created 5540219ea01SJeremy L Thompson CeedQFunction will be stored 5550219ea01SJeremy L Thompson 5560219ea01SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 5570219ea01SJeremy L Thompson 558*7a982d89SJeremy L. Thompson @ref User 5590219ea01SJeremy L Thompson **/ 56060f77c51Sjeremylt int CeedQFunctionCreateIdentity(Ceed ceed, CeedInt size, CeedEvalMode inmode, 56160f77c51Sjeremylt CeedEvalMode outmode, CeedQFunction *qf) { 5620219ea01SJeremy L Thompson int ierr; 5630219ea01SJeremy L Thompson 56460f77c51Sjeremylt if (inmode == CEED_EVAL_NONE && outmode == CEED_EVAL_NONE) 56560f77c51Sjeremylt // LCOV_EXCL_START 56660f77c51Sjeremylt return CeedError(ceed, 1, "CEED_EVAL_NONE for a both the input and " 56760f77c51Sjeremylt "output does not make sense with an identity QFunction"); 56860f77c51Sjeremylt // LCOV_EXCL_STOP 56960f77c51Sjeremylt 5700219ea01SJeremy L Thompson ierr = CeedQFunctionCreateInteriorByName(ceed, "Identity", qf); CeedChk(ierr); 57160f77c51Sjeremylt ierr = CeedQFunctionAddInput(*qf, "input", 1, inmode); CeedChk(ierr); 57260f77c51Sjeremylt ierr = CeedQFunctionAddOutput(*qf, "output", 1, outmode); CeedChk(ierr); 5730219ea01SJeremy L Thompson 5740219ea01SJeremy L Thompson (*qf)->identity = 1; 5750219ea01SJeremy L Thompson if (size > 1) { 5760219ea01SJeremy L Thompson CeedInt *ctx; 5770219ea01SJeremy L Thompson ierr = CeedCalloc(1, &ctx); CeedChk(ierr); 5780219ea01SJeremy L Thompson ctx[0] = size; 5790219ea01SJeremy L Thompson ierr = CeedQFunctionSetContext(*qf, ctx, sizeof(ctx)); CeedChk(ierr); 580c0fea178Sjeremylt (*qf)->inputfields[0]->size = size; 581c0fea178Sjeremylt (*qf)->outputfields[0]->size = size; 5820219ea01SJeremy L Thompson } 5830219ea01SJeremy L Thompson 5840219ea01SJeremy L Thompson return 0; 5850219ea01SJeremy L Thompson } 5860219ea01SJeremy L Thompson 5870219ea01SJeremy L Thompson /** 588a0a97fcfSJed Brown @brief Add a CeedQFunction input 589b11c1e72Sjeremylt 590b11c1e72Sjeremylt @param qf CeedQFunction 591b11c1e72Sjeremylt @param fieldname Name of QFunction field 59295bb1877Svaleriabarra @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 59395bb1877Svaleriabarra (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 594b11c1e72Sjeremylt @param emode \ref CEED_EVAL_NONE to use values directly, 595b11c1e72Sjeremylt \ref CEED_EVAL_INTERP to use interpolated values, 596b11c1e72Sjeremylt \ref CEED_EVAL_GRAD to use gradients. 597b11c1e72Sjeremylt 598b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 599dfdf5a53Sjeremylt 600*7a982d89SJeremy L. Thompson @ref User 601b11c1e72Sjeremylt **/ 6021d102b48SJeremy L Thompson int CeedQFunctionAddInput(CeedQFunction qf, const char *fieldname, CeedInt size, 6031d102b48SJeremy L Thompson CeedEvalMode emode) { 604fe2413ffSjeremylt int ierr = CeedQFunctionFieldSet(&qf->inputfields[qf->numinputfields], 6054d537eeaSYohann fieldname, size, emode); 606fe2413ffSjeremylt CeedChk(ierr); 607fe2413ffSjeremylt qf->numinputfields++; 608d7b241e6Sjeremylt return 0; 609d7b241e6Sjeremylt } 610d7b241e6Sjeremylt 611b11c1e72Sjeremylt /** 612a0a97fcfSJed Brown @brief Add a CeedQFunction output 613b11c1e72Sjeremylt 614b11c1e72Sjeremylt @param qf CeedQFunction 615b11c1e72Sjeremylt @param fieldname Name of QFunction field 61695bb1877Svaleriabarra @param size Size of QFunction field, (ncomp * dim) for CEED_EVAL_GRAD or 61795bb1877Svaleriabarra (ncomp * 1) for CEED_EVAL_NONE and CEED_EVAL_INTERP 618b11c1e72Sjeremylt @param emode \ref CEED_EVAL_NONE to use values directly, 619b11c1e72Sjeremylt \ref CEED_EVAL_INTERP to use interpolated values, 620b11c1e72Sjeremylt \ref CEED_EVAL_GRAD to use gradients. 621b11c1e72Sjeremylt 622b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 623dfdf5a53Sjeremylt 624*7a982d89SJeremy L. Thompson @ref User 625b11c1e72Sjeremylt **/ 626d7b241e6Sjeremylt int CeedQFunctionAddOutput(CeedQFunction qf, const char *fieldname, 6274d537eeaSYohann CeedInt size, CeedEvalMode emode) { 628d7b241e6Sjeremylt if (emode == CEED_EVAL_WEIGHT) 629c042f62fSJeremy L Thompson // LCOV_EXCL_START 6301d102b48SJeremy L Thompson return CeedError(qf->ceed, 1, "Cannot create QFunction output with " 6311d102b48SJeremy L Thompson "CEED_EVAL_WEIGHT"); 632c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 633fe2413ffSjeremylt int ierr = CeedQFunctionFieldSet(&qf->outputfields[qf->numoutputfields], 6344d537eeaSYohann fieldname, size, emode); 635fe2413ffSjeremylt CeedChk(ierr); 636fe2413ffSjeremylt qf->numoutputfields++; 637d7b241e6Sjeremylt return 0; 638d7b241e6Sjeremylt } 639d7b241e6Sjeremylt 640dfdf5a53Sjeremylt /** 6414ce2993fSjeremylt @brief Set global context for a CeedQFunction 642b11c1e72Sjeremylt 643b11c1e72Sjeremylt @param qf CeedQFunction 644b11c1e72Sjeremylt @param ctx Context data to set 645b11c1e72Sjeremylt @param ctxsize Size of context data values 646b11c1e72Sjeremylt 647b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 648dfdf5a53Sjeremylt 649*7a982d89SJeremy L. Thompson @ref User 650b11c1e72Sjeremylt **/ 651d7b241e6Sjeremylt int CeedQFunctionSetContext(CeedQFunction qf, void *ctx, size_t ctxsize) { 652d7b241e6Sjeremylt qf->ctx = ctx; 653d7b241e6Sjeremylt qf->ctxsize = ctxsize; 654d7b241e6Sjeremylt return 0; 655d7b241e6Sjeremylt } 656d7b241e6Sjeremylt 657b11c1e72Sjeremylt /** 65875affc3bSjeremylt @brief View a CeedQFunction 65975affc3bSjeremylt 66075affc3bSjeremylt @param[in] qf CeedQFunction to view 66175affc3bSjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 66275affc3bSjeremylt 66375affc3bSjeremylt @return Error code: 0 - success, otherwise - failure 66475affc3bSjeremylt 665*7a982d89SJeremy L. Thompson @ref User 66675affc3bSjeremylt **/ 66775affc3bSjeremylt int CeedQFunctionView(CeedQFunction qf, FILE *stream) { 66875affc3bSjeremylt int ierr; 66975affc3bSjeremylt 67075affc3bSjeremylt fprintf(stream, "%sCeedQFunction %s\n", 67175affc3bSjeremylt qf->qfname ? "Gallery " : "User ", qf->qfname ? qf->qfname : ""); 67275affc3bSjeremylt 6732da88da5Sjeremylt fprintf(stream, " %d Input Field%s:\n", qf->numinputfields, 67475affc3bSjeremylt qf->numinputfields>1 ? "s" : ""); 67575affc3bSjeremylt for (CeedInt i=0; i<qf->numinputfields; i++) { 6762da88da5Sjeremylt ierr = CeedQFunctionFieldView(qf->inputfields[i], i, 1, stream); 6772da88da5Sjeremylt CeedChk(ierr); 67875affc3bSjeremylt } 67975affc3bSjeremylt 6802da88da5Sjeremylt fprintf(stream, " %d Output Field%s:\n", qf->numoutputfields, 68175affc3bSjeremylt qf->numoutputfields>1 ? "s" : ""); 68275affc3bSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 6832da88da5Sjeremylt ierr = CeedQFunctionFieldView(qf->outputfields[i], i, 0, stream); 68475affc3bSjeremylt CeedChk(ierr); 68575affc3bSjeremylt } 68675affc3bSjeremylt return 0; 68775affc3bSjeremylt } 68875affc3bSjeremylt 68975affc3bSjeremylt /** 690b11c1e72Sjeremylt @brief Apply the action of a CeedQFunction 691b11c1e72Sjeremylt 692b11c1e72Sjeremylt @param qf CeedQFunction 693b11c1e72Sjeremylt @param Q Number of quadrature points 69434138859Sjeremylt @param[in] u Array of input CeedVectors 69534138859Sjeremylt @param[out] v Array of output CeedVectors 696b11c1e72Sjeremylt 697b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 698dfdf5a53Sjeremylt 699*7a982d89SJeremy L. Thompson @ref User 700b11c1e72Sjeremylt **/ 701d7b241e6Sjeremylt int CeedQFunctionApply(CeedQFunction qf, CeedInt Q, 702aedaa0e5Sjeremylt CeedVector *u, CeedVector *v) { 703d7b241e6Sjeremylt int ierr; 704d7b241e6Sjeremylt if (!qf->Apply) 705c042f62fSJeremy L Thompson // LCOV_EXCL_START 706d7b241e6Sjeremylt return CeedError(qf->ceed, 1, "Backend does not support QFunctionApply"); 707c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 708d7b241e6Sjeremylt if (Q % qf->vlength) 709c042f62fSJeremy L Thompson // LCOV_EXCL_START 7101d102b48SJeremy L Thompson return CeedError(qf->ceed, 2, "Number of quadrature points %d must be a " 7111d102b48SJeremy L Thompson "multiple of %d", Q, qf->vlength); 712c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 713d7b241e6Sjeremylt ierr = qf->Apply(qf, Q, u, v); CeedChk(ierr); 714d7b241e6Sjeremylt return 0; 715d7b241e6Sjeremylt } 716d7b241e6Sjeremylt 717b11c1e72Sjeremylt /** 718b11c1e72Sjeremylt @brief Destroy a CeedQFunction 719b11c1e72Sjeremylt 720b11c1e72Sjeremylt @param qf CeedQFunction to destroy 721b11c1e72Sjeremylt 722b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 723dfdf5a53Sjeremylt 724*7a982d89SJeremy L. Thompson @ref User 725b11c1e72Sjeremylt **/ 726d7b241e6Sjeremylt int CeedQFunctionDestroy(CeedQFunction *qf) { 727d7b241e6Sjeremylt int ierr; 728d7b241e6Sjeremylt 7291d102b48SJeremy L Thompson if (!*qf || --(*qf)->refcount > 0) 7301d102b48SJeremy L Thompson return 0; 731fe2413ffSjeremylt // Backend destroy 732d7b241e6Sjeremylt if ((*qf)->Destroy) { 733d7b241e6Sjeremylt ierr = (*qf)->Destroy(*qf); CeedChk(ierr); 734d7b241e6Sjeremylt } 735fe2413ffSjeremylt // Free fields 736fe2413ffSjeremylt for (int i=0; i<(*qf)->numinputfields; i++) { 737fe2413ffSjeremylt ierr = CeedFree(&(*(*qf)->inputfields[i]).fieldname); CeedChk(ierr); 738fe2413ffSjeremylt ierr = CeedFree(&(*qf)->inputfields[i]); CeedChk(ierr); 739fe2413ffSjeremylt } 740fe2413ffSjeremylt for (int i=0; i<(*qf)->numoutputfields; i++) { 741fe2413ffSjeremylt ierr = CeedFree(&(*(*qf)->outputfields[i]).fieldname); CeedChk(ierr); 742fe2413ffSjeremylt ierr = CeedFree(&(*qf)->outputfields[i]); CeedChk(ierr); 743fe2413ffSjeremylt } 744fe2413ffSjeremylt ierr = CeedFree(&(*qf)->inputfields); CeedChk(ierr); 745fe2413ffSjeremylt ierr = CeedFree(&(*qf)->outputfields); CeedChk(ierr); 7460219ea01SJeremy L Thompson // Free ctx if identity 7470219ea01SJeremy L Thompson if ((*qf)->identity) { 7480219ea01SJeremy L Thompson ierr = CeedFree(&(*qf)->ctx); CeedChk(ierr); 7490219ea01SJeremy L Thompson } 750fe2413ffSjeremylt 751288c0443SJeremy L Thompson ierr = CeedFree(&(*qf)->sourcepath); CeedChk(ierr); 75275affc3bSjeremylt ierr = CeedFree(&(*qf)->qfname); CeedChk(ierr); 753d7b241e6Sjeremylt ierr = CeedDestroy(&(*qf)->ceed); CeedChk(ierr); 754d7b241e6Sjeremylt ierr = CeedFree(qf); CeedChk(ierr); 755d7b241e6Sjeremylt return 0; 756d7b241e6Sjeremylt } 757d7b241e6Sjeremylt 758d7b241e6Sjeremylt /// @} 759