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 23dfdf5a53Sjeremylt /// Implementation of public CeedOperator interfaces 24dfdf5a53Sjeremylt /// 25dfdf5a53Sjeremylt /// @addtogroup CeedOperator 26dfdf5a53Sjeremylt /// @{ 27d7b241e6Sjeremylt 28d7b241e6Sjeremylt /** 290219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 300219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 310219ea01SJeremy L Thompson \ref CeedOperatorSetField. 32d7b241e6Sjeremylt 33b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 34d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 3534138859Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or 3634138859Sjeremylt CEED_QFUNCTION_NONE) 37d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 3834138859Sjeremylt of @a qf (or CEED_QFUNCTION_NONE) 39b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 40b11c1e72Sjeremylt CeedOperator will be stored 41b11c1e72Sjeremylt 42b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 43dfdf5a53Sjeremylt 44dfdf5a53Sjeremylt @ref Basic 45d7b241e6Sjeremylt */ 46d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 47d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 48d7b241e6Sjeremylt int ierr; 49d7b241e6Sjeremylt 505fe0d4faSjeremylt if (!ceed->OperatorCreate) { 515fe0d4faSjeremylt Ceed delegate; 52aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 535fe0d4faSjeremylt 545fe0d4faSjeremylt if (!delegate) 55c042f62fSJeremy L Thompson // LCOV_EXCL_START 565fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 57c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 585fe0d4faSjeremylt 595fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 605fe0d4faSjeremylt return 0; 615fe0d4faSjeremylt } 625fe0d4faSjeremylt 63d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 64d7b241e6Sjeremylt (*op)->ceed = ceed; 65d7b241e6Sjeremylt ceed->refcount++; 66d7b241e6Sjeremylt (*op)->refcount = 1; 67442e7f0bSjeremylt if (qf == CEED_QFUNCTION_NONE) 68442e7f0bSjeremylt // LCOV_EXCL_START 69442e7f0bSjeremylt return CeedError(ceed, 1, "Operator must have a valid QFunction."); 70442e7f0bSjeremylt // LCOV_EXCL_STOP 71d7b241e6Sjeremylt (*op)->qf = qf; 72d7b241e6Sjeremylt qf->refcount++; 73442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 74d7b241e6Sjeremylt (*op)->dqf = dqf; 75442e7f0bSjeremylt dqf->refcount++; 76442e7f0bSjeremylt } 77442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 78d7b241e6Sjeremylt (*op)->dqfT = dqfT; 79442e7f0bSjeremylt dqfT->refcount++; 80442e7f0bSjeremylt } 81fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 82fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 83d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 84d7b241e6Sjeremylt return 0; 85d7b241e6Sjeremylt } 86d7b241e6Sjeremylt 87d7b241e6Sjeremylt /** 8852d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 8952d6035fSJeremy L Thompson 9052d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 9152d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 9252d6035fSJeremy L Thompson Composite CeedOperator will be stored 9352d6035fSJeremy L Thompson 9452d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9552d6035fSJeremy L Thompson 9652d6035fSJeremy L Thompson @ref Basic 9752d6035fSJeremy L Thompson */ 9852d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 9952d6035fSJeremy L Thompson int ierr; 10052d6035fSJeremy L Thompson 10152d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 10252d6035fSJeremy L Thompson Ceed delegate; 103aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 10452d6035fSJeremy L Thompson 105250756a7Sjeremylt if (delegate) { 10652d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 10752d6035fSJeremy L Thompson return 0; 10852d6035fSJeremy L Thompson } 109250756a7Sjeremylt } 11052d6035fSJeremy L Thompson 11152d6035fSJeremy L Thompson ierr = CeedCalloc(1, op); CeedChk(ierr); 11252d6035fSJeremy L Thompson (*op)->ceed = ceed; 11352d6035fSJeremy L Thompson ceed->refcount++; 11452d6035fSJeremy L Thompson (*op)->composite = true; 11552d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 116250756a7Sjeremylt 117250756a7Sjeremylt if (ceed->CompositeOperatorCreate) { 11852d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 119250756a7Sjeremylt } 12052d6035fSJeremy L Thompson return 0; 12152d6035fSJeremy L Thompson } 12252d6035fSJeremy L Thompson 12352d6035fSJeremy L Thompson /** 124b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 125d7b241e6Sjeremylt 126d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 127d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 128d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 129d7b241e6Sjeremylt 130d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 131d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 132d7b241e6Sjeremylt input and at most one active output. 133d7b241e6Sjeremylt 1348c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 1358795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 1368795c945Sjeremylt CeedQFunction) 137b11c1e72Sjeremylt @param r CeedElemRestriction 138783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 139b11c1e72Sjeremylt if collocated with quadrature points 140b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 141b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 1428c91a0c9SJeremy L Thompson CEED_EVAL_WEIGHT in the QFunction 143b11c1e72Sjeremylt 144b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 145dfdf5a53Sjeremylt 146dfdf5a53Sjeremylt @ref Basic 147b11c1e72Sjeremylt **/ 148d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 149*a8d32208Sjeremylt CeedElemRestriction r, CeedBasis b, CeedVector v) { 150d7b241e6Sjeremylt int ierr; 15152d6035fSJeremy L Thompson if (op->composite) 152c042f62fSJeremy L Thompson // LCOV_EXCL_START 15352d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 154c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1558b067b84SJed Brown if (!r) 156c042f62fSJeremy L Thompson // LCOV_EXCL_START 157c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 158c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 159c042f62fSJeremy L Thompson fieldname); 160c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1618b067b84SJed Brown if (!b) 162c042f62fSJeremy L Thompson // LCOV_EXCL_START 163c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 164c042f62fSJeremy L Thompson fieldname); 165c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1668b067b84SJed Brown if (!v) 167c042f62fSJeremy L Thompson // LCOV_EXCL_START 168c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 169c042f62fSJeremy L Thompson fieldname); 170c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 17152d6035fSJeremy L Thompson 172d7b241e6Sjeremylt CeedInt numelements; 173d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 1742cb0afc5Sjeremylt if (op->hasrestriction && op->numelements != numelements) 175c042f62fSJeremy L Thompson // LCOV_EXCL_START 176d7b241e6Sjeremylt return CeedError(op->ceed, 1, 1771d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 1781d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 179c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 180d7b241e6Sjeremylt op->numelements = numelements; 1812cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 182d7b241e6Sjeremylt 183783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 184d7b241e6Sjeremylt CeedInt numqpoints; 185d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 186d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 187c042f62fSJeremy L Thompson // LCOV_EXCL_START 1881d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1891d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1901d102b48SJeremy L Thompson op->numqpoints); 191c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 192d7b241e6Sjeremylt op->numqpoints = numqpoints; 193d7b241e6Sjeremylt } 194d1bcdac9Sjeremylt CeedOperatorField *ofield; 195d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 196fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 197d7b241e6Sjeremylt ofield = &op->inputfields[i]; 198d7b241e6Sjeremylt goto found; 199d7b241e6Sjeremylt } 200d7b241e6Sjeremylt } 201d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 202fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 203d7b241e6Sjeremylt ofield = &op->outputfields[i]; 204d7b241e6Sjeremylt goto found; 205d7b241e6Sjeremylt } 206d7b241e6Sjeremylt } 207c042f62fSJeremy L Thompson // LCOV_EXCL_START 208d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 209d7b241e6Sjeremylt fieldname); 210c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 211d7b241e6Sjeremylt found: 212fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 213fe2413ffSjeremylt (*ofield)->Erestrict = r; 21471352a93Sjeremylt r->refcount += 1; 215fe2413ffSjeremylt (*ofield)->basis = b; 21671352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 21771352a93Sjeremylt b->refcount += 1; 218fe2413ffSjeremylt (*ofield)->vec = v; 21971352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 22071352a93Sjeremylt v->refcount += 1; 221d7b241e6Sjeremylt op->nfields += 1; 222d7b241e6Sjeremylt return 0; 223d7b241e6Sjeremylt } 224d7b241e6Sjeremylt 225d7b241e6Sjeremylt /** 22652d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 227288c0443SJeremy L Thompson 22834138859Sjeremylt @param[out] compositeop Composite CeedOperator 22934138859Sjeremylt @param subop Sub-operator CeedOperator 23052d6035fSJeremy L Thompson 23152d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23252d6035fSJeremy L Thompson 23352d6035fSJeremy L Thompson @ref Basic 23452d6035fSJeremy L Thompson */ 235692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 23652d6035fSJeremy L Thompson if (!compositeop->composite) 237c042f62fSJeremy L Thompson // LCOV_EXCL_START 2381d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2391d102b48SJeremy L Thompson "operator"); 240c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24152d6035fSJeremy L Thompson 24252d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 243c042f62fSJeremy L Thompson // LCOV_EXCL_START 2441d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 245c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24652d6035fSJeremy L Thompson 24752d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 24852d6035fSJeremy L Thompson subop->refcount++; 24952d6035fSJeremy L Thompson compositeop->numsub++; 25052d6035fSJeremy L Thompson return 0; 25152d6035fSJeremy L Thompson } 25252d6035fSJeremy L Thompson 25352d6035fSJeremy L Thompson /** 2545107b09fSJeremy L Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 2555107b09fSJeremy L Thompson CeedOperator functionality 2565107b09fSJeremy L Thompson 2575107b09fSJeremy L Thompson @param op CeedOperator to create fallback for 2585107b09fSJeremy L Thompson 2595107b09fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2605107b09fSJeremy L Thompson 2615107b09fSJeremy L Thompson @ref Developer 2625107b09fSJeremy L Thompson **/ 2635107b09fSJeremy L Thompson int CeedOperatorCreateFallback(CeedOperator op) { 2645107b09fSJeremy L Thompson int ierr; 2655107b09fSJeremy L Thompson 2665107b09fSJeremy L Thompson // Fallback Ceed 2675107b09fSJeremy L Thompson const char *resource, *fallbackresource; 2685107b09fSJeremy L Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 2695107b09fSJeremy L Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 2705107b09fSJeremy L Thompson CeedChk(ierr); 2715107b09fSJeremy L Thompson if (!strcmp(resource, fallbackresource)) 2725107b09fSJeremy L Thompson // LCOV_EXCL_START 2735107b09fSJeremy L Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 2745107b09fSJeremy L Thompson "fallback to resource %s", resource, fallbackresource); 2755107b09fSJeremy L Thompson // LCOV_EXCL_STOP 2765107b09fSJeremy L Thompson 2770ace9bf2Sjeremylt // Fallback Ceed 2785107b09fSJeremy L Thompson Ceed ceedref; 2790ace9bf2Sjeremylt if (!op->ceed->opfallbackceed) { 2805107b09fSJeremy L Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 2815107b09fSJeremy L Thompson ceedref->opfallbackparent = op->ceed; 2825107b09fSJeremy L Thompson op->ceed->opfallbackceed = ceedref; 2830ace9bf2Sjeremylt } 2840ace9bf2Sjeremylt ceedref = op->ceed->opfallbackceed; 2855107b09fSJeremy L Thompson 2865107b09fSJeremy L Thompson // Clone Op 2875107b09fSJeremy L Thompson CeedOperator opref; 2885107b09fSJeremy L Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 2895107b09fSJeremy L Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 2905107b09fSJeremy L Thompson opref->data = NULL; 2915107b09fSJeremy L Thompson opref->setupdone = 0; 2925107b09fSJeremy L Thompson opref->ceed = ceedref; 2935107b09fSJeremy L Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 2945107b09fSJeremy L Thompson op->opfallback = opref; 2955107b09fSJeremy L Thompson 2965107b09fSJeremy L Thompson // Clone QF 2975107b09fSJeremy L Thompson CeedQFunction qfref; 2985107b09fSJeremy L Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 2995107b09fSJeremy L Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 3005107b09fSJeremy L Thompson qfref->data = NULL; 3015107b09fSJeremy L Thompson qfref->ceed = ceedref; 3025107b09fSJeremy L Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 3035107b09fSJeremy L Thompson opref->qf = qfref; 3045107b09fSJeremy L Thompson op->qffallback = qfref; 3055107b09fSJeremy L Thompson 3065107b09fSJeremy L Thompson return 0; 3075107b09fSJeremy L Thompson } 3085107b09fSJeremy L Thompson 3095107b09fSJeremy L Thompson /** 310250756a7Sjeremylt @brief Check if a CeedOperator is ready to be used. 311250756a7Sjeremylt 312250756a7Sjeremylt @param[in] ceed Ceed object for error handling 313250756a7Sjeremylt @param[in] op CeedOperator to check 314250756a7Sjeremylt 315250756a7Sjeremylt @return An error code: 0 - success, otherwise - failure 316250756a7Sjeremylt 317250756a7Sjeremylt @ref Basic 318250756a7Sjeremylt **/ 319250756a7Sjeremylt static int CeedOperatorCheckReady(Ceed ceed, CeedOperator op) { 320250756a7Sjeremylt CeedQFunction qf = op->qf; 321250756a7Sjeremylt 322250756a7Sjeremylt if (op->composite) { 323250756a7Sjeremylt if (!op->numsub) 324250756a7Sjeremylt // LCOV_EXCL_START 325250756a7Sjeremylt return CeedError(ceed, 1, "No suboperators set"); 326250756a7Sjeremylt // LCOV_EXCL_STOP 327250756a7Sjeremylt } else { 328250756a7Sjeremylt if (op->nfields == 0) 329250756a7Sjeremylt // LCOV_EXCL_START 330250756a7Sjeremylt return CeedError(ceed, 1, "No operator fields set"); 331250756a7Sjeremylt // LCOV_EXCL_STOP 332250756a7Sjeremylt if (op->nfields < qf->numinputfields + qf->numoutputfields) 333250756a7Sjeremylt // LCOV_EXCL_START 334250756a7Sjeremylt return CeedError(ceed, 1, "Not all operator fields set"); 335250756a7Sjeremylt // LCOV_EXCL_STOP 336250756a7Sjeremylt if (!op->hasrestriction) 337250756a7Sjeremylt // LCOV_EXCL_START 338250756a7Sjeremylt return CeedError(ceed, 1,"At least one restriction required"); 339250756a7Sjeremylt // LCOV_EXCL_STOP 340250756a7Sjeremylt if (op->numqpoints == 0) 341250756a7Sjeremylt // LCOV_EXCL_START 342250756a7Sjeremylt return CeedError(ceed, 1,"At least one non-collocated basis required"); 343250756a7Sjeremylt // LCOV_EXCL_STOP 344250756a7Sjeremylt } 345250756a7Sjeremylt 346250756a7Sjeremylt return 0; 347250756a7Sjeremylt } 348250756a7Sjeremylt 349250756a7Sjeremylt /** 3501d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 3511d102b48SJeremy L Thompson 3521d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 3531d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 3541d102b48SJeremy L Thompson The vector 'assembled' is of shape 3551d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 3561d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 3571d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 3581d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 3591d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 3601d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 3611d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 3621d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 3631d102b48SJeremy L Thompson 3641d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 3651d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 3661d102b48SJeremy L Thompson quadrature points 3671d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 3681d102b48SJeremy L Thompson CeedQFunction 3691d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 3701d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 3711d102b48SJeremy L Thompson 3721d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3731d102b48SJeremy L Thompson 374b7ec98d8SJeremy L Thompson @ref Basic 3751d102b48SJeremy L Thompson **/ 3761d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 3777f823360Sjeremylt CeedElemRestriction *rstr, 3787f823360Sjeremylt CeedRequest *request) { 3791d102b48SJeremy L Thompson int ierr; 3801d102b48SJeremy L Thompson Ceed ceed = op->ceed; 381250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 3821d102b48SJeremy L Thompson 3837172caadSjeremylt // Backend version 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 } 396250756a7Sjeremylt 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; 418250756a7Sjeremylt 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); 4237172caadSjeremylt } else { 4247172caadSjeremylt // Fallback to reference Ceed 4257172caadSjeremylt if (!op->opfallback) { 4267172caadSjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 427b7ec98d8SJeremy L Thompson } 4287172caadSjeremylt // Assemble 4297172caadSjeremylt ierr = op->opfallback->AssembleLinearDiagonal(op->opfallback, assembled, 4307172caadSjeremylt request); CeedChk(ierr); 431b7ec98d8SJeremy L Thompson } 432b7ec98d8SJeremy L Thompson 433b7ec98d8SJeremy L Thompson return 0; 434b7ec98d8SJeremy L Thompson } 435b7ec98d8SJeremy L Thompson 436b7ec98d8SJeremy L Thompson /** 4373bd813ffSjeremylt @brief Build a FDM based approximate inverse for each element for a 4383bd813ffSjeremylt CeedOperator 4393bd813ffSjeremylt 4403bd813ffSjeremylt This returns a CeedOperator and CeedVector to apply a Fast Diagonalization 4413bd813ffSjeremylt Method based approximate inverse. This function obtains the simultaneous 4423bd813ffSjeremylt diagonalization for the 1D mass and Laplacian operators, 4433bd813ffSjeremylt M = V^T V, K = V^T S V. 4443bd813ffSjeremylt The assembled QFunction is used to modify the eigenvalues from simultaneous 4453bd813ffSjeremylt diagonalization and obtain an approximate inverse of the form 4463bd813ffSjeremylt V^T S^hat V. The CeedOperator must be linear and non-composite. The 4473bd813ffSjeremylt associated CeedQFunction must therefore also be linear. 4483bd813ffSjeremylt 4493bd813ffSjeremylt @param op CeedOperator to create element inverses 4503bd813ffSjeremylt @param[out] fdminv CeedOperator to apply the action of a FDM based inverse 4513bd813ffSjeremylt for each element 4523bd813ffSjeremylt @param request Address of CeedRequest for non-blocking completion, else 4533bd813ffSjeremylt CEED_REQUEST_IMMEDIATE 4543bd813ffSjeremylt 4553bd813ffSjeremylt @return An error code: 0 - success, otherwise - failure 4563bd813ffSjeremylt 4573bd813ffSjeremylt @ref Advanced 4583bd813ffSjeremylt **/ 4593bd813ffSjeremylt int CeedOperatorCreateFDMElementInverse(CeedOperator op, CeedOperator *fdminv, 4603bd813ffSjeremylt CeedRequest *request) { 4613bd813ffSjeremylt int ierr; 4623bd813ffSjeremylt Ceed ceed = op->ceed; 463713f43c3Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 4643bd813ffSjeremylt 465713f43c3Sjeremylt // Use backend version, if available 466713f43c3Sjeremylt if (op->CreateFDMElementInverse) { 467713f43c3Sjeremylt ierr = op->CreateFDMElementInverse(op, fdminv, request); CeedChk(ierr); 468713f43c3Sjeremylt } else { 469713f43c3Sjeremylt // Fallback to reference Ceed 470713f43c3Sjeremylt if (!op->opfallback) { 471713f43c3Sjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 4723bd813ffSjeremylt } 473713f43c3Sjeremylt // Assemble 474713f43c3Sjeremylt ierr = op->opfallback->CreateFDMElementInverse(op->opfallback, fdminv, 4753bd813ffSjeremylt request); CeedChk(ierr); 4763bd813ffSjeremylt } 4773bd813ffSjeremylt 4783bd813ffSjeremylt return 0; 4793bd813ffSjeremylt } 4803bd813ffSjeremylt 4813bd813ffSjeremylt 4823bd813ffSjeremylt /** 4833bd813ffSjeremylt @brief Apply CeedOperator to a vector 484d7b241e6Sjeremylt 485d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 486d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 487d7b241e6Sjeremylt CeedOperatorSetField(). 488d7b241e6Sjeremylt 489d7b241e6Sjeremylt @param op CeedOperator to apply 49034138859Sjeremylt @param[in] in CeedVector containing input state or CEED_VECTOR_NONE if 49134138859Sjeremylt there are no active inputs 492b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 49334138859Sjeremylt distinct from @a in) or CEED_VECTOR_NONE if there are no 49434138859Sjeremylt active outputs 495d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 496d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 497b11c1e72Sjeremylt 498b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 499dfdf5a53Sjeremylt 500dfdf5a53Sjeremylt @ref Basic 501b11c1e72Sjeremylt **/ 502692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 503692c2638Sjeremylt CeedRequest *request) { 504d7b241e6Sjeremylt int ierr; 505d7b241e6Sjeremylt Ceed ceed = op->ceed; 506250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 507d7b241e6Sjeremylt 508250756a7Sjeremylt if (op->numelements) { 509250756a7Sjeremylt // Standard Operator 510cae8b89aSjeremylt if (op->Apply) { 511250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 512cae8b89aSjeremylt } else { 513cae8b89aSjeremylt // Zero all output vectors 514250756a7Sjeremylt CeedQFunction qf = op->qf; 515cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 516cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 517cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 518cae8b89aSjeremylt vec = out; 519cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 520cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 521cae8b89aSjeremylt } 522cae8b89aSjeremylt } 523250756a7Sjeremylt // Apply 524250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 525250756a7Sjeremylt } 526250756a7Sjeremylt } else if (op->composite) { 527250756a7Sjeremylt // Composite Operator 528250756a7Sjeremylt if (op->ApplyComposite) { 529250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 530250756a7Sjeremylt } else { 531250756a7Sjeremylt CeedInt numsub; 532250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 533250756a7Sjeremylt CeedOperator *suboperators; 534250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 535250756a7Sjeremylt 536250756a7Sjeremylt // Zero all output vectors 537250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 538cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 539cae8b89aSjeremylt } 540250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 541250756a7Sjeremylt for (CeedInt j=0; j<suboperators[i]->qf->numoutputfields; j++) { 542250756a7Sjeremylt CeedVector vec = suboperators[i]->outputfields[j]->vec; 543250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 544250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 545250756a7Sjeremylt } 546250756a7Sjeremylt } 547250756a7Sjeremylt } 548250756a7Sjeremylt // Apply 549250756a7Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 550250756a7Sjeremylt ierr = CeedOperatorApplyAdd(op->suboperators[i], in, out, request); 551cae8b89aSjeremylt CeedChk(ierr); 552cae8b89aSjeremylt } 553cae8b89aSjeremylt } 554250756a7Sjeremylt } 555250756a7Sjeremylt 556cae8b89aSjeremylt return 0; 557cae8b89aSjeremylt } 558cae8b89aSjeremylt 559cae8b89aSjeremylt /** 560cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 561cae8b89aSjeremylt 562cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 563cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 564cae8b89aSjeremylt CeedOperatorSetField(). 565cae8b89aSjeremylt 566cae8b89aSjeremylt @param op CeedOperator to apply 567cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 568cae8b89aSjeremylt active inputs 569cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 570cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 571cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 572cae8b89aSjeremylt CEED_REQUEST_IMMEDIATE 573cae8b89aSjeremylt 574cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 575cae8b89aSjeremylt 576cae8b89aSjeremylt @ref Basic 577cae8b89aSjeremylt **/ 578cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 579cae8b89aSjeremylt CeedRequest *request) { 580cae8b89aSjeremylt int ierr; 581cae8b89aSjeremylt Ceed ceed = op->ceed; 582250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 583cae8b89aSjeremylt 584250756a7Sjeremylt if (op->numelements) { 585250756a7Sjeremylt // Standard Operator 586250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 587250756a7Sjeremylt } else if (op->composite) { 588250756a7Sjeremylt // Composite Operator 589250756a7Sjeremylt if (op->ApplyAddComposite) { 590250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 591cae8b89aSjeremylt } else { 592250756a7Sjeremylt CeedInt numsub; 593250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 594250756a7Sjeremylt CeedOperator *suboperators; 595250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 596250756a7Sjeremylt 597250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 598250756a7Sjeremylt ierr = CeedOperatorApplyAdd(suboperators[i], in, out, request); 599cae8b89aSjeremylt CeedChk(ierr); 6001d7d2407SJeremy L Thompson } 601250756a7Sjeremylt } 602250756a7Sjeremylt } 603250756a7Sjeremylt 604d7b241e6Sjeremylt return 0; 605d7b241e6Sjeremylt } 606d7b241e6Sjeremylt 607d7b241e6Sjeremylt /** 6084ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 6094ce2993fSjeremylt 6104ce2993fSjeremylt @param op CeedOperator 6114ce2993fSjeremylt @param[out] ceed Variable to store Ceed 6124ce2993fSjeremylt 6134ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6144ce2993fSjeremylt 61523617272Sjeremylt @ref Advanced 6164ce2993fSjeremylt **/ 6174ce2993fSjeremylt 6184ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 6194ce2993fSjeremylt *ceed = op->ceed; 6204ce2993fSjeremylt return 0; 6214ce2993fSjeremylt } 6224ce2993fSjeremylt 6234ce2993fSjeremylt /** 6244ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 6254ce2993fSjeremylt 6264ce2993fSjeremylt @param op CeedOperator 6274ce2993fSjeremylt @param[out] numelem Variable to store number of elements 6284ce2993fSjeremylt 6294ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6304ce2993fSjeremylt 63123617272Sjeremylt @ref Advanced 6324ce2993fSjeremylt **/ 6334ce2993fSjeremylt 6344ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 63552d6035fSJeremy L Thompson if (op->composite) 636c042f62fSJeremy L Thompson // LCOV_EXCL_START 63752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 638c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 63952d6035fSJeremy L Thompson 6404ce2993fSjeremylt *numelem = op->numelements; 6414ce2993fSjeremylt return 0; 6424ce2993fSjeremylt } 6434ce2993fSjeremylt 6444ce2993fSjeremylt /** 6454ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 6464ce2993fSjeremylt 6474ce2993fSjeremylt @param op CeedOperator 6484ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 6494ce2993fSjeremylt 6504ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6514ce2993fSjeremylt 65223617272Sjeremylt @ref Advanced 6534ce2993fSjeremylt **/ 6544ce2993fSjeremylt 6554ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 65652d6035fSJeremy L Thompson if (op->composite) 657c042f62fSJeremy L Thompson // LCOV_EXCL_START 65852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 659c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 66052d6035fSJeremy L Thompson 6614ce2993fSjeremylt *numqpts = op->numqpoints; 6624ce2993fSjeremylt return 0; 6634ce2993fSjeremylt } 6644ce2993fSjeremylt 6654ce2993fSjeremylt /** 6664ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 6674ce2993fSjeremylt 6684ce2993fSjeremylt @param op CeedOperator 6694ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 6704ce2993fSjeremylt 6714ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6724ce2993fSjeremylt 67323617272Sjeremylt @ref Advanced 6744ce2993fSjeremylt **/ 6754ce2993fSjeremylt 6764ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 67752d6035fSJeremy L Thompson if (op->composite) 678c042f62fSJeremy L Thompson // LCOV_EXCL_START 67952d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 680c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 681c042f62fSJeremy L Thompson 6824ce2993fSjeremylt *numargs = op->nfields; 6834ce2993fSjeremylt return 0; 6844ce2993fSjeremylt } 6854ce2993fSjeremylt 6864ce2993fSjeremylt /** 6874ce2993fSjeremylt @brief Get the setup status of a CeedOperator 6884ce2993fSjeremylt 6894ce2993fSjeremylt @param op CeedOperator 690288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 6914ce2993fSjeremylt 6924ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6934ce2993fSjeremylt 69423617272Sjeremylt @ref Advanced 6954ce2993fSjeremylt **/ 6964ce2993fSjeremylt 6974ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 6984ce2993fSjeremylt *setupdone = op->setupdone; 6994ce2993fSjeremylt return 0; 7004ce2993fSjeremylt } 7014ce2993fSjeremylt 7024ce2993fSjeremylt /** 7034ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 7044ce2993fSjeremylt 7054ce2993fSjeremylt @param op CeedOperator 7068c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 7074ce2993fSjeremylt 7084ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7094ce2993fSjeremylt 71023617272Sjeremylt @ref Advanced 7114ce2993fSjeremylt **/ 7124ce2993fSjeremylt 7134ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 71452d6035fSJeremy L Thompson if (op->composite) 715c042f62fSJeremy L Thompson // LCOV_EXCL_START 71652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 717c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 71852d6035fSJeremy L Thompson 7194ce2993fSjeremylt *qf = op->qf; 7204ce2993fSjeremylt return 0; 7214ce2993fSjeremylt } 7224ce2993fSjeremylt 7234ce2993fSjeremylt /** 72452d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 72552d6035fSJeremy L Thompson 72652d6035fSJeremy L Thompson @param op CeedOperator 72752d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 72852d6035fSJeremy L Thompson 72952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 73052d6035fSJeremy L Thompson 73152d6035fSJeremy L Thompson @ref Advanced 73252d6035fSJeremy L Thompson **/ 73352d6035fSJeremy L Thompson 73452d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 735c042f62fSJeremy L Thompson if (!op->composite) 736c042f62fSJeremy L Thompson // LCOV_EXCL_START 737c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 738c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 73952d6035fSJeremy L Thompson 74052d6035fSJeremy L Thompson *numsub = op->numsub; 74152d6035fSJeremy L Thompson return 0; 74252d6035fSJeremy L Thompson } 74352d6035fSJeremy L Thompson 74452d6035fSJeremy L Thompson /** 74552d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 74652d6035fSJeremy L Thompson 74752d6035fSJeremy L Thompson @param op CeedOperator 74852d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 74952d6035fSJeremy L Thompson 75052d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 75152d6035fSJeremy L Thompson 75252d6035fSJeremy L Thompson @ref Advanced 75352d6035fSJeremy L Thompson **/ 75452d6035fSJeremy L Thompson 75552d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 756c042f62fSJeremy L Thompson if (!op->composite) 757c042f62fSJeremy L Thompson // LCOV_EXCL_START 758c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 759c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 76052d6035fSJeremy L Thompson 76152d6035fSJeremy L Thompson *suboperators = op->suboperators; 76252d6035fSJeremy L Thompson return 0; 76352d6035fSJeremy L Thompson } 76452d6035fSJeremy L Thompson 76552d6035fSJeremy L Thompson /** 766fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 767fe2413ffSjeremylt 768fe2413ffSjeremylt @param[out] op CeedOperator 769fe2413ffSjeremylt @param data Data to set 770fe2413ffSjeremylt 771fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 772fe2413ffSjeremylt 773fe2413ffSjeremylt @ref Advanced 774fe2413ffSjeremylt **/ 775fe2413ffSjeremylt 776fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void **data) { 777fe2413ffSjeremylt op->data = *data; 778fe2413ffSjeremylt return 0; 779fe2413ffSjeremylt } 780fe2413ffSjeremylt 781fe2413ffSjeremylt /** 7824ce2993fSjeremylt @brief Get the backend data of a CeedOperator 7834ce2993fSjeremylt 7844ce2993fSjeremylt @param op CeedOperator 7854ce2993fSjeremylt @param[out] data Variable to store data 7864ce2993fSjeremylt 7874ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7884ce2993fSjeremylt 78923617272Sjeremylt @ref Advanced 7904ce2993fSjeremylt **/ 7914ce2993fSjeremylt 7924ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void **data) { 7934ce2993fSjeremylt *data = op->data; 7944ce2993fSjeremylt return 0; 7954ce2993fSjeremylt } 7964ce2993fSjeremylt 7974ce2993fSjeremylt /** 7984ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 7994ce2993fSjeremylt 8004ce2993fSjeremylt @param op CeedOperator 8014ce2993fSjeremylt 8024ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 8034ce2993fSjeremylt 80423617272Sjeremylt @ref Advanced 8054ce2993fSjeremylt **/ 8064ce2993fSjeremylt 8074ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 8084ce2993fSjeremylt op->setupdone = 1; 8094ce2993fSjeremylt return 0; 8104ce2993fSjeremylt } 8114ce2993fSjeremylt 8124ce2993fSjeremylt /** 8132ebaca42Sjeremylt @brief View a field of a CeedOperator 8142ebaca42Sjeremylt 8152ebaca42Sjeremylt @param[in] field Operator field to view 8162ebaca42Sjeremylt @param[in] fieldnumber Number of field being viewed 8172ebaca42Sjeremylt @param[in] stream Stream to view to, e.g., stdout 8182ebaca42Sjeremylt 8192ebaca42Sjeremylt @return An error code: 0 - success, otherwise - failure 8202ebaca42Sjeremylt 8212ebaca42Sjeremylt @ref Utility 8222ebaca42Sjeremylt **/ 8232ebaca42Sjeremylt static int CeedOperatorFieldView(CeedOperatorField field, 8242ebaca42Sjeremylt CeedQFunctionField qffield, 8252da88da5Sjeremylt CeedInt fieldnumber, bool sub, bool in, 8262da88da5Sjeremylt FILE *stream) { 8272ebaca42Sjeremylt const char *pre = sub ? " " : ""; 8282da88da5Sjeremylt const char *inout = in ? "Input" : "Output"; 8292ebaca42Sjeremylt 8302da88da5Sjeremylt fprintf(stream, "%s %s Field [%d]:\n" 831*a8d32208Sjeremylt "%s Name: \"%s\"\n", 832*a8d32208Sjeremylt pre, inout, fieldnumber, pre, qffield->fieldname); 8332ebaca42Sjeremylt 8342ebaca42Sjeremylt if (field->basis == CEED_BASIS_COLLOCATED) 8352ebaca42Sjeremylt fprintf(stream, "%s Collocated basis\n", pre); 8362ebaca42Sjeremylt 8372ebaca42Sjeremylt if (field->vec == CEED_VECTOR_ACTIVE) 8382ebaca42Sjeremylt fprintf(stream, "%s Active vector\n", pre); 8392ebaca42Sjeremylt else if (field->vec == CEED_VECTOR_NONE) 8402ebaca42Sjeremylt fprintf(stream, "%s No vector\n", pre); 8412ebaca42Sjeremylt 8422ebaca42Sjeremylt return 0; 8432ebaca42Sjeremylt } 8442ebaca42Sjeremylt 8452ebaca42Sjeremylt /** 8462ebaca42Sjeremylt @brief View a single CeedOperator 8472ebaca42Sjeremylt 8482ebaca42Sjeremylt @param[in] op CeedOperator to view 84977645d7bSjeremylt @param[in] sub Boolean flag for sub-operator 8502ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 8512ebaca42Sjeremylt 8522ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 8532ebaca42Sjeremylt 8542ebaca42Sjeremylt @ref Utility 8552ebaca42Sjeremylt **/ 8562ebaca42Sjeremylt int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 8572ebaca42Sjeremylt int ierr; 8582ebaca42Sjeremylt const char *pre = sub ? " " : ""; 8592ebaca42Sjeremylt 8602ebaca42Sjeremylt CeedInt totalfields; 8612ebaca42Sjeremylt ierr = CeedOperatorGetNumArgs(op, &totalfields); CeedChk(ierr); 8622da88da5Sjeremylt 8632ebaca42Sjeremylt fprintf(stream, "%s %d Field%s\n", pre, totalfields, totalfields>1 ? "s" : ""); 8642ebaca42Sjeremylt 8652da88da5Sjeremylt fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->numinputfields, 8662ebaca42Sjeremylt op->qf->numinputfields>1 ? "s" : ""); 8672ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 8682ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->inputfields[i], op->qf->inputfields[i], 8692da88da5Sjeremylt i, sub, 1, stream); CeedChk(ierr); 8702ebaca42Sjeremylt } 8712ebaca42Sjeremylt 8722da88da5Sjeremylt fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->numoutputfields, 8732ebaca42Sjeremylt op->qf->numoutputfields>1 ? "s" : ""); 8742ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 8752ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->outputfields[i], op->qf->inputfields[i], 8762da88da5Sjeremylt i, sub, 0, stream); CeedChk(ierr); 8772ebaca42Sjeremylt } 8782ebaca42Sjeremylt 8792ebaca42Sjeremylt return 0; 8802ebaca42Sjeremylt } 8812ebaca42Sjeremylt 8822ebaca42Sjeremylt /** 8832ebaca42Sjeremylt @brief View a CeedOperator 8842ebaca42Sjeremylt 8852ebaca42Sjeremylt @param[in] op CeedOperator to view 8862ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 8872ebaca42Sjeremylt 8882ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 8892ebaca42Sjeremylt 8902ebaca42Sjeremylt @ref Utility 8912ebaca42Sjeremylt **/ 8922ebaca42Sjeremylt int CeedOperatorView(CeedOperator op, FILE *stream) { 8932ebaca42Sjeremylt int ierr; 8942ebaca42Sjeremylt 8952ebaca42Sjeremylt if (op->composite) { 8962ebaca42Sjeremylt fprintf(stream, "Composite CeedOperator\n"); 8972ebaca42Sjeremylt 8982ebaca42Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 8992da88da5Sjeremylt fprintf(stream, " SubOperator [%d]:\n", i); 9002ebaca42Sjeremylt ierr = CeedOperatorSingleView(op->suboperators[i], 1, stream); 9012ebaca42Sjeremylt CeedChk(ierr); 9022ebaca42Sjeremylt } 9032ebaca42Sjeremylt } else { 9042ebaca42Sjeremylt fprintf(stream, "CeedOperator\n"); 9052ebaca42Sjeremylt ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 9062ebaca42Sjeremylt } 9072ebaca42Sjeremylt 9082ebaca42Sjeremylt return 0; 9092ebaca42Sjeremylt } 9102ebaca42Sjeremylt 9112ebaca42Sjeremylt /** 912d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 913d1bcdac9Sjeremylt 914d1bcdac9Sjeremylt @param op CeedOperator 915d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 916d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 917d1bcdac9Sjeremylt 918d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 919d1bcdac9Sjeremylt 920d1bcdac9Sjeremylt @ref Advanced 921d1bcdac9Sjeremylt **/ 922d1bcdac9Sjeremylt 923692c2638Sjeremylt int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **inputfields, 924d1bcdac9Sjeremylt CeedOperatorField **outputfields) { 92552d6035fSJeremy L Thompson if (op->composite) 926c042f62fSJeremy L Thompson // LCOV_EXCL_START 92752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 928c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 92952d6035fSJeremy L Thompson 930d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 931d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 932d1bcdac9Sjeremylt return 0; 933d1bcdac9Sjeremylt } 934d1bcdac9Sjeremylt 935d1bcdac9Sjeremylt /** 936d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 937d1bcdac9Sjeremylt 938d1bcdac9Sjeremylt @param opfield CeedOperatorField 939d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 940d1bcdac9Sjeremylt 941d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 942d1bcdac9Sjeremylt 943d1bcdac9Sjeremylt @ref Advanced 944d1bcdac9Sjeremylt **/ 945d1bcdac9Sjeremylt 946d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 947d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 948fe2413ffSjeremylt *rstr = opfield->Erestrict; 949d1bcdac9Sjeremylt return 0; 950d1bcdac9Sjeremylt } 951d1bcdac9Sjeremylt 952d1bcdac9Sjeremylt /** 953d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 954d1bcdac9Sjeremylt 955d1bcdac9Sjeremylt @param opfield CeedOperatorField 956d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 957d1bcdac9Sjeremylt 958d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 959d1bcdac9Sjeremylt 960d1bcdac9Sjeremylt @ref Advanced 961d1bcdac9Sjeremylt **/ 962d1bcdac9Sjeremylt 963692c2638Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 964fe2413ffSjeremylt *basis = opfield->basis; 965d1bcdac9Sjeremylt return 0; 966d1bcdac9Sjeremylt } 967d1bcdac9Sjeremylt 968d1bcdac9Sjeremylt /** 969d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 970d1bcdac9Sjeremylt 971d1bcdac9Sjeremylt @param opfield CeedOperatorField 972d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 973d1bcdac9Sjeremylt 974d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 975d1bcdac9Sjeremylt 976d1bcdac9Sjeremylt @ref Advanced 977d1bcdac9Sjeremylt **/ 978d1bcdac9Sjeremylt 979692c2638Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 980fe2413ffSjeremylt *vec = opfield->vec; 981d1bcdac9Sjeremylt return 0; 982d1bcdac9Sjeremylt } 983d1bcdac9Sjeremylt 984d1bcdac9Sjeremylt /** 985b11c1e72Sjeremylt @brief Destroy a CeedOperator 986d7b241e6Sjeremylt 987d7b241e6Sjeremylt @param op CeedOperator to destroy 988b11c1e72Sjeremylt 989b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 990dfdf5a53Sjeremylt 991dfdf5a53Sjeremylt @ref Basic 992b11c1e72Sjeremylt **/ 993d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 994d7b241e6Sjeremylt int ierr; 995d7b241e6Sjeremylt 996d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 997d7b241e6Sjeremylt if ((*op)->Destroy) { 998d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 999d7b241e6Sjeremylt } 1000fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1001fe2413ffSjeremylt // Free fields 10021d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 100352d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 100471352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 100571352a93Sjeremylt CeedChk(ierr); 100671352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 100771352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 100871352a93Sjeremylt } 100971352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 101071352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 101171352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 101271352a93Sjeremylt } 1013fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1014fe2413ffSjeremylt } 10151d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1016d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 101771352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 101871352a93Sjeremylt CeedChk(ierr); 101971352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 102071352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 102171352a93Sjeremylt } 102271352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 102371352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 102471352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 102571352a93Sjeremylt } 1026fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1027fe2413ffSjeremylt } 102852d6035fSJeremy L Thompson // Destroy suboperators 10291d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 103052d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 103152d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 103252d6035fSJeremy L Thompson } 1033d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1034d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1035d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1036fe2413ffSjeremylt 10375107b09fSJeremy L Thompson // Destroy fallback 10385107b09fSJeremy L Thompson if ((*op)->opfallback) { 10395107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 10405107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 10415107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 10425107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 10435107b09fSJeremy L Thompson } 10445107b09fSJeremy L Thompson 1045fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1046fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 104752d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1048d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1049d7b241e6Sjeremylt return 0; 1050d7b241e6Sjeremylt } 1051d7b241e6Sjeremylt 1052d7b241e6Sjeremylt /// @} 1053