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> 203bd813ffSjeremylt #include <math.h> 21d7b241e6Sjeremylt 22dfdf5a53Sjeremylt /// @file 23*7a982d89SJeremy L. Thompson /// Implementation of CeedOperator interfaces 24*7a982d89SJeremy L. Thompson 25*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 26*7a982d89SJeremy L. Thompson /// CeedOperator Library Internal Functions 27*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 28*7a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorDeveloper 29*7a982d89SJeremy L. Thompson /// @{ 30*7a982d89SJeremy L. Thompson 31*7a982d89SJeremy L. Thompson /** 32*7a982d89SJeremy L. Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 33*7a982d89SJeremy L. Thompson CeedOperator functionality 34*7a982d89SJeremy L. Thompson 35*7a982d89SJeremy L. Thompson @param op CeedOperator to create fallback for 36*7a982d89SJeremy L. Thompson 37*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 38*7a982d89SJeremy L. Thompson 39*7a982d89SJeremy L. Thompson @ref Developer 40*7a982d89SJeremy L. Thompson **/ 41*7a982d89SJeremy L. Thompson int CeedOperatorCreateFallback(CeedOperator op) { 42*7a982d89SJeremy L. Thompson int ierr; 43*7a982d89SJeremy L. Thompson 44*7a982d89SJeremy L. Thompson // Fallback Ceed 45*7a982d89SJeremy L. Thompson const char *resource, *fallbackresource; 46*7a982d89SJeremy L. Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 47*7a982d89SJeremy L. Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 48*7a982d89SJeremy L. Thompson CeedChk(ierr); 49*7a982d89SJeremy L. Thompson if (!strcmp(resource, fallbackresource)) 50*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 51*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 52*7a982d89SJeremy L. Thompson "fallback to resource %s", resource, fallbackresource); 53*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 54*7a982d89SJeremy L. Thompson 55*7a982d89SJeremy L. Thompson // Fallback Ceed 56*7a982d89SJeremy L. Thompson Ceed ceedref; 57*7a982d89SJeremy L. Thompson if (!op->ceed->opfallbackceed) { 58*7a982d89SJeremy L. Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 59*7a982d89SJeremy L. Thompson ceedref->opfallbackparent = op->ceed; 60*7a982d89SJeremy L. Thompson op->ceed->opfallbackceed = ceedref; 61*7a982d89SJeremy L. Thompson } 62*7a982d89SJeremy L. Thompson ceedref = op->ceed->opfallbackceed; 63*7a982d89SJeremy L. Thompson 64*7a982d89SJeremy L. Thompson // Clone Op 65*7a982d89SJeremy L. Thompson CeedOperator opref; 66*7a982d89SJeremy L. Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 67*7a982d89SJeremy L. Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 68*7a982d89SJeremy L. Thompson opref->data = NULL; 69*7a982d89SJeremy L. Thompson opref->setupdone = 0; 70*7a982d89SJeremy L. Thompson opref->ceed = ceedref; 71*7a982d89SJeremy L. Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 72*7a982d89SJeremy L. Thompson op->opfallback = opref; 73*7a982d89SJeremy L. Thompson 74*7a982d89SJeremy L. Thompson // Clone QF 75*7a982d89SJeremy L. Thompson CeedQFunction qfref; 76*7a982d89SJeremy L. Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 77*7a982d89SJeremy L. Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 78*7a982d89SJeremy L. Thompson qfref->data = NULL; 79*7a982d89SJeremy L. Thompson qfref->ceed = ceedref; 80*7a982d89SJeremy L. Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 81*7a982d89SJeremy L. Thompson opref->qf = qfref; 82*7a982d89SJeremy L. Thompson op->qffallback = qfref; 83*7a982d89SJeremy L. Thompson 84*7a982d89SJeremy L. Thompson return 0; 85*7a982d89SJeremy L. Thompson } 86*7a982d89SJeremy L. Thompson 87*7a982d89SJeremy L. Thompson /** 88*7a982d89SJeremy L. Thompson @brief Check if a CeedOperator is ready to be used. 89*7a982d89SJeremy L. Thompson 90*7a982d89SJeremy L. Thompson @param[in] ceed Ceed object for error handling 91*7a982d89SJeremy L. Thompson @param[in] op CeedOperator to check 92*7a982d89SJeremy L. Thompson 93*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 94*7a982d89SJeremy L. Thompson 95*7a982d89SJeremy L. Thompson @ref Developer 96*7a982d89SJeremy L. Thompson **/ 97*7a982d89SJeremy L. Thompson static int CeedOperatorCheckReady(Ceed ceed, CeedOperator op) { 98*7a982d89SJeremy L. Thompson CeedQFunction qf = op->qf; 99*7a982d89SJeremy L. Thompson 100*7a982d89SJeremy L. Thompson if (op->composite) { 101*7a982d89SJeremy L. Thompson if (!op->numsub) 102*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 103*7a982d89SJeremy L. Thompson return CeedError(ceed, 1, "No suboperators set"); 104*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 105*7a982d89SJeremy L. Thompson } else { 106*7a982d89SJeremy L. Thompson if (op->nfields == 0) 107*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 108*7a982d89SJeremy L. Thompson return CeedError(ceed, 1, "No operator fields set"); 109*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 110*7a982d89SJeremy L. Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 111*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 112*7a982d89SJeremy L. Thompson return CeedError(ceed, 1, "Not all operator fields set"); 113*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 114*7a982d89SJeremy L. Thompson if (!op->hasrestriction) 115*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 116*7a982d89SJeremy L. Thompson return CeedError(ceed, 1,"At least one restriction required"); 117*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 118*7a982d89SJeremy L. Thompson if (op->numqpoints == 0) 119*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 120*7a982d89SJeremy L. Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 121*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 122*7a982d89SJeremy L. Thompson } 123*7a982d89SJeremy L. Thompson 124*7a982d89SJeremy L. Thompson return 0; 125*7a982d89SJeremy L. Thompson } 126*7a982d89SJeremy L. Thompson 127*7a982d89SJeremy L. Thompson /** 128*7a982d89SJeremy L. Thompson @brief View a field of a CeedOperator 129*7a982d89SJeremy L. Thompson 130*7a982d89SJeremy L. Thompson @param[in] field Operator field to view 131*7a982d89SJeremy L. Thompson @param[in] fieldnumber Number of field being viewed 132*7a982d89SJeremy L. Thompson @param[in] stream Stream to view to, e.g., stdout 133*7a982d89SJeremy L. Thompson 134*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 135*7a982d89SJeremy L. Thompson 136*7a982d89SJeremy L. Thompson @ref Utility 137*7a982d89SJeremy L. Thompson **/ 138*7a982d89SJeremy L. Thompson static int CeedOperatorFieldView(CeedOperatorField field, 139*7a982d89SJeremy L. Thompson CeedQFunctionField qffield, 140*7a982d89SJeremy L. Thompson CeedInt fieldnumber, bool sub, bool in, 141*7a982d89SJeremy L. Thompson FILE *stream) { 142*7a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 143*7a982d89SJeremy L. Thompson const char *inout = in ? "Input" : "Output"; 144*7a982d89SJeremy L. Thompson 145*7a982d89SJeremy L. Thompson fprintf(stream, "%s %s Field [%d]:\n" 146*7a982d89SJeremy L. Thompson "%s Name: \"%s\"\n", 147*7a982d89SJeremy L. Thompson pre, inout, fieldnumber, pre, qffield->fieldname); 148*7a982d89SJeremy L. Thompson 149*7a982d89SJeremy L. Thompson if (field->basis == CEED_BASIS_COLLOCATED) 150*7a982d89SJeremy L. Thompson fprintf(stream, "%s Collocated basis\n", pre); 151*7a982d89SJeremy L. Thompson 152*7a982d89SJeremy L. Thompson if (field->vec == CEED_VECTOR_ACTIVE) 153*7a982d89SJeremy L. Thompson fprintf(stream, "%s Active vector\n", pre); 154*7a982d89SJeremy L. Thompson else if (field->vec == CEED_VECTOR_NONE) 155*7a982d89SJeremy L. Thompson fprintf(stream, "%s No vector\n", pre); 156*7a982d89SJeremy L. Thompson 157*7a982d89SJeremy L. Thompson return 0; 158*7a982d89SJeremy L. Thompson } 159*7a982d89SJeremy L. Thompson 160*7a982d89SJeremy L. Thompson /** 161*7a982d89SJeremy L. Thompson @brief View a single CeedOperator 162*7a982d89SJeremy L. Thompson 163*7a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 164*7a982d89SJeremy L. Thompson @param[in] sub Boolean flag for sub-operator 165*7a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 166*7a982d89SJeremy L. Thompson 167*7a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 168*7a982d89SJeremy L. Thompson 169*7a982d89SJeremy L. Thompson @ref Utility 170*7a982d89SJeremy L. Thompson **/ 171*7a982d89SJeremy L. Thompson int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 172*7a982d89SJeremy L. Thompson int ierr; 173*7a982d89SJeremy L. Thompson const char *pre = sub ? " " : ""; 174*7a982d89SJeremy L. Thompson 175*7a982d89SJeremy L. Thompson CeedInt totalfields; 176*7a982d89SJeremy L. Thompson ierr = CeedOperatorGetNumArgs(op, &totalfields); CeedChk(ierr); 177*7a982d89SJeremy L. Thompson 178*7a982d89SJeremy L. Thompson fprintf(stream, "%s %d Field%s\n", pre, totalfields, totalfields>1 ? "s" : ""); 179*7a982d89SJeremy L. Thompson 180*7a982d89SJeremy L. Thompson fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->numinputfields, 181*7a982d89SJeremy L. Thompson op->qf->numinputfields>1 ? "s" : ""); 182*7a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->qf->numinputfields; i++) { 183*7a982d89SJeremy L. Thompson ierr = CeedOperatorFieldView(op->inputfields[i], op->qf->inputfields[i], 184*7a982d89SJeremy L. Thompson i, sub, 1, stream); CeedChk(ierr); 185*7a982d89SJeremy L. Thompson } 186*7a982d89SJeremy L. Thompson 187*7a982d89SJeremy L. Thompson fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->numoutputfields, 188*7a982d89SJeremy L. Thompson op->qf->numoutputfields>1 ? "s" : ""); 189*7a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 190*7a982d89SJeremy L. Thompson ierr = CeedOperatorFieldView(op->outputfields[i], op->qf->inputfields[i], 191*7a982d89SJeremy L. Thompson i, sub, 0, stream); CeedChk(ierr); 192*7a982d89SJeremy L. Thompson } 193*7a982d89SJeremy L. Thompson 194*7a982d89SJeremy L. Thompson return 0; 195*7a982d89SJeremy L. Thompson } 196*7a982d89SJeremy L. Thompson 197*7a982d89SJeremy L. Thompson /// @} 198*7a982d89SJeremy L. Thompson 199*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 200*7a982d89SJeremy L. Thompson /// CeedOperator Backend API 201*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 202*7a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorBackend 203*7a982d89SJeremy L. Thompson /// @{ 204*7a982d89SJeremy L. Thompson 205*7a982d89SJeremy L. Thompson /** 206*7a982d89SJeremy L. Thompson @brief Get the Ceed associated with a CeedOperator 207*7a982d89SJeremy L. Thompson 208*7a982d89SJeremy L. Thompson @param op CeedOperator 209*7a982d89SJeremy L. Thompson @param[out] ceed Variable to store Ceed 210*7a982d89SJeremy L. Thompson 211*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 212*7a982d89SJeremy L. Thompson 213*7a982d89SJeremy L. Thompson @ref Backend 214*7a982d89SJeremy L. Thompson **/ 215*7a982d89SJeremy L. Thompson 216*7a982d89SJeremy L. Thompson int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 217*7a982d89SJeremy L. Thompson *ceed = op->ceed; 218*7a982d89SJeremy L. Thompson return 0; 219*7a982d89SJeremy L. Thompson } 220*7a982d89SJeremy L. Thompson 221*7a982d89SJeremy L. Thompson /** 222*7a982d89SJeremy L. Thompson @brief Get the number of elements associated with a CeedOperator 223*7a982d89SJeremy L. Thompson 224*7a982d89SJeremy L. Thompson @param op CeedOperator 225*7a982d89SJeremy L. Thompson @param[out] numelem Variable to store number of elements 226*7a982d89SJeremy L. Thompson 227*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 228*7a982d89SJeremy L. Thompson 229*7a982d89SJeremy L. Thompson @ref Backend 230*7a982d89SJeremy L. Thompson **/ 231*7a982d89SJeremy L. Thompson 232*7a982d89SJeremy L. Thompson int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 233*7a982d89SJeremy L. Thompson if (op->composite) 234*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 235*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 236*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 237*7a982d89SJeremy L. Thompson 238*7a982d89SJeremy L. Thompson *numelem = op->numelements; 239*7a982d89SJeremy L. Thompson return 0; 240*7a982d89SJeremy L. Thompson } 241*7a982d89SJeremy L. Thompson 242*7a982d89SJeremy L. Thompson /** 243*7a982d89SJeremy L. Thompson @brief Get the number of quadrature points associated with a CeedOperator 244*7a982d89SJeremy L. Thompson 245*7a982d89SJeremy L. Thompson @param op CeedOperator 246*7a982d89SJeremy L. Thompson @param[out] numqpts Variable to store vector number of quadrature points 247*7a982d89SJeremy L. Thompson 248*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 249*7a982d89SJeremy L. Thompson 250*7a982d89SJeremy L. Thompson @ref Backend 251*7a982d89SJeremy L. Thompson **/ 252*7a982d89SJeremy L. Thompson 253*7a982d89SJeremy L. Thompson int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 254*7a982d89SJeremy L. Thompson if (op->composite) 255*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 256*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 257*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 258*7a982d89SJeremy L. Thompson 259*7a982d89SJeremy L. Thompson *numqpts = op->numqpoints; 260*7a982d89SJeremy L. Thompson return 0; 261*7a982d89SJeremy L. Thompson } 262*7a982d89SJeremy L. Thompson 263*7a982d89SJeremy L. Thompson /** 264*7a982d89SJeremy L. Thompson @brief Get the number of arguments associated with a CeedOperator 265*7a982d89SJeremy L. Thompson 266*7a982d89SJeremy L. Thompson @param op CeedOperator 267*7a982d89SJeremy L. Thompson @param[out] numargs Variable to store vector number of arguments 268*7a982d89SJeremy L. Thompson 269*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 270*7a982d89SJeremy L. Thompson 271*7a982d89SJeremy L. Thompson @ref Backend 272*7a982d89SJeremy L. Thompson **/ 273*7a982d89SJeremy L. Thompson 274*7a982d89SJeremy L. Thompson int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 275*7a982d89SJeremy L. Thompson if (op->composite) 276*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 277*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 278*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 279*7a982d89SJeremy L. Thompson 280*7a982d89SJeremy L. Thompson *numargs = op->nfields; 281*7a982d89SJeremy L. Thompson return 0; 282*7a982d89SJeremy L. Thompson } 283*7a982d89SJeremy L. Thompson 284*7a982d89SJeremy L. Thompson /** 285*7a982d89SJeremy L. Thompson @brief Get the setup status of a CeedOperator 286*7a982d89SJeremy L. Thompson 287*7a982d89SJeremy L. Thompson @param op CeedOperator 288*7a982d89SJeremy L. Thompson @param[out] setupdone Variable to store setup status 289*7a982d89SJeremy L. Thompson 290*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 291*7a982d89SJeremy L. Thompson 292*7a982d89SJeremy L. Thompson @ref Backend 293*7a982d89SJeremy L. Thompson **/ 294*7a982d89SJeremy L. Thompson 295*7a982d89SJeremy L. Thompson int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 296*7a982d89SJeremy L. Thompson *setupdone = op->setupdone; 297*7a982d89SJeremy L. Thompson return 0; 298*7a982d89SJeremy L. Thompson } 299*7a982d89SJeremy L. Thompson 300*7a982d89SJeremy L. Thompson /** 301*7a982d89SJeremy L. Thompson @brief Get the QFunction associated with a CeedOperator 302*7a982d89SJeremy L. Thompson 303*7a982d89SJeremy L. Thompson @param op CeedOperator 304*7a982d89SJeremy L. Thompson @param[out] qf Variable to store QFunction 305*7a982d89SJeremy L. Thompson 306*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 307*7a982d89SJeremy L. Thompson 308*7a982d89SJeremy L. Thompson @ref Backend 309*7a982d89SJeremy L. Thompson **/ 310*7a982d89SJeremy L. Thompson 311*7a982d89SJeremy L. Thompson int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 312*7a982d89SJeremy L. Thompson if (op->composite) 313*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 314*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 315*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 316*7a982d89SJeremy L. Thompson 317*7a982d89SJeremy L. Thompson *qf = op->qf; 318*7a982d89SJeremy L. Thompson return 0; 319*7a982d89SJeremy L. Thompson } 320*7a982d89SJeremy L. Thompson 321*7a982d89SJeremy L. Thompson /** 322*7a982d89SJeremy L. Thompson @brief Get the number of suboperators associated with a CeedOperator 323*7a982d89SJeremy L. Thompson 324*7a982d89SJeremy L. Thompson @param op CeedOperator 325*7a982d89SJeremy L. Thompson @param[out] numsub Variable to store number of suboperators 326*7a982d89SJeremy L. Thompson 327*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 328*7a982d89SJeremy L. Thompson 329*7a982d89SJeremy L. Thompson @ref Backend 330*7a982d89SJeremy L. Thompson **/ 331*7a982d89SJeremy L. Thompson 332*7a982d89SJeremy L. Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 333*7a982d89SJeremy L. Thompson if (!op->composite) 334*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 335*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 336*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 337*7a982d89SJeremy L. Thompson 338*7a982d89SJeremy L. Thompson *numsub = op->numsub; 339*7a982d89SJeremy L. Thompson return 0; 340*7a982d89SJeremy L. Thompson } 341*7a982d89SJeremy L. Thompson 342*7a982d89SJeremy L. Thompson /** 343*7a982d89SJeremy L. Thompson @brief Get the list of suboperators associated with a CeedOperator 344*7a982d89SJeremy L. Thompson 345*7a982d89SJeremy L. Thompson @param op CeedOperator 346*7a982d89SJeremy L. Thompson @param[out] suboperators Variable to store list of suboperators 347*7a982d89SJeremy L. Thompson 348*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 349*7a982d89SJeremy L. Thompson 350*7a982d89SJeremy L. Thompson @ref Backend 351*7a982d89SJeremy L. Thompson **/ 352*7a982d89SJeremy L. Thompson 353*7a982d89SJeremy L. Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 354*7a982d89SJeremy L. Thompson if (!op->composite) 355*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 356*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 357*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 358*7a982d89SJeremy L. Thompson 359*7a982d89SJeremy L. Thompson *suboperators = op->suboperators; 360*7a982d89SJeremy L. Thompson return 0; 361*7a982d89SJeremy L. Thompson } 362*7a982d89SJeremy L. Thompson 363*7a982d89SJeremy L. Thompson /** 364*7a982d89SJeremy L. Thompson @brief Get the backend data of a CeedOperator 365*7a982d89SJeremy L. Thompson 366*7a982d89SJeremy L. Thompson @param op CeedOperator 367*7a982d89SJeremy L. Thompson @param[out] data Variable to store data 368*7a982d89SJeremy L. Thompson 369*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 370*7a982d89SJeremy L. Thompson 371*7a982d89SJeremy L. Thompson @ref Backend 372*7a982d89SJeremy L. Thompson **/ 373*7a982d89SJeremy L. Thompson 374*7a982d89SJeremy L. Thompson int CeedOperatorGetData(CeedOperator op, void **data) { 375*7a982d89SJeremy L. Thompson *data = op->data; 376*7a982d89SJeremy L. Thompson return 0; 377*7a982d89SJeremy L. Thompson } 378*7a982d89SJeremy L. Thompson 379*7a982d89SJeremy L. Thompson /** 380*7a982d89SJeremy L. Thompson @brief Set the backend data of a CeedOperator 381*7a982d89SJeremy L. Thompson 382*7a982d89SJeremy L. Thompson @param[out] op CeedOperator 383*7a982d89SJeremy L. Thompson @param data Data to set 384*7a982d89SJeremy L. Thompson 385*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 386*7a982d89SJeremy L. Thompson 387*7a982d89SJeremy L. Thompson @ref Backend 388*7a982d89SJeremy L. Thompson **/ 389*7a982d89SJeremy L. Thompson 390*7a982d89SJeremy L. Thompson int CeedOperatorSetData(CeedOperator op, void **data) { 391*7a982d89SJeremy L. Thompson op->data = *data; 392*7a982d89SJeremy L. Thompson return 0; 393*7a982d89SJeremy L. Thompson } 394*7a982d89SJeremy L. Thompson 395*7a982d89SJeremy L. Thompson /** 396*7a982d89SJeremy L. Thompson @brief Set the setup flag of a CeedOperator to True 397*7a982d89SJeremy L. Thompson 398*7a982d89SJeremy L. Thompson @param op CeedOperator 399*7a982d89SJeremy L. Thompson 400*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 401*7a982d89SJeremy L. Thompson 402*7a982d89SJeremy L. Thompson @ref Backend 403*7a982d89SJeremy L. Thompson **/ 404*7a982d89SJeremy L. Thompson 405*7a982d89SJeremy L. Thompson int CeedOperatorSetSetupDone(CeedOperator op) { 406*7a982d89SJeremy L. Thompson op->setupdone = 1; 407*7a982d89SJeremy L. Thompson return 0; 408*7a982d89SJeremy L. Thompson } 409*7a982d89SJeremy L. Thompson 410*7a982d89SJeremy L. Thompson /** 411*7a982d89SJeremy L. Thompson @brief Get the CeedOperatorFields of a CeedOperator 412*7a982d89SJeremy L. Thompson 413*7a982d89SJeremy L. Thompson @param op CeedOperator 414*7a982d89SJeremy L. Thompson @param[out] inputfields Variable to store inputfields 415*7a982d89SJeremy L. Thompson @param[out] outputfields Variable to store outputfields 416*7a982d89SJeremy L. Thompson 417*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 418*7a982d89SJeremy L. Thompson 419*7a982d89SJeremy L. Thompson @ref Backend 420*7a982d89SJeremy L. Thompson **/ 421*7a982d89SJeremy L. Thompson 422*7a982d89SJeremy L. Thompson int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **inputfields, 423*7a982d89SJeremy L. Thompson CeedOperatorField **outputfields) { 424*7a982d89SJeremy L. Thompson if (op->composite) 425*7a982d89SJeremy L. Thompson // LCOV_EXCL_START 426*7a982d89SJeremy L. Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 427*7a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 428*7a982d89SJeremy L. Thompson 429*7a982d89SJeremy L. Thompson if (inputfields) *inputfields = op->inputfields; 430*7a982d89SJeremy L. Thompson if (outputfields) *outputfields = op->outputfields; 431*7a982d89SJeremy L. Thompson return 0; 432*7a982d89SJeremy L. Thompson } 433*7a982d89SJeremy L. Thompson 434*7a982d89SJeremy L. Thompson /** 435*7a982d89SJeremy L. Thompson @brief Get the CeedElemRestriction of a CeedOperatorField 436*7a982d89SJeremy L. Thompson 437*7a982d89SJeremy L. Thompson @param opfield CeedOperatorField 438*7a982d89SJeremy L. Thompson @param[out] rstr Variable to store CeedElemRestriction 439*7a982d89SJeremy L. Thompson 440*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 441*7a982d89SJeremy L. Thompson 442*7a982d89SJeremy L. Thompson @ref Backend 443*7a982d89SJeremy L. Thompson **/ 444*7a982d89SJeremy L. Thompson 445*7a982d89SJeremy L. Thompson int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 446*7a982d89SJeremy L. Thompson CeedElemRestriction *rstr) { 447*7a982d89SJeremy L. Thompson *rstr = opfield->Erestrict; 448*7a982d89SJeremy L. Thompson return 0; 449*7a982d89SJeremy L. Thompson } 450*7a982d89SJeremy L. Thompson 451*7a982d89SJeremy L. Thompson /** 452*7a982d89SJeremy L. Thompson @brief Get the CeedBasis of a CeedOperatorField 453*7a982d89SJeremy L. Thompson 454*7a982d89SJeremy L. Thompson @param opfield CeedOperatorField 455*7a982d89SJeremy L. Thompson @param[out] basis Variable to store CeedBasis 456*7a982d89SJeremy L. Thompson 457*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 458*7a982d89SJeremy L. Thompson 459*7a982d89SJeremy L. Thompson @ref Backend 460*7a982d89SJeremy L. Thompson **/ 461*7a982d89SJeremy L. Thompson 462*7a982d89SJeremy L. Thompson int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 463*7a982d89SJeremy L. Thompson *basis = opfield->basis; 464*7a982d89SJeremy L. Thompson return 0; 465*7a982d89SJeremy L. Thompson } 466*7a982d89SJeremy L. Thompson 467*7a982d89SJeremy L. Thompson /** 468*7a982d89SJeremy L. Thompson @brief Get the CeedVector of a CeedOperatorField 469*7a982d89SJeremy L. Thompson 470*7a982d89SJeremy L. Thompson @param opfield CeedOperatorField 471*7a982d89SJeremy L. Thompson @param[out] vec Variable to store CeedVector 472*7a982d89SJeremy L. Thompson 473*7a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 474*7a982d89SJeremy L. Thompson 475*7a982d89SJeremy L. Thompson @ref Backend 476*7a982d89SJeremy L. Thompson **/ 477*7a982d89SJeremy L. Thompson 478*7a982d89SJeremy L. Thompson int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 479*7a982d89SJeremy L. Thompson *vec = opfield->vec; 480*7a982d89SJeremy L. Thompson return 0; 481*7a982d89SJeremy L. Thompson } 482*7a982d89SJeremy L. Thompson 483*7a982d89SJeremy L. Thompson /// @} 484*7a982d89SJeremy L. Thompson 485*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 486*7a982d89SJeremy L. Thompson /// CeedOperator Public API 487*7a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 488*7a982d89SJeremy L. Thompson /// @addtogroup CeedOperatorUser 489dfdf5a53Sjeremylt /// @{ 490d7b241e6Sjeremylt 491d7b241e6Sjeremylt /** 4920219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 4930219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 4940219ea01SJeremy L Thompson \ref CeedOperatorSetField. 495d7b241e6Sjeremylt 496b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 497d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 49834138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 49934138859Sjeremylt CEED_QFUNCTION_NONE) 500d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 50134138859Sjeremylt of @a qf (or CEED_QFUNCTION_NONE) 502b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 503b11c1e72Sjeremylt CeedOperator will be stored 504b11c1e72Sjeremylt 505b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 506dfdf5a53Sjeremylt 507*7a982d89SJeremy L. Thompson @ref User 508d7b241e6Sjeremylt */ 509d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 510d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 511d7b241e6Sjeremylt int ierr; 512d7b241e6Sjeremylt 5135fe0d4faSjeremylt if (!ceed->OperatorCreate) { 5145fe0d4faSjeremylt Ceed delegate; 515aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 5165fe0d4faSjeremylt 5175fe0d4faSjeremylt if (!delegate) 518c042f62fSJeremy L Thompson // LCOV_EXCL_START 5195fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 520c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 5215fe0d4faSjeremylt 5225fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 5235fe0d4faSjeremylt return 0; 5245fe0d4faSjeremylt } 5255fe0d4faSjeremylt 526d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 527d7b241e6Sjeremylt (*op)->ceed = ceed; 528d7b241e6Sjeremylt ceed->refcount++; 529d7b241e6Sjeremylt (*op)->refcount = 1; 530442e7f0bSjeremylt if (qf == CEED_QFUNCTION_NONE) 531442e7f0bSjeremylt // LCOV_EXCL_START 532442e7f0bSjeremylt return CeedError(ceed, 1, "Operator must have a valid QFunction."); 533442e7f0bSjeremylt // LCOV_EXCL_STOP 534d7b241e6Sjeremylt (*op)->qf = qf; 535d7b241e6Sjeremylt qf->refcount++; 536442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 537d7b241e6Sjeremylt (*op)->dqf = dqf; 538442e7f0bSjeremylt dqf->refcount++; 539442e7f0bSjeremylt } 540442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 541d7b241e6Sjeremylt (*op)->dqfT = dqfT; 542442e7f0bSjeremylt dqfT->refcount++; 543442e7f0bSjeremylt } 544fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 545fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 546d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 547d7b241e6Sjeremylt return 0; 548d7b241e6Sjeremylt } 549d7b241e6Sjeremylt 550d7b241e6Sjeremylt /** 55152d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 55252d6035fSJeremy L Thompson 55352d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 55452d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 55552d6035fSJeremy L Thompson Composite CeedOperator will be stored 55652d6035fSJeremy L Thompson 55752d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 55852d6035fSJeremy L Thompson 559*7a982d89SJeremy L. Thompson @ref User 56052d6035fSJeremy L Thompson */ 56152d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 56252d6035fSJeremy L Thompson int ierr; 56352d6035fSJeremy L Thompson 56452d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 56552d6035fSJeremy L Thompson Ceed delegate; 566aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 56752d6035fSJeremy L Thompson 568250756a7Sjeremylt if (delegate) { 56952d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 57052d6035fSJeremy L Thompson return 0; 57152d6035fSJeremy L Thompson } 572250756a7Sjeremylt } 57352d6035fSJeremy L Thompson 57452d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 57552d6035fSJeremy L Thompson (*op)->ceed = ceed; 57652d6035fSJeremy L Thompson ceed->refcount++; 57752d6035fSJeremy L Thompson (*op)->composite = true; 57852d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 579250756a7Sjeremylt 580250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 58152d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 582250756a7Sjeremylt } 58352d6035fSJeremy L Thompson return 0; 58452d6035fSJeremy L Thompson } 58552d6035fSJeremy L Thompson 58652d6035fSJeremy L Thompson /** 587b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 588d7b241e6Sjeremylt 589d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 590d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 591d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 592d7b241e6Sjeremylt 593d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 594d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 595d7b241e6Sjeremylt input and at most one active output. 596d7b241e6Sjeremylt 5978c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 5988795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 5998795c945Sjeremylt CeedQFunction) 600b11c1e72Sjeremylt @param r CeedElemRestriction 601783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 602b11c1e72Sjeremylt if collocated with quadrature points 603b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 604b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 6058c91a0c9SJeremy L Thompson CEED_EVAL_WEIGHT in the QFunction 606b11c1e72Sjeremylt 607b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 608dfdf5a53Sjeremylt 609*7a982d89SJeremy L. Thompson @ref User 610b11c1e72Sjeremylt **/ 611d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 612a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 613d7b241e6Sjeremylt int ierr; 61452d6035fSJeremy L Thompson if (op->composite) 615c042f62fSJeremy L Thompson // LCOV_EXCL_START 61652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 617c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6188b067b84SJed Brown if (!r) 619c042f62fSJeremy L Thompson // LCOV_EXCL_START 620c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 621c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 622c042f62fSJeremy L Thompson fieldname); 623c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6248b067b84SJed Brown if (!b) 625c042f62fSJeremy L Thompson // LCOV_EXCL_START 626c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 627c042f62fSJeremy L Thompson fieldname); 628c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6298b067b84SJed Brown if (!v) 630c042f62fSJeremy L Thompson // LCOV_EXCL_START 631c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 632c042f62fSJeremy L Thompson fieldname); 633c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 63452d6035fSJeremy L Thompson 635d7b241e6Sjeremylt CeedInt numelements; 636d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 63715910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->hasrestriction && 63815910d16Sjeremylt op->numelements != numelements) 639c042f62fSJeremy L Thompson // LCOV_EXCL_START 640d7b241e6Sjeremylt return CeedError(op->ceed, 1, 6411d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 6421d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 643c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 64415910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE) { 645d7b241e6Sjeremylt op->numelements = numelements; 6462cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 64715910d16Sjeremylt } 648d7b241e6Sjeremylt 649783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 650d7b241e6Sjeremylt CeedInt numqpoints; 651d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 652d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 653c042f62fSJeremy L Thompson // LCOV_EXCL_START 6541d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 6551d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 6561d102b48SJeremy L Thompson op->numqpoints); 657c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 658d7b241e6Sjeremylt op->numqpoints = numqpoints; 659d7b241e6Sjeremylt } 66015910d16Sjeremylt CeedQFunctionField qfield; 661d1bcdac9Sjeremylt CeedOperatorField *ofield; 662d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 663fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 66415910d16Sjeremylt qfield = op->qf->inputfields[i]; 665d7b241e6Sjeremylt ofield = &op->inputfields[i]; 666d7b241e6Sjeremylt goto found; 667d7b241e6Sjeremylt } 668d7b241e6Sjeremylt } 669d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 670fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 67115910d16Sjeremylt qfield = op->qf->inputfields[i]; 672d7b241e6Sjeremylt ofield = &op->outputfields[i]; 673d7b241e6Sjeremylt goto found; 674d7b241e6Sjeremylt } 675d7b241e6Sjeremylt } 676c042f62fSJeremy L Thompson // LCOV_EXCL_START 677d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 678d7b241e6Sjeremylt fieldname); 679c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 680d7b241e6Sjeremylt found: 68115910d16Sjeremylt if (r == CEED_ELEMRESTRICTION_NONE && qfield->emode != CEED_EVAL_WEIGHT) 68215910d16Sjeremylt return CeedError(op->ceed, 1, "CEED_ELEMRESTRICTION_NONE can only be used " 68315910d16Sjeremylt "for a field with eval mode CEED_EVAL_WEIGHT"); 684fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 685fe2413ffSjeremylt (*ofield)->Erestrict = r; 68671352a93Sjeremylt r->refcount += 1; 687fe2413ffSjeremylt (*ofield)->basis = b; 68871352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 68971352a93Sjeremylt b->refcount += 1; 690fe2413ffSjeremylt (*ofield)->vec = v; 69171352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 69271352a93Sjeremylt v->refcount += 1; 693d7b241e6Sjeremylt op->nfields += 1; 694d7b241e6Sjeremylt return 0; 695d7b241e6Sjeremylt } 696d7b241e6Sjeremylt 697d7b241e6Sjeremylt /** 69852d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 699288c0443SJeremy L Thompson 70034138859Sjeremylt @param[out] compositeop Composite CeedOperator 70134138859Sjeremylt @param subop Sub-operator CeedOperator 70252d6035fSJeremy L Thompson 70352d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 70452d6035fSJeremy L Thompson 705*7a982d89SJeremy L. Thompson @ref User 70652d6035fSJeremy L Thompson */ 707692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 70852d6035fSJeremy L Thompson if (!compositeop->composite) 709c042f62fSJeremy L Thompson // LCOV_EXCL_START 7101d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 7111d102b48SJeremy L Thompson "operator"); 712c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71352d6035fSJeremy L Thompson 71452d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 715c042f62fSJeremy L Thompson // LCOV_EXCL_START 7161d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 717c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71852d6035fSJeremy L Thompson 71952d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 72052d6035fSJeremy L Thompson subop->refcount++; 72152d6035fSJeremy L Thompson compositeop->numsub++; 72252d6035fSJeremy L Thompson return 0; 72352d6035fSJeremy L Thompson } 72452d6035fSJeremy L Thompson 72552d6035fSJeremy L Thompson /** 7261d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 7271d102b48SJeremy L Thompson 7281d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 7291d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 7301d102b48SJeremy L Thompson The vector 'assembled' is of shape 7311d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 7321d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 7331d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 7341d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 7351d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 7361d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 7371d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 7381d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 7391d102b48SJeremy L Thompson 7401d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 7411d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 7421d102b48SJeremy L Thompson quadrature points 7431d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 7441d102b48SJeremy L Thompson CeedQFunction 7451d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 7461d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 7471d102b48SJeremy L Thompson 7481d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 7491d102b48SJeremy L Thompson 750*7a982d89SJeremy L. Thompson @ref User 7511d102b48SJeremy L Thompson **/ 7521d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 7537f823360Sjeremylt CeedElemRestriction *rstr, 7547f823360Sjeremylt CeedRequest *request) { 7551d102b48SJeremy L Thompson int ierr; 7561d102b48SJeremy L Thompson Ceed ceed = op->ceed; 757250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 7581d102b48SJeremy L Thompson 7597172caadSjeremylt // Backend version 7605107b09fSJeremy L Thompson if (op->AssembleLinearQFunction) { 7611d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 7621d102b48SJeremy L Thompson CeedChk(ierr); 7635107b09fSJeremy L Thompson } else { 7645107b09fSJeremy L Thompson // Fallback to reference Ceed 7655107b09fSJeremy L Thompson if (!op->opfallback) { 7665107b09fSJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 7675107b09fSJeremy L Thompson } 7685107b09fSJeremy L Thompson // Assemble 7695107b09fSJeremy L Thompson ierr = op->opfallback->AssembleLinearQFunction(op->opfallback, assembled, 7705107b09fSJeremy L Thompson rstr, request); CeedChk(ierr); 7715107b09fSJeremy L Thompson } 772250756a7Sjeremylt 7731d102b48SJeremy L Thompson return 0; 7741d102b48SJeremy L Thompson } 7751d102b48SJeremy L Thompson 7761d102b48SJeremy L Thompson /** 777b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 778b7ec98d8SJeremy L Thompson 779b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 780b7ec98d8SJeremy L Thompson 781b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 782b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 783b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 784b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 785b7ec98d8SJeremy L Thompson 786b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 787b7ec98d8SJeremy L Thompson 788*7a982d89SJeremy L. Thompson @ref User 789b7ec98d8SJeremy L Thompson **/ 7907f823360Sjeremylt int CeedOperatorAssembleLinearDiagonal(CeedOperator op, CeedVector *assembled, 7917f823360Sjeremylt CeedRequest *request) { 792b7ec98d8SJeremy L Thompson int ierr; 793b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 794250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 795b7ec98d8SJeremy L Thompson 796b7ec98d8SJeremy L Thompson // Use backend version, if available 797b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 798b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 7997172caadSjeremylt } else { 8007172caadSjeremylt // Fallback to reference Ceed 8017172caadSjeremylt if (!op->opfallback) { 8027172caadSjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 803b7ec98d8SJeremy L Thompson } 8047172caadSjeremylt // Assemble 8057172caadSjeremylt ierr = op->opfallback->AssembleLinearDiagonal(op->opfallback, assembled, 8067172caadSjeremylt request); CeedChk(ierr); 807b7ec98d8SJeremy L Thompson } 808b7ec98d8SJeremy L Thompson 809b7ec98d8SJeremy L Thompson return 0; 810b7ec98d8SJeremy L Thompson } 811b7ec98d8SJeremy L Thompson 812b7ec98d8SJeremy L Thompson /** 8133bd813ffSjeremylt @brief Build a FDM based approximate inverse for each element for a 8143bd813ffSjeremylt CeedOperator 8153bd813ffSjeremylt 8163bd813ffSjeremylt This returns a CeedOperator and CeedVector to apply a Fast Diagonalization 8173bd813ffSjeremylt Method based approximate inverse. This function obtains the simultaneous 8183bd813ffSjeremylt diagonalization for the 1D mass and Laplacian operators, 8193bd813ffSjeremylt M = V^T V, K = V^T S V. 8203bd813ffSjeremylt The assembled QFunction is used to modify the eigenvalues from simultaneous 8213bd813ffSjeremylt diagonalization and obtain an approximate inverse of the form 8223bd813ffSjeremylt V^T S^hat V. The CeedOperator must be linear and non-composite. The 8233bd813ffSjeremylt associated CeedQFunction must therefore also be linear. 8243bd813ffSjeremylt 8253bd813ffSjeremylt @param op CeedOperator to create element inverses 8263bd813ffSjeremylt @param[out] fdminv CeedOperator to apply the action of a FDM based inverse 8273bd813ffSjeremylt for each element 8283bd813ffSjeremylt @param request Address of CeedRequest for non-blocking completion, else 8293bd813ffSjeremylt CEED_REQUEST_IMMEDIATE 8303bd813ffSjeremylt 8313bd813ffSjeremylt @return An error code: 0 - success, otherwise - failure 8323bd813ffSjeremylt 833*7a982d89SJeremy L. Thompson @ref Backend 8343bd813ffSjeremylt **/ 8353bd813ffSjeremylt int CeedOperatorCreateFDMElementInverse(CeedOperator op, CeedOperator *fdminv, 8363bd813ffSjeremylt CeedRequest *request) { 8373bd813ffSjeremylt int ierr; 8383bd813ffSjeremylt Ceed ceed = op->ceed; 839713f43c3Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 8403bd813ffSjeremylt 841713f43c3Sjeremylt // Use backend version, if available 842713f43c3Sjeremylt if (op->CreateFDMElementInverse) { 843713f43c3Sjeremylt ierr = op->CreateFDMElementInverse(op, fdminv, request); CeedChk(ierr); 844713f43c3Sjeremylt } else { 845713f43c3Sjeremylt // Fallback to reference Ceed 846713f43c3Sjeremylt if (!op->opfallback) { 847713f43c3Sjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 8483bd813ffSjeremylt } 849713f43c3Sjeremylt // Assemble 850713f43c3Sjeremylt ierr = op->opfallback->CreateFDMElementInverse(op->opfallback, fdminv, 8513bd813ffSjeremylt request); CeedChk(ierr); 8523bd813ffSjeremylt } 8533bd813ffSjeremylt 8543bd813ffSjeremylt return 0; 8553bd813ffSjeremylt } 8563bd813ffSjeremylt 857*7a982d89SJeremy L. Thompson /** 858*7a982d89SJeremy L. Thompson @brief View a CeedOperator 859*7a982d89SJeremy L. Thompson 860*7a982d89SJeremy L. Thompson @param[in] op CeedOperator to view 861*7a982d89SJeremy L. Thompson @param[in] stream Stream to write; typically stdout/stderr or a file 862*7a982d89SJeremy L. Thompson 863*7a982d89SJeremy L. Thompson @return Error code: 0 - success, otherwise - failure 864*7a982d89SJeremy L. Thompson 865*7a982d89SJeremy L. Thompson @ref User 866*7a982d89SJeremy L. Thompson **/ 867*7a982d89SJeremy L. Thompson int CeedOperatorView(CeedOperator op, FILE *stream) { 868*7a982d89SJeremy L. Thompson int ierr; 869*7a982d89SJeremy L. Thompson 870*7a982d89SJeremy L. Thompson if (op->composite) { 871*7a982d89SJeremy L. Thompson fprintf(stream, "Composite CeedOperator\n"); 872*7a982d89SJeremy L. Thompson 873*7a982d89SJeremy L. Thompson for (CeedInt i=0; i<op->numsub; i++) { 874*7a982d89SJeremy L. Thompson fprintf(stream, " SubOperator [%d]:\n", i); 875*7a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op->suboperators[i], 1, stream); 876*7a982d89SJeremy L. Thompson CeedChk(ierr); 877*7a982d89SJeremy L. Thompson } 878*7a982d89SJeremy L. Thompson } else { 879*7a982d89SJeremy L. Thompson fprintf(stream, "CeedOperator\n"); 880*7a982d89SJeremy L. Thompson ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 881*7a982d89SJeremy L. Thompson } 882*7a982d89SJeremy L. Thompson 883*7a982d89SJeremy L. Thompson return 0; 884*7a982d89SJeremy L. Thompson } 8853bd813ffSjeremylt 8863bd813ffSjeremylt /** 8873bd813ffSjeremylt @brief Apply CeedOperator to a vector 888d7b241e6Sjeremylt 889d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 890d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 891d7b241e6Sjeremylt CeedOperatorSetField(). 892d7b241e6Sjeremylt 893d7b241e6Sjeremylt @param op CeedOperator to apply 89434138859Sjeremylt @param[in] in CeedVector containing input state or CEED_VECTOR_NONE if 89534138859Sjeremylt there are no active inputs 896b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 89734138859Sjeremylt distinct from @a in) or CEED_VECTOR_NONE if there are no 89834138859Sjeremylt active outputs 899d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 900d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 901b11c1e72Sjeremylt 902b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 903dfdf5a53Sjeremylt 904*7a982d89SJeremy L. Thompson @ref User 905b11c1e72Sjeremylt **/ 906692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 907692c2638Sjeremylt CeedRequest *request) { 908d7b241e6Sjeremylt int ierr; 909d7b241e6Sjeremylt Ceed ceed = op->ceed; 910250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 911d7b241e6Sjeremylt 912250756a7Sjeremylt if (op->numelements) { 913250756a7Sjeremylt // Standard Operator 914cae8b89aSjeremylt if (op->Apply) { 915250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 916cae8b89aSjeremylt } else { 917cae8b89aSjeremylt // Zero all output vectors 918250756a7Sjeremylt CeedQFunction qf = op->qf; 919cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 920cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 921cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 922cae8b89aSjeremylt vec = out; 923cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 924cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 925cae8b89aSjeremylt } 926cae8b89aSjeremylt } 927250756a7Sjeremylt // Apply 928250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 929250756a7Sjeremylt } 930250756a7Sjeremylt } else if (op->composite) { 931250756a7Sjeremylt // Composite Operator 932250756a7Sjeremylt if (op->ApplyComposite) { 933250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 934250756a7Sjeremylt } else { 935250756a7Sjeremylt CeedInt numsub; 936250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 937250756a7Sjeremylt CeedOperator *suboperators; 938250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 939250756a7Sjeremylt 940250756a7Sjeremylt // Zero all output vectors 941250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 942cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 943cae8b89aSjeremylt } 944250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 945250756a7Sjeremylt for (CeedInt j=0; j<suboperators[i]->qf->numoutputfields; j++) { 946250756a7Sjeremylt CeedVector vec = suboperators[i]->outputfields[j]->vec; 947250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 948250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 949250756a7Sjeremylt } 950250756a7Sjeremylt } 951250756a7Sjeremylt } 952250756a7Sjeremylt // Apply 953250756a7Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 954250756a7Sjeremylt ierr = CeedOperatorApplyAdd(op->suboperators[i], in, out, request); 955cae8b89aSjeremylt CeedChk(ierr); 956cae8b89aSjeremylt } 957cae8b89aSjeremylt } 958250756a7Sjeremylt } 959250756a7Sjeremylt 960cae8b89aSjeremylt return 0; 961cae8b89aSjeremylt } 962cae8b89aSjeremylt 963cae8b89aSjeremylt /** 964cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 965cae8b89aSjeremylt 966cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 967cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 968cae8b89aSjeremylt CeedOperatorSetField(). 969cae8b89aSjeremylt 970cae8b89aSjeremylt @param op CeedOperator to apply 971cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 972cae8b89aSjeremylt active inputs 973cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 974cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 975cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 976cae8b89aSjeremylt CEED_REQUEST_IMMEDIATE 977cae8b89aSjeremylt 978cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 979cae8b89aSjeremylt 980*7a982d89SJeremy L. Thompson @ref User 981cae8b89aSjeremylt **/ 982cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 983cae8b89aSjeremylt CeedRequest *request) { 984cae8b89aSjeremylt int ierr; 985cae8b89aSjeremylt Ceed ceed = op->ceed; 986250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 987cae8b89aSjeremylt 988250756a7Sjeremylt if (op->numelements) { 989250756a7Sjeremylt // Standard Operator 990250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 991250756a7Sjeremylt } else if (op->composite) { 992250756a7Sjeremylt // Composite Operator 993250756a7Sjeremylt if (op->ApplyAddComposite) { 994250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 995cae8b89aSjeremylt } else { 996250756a7Sjeremylt CeedInt numsub; 997250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 998250756a7Sjeremylt CeedOperator *suboperators; 999250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 1000250756a7Sjeremylt 1001250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 1002250756a7Sjeremylt ierr = CeedOperatorApplyAdd(suboperators[i], in, out, request); 1003cae8b89aSjeremylt CeedChk(ierr); 10041d7d2407SJeremy L Thompson } 1005250756a7Sjeremylt } 1006250756a7Sjeremylt } 1007250756a7Sjeremylt 1008d7b241e6Sjeremylt return 0; 1009d7b241e6Sjeremylt } 1010d7b241e6Sjeremylt 1011d7b241e6Sjeremylt /** 1012b11c1e72Sjeremylt @brief Destroy a CeedOperator 1013d7b241e6Sjeremylt 1014d7b241e6Sjeremylt @param op CeedOperator to destroy 1015b11c1e72Sjeremylt 1016b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1017dfdf5a53Sjeremylt 1018*7a982d89SJeremy L. Thompson @ref User 1019b11c1e72Sjeremylt **/ 1020d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1021d7b241e6Sjeremylt int ierr; 1022d7b241e6Sjeremylt 1023d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 1024d7b241e6Sjeremylt if ((*op)->Destroy) { 1025d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1026d7b241e6Sjeremylt } 1027fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1028fe2413ffSjeremylt // Free fields 10291d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 103052d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 103115910d16Sjeremylt if ((*op)->inputfields[i]->Erestrict != CEED_ELEMRESTRICTION_NONE) { 103271352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 103371352a93Sjeremylt CeedChk(ierr); 103415910d16Sjeremylt } 103571352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 103671352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 103771352a93Sjeremylt } 103871352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 103971352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 104071352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 104171352a93Sjeremylt } 1042fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1043fe2413ffSjeremylt } 10441d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1045d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 104671352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 104771352a93Sjeremylt CeedChk(ierr); 104871352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 104971352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 105071352a93Sjeremylt } 105171352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 105271352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 105371352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 105471352a93Sjeremylt } 1055fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1056fe2413ffSjeremylt } 105752d6035fSJeremy L Thompson // Destroy suboperators 10581d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 105952d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 106052d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 106152d6035fSJeremy L Thompson } 1062d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1063d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1064d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1065fe2413ffSjeremylt 10665107b09fSJeremy L Thompson // Destroy fallback 10675107b09fSJeremy L Thompson if ((*op)->opfallback) { 10685107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 10695107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 10705107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 10715107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 10725107b09fSJeremy L Thompson } 10735107b09fSJeremy L Thompson 1074fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1075fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 107652d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1077d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1078d7b241e6Sjeremylt return 0; 1079d7b241e6Sjeremylt } 1080d7b241e6Sjeremylt 1081d7b241e6Sjeremylt /// @} 1082