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; 65d7b241e6Sjeremylt (*op)->qf = qf; 66d7b241e6Sjeremylt qf->refcount++; 67d7b241e6Sjeremylt (*op)->dqf = dqf; 68d7b241e6Sjeremylt if (dqf) dqf->refcount++; 69d7b241e6Sjeremylt (*op)->dqfT = dqfT; 70d7b241e6Sjeremylt if (dqfT) dqfT->refcount++; 71fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr); 72fe2413ffSjeremylt ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr); 73d7b241e6Sjeremylt ierr = ceed->OperatorCreate(*op); CeedChk(ierr); 74d7b241e6Sjeremylt return 0; 75d7b241e6Sjeremylt } 76d7b241e6Sjeremylt 77d7b241e6Sjeremylt /** 7852d6035fSJeremy L Thompson @brief Create an operator that composes the action of several operators 7952d6035fSJeremy L Thompson 8052d6035fSJeremy L Thompson @param ceed A Ceed object where the CeedOperator will be created 8152d6035fSJeremy L Thompson @param[out] op Address of the variable where the newly created 8252d6035fSJeremy L Thompson Composite CeedOperator will be stored 8352d6035fSJeremy L Thompson 8452d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8552d6035fSJeremy L Thompson 8652d6035fSJeremy L Thompson @ref Basic 8752d6035fSJeremy L Thompson */ 8852d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) { 8952d6035fSJeremy L Thompson int ierr; 9052d6035fSJeremy L Thompson 9152d6035fSJeremy L Thompson if (!ceed->CompositeOperatorCreate) { 9252d6035fSJeremy L Thompson Ceed delegate; 93aefd8378Sjeremylt ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr); 9452d6035fSJeremy L Thompson 9552d6035fSJeremy L Thompson if (!delegate) 96c042f62fSJeremy L Thompson // LCOV_EXCL_START 971d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 981d102b48SJeremy L Thompson "CompositeOperatorCreate"); 99c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 10052d6035fSJeremy L Thompson 10152d6035fSJeremy L Thompson ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr); 10252d6035fSJeremy L Thompson return 0; 10352d6035fSJeremy L Thompson } 10452d6035fSJeremy L Thompson 10552d6035fSJeremy L Thompson ierr = CeedCalloc(1,op); CeedChk(ierr); 10652d6035fSJeremy L Thompson (*op)->ceed = ceed; 10752d6035fSJeremy L Thompson ceed->refcount++; 10852d6035fSJeremy L Thompson (*op)->composite = true; 10952d6035fSJeremy L Thompson ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr); 11052d6035fSJeremy L Thompson ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr); 11152d6035fSJeremy L Thompson return 0; 11252d6035fSJeremy L Thompson } 11352d6035fSJeremy L Thompson 11452d6035fSJeremy L Thompson /** 115b11c1e72Sjeremylt @brief Provide a field to a CeedOperator for use by its CeedQFunction 116d7b241e6Sjeremylt 117d7b241e6Sjeremylt This function is used to specify both active and passive fields to a 118d7b241e6Sjeremylt CeedOperator. For passive fields, a vector @arg v must be provided. Passive 119d7b241e6Sjeremylt fields can inputs or outputs (updated in-place when operator is applied). 120d7b241e6Sjeremylt 121d7b241e6Sjeremylt Active fields must be specified using this function, but their data (in a 122d7b241e6Sjeremylt CeedVector) is passed in CeedOperatorApply(). There can be at most one active 123d7b241e6Sjeremylt input and at most one active output. 124d7b241e6Sjeremylt 1258c91a0c9SJeremy L Thompson @param op CeedOperator on which to provide the field 1268795c945Sjeremylt @param fieldname Name of the field (to be matched with the name used by 1278795c945Sjeremylt CeedQFunction) 128b11c1e72Sjeremylt @param r CeedElemRestriction 129b0e29e78Sjeremylt @param lmode CeedTransposeMode which specifies the ordering of the 130b0e29e78Sjeremylt components of the l-vector used by this CeedOperatorField, 131b0e29e78Sjeremylt CEED_NOTRANSPOSE indicates the component is the 132b0e29e78Sjeremylt outermost index and CEED_TRANSPOSE indicates the component 133b0e29e78Sjeremylt is the innermost index in ordering of the l-vector 134783c99b3SValeria Barra @param b CeedBasis in which the field resides or CEED_BASIS_COLLOCATED 135b11c1e72Sjeremylt if collocated with quadrature points 136b11c1e72Sjeremylt @param v CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE 137b11c1e72Sjeremylt if field is active or CEED_VECTOR_NONE if using 1388c91a0c9SJeremy L Thompson CEED_EVAL_WEIGHT in the QFunction 139b11c1e72Sjeremylt 140b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 141dfdf5a53Sjeremylt 142dfdf5a53Sjeremylt @ref Basic 143b11c1e72Sjeremylt **/ 144d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname, 1454dccadb6Sjeremylt CeedElemRestriction r, CeedTransposeMode lmode, 1464dccadb6Sjeremylt CeedBasis b, CeedVector v) { 147d7b241e6Sjeremylt int ierr; 14852d6035fSJeremy L Thompson if (op->composite) 149c042f62fSJeremy L Thompson // LCOV_EXCL_START 15052d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Cannot add field to composite operator."); 151c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1528b067b84SJed Brown if (!r) 153c042f62fSJeremy L Thompson // LCOV_EXCL_START 154c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, 155c042f62fSJeremy L Thompson "ElemRestriction r for field \"%s\" must be non-NULL.", 156c042f62fSJeremy L Thompson fieldname); 157c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1588b067b84SJed Brown if (!b) 159c042f62fSJeremy L Thompson // LCOV_EXCL_START 160c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", 161c042f62fSJeremy L Thompson fieldname); 162c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 1638b067b84SJed Brown if (!v) 164c042f62fSJeremy L Thompson // LCOV_EXCL_START 165c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", 166c042f62fSJeremy L Thompson fieldname); 167c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 16852d6035fSJeremy L Thompson 169d7b241e6Sjeremylt CeedInt numelements; 170d7b241e6Sjeremylt ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr); 171d7b241e6Sjeremylt if (op->numelements && op->numelements != numelements) 172c042f62fSJeremy L Thompson // LCOV_EXCL_START 173d7b241e6Sjeremylt return CeedError(op->ceed, 1, 1741d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 1751d102b48SJeremy L Thompson "%d elements", numelements, op->numelements); 176c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 177d7b241e6Sjeremylt op->numelements = numelements; 178d7b241e6Sjeremylt 179783c99b3SValeria Barra if (b != CEED_BASIS_COLLOCATED) { 180d7b241e6Sjeremylt CeedInt numqpoints; 181d7b241e6Sjeremylt ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr); 182d7b241e6Sjeremylt if (op->numqpoints && op->numqpoints != numqpoints) 183c042f62fSJeremy L Thompson // LCOV_EXCL_START 1841d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 1851d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 1861d102b48SJeremy L Thompson op->numqpoints); 187c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 188d7b241e6Sjeremylt op->numqpoints = numqpoints; 189d7b241e6Sjeremylt } 190d1bcdac9Sjeremylt CeedOperatorField *ofield; 191d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numinputfields; i++) { 192fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) { 193d7b241e6Sjeremylt ofield = &op->inputfields[i]; 194d7b241e6Sjeremylt goto found; 195d7b241e6Sjeremylt } 196d7b241e6Sjeremylt } 197d7b241e6Sjeremylt for (CeedInt i=0; i<op->qf->numoutputfields; i++) { 198fe2413ffSjeremylt if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) { 199d7b241e6Sjeremylt ofield = &op->outputfields[i]; 200d7b241e6Sjeremylt goto found; 201d7b241e6Sjeremylt } 202d7b241e6Sjeremylt } 203c042f62fSJeremy L Thompson // LCOV_EXCL_START 204d7b241e6Sjeremylt return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'", 205d7b241e6Sjeremylt fieldname); 206c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 207d7b241e6Sjeremylt found: 208fe2413ffSjeremylt ierr = CeedCalloc(1, ofield); CeedChk(ierr); 209fe2413ffSjeremylt (*ofield)->Erestrict = r; 21071352a93Sjeremylt r->refcount += 1; 211fe2413ffSjeremylt (*ofield)->lmode = lmode; 212fe2413ffSjeremylt (*ofield)->basis = b; 21371352a93Sjeremylt if (b != CEED_BASIS_COLLOCATED) 21471352a93Sjeremylt b->refcount += 1; 215fe2413ffSjeremylt (*ofield)->vec = v; 21671352a93Sjeremylt if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE) 21771352a93Sjeremylt v->refcount += 1; 218d7b241e6Sjeremylt op->nfields += 1; 219d7b241e6Sjeremylt return 0; 220d7b241e6Sjeremylt } 221d7b241e6Sjeremylt 222d7b241e6Sjeremylt /** 22352d6035fSJeremy L Thompson @brief Add a sub-operator to a composite CeedOperator 224288c0443SJeremy L Thompson 225288c0443SJeremy L Thompson @param[out] compositeop Address of the composite CeedOperator 226288c0443SJeremy L Thompson @param subop Address of the sub-operator CeedOperator 22752d6035fSJeremy L Thompson 22852d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 22952d6035fSJeremy L Thompson 23052d6035fSJeremy L Thompson @ref Basic 23152d6035fSJeremy L Thompson */ 23252d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop, 23352d6035fSJeremy L Thompson CeedOperator subop) { 23452d6035fSJeremy L Thompson if (!compositeop->composite) 235c042f62fSJeremy L Thompson // LCOV_EXCL_START 2361d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 2371d102b48SJeremy L Thompson "operator"); 238c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 23952d6035fSJeremy L Thompson 24052d6035fSJeremy L Thompson if (compositeop->numsub == CEED_COMPOSITE_MAX) 241c042f62fSJeremy L Thompson // LCOV_EXCL_START 2421d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "Cannot add additional suboperators"); 243c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 24452d6035fSJeremy L Thompson 24552d6035fSJeremy L Thompson compositeop->suboperators[compositeop->numsub] = subop; 24652d6035fSJeremy L Thompson subop->refcount++; 24752d6035fSJeremy L Thompson compositeop->numsub++; 24852d6035fSJeremy L Thompson return 0; 24952d6035fSJeremy L Thompson } 25052d6035fSJeremy L Thompson 25152d6035fSJeremy L Thompson /** 2521d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 2531d102b48SJeremy L Thompson 2541d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 2551d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 2561d102b48SJeremy L Thompson The vector 'assembled' is of shape 2571d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 2581d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 2591d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 2601d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 2611d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 2621d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 2631d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 2641d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 2651d102b48SJeremy L Thompson 2661d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 2671d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled Ceed QFunction at 2681d102b48SJeremy L Thompson quadrature points 2691d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 2701d102b48SJeremy L Thompson CeedQFunction 2711d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 2721d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 2731d102b48SJeremy L Thompson 2741d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2751d102b48SJeremy L Thompson 2761d102b48SJeremy L Thompson @ref Advanced 2771d102b48SJeremy L Thompson **/ 2781d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 2791d102b48SJeremy L Thompson CeedElemRestriction *rstr, CeedRequest *request) { 2801d102b48SJeremy L Thompson int ierr; 2811d102b48SJeremy L Thompson Ceed ceed = op->ceed; 2821d102b48SJeremy L Thompson CeedQFunction qf = op->qf; 2831d102b48SJeremy L Thompson 2841d102b48SJeremy L Thompson if (op->composite) { 285*138d4072Sjeremylt // LCOV_EXCL_START 2861d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 287*138d4072Sjeremylt // LCOV_EXCL_STOP 2881d102b48SJeremy L Thompson } else { 2891d102b48SJeremy L Thompson if (op->nfields == 0) 290*138d4072Sjeremylt // LCOV_EXCL_START 2911d102b48SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 292*138d4072Sjeremylt // LCOV_EXCL_STOP 2931d102b48SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 294*138d4072Sjeremylt // LCOV_EXCL_START 2951d102b48SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 296*138d4072Sjeremylt // LCOV_EXCL_STOP 2971d102b48SJeremy L Thompson if (op->numelements == 0) 298*138d4072Sjeremylt // LCOV_EXCL_START 2991d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 300*138d4072Sjeremylt // LCOV_EXCL_STOP 3011d102b48SJeremy L Thompson if (op->numqpoints == 0) 302*138d4072Sjeremylt // LCOV_EXCL_START 3031d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 304*138d4072Sjeremylt // LCOV_EXCL_STOP 3051d102b48SJeremy L Thompson } 3061d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 3071d102b48SJeremy L Thompson CeedChk(ierr); 3081d102b48SJeremy L Thompson return 0; 3091d102b48SJeremy L Thompson } 3101d102b48SJeremy L Thompson 3111d102b48SJeremy L Thompson /** 312b11c1e72Sjeremylt @brief Apply CeedOperator to a vector 313d7b241e6Sjeremylt 314d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 315d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 316d7b241e6Sjeremylt CeedOperatorSetField(). 317d7b241e6Sjeremylt 318d7b241e6Sjeremylt @param op CeedOperator to apply 319b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 320b11c1e72Sjeremylt active inputs 321b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 322d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 323d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 324d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 325b11c1e72Sjeremylt 326b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 327dfdf5a53Sjeremylt 328dfdf5a53Sjeremylt @ref Basic 329b11c1e72Sjeremylt **/ 330d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, 331d7b241e6Sjeremylt CeedVector out, CeedRequest *request) { 332d7b241e6Sjeremylt int ierr; 333d7b241e6Sjeremylt Ceed ceed = op->ceed; 334d7b241e6Sjeremylt CeedQFunction qf = op->qf; 335d7b241e6Sjeremylt 33652d6035fSJeremy L Thompson if (op->composite) { 337c042f62fSJeremy L Thompson if (!op->numsub) 338c042f62fSJeremy L Thompson // LCOV_EXCL_START 339c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No suboperators set"); 340c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 34152d6035fSJeremy L Thompson } else { 342c042f62fSJeremy L Thompson if (op->nfields == 0) 343c042f62fSJeremy L Thompson // LCOV_EXCL_START 344c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 345c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 346c042f62fSJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 347c042f62fSJeremy L Thompson // LCOV_EXCL_START 348c042f62fSJeremy L Thompson return CeedError(ceed, 1, "Not all operator fields set"); 349c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 350c042f62fSJeremy L Thompson if (op->numelements == 0) 351c042f62fSJeremy L Thompson // LCOV_EXCL_START 352c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one restriction required"); 353c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 354c042f62fSJeremy L Thompson if (op->numqpoints == 0) 355c042f62fSJeremy L Thompson // LCOV_EXCL_START 356c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 357c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 35852d6035fSJeremy L Thompson } 359d7b241e6Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 360d7b241e6Sjeremylt return 0; 361d7b241e6Sjeremylt } 362d7b241e6Sjeremylt 363d7b241e6Sjeremylt /** 3644ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 3654ce2993fSjeremylt 3664ce2993fSjeremylt @param op CeedOperator 3674ce2993fSjeremylt @param[out] ceed Variable to store Ceed 3684ce2993fSjeremylt 3694ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 3704ce2993fSjeremylt 37123617272Sjeremylt @ref Advanced 3724ce2993fSjeremylt **/ 3734ce2993fSjeremylt 3744ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 3754ce2993fSjeremylt *ceed = op->ceed; 3764ce2993fSjeremylt return 0; 3774ce2993fSjeremylt } 3784ce2993fSjeremylt 3794ce2993fSjeremylt /** 3804ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 3814ce2993fSjeremylt 3824ce2993fSjeremylt @param op CeedOperator 3834ce2993fSjeremylt @param[out] numelem Variable to store number of elements 3844ce2993fSjeremylt 3854ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 3864ce2993fSjeremylt 38723617272Sjeremylt @ref Advanced 3884ce2993fSjeremylt **/ 3894ce2993fSjeremylt 3904ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 39152d6035fSJeremy L Thompson if (op->composite) 392c042f62fSJeremy L Thompson // LCOV_EXCL_START 39352d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 394c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 39552d6035fSJeremy L Thompson 3964ce2993fSjeremylt *numelem = op->numelements; 3974ce2993fSjeremylt return 0; 3984ce2993fSjeremylt } 3994ce2993fSjeremylt 4004ce2993fSjeremylt /** 4014ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 4024ce2993fSjeremylt 4034ce2993fSjeremylt @param op CeedOperator 4044ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 4054ce2993fSjeremylt 4064ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4074ce2993fSjeremylt 40823617272Sjeremylt @ref Advanced 4094ce2993fSjeremylt **/ 4104ce2993fSjeremylt 4114ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 41252d6035fSJeremy L Thompson if (op->composite) 413c042f62fSJeremy L Thompson // LCOV_EXCL_START 41452d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 415c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 41652d6035fSJeremy L Thompson 4174ce2993fSjeremylt *numqpts = op->numqpoints; 4184ce2993fSjeremylt return 0; 4194ce2993fSjeremylt } 4204ce2993fSjeremylt 4214ce2993fSjeremylt /** 4224ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 4234ce2993fSjeremylt 4244ce2993fSjeremylt @param op CeedOperator 4254ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 4264ce2993fSjeremylt 4274ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4284ce2993fSjeremylt 42923617272Sjeremylt @ref Advanced 4304ce2993fSjeremylt **/ 4314ce2993fSjeremylt 4324ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 43352d6035fSJeremy L Thompson if (op->composite) 434c042f62fSJeremy L Thompson // LCOV_EXCL_START 43552d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 436c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 437c042f62fSJeremy L Thompson 4384ce2993fSjeremylt *numargs = op->nfields; 4394ce2993fSjeremylt return 0; 4404ce2993fSjeremylt } 4414ce2993fSjeremylt 4424ce2993fSjeremylt /** 4434ce2993fSjeremylt @brief Get the setup status of a CeedOperator 4444ce2993fSjeremylt 4454ce2993fSjeremylt @param op CeedOperator 446288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 4474ce2993fSjeremylt 4484ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4494ce2993fSjeremylt 45023617272Sjeremylt @ref Advanced 4514ce2993fSjeremylt **/ 4524ce2993fSjeremylt 4534ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 4544ce2993fSjeremylt *setupdone = op->setupdone; 4554ce2993fSjeremylt return 0; 4564ce2993fSjeremylt } 4574ce2993fSjeremylt 4584ce2993fSjeremylt /** 4594ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 4604ce2993fSjeremylt 4614ce2993fSjeremylt @param op CeedOperator 4628c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 4634ce2993fSjeremylt 4644ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4654ce2993fSjeremylt 46623617272Sjeremylt @ref Advanced 4674ce2993fSjeremylt **/ 4684ce2993fSjeremylt 4694ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 47052d6035fSJeremy L Thompson if (op->composite) 471c042f62fSJeremy L Thompson // LCOV_EXCL_START 47252d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 473c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 47452d6035fSJeremy L Thompson 4754ce2993fSjeremylt *qf = op->qf; 4764ce2993fSjeremylt return 0; 4774ce2993fSjeremylt } 4784ce2993fSjeremylt 4794ce2993fSjeremylt /** 48052d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 48152d6035fSJeremy L Thompson 48252d6035fSJeremy L Thompson @param op CeedOperator 48352d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 48452d6035fSJeremy L Thompson 48552d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 48652d6035fSJeremy L Thompson 48752d6035fSJeremy L Thompson @ref Advanced 48852d6035fSJeremy L Thompson **/ 48952d6035fSJeremy L Thompson 49052d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 491c042f62fSJeremy L Thompson if (!op->composite) 492c042f62fSJeremy L Thompson // LCOV_EXCL_START 493c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 494c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 49552d6035fSJeremy L Thompson 49652d6035fSJeremy L Thompson *numsub = op->numsub; 49752d6035fSJeremy L Thompson return 0; 49852d6035fSJeremy L Thompson } 49952d6035fSJeremy L Thompson 50052d6035fSJeremy L Thompson /** 50152d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 50252d6035fSJeremy L Thompson 50352d6035fSJeremy L Thompson @param op CeedOperator 50452d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 50552d6035fSJeremy L Thompson 50652d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 50752d6035fSJeremy L Thompson 50852d6035fSJeremy L Thompson @ref Advanced 50952d6035fSJeremy L Thompson **/ 51052d6035fSJeremy L Thompson 51152d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) { 512c042f62fSJeremy L Thompson if (!op->composite) 513c042f62fSJeremy L Thompson // LCOV_EXCL_START 514c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 515c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 51652d6035fSJeremy L Thompson 51752d6035fSJeremy L Thompson *suboperators = op->suboperators; 51852d6035fSJeremy L Thompson return 0; 51952d6035fSJeremy L Thompson } 52052d6035fSJeremy L Thompson 52152d6035fSJeremy L Thompson /** 522fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 523fe2413ffSjeremylt 524fe2413ffSjeremylt @param[out] op CeedOperator 525fe2413ffSjeremylt @param data Data to set 526fe2413ffSjeremylt 527fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 528fe2413ffSjeremylt 529fe2413ffSjeremylt @ref Advanced 530fe2413ffSjeremylt **/ 531fe2413ffSjeremylt 532fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) { 533fe2413ffSjeremylt op->data = *data; 534fe2413ffSjeremylt return 0; 535fe2413ffSjeremylt } 536fe2413ffSjeremylt 537fe2413ffSjeremylt /** 5384ce2993fSjeremylt @brief Get the backend data of a CeedOperator 5394ce2993fSjeremylt 5404ce2993fSjeremylt @param op CeedOperator 5414ce2993fSjeremylt @param[out] data Variable to store data 5424ce2993fSjeremylt 5434ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5444ce2993fSjeremylt 54523617272Sjeremylt @ref Advanced 5464ce2993fSjeremylt **/ 5474ce2993fSjeremylt 5484ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) { 5494ce2993fSjeremylt *data = op->data; 5504ce2993fSjeremylt return 0; 5514ce2993fSjeremylt } 5524ce2993fSjeremylt 5534ce2993fSjeremylt /** 5544ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 5554ce2993fSjeremylt 5564ce2993fSjeremylt @param op CeedOperator 5574ce2993fSjeremylt 5584ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5594ce2993fSjeremylt 56023617272Sjeremylt @ref Advanced 5614ce2993fSjeremylt **/ 5624ce2993fSjeremylt 5634ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 5644ce2993fSjeremylt op->setupdone = 1; 5654ce2993fSjeremylt return 0; 5664ce2993fSjeremylt } 5674ce2993fSjeremylt 5684ce2993fSjeremylt /** 569d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 570d1bcdac9Sjeremylt 571d1bcdac9Sjeremylt @param op CeedOperator 572d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 573d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 574d1bcdac9Sjeremylt 575d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 576d1bcdac9Sjeremylt 577d1bcdac9Sjeremylt @ref Advanced 578d1bcdac9Sjeremylt **/ 579d1bcdac9Sjeremylt 580d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op, 581d1bcdac9Sjeremylt CeedOperatorField* *inputfields, 582d1bcdac9Sjeremylt CeedOperatorField* *outputfields) { 58352d6035fSJeremy L Thompson if (op->composite) 584c042f62fSJeremy L Thompson // LCOV_EXCL_START 58552d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 586c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 58752d6035fSJeremy L Thompson 588d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 589d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 590d1bcdac9Sjeremylt return 0; 591d1bcdac9Sjeremylt } 592d1bcdac9Sjeremylt 593d1bcdac9Sjeremylt /** 5944dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 5954dccadb6Sjeremylt 5964dccadb6Sjeremylt @param opfield CeedOperatorField 5974dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 5984dccadb6Sjeremylt 5994dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 6004dccadb6Sjeremylt 6014dccadb6Sjeremylt @ref Advanced 6024dccadb6Sjeremylt **/ 6034dccadb6Sjeremylt 6044dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 6054dccadb6Sjeremylt CeedTransposeMode *lmode) { 606fe2413ffSjeremylt *lmode = opfield->lmode; 6074dccadb6Sjeremylt return 0; 6082b8e417aSjeremylt } 6092b8e417aSjeremylt 6102b8e417aSjeremylt /** 611d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 612d1bcdac9Sjeremylt 613d1bcdac9Sjeremylt @param opfield CeedOperatorField 614d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 615d1bcdac9Sjeremylt 616d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 617d1bcdac9Sjeremylt 618d1bcdac9Sjeremylt @ref Advanced 619d1bcdac9Sjeremylt **/ 620d1bcdac9Sjeremylt 621d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 622d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 623fe2413ffSjeremylt *rstr = opfield->Erestrict; 624d1bcdac9Sjeremylt return 0; 625d1bcdac9Sjeremylt } 626d1bcdac9Sjeremylt 627d1bcdac9Sjeremylt /** 628d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 629d1bcdac9Sjeremylt 630d1bcdac9Sjeremylt @param opfield CeedOperatorField 631d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 632d1bcdac9Sjeremylt 633d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 634d1bcdac9Sjeremylt 635d1bcdac9Sjeremylt @ref Advanced 636d1bcdac9Sjeremylt **/ 637d1bcdac9Sjeremylt 638d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, 639d1bcdac9Sjeremylt CeedBasis *basis) { 640fe2413ffSjeremylt *basis = opfield->basis; 641d1bcdac9Sjeremylt return 0; 642d1bcdac9Sjeremylt } 643d1bcdac9Sjeremylt 644d1bcdac9Sjeremylt /** 645d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 646d1bcdac9Sjeremylt 647d1bcdac9Sjeremylt @param opfield CeedOperatorField 648d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 649d1bcdac9Sjeremylt 650d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 651d1bcdac9Sjeremylt 652d1bcdac9Sjeremylt @ref Advanced 653d1bcdac9Sjeremylt **/ 654d1bcdac9Sjeremylt 655d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, 656d1bcdac9Sjeremylt CeedVector *vec) { 657fe2413ffSjeremylt *vec = opfield->vec; 658d1bcdac9Sjeremylt return 0; 659d1bcdac9Sjeremylt } 660d1bcdac9Sjeremylt 661d1bcdac9Sjeremylt /** 662b11c1e72Sjeremylt @brief Destroy a CeedOperator 663d7b241e6Sjeremylt 664d7b241e6Sjeremylt @param op CeedOperator to destroy 665b11c1e72Sjeremylt 666b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 667dfdf5a53Sjeremylt 668dfdf5a53Sjeremylt @ref Basic 669b11c1e72Sjeremylt **/ 670d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 671d7b241e6Sjeremylt int ierr; 672d7b241e6Sjeremylt 673d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 674d7b241e6Sjeremylt if ((*op)->Destroy) { 675d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 676d7b241e6Sjeremylt } 677fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 678fe2413ffSjeremylt // Free fields 6791d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 68052d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 68171352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 68271352a93Sjeremylt CeedChk(ierr); 68371352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 68471352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 68571352a93Sjeremylt } 68671352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 68771352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 68871352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 68971352a93Sjeremylt } 690fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 691fe2413ffSjeremylt } 6921d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 693d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 69471352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 69571352a93Sjeremylt CeedChk(ierr); 69671352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 69771352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 69871352a93Sjeremylt } 69971352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 70071352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 70171352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 70271352a93Sjeremylt } 703fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 704fe2413ffSjeremylt } 70552d6035fSJeremy L Thompson // Destroy suboperators 7061d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 70752d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 70852d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 70952d6035fSJeremy L Thompson } 710d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 711d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 712d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 713fe2413ffSjeremylt 714fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 715fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 71652d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 717d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 718d7b241e6Sjeremylt return 0; 719d7b241e6Sjeremylt } 720d7b241e6Sjeremylt 721d7b241e6Sjeremylt /// @} 722