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> 20d7b241e6Sjeremylt 21dfdf5a53Sjeremylt /// @file 22dfdf5a53Sjeremylt /// Implementation of public CeedOperator interfaces 23dfdf5a53Sjeremylt /// 24dfdf5a53Sjeremylt /// @addtogroup CeedOperator 25dfdf5a53Sjeremylt /// @{ 26d7b241e6Sjeremylt 27d7b241e6Sjeremylt /** 28b11c1e72Sjeremylt @brief Create an operator from element restriction, basis, and QFunction 29d7b241e6Sjeremylt 30b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 31d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 32d7b241e6Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or NULL) 33d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 34d7b241e6Sjeremylt of @a qf (or NULL) 35b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 36b11c1e72Sjeremylt CeedOperator will be stored 37b11c1e72Sjeremylt 38b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 39dfdf5a53Sjeremylt 40dfdf5a53Sjeremylt @ref Basic 41d7b241e6Sjeremylt */ 42d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 43d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 44d7b241e6Sjeremylt int ierr; 45d7b241e6Sjeremylt 465fe0d4faSjeremylt if (!ceed->OperatorCreate) { 475fe0d4faSjeremylt Ceed delegate; 485fe0d4faSjeremylt ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr); 495fe0d4faSjeremylt 505fe0d4faSjeremylt if (!delegate) 515fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 525fe0d4faSjeremylt 535fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 545fe0d4faSjeremylt return 0; 555fe0d4faSjeremylt } 565fe0d4faSjeremylt 57d7b241e6Sjeremylt ierr = CeedCalloc(1,op); CeedChk(ierr); 58d7b241e6Sjeremylt (*op)->ceed = ceed; 59d7b241e6Sjeremylt ceed->refcount++; 60d7b241e6Sjeremylt (*op)->refcount = 1; 61d7b241e6Sjeremylt (*op)->qf = qf; 62d7b241e6Sjeremylt qf->refcount++; 63d7b241e6Sjeremylt (*op)->dqf = dqf; 64d7b241e6Sjeremylt if (dqf) dqf->refcount++; 65d7b241e6Sjeremylt (*op)->dqfT = dqfT; 66d7b241e6Sjeremylt if (dqfT) dqfT->refcount++; 67d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 68d7b241e6Sjeremylt return 0; 69d7b241e6Sjeremylt } 70d7b241e6Sjeremylt 71d7b241e6Sjeremylt /** 72b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 73d7b241e6Sjeremylt 74d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 75d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 76d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 77d7b241e6Sjeremylt 78d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 79d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 80d7b241e6Sjeremylt input and at most one active output. 81d7b241e6Sjeremylt 82b11c1e72Sjeremylt @param op Ceedoperator on which to provide the field 83b11c1e72Sjeremylt @param fieldname Name of the field (to be matched with the name used by CeedQFunction) 84b11c1e72Sjeremylt @param r CeedElemRestriction 85*b0e29e78Sjeremylt @param lmode CeedTransposeMode which specifies the ordering of the 86*b0e29e78Sjeremylt components of the l-vector used by this CeedOperatorField, 87*b0e29e78Sjeremylt CEED_NOTRANSPOSE indicates the component is the 88*b0e29e78Sjeremylt outermost index and CEED_TRANSPOSE indicates the component 89*b0e29e78Sjeremylt is the innermost index in ordering of the l-vector 90783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 91b11c1e72Sjeremylt if collocated with quadrature points 92b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 93b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 94b11c1e72Sjeremylt CEED_EVAL_WEIGHT in the qfunction 95b11c1e72Sjeremylt 96b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 97dfdf5a53Sjeremylt 98dfdf5a53Sjeremylt @ref Basic 99b11c1e72Sjeremylt **/ 100d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 1014dccadb6Sjeremylt CeedElemRestriction r, CeedTransposeMode lmode, 1024dccadb6Sjeremylt CeedBasis b, CeedVector v) { 103d7b241e6Sjeremylt int ierr; 104d7b241e6Sjeremylt CeedInt numelements; 105d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 106d7b241e6Sjeremylt if (op->numelements && op->numelements != numelements) 107d7b241e6Sjeremylt return CeedError(op->ceed, 1, 108d7b241e6Sjeremylt "ElemRestriction with %d elements incompatible with prior %d elements", 109d7b241e6Sjeremylt numelements, op->numelements); 110d7b241e6Sjeremylt op->numelements = numelements; 111d7b241e6Sjeremylt 112783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 113d7b241e6Sjeremylt CeedInt numqpoints; 114d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 115d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 116d7b241e6Sjeremylt return CeedError(op->ceed, 1, 117d7b241e6Sjeremylt "Basis with %d quadrature points incompatible with prior %d points", 118d7b241e6Sjeremylt numqpoints, op->numqpoints); 119d7b241e6Sjeremylt op->numqpoints = numqpoints; 120d7b241e6Sjeremylt } 121d1bcdac9Sjeremylt CeedOperatorField *ofield; 122d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 123d7b241e6Sjeremylt if (!strcmp(fieldname, op->qf->inputfields[i].fieldname)) { 124d7b241e6Sjeremylt ofield = &op->inputfields[i]; 125d7b241e6Sjeremylt goto found; 126d7b241e6Sjeremylt } 127d7b241e6Sjeremylt } 128d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 129d7b241e6Sjeremylt if (!strcmp(fieldname, op->qf->outputfields[i].fieldname)) { 130d7b241e6Sjeremylt ofield = &op->outputfields[i]; 131d7b241e6Sjeremylt goto found; 132d7b241e6Sjeremylt } 133d7b241e6Sjeremylt } 134d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 135d7b241e6Sjeremylt fieldname); 136d7b241e6Sjeremylt found: 137d7b241e6Sjeremylt ofield->Erestrict = r; 1384dccadb6Sjeremylt ofield->lmode = lmode; 139d7b241e6Sjeremylt ofield->basis = b; 140d7b241e6Sjeremylt ofield->vec = v; 141d7b241e6Sjeremylt op->nfields += 1; 142d7b241e6Sjeremylt return 0; 143d7b241e6Sjeremylt } 144d7b241e6Sjeremylt 145d7b241e6Sjeremylt /** 146b11c1e72Sjeremylt @brief Apply CeedOperator to a vector 147d7b241e6Sjeremylt 148d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 149d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 150d7b241e6Sjeremylt CeedOperatorSetField(). 151d7b241e6Sjeremylt 152d7b241e6Sjeremylt @param op CeedOperator to apply 153b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 154b11c1e72Sjeremylt active inputs 155b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 156d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 157d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 158d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 159b11c1e72Sjeremylt 160b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 161dfdf5a53Sjeremylt 162dfdf5a53Sjeremylt @ref Basic 163b11c1e72Sjeremylt **/ 164d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, 165d7b241e6Sjeremylt CeedVector out, CeedRequest *request) { 166d7b241e6Sjeremylt int ierr; 167d7b241e6Sjeremylt Ceed ceed = op->ceed; 168d7b241e6Sjeremylt CeedQFunction qf = op->qf; 169d7b241e6Sjeremylt 170d7b241e6Sjeremylt if (op->nfields == 0) return CeedError(ceed, 1, "No operator fields set"); 171d7b241e6Sjeremylt if (op->nfields < qf->numinputfields + qf->numoutputfields) return CeedError( 172d7b241e6Sjeremylt ceed, 1, "Not all operator fields set"); 173d7b241e6Sjeremylt if (op->numelements == 0) return CeedError(ceed, 1, 174d7b241e6Sjeremylt "At least one restriction required"); 175d7b241e6Sjeremylt if (op->numqpoints == 0) return CeedError(ceed, 1, 176783c99b3SValeria Barra "At least one non-collocated basis required"); 177d7b241e6Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 178d7b241e6Sjeremylt return 0; 179d7b241e6Sjeremylt } 180d7b241e6Sjeremylt 181d7b241e6Sjeremylt /** 1824ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 1834ce2993fSjeremylt 1844ce2993fSjeremylt @param op CeedOperator 1854ce2993fSjeremylt @param[out] ceed Variable to store Ceed 1864ce2993fSjeremylt 1874ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 1884ce2993fSjeremylt 18923617272Sjeremylt @ref Advanced 1904ce2993fSjeremylt **/ 1914ce2993fSjeremylt 1924ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 1934ce2993fSjeremylt *ceed = op->ceed; 1944ce2993fSjeremylt return 0; 1954ce2993fSjeremylt } 1964ce2993fSjeremylt 1974ce2993fSjeremylt /** 1984ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 1994ce2993fSjeremylt 2004ce2993fSjeremylt @param op CeedOperator 2014ce2993fSjeremylt @param[out] numelem Variable to store number of elements 2024ce2993fSjeremylt 2034ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 2044ce2993fSjeremylt 20523617272Sjeremylt @ref Advanced 2064ce2993fSjeremylt **/ 2074ce2993fSjeremylt 2084ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 2094ce2993fSjeremylt *numelem = op->numelements; 2104ce2993fSjeremylt return 0; 2114ce2993fSjeremylt } 2124ce2993fSjeremylt 2134ce2993fSjeremylt /** 2144ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 2154ce2993fSjeremylt 2164ce2993fSjeremylt @param op CeedOperator 2174ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 2184ce2993fSjeremylt 2194ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 2204ce2993fSjeremylt 22123617272Sjeremylt @ref Advanced 2224ce2993fSjeremylt **/ 2234ce2993fSjeremylt 2244ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 2254ce2993fSjeremylt *numqpts = op->numqpoints; 2264ce2993fSjeremylt return 0; 2274ce2993fSjeremylt } 2284ce2993fSjeremylt 2294ce2993fSjeremylt /** 2304ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 2314ce2993fSjeremylt 2324ce2993fSjeremylt @param op CeedOperator 2334ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 2344ce2993fSjeremylt 2354ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 2364ce2993fSjeremylt 23723617272Sjeremylt @ref Advanced 2384ce2993fSjeremylt **/ 2394ce2993fSjeremylt 2404ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 2414ce2993fSjeremylt *numargs = op->nfields; 2424ce2993fSjeremylt return 0; 2434ce2993fSjeremylt } 2444ce2993fSjeremylt 2454ce2993fSjeremylt /** 2464ce2993fSjeremylt @brief Get the setup status of a CeedOperator 2474ce2993fSjeremylt 2484ce2993fSjeremylt @param op CeedOperator 2494ce2993fSjeremylt @param[out] numelem Variable to store setup status 2504ce2993fSjeremylt 2514ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 2524ce2993fSjeremylt 25323617272Sjeremylt @ref Advanced 2544ce2993fSjeremylt **/ 2554ce2993fSjeremylt 2564ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 2574ce2993fSjeremylt *setupdone = op->setupdone; 2584ce2993fSjeremylt return 0; 2594ce2993fSjeremylt } 2604ce2993fSjeremylt 2614ce2993fSjeremylt /** 2624ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 2634ce2993fSjeremylt 2644ce2993fSjeremylt @param op CeedOperator 2654ce2993fSjeremylt @param[out] qf Variable to store qfunction 2664ce2993fSjeremylt 2674ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 2684ce2993fSjeremylt 26923617272Sjeremylt @ref Advanced 2704ce2993fSjeremylt **/ 2714ce2993fSjeremylt 2724ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 2734ce2993fSjeremylt *qf = op->qf; 2744ce2993fSjeremylt return 0; 2754ce2993fSjeremylt } 2764ce2993fSjeremylt 2774ce2993fSjeremylt /** 2784ce2993fSjeremylt @brief Get the backend data of a CeedOperator 2794ce2993fSjeremylt 2804ce2993fSjeremylt @param op CeedOperator 2814ce2993fSjeremylt @param[out] data Variable to store data 2824ce2993fSjeremylt 2834ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 2844ce2993fSjeremylt 28523617272Sjeremylt @ref Advanced 2864ce2993fSjeremylt **/ 2874ce2993fSjeremylt 2884ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) { 2894ce2993fSjeremylt *data = op->data; 2904ce2993fSjeremylt return 0; 2914ce2993fSjeremylt } 2924ce2993fSjeremylt 2934ce2993fSjeremylt /** 2944ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 2954ce2993fSjeremylt 2964ce2993fSjeremylt @param op CeedOperator 2974ce2993fSjeremylt 2984ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 2994ce2993fSjeremylt 30023617272Sjeremylt @ref Advanced 3014ce2993fSjeremylt **/ 3024ce2993fSjeremylt 3034ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 3044ce2993fSjeremylt op->setupdone = 1; 3054ce2993fSjeremylt return 0; 3064ce2993fSjeremylt } 3074ce2993fSjeremylt 3084ce2993fSjeremylt /** 309d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 310d1bcdac9Sjeremylt 311d1bcdac9Sjeremylt @param op CeedOperator 312d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 313d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 314d1bcdac9Sjeremylt 315d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 316d1bcdac9Sjeremylt 317d1bcdac9Sjeremylt @ref Advanced 318d1bcdac9Sjeremylt **/ 319d1bcdac9Sjeremylt 320d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op, 321d1bcdac9Sjeremylt CeedOperatorField* *inputfields, 322d1bcdac9Sjeremylt CeedOperatorField* *outputfields) { 323d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 324d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 325d1bcdac9Sjeremylt return 0; 326d1bcdac9Sjeremylt } 327d1bcdac9Sjeremylt 328d1bcdac9Sjeremylt /** 3294dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 3304dccadb6Sjeremylt 3314dccadb6Sjeremylt @param opfield CeedOperatorField 3324dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 3334dccadb6Sjeremylt 3344dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 3354dccadb6Sjeremylt 3364dccadb6Sjeremylt @ref Advanced 3374dccadb6Sjeremylt **/ 3384dccadb6Sjeremylt 3394dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 3404dccadb6Sjeremylt CeedTransposeMode *lmode) { 3414dccadb6Sjeremylt *lmode = (&opfield)->lmode; 3424dccadb6Sjeremylt return 0; 3434dccadb6Sjeremylt }/** 344d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 345d1bcdac9Sjeremylt 346d1bcdac9Sjeremylt @param opfield CeedOperatorField 347d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 348d1bcdac9Sjeremylt 349d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 350d1bcdac9Sjeremylt 351d1bcdac9Sjeremylt @ref Advanced 352d1bcdac9Sjeremylt **/ 353d1bcdac9Sjeremylt 354d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 355d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 356d1bcdac9Sjeremylt *rstr = (&opfield)->Erestrict; 357d1bcdac9Sjeremylt return 0; 358d1bcdac9Sjeremylt } 359d1bcdac9Sjeremylt 360d1bcdac9Sjeremylt /** 361d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 362d1bcdac9Sjeremylt 363d1bcdac9Sjeremylt @param opfield CeedOperatorField 364d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 365d1bcdac9Sjeremylt 366d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 367d1bcdac9Sjeremylt 368d1bcdac9Sjeremylt @ref Advanced 369d1bcdac9Sjeremylt **/ 370d1bcdac9Sjeremylt 371d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, 372d1bcdac9Sjeremylt CeedBasis *basis) { 373d1bcdac9Sjeremylt *basis = (&opfield)->basis; 374d1bcdac9Sjeremylt return 0; 375d1bcdac9Sjeremylt } 376d1bcdac9Sjeremylt 377d1bcdac9Sjeremylt /** 378d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 379d1bcdac9Sjeremylt 380d1bcdac9Sjeremylt @param opfield CeedOperatorField 381d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 382d1bcdac9Sjeremylt 383d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 384d1bcdac9Sjeremylt 385d1bcdac9Sjeremylt @ref Advanced 386d1bcdac9Sjeremylt **/ 387d1bcdac9Sjeremylt 388d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, 389d1bcdac9Sjeremylt CeedVector *vec) { 390d1bcdac9Sjeremylt *vec = (&opfield)->vec; 391d1bcdac9Sjeremylt return 0; 392d1bcdac9Sjeremylt } 393d1bcdac9Sjeremylt 394d1bcdac9Sjeremylt /** 395b11c1e72Sjeremylt @brief Destroy a CeedOperator 396d7b241e6Sjeremylt 397d7b241e6Sjeremylt @param op CeedOperator to destroy 398b11c1e72Sjeremylt 399b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 400dfdf5a53Sjeremylt 401dfdf5a53Sjeremylt @ref Basic 402b11c1e72Sjeremylt **/ 403d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 404d7b241e6Sjeremylt int ierr; 405d7b241e6Sjeremylt 406d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 407d7b241e6Sjeremylt if ((*op)->Destroy) { 408d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 409d7b241e6Sjeremylt } 410d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 411d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 412d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 413d7b241e6Sjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 414d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 415d7b241e6Sjeremylt return 0; 416d7b241e6Sjeremylt } 417d7b241e6Sjeremylt 418d7b241e6Sjeremylt /// @} 419