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 /** 280219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 290219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 300219ea01SJeremy L Thompson \ref CeedOperatorSetField. 31d7b241e6Sjeremylt 32b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 33d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 34d7b241e6Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or NULL) 35d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 36d7b241e6Sjeremylt of @a qf (or NULL) 37b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 38b11c1e72Sjeremylt CeedOperator will be stored 39b11c1e72Sjeremylt 40b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 41dfdf5a53Sjeremylt 42dfdf5a53Sjeremylt @ref Basic 43d7b241e6Sjeremylt */ 44d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 45d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 46d7b241e6Sjeremylt int ierr; 47d7b241e6Sjeremylt 485fe0d4faSjeremylt if (!ceed->OperatorCreate) { 495fe0d4faSjeremylt Ceed delegate; 50aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 515fe0d4faSjeremylt 525fe0d4faSjeremylt if (!delegate) 53c042f62fSJeremy L Thompson // LCOV_EXCL_START 545fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 55c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 565fe0d4faSjeremylt 575fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 585fe0d4faSjeremylt return 0; 595fe0d4faSjeremylt } 605fe0d4faSjeremylt 61d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 62d7b241e6Sjeremylt (*op)->ceed = ceed; 63d7b241e6Sjeremylt ceed->refcount++; 64d7b241e6Sjeremylt (*op)->refcount = 1; 65442e7f0bSjeremylt if (qf == CEED_QFUNCTION_NONE) 66442e7f0bSjeremylt // LCOV_EXCL_START 67442e7f0bSjeremylt return CeedError(ceed, 1, "Operator must have a valid QFunction."); 68442e7f0bSjeremylt // LCOV_EXCL_STOP 69d7b241e6Sjeremylt (*op)->qf = qf; 70d7b241e6Sjeremylt qf->refcount++; 71442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 72d7b241e6Sjeremylt (*op)->dqf = dqf; 73442e7f0bSjeremylt dqf->refcount++; 74442e7f0bSjeremylt } 75442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 76d7b241e6Sjeremylt (*op)->dqfT = dqfT; 77442e7f0bSjeremylt dqfT->refcount++; 78442e7f0bSjeremylt } 79fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 80fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 81d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 82d7b241e6Sjeremylt return 0; 83d7b241e6Sjeremylt } 84d7b241e6Sjeremylt 85d7b241e6Sjeremylt /** 8652d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 8752d6035fSJeremy L Thompson 8852d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 8952d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 9052d6035fSJeremy L Thompson Composite CeedOperator will be stored 9152d6035fSJeremy L Thompson 9252d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9352d6035fSJeremy L Thompson 9452d6035fSJeremy L Thompson @ref Basic 9552d6035fSJeremy L Thompson */ 9652d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 9752d6035fSJeremy L Thompson int ierr; 9852d6035fSJeremy L Thompson 9952d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 10052d6035fSJeremy L Thompson Ceed delegate; 101aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 10252d6035fSJeremy L Thompson 103*250756a7Sjeremylt if (delegate) { 10452d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 10552d6035fSJeremy L Thompson return 0; 10652d6035fSJeremy L Thompson } 107*250756a7Sjeremylt } 10852d6035fSJeremy L Thompson 10952d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 11052d6035fSJeremy L Thompson (*op)->ceed = ceed; 11152d6035fSJeremy L Thompson ceed->refcount++; 11252d6035fSJeremy L Thompson (*op)->composite = true; 11352d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 114*250756a7Sjeremylt 115*250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 11652d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 117*250756a7Sjeremylt } 11852d6035fSJeremy L Thompson return 0; 11952d6035fSJeremy L Thompson } 12052d6035fSJeremy L Thompson 12152d6035fSJeremy L Thompson /** 122b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 123d7b241e6Sjeremylt 124d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 125d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 126d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 127d7b241e6Sjeremylt 128d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 129d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 130d7b241e6Sjeremylt input and at most one active output. 131d7b241e6Sjeremylt 1328c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 1338795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 1348795c945Sjeremylt CeedQFunction) 135b11c1e72Sjeremylt @param r CeedElemRestriction 136b0e29e78Sjeremylt @param lmode CeedTransposeMode which specifies the ordering of the 137b0e29e78Sjeremylt components of the l-vector used by this CeedOperatorField, 138b0e29e78Sjeremylt CEED_NOTRANSPOSE indicates the component is the 139b0e29e78Sjeremylt outermost index and CEED_TRANSPOSE indicates the component 140b0e29e78Sjeremylt is the innermost index in ordering of the l-vector 141783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 142b11c1e72Sjeremylt if collocated with quadrature points 143b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 144b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 1458c91a0c9SJeremy L Thompson CEED_EVAL_WEIGHT in the QFunction 146b11c1e72Sjeremylt 147b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 148dfdf5a53Sjeremylt 149dfdf5a53Sjeremylt @ref Basic 150b11c1e72Sjeremylt **/ 151d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 1524dccadb6Sjeremylt CeedElemRestriction r, CeedTransposeMode lmode, 1534dccadb6Sjeremylt CeedBasis b, CeedVector v) { 154d7b241e6Sjeremylt int ierr; 15552d6035fSJeremy L Thompson if (op->composite) 156c042f62fSJeremy L Thompson // LCOV_EXCL_START 15752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 158c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1598b067b84SJed Brown if (!r) 160c042f62fSJeremy L Thompson // LCOV_EXCL_START 161c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 162c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 163c042f62fSJeremy L Thompson fieldname); 164c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1658b067b84SJed Brown if (!b) 166c042f62fSJeremy L Thompson // LCOV_EXCL_START 167c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 168c042f62fSJeremy L Thompson fieldname); 169c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1708b067b84SJed Brown if (!v) 171c042f62fSJeremy L Thompson // LCOV_EXCL_START 172c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 173c042f62fSJeremy L Thompson fieldname); 174c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 17552d6035fSJeremy L Thompson 176d7b241e6Sjeremylt CeedInt numelements; 177d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 1782cb0afc5Sjeremylt if (op->hasrestriction && op->numelements != numelements) 179c042f62fSJeremy L Thompson // LCOV_EXCL_START 180d7b241e6Sjeremylt return CeedError(op->ceed, 1, 1811d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 1821d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 183c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 184d7b241e6Sjeremylt op->numelements = numelements; 1852cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 186d7b241e6Sjeremylt 187783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 188d7b241e6Sjeremylt CeedInt numqpoints; 189d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 190d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 191c042f62fSJeremy L Thompson // LCOV_EXCL_START 1921d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1931d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1941d102b48SJeremy L Thompson op->numqpoints); 195c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 196d7b241e6Sjeremylt op->numqpoints = numqpoints; 197d7b241e6Sjeremylt } 198d1bcdac9Sjeremylt CeedOperatorField *ofield; 199d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 200fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 201d7b241e6Sjeremylt ofield = &op->inputfields[i]; 202d7b241e6Sjeremylt goto found; 203d7b241e6Sjeremylt } 204d7b241e6Sjeremylt } 205d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 206fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 207d7b241e6Sjeremylt ofield = &op->outputfields[i]; 208d7b241e6Sjeremylt goto found; 209d7b241e6Sjeremylt } 210d7b241e6Sjeremylt } 211c042f62fSJeremy L Thompson // LCOV_EXCL_START 212d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 213d7b241e6Sjeremylt fieldname); 214c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 215d7b241e6Sjeremylt found: 216fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 217fe2413ffSjeremylt (*ofield)->Erestrict = r; 21871352a93Sjeremylt r->refcount += 1; 219fe2413ffSjeremylt (*ofield)->lmode = lmode; 220fe2413ffSjeremylt (*ofield)->basis = b; 22171352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 22271352a93Sjeremylt b->refcount += 1; 223fe2413ffSjeremylt (*ofield)->vec = v; 22471352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 22571352a93Sjeremylt v->refcount += 1; 226d7b241e6Sjeremylt op->nfields += 1; 227d7b241e6Sjeremylt return 0; 228d7b241e6Sjeremylt } 229d7b241e6Sjeremylt 230d7b241e6Sjeremylt /** 23152d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 232288c0443SJeremy L Thompson 233288c0443SJeremy L Thompson @param[out] compositeop Address of the composite CeedOperator 234288c0443SJeremy L Thompson @param subop Address of the sub-operator CeedOperator 23552d6035fSJeremy L Thompson 23652d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23752d6035fSJeremy L Thompson 23852d6035fSJeremy L Thompson @ref Basic 23952d6035fSJeremy L Thompson */ 240692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 24152d6035fSJeremy L Thompson if (!compositeop->composite) 242c042f62fSJeremy L Thompson // LCOV_EXCL_START 2431d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2441d102b48SJeremy L Thompson "operator"); 245c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24652d6035fSJeremy L Thompson 24752d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 248c042f62fSJeremy L Thompson // LCOV_EXCL_START 2491d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 250c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 25152d6035fSJeremy L Thompson 25252d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 25352d6035fSJeremy L Thompson subop->refcount++; 25452d6035fSJeremy L Thompson compositeop->numsub++; 25552d6035fSJeremy L Thompson return 0; 25652d6035fSJeremy L Thompson } 25752d6035fSJeremy L Thompson 25852d6035fSJeremy L Thompson /** 2595107b09fSJeremy L Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 2605107b09fSJeremy L Thompson CeedOperator functionality 2615107b09fSJeremy L Thompson 2625107b09fSJeremy L Thompson @param op CeedOperator to create fallback for 2635107b09fSJeremy L Thompson 2645107b09fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2655107b09fSJeremy L Thompson 2665107b09fSJeremy L Thompson @ref Developer 2675107b09fSJeremy L Thompson **/ 2685107b09fSJeremy L Thompson int CeedOperatorCreateFallback(CeedOperator op) { 2695107b09fSJeremy L Thompson int ierr; 2705107b09fSJeremy L Thompson 2715107b09fSJeremy L Thompson // Fallback Ceed 2725107b09fSJeremy L Thompson const char *resource, *fallbackresource; 2735107b09fSJeremy L Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 2745107b09fSJeremy L Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 2755107b09fSJeremy L Thompson CeedChk(ierr); 2765107b09fSJeremy L Thompson if (!strcmp(resource, fallbackresource)) 2775107b09fSJeremy L Thompson // LCOV_EXCL_START 2785107b09fSJeremy L Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 2795107b09fSJeremy L Thompson "fallback to resource %s", resource, fallbackresource); 2805107b09fSJeremy L Thompson // LCOV_EXCL_STOP 2815107b09fSJeremy L Thompson 2825107b09fSJeremy L Thompson Ceed ceedref; 2835107b09fSJeremy L Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 2845107b09fSJeremy L Thompson ceedref->opfallbackparent = op->ceed; 2855107b09fSJeremy L Thompson op->ceed->opfallbackceed = ceedref; 2865107b09fSJeremy L Thompson 2875107b09fSJeremy L Thompson // Clone Op 2885107b09fSJeremy L Thompson CeedOperator opref; 2895107b09fSJeremy L Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 2905107b09fSJeremy L Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 2915107b09fSJeremy L Thompson opref->data = NULL; 2925107b09fSJeremy L Thompson opref->setupdone = 0; 2935107b09fSJeremy L Thompson opref->ceed = ceedref; 2945107b09fSJeremy L Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 2955107b09fSJeremy L Thompson op->opfallback = opref; 2965107b09fSJeremy L Thompson 2975107b09fSJeremy L Thompson // Clone QF 2985107b09fSJeremy L Thompson CeedQFunction qfref; 2995107b09fSJeremy L Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 3005107b09fSJeremy L Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 3015107b09fSJeremy L Thompson qfref->data = NULL; 3025107b09fSJeremy L Thompson qfref->ceed = ceedref; 3035107b09fSJeremy L Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 3045107b09fSJeremy L Thompson opref->qf = qfref; 3055107b09fSJeremy L Thompson op->qffallback = qfref; 3065107b09fSJeremy L Thompson 3075107b09fSJeremy L Thompson return 0; 3085107b09fSJeremy L Thompson } 3095107b09fSJeremy L Thompson 3105107b09fSJeremy L Thompson /** 311*250756a7Sjeremylt @brief Check if a CeedOperator is ready to be used. 312*250756a7Sjeremylt 313*250756a7Sjeremylt @param[in] ceed Ceed object for error handling 314*250756a7Sjeremylt @param[in] op CeedOperator to check 315*250756a7Sjeremylt 316*250756a7Sjeremylt @return An error code: 0 - success, otherwise - failure 317*250756a7Sjeremylt 318*250756a7Sjeremylt @ref Basic 319*250756a7Sjeremylt **/ 320*250756a7Sjeremylt static int CeedOperatorCheckReady(Ceed ceed, CeedOperator op) { 321*250756a7Sjeremylt CeedQFunction qf = op->qf; 322*250756a7Sjeremylt 323*250756a7Sjeremylt if (op->composite) { 324*250756a7Sjeremylt if (!op->numsub) 325*250756a7Sjeremylt // LCOV_EXCL_START 326*250756a7Sjeremylt return CeedError(ceed, 1, "No suboperators set"); 327*250756a7Sjeremylt // LCOV_EXCL_STOP 328*250756a7Sjeremylt } else { 329*250756a7Sjeremylt if (op->nfields == 0) 330*250756a7Sjeremylt // LCOV_EXCL_START 331*250756a7Sjeremylt return CeedError(ceed, 1, "No operator fields set"); 332*250756a7Sjeremylt // LCOV_EXCL_STOP 333*250756a7Sjeremylt if (op->nfields < qf->numinputfields + qf->numoutputfields) 334*250756a7Sjeremylt // LCOV_EXCL_START 335*250756a7Sjeremylt return CeedError(ceed, 1, "Not all operator fields set"); 336*250756a7Sjeremylt // LCOV_EXCL_STOP 337*250756a7Sjeremylt if (!op->hasrestriction) 338*250756a7Sjeremylt // LCOV_EXCL_START 339*250756a7Sjeremylt return CeedError(ceed, 1,"At least one restriction required"); 340*250756a7Sjeremylt // LCOV_EXCL_STOP 341*250756a7Sjeremylt if (op->numqpoints == 0) 342*250756a7Sjeremylt // LCOV_EXCL_START 343*250756a7Sjeremylt return CeedError(ceed, 1,"At least one non-collocated basis required"); 344*250756a7Sjeremylt // LCOV_EXCL_STOP 345*250756a7Sjeremylt } 346*250756a7Sjeremylt 347*250756a7Sjeremylt return 0; 348*250756a7Sjeremylt } 349*250756a7Sjeremylt 350*250756a7Sjeremylt /** 3511d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 3521d102b48SJeremy L Thompson 3531d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 3541d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 3551d102b48SJeremy L Thompson The vector 'assembled' is of shape 3561d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 3571d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 3581d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 3591d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 3601d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 3611d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 3621d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 3631d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 3641d102b48SJeremy L Thompson 3651d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 3661d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 3671d102b48SJeremy L Thompson quadrature points 3681d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 3691d102b48SJeremy L Thompson CeedQFunction 3701d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 3711d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 3721d102b48SJeremy L Thompson 3731d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3741d102b48SJeremy L Thompson 375b7ec98d8SJeremy L Thompson @ref Basic 3761d102b48SJeremy L Thompson **/ 3771d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 3787f823360Sjeremylt CeedElemRestriction *rstr, 3797f823360Sjeremylt CeedRequest *request) { 3801d102b48SJeremy L Thompson int ierr; 3811d102b48SJeremy L Thompson Ceed ceed = op->ceed; 382*250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 3831d102b48SJeremy L Thompson 3845107b09fSJeremy L Thompson if (op->AssembleLinearQFunction) { 3851d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3861d102b48SJeremy L Thompson CeedChk(ierr); 3875107b09fSJeremy L Thompson } else { 3885107b09fSJeremy L Thompson // Fallback to reference Ceed 3895107b09fSJeremy L Thompson if (!op->opfallback) { 3905107b09fSJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 3915107b09fSJeremy L Thompson } 3925107b09fSJeremy L Thompson // Assemble 3935107b09fSJeremy L Thompson ierr = op->opfallback->AssembleLinearQFunction(op->opfallback, assembled, 3945107b09fSJeremy L Thompson rstr, request); CeedChk(ierr); 3955107b09fSJeremy L Thompson } 396*250756a7Sjeremylt 3971d102b48SJeremy L Thompson return 0; 3981d102b48SJeremy L Thompson } 3991d102b48SJeremy L Thompson 4001d102b48SJeremy L Thompson /** 401b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 402b7ec98d8SJeremy L Thompson 403b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 404b7ec98d8SJeremy L Thompson 405b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 406b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 407b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 408b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 409b7ec98d8SJeremy L Thompson 410b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 411b7ec98d8SJeremy L Thompson 412b7ec98d8SJeremy L Thompson @ref Basic 413b7ec98d8SJeremy L Thompson **/ 4147f823360Sjeremylt int CeedOperatorAssembleLinearDiagonal(CeedOperator op, CeedVector *assembled, 4157f823360Sjeremylt CeedRequest *request) { 416b7ec98d8SJeremy L Thompson int ierr; 417b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 418*250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 419b7ec98d8SJeremy L Thompson 420b7ec98d8SJeremy L Thompson // Use backend version, if available 421b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 422b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 423b7ec98d8SJeremy L Thompson return 0; 424b7ec98d8SJeremy L Thompson } 425b7ec98d8SJeremy L Thompson 426b7ec98d8SJeremy L Thompson // Assemble QFunction 427*250756a7Sjeremylt CeedQFunction qf = op->qf; 428b7ec98d8SJeremy L Thompson CeedVector assembledqf; 429b7ec98d8SJeremy L Thompson CeedElemRestriction rstr; 430b7ec98d8SJeremy L Thompson ierr = CeedOperatorAssembleLinearQFunction(op, &assembledqf, &rstr, request); 431b7ec98d8SJeremy L Thompson CeedChk(ierr); 432b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&rstr); CeedChk(ierr); 433b7ec98d8SJeremy L Thompson 434b7ec98d8SJeremy L Thompson // Determine active input basis 435112e3f70Sjeremylt CeedInt numemodein = 0, ncomp, dim = 1; 436b7ec98d8SJeremy L Thompson CeedEvalMode *emodein = NULL; 437112e3f70Sjeremylt CeedBasis basisin = NULL; 438112e3f70Sjeremylt CeedElemRestriction rstrin = NULL; 439b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numinputfields; i++) 440b7ec98d8SJeremy L Thompson if (op->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 441b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->inputfields[i], &basisin); 442b7ec98d8SJeremy L Thompson CeedChk(ierr); 443b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisin, &ncomp); CeedChk(ierr); 444b7ec98d8SJeremy L Thompson ierr = CeedBasisGetDimension(basisin, &dim); CeedChk(ierr); 445b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->inputfields[i], &rstrin); 446b7ec98d8SJeremy L Thompson CeedChk(ierr); 447b7ec98d8SJeremy L Thompson CeedEvalMode emode; 448b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->inputfields[i], &emode); 449b7ec98d8SJeremy L Thompson CeedChk(ierr); 450b7ec98d8SJeremy L Thompson switch (emode) { 451b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 452b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 453b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + 1, &emodein); CeedChk(ierr); 454b7ec98d8SJeremy L Thompson emodein[numemodein] = emode; 455b7ec98d8SJeremy L Thompson numemodein += 1; 456b7ec98d8SJeremy L Thompson break; 457b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 458b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + dim, &emodein); CeedChk(ierr); 459b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 460b7ec98d8SJeremy L Thompson emodein[numemodein+d] = emode; 461b7ec98d8SJeremy L Thompson numemodein += dim; 462b7ec98d8SJeremy L Thompson break; 463b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 464b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 465b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 466b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 467b7ec98d8SJeremy L Thompson } 468b7ec98d8SJeremy L Thompson } 469b7ec98d8SJeremy L Thompson 470b7ec98d8SJeremy L Thompson // Determine active output basis 471b7ec98d8SJeremy L Thompson CeedInt numemodeout = 0; 472b7ec98d8SJeremy L Thompson CeedEvalMode *emodeout = NULL; 473112e3f70Sjeremylt CeedBasis basisout = NULL; 474112e3f70Sjeremylt CeedElemRestriction rstrout = NULL; 475112e3f70Sjeremylt CeedTransposeMode lmodeout = CEED_NOTRANSPOSE; 476b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numoutputfields; i++) 477b7ec98d8SJeremy L Thompson if (op->outputfields[i]->vec == CEED_VECTOR_ACTIVE) { 478b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->outputfields[i], &basisout); 479b7ec98d8SJeremy L Thompson CeedChk(ierr); 480b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->outputfields[i], &rstrout); 481b7ec98d8SJeremy L Thompson CeedChk(ierr); 482b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(op->outputfields[i], &lmodeout); 483b7ec98d8SJeremy L Thompson CeedChk(ierr); 484b7ec98d8SJeremy L Thompson CeedEvalMode emode; 485b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->outputfields[i], &emode); 486b7ec98d8SJeremy L Thompson CeedChk(ierr); 487b7ec98d8SJeremy L Thompson switch (emode) { 488b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 489b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 490b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + 1, &emodeout); CeedChk(ierr); 491b7ec98d8SJeremy L Thompson emodeout[numemodeout] = emode; 492b7ec98d8SJeremy L Thompson numemodeout += 1; 493b7ec98d8SJeremy L Thompson break; 494b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 495b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + dim, &emodeout); CeedChk(ierr); 496b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 497b7ec98d8SJeremy L Thompson emodeout[numemodeout+d] = emode; 498b7ec98d8SJeremy L Thompson numemodeout += dim; 499b7ec98d8SJeremy L Thompson break; 500b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 501b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 502b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 503b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 504b7ec98d8SJeremy L Thompson } 505b7ec98d8SJeremy L Thompson } 506b7ec98d8SJeremy L Thompson 507b7ec98d8SJeremy L Thompson // Create diagonal vector 508b7ec98d8SJeremy L Thompson CeedVector elemdiag; 509b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionCreateVector(rstrin, assembled, &elemdiag); 510b7ec98d8SJeremy L Thompson CeedChk(ierr); 511b7ec98d8SJeremy L Thompson 512b7ec98d8SJeremy L Thompson // Assemble element operator diagonals 513b7ec98d8SJeremy L Thompson CeedScalar *elemdiagarray, *assembledqfarray; 514b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(elemdiag, 0.0); CeedChk(ierr); 515b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(elemdiag, CEED_MEM_HOST, &elemdiagarray); 516b7ec98d8SJeremy L Thompson CeedChk(ierr); 517b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(assembledqf, CEED_MEM_HOST, &assembledqfarray); 518b7ec98d8SJeremy L Thompson CeedChk(ierr); 519b7ec98d8SJeremy L Thompson CeedInt nelem, nnodes, nqpts; 520b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionGetNumElements(rstrin, &nelem); CeedChk(ierr); 521b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisin, &nnodes); CeedChk(ierr); 522b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisin, &nqpts); CeedChk(ierr); 523b7ec98d8SJeremy L Thompson // Compute the diagonal of B^T D B 524b7ec98d8SJeremy L Thompson // Each node, qpt pair 525b7ec98d8SJeremy L Thompson for (CeedInt n=0; n<nnodes; n++) 526b7ec98d8SJeremy L Thompson for (CeedInt q=0; q<nqpts; q++) { 527b7ec98d8SJeremy L Thompson CeedInt dout = -1; 528b7ec98d8SJeremy L Thompson // Each basis eval mode pair 529b7ec98d8SJeremy L Thompson for (CeedInt eout=0; eout<numemodeout; eout++) { 530b7ec98d8SJeremy L Thompson CeedScalar bt = 1.0; 531b7ec98d8SJeremy L Thompson if (emodeout[eout] == CEED_EVAL_GRAD) 532b7ec98d8SJeremy L Thompson dout += 1; 533b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisout, emodeout[eout], q, n, dout, &bt); 534b7ec98d8SJeremy L Thompson CeedChk(ierr); 535b7ec98d8SJeremy L Thompson CeedInt din = -1; 536b7ec98d8SJeremy L Thompson for (CeedInt ein=0; ein<numemodein; ein++) { 537b7ec98d8SJeremy L Thompson CeedScalar b = 0.0; 538b7ec98d8SJeremy L Thompson if (emodein[ein] == CEED_EVAL_GRAD) 539b7ec98d8SJeremy L Thompson din += 1; 540b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisin, emodein[ein], q, n, din, &b); 541b7ec98d8SJeremy L Thompson CeedChk(ierr); 542b7ec98d8SJeremy L Thompson // Each element and component 543b7ec98d8SJeremy L Thompson for (CeedInt e=0; e<nelem; e++) 544b7ec98d8SJeremy L Thompson for (CeedInt cout=0; cout<ncomp; cout++) { 545b7ec98d8SJeremy L Thompson CeedScalar db = 0.0; 546b7ec98d8SJeremy L Thompson for (CeedInt cin=0; cin<ncomp; cin++) 547b7ec98d8SJeremy L Thompson db += assembledqfarray[((((e*numemodein+ein)*ncomp+cin)* 548b7ec98d8SJeremy L Thompson numemodeout+eout)*ncomp+cout)*nqpts+q]*b; 549b7ec98d8SJeremy L Thompson elemdiagarray[(e*ncomp+cout)*nnodes+n] += bt * db; 550b7ec98d8SJeremy L Thompson } 551b7ec98d8SJeremy L Thompson } 552b7ec98d8SJeremy L Thompson } 553b7ec98d8SJeremy L Thompson } 554b7ec98d8SJeremy L Thompson 555b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(elemdiag, &elemdiagarray); CeedChk(ierr); 556b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(assembledqf, &assembledqfarray); CeedChk(ierr); 557b7ec98d8SJeremy L Thompson 558b7ec98d8SJeremy L Thompson // Assemble local operator diagonal 559b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 560b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrout, CEED_TRANSPOSE, lmodeout, elemdiag, 561b7ec98d8SJeremy L Thompson *assembled, request); CeedChk(ierr); 562b7ec98d8SJeremy L Thompson 563b7ec98d8SJeremy L Thompson // Cleanup 564b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&assembledqf); CeedChk(ierr); 565b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&elemdiag); CeedChk(ierr); 566b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodein); CeedChk(ierr); 567b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodeout); CeedChk(ierr); 568b7ec98d8SJeremy L Thompson 569b7ec98d8SJeremy L Thompson return 0; 570b7ec98d8SJeremy L Thompson } 571b7ec98d8SJeremy L Thompson 572b7ec98d8SJeremy L Thompson /** 573cae8b89aSjeremylt @brief Apply CeedOperator to a vector and overwrite output vector 574d7b241e6Sjeremylt 575d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 576d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 577d7b241e6Sjeremylt CeedOperatorSetField(). 578d7b241e6Sjeremylt 579d7b241e6Sjeremylt @param op CeedOperator to apply 580b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 581b11c1e72Sjeremylt active inputs 582b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 583d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 584d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 585d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 586b11c1e72Sjeremylt 587b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 588dfdf5a53Sjeremylt 589dfdf5a53Sjeremylt @ref Basic 590b11c1e72Sjeremylt **/ 591692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 592692c2638Sjeremylt CeedRequest *request) { 593d7b241e6Sjeremylt int ierr; 594d7b241e6Sjeremylt Ceed ceed = op->ceed; 595*250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 596d7b241e6Sjeremylt 597*250756a7Sjeremylt if (op->numelements) { 598*250756a7Sjeremylt // Standard Operator 599cae8b89aSjeremylt if (op->Apply) { 600*250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 601cae8b89aSjeremylt } else { 602cae8b89aSjeremylt // Zero all output vectors 603*250756a7Sjeremylt CeedQFunction qf = op->qf; 604cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 605cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 606cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 607cae8b89aSjeremylt vec = out; 608cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 609cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 610cae8b89aSjeremylt } 611cae8b89aSjeremylt } 612*250756a7Sjeremylt // Apply 613*250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 614*250756a7Sjeremylt } 615*250756a7Sjeremylt } else if (op->composite) { 616*250756a7Sjeremylt // Composite Operator 617*250756a7Sjeremylt if (op->ApplyComposite) { 618*250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 619*250756a7Sjeremylt } else { 620*250756a7Sjeremylt CeedInt numsub; 621*250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 622*250756a7Sjeremylt CeedOperator *suboperators; 623*250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 624*250756a7Sjeremylt 625*250756a7Sjeremylt // Zero all output vectors 626*250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 627cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 628cae8b89aSjeremylt } 629*250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 630*250756a7Sjeremylt for (CeedInt j=0; j<suboperators[i]->qf->numoutputfields; j++) { 631*250756a7Sjeremylt CeedVector vec = suboperators[i]->outputfields[j]->vec; 632*250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 633*250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 634*250756a7Sjeremylt } 635*250756a7Sjeremylt } 636*250756a7Sjeremylt } 637*250756a7Sjeremylt // Apply 638*250756a7Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 639*250756a7Sjeremylt ierr = CeedOperatorApplyAdd(op->suboperators[i], in, out, request); 640cae8b89aSjeremylt CeedChk(ierr); 641cae8b89aSjeremylt } 642cae8b89aSjeremylt } 643*250756a7Sjeremylt } 644*250756a7Sjeremylt 645cae8b89aSjeremylt return 0; 646cae8b89aSjeremylt } 647cae8b89aSjeremylt 648cae8b89aSjeremylt /** 649cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 650cae8b89aSjeremylt 651cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 652cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 653cae8b89aSjeremylt CeedOperatorSetField(). 654cae8b89aSjeremylt 655cae8b89aSjeremylt @param op CeedOperator to apply 656cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 657cae8b89aSjeremylt active inputs 658cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 659cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 660cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 661cae8b89aSjeremylt CEED_REQUEST_IMMEDIATE 662cae8b89aSjeremylt 663cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 664cae8b89aSjeremylt 665cae8b89aSjeremylt @ref Basic 666cae8b89aSjeremylt **/ 667cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 668cae8b89aSjeremylt CeedRequest *request) { 669cae8b89aSjeremylt int ierr; 670cae8b89aSjeremylt Ceed ceed = op->ceed; 671*250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 672cae8b89aSjeremylt 673*250756a7Sjeremylt if (op->numelements) { 674*250756a7Sjeremylt // Standard Operator 675*250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 676*250756a7Sjeremylt } else if (op->composite) { 677*250756a7Sjeremylt // Composite Operator 678*250756a7Sjeremylt if (op->ApplyAddComposite) { 679*250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 680cae8b89aSjeremylt } else { 681*250756a7Sjeremylt CeedInt numsub; 682*250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 683*250756a7Sjeremylt CeedOperator *suboperators; 684*250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 685*250756a7Sjeremylt 686*250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 687*250756a7Sjeremylt ierr = CeedOperatorApplyAdd(suboperators[i], in, out, request); 688cae8b89aSjeremylt CeedChk(ierr); 6891d7d2407SJeremy L Thompson } 690*250756a7Sjeremylt } 691*250756a7Sjeremylt } 692*250756a7Sjeremylt 693d7b241e6Sjeremylt return 0; 694d7b241e6Sjeremylt } 695d7b241e6Sjeremylt 696d7b241e6Sjeremylt /** 6974ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 6984ce2993fSjeremylt 6994ce2993fSjeremylt @param op CeedOperator 7004ce2993fSjeremylt @param[out] ceed Variable to store Ceed 7014ce2993fSjeremylt 7024ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7034ce2993fSjeremylt 70423617272Sjeremylt @ref Advanced 7054ce2993fSjeremylt **/ 7064ce2993fSjeremylt 7074ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 7084ce2993fSjeremylt *ceed = op->ceed; 7094ce2993fSjeremylt return 0; 7104ce2993fSjeremylt } 7114ce2993fSjeremylt 7124ce2993fSjeremylt /** 7134ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 7144ce2993fSjeremylt 7154ce2993fSjeremylt @param op CeedOperator 7164ce2993fSjeremylt @param[out] numelem Variable to store number of elements 7174ce2993fSjeremylt 7184ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7194ce2993fSjeremylt 72023617272Sjeremylt @ref Advanced 7214ce2993fSjeremylt **/ 7224ce2993fSjeremylt 7234ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 72452d6035fSJeremy L Thompson if (op->composite) 725c042f62fSJeremy L Thompson // LCOV_EXCL_START 72652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 727c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 72852d6035fSJeremy L Thompson 7294ce2993fSjeremylt *numelem = op->numelements; 7304ce2993fSjeremylt return 0; 7314ce2993fSjeremylt } 7324ce2993fSjeremylt 7334ce2993fSjeremylt /** 7344ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 7354ce2993fSjeremylt 7364ce2993fSjeremylt @param op CeedOperator 7374ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 7384ce2993fSjeremylt 7394ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7404ce2993fSjeremylt 74123617272Sjeremylt @ref Advanced 7424ce2993fSjeremylt **/ 7434ce2993fSjeremylt 7444ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 74552d6035fSJeremy L Thompson if (op->composite) 746c042f62fSJeremy L Thompson // LCOV_EXCL_START 74752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 748c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 74952d6035fSJeremy L Thompson 7504ce2993fSjeremylt *numqpts = op->numqpoints; 7514ce2993fSjeremylt return 0; 7524ce2993fSjeremylt } 7534ce2993fSjeremylt 7544ce2993fSjeremylt /** 7554ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 7564ce2993fSjeremylt 7574ce2993fSjeremylt @param op CeedOperator 7584ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 7594ce2993fSjeremylt 7604ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7614ce2993fSjeremylt 76223617272Sjeremylt @ref Advanced 7634ce2993fSjeremylt **/ 7644ce2993fSjeremylt 7654ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 76652d6035fSJeremy L Thompson if (op->composite) 767c042f62fSJeremy L Thompson // LCOV_EXCL_START 76852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 769c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 770c042f62fSJeremy L Thompson 7714ce2993fSjeremylt *numargs = op->nfields; 7724ce2993fSjeremylt return 0; 7734ce2993fSjeremylt } 7744ce2993fSjeremylt 7754ce2993fSjeremylt /** 7764ce2993fSjeremylt @brief Get the setup status of a CeedOperator 7774ce2993fSjeremylt 7784ce2993fSjeremylt @param op CeedOperator 779288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 7804ce2993fSjeremylt 7814ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7824ce2993fSjeremylt 78323617272Sjeremylt @ref Advanced 7844ce2993fSjeremylt **/ 7854ce2993fSjeremylt 7864ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 7874ce2993fSjeremylt *setupdone = op->setupdone; 7884ce2993fSjeremylt return 0; 7894ce2993fSjeremylt } 7904ce2993fSjeremylt 7914ce2993fSjeremylt /** 7924ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 7934ce2993fSjeremylt 7944ce2993fSjeremylt @param op CeedOperator 7958c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 7964ce2993fSjeremylt 7974ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7984ce2993fSjeremylt 79923617272Sjeremylt @ref Advanced 8004ce2993fSjeremylt **/ 8014ce2993fSjeremylt 8024ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 80352d6035fSJeremy L Thompson if (op->composite) 804c042f62fSJeremy L Thompson // LCOV_EXCL_START 80552d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 806c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 80752d6035fSJeremy L Thompson 8084ce2993fSjeremylt *qf = op->qf; 8094ce2993fSjeremylt return 0; 8104ce2993fSjeremylt } 8114ce2993fSjeremylt 8124ce2993fSjeremylt /** 81352d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 81452d6035fSJeremy L Thompson 81552d6035fSJeremy L Thompson @param op CeedOperator 81652d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 81752d6035fSJeremy L Thompson 81852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 81952d6035fSJeremy L Thompson 82052d6035fSJeremy L Thompson @ref Advanced 82152d6035fSJeremy L Thompson **/ 82252d6035fSJeremy L Thompson 82352d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 824c042f62fSJeremy L Thompson if (!op->composite) 825c042f62fSJeremy L Thompson // LCOV_EXCL_START 826c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 827c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 82852d6035fSJeremy L Thompson 82952d6035fSJeremy L Thompson *numsub = op->numsub; 83052d6035fSJeremy L Thompson return 0; 83152d6035fSJeremy L Thompson } 83252d6035fSJeremy L Thompson 83352d6035fSJeremy L Thompson /** 83452d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 83552d6035fSJeremy L Thompson 83652d6035fSJeremy L Thompson @param op CeedOperator 83752d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 83852d6035fSJeremy L Thompson 83952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 84052d6035fSJeremy L Thompson 84152d6035fSJeremy L Thompson @ref Advanced 84252d6035fSJeremy L Thompson **/ 84352d6035fSJeremy L Thompson 84452d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 845c042f62fSJeremy L Thompson if (!op->composite) 846c042f62fSJeremy L Thompson // LCOV_EXCL_START 847c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 848c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 84952d6035fSJeremy L Thompson 85052d6035fSJeremy L Thompson *suboperators = op->suboperators; 85152d6035fSJeremy L Thompson return 0; 85252d6035fSJeremy L Thompson } 85352d6035fSJeremy L Thompson 85452d6035fSJeremy L Thompson /** 855fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 856fe2413ffSjeremylt 857fe2413ffSjeremylt @param[out] op CeedOperator 858fe2413ffSjeremylt @param data Data to set 859fe2413ffSjeremylt 860fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 861fe2413ffSjeremylt 862fe2413ffSjeremylt @ref Advanced 863fe2413ffSjeremylt **/ 864fe2413ffSjeremylt 865fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void **data) { 866fe2413ffSjeremylt op->data = *data; 867fe2413ffSjeremylt return 0; 868fe2413ffSjeremylt } 869fe2413ffSjeremylt 870fe2413ffSjeremylt /** 8714ce2993fSjeremylt @brief Get the backend data of a CeedOperator 8724ce2993fSjeremylt 8734ce2993fSjeremylt @param op CeedOperator 8744ce2993fSjeremylt @param[out] data Variable to store data 8754ce2993fSjeremylt 8764ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 8774ce2993fSjeremylt 87823617272Sjeremylt @ref Advanced 8794ce2993fSjeremylt **/ 8804ce2993fSjeremylt 8814ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void **data) { 8824ce2993fSjeremylt *data = op->data; 8834ce2993fSjeremylt return 0; 8844ce2993fSjeremylt } 8854ce2993fSjeremylt 8864ce2993fSjeremylt /** 8874ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 8884ce2993fSjeremylt 8894ce2993fSjeremylt @param op CeedOperator 8904ce2993fSjeremylt 8914ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 8924ce2993fSjeremylt 89323617272Sjeremylt @ref Advanced 8944ce2993fSjeremylt **/ 8954ce2993fSjeremylt 8964ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 8974ce2993fSjeremylt op->setupdone = 1; 8984ce2993fSjeremylt return 0; 8994ce2993fSjeremylt } 9004ce2993fSjeremylt 9014ce2993fSjeremylt /** 9022ebaca42Sjeremylt @brief View a field of a CeedOperator 9032ebaca42Sjeremylt 9042ebaca42Sjeremylt @param[in] field Operator field to view 9052ebaca42Sjeremylt @param[in] fieldnumber Number of field being viewed 9062ebaca42Sjeremylt @param[in] stream Stream to view to, e.g., stdout 9072ebaca42Sjeremylt 9082ebaca42Sjeremylt @return An error code: 0 - success, otherwise - failure 9092ebaca42Sjeremylt 9102ebaca42Sjeremylt @ref Utility 9112ebaca42Sjeremylt **/ 9122ebaca42Sjeremylt static int CeedOperatorFieldView(CeedOperatorField field, 9132ebaca42Sjeremylt CeedQFunctionField qffield, 9142da88da5Sjeremylt CeedInt fieldnumber, bool sub, bool in, 9152da88da5Sjeremylt FILE *stream) { 9162ebaca42Sjeremylt const char *pre = sub ? " " : ""; 9172da88da5Sjeremylt const char *inout = in ? "Input" : "Output"; 9182ebaca42Sjeremylt 9192da88da5Sjeremylt fprintf(stream, "%s %s Field [%d]:\n" 9202da88da5Sjeremylt "%s Name: \"%s\"\n" 9212da88da5Sjeremylt "%s Lmode: \"%s\"\n", 9222da88da5Sjeremylt pre, inout, fieldnumber, pre, qffield->fieldname, 9232ebaca42Sjeremylt pre, CeedTransposeModes[field->lmode]); 9242ebaca42Sjeremylt 9252ebaca42Sjeremylt if (field->basis == CEED_BASIS_COLLOCATED) 9262ebaca42Sjeremylt fprintf(stream, "%s Collocated basis\n", pre); 9272ebaca42Sjeremylt 9282ebaca42Sjeremylt if (field->vec == CEED_VECTOR_ACTIVE) 9292ebaca42Sjeremylt fprintf(stream, "%s Active vector\n", pre); 9302ebaca42Sjeremylt else if (field->vec == CEED_VECTOR_NONE) 9312ebaca42Sjeremylt fprintf(stream, "%s No vector\n", pre); 9322ebaca42Sjeremylt 9332ebaca42Sjeremylt return 0; 9342ebaca42Sjeremylt } 9352ebaca42Sjeremylt 9362ebaca42Sjeremylt /** 9372ebaca42Sjeremylt @brief View a single CeedOperator 9382ebaca42Sjeremylt 9392ebaca42Sjeremylt @param[in] op CeedOperator to view 9402ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 9412ebaca42Sjeremylt 9422ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 9432ebaca42Sjeremylt 9442ebaca42Sjeremylt @ref Utility 9452ebaca42Sjeremylt **/ 9462ebaca42Sjeremylt int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 9472ebaca42Sjeremylt int ierr; 9482ebaca42Sjeremylt const char *pre = sub ? " " : ""; 9492ebaca42Sjeremylt 9502ebaca42Sjeremylt CeedInt totalfields; 9512ebaca42Sjeremylt ierr = CeedOperatorGetNumArgs(op, &totalfields); CeedChk(ierr); 9522da88da5Sjeremylt 9532ebaca42Sjeremylt fprintf(stream, "%s %d Field%s\n", pre, totalfields, totalfields>1 ? "s" : ""); 9542ebaca42Sjeremylt 9552da88da5Sjeremylt fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->numinputfields, 9562ebaca42Sjeremylt op->qf->numinputfields>1 ? "s" : ""); 9572ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 9582ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->inputfields[i], op->qf->inputfields[i], 9592da88da5Sjeremylt i, sub, 1, stream); CeedChk(ierr); 9602ebaca42Sjeremylt } 9612ebaca42Sjeremylt 9622da88da5Sjeremylt fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->numoutputfields, 9632ebaca42Sjeremylt op->qf->numoutputfields>1 ? "s" : ""); 9642ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 9652ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->outputfields[i], op->qf->inputfields[i], 9662da88da5Sjeremylt i, sub, 0, stream); CeedChk(ierr); 9672ebaca42Sjeremylt } 9682ebaca42Sjeremylt 9692ebaca42Sjeremylt return 0; 9702ebaca42Sjeremylt } 9712ebaca42Sjeremylt 9722ebaca42Sjeremylt /** 9732ebaca42Sjeremylt @brief View a CeedOperator 9742ebaca42Sjeremylt 9752ebaca42Sjeremylt @param[in] op CeedOperator to view 9762ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 9772ebaca42Sjeremylt 9782ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 9792ebaca42Sjeremylt 9802ebaca42Sjeremylt @ref Utility 9812ebaca42Sjeremylt **/ 9822ebaca42Sjeremylt int CeedOperatorView(CeedOperator op, FILE *stream) { 9832ebaca42Sjeremylt int ierr; 9842ebaca42Sjeremylt 9852ebaca42Sjeremylt if (op->composite) { 9862ebaca42Sjeremylt fprintf(stream, "Composite CeedOperator\n"); 9872ebaca42Sjeremylt 9882ebaca42Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 9892da88da5Sjeremylt fprintf(stream, " SubOperator [%d]:\n", i); 9902ebaca42Sjeremylt ierr = CeedOperatorSingleView(op->suboperators[i], 1, stream); 9912ebaca42Sjeremylt CeedChk(ierr); 9922ebaca42Sjeremylt } 9932ebaca42Sjeremylt } else { 9942ebaca42Sjeremylt fprintf(stream, "CeedOperator\n"); 9952ebaca42Sjeremylt ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 9962ebaca42Sjeremylt } 9972ebaca42Sjeremylt 9982ebaca42Sjeremylt return 0; 9992ebaca42Sjeremylt } 10002ebaca42Sjeremylt 10012ebaca42Sjeremylt /** 1002d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 1003d1bcdac9Sjeremylt 1004d1bcdac9Sjeremylt @param op CeedOperator 1005d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 1006d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 1007d1bcdac9Sjeremylt 1008d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1009d1bcdac9Sjeremylt 1010d1bcdac9Sjeremylt @ref Advanced 1011d1bcdac9Sjeremylt **/ 1012d1bcdac9Sjeremylt 1013692c2638Sjeremylt int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **inputfields, 1014d1bcdac9Sjeremylt CeedOperatorField **outputfields) { 101552d6035fSJeremy L Thompson if (op->composite) 1016c042f62fSJeremy L Thompson // LCOV_EXCL_START 101752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 1018c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 101952d6035fSJeremy L Thompson 1020d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 1021d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 1022d1bcdac9Sjeremylt return 0; 1023d1bcdac9Sjeremylt } 1024d1bcdac9Sjeremylt 1025d1bcdac9Sjeremylt /** 10264dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 10274dccadb6Sjeremylt 10284dccadb6Sjeremylt @param opfield CeedOperatorField 10294dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 10304dccadb6Sjeremylt 10314dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 10324dccadb6Sjeremylt 10334dccadb6Sjeremylt @ref Advanced 10344dccadb6Sjeremylt **/ 10354dccadb6Sjeremylt 10364dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 10374dccadb6Sjeremylt CeedTransposeMode *lmode) { 1038fe2413ffSjeremylt *lmode = opfield->lmode; 10394dccadb6Sjeremylt return 0; 10402b8e417aSjeremylt } 10412b8e417aSjeremylt 10422b8e417aSjeremylt /** 1043d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 1044d1bcdac9Sjeremylt 1045d1bcdac9Sjeremylt @param opfield CeedOperatorField 1046d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 1047d1bcdac9Sjeremylt 1048d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1049d1bcdac9Sjeremylt 1050d1bcdac9Sjeremylt @ref Advanced 1051d1bcdac9Sjeremylt **/ 1052d1bcdac9Sjeremylt 1053d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 1054d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 1055fe2413ffSjeremylt *rstr = opfield->Erestrict; 1056d1bcdac9Sjeremylt return 0; 1057d1bcdac9Sjeremylt } 1058d1bcdac9Sjeremylt 1059d1bcdac9Sjeremylt /** 1060d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 1061d1bcdac9Sjeremylt 1062d1bcdac9Sjeremylt @param opfield CeedOperatorField 1063d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 1064d1bcdac9Sjeremylt 1065d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1066d1bcdac9Sjeremylt 1067d1bcdac9Sjeremylt @ref Advanced 1068d1bcdac9Sjeremylt **/ 1069d1bcdac9Sjeremylt 1070692c2638Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 1071fe2413ffSjeremylt *basis = opfield->basis; 1072d1bcdac9Sjeremylt return 0; 1073d1bcdac9Sjeremylt } 1074d1bcdac9Sjeremylt 1075d1bcdac9Sjeremylt /** 1076d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 1077d1bcdac9Sjeremylt 1078d1bcdac9Sjeremylt @param opfield CeedOperatorField 1079d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 1080d1bcdac9Sjeremylt 1081d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1082d1bcdac9Sjeremylt 1083d1bcdac9Sjeremylt @ref Advanced 1084d1bcdac9Sjeremylt **/ 1085d1bcdac9Sjeremylt 1086692c2638Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 1087fe2413ffSjeremylt *vec = opfield->vec; 1088d1bcdac9Sjeremylt return 0; 1089d1bcdac9Sjeremylt } 1090d1bcdac9Sjeremylt 1091d1bcdac9Sjeremylt /** 1092b11c1e72Sjeremylt @brief Destroy a CeedOperator 1093d7b241e6Sjeremylt 1094d7b241e6Sjeremylt @param op CeedOperator to destroy 1095b11c1e72Sjeremylt 1096b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1097dfdf5a53Sjeremylt 1098dfdf5a53Sjeremylt @ref Basic 1099b11c1e72Sjeremylt **/ 1100d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1101d7b241e6Sjeremylt int ierr; 1102d7b241e6Sjeremylt 1103d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 1104d7b241e6Sjeremylt if ((*op)->Destroy) { 1105d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1106d7b241e6Sjeremylt } 1107fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1108fe2413ffSjeremylt // Free fields 11091d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 111052d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 111171352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 111271352a93Sjeremylt CeedChk(ierr); 111371352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 111471352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 111571352a93Sjeremylt } 111671352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 111771352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 111871352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 111971352a93Sjeremylt } 1120fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1121fe2413ffSjeremylt } 11221d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1123d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 112471352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 112571352a93Sjeremylt CeedChk(ierr); 112671352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 112771352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 112871352a93Sjeremylt } 112971352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 113071352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 113171352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 113271352a93Sjeremylt } 1133fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1134fe2413ffSjeremylt } 113552d6035fSJeremy L Thompson // Destroy suboperators 11361d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 113752d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 113852d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 113952d6035fSJeremy L Thompson } 1140d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1141d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1142d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1143fe2413ffSjeremylt 11445107b09fSJeremy L Thompson // Destroy fallback 11455107b09fSJeremy L Thompson if ((*op)->opfallback) { 11465107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 11475107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 11485107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 11495107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 11505107b09fSJeremy L Thompson } 11515107b09fSJeremy L Thompson 1152fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1153fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 115452d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1155d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1156d7b241e6Sjeremylt return 0; 1157d7b241e6Sjeremylt } 1158d7b241e6Sjeremylt 1159d7b241e6Sjeremylt /// @} 1160