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 138b0e29e78Sjeremylt @param lmode CeedTransposeMode which specifies the ordering of the 139b0e29e78Sjeremylt components of the l-vector used by this CeedOperatorField, 140b0e29e78Sjeremylt CEED_NOTRANSPOSE indicates the component is the 141b0e29e78Sjeremylt outermost index and CEED_TRANSPOSE indicates the component 142b0e29e78Sjeremylt is the innermost index in ordering of the l-vector 143783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 144b11c1e72Sjeremylt if collocated with quadrature points 145b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 146b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 1478c91a0c9SJeremy L Thompson CEED_EVAL_WEIGHT in the QFunction 148b11c1e72Sjeremylt 149b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 150dfdf5a53Sjeremylt 151dfdf5a53Sjeremylt @ref Basic 152b11c1e72Sjeremylt **/ 153d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 1544dccadb6Sjeremylt CeedElemRestriction r, CeedTransposeMode lmode, 1554dccadb6Sjeremylt CeedBasis b, CeedVector v) { 156d7b241e6Sjeremylt int ierr; 15752d6035fSJeremy L Thompson if (op->composite) 158c042f62fSJeremy L Thompson // LCOV_EXCL_START 15952d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 160c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1618b067b84SJed Brown if (!r) 162c042f62fSJeremy L Thompson // LCOV_EXCL_START 163c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 164c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 165c042f62fSJeremy L Thompson fieldname); 166c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1678b067b84SJed Brown if (!b) 168c042f62fSJeremy L Thompson // LCOV_EXCL_START 169c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 170c042f62fSJeremy L Thompson fieldname); 171c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1728b067b84SJed Brown if (!v) 173c042f62fSJeremy L Thompson // LCOV_EXCL_START 174c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 175c042f62fSJeremy L Thompson fieldname); 176c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 17752d6035fSJeremy L Thompson 178d7b241e6Sjeremylt CeedInt numelements; 179d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 1802cb0afc5Sjeremylt if (op->hasrestriction && op->numelements != numelements) 181c042f62fSJeremy L Thompson // LCOV_EXCL_START 182d7b241e6Sjeremylt return CeedError(op->ceed, 1, 1831d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 1841d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 185c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 186d7b241e6Sjeremylt op->numelements = numelements; 1872cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 188d7b241e6Sjeremylt 189783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 190d7b241e6Sjeremylt CeedInt numqpoints; 191d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 192d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 193c042f62fSJeremy L Thompson // LCOV_EXCL_START 1941d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1951d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1961d102b48SJeremy L Thompson op->numqpoints); 197c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 198d7b241e6Sjeremylt op->numqpoints = numqpoints; 199d7b241e6Sjeremylt } 200d1bcdac9Sjeremylt CeedOperatorField *ofield; 201d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 202fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 203d7b241e6Sjeremylt ofield = &op->inputfields[i]; 204d7b241e6Sjeremylt goto found; 205d7b241e6Sjeremylt } 206d7b241e6Sjeremylt } 207d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 208fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 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: 218fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 219fe2413ffSjeremylt (*ofield)->Erestrict = r; 22071352a93Sjeremylt r->refcount += 1; 221fe2413ffSjeremylt (*ofield)->lmode = lmode; 222fe2413ffSjeremylt (*ofield)->basis = b; 22371352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 22471352a93Sjeremylt b->refcount += 1; 225fe2413ffSjeremylt (*ofield)->vec = v; 22671352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 22771352a93Sjeremylt v->refcount += 1; 228d7b241e6Sjeremylt op->nfields += 1; 229d7b241e6Sjeremylt return 0; 230d7b241e6Sjeremylt } 231d7b241e6Sjeremylt 232d7b241e6Sjeremylt /** 23352d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 234288c0443SJeremy L Thompson 23534138859Sjeremylt @param[out] compositeop Composite CeedOperator 23634138859Sjeremylt @param subop Sub-operator CeedOperator 23752d6035fSJeremy L Thompson 23852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23952d6035fSJeremy L Thompson 24052d6035fSJeremy L Thompson @ref Basic 24152d6035fSJeremy L Thompson */ 242692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 24352d6035fSJeremy L Thompson if (!compositeop->composite) 244c042f62fSJeremy L Thompson // LCOV_EXCL_START 2451d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2461d102b48SJeremy L Thompson "operator"); 247c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24852d6035fSJeremy L Thompson 24952d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 250c042f62fSJeremy L Thompson // LCOV_EXCL_START 2511d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 252c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 25352d6035fSJeremy L Thompson 25452d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 25552d6035fSJeremy L Thompson subop->refcount++; 25652d6035fSJeremy L Thompson compositeop->numsub++; 25752d6035fSJeremy L Thompson return 0; 25852d6035fSJeremy L Thompson } 25952d6035fSJeremy L Thompson 26052d6035fSJeremy L Thompson /** 2615107b09fSJeremy L Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 2625107b09fSJeremy L Thompson CeedOperator functionality 2635107b09fSJeremy L Thompson 2645107b09fSJeremy L Thompson @param op CeedOperator to create fallback for 2655107b09fSJeremy L Thompson 2665107b09fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2675107b09fSJeremy L Thompson 2685107b09fSJeremy L Thompson @ref Developer 2695107b09fSJeremy L Thompson **/ 2705107b09fSJeremy L Thompson int CeedOperatorCreateFallback(CeedOperator op) { 2715107b09fSJeremy L Thompson int ierr; 2725107b09fSJeremy L Thompson 2735107b09fSJeremy L Thompson // Fallback Ceed 2745107b09fSJeremy L Thompson const char *resource, *fallbackresource; 2755107b09fSJeremy L Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 2765107b09fSJeremy L Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 2775107b09fSJeremy L Thompson CeedChk(ierr); 2785107b09fSJeremy L Thompson if (!strcmp(resource, fallbackresource)) 2795107b09fSJeremy L Thompson // LCOV_EXCL_START 2805107b09fSJeremy L Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 2815107b09fSJeremy L Thompson "fallback to resource %s", resource, fallbackresource); 2825107b09fSJeremy L Thompson // LCOV_EXCL_STOP 2835107b09fSJeremy L Thompson 284*0ace9bf2Sjeremylt // Fallback Ceed 2855107b09fSJeremy L Thompson Ceed ceedref; 286*0ace9bf2Sjeremylt if (!op->ceed->opfallbackceed) { 2875107b09fSJeremy L Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 2885107b09fSJeremy L Thompson ceedref->opfallbackparent = op->ceed; 2895107b09fSJeremy L Thompson op->ceed->opfallbackceed = ceedref; 290*0ace9bf2Sjeremylt } 291*0ace9bf2Sjeremylt ceedref = op->ceed->opfallbackceed; 2925107b09fSJeremy L Thompson 2935107b09fSJeremy L Thompson // Clone Op 2945107b09fSJeremy L Thompson CeedOperator opref; 2955107b09fSJeremy L Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 2965107b09fSJeremy L Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 2975107b09fSJeremy L Thompson opref->data = NULL; 2985107b09fSJeremy L Thompson opref->setupdone = 0; 2995107b09fSJeremy L Thompson opref->ceed = ceedref; 3005107b09fSJeremy L Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 3015107b09fSJeremy L Thompson op->opfallback = opref; 3025107b09fSJeremy L Thompson 3035107b09fSJeremy L Thompson // Clone QF 3045107b09fSJeremy L Thompson CeedQFunction qfref; 3055107b09fSJeremy L Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 3065107b09fSJeremy L Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 3075107b09fSJeremy L Thompson qfref->data = NULL; 3085107b09fSJeremy L Thompson qfref->ceed = ceedref; 3095107b09fSJeremy L Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 3105107b09fSJeremy L Thompson opref->qf = qfref; 3115107b09fSJeremy L Thompson op->qffallback = qfref; 3125107b09fSJeremy L Thompson 3135107b09fSJeremy L Thompson return 0; 3145107b09fSJeremy L Thompson } 3155107b09fSJeremy L Thompson 3165107b09fSJeremy L Thompson /** 317250756a7Sjeremylt @brief Check if a CeedOperator is ready to be used. 318250756a7Sjeremylt 319250756a7Sjeremylt @param[in] ceed Ceed object for error handling 320250756a7Sjeremylt @param[in] op CeedOperator to check 321250756a7Sjeremylt 322250756a7Sjeremylt @return An error code: 0 - success, otherwise - failure 323250756a7Sjeremylt 324250756a7Sjeremylt @ref Basic 325250756a7Sjeremylt **/ 326250756a7Sjeremylt static int CeedOperatorCheckReady(Ceed ceed, CeedOperator op) { 327250756a7Sjeremylt CeedQFunction qf = op->qf; 328250756a7Sjeremylt 329250756a7Sjeremylt if (op->composite) { 330250756a7Sjeremylt if (!op->numsub) 331250756a7Sjeremylt // LCOV_EXCL_START 332250756a7Sjeremylt return CeedError(ceed, 1, "No suboperators set"); 333250756a7Sjeremylt // LCOV_EXCL_STOP 334250756a7Sjeremylt } else { 335250756a7Sjeremylt if (op->nfields == 0) 336250756a7Sjeremylt // LCOV_EXCL_START 337250756a7Sjeremylt return CeedError(ceed, 1, "No operator fields set"); 338250756a7Sjeremylt // LCOV_EXCL_STOP 339250756a7Sjeremylt if (op->nfields < qf->numinputfields + qf->numoutputfields) 340250756a7Sjeremylt // LCOV_EXCL_START 341250756a7Sjeremylt return CeedError(ceed, 1, "Not all operator fields set"); 342250756a7Sjeremylt // LCOV_EXCL_STOP 343250756a7Sjeremylt if (!op->hasrestriction) 344250756a7Sjeremylt // LCOV_EXCL_START 345250756a7Sjeremylt return CeedError(ceed, 1,"At least one restriction required"); 346250756a7Sjeremylt // LCOV_EXCL_STOP 347250756a7Sjeremylt if (op->numqpoints == 0) 348250756a7Sjeremylt // LCOV_EXCL_START 349250756a7Sjeremylt return CeedError(ceed, 1,"At least one non-collocated basis required"); 350250756a7Sjeremylt // LCOV_EXCL_STOP 351250756a7Sjeremylt } 352250756a7Sjeremylt 353250756a7Sjeremylt return 0; 354250756a7Sjeremylt } 355250756a7Sjeremylt 356250756a7Sjeremylt /** 3571d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 3581d102b48SJeremy L Thompson 3591d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 3601d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 3611d102b48SJeremy L Thompson The vector 'assembled' is of shape 3621d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 3631d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 3641d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 3651d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 3661d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 3671d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 3681d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 3691d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 3701d102b48SJeremy L Thompson 3711d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 3721d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 3731d102b48SJeremy L Thompson quadrature points 3741d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 3751d102b48SJeremy L Thompson CeedQFunction 3761d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 3771d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 3781d102b48SJeremy L Thompson 3791d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3801d102b48SJeremy L Thompson 381b7ec98d8SJeremy L Thompson @ref Basic 3821d102b48SJeremy L Thompson **/ 3831d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 3847f823360Sjeremylt CeedElemRestriction *rstr, 3857f823360Sjeremylt CeedRequest *request) { 3861d102b48SJeremy L Thompson int ierr; 3871d102b48SJeremy L Thompson Ceed ceed = op->ceed; 388250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 3891d102b48SJeremy L Thompson 3907172caadSjeremylt // Backend version 3915107b09fSJeremy L Thompson if (op->AssembleLinearQFunction) { 3921d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3931d102b48SJeremy L Thompson CeedChk(ierr); 3945107b09fSJeremy L Thompson } else { 3955107b09fSJeremy L Thompson // Fallback to reference Ceed 3965107b09fSJeremy L Thompson if (!op->opfallback) { 3975107b09fSJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 3985107b09fSJeremy L Thompson } 3995107b09fSJeremy L Thompson // Assemble 4005107b09fSJeremy L Thompson ierr = op->opfallback->AssembleLinearQFunction(op->opfallback, assembled, 4015107b09fSJeremy L Thompson rstr, request); CeedChk(ierr); 4025107b09fSJeremy L Thompson } 403250756a7Sjeremylt 4041d102b48SJeremy L Thompson return 0; 4051d102b48SJeremy L Thompson } 4061d102b48SJeremy L Thompson 4071d102b48SJeremy L Thompson /** 408b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 409b7ec98d8SJeremy L Thompson 410b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 411b7ec98d8SJeremy L Thompson 412b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 413b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 414b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 415b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 416b7ec98d8SJeremy L Thompson 417b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 418b7ec98d8SJeremy L Thompson 419b7ec98d8SJeremy L Thompson @ref Basic 420b7ec98d8SJeremy L Thompson **/ 4217f823360Sjeremylt int CeedOperatorAssembleLinearDiagonal(CeedOperator op, CeedVector *assembled, 4227f823360Sjeremylt CeedRequest *request) { 423b7ec98d8SJeremy L Thompson int ierr; 424b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 425250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 426b7ec98d8SJeremy L Thompson 427b7ec98d8SJeremy L Thompson // Use backend version, if available 428b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 429b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 4307172caadSjeremylt } else { 4317172caadSjeremylt // Fallback to reference Ceed 4327172caadSjeremylt if (!op->opfallback) { 4337172caadSjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 434b7ec98d8SJeremy L Thompson } 4357172caadSjeremylt // Assemble 4367172caadSjeremylt ierr = op->opfallback->AssembleLinearDiagonal(op->opfallback, assembled, 4377172caadSjeremylt request); CeedChk(ierr); 438b7ec98d8SJeremy L Thompson } 439b7ec98d8SJeremy L Thompson 440b7ec98d8SJeremy L Thompson return 0; 441b7ec98d8SJeremy L Thompson } 442b7ec98d8SJeremy L Thompson 443b7ec98d8SJeremy L Thompson /** 4443bd813ffSjeremylt @brief Build a FDM based approximate inverse for each element for a 4453bd813ffSjeremylt CeedOperator 4463bd813ffSjeremylt 4473bd813ffSjeremylt This returns a CeedOperator and CeedVector to apply a Fast Diagonalization 4483bd813ffSjeremylt Method based approximate inverse. This function obtains the simultaneous 4493bd813ffSjeremylt diagonalization for the 1D mass and Laplacian operators, 4503bd813ffSjeremylt M = V^T V, K = V^T S V. 4513bd813ffSjeremylt The assembled QFunction is used to modify the eigenvalues from simultaneous 4523bd813ffSjeremylt diagonalization and obtain an approximate inverse of the form 4533bd813ffSjeremylt V^T S^hat V. The CeedOperator must be linear and non-composite. The 4543bd813ffSjeremylt associated CeedQFunction must therefore also be linear. 4553bd813ffSjeremylt 4563bd813ffSjeremylt @param op CeedOperator to create element inverses 4573bd813ffSjeremylt @param[out] fdminv CeedOperator to apply the action of a FDM based inverse 4583bd813ffSjeremylt for each element 4593bd813ffSjeremylt @param request Address of CeedRequest for non-blocking completion, else 4603bd813ffSjeremylt CEED_REQUEST_IMMEDIATE 4613bd813ffSjeremylt 4623bd813ffSjeremylt @return An error code: 0 - success, otherwise - failure 4633bd813ffSjeremylt 4643bd813ffSjeremylt @ref Advanced 4653bd813ffSjeremylt **/ 4663bd813ffSjeremylt int CeedOperatorCreateFDMElementInverse(CeedOperator op, CeedOperator *fdminv, 4673bd813ffSjeremylt CeedRequest *request) { 4683bd813ffSjeremylt int ierr; 4693bd813ffSjeremylt Ceed ceed = op->ceed; 470713f43c3Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 4713bd813ffSjeremylt 472713f43c3Sjeremylt // Use backend version, if available 473713f43c3Sjeremylt if (op->CreateFDMElementInverse) { 474713f43c3Sjeremylt ierr = op->CreateFDMElementInverse(op, fdminv, request); CeedChk(ierr); 475713f43c3Sjeremylt } else { 476713f43c3Sjeremylt // Fallback to reference Ceed 477713f43c3Sjeremylt if (!op->opfallback) { 478713f43c3Sjeremylt ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 4793bd813ffSjeremylt } 480713f43c3Sjeremylt // Assemble 481713f43c3Sjeremylt ierr = op->opfallback->CreateFDMElementInverse(op->opfallback, fdminv, 4823bd813ffSjeremylt request); CeedChk(ierr); 4833bd813ffSjeremylt } 4843bd813ffSjeremylt 4853bd813ffSjeremylt return 0; 4863bd813ffSjeremylt } 4873bd813ffSjeremylt 4883bd813ffSjeremylt 4893bd813ffSjeremylt /** 4903bd813ffSjeremylt @brief Apply CeedOperator to a vector 491d7b241e6Sjeremylt 492d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 493d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 494d7b241e6Sjeremylt CeedOperatorSetField(). 495d7b241e6Sjeremylt 496d7b241e6Sjeremylt @param op CeedOperator to apply 49734138859Sjeremylt @param[in] in CeedVector containing input state or CEED_VECTOR_NONE if 49834138859Sjeremylt there are no active inputs 499b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 50034138859Sjeremylt distinct from @a in) or CEED_VECTOR_NONE if there are no 50134138859Sjeremylt active outputs 502d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 503d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 504b11c1e72Sjeremylt 505b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 506dfdf5a53Sjeremylt 507dfdf5a53Sjeremylt @ref Basic 508b11c1e72Sjeremylt **/ 509692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 510692c2638Sjeremylt CeedRequest *request) { 511d7b241e6Sjeremylt int ierr; 512d7b241e6Sjeremylt Ceed ceed = op->ceed; 513250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 514d7b241e6Sjeremylt 515250756a7Sjeremylt if (op->numelements) { 516250756a7Sjeremylt // Standard Operator 517cae8b89aSjeremylt if (op->Apply) { 518250756a7Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 519cae8b89aSjeremylt } else { 520cae8b89aSjeremylt // Zero all output vectors 521250756a7Sjeremylt CeedQFunction qf = op->qf; 522cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 523cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 524cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 525cae8b89aSjeremylt vec = out; 526cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 527cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 528cae8b89aSjeremylt } 529cae8b89aSjeremylt } 530250756a7Sjeremylt // Apply 531250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 532250756a7Sjeremylt } 533250756a7Sjeremylt } else if (op->composite) { 534250756a7Sjeremylt // Composite Operator 535250756a7Sjeremylt if (op->ApplyComposite) { 536250756a7Sjeremylt ierr = op->ApplyComposite(op, in, out, request); CeedChk(ierr); 537250756a7Sjeremylt } else { 538250756a7Sjeremylt CeedInt numsub; 539250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 540250756a7Sjeremylt CeedOperator *suboperators; 541250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 542250756a7Sjeremylt 543250756a7Sjeremylt // Zero all output vectors 544250756a7Sjeremylt if (out != CEED_VECTOR_NONE) { 545cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 546cae8b89aSjeremylt } 547250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 548250756a7Sjeremylt for (CeedInt j=0; j<suboperators[i]->qf->numoutputfields; j++) { 549250756a7Sjeremylt CeedVector vec = suboperators[i]->outputfields[j]->vec; 550250756a7Sjeremylt if (vec != CEED_VECTOR_ACTIVE && vec != CEED_VECTOR_NONE) { 551250756a7Sjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 552250756a7Sjeremylt } 553250756a7Sjeremylt } 554250756a7Sjeremylt } 555250756a7Sjeremylt // Apply 556250756a7Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 557250756a7Sjeremylt ierr = CeedOperatorApplyAdd(op->suboperators[i], in, out, request); 558cae8b89aSjeremylt CeedChk(ierr); 559cae8b89aSjeremylt } 560cae8b89aSjeremylt } 561250756a7Sjeremylt } 562250756a7Sjeremylt 563cae8b89aSjeremylt return 0; 564cae8b89aSjeremylt } 565cae8b89aSjeremylt 566cae8b89aSjeremylt /** 567cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 568cae8b89aSjeremylt 569cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 570cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 571cae8b89aSjeremylt CeedOperatorSetField(). 572cae8b89aSjeremylt 573cae8b89aSjeremylt @param op CeedOperator to apply 574cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 575cae8b89aSjeremylt active inputs 576cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 577cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 578cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 579cae8b89aSjeremylt CEED_REQUEST_IMMEDIATE 580cae8b89aSjeremylt 581cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 582cae8b89aSjeremylt 583cae8b89aSjeremylt @ref Basic 584cae8b89aSjeremylt **/ 585cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 586cae8b89aSjeremylt CeedRequest *request) { 587cae8b89aSjeremylt int ierr; 588cae8b89aSjeremylt Ceed ceed = op->ceed; 589250756a7Sjeremylt ierr = CeedOperatorCheckReady(ceed, op); CeedChk(ierr); 590cae8b89aSjeremylt 591250756a7Sjeremylt if (op->numelements) { 592250756a7Sjeremylt // Standard Operator 593250756a7Sjeremylt ierr = op->ApplyAdd(op, in, out, request); CeedChk(ierr); 594250756a7Sjeremylt } else if (op->composite) { 595250756a7Sjeremylt // Composite Operator 596250756a7Sjeremylt if (op->ApplyAddComposite) { 597250756a7Sjeremylt ierr = op->ApplyAddComposite(op, in, out, request); CeedChk(ierr); 598cae8b89aSjeremylt } else { 599250756a7Sjeremylt CeedInt numsub; 600250756a7Sjeremylt ierr = CeedOperatorGetNumSub(op, &numsub); CeedChk(ierr); 601250756a7Sjeremylt CeedOperator *suboperators; 602250756a7Sjeremylt ierr = CeedOperatorGetSubList(op, &suboperators); CeedChk(ierr); 603250756a7Sjeremylt 604250756a7Sjeremylt for (CeedInt i=0; i<numsub; i++) { 605250756a7Sjeremylt ierr = CeedOperatorApplyAdd(suboperators[i], in, out, request); 606cae8b89aSjeremylt CeedChk(ierr); 6071d7d2407SJeremy L Thompson } 608250756a7Sjeremylt } 609250756a7Sjeremylt } 610250756a7Sjeremylt 611d7b241e6Sjeremylt return 0; 612d7b241e6Sjeremylt } 613d7b241e6Sjeremylt 614d7b241e6Sjeremylt /** 6154ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 6164ce2993fSjeremylt 6174ce2993fSjeremylt @param op CeedOperator 6184ce2993fSjeremylt @param[out] ceed Variable to store Ceed 6194ce2993fSjeremylt 6204ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6214ce2993fSjeremylt 62223617272Sjeremylt @ref Advanced 6234ce2993fSjeremylt **/ 6244ce2993fSjeremylt 6254ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 6264ce2993fSjeremylt *ceed = op->ceed; 6274ce2993fSjeremylt return 0; 6284ce2993fSjeremylt } 6294ce2993fSjeremylt 6304ce2993fSjeremylt /** 6314ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 6324ce2993fSjeremylt 6334ce2993fSjeremylt @param op CeedOperator 6344ce2993fSjeremylt @param[out] numelem Variable to store number of elements 6354ce2993fSjeremylt 6364ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6374ce2993fSjeremylt 63823617272Sjeremylt @ref Advanced 6394ce2993fSjeremylt **/ 6404ce2993fSjeremylt 6414ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 64252d6035fSJeremy L Thompson if (op->composite) 643c042f62fSJeremy L Thompson // LCOV_EXCL_START 64452d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 645c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 64652d6035fSJeremy L Thompson 6474ce2993fSjeremylt *numelem = op->numelements; 6484ce2993fSjeremylt return 0; 6494ce2993fSjeremylt } 6504ce2993fSjeremylt 6514ce2993fSjeremylt /** 6524ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 6534ce2993fSjeremylt 6544ce2993fSjeremylt @param op CeedOperator 6554ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 6564ce2993fSjeremylt 6574ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6584ce2993fSjeremylt 65923617272Sjeremylt @ref Advanced 6604ce2993fSjeremylt **/ 6614ce2993fSjeremylt 6624ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 66352d6035fSJeremy L Thompson if (op->composite) 664c042f62fSJeremy L Thompson // LCOV_EXCL_START 66552d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 666c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 66752d6035fSJeremy L Thompson 6684ce2993fSjeremylt *numqpts = op->numqpoints; 6694ce2993fSjeremylt return 0; 6704ce2993fSjeremylt } 6714ce2993fSjeremylt 6724ce2993fSjeremylt /** 6734ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 6744ce2993fSjeremylt 6754ce2993fSjeremylt @param op CeedOperator 6764ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 6774ce2993fSjeremylt 6784ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 6794ce2993fSjeremylt 68023617272Sjeremylt @ref Advanced 6814ce2993fSjeremylt **/ 6824ce2993fSjeremylt 6834ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 68452d6035fSJeremy L Thompson if (op->composite) 685c042f62fSJeremy L Thompson // LCOV_EXCL_START 68652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 687c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 688c042f62fSJeremy L Thompson 6894ce2993fSjeremylt *numargs = op->nfields; 6904ce2993fSjeremylt return 0; 6914ce2993fSjeremylt } 6924ce2993fSjeremylt 6934ce2993fSjeremylt /** 6944ce2993fSjeremylt @brief Get the setup status of a CeedOperator 6954ce2993fSjeremylt 6964ce2993fSjeremylt @param op CeedOperator 697288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 6984ce2993fSjeremylt 6994ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7004ce2993fSjeremylt 70123617272Sjeremylt @ref Advanced 7024ce2993fSjeremylt **/ 7034ce2993fSjeremylt 7044ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 7054ce2993fSjeremylt *setupdone = op->setupdone; 7064ce2993fSjeremylt return 0; 7074ce2993fSjeremylt } 7084ce2993fSjeremylt 7094ce2993fSjeremylt /** 7104ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 7114ce2993fSjeremylt 7124ce2993fSjeremylt @param op CeedOperator 7138c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 7144ce2993fSjeremylt 7154ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7164ce2993fSjeremylt 71723617272Sjeremylt @ref Advanced 7184ce2993fSjeremylt **/ 7194ce2993fSjeremylt 7204ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 72152d6035fSJeremy L Thompson if (op->composite) 722c042f62fSJeremy L Thompson // LCOV_EXCL_START 72352d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 724c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 72552d6035fSJeremy L Thompson 7264ce2993fSjeremylt *qf = op->qf; 7274ce2993fSjeremylt return 0; 7284ce2993fSjeremylt } 7294ce2993fSjeremylt 7304ce2993fSjeremylt /** 73152d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 73252d6035fSJeremy L Thompson 73352d6035fSJeremy L Thompson @param op CeedOperator 73452d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 73552d6035fSJeremy L Thompson 73652d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 73752d6035fSJeremy L Thompson 73852d6035fSJeremy L Thompson @ref Advanced 73952d6035fSJeremy L Thompson **/ 74052d6035fSJeremy L Thompson 74152d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 742c042f62fSJeremy L Thompson if (!op->composite) 743c042f62fSJeremy L Thompson // LCOV_EXCL_START 744c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 745c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 74652d6035fSJeremy L Thompson 74752d6035fSJeremy L Thompson *numsub = op->numsub; 74852d6035fSJeremy L Thompson return 0; 74952d6035fSJeremy L Thompson } 75052d6035fSJeremy L Thompson 75152d6035fSJeremy L Thompson /** 75252d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 75352d6035fSJeremy L Thompson 75452d6035fSJeremy L Thompson @param op CeedOperator 75552d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 75652d6035fSJeremy L Thompson 75752d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 75852d6035fSJeremy L Thompson 75952d6035fSJeremy L Thompson @ref Advanced 76052d6035fSJeremy L Thompson **/ 76152d6035fSJeremy L Thompson 76252d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 763c042f62fSJeremy L Thompson if (!op->composite) 764c042f62fSJeremy L Thompson // LCOV_EXCL_START 765c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 766c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 76752d6035fSJeremy L Thompson 76852d6035fSJeremy L Thompson *suboperators = op->suboperators; 76952d6035fSJeremy L Thompson return 0; 77052d6035fSJeremy L Thompson } 77152d6035fSJeremy L Thompson 77252d6035fSJeremy L Thompson /** 773fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 774fe2413ffSjeremylt 775fe2413ffSjeremylt @param[out] op CeedOperator 776fe2413ffSjeremylt @param data Data to set 777fe2413ffSjeremylt 778fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 779fe2413ffSjeremylt 780fe2413ffSjeremylt @ref Advanced 781fe2413ffSjeremylt **/ 782fe2413ffSjeremylt 783fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void **data) { 784fe2413ffSjeremylt op->data = *data; 785fe2413ffSjeremylt return 0; 786fe2413ffSjeremylt } 787fe2413ffSjeremylt 788fe2413ffSjeremylt /** 7894ce2993fSjeremylt @brief Get the backend data of a CeedOperator 7904ce2993fSjeremylt 7914ce2993fSjeremylt @param op CeedOperator 7924ce2993fSjeremylt @param[out] data Variable to store data 7934ce2993fSjeremylt 7944ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7954ce2993fSjeremylt 79623617272Sjeremylt @ref Advanced 7974ce2993fSjeremylt **/ 7984ce2993fSjeremylt 7994ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void **data) { 8004ce2993fSjeremylt *data = op->data; 8014ce2993fSjeremylt return 0; 8024ce2993fSjeremylt } 8034ce2993fSjeremylt 8044ce2993fSjeremylt /** 8054ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 8064ce2993fSjeremylt 8074ce2993fSjeremylt @param op CeedOperator 8084ce2993fSjeremylt 8094ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 8104ce2993fSjeremylt 81123617272Sjeremylt @ref Advanced 8124ce2993fSjeremylt **/ 8134ce2993fSjeremylt 8144ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 8154ce2993fSjeremylt op->setupdone = 1; 8164ce2993fSjeremylt return 0; 8174ce2993fSjeremylt } 8184ce2993fSjeremylt 8194ce2993fSjeremylt /** 8202ebaca42Sjeremylt @brief View a field of a CeedOperator 8212ebaca42Sjeremylt 8222ebaca42Sjeremylt @param[in] field Operator field to view 8232ebaca42Sjeremylt @param[in] fieldnumber Number of field being viewed 8242ebaca42Sjeremylt @param[in] stream Stream to view to, e.g., stdout 8252ebaca42Sjeremylt 8262ebaca42Sjeremylt @return An error code: 0 - success, otherwise - failure 8272ebaca42Sjeremylt 8282ebaca42Sjeremylt @ref Utility 8292ebaca42Sjeremylt **/ 8302ebaca42Sjeremylt static int CeedOperatorFieldView(CeedOperatorField field, 8312ebaca42Sjeremylt CeedQFunctionField qffield, 8322da88da5Sjeremylt CeedInt fieldnumber, bool sub, bool in, 8332da88da5Sjeremylt FILE *stream) { 8342ebaca42Sjeremylt const char *pre = sub ? " " : ""; 8352da88da5Sjeremylt const char *inout = in ? "Input" : "Output"; 8362ebaca42Sjeremylt 8372da88da5Sjeremylt fprintf(stream, "%s %s Field [%d]:\n" 8382da88da5Sjeremylt "%s Name: \"%s\"\n" 8392da88da5Sjeremylt "%s Lmode: \"%s\"\n", 8402da88da5Sjeremylt pre, inout, fieldnumber, pre, qffield->fieldname, 8412ebaca42Sjeremylt pre, CeedTransposeModes[field->lmode]); 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 /** 9454dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 9464dccadb6Sjeremylt 9474dccadb6Sjeremylt @param opfield CeedOperatorField 9484dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 9494dccadb6Sjeremylt 9504dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 9514dccadb6Sjeremylt 9524dccadb6Sjeremylt @ref Advanced 9534dccadb6Sjeremylt **/ 9544dccadb6Sjeremylt 9554dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 9564dccadb6Sjeremylt CeedTransposeMode *lmode) { 957fe2413ffSjeremylt *lmode = opfield->lmode; 9584dccadb6Sjeremylt return 0; 9592b8e417aSjeremylt } 9602b8e417aSjeremylt 9612b8e417aSjeremylt /** 962d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 963d1bcdac9Sjeremylt 964d1bcdac9Sjeremylt @param opfield CeedOperatorField 965d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 966d1bcdac9Sjeremylt 967d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 968d1bcdac9Sjeremylt 969d1bcdac9Sjeremylt @ref Advanced 970d1bcdac9Sjeremylt **/ 971d1bcdac9Sjeremylt 972d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 973d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 974fe2413ffSjeremylt *rstr = opfield->Erestrict; 975d1bcdac9Sjeremylt return 0; 976d1bcdac9Sjeremylt } 977d1bcdac9Sjeremylt 978d1bcdac9Sjeremylt /** 979d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 980d1bcdac9Sjeremylt 981d1bcdac9Sjeremylt @param opfield CeedOperatorField 982d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 983d1bcdac9Sjeremylt 984d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 985d1bcdac9Sjeremylt 986d1bcdac9Sjeremylt @ref Advanced 987d1bcdac9Sjeremylt **/ 988d1bcdac9Sjeremylt 989692c2638Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 990fe2413ffSjeremylt *basis = opfield->basis; 991d1bcdac9Sjeremylt return 0; 992d1bcdac9Sjeremylt } 993d1bcdac9Sjeremylt 994d1bcdac9Sjeremylt /** 995d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 996d1bcdac9Sjeremylt 997d1bcdac9Sjeremylt @param opfield CeedOperatorField 998d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 999d1bcdac9Sjeremylt 1000d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1001d1bcdac9Sjeremylt 1002d1bcdac9Sjeremylt @ref Advanced 1003d1bcdac9Sjeremylt **/ 1004d1bcdac9Sjeremylt 1005692c2638Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 1006fe2413ffSjeremylt *vec = opfield->vec; 1007d1bcdac9Sjeremylt return 0; 1008d1bcdac9Sjeremylt } 1009d1bcdac9Sjeremylt 1010d1bcdac9Sjeremylt /** 1011b11c1e72Sjeremylt @brief Destroy a CeedOperator 1012d7b241e6Sjeremylt 1013d7b241e6Sjeremylt @param op CeedOperator to destroy 1014b11c1e72Sjeremylt 1015b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1016dfdf5a53Sjeremylt 1017dfdf5a53Sjeremylt @ref Basic 1018b11c1e72Sjeremylt **/ 1019d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1020d7b241e6Sjeremylt int ierr; 1021d7b241e6Sjeremylt 1022d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 1023d7b241e6Sjeremylt if ((*op)->Destroy) { 1024d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1025d7b241e6Sjeremylt } 1026fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1027fe2413ffSjeremylt // Free fields 10281d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 102952d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 103071352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 103171352a93Sjeremylt CeedChk(ierr); 103271352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 103371352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 103471352a93Sjeremylt } 103571352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 103671352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 103771352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 103871352a93Sjeremylt } 1039fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1040fe2413ffSjeremylt } 10411d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1042d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 104371352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 104471352a93Sjeremylt CeedChk(ierr); 104571352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 104671352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 104771352a93Sjeremylt } 104871352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 104971352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 105071352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 105171352a93Sjeremylt } 1052fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1053fe2413ffSjeremylt } 105452d6035fSJeremy L Thompson // Destroy suboperators 10551d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 105652d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 105752d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 105852d6035fSJeremy L Thompson } 1059d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1060d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1061d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1062fe2413ffSjeremylt 10635107b09fSJeremy L Thompson // Destroy fallback 10645107b09fSJeremy L Thompson if ((*op)->opfallback) { 10655107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 10665107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 10675107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 10685107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 10695107b09fSJeremy L Thompson } 10705107b09fSJeremy L Thompson 1071fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1072fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 107352d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1074d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1075d7b241e6Sjeremylt return 0; 1076d7b241e6Sjeremylt } 1077d7b241e6Sjeremylt 1078d7b241e6Sjeremylt /// @} 1079