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, 149a8d32208Sjeremylt 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); 174*15910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE && op->hasrestriction && 175*15910d16Sjeremylt op->numelements != numelements) 176c042f62fSJeremy L Thompson // LCOV_EXCL_START 177d7b241e6Sjeremylt return CeedError(op->ceed, 1, 1781d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 1791d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 180c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 181*15910d16Sjeremylt if (r != CEED_ELEMRESTRICTION_NONE) { 182d7b241e6Sjeremylt op->numelements = numelements; 1832cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 184*15910d16Sjeremylt } 185d7b241e6Sjeremylt 186783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 187d7b241e6Sjeremylt CeedInt numqpoints; 188d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 189d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 190c042f62fSJeremy L Thompson // LCOV_EXCL_START 1911d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1921d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1931d102b48SJeremy L Thompson op->numqpoints); 194c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 195d7b241e6Sjeremylt op->numqpoints = numqpoints; 196d7b241e6Sjeremylt } 197*15910d16Sjeremylt CeedQFunctionField qfield; 198d1bcdac9Sjeremylt CeedOperatorField *ofield; 199d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 200fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 201*15910d16Sjeremylt qfield = op->qf->inputfields[i]; 202d7b241e6Sjeremylt ofield = &op->inputfields[i]; 203d7b241e6Sjeremylt goto found; 204d7b241e6Sjeremylt } 205d7b241e6Sjeremylt } 206d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 207fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 208*15910d16Sjeremylt qfield = op->qf->inputfields[i]; 209d7b241e6Sjeremylt ofield = &op->outputfields[i]; 210d7b241e6Sjeremylt goto found; 211d7b241e6Sjeremylt } 212d7b241e6Sjeremylt } 213c042f62fSJeremy L Thompson // LCOV_EXCL_START 214d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 215d7b241e6Sjeremylt fieldname); 216c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 217d7b241e6Sjeremylt found: 218*15910d16Sjeremylt if (r == CEED_ELEMRESTRICTION_NONE && qfield->emode != CEED_EVAL_WEIGHT) 219*15910d16Sjeremylt return CeedError(op->ceed, 1, "CEED_ELEMRESTRICTION_NONE can only be used " 220*15910d16Sjeremylt "for a field with eval mode CEED_EVAL_WEIGHT"); 221fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 222fe2413ffSjeremylt (*ofield)->Erestrict = r; 22371352a93Sjeremylt r->refcount += 1; 224fe2413ffSjeremylt (*ofield)->basis = b; 22571352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 22671352a93Sjeremylt b->refcount += 1; 227fe2413ffSjeremylt (*ofield)->vec = v; 22871352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 22971352a93Sjeremylt v->refcount += 1; 230d7b241e6Sjeremylt op->nfields += 1; 231d7b241e6Sjeremylt return 0; 232d7b241e6Sjeremylt } 233d7b241e6Sjeremylt 234d7b241e6Sjeremylt /** 23552d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 236288c0443SJeremy L Thompson 23734138859Sjeremylt @param[out] compositeop Composite CeedOperator 23834138859Sjeremylt @param subop Sub-operator CeedOperator 23952d6035fSJeremy L Thompson 24052d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 24152d6035fSJeremy L Thompson 24252d6035fSJeremy L Thompson @ref Basic 24352d6035fSJeremy L Thompson */ 244692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 24552d6035fSJeremy L Thompson if (!compositeop->composite) 246c042f62fSJeremy L Thompson // LCOV_EXCL_START 2471d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2481d102b48SJeremy L Thompson "operator"); 249c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 25052d6035fSJeremy L Thompson 25152d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 252c042f62fSJeremy L Thompson // LCOV_EXCL_START 2531d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 254c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 25552d6035fSJeremy L Thompson 25652d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 25752d6035fSJeremy L Thompson subop->refcount++; 25852d6035fSJeremy L Thompson compositeop->numsub++; 25952d6035fSJeremy L Thompson return 0; 26052d6035fSJeremy L Thompson } 26152d6035fSJeremy L Thompson 26252d6035fSJeremy L Thompson /** 2635107b09fSJeremy L Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 2645107b09fSJeremy L Thompson CeedOperator functionality 2655107b09fSJeremy L Thompson 2665107b09fSJeremy L Thompson @param op CeedOperator to create fallback for 2675107b09fSJeremy L Thompson 2685107b09fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2695107b09fSJeremy L Thompson 2705107b09fSJeremy L Thompson @ref Developer 2715107b09fSJeremy L Thompson **/ 2725107b09fSJeremy L Thompson int CeedOperatorCreateFallback(CeedOperator op) { 2735107b09fSJeremy L Thompson int ierr; 2745107b09fSJeremy L Thompson 2755107b09fSJeremy L Thompson // Fallback Ceed 2765107b09fSJeremy L Thompson const char *resource, *fallbackresource; 2775107b09fSJeremy L Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 2785107b09fSJeremy L Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 2795107b09fSJeremy L Thompson CeedChk(ierr); 2805107b09fSJeremy L Thompson if (!strcmp(resource, fallbackresource)) 2815107b09fSJeremy L Thompson // LCOV_EXCL_START 2825107b09fSJeremy L Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 2835107b09fSJeremy L Thompson "fallback to resource %s", resource, fallbackresource); 2845107b09fSJeremy L Thompson // LCOV_EXCL_STOP 2855107b09fSJeremy L Thompson 2860ace9bf2Sjeremylt // Fallback Ceed 2875107b09fSJeremy L Thompson Ceed ceedref; 2880ace9bf2Sjeremylt if (!op->ceed->opfallbackceed) { 2895107b09fSJeremy L Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 2905107b09fSJeremy L Thompson ceedref->opfallbackparent = op->ceed; 2915107b09fSJeremy L Thompson op->ceed->opfallbackceed = ceedref; 2920ace9bf2Sjeremylt } 2930ace9bf2Sjeremylt ceedref = op->ceed->opfallbackceed; 2945107b09fSJeremy L Thompson 2955107b09fSJeremy L Thompson // Clone Op 2965107b09fSJeremy L Thompson CeedOperator opref; 2975107b09fSJeremy L Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 2985107b09fSJeremy L Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 2995107b09fSJeremy L Thompson opref->data = NULL; 3005107b09fSJeremy L Thompson opref->setupdone = 0; 3015107b09fSJeremy L Thompson opref->ceed = ceedref; 3025107b09fSJeremy L Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 3035107b09fSJeremy L Thompson op->opfallback = opref; 3045107b09fSJeremy L Thompson 3055107b09fSJeremy L Thompson // Clone QF 3065107b09fSJeremy L Thompson CeedQFunction qfref; 3075107b09fSJeremy L Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 3085107b09fSJeremy L Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 3095107b09fSJeremy L Thompson qfref->data = NULL; 3105107b09fSJeremy L Thompson qfref->ceed = ceedref; 3115107b09fSJeremy L Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 3125107b09fSJeremy L Thompson opref->qf = qfref; 3135107b09fSJeremy L Thompson op->qffallback = qfref; 3145107b09fSJeremy L Thompson 3155107b09fSJeremy L Thompson return 0; 3165107b09fSJeremy L Thompson } 3175107b09fSJeremy L Thompson 3185107b09fSJeremy L Thompson /** 319250756a7Sjeremylt @brief Check if a CeedOperator is ready to be used. 320250756a7Sjeremylt 321250756a7Sjeremylt @param[in] ceed Ceed object for error handling 322250756a7Sjeremylt @param[in] op CeedOperator to check 323250756a7Sjeremylt 324250756a7Sjeremylt @return An error code: 0 - success, otherwise - failure 325250756a7Sjeremylt 326250756a7Sjeremylt @ref Basic 327250756a7Sjeremylt **/ 328250756a7Sjeremylt static int CeedOperatorCheckReady(Ceed ceed, CeedOperator op) { 329250756a7Sjeremylt CeedQFunction qf = op->qf; 330250756a7Sjeremylt 331250756a7Sjeremylt if (op->composite) { 332250756a7Sjeremylt if (!op->numsub) 333250756a7Sjeremylt // LCOV_EXCL_START 334250756a7Sjeremylt return CeedError(ceed, 1, "No suboperators set"); 335250756a7Sjeremylt // LCOV_EXCL_STOP 336250756a7Sjeremylt } else { 337250756a7Sjeremylt if (op->nfields == 0) 338250756a7Sjeremylt // LCOV_EXCL_START 339250756a7Sjeremylt return CeedError(ceed, 1, "No operator fields set"); 340250756a7Sjeremylt // LCOV_EXCL_STOP 341250756a7Sjeremylt if (op->nfields < qf->numinputfields + qf->numoutputfields) 342250756a7Sjeremylt // LCOV_EXCL_START 343250756a7Sjeremylt return CeedError(ceed, 1, "Not all operator fields set"); 344250756a7Sjeremylt // LCOV_EXCL_STOP 345250756a7Sjeremylt if (!op->hasrestriction) 346250756a7Sjeremylt // LCOV_EXCL_START 347250756a7Sjeremylt return CeedError(ceed, 1,"At least one restriction required"); 348250756a7Sjeremylt // LCOV_EXCL_STOP 349250756a7Sjeremylt if (op->numqpoints == 0) 350250756a7Sjeremylt // LCOV_EXCL_START 351250756a7Sjeremylt return CeedError(ceed, 1,"At least one non-collocated basis required"); 352250756a7Sjeremylt // LCOV_EXCL_STOP 353250756a7Sjeremylt } 354250756a7Sjeremylt 355250756a7Sjeremylt return 0; 356250756a7Sjeremylt } 357250756a7Sjeremylt 358250756a7Sjeremylt /** 3591d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 3601d102b48SJeremy L Thompson 3611d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 3621d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 3631d102b48SJeremy L Thompson The vector 'assembled' is of shape 3641d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 3651d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 3661d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 3671d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 3681d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 3691d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 3701d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 3711d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 3721d102b48SJeremy L Thompson 3731d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 3741d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 3751d102b48SJeremy L Thompson quadrature points 3761d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 3771d102b48SJeremy L Thompson CeedQFunction 3781d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 3791d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 3801d102b48SJeremy L Thompson 3811d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3821d102b48SJeremy L Thompson 383b7ec98d8SJeremy L Thompson @ref Basic 3841d102b48SJeremy L Thompson **/ 3851d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 3867f823360Sjeremylt CeedElemRestriction *rstr, 3877f823360Sjeremylt CeedRequest *request) { 3881d102b48SJeremy L Thompson int ierr; 3891d102b48SJeremy L Thompson Ceed ceed = op->ceed; 390250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 3911d102b48SJeremy L Thompson 3927172caadSjeremylt // Backend version 3935107b09fSJeremy L Thompson if (op->AssembleLinearQFunction) { 3941d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3951d102b48SJeremy L Thompson CeedChk(ierr); 3965107b09fSJeremy L Thompson } else { 3975107b09fSJeremy L Thompson // Fallback to reference Ceed 3985107b09fSJeremy L Thompson if (!op->opfallback) { 3995107b09fSJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 4005107b09fSJeremy L Thompson } 4015107b09fSJeremy L Thompson // Assemble 4025107b09fSJeremy L Thompson ierr = op->opfallback->AssembleLinearQFunction(op->opfallback, assembled, 4035107b09fSJeremy L Thompson rstr, request); CeedChk(ierr); 4045107b09fSJeremy L Thompson } 405250756a7Sjeremylt 4061d102b48SJeremy L Thompson return 0; 4071d102b48SJeremy L Thompson } 4081d102b48SJeremy L Thompson 4091d102b48SJeremy L Thompson /** 410b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 411b7ec98d8SJeremy L Thompson 412b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 413b7ec98d8SJeremy L Thompson 414b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 415b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 416b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 417b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 418b7ec98d8SJeremy L Thompson 419b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 420b7ec98d8SJeremy L Thompson 421b7ec98d8SJeremy L Thompson @ref Basic 422b7ec98d8SJeremy L Thompson **/ 4237f823360Sjeremylt int CeedOperatorAssembleLinearDiagonal(CeedOperator op, CeedVector *assembled, 4247f823360Sjeremylt CeedRequest *request) { 425b7ec98d8SJeremy L Thompson int ierr; 426b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 427250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 428b7ec98d8SJeremy L Thompson 429b7ec98d8SJeremy L Thompson // Use backend version, if available 430b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 431b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 4327172caadSjeremylt } else { 4337172caadSjeremylt // Fallback to reference Ceed 4347172caadSjeremylt if (!op->opfallback) { 4357172caadSjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 436b7ec98d8SJeremy L Thompson } 4377172caadSjeremylt // Assemble 4387172caadSjeremylt ierr = op->opfallback->AssembleLinearDiagonal(op->opfallback, assembled, 4397172caadSjeremylt request); CeedChk(ierr); 440b7ec98d8SJeremy L Thompson } 441b7ec98d8SJeremy L Thompson 442b7ec98d8SJeremy L Thompson return 0; 443b7ec98d8SJeremy L Thompson } 444b7ec98d8SJeremy L Thompson 445b7ec98d8SJeremy L Thompson /** 4463bd813ffSjeremylt @brief Build a FDM based approximate inverse for each element for a 4473bd813ffSjeremylt CeedOperator 4483bd813ffSjeremylt 4493bd813ffSjeremylt This returns a CeedOperator and CeedVector to apply a Fast Diagonalization 4503bd813ffSjeremylt Method based approximate inverse. This function obtains the simultaneous 4513bd813ffSjeremylt diagonalization for the 1D mass and Laplacian operators, 4523bd813ffSjeremylt M = V^T V, K = V^T S V. 4533bd813ffSjeremylt The assembled QFunction is used to modify the eigenvalues from simultaneous 4543bd813ffSjeremylt diagonalization and obtain an approximate inverse of the form 4553bd813ffSjeremylt V^T S^hat V. The CeedOperator must be linear and non-composite. The 4563bd813ffSjeremylt associated CeedQFunction must therefore also be linear. 4573bd813ffSjeremylt 4583bd813ffSjeremylt @param op CeedOperator to create element inverses 4593bd813ffSjeremylt @param[out] fdminv CeedOperator to apply the action of a FDM based inverse 4603bd813ffSjeremylt for each element 4613bd813ffSjeremylt @param request Address of CeedRequest for non-blocking completion, else 4623bd813ffSjeremylt CEED_REQUEST_IMMEDIATE 4633bd813ffSjeremylt 4643bd813ffSjeremylt @return An error code: 0 - success, otherwise - failure 4653bd813ffSjeremylt 4663bd813ffSjeremylt @ref Advanced 4673bd813ffSjeremylt **/ 4683bd813ffSjeremylt int CeedOperatorCreateFDMElementInverse(CeedOperator op, CeedOperator *fdminv, 4693bd813ffSjeremylt CeedRequest *request) { 4703bd813ffSjeremylt int ierr; 4713bd813ffSjeremylt Ceed ceed = op->ceed; 472713f43c3Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 4733bd813ffSjeremylt 474713f43c3Sjeremylt // Use backend version, if available 475713f43c3Sjeremylt if (op->CreateFDMElementInverse) { 476713f43c3Sjeremylt ierr = op->CreateFDMElementInverse(op, fdminv, request); CeedChk(ierr); 477713f43c3Sjeremylt } else { 478713f43c3Sjeremylt // Fallback to reference Ceed 479713f43c3Sjeremylt if (!op->opfallback) { 480713f43c3Sjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 4813bd813ffSjeremylt } 482713f43c3Sjeremylt // Assemble 483713f43c3Sjeremylt ierr = op->opfallback->CreateFDMElementInverse(op->opfallback, fdminv, 4843bd813ffSjeremylt request); CeedChk(ierr); 4853bd813ffSjeremylt } 4863bd813ffSjeremylt 4873bd813ffSjeremylt return 0; 4883bd813ffSjeremylt } 4893bd813ffSjeremylt 4903bd813ffSjeremylt 4913bd813ffSjeremylt /** 4923bd813ffSjeremylt @brief Apply CeedOperator to a vector 493d7b241e6Sjeremylt 494d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 495d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 496d7b241e6Sjeremylt CeedOperatorSetField(). 497d7b241e6Sjeremylt 498d7b241e6Sjeremylt @param op CeedOperator to apply 49934138859Sjeremylt @param[in] in CeedVector containing input state or CEED_VECTOR_NONE if 50034138859Sjeremylt there are no active inputs 501b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 50234138859Sjeremylt distinct from @a in) or CEED_VECTOR_NONE if there are no 50334138859Sjeremylt active outputs 504d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 505d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 506b11c1e72Sjeremylt 507b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 508dfdf5a53Sjeremylt 509dfdf5a53Sjeremylt @ref Basic 510b11c1e72Sjeremylt **/ 511692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 512692c2638Sjeremylt CeedRequest *request) { 513d7b241e6Sjeremylt int ierr; 514d7b241e6Sjeremylt Ceed ceed = op->ceed; 515250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 516d7b241e6Sjeremylt 517250756a7Sjeremylt if (op->numelements) { 518250756a7Sjeremylt // Standard Operator 519cae8b89aSjeremylt if (op->Apply) { 520250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 521cae8b89aSjeremylt } else { 522cae8b89aSjeremylt // Zero all output vectors 523250756a7Sjeremylt CeedQFunction qf = op->qf; 524cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 525cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 526cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 527cae8b89aSjeremylt vec = out; 528cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 529cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 530cae8b89aSjeremylt } 531cae8b89aSjeremylt } 532250756a7Sjeremylt // Apply 533250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 534250756a7Sjeremylt } 535250756a7Sjeremylt } else if (op->composite) { 536250756a7Sjeremylt // Composite Operator 537250756a7Sjeremylt if (op->ApplyComposite) { 538250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 539250756a7Sjeremylt } else { 540250756a7Sjeremylt CeedInt numsub; 541250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 542250756a7Sjeremylt CeedOperator *suboperators; 543250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 544250756a7Sjeremylt 545250756a7Sjeremylt // Zero all output vectors 546250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 547cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 548cae8b89aSjeremylt } 549250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 550250756a7Sjeremylt for (CeedInt j=0; j<suboperators[i]->qf->numoutputfields; j++) { 551250756a7Sjeremylt CeedVector vec = suboperators[i]->outputfields[j]->vec; 552250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 553250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 554250756a7Sjeremylt } 555250756a7Sjeremylt } 556250756a7Sjeremylt } 557250756a7Sjeremylt // Apply 558250756a7Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 559250756a7Sjeremylt ierr = CeedOperatorApplyAdd(op->suboperators[i], in, out, request); 560cae8b89aSjeremylt CeedChk(ierr); 561cae8b89aSjeremylt } 562cae8b89aSjeremylt } 563250756a7Sjeremylt } 564250756a7Sjeremylt 565cae8b89aSjeremylt return 0; 566cae8b89aSjeremylt } 567cae8b89aSjeremylt 568cae8b89aSjeremylt /** 569cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 570cae8b89aSjeremylt 571cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 572cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 573cae8b89aSjeremylt CeedOperatorSetField(). 574cae8b89aSjeremylt 575cae8b89aSjeremylt @param op CeedOperator to apply 576cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 577cae8b89aSjeremylt active inputs 578cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 579cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 580cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 581cae8b89aSjeremylt CEED_REQUEST_IMMEDIATE 582cae8b89aSjeremylt 583cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 584cae8b89aSjeremylt 585cae8b89aSjeremylt @ref Basic 586cae8b89aSjeremylt **/ 587cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 588cae8b89aSjeremylt CeedRequest *request) { 589cae8b89aSjeremylt int ierr; 590cae8b89aSjeremylt Ceed ceed = op->ceed; 591250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 592cae8b89aSjeremylt 593250756a7Sjeremylt if (op->numelements) { 594250756a7Sjeremylt // Standard Operator 595250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 596250756a7Sjeremylt } else if (op->composite) { 597250756a7Sjeremylt // Composite Operator 598250756a7Sjeremylt if (op->ApplyAddComposite) { 599250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 600cae8b89aSjeremylt } else { 601250756a7Sjeremylt CeedInt numsub; 602250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 603250756a7Sjeremylt CeedOperator *suboperators; 604250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 605250756a7Sjeremylt 606250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 607250756a7Sjeremylt ierr = CeedOperatorApplyAdd(suboperators[i], in, out, request); 608cae8b89aSjeremylt CeedChk(ierr); 6091d7d2407SJeremy L Thompson } 610250756a7Sjeremylt } 611250756a7Sjeremylt } 612250756a7Sjeremylt 613d7b241e6Sjeremylt return 0; 614d7b241e6Sjeremylt } 615d7b241e6Sjeremylt 616d7b241e6Sjeremylt /** 6174ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 6184ce2993fSjeremylt 6194ce2993fSjeremylt @param op CeedOperator 6204ce2993fSjeremylt @param[out] ceed Variable to store Ceed 6214ce2993fSjeremylt 6224ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6234ce2993fSjeremylt 62423617272Sjeremylt @ref Advanced 6254ce2993fSjeremylt **/ 6264ce2993fSjeremylt 6274ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 6284ce2993fSjeremylt *ceed = op->ceed; 6294ce2993fSjeremylt return 0; 6304ce2993fSjeremylt } 6314ce2993fSjeremylt 6324ce2993fSjeremylt /** 6334ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 6344ce2993fSjeremylt 6354ce2993fSjeremylt @param op CeedOperator 6364ce2993fSjeremylt @param[out] numelem Variable to store number of elements 6374ce2993fSjeremylt 6384ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6394ce2993fSjeremylt 64023617272Sjeremylt @ref Advanced 6414ce2993fSjeremylt **/ 6424ce2993fSjeremylt 6434ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 64452d6035fSJeremy L Thompson if (op->composite) 645c042f62fSJeremy L Thompson // LCOV_EXCL_START 64652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 647c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 64852d6035fSJeremy L Thompson 6494ce2993fSjeremylt *numelem = op->numelements; 6504ce2993fSjeremylt return 0; 6514ce2993fSjeremylt } 6524ce2993fSjeremylt 6534ce2993fSjeremylt /** 6544ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 6554ce2993fSjeremylt 6564ce2993fSjeremylt @param op CeedOperator 6574ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 6584ce2993fSjeremylt 6594ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6604ce2993fSjeremylt 66123617272Sjeremylt @ref Advanced 6624ce2993fSjeremylt **/ 6634ce2993fSjeremylt 6644ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 66552d6035fSJeremy L Thompson if (op->composite) 666c042f62fSJeremy L Thompson // LCOV_EXCL_START 66752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 668c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 66952d6035fSJeremy L Thompson 6704ce2993fSjeremylt *numqpts = op->numqpoints; 6714ce2993fSjeremylt return 0; 6724ce2993fSjeremylt } 6734ce2993fSjeremylt 6744ce2993fSjeremylt /** 6754ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 6764ce2993fSjeremylt 6774ce2993fSjeremylt @param op CeedOperator 6784ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 6794ce2993fSjeremylt 6804ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6814ce2993fSjeremylt 68223617272Sjeremylt @ref Advanced 6834ce2993fSjeremylt **/ 6844ce2993fSjeremylt 6854ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 68652d6035fSJeremy L Thompson if (op->composite) 687c042f62fSJeremy L Thompson // LCOV_EXCL_START 68852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 689c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 690c042f62fSJeremy L Thompson 6914ce2993fSjeremylt *numargs = op->nfields; 6924ce2993fSjeremylt return 0; 6934ce2993fSjeremylt } 6944ce2993fSjeremylt 6954ce2993fSjeremylt /** 6964ce2993fSjeremylt @brief Get the setup status of a CeedOperator 6974ce2993fSjeremylt 6984ce2993fSjeremylt @param op CeedOperator 699288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 7004ce2993fSjeremylt 7014ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7024ce2993fSjeremylt 70323617272Sjeremylt @ref Advanced 7044ce2993fSjeremylt **/ 7054ce2993fSjeremylt 7064ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 7074ce2993fSjeremylt *setupdone = op->setupdone; 7084ce2993fSjeremylt return 0; 7094ce2993fSjeremylt } 7104ce2993fSjeremylt 7114ce2993fSjeremylt /** 7124ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 7134ce2993fSjeremylt 7144ce2993fSjeremylt @param op CeedOperator 7158c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 7164ce2993fSjeremylt 7174ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7184ce2993fSjeremylt 71923617272Sjeremylt @ref Advanced 7204ce2993fSjeremylt **/ 7214ce2993fSjeremylt 7224ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 72352d6035fSJeremy L Thompson if (op->composite) 724c042f62fSJeremy L Thompson // LCOV_EXCL_START 72552d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 726c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 72752d6035fSJeremy L Thompson 7284ce2993fSjeremylt *qf = op->qf; 7294ce2993fSjeremylt return 0; 7304ce2993fSjeremylt } 7314ce2993fSjeremylt 7324ce2993fSjeremylt /** 73352d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 73452d6035fSJeremy L Thompson 73552d6035fSJeremy L Thompson @param op CeedOperator 73652d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 73752d6035fSJeremy L Thompson 73852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 73952d6035fSJeremy L Thompson 74052d6035fSJeremy L Thompson @ref Advanced 74152d6035fSJeremy L Thompson **/ 74252d6035fSJeremy L Thompson 74352d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 744c042f62fSJeremy L Thompson if (!op->composite) 745c042f62fSJeremy L Thompson // LCOV_EXCL_START 746c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 747c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 74852d6035fSJeremy L Thompson 74952d6035fSJeremy L Thompson *numsub = op->numsub; 75052d6035fSJeremy L Thompson return 0; 75152d6035fSJeremy L Thompson } 75252d6035fSJeremy L Thompson 75352d6035fSJeremy L Thompson /** 75452d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 75552d6035fSJeremy L Thompson 75652d6035fSJeremy L Thompson @param op CeedOperator 75752d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 75852d6035fSJeremy L Thompson 75952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 76052d6035fSJeremy L Thompson 76152d6035fSJeremy L Thompson @ref Advanced 76252d6035fSJeremy L Thompson **/ 76352d6035fSJeremy L Thompson 76452d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 765c042f62fSJeremy L Thompson if (!op->composite) 766c042f62fSJeremy L Thompson // LCOV_EXCL_START 767c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 768c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 76952d6035fSJeremy L Thompson 77052d6035fSJeremy L Thompson *suboperators = op->suboperators; 77152d6035fSJeremy L Thompson return 0; 77252d6035fSJeremy L Thompson } 77352d6035fSJeremy L Thompson 77452d6035fSJeremy L Thompson /** 775fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 776fe2413ffSjeremylt 777fe2413ffSjeremylt @param[out] op CeedOperator 778fe2413ffSjeremylt @param data Data to set 779fe2413ffSjeremylt 780fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 781fe2413ffSjeremylt 782fe2413ffSjeremylt @ref Advanced 783fe2413ffSjeremylt **/ 784fe2413ffSjeremylt 785fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void **data) { 786fe2413ffSjeremylt op->data = *data; 787fe2413ffSjeremylt return 0; 788fe2413ffSjeremylt } 789fe2413ffSjeremylt 790fe2413ffSjeremylt /** 7914ce2993fSjeremylt @brief Get the backend data of a CeedOperator 7924ce2993fSjeremylt 7934ce2993fSjeremylt @param op CeedOperator 7944ce2993fSjeremylt @param[out] data Variable to store data 7954ce2993fSjeremylt 7964ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7974ce2993fSjeremylt 79823617272Sjeremylt @ref Advanced 7994ce2993fSjeremylt **/ 8004ce2993fSjeremylt 8014ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void **data) { 8024ce2993fSjeremylt *data = op->data; 8034ce2993fSjeremylt return 0; 8044ce2993fSjeremylt } 8054ce2993fSjeremylt 8064ce2993fSjeremylt /** 8074ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 8084ce2993fSjeremylt 8094ce2993fSjeremylt @param op CeedOperator 8104ce2993fSjeremylt 8114ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 8124ce2993fSjeremylt 81323617272Sjeremylt @ref Advanced 8144ce2993fSjeremylt **/ 8154ce2993fSjeremylt 8164ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 8174ce2993fSjeremylt op->setupdone = 1; 8184ce2993fSjeremylt return 0; 8194ce2993fSjeremylt } 8204ce2993fSjeremylt 8214ce2993fSjeremylt /** 8222ebaca42Sjeremylt @brief View a field of a CeedOperator 8232ebaca42Sjeremylt 8242ebaca42Sjeremylt @param[in] field Operator field to view 8252ebaca42Sjeremylt @param[in] fieldnumber Number of field being viewed 8262ebaca42Sjeremylt @param[in] stream Stream to view to, e.g., stdout 8272ebaca42Sjeremylt 8282ebaca42Sjeremylt @return An error code: 0 - success, otherwise - failure 8292ebaca42Sjeremylt 8302ebaca42Sjeremylt @ref Utility 8312ebaca42Sjeremylt **/ 8322ebaca42Sjeremylt static int CeedOperatorFieldView(CeedOperatorField field, 8332ebaca42Sjeremylt CeedQFunctionField qffield, 8342da88da5Sjeremylt CeedInt fieldnumber, bool sub, bool in, 8352da88da5Sjeremylt FILE *stream) { 8362ebaca42Sjeremylt const char *pre = sub ? " " : ""; 8372da88da5Sjeremylt const char *inout = in ? "Input" : "Output"; 8382ebaca42Sjeremylt 8392da88da5Sjeremylt fprintf(stream, "%s %s Field [%d]:\n" 840a8d32208Sjeremylt "%s Name: \"%s\"\n", 841a8d32208Sjeremylt pre, inout, fieldnumber, pre, qffield->fieldname); 8422ebaca42Sjeremylt 8432ebaca42Sjeremylt if (field->basis == CEED_BASIS_COLLOCATED) 8442ebaca42Sjeremylt fprintf(stream, "%s Collocated basis\n", pre); 8452ebaca42Sjeremylt 8462ebaca42Sjeremylt if (field->vec == CEED_VECTOR_ACTIVE) 8472ebaca42Sjeremylt fprintf(stream, "%s Active vector\n", pre); 8482ebaca42Sjeremylt else if (field->vec == CEED_VECTOR_NONE) 8492ebaca42Sjeremylt fprintf(stream, "%s No vector\n", pre); 8502ebaca42Sjeremylt 8512ebaca42Sjeremylt return 0; 8522ebaca42Sjeremylt } 8532ebaca42Sjeremylt 8542ebaca42Sjeremylt /** 8552ebaca42Sjeremylt @brief View a single CeedOperator 8562ebaca42Sjeremylt 8572ebaca42Sjeremylt @param[in] op CeedOperator to view 85877645d7bSjeremylt @param[in] sub Boolean flag for sub-operator 8592ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 8602ebaca42Sjeremylt 8612ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 8622ebaca42Sjeremylt 8632ebaca42Sjeremylt @ref Utility 8642ebaca42Sjeremylt **/ 8652ebaca42Sjeremylt int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 8662ebaca42Sjeremylt int ierr; 8672ebaca42Sjeremylt const char *pre = sub ? " " : ""; 8682ebaca42Sjeremylt 8692ebaca42Sjeremylt CeedInt totalfields; 8702ebaca42Sjeremylt ierr = CeedOperatorGetNumArgs(op, &totalfields); CeedChk(ierr); 8712da88da5Sjeremylt 8722ebaca42Sjeremylt fprintf(stream, "%s %d Field%s\n", pre, totalfields, totalfields>1 ? "s" : ""); 8732ebaca42Sjeremylt 8742da88da5Sjeremylt fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->numinputfields, 8752ebaca42Sjeremylt op->qf->numinputfields>1 ? "s" : ""); 8762ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 8772ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->inputfields[i], op->qf->inputfields[i], 8782da88da5Sjeremylt i, sub, 1, stream); CeedChk(ierr); 8792ebaca42Sjeremylt } 8802ebaca42Sjeremylt 8812da88da5Sjeremylt fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->numoutputfields, 8822ebaca42Sjeremylt op->qf->numoutputfields>1 ? "s" : ""); 8832ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 8842ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->outputfields[i], op->qf->inputfields[i], 8852da88da5Sjeremylt i, sub, 0, stream); CeedChk(ierr); 8862ebaca42Sjeremylt } 8872ebaca42Sjeremylt 8882ebaca42Sjeremylt return 0; 8892ebaca42Sjeremylt } 8902ebaca42Sjeremylt 8912ebaca42Sjeremylt /** 8922ebaca42Sjeremylt @brief View a CeedOperator 8932ebaca42Sjeremylt 8942ebaca42Sjeremylt @param[in] op CeedOperator to view 8952ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 8962ebaca42Sjeremylt 8972ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 8982ebaca42Sjeremylt 8992ebaca42Sjeremylt @ref Utility 9002ebaca42Sjeremylt **/ 9012ebaca42Sjeremylt int CeedOperatorView(CeedOperator op, FILE *stream) { 9022ebaca42Sjeremylt int ierr; 9032ebaca42Sjeremylt 9042ebaca42Sjeremylt if (op->composite) { 9052ebaca42Sjeremylt fprintf(stream, "Composite CeedOperator\n"); 9062ebaca42Sjeremylt 9072ebaca42Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 9082da88da5Sjeremylt fprintf(stream, " SubOperator [%d]:\n", i); 9092ebaca42Sjeremylt ierr = CeedOperatorSingleView(op->suboperators[i], 1, stream); 9102ebaca42Sjeremylt CeedChk(ierr); 9112ebaca42Sjeremylt } 9122ebaca42Sjeremylt } else { 9132ebaca42Sjeremylt fprintf(stream, "CeedOperator\n"); 9142ebaca42Sjeremylt ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 9152ebaca42Sjeremylt } 9162ebaca42Sjeremylt 9172ebaca42Sjeremylt return 0; 9182ebaca42Sjeremylt } 9192ebaca42Sjeremylt 9202ebaca42Sjeremylt /** 921d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 922d1bcdac9Sjeremylt 923d1bcdac9Sjeremylt @param op CeedOperator 924d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 925d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 926d1bcdac9Sjeremylt 927d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 928d1bcdac9Sjeremylt 929d1bcdac9Sjeremylt @ref Advanced 930d1bcdac9Sjeremylt **/ 931d1bcdac9Sjeremylt 932692c2638Sjeremylt int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **inputfields, 933d1bcdac9Sjeremylt CeedOperatorField **outputfields) { 93452d6035fSJeremy L Thompson if (op->composite) 935c042f62fSJeremy L Thompson // LCOV_EXCL_START 93652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 937c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 93852d6035fSJeremy L Thompson 939d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 940d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 941d1bcdac9Sjeremylt return 0; 942d1bcdac9Sjeremylt } 943d1bcdac9Sjeremylt 944d1bcdac9Sjeremylt /** 945d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 946d1bcdac9Sjeremylt 947d1bcdac9Sjeremylt @param opfield CeedOperatorField 948d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 949d1bcdac9Sjeremylt 950d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 951d1bcdac9Sjeremylt 952d1bcdac9Sjeremylt @ref Advanced 953d1bcdac9Sjeremylt **/ 954d1bcdac9Sjeremylt 955d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 956d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 957fe2413ffSjeremylt *rstr = opfield->Erestrict; 958d1bcdac9Sjeremylt return 0; 959d1bcdac9Sjeremylt } 960d1bcdac9Sjeremylt 961d1bcdac9Sjeremylt /** 962d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 963d1bcdac9Sjeremylt 964d1bcdac9Sjeremylt @param opfield CeedOperatorField 965d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 966d1bcdac9Sjeremylt 967d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 968d1bcdac9Sjeremylt 969d1bcdac9Sjeremylt @ref Advanced 970d1bcdac9Sjeremylt **/ 971d1bcdac9Sjeremylt 972692c2638Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 973fe2413ffSjeremylt *basis = opfield->basis; 974d1bcdac9Sjeremylt return 0; 975d1bcdac9Sjeremylt } 976d1bcdac9Sjeremylt 977d1bcdac9Sjeremylt /** 978d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 979d1bcdac9Sjeremylt 980d1bcdac9Sjeremylt @param opfield CeedOperatorField 981d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 982d1bcdac9Sjeremylt 983d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 984d1bcdac9Sjeremylt 985d1bcdac9Sjeremylt @ref Advanced 986d1bcdac9Sjeremylt **/ 987d1bcdac9Sjeremylt 988692c2638Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 989fe2413ffSjeremylt *vec = opfield->vec; 990d1bcdac9Sjeremylt return 0; 991d1bcdac9Sjeremylt } 992d1bcdac9Sjeremylt 993d1bcdac9Sjeremylt /** 994b11c1e72Sjeremylt @brief Destroy a CeedOperator 995d7b241e6Sjeremylt 996d7b241e6Sjeremylt @param op CeedOperator to destroy 997b11c1e72Sjeremylt 998b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 999dfdf5a53Sjeremylt 1000dfdf5a53Sjeremylt @ref Basic 1001b11c1e72Sjeremylt **/ 1002d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1003d7b241e6Sjeremylt int ierr; 1004d7b241e6Sjeremylt 1005d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 1006d7b241e6Sjeremylt if ((*op)->Destroy) { 1007d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1008d7b241e6Sjeremylt } 1009fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1010fe2413ffSjeremylt // Free fields 10111d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 101252d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 1013*15910d16Sjeremylt if ((*op)->inputfields[i]->Erestrict != CEED_ELEMRESTRICTION_NONE) { 101471352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 101571352a93Sjeremylt CeedChk(ierr); 1016*15910d16Sjeremylt } 101771352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 101871352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 101971352a93Sjeremylt } 102071352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 102171352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 102271352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 102371352a93Sjeremylt } 1024fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1025fe2413ffSjeremylt } 10261d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1027d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 102871352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 102971352a93Sjeremylt CeedChk(ierr); 103071352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 103171352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 103271352a93Sjeremylt } 103371352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 103471352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 103571352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 103671352a93Sjeremylt } 1037fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1038fe2413ffSjeremylt } 103952d6035fSJeremy L Thompson // Destroy suboperators 10401d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 104152d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 104252d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 104352d6035fSJeremy L Thompson } 1044d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1045d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1046d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1047fe2413ffSjeremylt 10485107b09fSJeremy L Thompson // Destroy fallback 10495107b09fSJeremy L Thompson if ((*op)->opfallback) { 10505107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 10515107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 10525107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 10535107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 10545107b09fSJeremy L Thompson } 10555107b09fSJeremy L Thompson 1056fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1057fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 105852d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1059d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1060d7b241e6Sjeremylt return 0; 1061d7b241e6Sjeremylt } 1062d7b241e6Sjeremylt 1063d7b241e6Sjeremylt /// @} 1064