1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details. 4d7b241e6Sjeremylt // 5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software 6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral 7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and 8d7b241e6Sjeremylt // source code availability see http://github.com/ceed. 9d7b241e6Sjeremylt // 10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office 12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for 13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including 14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early 15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative. 16d7b241e6Sjeremylt 17d7b241e6Sjeremylt #include <ceed-impl.h> 18d863ab9bSjeremylt #include <ceed-backend.h> 19d7b241e6Sjeremylt #include <string.h> 20d7b241e6Sjeremylt 21dfdf5a53Sjeremylt /// @file 22dfdf5a53Sjeremylt /// Implementation of public CeedOperator interfaces 23dfdf5a53Sjeremylt /// 24dfdf5a53Sjeremylt /// @addtogroup CeedOperator 25dfdf5a53Sjeremylt /// @{ 26d7b241e6Sjeremylt 27d7b241e6Sjeremylt /** 280219ea01SJeremy L Thompson @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and 290219ea01SJeremy L Thompson CeedElemRestriction can be associated with CeedQFunction fields with 300219ea01SJeremy L Thompson \ref CeedOperatorSetField. 31d7b241e6Sjeremylt 32b11c1e72Sjeremylt @param ceed A Ceed object where the CeedOperator will be created 33d7b241e6Sjeremylt @param qf QFunction defining the action of the operator at quadrature points 34d7b241e6Sjeremylt @param dqf QFunction defining the action of the Jacobian of @a qf (or NULL) 35d7b241e6Sjeremylt @param dqfT QFunction defining the action of the transpose of the Jacobian 36d7b241e6Sjeremylt of @a qf (or NULL) 37b11c1e72Sjeremylt @param[out] op Address of the variable where the newly created 38b11c1e72Sjeremylt CeedOperator will be stored 39b11c1e72Sjeremylt 40b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 41dfdf5a53Sjeremylt 42dfdf5a53Sjeremylt @ref Basic 43d7b241e6Sjeremylt */ 44d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf, 45d7b241e6Sjeremylt CeedQFunction dqfT, CeedOperator *op) { 46d7b241e6Sjeremylt int ierr; 47d7b241e6Sjeremylt 485fe0d4faSjeremylt if (!ceed->OperatorCreate) { 495fe0d4faSjeremylt Ceed delegate; 50aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 515fe0d4faSjeremylt 525fe0d4faSjeremylt if (!delegate) 53c042f62fSJeremy L Thompson // LCOV_EXCL_START 545fe0d4faSjeremylt return CeedError(ceed, 1, "Backend does not support OperatorCreate"); 55c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 565fe0d4faSjeremylt 575fe0d4faSjeremylt ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr); 585fe0d4faSjeremylt return 0; 595fe0d4faSjeremylt } 605fe0d4faSjeremylt 61d7b241e6Sjeremylt ierr = CeedCalloc(1, op); CeedChk(ierr); 62d7b241e6Sjeremylt (*op)->ceed = ceed; 63d7b241e6Sjeremylt ceed->refcount++; 64d7b241e6Sjeremylt (*op)->refcount = 1; 65442e7f0bSjeremylt if (qf == CEED_QFUNCTION_NONE) 66442e7f0bSjeremylt // LCOV_EXCL_START 67442e7f0bSjeremylt return CeedError(ceed, 1, "Operator must have a valid QFunction."); 68442e7f0bSjeremylt // LCOV_EXCL_STOP 69d7b241e6Sjeremylt (*op)->qf = qf; 70d7b241e6Sjeremylt qf->refcount++; 71442e7f0bSjeremylt if (dqf && dqf != CEED_QFUNCTION_NONE) { 72d7b241e6Sjeremylt (*op)->dqf = dqf; 73442e7f0bSjeremylt dqf->refcount++; 74442e7f0bSjeremylt } 75442e7f0bSjeremylt if (dqfT && dqfT != CEED_QFUNCTION_NONE) { 76d7b241e6Sjeremylt (*op)->dqfT = dqfT; 77442e7f0bSjeremylt dqfT->refcount++; 78442e7f0bSjeremylt } 79fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 80fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 81d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 82d7b241e6Sjeremylt return 0; 83d7b241e6Sjeremylt } 84d7b241e6Sjeremylt 85d7b241e6Sjeremylt /** 8652d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 8752d6035fSJeremy L Thompson 8852d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 8952d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 9052d6035fSJeremy L Thompson Composite CeedOperator will be stored 9152d6035fSJeremy L Thompson 9252d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9352d6035fSJeremy L Thompson 9452d6035fSJeremy L Thompson @ref Basic 9552d6035fSJeremy L Thompson */ 9652d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 9752d6035fSJeremy L Thompson int ierr; 9852d6035fSJeremy L Thompson 9952d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 10052d6035fSJeremy L Thompson Ceed delegate; 101aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 10252d6035fSJeremy L Thompson 10352d6035fSJeremy L Thompson if (!delegate) 104c042f62fSJeremy L Thompson // LCOV_EXCL_START 1051d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 1061d102b48SJeremy L Thompson "CompositeOperatorCreate"); 107c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 10852d6035fSJeremy L Thompson 10952d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 11052d6035fSJeremy L Thompson return 0; 11152d6035fSJeremy L Thompson } 11252d6035fSJeremy L Thompson 11352d6035fSJeremy L Thompson ierr = CeedCalloc(1,op); CeedChk(ierr); 11452d6035fSJeremy L Thompson (*op)->ceed = ceed; 11552d6035fSJeremy L Thompson ceed->refcount++; 11652d6035fSJeremy L Thompson (*op)->composite = true; 11752d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 11852d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 11952d6035fSJeremy L Thompson return 0; 12052d6035fSJeremy L Thompson } 12152d6035fSJeremy L Thompson 12252d6035fSJeremy L Thompson /** 123b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 124d7b241e6Sjeremylt 125d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 126d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 127d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 128d7b241e6Sjeremylt 129d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 130d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 131d7b241e6Sjeremylt input and at most one active output. 132d7b241e6Sjeremylt 1338c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 1348795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 1358795c945Sjeremylt CeedQFunction) 136b11c1e72Sjeremylt @param r CeedElemRestriction 137b0e29e78Sjeremylt @param lmode CeedTransposeMode which specifies the ordering of the 138b0e29e78Sjeremylt components of the l-vector used by this CeedOperatorField, 139b0e29e78Sjeremylt CEED_NOTRANSPOSE indicates the component is the 140b0e29e78Sjeremylt outermost index and CEED_TRANSPOSE indicates the component 141b0e29e78Sjeremylt is the innermost index in ordering of the l-vector 142783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 143b11c1e72Sjeremylt if collocated with quadrature points 144b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 145b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 1468c91a0c9SJeremy L Thompson CEED_EVAL_WEIGHT in the QFunction 147b11c1e72Sjeremylt 148b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 149dfdf5a53Sjeremylt 150dfdf5a53Sjeremylt @ref Basic 151b11c1e72Sjeremylt **/ 152d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 1534dccadb6Sjeremylt CeedElemRestriction r, CeedTransposeMode lmode, 1544dccadb6Sjeremylt CeedBasis b, CeedVector v) { 155d7b241e6Sjeremylt int ierr; 15652d6035fSJeremy L Thompson if (op->composite) 157c042f62fSJeremy L Thompson // LCOV_EXCL_START 15852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 159c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1608b067b84SJed Brown if (!r) 161c042f62fSJeremy L Thompson // LCOV_EXCL_START 162c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 163c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 164c042f62fSJeremy L Thompson fieldname); 165c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1668b067b84SJed Brown if (!b) 167c042f62fSJeremy L Thompson // LCOV_EXCL_START 168c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 169c042f62fSJeremy L Thompson fieldname); 170c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1718b067b84SJed Brown if (!v) 172c042f62fSJeremy L Thompson // LCOV_EXCL_START 173c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 174c042f62fSJeremy L Thompson fieldname); 175c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 17652d6035fSJeremy L Thompson 177d7b241e6Sjeremylt CeedInt numelements; 178d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 1792cb0afc5Sjeremylt if (op->hasrestriction && op->numelements != numelements) 180c042f62fSJeremy L Thompson // LCOV_EXCL_START 181d7b241e6Sjeremylt return CeedError(op->ceed, 1, 1821d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 1831d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 184c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 185d7b241e6Sjeremylt op->numelements = numelements; 1862cb0afc5Sjeremylt op->hasrestriction = true; // Restriction set, but numelements may be 0 187d7b241e6Sjeremylt 188783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 189d7b241e6Sjeremylt CeedInt numqpoints; 190d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 191d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 192c042f62fSJeremy L Thompson // LCOV_EXCL_START 1931d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1941d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1951d102b48SJeremy L Thompson op->numqpoints); 196c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 197d7b241e6Sjeremylt op->numqpoints = numqpoints; 198d7b241e6Sjeremylt } 199d1bcdac9Sjeremylt CeedOperatorField *ofield; 200d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 201fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 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)) { 208d7b241e6Sjeremylt ofield = &op->outputfields[i]; 209d7b241e6Sjeremylt goto found; 210d7b241e6Sjeremylt } 211d7b241e6Sjeremylt } 212c042f62fSJeremy L Thompson // LCOV_EXCL_START 213d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 214d7b241e6Sjeremylt fieldname); 215c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 216d7b241e6Sjeremylt found: 217fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 218fe2413ffSjeremylt (*ofield)->Erestrict = r; 21971352a93Sjeremylt r->refcount += 1; 220fe2413ffSjeremylt (*ofield)->lmode = lmode; 221fe2413ffSjeremylt (*ofield)->basis = b; 22271352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 22371352a93Sjeremylt b->refcount += 1; 224fe2413ffSjeremylt (*ofield)->vec = v; 22571352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 22671352a93Sjeremylt v->refcount += 1; 227d7b241e6Sjeremylt op->nfields += 1; 228d7b241e6Sjeremylt return 0; 229d7b241e6Sjeremylt } 230d7b241e6Sjeremylt 231d7b241e6Sjeremylt /** 23252d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 233288c0443SJeremy L Thompson 234288c0443SJeremy L Thompson @param[out] compositeop Address of the composite CeedOperator 235288c0443SJeremy L Thompson @param subop Address of the sub-operator CeedOperator 23652d6035fSJeremy L Thompson 23752d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 23852d6035fSJeremy L Thompson 23952d6035fSJeremy L Thompson @ref Basic 24052d6035fSJeremy L Thompson */ 241692c2638Sjeremylt int CeedCompositeOperatorAddSub(CeedOperator compositeop, CeedOperator subop) { 24252d6035fSJeremy L Thompson if (!compositeop->composite) 243c042f62fSJeremy L Thompson // LCOV_EXCL_START 2441d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2451d102b48SJeremy L Thompson "operator"); 246c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24752d6035fSJeremy L Thompson 24852d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 249c042f62fSJeremy L Thompson // LCOV_EXCL_START 2501d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 251c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 25252d6035fSJeremy L Thompson 25352d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 25452d6035fSJeremy L Thompson subop->refcount++; 25552d6035fSJeremy L Thompson compositeop->numsub++; 25652d6035fSJeremy L Thompson return 0; 25752d6035fSJeremy L Thompson } 25852d6035fSJeremy L Thompson 25952d6035fSJeremy L Thompson /** 2605107b09fSJeremy L Thompson @brief Duplicate a CeedOperator with a reference Ceed to fallback for advanced 2615107b09fSJeremy L Thompson CeedOperator functionality 2625107b09fSJeremy L Thompson 2635107b09fSJeremy L Thompson @param op CeedOperator to create fallback for 2645107b09fSJeremy L Thompson 2655107b09fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2665107b09fSJeremy L Thompson 2675107b09fSJeremy L Thompson @ref Developer 2685107b09fSJeremy L Thompson **/ 2695107b09fSJeremy L Thompson int CeedOperatorCreateFallback(CeedOperator op) { 2705107b09fSJeremy L Thompson int ierr; 2715107b09fSJeremy L Thompson 2725107b09fSJeremy L Thompson // Fallback Ceed 2735107b09fSJeremy L Thompson const char *resource, *fallbackresource; 2745107b09fSJeremy L Thompson ierr = CeedGetResource(op->ceed, &resource); CeedChk(ierr); 2755107b09fSJeremy L Thompson ierr = CeedGetOperatorFallbackResource(op->ceed, &fallbackresource); 2765107b09fSJeremy L Thompson CeedChk(ierr); 2775107b09fSJeremy L Thompson if (!strcmp(resource, fallbackresource)) 2785107b09fSJeremy L Thompson // LCOV_EXCL_START 2795107b09fSJeremy L Thompson return CeedError(op->ceed, 1, "Backend %s cannot create an operator" 2805107b09fSJeremy L Thompson "fallback to resource %s", resource, fallbackresource); 2815107b09fSJeremy L Thompson // LCOV_EXCL_STOP 2825107b09fSJeremy L Thompson 2835107b09fSJeremy L Thompson Ceed ceedref; 2845107b09fSJeremy L Thompson ierr = CeedInit(fallbackresource, &ceedref); CeedChk(ierr); 2855107b09fSJeremy L Thompson ceedref->opfallbackparent = op->ceed; 2865107b09fSJeremy L Thompson op->ceed->opfallbackceed = ceedref; 2875107b09fSJeremy L Thompson 2885107b09fSJeremy L Thompson // Clone Op 2895107b09fSJeremy L Thompson CeedOperator opref; 2905107b09fSJeremy L Thompson ierr = CeedCalloc(1, &opref); CeedChk(ierr); 2915107b09fSJeremy L Thompson memcpy(opref, op, sizeof(*opref)); CeedChk(ierr); 2925107b09fSJeremy L Thompson opref->data = NULL; 2935107b09fSJeremy L Thompson opref->setupdone = 0; 2945107b09fSJeremy L Thompson opref->ceed = ceedref; 2955107b09fSJeremy L Thompson ierr = ceedref->OperatorCreate(opref); CeedChk(ierr); 2965107b09fSJeremy L Thompson op->opfallback = opref; 2975107b09fSJeremy L Thompson 2985107b09fSJeremy L Thompson // Clone QF 2995107b09fSJeremy L Thompson CeedQFunction qfref; 3005107b09fSJeremy L Thompson ierr = CeedCalloc(1, &qfref); CeedChk(ierr); 3015107b09fSJeremy L Thompson memcpy(qfref, (op->qf), sizeof(*qfref)); CeedChk(ierr); 3025107b09fSJeremy L Thompson qfref->data = NULL; 3035107b09fSJeremy L Thompson qfref->ceed = ceedref; 3045107b09fSJeremy L Thompson ierr = ceedref->QFunctionCreate(qfref); CeedChk(ierr); 3055107b09fSJeremy L Thompson opref->qf = qfref; 3065107b09fSJeremy L Thompson op->qffallback = qfref; 3075107b09fSJeremy L Thompson 3085107b09fSJeremy L Thompson return 0; 3095107b09fSJeremy L Thompson } 3105107b09fSJeremy L Thompson 3115107b09fSJeremy L Thompson /** 3121d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 3131d102b48SJeremy L Thompson 3141d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 3151d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 3161d102b48SJeremy L Thompson The vector 'assembled' is of shape 3171d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 3181d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 3191d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 3201d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 3211d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 3221d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 3231d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 3241d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 3251d102b48SJeremy L Thompson 3261d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 3271d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedQFunction at 3281d102b48SJeremy L Thompson quadrature points 3291d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 3301d102b48SJeremy L Thompson CeedQFunction 3311d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 3321d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 3331d102b48SJeremy L Thompson 3341d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3351d102b48SJeremy L Thompson 336b7ec98d8SJeremy L Thompson @ref Basic 3371d102b48SJeremy L Thompson **/ 3381d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 3397f823360Sjeremylt CeedElemRestriction *rstr, 3407f823360Sjeremylt CeedRequest *request) { 3411d102b48SJeremy L Thompson int ierr; 3421d102b48SJeremy L Thompson Ceed ceed = op->ceed; 3431d102b48SJeremy L Thompson CeedQFunction qf = op->qf; 3441d102b48SJeremy L Thompson 3451d102b48SJeremy L Thompson if (op->composite) { 346138d4072Sjeremylt // LCOV_EXCL_START 3471d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 348138d4072Sjeremylt // LCOV_EXCL_STOP 3491d102b48SJeremy L Thompson } else { 3501d102b48SJeremy L Thompson if (op->nfields == 0) 351138d4072Sjeremylt // LCOV_EXCL_START 3521d102b48SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 353138d4072Sjeremylt // LCOV_EXCL_STOP 3541d102b48SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 355138d4072Sjeremylt // LCOV_EXCL_START 3561d102b48SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 357138d4072Sjeremylt // LCOV_EXCL_STOP 3582cb0afc5Sjeremylt if (!op->hasrestriction) 359138d4072Sjeremylt // LCOV_EXCL_START 3601d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 361138d4072Sjeremylt // LCOV_EXCL_STOP 3621d102b48SJeremy L Thompson if (op->numqpoints == 0) 363138d4072Sjeremylt // LCOV_EXCL_START 3641d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 365138d4072Sjeremylt // LCOV_EXCL_STOP 3661d102b48SJeremy L Thompson } 3675107b09fSJeremy L Thompson if (op->AssembleLinearQFunction) { 3681d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3691d102b48SJeremy L Thompson CeedChk(ierr); 3705107b09fSJeremy L Thompson } else { 3715107b09fSJeremy L Thompson // Fallback to reference Ceed 3725107b09fSJeremy L Thompson if (!op->opfallback) { 3735107b09fSJeremy L Thompson ierr = CeedOperatorCreateFallback(op); CeedChk(ierr); 3745107b09fSJeremy L Thompson } 3755107b09fSJeremy L Thompson // Assemble 3765107b09fSJeremy L Thompson ierr = op->opfallback->AssembleLinearQFunction(op->opfallback, assembled, 3775107b09fSJeremy L Thompson rstr, request); CeedChk(ierr); 3785107b09fSJeremy L Thompson } 3791d102b48SJeremy L Thompson return 0; 3801d102b48SJeremy L Thompson } 3811d102b48SJeremy L Thompson 3821d102b48SJeremy L Thompson /** 383b7ec98d8SJeremy L Thompson @brief Assemble the diagonal of a square linear Operator 384b7ec98d8SJeremy L Thompson 385b7ec98d8SJeremy L Thompson This returns a CeedVector containing the diagonal of a linear CeedOperator. 386b7ec98d8SJeremy L Thompson 387b7ec98d8SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 388b7ec98d8SJeremy L Thompson @param[out] assembled CeedVector to store assembled CeedOperator diagonal 389b7ec98d8SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 390b7ec98d8SJeremy L Thompson CEED_REQUEST_IMMEDIATE 391b7ec98d8SJeremy L Thompson 392b7ec98d8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 393b7ec98d8SJeremy L Thompson 394b7ec98d8SJeremy L Thompson @ref Basic 395b7ec98d8SJeremy L Thompson **/ 3967f823360Sjeremylt int CeedOperatorAssembleLinearDiagonal(CeedOperator op, CeedVector *assembled, 3977f823360Sjeremylt CeedRequest *request) { 398b7ec98d8SJeremy L Thompson int ierr; 399b7ec98d8SJeremy L Thompson Ceed ceed = op->ceed; 400b7ec98d8SJeremy L Thompson CeedQFunction qf = op->qf; 401b7ec98d8SJeremy L Thompson 402b7ec98d8SJeremy L Thompson if (op->composite) { 403b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 404b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 405b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 406b7ec98d8SJeremy L Thompson } else { 407b7ec98d8SJeremy L Thompson if (op->nfields == 0) 408b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 409b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 410b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 411b7ec98d8SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 412b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 413b7ec98d8SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 414b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 4152cb0afc5Sjeremylt if (!op->hasrestriction) 416b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 417b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 418b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 419b7ec98d8SJeremy L Thompson if (op->numqpoints == 0) 420b7ec98d8SJeremy L Thompson // LCOV_EXCL_START 421b7ec98d8SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 422b7ec98d8SJeremy L Thompson // LCOV_EXCL_STOP 423b7ec98d8SJeremy L Thompson } 424b7ec98d8SJeremy L Thompson 425b7ec98d8SJeremy L Thompson // Use backend version, if available 426b7ec98d8SJeremy L Thompson if (op->AssembleLinearDiagonal) { 427b7ec98d8SJeremy L Thompson ierr = op->AssembleLinearDiagonal(op, assembled, request); CeedChk(ierr); 428b7ec98d8SJeremy L Thompson return 0; 429b7ec98d8SJeremy L Thompson } 430b7ec98d8SJeremy L Thompson 431b7ec98d8SJeremy L Thompson // Assemble QFunction 432b7ec98d8SJeremy L Thompson CeedVector assembledqf; 433b7ec98d8SJeremy L Thompson CeedElemRestriction rstr; 434b7ec98d8SJeremy L Thompson ierr = CeedOperatorAssembleLinearQFunction(op, &assembledqf, &rstr, request); 435b7ec98d8SJeremy L Thompson CeedChk(ierr); 436b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionDestroy(&rstr); CeedChk(ierr); 437b7ec98d8SJeremy L Thompson 438b7ec98d8SJeremy L Thompson // Determine active input basis 439112e3f70Sjeremylt CeedInt numemodein = 0, ncomp, dim = 1; 440b7ec98d8SJeremy L Thompson CeedEvalMode *emodein = NULL; 441112e3f70Sjeremylt CeedBasis basisin = NULL; 442112e3f70Sjeremylt CeedElemRestriction rstrin = NULL; 443b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numinputfields; i++) 444b7ec98d8SJeremy L Thompson if (op->inputfields[i]->vec == CEED_VECTOR_ACTIVE) { 445b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->inputfields[i], &basisin); 446b7ec98d8SJeremy L Thompson CeedChk(ierr); 447b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumComponents(basisin, &ncomp); CeedChk(ierr); 448b7ec98d8SJeremy L Thompson ierr = CeedBasisGetDimension(basisin, &dim); CeedChk(ierr); 449b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->inputfields[i], &rstrin); 450b7ec98d8SJeremy L Thompson CeedChk(ierr); 451b7ec98d8SJeremy L Thompson CeedEvalMode emode; 452b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->inputfields[i], &emode); 453b7ec98d8SJeremy L Thompson CeedChk(ierr); 454b7ec98d8SJeremy L Thompson switch (emode) { 455b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 456b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 457b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + 1, &emodein); CeedChk(ierr); 458b7ec98d8SJeremy L Thompson emodein[numemodein] = emode; 459b7ec98d8SJeremy L Thompson numemodein += 1; 460b7ec98d8SJeremy L Thompson break; 461b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 462b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodein + dim, &emodein); CeedChk(ierr); 463b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 464b7ec98d8SJeremy L Thompson emodein[numemodein+d] = emode; 465b7ec98d8SJeremy L Thompson numemodein += dim; 466b7ec98d8SJeremy L Thompson break; 467b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 468b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 469b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 470b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 471b7ec98d8SJeremy L Thompson } 472b7ec98d8SJeremy L Thompson } 473b7ec98d8SJeremy L Thompson 474b7ec98d8SJeremy L Thompson // Determine active output basis 475b7ec98d8SJeremy L Thompson CeedInt numemodeout = 0; 476b7ec98d8SJeremy L Thompson CeedEvalMode *emodeout = NULL; 477112e3f70Sjeremylt CeedBasis basisout = NULL; 478112e3f70Sjeremylt CeedElemRestriction rstrout = NULL; 479112e3f70Sjeremylt CeedTransposeMode lmodeout = CEED_NOTRANSPOSE; 480b7ec98d8SJeremy L Thompson for (CeedInt i=0; i<qf->numoutputfields; i++) 481b7ec98d8SJeremy L Thompson if (op->outputfields[i]->vec == CEED_VECTOR_ACTIVE) { 482b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetBasis(op->outputfields[i], &basisout); 483b7ec98d8SJeremy L Thompson CeedChk(ierr); 484b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetElemRestriction(op->outputfields[i], &rstrout); 485b7ec98d8SJeremy L Thompson CeedChk(ierr); 486b7ec98d8SJeremy L Thompson ierr = CeedOperatorFieldGetLMode(op->outputfields[i], &lmodeout); 487b7ec98d8SJeremy L Thompson CeedChk(ierr); 488b7ec98d8SJeremy L Thompson CeedEvalMode emode; 489b7ec98d8SJeremy L Thompson ierr = CeedQFunctionFieldGetEvalMode(qf->outputfields[i], &emode); 490b7ec98d8SJeremy L Thompson CeedChk(ierr); 491b7ec98d8SJeremy L Thompson switch (emode) { 492b7ec98d8SJeremy L Thompson case CEED_EVAL_NONE: 493b7ec98d8SJeremy L Thompson case CEED_EVAL_INTERP: 494b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + 1, &emodeout); CeedChk(ierr); 495b7ec98d8SJeremy L Thompson emodeout[numemodeout] = emode; 496b7ec98d8SJeremy L Thompson numemodeout += 1; 497b7ec98d8SJeremy L Thompson break; 498b7ec98d8SJeremy L Thompson case CEED_EVAL_GRAD: 499b7ec98d8SJeremy L Thompson ierr = CeedRealloc(numemodeout + dim, &emodeout); CeedChk(ierr); 500b7ec98d8SJeremy L Thompson for (CeedInt d=0; d<dim; d++) 501b7ec98d8SJeremy L Thompson emodeout[numemodeout+d] = emode; 502b7ec98d8SJeremy L Thompson numemodeout += dim; 503b7ec98d8SJeremy L Thompson break; 504b7ec98d8SJeremy L Thompson case CEED_EVAL_WEIGHT: 505b7ec98d8SJeremy L Thompson case CEED_EVAL_DIV: 506b7ec98d8SJeremy L Thompson case CEED_EVAL_CURL: 507b7ec98d8SJeremy L Thompson break; // Caught by QF Assembly 508b7ec98d8SJeremy L Thompson } 509b7ec98d8SJeremy L Thompson } 510b7ec98d8SJeremy L Thompson 511b7ec98d8SJeremy L Thompson // Create diagonal vector 512b7ec98d8SJeremy L Thompson CeedVector elemdiag; 513b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionCreateVector(rstrin, assembled, &elemdiag); 514b7ec98d8SJeremy L Thompson CeedChk(ierr); 515b7ec98d8SJeremy L Thompson 516b7ec98d8SJeremy L Thompson // Assemble element operator diagonals 517b7ec98d8SJeremy L Thompson CeedScalar *elemdiagarray, *assembledqfarray; 518b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(elemdiag, 0.0); CeedChk(ierr); 519b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(elemdiag, CEED_MEM_HOST, &elemdiagarray); 520b7ec98d8SJeremy L Thompson CeedChk(ierr); 521b7ec98d8SJeremy L Thompson ierr = CeedVectorGetArray(assembledqf, CEED_MEM_HOST, &assembledqfarray); 522b7ec98d8SJeremy L Thompson CeedChk(ierr); 523b7ec98d8SJeremy L Thompson CeedInt nelem, nnodes, nqpts; 524b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionGetNumElements(rstrin, &nelem); CeedChk(ierr); 525b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumNodes(basisin, &nnodes); CeedChk(ierr); 526b7ec98d8SJeremy L Thompson ierr = CeedBasisGetNumQuadraturePoints(basisin, &nqpts); CeedChk(ierr); 527b7ec98d8SJeremy L Thompson // Compute the diagonal of B^T D B 528b7ec98d8SJeremy L Thompson // Each node, qpt pair 529b7ec98d8SJeremy L Thompson for (CeedInt n=0; n<nnodes; n++) 530b7ec98d8SJeremy L Thompson for (CeedInt q=0; q<nqpts; q++) { 531b7ec98d8SJeremy L Thompson CeedInt dout = -1; 532b7ec98d8SJeremy L Thompson // Each basis eval mode pair 533b7ec98d8SJeremy L Thompson for (CeedInt eout=0; eout<numemodeout; eout++) { 534b7ec98d8SJeremy L Thompson CeedScalar bt = 1.0; 535b7ec98d8SJeremy L Thompson if (emodeout[eout] == CEED_EVAL_GRAD) 536b7ec98d8SJeremy L Thompson dout += 1; 537b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisout, emodeout[eout], q, n, dout, &bt); 538b7ec98d8SJeremy L Thompson CeedChk(ierr); 539b7ec98d8SJeremy L Thompson CeedInt din = -1; 540b7ec98d8SJeremy L Thompson for (CeedInt ein=0; ein<numemodein; ein++) { 541b7ec98d8SJeremy L Thompson CeedScalar b = 0.0; 542b7ec98d8SJeremy L Thompson if (emodein[ein] == CEED_EVAL_GRAD) 543b7ec98d8SJeremy L Thompson din += 1; 544b7ec98d8SJeremy L Thompson ierr = CeedBasisGetValue(basisin, emodein[ein], q, n, din, &b); 545b7ec98d8SJeremy L Thompson CeedChk(ierr); 546b7ec98d8SJeremy L Thompson // Each element and component 547b7ec98d8SJeremy L Thompson for (CeedInt e=0; e<nelem; e++) 548b7ec98d8SJeremy L Thompson for (CeedInt cout=0; cout<ncomp; cout++) { 549b7ec98d8SJeremy L Thompson CeedScalar db = 0.0; 550b7ec98d8SJeremy L Thompson for (CeedInt cin=0; cin<ncomp; cin++) 551b7ec98d8SJeremy L Thompson db += assembledqfarray[((((e*numemodein+ein)*ncomp+cin)* 552b7ec98d8SJeremy L Thompson numemodeout+eout)*ncomp+cout)*nqpts+q]*b; 553b7ec98d8SJeremy L Thompson elemdiagarray[(e*ncomp+cout)*nnodes+n] += bt * db; 554b7ec98d8SJeremy L Thompson } 555b7ec98d8SJeremy L Thompson } 556b7ec98d8SJeremy L Thompson } 557b7ec98d8SJeremy L Thompson } 558b7ec98d8SJeremy L Thompson 559b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(elemdiag, &elemdiagarray); CeedChk(ierr); 560b7ec98d8SJeremy L Thompson ierr = CeedVectorRestoreArray(assembledqf, &assembledqfarray); CeedChk(ierr); 561b7ec98d8SJeremy L Thompson 562b7ec98d8SJeremy L Thompson // Assemble local operator diagonal 563b7ec98d8SJeremy L Thompson ierr = CeedVectorSetValue(*assembled, 0.0); CeedChk(ierr); 564b7ec98d8SJeremy L Thompson ierr = CeedElemRestrictionApply(rstrout, CEED_TRANSPOSE, lmodeout, elemdiag, 565b7ec98d8SJeremy L Thompson *assembled, request); CeedChk(ierr); 566b7ec98d8SJeremy L Thompson 567b7ec98d8SJeremy L Thompson // Cleanup 568b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&assembledqf); CeedChk(ierr); 569b7ec98d8SJeremy L Thompson ierr = CeedVectorDestroy(&elemdiag); CeedChk(ierr); 570b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodein); CeedChk(ierr); 571b7ec98d8SJeremy L Thompson ierr = CeedFree(&emodeout); CeedChk(ierr); 572b7ec98d8SJeremy L Thompson 573b7ec98d8SJeremy L Thompson return 0; 574b7ec98d8SJeremy L Thompson } 575b7ec98d8SJeremy L Thompson 576b7ec98d8SJeremy L Thompson /** 577*cae8b89aSjeremylt @brief Apply CeedOperator to a vector and overwrite output vector 578d7b241e6Sjeremylt 579d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 580d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 581d7b241e6Sjeremylt CeedOperatorSetField(). 582d7b241e6Sjeremylt 583d7b241e6Sjeremylt @param op CeedOperator to apply 584b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 585b11c1e72Sjeremylt active inputs 586b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 587d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 588d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 589d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 590b11c1e72Sjeremylt 591b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 592dfdf5a53Sjeremylt 593dfdf5a53Sjeremylt @ref Basic 594b11c1e72Sjeremylt **/ 595692c2638Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, CeedVector out, 596692c2638Sjeremylt CeedRequest *request) { 597d7b241e6Sjeremylt int ierr; 598d7b241e6Sjeremylt Ceed ceed = op->ceed; 599d7b241e6Sjeremylt CeedQFunction qf = op->qf; 600d7b241e6Sjeremylt 60152d6035fSJeremy L Thompson if (op->composite) { 602c042f62fSJeremy L Thompson if (!op->numsub) 603c042f62fSJeremy L Thompson // LCOV_EXCL_START 604c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No suboperators set"); 605c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 60652d6035fSJeremy L Thompson } else { 607c042f62fSJeremy L Thompson if (op->nfields == 0) 608c042f62fSJeremy L Thompson // LCOV_EXCL_START 609c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 610c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 611c042f62fSJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 612c042f62fSJeremy L Thompson // LCOV_EXCL_START 613c042f62fSJeremy L Thompson return CeedError(ceed, 1, "Not all operator fields set"); 614c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 6152cb0afc5Sjeremylt if (!op->hasrestriction) 616c042f62fSJeremy L Thompson // LCOV_EXCL_START 617c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one restriction required"); 618c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 619c042f62fSJeremy L Thompson if (op->numqpoints == 0) 620c042f62fSJeremy L Thompson // LCOV_EXCL_START 621c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 622c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 62352d6035fSJeremy L Thompson } 6241d7d2407SJeremy L Thompson if (op->numelements || op->composite) { 625*cae8b89aSjeremylt if (op->Apply) { 626e97ff134Sjeremylt ierr = op->Apply(op, in != CEED_VECTOR_NONE ? in : NULL, 627e97ff134Sjeremylt out != CEED_VECTOR_NONE ? out : NULL, request); 628e97ff134Sjeremylt CeedChk(ierr); 629*cae8b89aSjeremylt } else { 630*cae8b89aSjeremylt // Zero all output vectors 631*cae8b89aSjeremylt if (!op->composite) { 632*cae8b89aSjeremylt for (CeedInt i=0; i<qf->numoutputfields; i++) { 633*cae8b89aSjeremylt CeedVector vec = op->outputfields[i]->vec; 634*cae8b89aSjeremylt if (vec == CEED_VECTOR_ACTIVE) 635*cae8b89aSjeremylt vec = out; 636*cae8b89aSjeremylt if (vec != CEED_VECTOR_NONE) { 637*cae8b89aSjeremylt ierr = CeedVectorSetValue(vec, 0.0); CeedChk(ierr); 638*cae8b89aSjeremylt } 639*cae8b89aSjeremylt } 640*cae8b89aSjeremylt } else if (out != CEED_VECTOR_NONE) { // Zero active output if composite 641*cae8b89aSjeremylt ierr = CeedVectorSetValue(out, 0.0); CeedChk(ierr); 642*cae8b89aSjeremylt } 643*cae8b89aSjeremylt ierr = op->ApplyAdd(op, in != CEED_VECTOR_NONE ? in : NULL, 644*cae8b89aSjeremylt out != CEED_VECTOR_NONE ? out : NULL, request); 645*cae8b89aSjeremylt CeedChk(ierr); 646*cae8b89aSjeremylt } 647*cae8b89aSjeremylt } 648*cae8b89aSjeremylt return 0; 649*cae8b89aSjeremylt } 650*cae8b89aSjeremylt 651*cae8b89aSjeremylt /** 652*cae8b89aSjeremylt @brief Apply CeedOperator to a vector and add result to output vector 653*cae8b89aSjeremylt 654*cae8b89aSjeremylt This computes the action of the operator on the specified (active) input, 655*cae8b89aSjeremylt yielding its (active) output. All inputs and outputs must be specified using 656*cae8b89aSjeremylt CeedOperatorSetField(). 657*cae8b89aSjeremylt 658*cae8b89aSjeremylt @param op CeedOperator to apply 659*cae8b89aSjeremylt @param[in] in CeedVector containing input state or NULL if there are no 660*cae8b89aSjeremylt active inputs 661*cae8b89aSjeremylt @param[out] out CeedVector to sum in result of applying operator (must be 662*cae8b89aSjeremylt distinct from @a in) or NULL if there are no active outputs 663*cae8b89aSjeremylt @param request Address of CeedRequest for non-blocking completion, else 664*cae8b89aSjeremylt CEED_REQUEST_IMMEDIATE 665*cae8b89aSjeremylt 666*cae8b89aSjeremylt @return An error code: 0 - success, otherwise - failure 667*cae8b89aSjeremylt 668*cae8b89aSjeremylt @ref Basic 669*cae8b89aSjeremylt **/ 670*cae8b89aSjeremylt int CeedOperatorApplyAdd(CeedOperator op, CeedVector in, CeedVector out, 671*cae8b89aSjeremylt CeedRequest *request) { 672*cae8b89aSjeremylt int ierr; 673*cae8b89aSjeremylt Ceed ceed = op->ceed; 674*cae8b89aSjeremylt CeedQFunction qf = op->qf; 675*cae8b89aSjeremylt 676*cae8b89aSjeremylt if (op->composite) { 677*cae8b89aSjeremylt if (!op->numsub) 678*cae8b89aSjeremylt // LCOV_EXCL_START 679*cae8b89aSjeremylt return CeedError(ceed, 1, "No suboperators set"); 680*cae8b89aSjeremylt // LCOV_EXCL_STOP 681*cae8b89aSjeremylt } else { 682*cae8b89aSjeremylt if (op->nfields == 0) 683*cae8b89aSjeremylt // LCOV_EXCL_START 684*cae8b89aSjeremylt return CeedError(ceed, 1, "No operator fields set"); 685*cae8b89aSjeremylt // LCOV_EXCL_STOP 686*cae8b89aSjeremylt if (op->nfields < qf->numinputfields + qf->numoutputfields) 687*cae8b89aSjeremylt // LCOV_EXCL_START 688*cae8b89aSjeremylt return CeedError(ceed, 1, "Not all operator fields set"); 689*cae8b89aSjeremylt // LCOV_EXCL_STOP 690*cae8b89aSjeremylt if (!op->hasrestriction) 691*cae8b89aSjeremylt // LCOV_EXCL_START 692*cae8b89aSjeremylt return CeedError(ceed, 1,"At least one restriction required"); 693*cae8b89aSjeremylt // LCOV_EXCL_STOP 694*cae8b89aSjeremylt if (op->numqpoints == 0) 695*cae8b89aSjeremylt // LCOV_EXCL_START 696*cae8b89aSjeremylt return CeedError(ceed, 1,"At least one non-collocated basis required"); 697*cae8b89aSjeremylt // LCOV_EXCL_STOP 698*cae8b89aSjeremylt } 699*cae8b89aSjeremylt if (op->numelements || op->composite) { 700*cae8b89aSjeremylt ierr = op->ApplyAdd(op, in != CEED_VECTOR_NONE ? in : NULL, 701*cae8b89aSjeremylt out != CEED_VECTOR_NONE ? out : NULL, request); 702*cae8b89aSjeremylt CeedChk(ierr); 7031d7d2407SJeremy L Thompson } 704d7b241e6Sjeremylt return 0; 705d7b241e6Sjeremylt } 706d7b241e6Sjeremylt 707d7b241e6Sjeremylt /** 7084ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 7094ce2993fSjeremylt 7104ce2993fSjeremylt @param op CeedOperator 7114ce2993fSjeremylt @param[out] ceed Variable to store Ceed 7124ce2993fSjeremylt 7134ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7144ce2993fSjeremylt 71523617272Sjeremylt @ref Advanced 7164ce2993fSjeremylt **/ 7174ce2993fSjeremylt 7184ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 7194ce2993fSjeremylt *ceed = op->ceed; 7204ce2993fSjeremylt return 0; 7214ce2993fSjeremylt } 7224ce2993fSjeremylt 7234ce2993fSjeremylt /** 7244ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 7254ce2993fSjeremylt 7264ce2993fSjeremylt @param op CeedOperator 7274ce2993fSjeremylt @param[out] numelem Variable to store number of elements 7284ce2993fSjeremylt 7294ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7304ce2993fSjeremylt 73123617272Sjeremylt @ref Advanced 7324ce2993fSjeremylt **/ 7334ce2993fSjeremylt 7344ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 73552d6035fSJeremy L Thompson if (op->composite) 736c042f62fSJeremy L Thompson // LCOV_EXCL_START 73752d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 738c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 73952d6035fSJeremy L Thompson 7404ce2993fSjeremylt *numelem = op->numelements; 7414ce2993fSjeremylt return 0; 7424ce2993fSjeremylt } 7434ce2993fSjeremylt 7444ce2993fSjeremylt /** 7454ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 7464ce2993fSjeremylt 7474ce2993fSjeremylt @param op CeedOperator 7484ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 7494ce2993fSjeremylt 7504ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7514ce2993fSjeremylt 75223617272Sjeremylt @ref Advanced 7534ce2993fSjeremylt **/ 7544ce2993fSjeremylt 7554ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 75652d6035fSJeremy L Thompson if (op->composite) 757c042f62fSJeremy L Thompson // LCOV_EXCL_START 75852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 759c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 76052d6035fSJeremy L Thompson 7614ce2993fSjeremylt *numqpts = op->numqpoints; 7624ce2993fSjeremylt return 0; 7634ce2993fSjeremylt } 7644ce2993fSjeremylt 7654ce2993fSjeremylt /** 7664ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 7674ce2993fSjeremylt 7684ce2993fSjeremylt @param op CeedOperator 7694ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 7704ce2993fSjeremylt 7714ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7724ce2993fSjeremylt 77323617272Sjeremylt @ref Advanced 7744ce2993fSjeremylt **/ 7754ce2993fSjeremylt 7764ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 77752d6035fSJeremy L Thompson if (op->composite) 778c042f62fSJeremy L Thompson // LCOV_EXCL_START 77952d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 780c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 781c042f62fSJeremy L Thompson 7824ce2993fSjeremylt *numargs = op->nfields; 7834ce2993fSjeremylt return 0; 7844ce2993fSjeremylt } 7854ce2993fSjeremylt 7864ce2993fSjeremylt /** 7874ce2993fSjeremylt @brief Get the setup status of a CeedOperator 7884ce2993fSjeremylt 7894ce2993fSjeremylt @param op CeedOperator 790288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 7914ce2993fSjeremylt 7924ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 7934ce2993fSjeremylt 79423617272Sjeremylt @ref Advanced 7954ce2993fSjeremylt **/ 7964ce2993fSjeremylt 7974ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 7984ce2993fSjeremylt *setupdone = op->setupdone; 7994ce2993fSjeremylt return 0; 8004ce2993fSjeremylt } 8014ce2993fSjeremylt 8024ce2993fSjeremylt /** 8034ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 8044ce2993fSjeremylt 8054ce2993fSjeremylt @param op CeedOperator 8068c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 8074ce2993fSjeremylt 8084ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 8094ce2993fSjeremylt 81023617272Sjeremylt @ref Advanced 8114ce2993fSjeremylt **/ 8124ce2993fSjeremylt 8134ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 81452d6035fSJeremy L Thompson if (op->composite) 815c042f62fSJeremy L Thompson // LCOV_EXCL_START 81652d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 817c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 81852d6035fSJeremy L Thompson 8194ce2993fSjeremylt *qf = op->qf; 8204ce2993fSjeremylt return 0; 8214ce2993fSjeremylt } 8224ce2993fSjeremylt 8234ce2993fSjeremylt /** 82452d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 82552d6035fSJeremy L Thompson 82652d6035fSJeremy L Thompson @param op CeedOperator 82752d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 82852d6035fSJeremy L Thompson 82952d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83052d6035fSJeremy L Thompson 83152d6035fSJeremy L Thompson @ref Advanced 83252d6035fSJeremy L Thompson **/ 83352d6035fSJeremy L Thompson 83452d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 835c042f62fSJeremy L Thompson if (!op->composite) 836c042f62fSJeremy L Thompson // LCOV_EXCL_START 837c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 838c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 83952d6035fSJeremy L Thompson 84052d6035fSJeremy L Thompson *numsub = op->numsub; 84152d6035fSJeremy L Thompson return 0; 84252d6035fSJeremy L Thompson } 84352d6035fSJeremy L Thompson 84452d6035fSJeremy L Thompson /** 84552d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 84652d6035fSJeremy L Thompson 84752d6035fSJeremy L Thompson @param op CeedOperator 84852d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 84952d6035fSJeremy L Thompson 85052d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 85152d6035fSJeremy L Thompson 85252d6035fSJeremy L Thompson @ref Advanced 85352d6035fSJeremy L Thompson **/ 85452d6035fSJeremy L Thompson 85552d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator **suboperators) { 856c042f62fSJeremy L Thompson if (!op->composite) 857c042f62fSJeremy L Thompson // LCOV_EXCL_START 858c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 859c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 86052d6035fSJeremy L Thompson 86152d6035fSJeremy L Thompson *suboperators = op->suboperators; 86252d6035fSJeremy L Thompson return 0; 86352d6035fSJeremy L Thompson } 86452d6035fSJeremy L Thompson 86552d6035fSJeremy L Thompson /** 866fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 867fe2413ffSjeremylt 868fe2413ffSjeremylt @param[out] op CeedOperator 869fe2413ffSjeremylt @param data Data to set 870fe2413ffSjeremylt 871fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 872fe2413ffSjeremylt 873fe2413ffSjeremylt @ref Advanced 874fe2413ffSjeremylt **/ 875fe2413ffSjeremylt 876fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void **data) { 877fe2413ffSjeremylt op->data = *data; 878fe2413ffSjeremylt return 0; 879fe2413ffSjeremylt } 880fe2413ffSjeremylt 881fe2413ffSjeremylt /** 8824ce2993fSjeremylt @brief Get the backend data of a CeedOperator 8834ce2993fSjeremylt 8844ce2993fSjeremylt @param op CeedOperator 8854ce2993fSjeremylt @param[out] data Variable to store data 8864ce2993fSjeremylt 8874ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 8884ce2993fSjeremylt 88923617272Sjeremylt @ref Advanced 8904ce2993fSjeremylt **/ 8914ce2993fSjeremylt 8924ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void **data) { 8934ce2993fSjeremylt *data = op->data; 8944ce2993fSjeremylt return 0; 8954ce2993fSjeremylt } 8964ce2993fSjeremylt 8974ce2993fSjeremylt /** 8984ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 8994ce2993fSjeremylt 9004ce2993fSjeremylt @param op CeedOperator 9014ce2993fSjeremylt 9024ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 9034ce2993fSjeremylt 90423617272Sjeremylt @ref Advanced 9054ce2993fSjeremylt **/ 9064ce2993fSjeremylt 9074ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 9084ce2993fSjeremylt op->setupdone = 1; 9094ce2993fSjeremylt return 0; 9104ce2993fSjeremylt } 9114ce2993fSjeremylt 9124ce2993fSjeremylt /** 9132ebaca42Sjeremylt @brief View a field of a CeedOperator 9142ebaca42Sjeremylt 9152ebaca42Sjeremylt @param[in] field Operator field to view 9162ebaca42Sjeremylt @param[in] fieldnumber Number of field being viewed 9172ebaca42Sjeremylt @param[in] stream Stream to view to, e.g., stdout 9182ebaca42Sjeremylt 9192ebaca42Sjeremylt @return An error code: 0 - success, otherwise - failure 9202ebaca42Sjeremylt 9212ebaca42Sjeremylt @ref Utility 9222ebaca42Sjeremylt **/ 9232ebaca42Sjeremylt static int CeedOperatorFieldView(CeedOperatorField field, 9242ebaca42Sjeremylt CeedQFunctionField qffield, 9252da88da5Sjeremylt CeedInt fieldnumber, bool sub, bool in, 9262da88da5Sjeremylt FILE *stream) { 9272ebaca42Sjeremylt const char *pre = sub ? " " : ""; 9282da88da5Sjeremylt const char *inout = in ? "Input" : "Output"; 9292ebaca42Sjeremylt 9302da88da5Sjeremylt fprintf(stream, "%s %s Field [%d]:\n" 9312da88da5Sjeremylt "%s Name: \"%s\"\n" 9322da88da5Sjeremylt "%s Lmode: \"%s\"\n", 9332da88da5Sjeremylt pre, inout, fieldnumber, pre, qffield->fieldname, 9342ebaca42Sjeremylt pre, CeedTransposeModes[field->lmode]); 9352ebaca42Sjeremylt 9362ebaca42Sjeremylt if (field->basis == CEED_BASIS_COLLOCATED) 9372ebaca42Sjeremylt fprintf(stream, "%s Collocated basis\n", pre); 9382ebaca42Sjeremylt 9392ebaca42Sjeremylt if (field->vec == CEED_VECTOR_ACTIVE) 9402ebaca42Sjeremylt fprintf(stream, "%s Active vector\n", pre); 9412ebaca42Sjeremylt else if (field->vec == CEED_VECTOR_NONE) 9422ebaca42Sjeremylt fprintf(stream, "%s No vector\n", pre); 9432ebaca42Sjeremylt 9442ebaca42Sjeremylt return 0; 9452ebaca42Sjeremylt } 9462ebaca42Sjeremylt 9472ebaca42Sjeremylt /** 9482ebaca42Sjeremylt @brief View a single CeedOperator 9492ebaca42Sjeremylt 9502ebaca42Sjeremylt @param[in] op CeedOperator to view 9512ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 9522ebaca42Sjeremylt 9532ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 9542ebaca42Sjeremylt 9552ebaca42Sjeremylt @ref Utility 9562ebaca42Sjeremylt **/ 9572ebaca42Sjeremylt int CeedOperatorSingleView(CeedOperator op, bool sub, FILE *stream) { 9582ebaca42Sjeremylt int ierr; 9592ebaca42Sjeremylt const char *pre = sub ? " " : ""; 9602ebaca42Sjeremylt 9612ebaca42Sjeremylt CeedInt totalfields; 9622ebaca42Sjeremylt ierr = CeedOperatorGetNumArgs(op, &totalfields); CeedChk(ierr); 9632da88da5Sjeremylt 9642ebaca42Sjeremylt fprintf(stream, "%s %d Field%s\n", pre, totalfields, totalfields>1 ? "s" : ""); 9652ebaca42Sjeremylt 9662da88da5Sjeremylt fprintf(stream, "%s %d Input Field%s:\n", pre, op->qf->numinputfields, 9672ebaca42Sjeremylt op->qf->numinputfields>1 ? "s" : ""); 9682ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 9692ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->inputfields[i], op->qf->inputfields[i], 9702da88da5Sjeremylt i, sub, 1, stream); CeedChk(ierr); 9712ebaca42Sjeremylt } 9722ebaca42Sjeremylt 9732da88da5Sjeremylt fprintf(stream, "%s %d Output Field%s:\n", pre, op->qf->numoutputfields, 9742ebaca42Sjeremylt op->qf->numoutputfields>1 ? "s" : ""); 9752ebaca42Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 9762ebaca42Sjeremylt ierr = CeedOperatorFieldView(op->outputfields[i], op->qf->inputfields[i], 9772da88da5Sjeremylt i, sub, 0, stream); CeedChk(ierr); 9782ebaca42Sjeremylt } 9792ebaca42Sjeremylt 9802ebaca42Sjeremylt return 0; 9812ebaca42Sjeremylt } 9822ebaca42Sjeremylt 9832ebaca42Sjeremylt /** 9842ebaca42Sjeremylt @brief View a CeedOperator 9852ebaca42Sjeremylt 9862ebaca42Sjeremylt @param[in] op CeedOperator to view 9872ebaca42Sjeremylt @param[in] stream Stream to write; typically stdout/stderr or a file 9882ebaca42Sjeremylt 9892ebaca42Sjeremylt @return Error code: 0 - success, otherwise - failure 9902ebaca42Sjeremylt 9912ebaca42Sjeremylt @ref Utility 9922ebaca42Sjeremylt **/ 9932ebaca42Sjeremylt int CeedOperatorView(CeedOperator op, FILE *stream) { 9942ebaca42Sjeremylt int ierr; 9952ebaca42Sjeremylt 9962ebaca42Sjeremylt if (op->composite) { 9972ebaca42Sjeremylt fprintf(stream, "Composite CeedOperator\n"); 9982ebaca42Sjeremylt 9992ebaca42Sjeremylt for (CeedInt i=0; i<op->numsub; i++) { 10002da88da5Sjeremylt fprintf(stream, " SubOperator [%d]:\n", i); 10012ebaca42Sjeremylt ierr = CeedOperatorSingleView(op->suboperators[i], 1, stream); 10022ebaca42Sjeremylt CeedChk(ierr); 10032ebaca42Sjeremylt } 10042ebaca42Sjeremylt } else { 10052ebaca42Sjeremylt fprintf(stream, "CeedOperator\n"); 10062ebaca42Sjeremylt ierr = CeedOperatorSingleView(op, 0, stream); CeedChk(ierr); 10072ebaca42Sjeremylt } 10082ebaca42Sjeremylt 10092ebaca42Sjeremylt return 0; 10102ebaca42Sjeremylt } 10112ebaca42Sjeremylt 10122ebaca42Sjeremylt /** 1013d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 1014d1bcdac9Sjeremylt 1015d1bcdac9Sjeremylt @param op CeedOperator 1016d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 1017d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 1018d1bcdac9Sjeremylt 1019d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1020d1bcdac9Sjeremylt 1021d1bcdac9Sjeremylt @ref Advanced 1022d1bcdac9Sjeremylt **/ 1023d1bcdac9Sjeremylt 1024692c2638Sjeremylt int CeedOperatorGetFields(CeedOperator op, CeedOperatorField **inputfields, 1025d1bcdac9Sjeremylt CeedOperatorField **outputfields) { 102652d6035fSJeremy L Thompson if (op->composite) 1027c042f62fSJeremy L Thompson // LCOV_EXCL_START 102852d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 1029c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 103052d6035fSJeremy L Thompson 1031d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 1032d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 1033d1bcdac9Sjeremylt return 0; 1034d1bcdac9Sjeremylt } 1035d1bcdac9Sjeremylt 1036d1bcdac9Sjeremylt /** 10374dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 10384dccadb6Sjeremylt 10394dccadb6Sjeremylt @param opfield CeedOperatorField 10404dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 10414dccadb6Sjeremylt 10424dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 10434dccadb6Sjeremylt 10444dccadb6Sjeremylt @ref Advanced 10454dccadb6Sjeremylt **/ 10464dccadb6Sjeremylt 10474dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 10484dccadb6Sjeremylt CeedTransposeMode *lmode) { 1049fe2413ffSjeremylt *lmode = opfield->lmode; 10504dccadb6Sjeremylt return 0; 10512b8e417aSjeremylt } 10522b8e417aSjeremylt 10532b8e417aSjeremylt /** 1054d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 1055d1bcdac9Sjeremylt 1056d1bcdac9Sjeremylt @param opfield CeedOperatorField 1057d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 1058d1bcdac9Sjeremylt 1059d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1060d1bcdac9Sjeremylt 1061d1bcdac9Sjeremylt @ref Advanced 1062d1bcdac9Sjeremylt **/ 1063d1bcdac9Sjeremylt 1064d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 1065d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 1066fe2413ffSjeremylt *rstr = opfield->Erestrict; 1067d1bcdac9Sjeremylt return 0; 1068d1bcdac9Sjeremylt } 1069d1bcdac9Sjeremylt 1070d1bcdac9Sjeremylt /** 1071d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 1072d1bcdac9Sjeremylt 1073d1bcdac9Sjeremylt @param opfield CeedOperatorField 1074d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 1075d1bcdac9Sjeremylt 1076d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1077d1bcdac9Sjeremylt 1078d1bcdac9Sjeremylt @ref Advanced 1079d1bcdac9Sjeremylt **/ 1080d1bcdac9Sjeremylt 1081692c2638Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, CeedBasis *basis) { 1082fe2413ffSjeremylt *basis = opfield->basis; 1083d1bcdac9Sjeremylt return 0; 1084d1bcdac9Sjeremylt } 1085d1bcdac9Sjeremylt 1086d1bcdac9Sjeremylt /** 1087d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 1088d1bcdac9Sjeremylt 1089d1bcdac9Sjeremylt @param opfield CeedOperatorField 1090d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 1091d1bcdac9Sjeremylt 1092d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 1093d1bcdac9Sjeremylt 1094d1bcdac9Sjeremylt @ref Advanced 1095d1bcdac9Sjeremylt **/ 1096d1bcdac9Sjeremylt 1097692c2638Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, CeedVector *vec) { 1098fe2413ffSjeremylt *vec = opfield->vec; 1099d1bcdac9Sjeremylt return 0; 1100d1bcdac9Sjeremylt } 1101d1bcdac9Sjeremylt 1102d1bcdac9Sjeremylt /** 1103b11c1e72Sjeremylt @brief Destroy a CeedOperator 1104d7b241e6Sjeremylt 1105d7b241e6Sjeremylt @param op CeedOperator to destroy 1106b11c1e72Sjeremylt 1107b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1108dfdf5a53Sjeremylt 1109dfdf5a53Sjeremylt @ref Basic 1110b11c1e72Sjeremylt **/ 1111d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 1112d7b241e6Sjeremylt int ierr; 1113d7b241e6Sjeremylt 1114d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 1115d7b241e6Sjeremylt if ((*op)->Destroy) { 1116d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 1117d7b241e6Sjeremylt } 1118fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 1119fe2413ffSjeremylt // Free fields 11201d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 112152d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 112271352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 112371352a93Sjeremylt CeedChk(ierr); 112471352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 112571352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 112671352a93Sjeremylt } 112771352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 112871352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 112971352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 113071352a93Sjeremylt } 1131fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 1132fe2413ffSjeremylt } 11331d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 1134d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 113571352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 113671352a93Sjeremylt CeedChk(ierr); 113771352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 113871352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 113971352a93Sjeremylt } 114071352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 114171352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 114271352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 114371352a93Sjeremylt } 1144fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 1145fe2413ffSjeremylt } 114652d6035fSJeremy L Thompson // Destroy suboperators 11471d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 114852d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 114952d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 115052d6035fSJeremy L Thompson } 1151d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 1152d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 1153d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 1154fe2413ffSjeremylt 11555107b09fSJeremy L Thompson // Destroy fallback 11565107b09fSJeremy L Thompson if ((*op)->opfallback) { 11575107b09fSJeremy L Thompson ierr = (*op)->qffallback->Destroy((*op)->qffallback); CeedChk(ierr); 11585107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->qffallback); CeedChk(ierr); 11595107b09fSJeremy L Thompson ierr = (*op)->opfallback->Destroy((*op)->opfallback); CeedChk(ierr); 11605107b09fSJeremy L Thompson ierr = CeedFree(&(*op)->opfallback); CeedChk(ierr); 11615107b09fSJeremy L Thompson } 11625107b09fSJeremy L Thompson 1163fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 1164fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 116552d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 1166d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 1167d7b241e6Sjeremylt return 0; 1168d7b241e6Sjeremylt } 1169d7b241e6Sjeremylt 1170d7b241e6Sjeremylt /// @} 1171