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 97*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support " 98*1d102b48SJeremy 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, 174*1d102b48SJeremy L Thompson "ElemRestriction with %d elements incompatible with prior " 175*1d102b48SJeremy 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 184*1d102b48SJeremy L Thompson return CeedError(op->ceed, 1, "Basis with %d quadrature points " 185*1d102b48SJeremy L Thompson "incompatible with prior %d points", numqpoints, 186*1d102b48SJeremy 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 236*1d102b48SJeremy L Thompson return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite " 237*1d102b48SJeremy 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 242*1d102b48SJeremy 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 /** 252*1d102b48SJeremy L Thompson @brief Assemble a linear CeedQFunction associated with a CeedOperator 253*1d102b48SJeremy L Thompson 254*1d102b48SJeremy L Thompson This returns a CeedVector containing a matrix at each quadrature point 255*1d102b48SJeremy L Thompson providing the action of the CeedQFunction associated with the CeedOperator. 256*1d102b48SJeremy L Thompson The vector 'assembled' is of shape 257*1d102b48SJeremy L Thompson [num_elements, num_input_fields, num_output_fields, num_quad_points] 258*1d102b48SJeremy L Thompson and contains column-major matrices representing the action of the 259*1d102b48SJeremy L Thompson CeedQFunction for a corresponding quadrature point on an element. Inputs and 260*1d102b48SJeremy L Thompson outputs are in the order provided by the user when adding CeedOperator fields. 261*1d102b48SJeremy L Thompson For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and 262*1d102b48SJeremy L Thompson 'v', provided in that order, would result in an assembled QFunction that 263*1d102b48SJeremy L Thompson consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting 264*1d102b48SJeremy L Thompson on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v]. 265*1d102b48SJeremy L Thompson 266*1d102b48SJeremy L Thompson @param op CeedOperator to assemble CeedQFunction 267*1d102b48SJeremy L Thompson @param[out] assembled CeedVector to store assembled Ceed QFunction at 268*1d102b48SJeremy L Thompson quadrature points 269*1d102b48SJeremy L Thompson @param[out] rstr CeedElemRestriction for CeedVector containing assembled 270*1d102b48SJeremy L Thompson CeedQFunction 271*1d102b48SJeremy L Thompson @param request Address of CeedRequest for non-blocking completion, else 272*1d102b48SJeremy L Thompson CEED_REQUEST_IMMEDIATE 273*1d102b48SJeremy L Thompson 274*1d102b48SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 275*1d102b48SJeremy L Thompson 276*1d102b48SJeremy L Thompson @ref Advanced 277*1d102b48SJeremy L Thompson **/ 278*1d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled, 279*1d102b48SJeremy L Thompson CeedElemRestriction *rstr, CeedRequest *request) { 280*1d102b48SJeremy L Thompson int ierr; 281*1d102b48SJeremy L Thompson Ceed ceed = op->ceed; 282*1d102b48SJeremy L Thompson CeedQFunction qf = op->qf; 283*1d102b48SJeremy L Thompson 284*1d102b48SJeremy L Thompson if (op->composite) { 285*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator"); 286*1d102b48SJeremy L Thompson } else { 287*1d102b48SJeremy L Thompson if (op->nfields == 0) 288*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 289*1d102b48SJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 290*1d102b48SJeremy L Thompson return CeedError( ceed, 1, "Not all operator fields set"); 291*1d102b48SJeremy L Thompson if (op->numelements == 0) 292*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one restriction required"); 293*1d102b48SJeremy L Thompson if (op->numqpoints == 0) 294*1d102b48SJeremy L Thompson return CeedError(ceed, 1, "At least one non-collocated basis required"); 295*1d102b48SJeremy L Thompson } 296*1d102b48SJeremy L Thompson ierr = op->AssembleLinearQFunction(op, assembled, rstr, request); 297*1d102b48SJeremy L Thompson CeedChk(ierr); 298*1d102b48SJeremy L Thompson return 0; 299*1d102b48SJeremy L Thompson } 300*1d102b48SJeremy L Thompson 301*1d102b48SJeremy L Thompson /** 302b11c1e72Sjeremylt @brief Apply CeedOperator to a vector 303d7b241e6Sjeremylt 304d7b241e6Sjeremylt This computes the action of the operator on the specified (active) input, 305d7b241e6Sjeremylt yielding its (active) output. All inputs and outputs must be specified using 306d7b241e6Sjeremylt CeedOperatorSetField(). 307d7b241e6Sjeremylt 308d7b241e6Sjeremylt @param op CeedOperator to apply 309b11c1e72Sjeremylt @param[in] in CeedVector containing input state or NULL if there are no 310b11c1e72Sjeremylt active inputs 311b11c1e72Sjeremylt @param[out] out CeedVector to store result of applying operator (must be 312d7b241e6Sjeremylt distinct from @a in) or NULL if there are no active outputs 313d7b241e6Sjeremylt @param request Address of CeedRequest for non-blocking completion, else 314d7b241e6Sjeremylt CEED_REQUEST_IMMEDIATE 315b11c1e72Sjeremylt 316b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 317dfdf5a53Sjeremylt 318dfdf5a53Sjeremylt @ref Basic 319b11c1e72Sjeremylt **/ 320d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in, 321d7b241e6Sjeremylt CeedVector out, CeedRequest *request) { 322d7b241e6Sjeremylt int ierr; 323d7b241e6Sjeremylt Ceed ceed = op->ceed; 324d7b241e6Sjeremylt CeedQFunction qf = op->qf; 325d7b241e6Sjeremylt 32652d6035fSJeremy L Thompson if (op->composite) { 327c042f62fSJeremy L Thompson if (!op->numsub) 328c042f62fSJeremy L Thompson // LCOV_EXCL_START 329c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No suboperators set"); 330c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 33152d6035fSJeremy L Thompson } else { 332c042f62fSJeremy L Thompson if (op->nfields == 0) 333c042f62fSJeremy L Thompson // LCOV_EXCL_START 334c042f62fSJeremy L Thompson return CeedError(ceed, 1, "No operator fields set"); 335c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 336c042f62fSJeremy L Thompson if (op->nfields < qf->numinputfields + qf->numoutputfields) 337c042f62fSJeremy L Thompson // LCOV_EXCL_START 338c042f62fSJeremy L Thompson return CeedError(ceed, 1, "Not all operator fields set"); 339c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 340c042f62fSJeremy L Thompson if (op->numelements == 0) 341c042f62fSJeremy L Thompson // LCOV_EXCL_START 342c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one restriction required"); 343c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 344c042f62fSJeremy L Thompson if (op->numqpoints == 0) 345c042f62fSJeremy L Thompson // LCOV_EXCL_START 346c042f62fSJeremy L Thompson return CeedError(ceed, 1,"At least one non-collocated basis required"); 347c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 34852d6035fSJeremy L Thompson } 349d7b241e6Sjeremylt ierr = op->Apply(op, in, out, request); CeedChk(ierr); 350d7b241e6Sjeremylt return 0; 351d7b241e6Sjeremylt } 352d7b241e6Sjeremylt 353d7b241e6Sjeremylt /** 3544ce2993fSjeremylt @brief Get the Ceed associated with a CeedOperator 3554ce2993fSjeremylt 3564ce2993fSjeremylt @param op CeedOperator 3574ce2993fSjeremylt @param[out] ceed Variable to store Ceed 3584ce2993fSjeremylt 3594ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 3604ce2993fSjeremylt 36123617272Sjeremylt @ref Advanced 3624ce2993fSjeremylt **/ 3634ce2993fSjeremylt 3644ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) { 3654ce2993fSjeremylt *ceed = op->ceed; 3664ce2993fSjeremylt return 0; 3674ce2993fSjeremylt } 3684ce2993fSjeremylt 3694ce2993fSjeremylt /** 3704ce2993fSjeremylt @brief Get the number of elements associated with a CeedOperator 3714ce2993fSjeremylt 3724ce2993fSjeremylt @param op CeedOperator 3734ce2993fSjeremylt @param[out] numelem Variable to store number of elements 3744ce2993fSjeremylt 3754ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 3764ce2993fSjeremylt 37723617272Sjeremylt @ref Advanced 3784ce2993fSjeremylt **/ 3794ce2993fSjeremylt 3804ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) { 38152d6035fSJeremy L Thompson if (op->composite) 382c042f62fSJeremy L Thompson // LCOV_EXCL_START 38352d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 384c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 38552d6035fSJeremy L Thompson 3864ce2993fSjeremylt *numelem = op->numelements; 3874ce2993fSjeremylt return 0; 3884ce2993fSjeremylt } 3894ce2993fSjeremylt 3904ce2993fSjeremylt /** 3914ce2993fSjeremylt @brief Get the number of quadrature points associated with a CeedOperator 3924ce2993fSjeremylt 3934ce2993fSjeremylt @param op CeedOperator 3944ce2993fSjeremylt @param[out] numqpts Variable to store vector number of quadrature points 3954ce2993fSjeremylt 3964ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 3974ce2993fSjeremylt 39823617272Sjeremylt @ref Advanced 3994ce2993fSjeremylt **/ 4004ce2993fSjeremylt 4014ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) { 40252d6035fSJeremy L Thompson if (op->composite) 403c042f62fSJeremy L Thompson // LCOV_EXCL_START 40452d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 405c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 40652d6035fSJeremy L Thompson 4074ce2993fSjeremylt *numqpts = op->numqpoints; 4084ce2993fSjeremylt return 0; 4094ce2993fSjeremylt } 4104ce2993fSjeremylt 4114ce2993fSjeremylt /** 4124ce2993fSjeremylt @brief Get the number of arguments associated with a CeedOperator 4134ce2993fSjeremylt 4144ce2993fSjeremylt @param op CeedOperator 4154ce2993fSjeremylt @param[out] numargs Variable to store vector number of arguments 4164ce2993fSjeremylt 4174ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4184ce2993fSjeremylt 41923617272Sjeremylt @ref Advanced 4204ce2993fSjeremylt **/ 4214ce2993fSjeremylt 4224ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) { 42352d6035fSJeremy L Thompson if (op->composite) 424c042f62fSJeremy L Thompson // LCOV_EXCL_START 42552d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operators"); 426c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 427c042f62fSJeremy L Thompson 4284ce2993fSjeremylt *numargs = op->nfields; 4294ce2993fSjeremylt return 0; 4304ce2993fSjeremylt } 4314ce2993fSjeremylt 4324ce2993fSjeremylt /** 4334ce2993fSjeremylt @brief Get the setup status of a CeedOperator 4344ce2993fSjeremylt 4354ce2993fSjeremylt @param op CeedOperator 436288c0443SJeremy L Thompson @param[out] setupdone Variable to store setup status 4374ce2993fSjeremylt 4384ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4394ce2993fSjeremylt 44023617272Sjeremylt @ref Advanced 4414ce2993fSjeremylt **/ 4424ce2993fSjeremylt 4434ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) { 4444ce2993fSjeremylt *setupdone = op->setupdone; 4454ce2993fSjeremylt return 0; 4464ce2993fSjeremylt } 4474ce2993fSjeremylt 4484ce2993fSjeremylt /** 4494ce2993fSjeremylt @brief Get the QFunction associated with a CeedOperator 4504ce2993fSjeremylt 4514ce2993fSjeremylt @param op CeedOperator 4528c91a0c9SJeremy L Thompson @param[out] qf Variable to store QFunction 4534ce2993fSjeremylt 4544ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 4554ce2993fSjeremylt 45623617272Sjeremylt @ref Advanced 4574ce2993fSjeremylt **/ 4584ce2993fSjeremylt 4594ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) { 46052d6035fSJeremy L Thompson if (op->composite) 461c042f62fSJeremy L Thompson // LCOV_EXCL_START 46252d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 463c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 46452d6035fSJeremy L Thompson 4654ce2993fSjeremylt *qf = op->qf; 4664ce2993fSjeremylt return 0; 4674ce2993fSjeremylt } 4684ce2993fSjeremylt 4694ce2993fSjeremylt /** 47052d6035fSJeremy L Thompson @brief Get the number of suboperators associated with a CeedOperator 47152d6035fSJeremy L Thompson 47252d6035fSJeremy L Thompson @param op CeedOperator 47352d6035fSJeremy L Thompson @param[out] numsub Variable to store number of suboperators 47452d6035fSJeremy L Thompson 47552d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 47652d6035fSJeremy L Thompson 47752d6035fSJeremy L Thompson @ref Advanced 47852d6035fSJeremy L Thompson **/ 47952d6035fSJeremy L Thompson 48052d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) { 481c042f62fSJeremy L Thompson if (!op->composite) 482c042f62fSJeremy L Thompson // LCOV_EXCL_START 483c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 484c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 48552d6035fSJeremy L Thompson 48652d6035fSJeremy L Thompson *numsub = op->numsub; 48752d6035fSJeremy L Thompson return 0; 48852d6035fSJeremy L Thompson } 48952d6035fSJeremy L Thompson 49052d6035fSJeremy L Thompson /** 49152d6035fSJeremy L Thompson @brief Get the list of suboperators associated with a CeedOperator 49252d6035fSJeremy L Thompson 49352d6035fSJeremy L Thompson @param op CeedOperator 49452d6035fSJeremy L Thompson @param[out] suboperators Variable to store list of suboperators 49552d6035fSJeremy L Thompson 49652d6035fSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 49752d6035fSJeremy L Thompson 49852d6035fSJeremy L Thompson @ref Advanced 49952d6035fSJeremy L Thompson **/ 50052d6035fSJeremy L Thompson 50152d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) { 502c042f62fSJeremy L Thompson if (!op->composite) 503c042f62fSJeremy L Thompson // LCOV_EXCL_START 504c042f62fSJeremy L Thompson return CeedError(op->ceed, 1, "Not a composite operator"); 505c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 50652d6035fSJeremy L Thompson 50752d6035fSJeremy L Thompson *suboperators = op->suboperators; 50852d6035fSJeremy L Thompson return 0; 50952d6035fSJeremy L Thompson } 51052d6035fSJeremy L Thompson 51152d6035fSJeremy L Thompson /** 512fe2413ffSjeremylt @brief Set the backend data of a CeedOperator 513fe2413ffSjeremylt 514fe2413ffSjeremylt @param[out] op CeedOperator 515fe2413ffSjeremylt @param data Data to set 516fe2413ffSjeremylt 517fe2413ffSjeremylt @return An error code: 0 - success, otherwise - failure 518fe2413ffSjeremylt 519fe2413ffSjeremylt @ref Advanced 520fe2413ffSjeremylt **/ 521fe2413ffSjeremylt 522fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) { 523fe2413ffSjeremylt op->data = *data; 524fe2413ffSjeremylt return 0; 525fe2413ffSjeremylt } 526fe2413ffSjeremylt 527fe2413ffSjeremylt /** 5284ce2993fSjeremylt @brief Get the backend data of a CeedOperator 5294ce2993fSjeremylt 5304ce2993fSjeremylt @param op CeedOperator 5314ce2993fSjeremylt @param[out] data Variable to store data 5324ce2993fSjeremylt 5334ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5344ce2993fSjeremylt 53523617272Sjeremylt @ref Advanced 5364ce2993fSjeremylt **/ 5374ce2993fSjeremylt 5384ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) { 5394ce2993fSjeremylt *data = op->data; 5404ce2993fSjeremylt return 0; 5414ce2993fSjeremylt } 5424ce2993fSjeremylt 5434ce2993fSjeremylt /** 5444ce2993fSjeremylt @brief Set the setup flag of a CeedOperator to True 5454ce2993fSjeremylt 5464ce2993fSjeremylt @param op CeedOperator 5474ce2993fSjeremylt 5484ce2993fSjeremylt @return An error code: 0 - success, otherwise - failure 5494ce2993fSjeremylt 55023617272Sjeremylt @ref Advanced 5514ce2993fSjeremylt **/ 5524ce2993fSjeremylt 5534ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) { 5544ce2993fSjeremylt op->setupdone = 1; 5554ce2993fSjeremylt return 0; 5564ce2993fSjeremylt } 5574ce2993fSjeremylt 5584ce2993fSjeremylt /** 559d1bcdac9Sjeremylt @brief Get the CeedOperatorFields of a CeedOperator 560d1bcdac9Sjeremylt 561d1bcdac9Sjeremylt @param op CeedOperator 562d1bcdac9Sjeremylt @param[out] inputfields Variable to store inputfields 563d1bcdac9Sjeremylt @param[out] outputfields Variable to store outputfields 564d1bcdac9Sjeremylt 565d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 566d1bcdac9Sjeremylt 567d1bcdac9Sjeremylt @ref Advanced 568d1bcdac9Sjeremylt **/ 569d1bcdac9Sjeremylt 570d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op, 571d1bcdac9Sjeremylt CeedOperatorField* *inputfields, 572d1bcdac9Sjeremylt CeedOperatorField* *outputfields) { 57352d6035fSJeremy L Thompson if (op->composite) 574c042f62fSJeremy L Thompson // LCOV_EXCL_START 57552d6035fSJeremy L Thompson return CeedError(op->ceed, 1, "Not defined for composite operator"); 576c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 57752d6035fSJeremy L Thompson 578d1bcdac9Sjeremylt if (inputfields) *inputfields = op->inputfields; 579d1bcdac9Sjeremylt if (outputfields) *outputfields = op->outputfields; 580d1bcdac9Sjeremylt return 0; 581d1bcdac9Sjeremylt } 582d1bcdac9Sjeremylt 583d1bcdac9Sjeremylt /** 5844dccadb6Sjeremylt @brief Get the L vector CeedTransposeMode of a CeedOperatorField 5854dccadb6Sjeremylt 5864dccadb6Sjeremylt @param opfield CeedOperatorField 5874dccadb6Sjeremylt @param[out] lmode Variable to store CeedTransposeMode 5884dccadb6Sjeremylt 5894dccadb6Sjeremylt @return An error code: 0 - success, otherwise - failure 5904dccadb6Sjeremylt 5914dccadb6Sjeremylt @ref Advanced 5924dccadb6Sjeremylt **/ 5934dccadb6Sjeremylt 5944dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield, 5954dccadb6Sjeremylt CeedTransposeMode *lmode) { 596fe2413ffSjeremylt *lmode = opfield->lmode; 5974dccadb6Sjeremylt return 0; 5982b8e417aSjeremylt } 5992b8e417aSjeremylt 6002b8e417aSjeremylt /** 601d1bcdac9Sjeremylt @brief Get the CeedElemRestriction of a CeedOperatorField 602d1bcdac9Sjeremylt 603d1bcdac9Sjeremylt @param opfield CeedOperatorField 604d1bcdac9Sjeremylt @param[out] rstr Variable to store CeedElemRestriction 605d1bcdac9Sjeremylt 606d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 607d1bcdac9Sjeremylt 608d1bcdac9Sjeremylt @ref Advanced 609d1bcdac9Sjeremylt **/ 610d1bcdac9Sjeremylt 611d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield, 612d1bcdac9Sjeremylt CeedElemRestriction *rstr) { 613fe2413ffSjeremylt *rstr = opfield->Erestrict; 614d1bcdac9Sjeremylt return 0; 615d1bcdac9Sjeremylt } 616d1bcdac9Sjeremylt 617d1bcdac9Sjeremylt /** 618d1bcdac9Sjeremylt @brief Get the CeedBasis of a CeedOperatorField 619d1bcdac9Sjeremylt 620d1bcdac9Sjeremylt @param opfield CeedOperatorField 621d1bcdac9Sjeremylt @param[out] basis Variable to store CeedBasis 622d1bcdac9Sjeremylt 623d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 624d1bcdac9Sjeremylt 625d1bcdac9Sjeremylt @ref Advanced 626d1bcdac9Sjeremylt **/ 627d1bcdac9Sjeremylt 628d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield, 629d1bcdac9Sjeremylt CeedBasis *basis) { 630fe2413ffSjeremylt *basis = opfield->basis; 631d1bcdac9Sjeremylt return 0; 632d1bcdac9Sjeremylt } 633d1bcdac9Sjeremylt 634d1bcdac9Sjeremylt /** 635d1bcdac9Sjeremylt @brief Get the CeedVector of a CeedOperatorField 636d1bcdac9Sjeremylt 637d1bcdac9Sjeremylt @param opfield CeedOperatorField 638d1bcdac9Sjeremylt @param[out] vec Variable to store CeedVector 639d1bcdac9Sjeremylt 640d1bcdac9Sjeremylt @return An error code: 0 - success, otherwise - failure 641d1bcdac9Sjeremylt 642d1bcdac9Sjeremylt @ref Advanced 643d1bcdac9Sjeremylt **/ 644d1bcdac9Sjeremylt 645d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield, 646d1bcdac9Sjeremylt CeedVector *vec) { 647fe2413ffSjeremylt *vec = opfield->vec; 648d1bcdac9Sjeremylt return 0; 649d1bcdac9Sjeremylt } 650d1bcdac9Sjeremylt 651d1bcdac9Sjeremylt /** 652b11c1e72Sjeremylt @brief Destroy a CeedOperator 653d7b241e6Sjeremylt 654d7b241e6Sjeremylt @param op CeedOperator to destroy 655b11c1e72Sjeremylt 656b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 657dfdf5a53Sjeremylt 658dfdf5a53Sjeremylt @ref Basic 659b11c1e72Sjeremylt **/ 660d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) { 661d7b241e6Sjeremylt int ierr; 662d7b241e6Sjeremylt 663d7b241e6Sjeremylt if (!*op || --(*op)->refcount > 0) return 0; 664d7b241e6Sjeremylt if ((*op)->Destroy) { 665d7b241e6Sjeremylt ierr = (*op)->Destroy(*op); CeedChk(ierr); 666d7b241e6Sjeremylt } 667fe2413ffSjeremylt ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr); 668fe2413ffSjeremylt // Free fields 669*1d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 67052d6035fSJeremy L Thompson if ((*op)->inputfields[i]) { 67171352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict); 67271352a93Sjeremylt CeedChk(ierr); 67371352a93Sjeremylt if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) { 67471352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr); 67571352a93Sjeremylt } 67671352a93Sjeremylt if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE && 67771352a93Sjeremylt (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) { 67871352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr); 67971352a93Sjeremylt } 680fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr); 681fe2413ffSjeremylt } 682*1d102b48SJeremy L Thompson for (int i=0; i<(*op)->nfields; i++) 683d0eb30a5Sjeremylt if ((*op)->outputfields[i]) { 68471352a93Sjeremylt ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict); 68571352a93Sjeremylt CeedChk(ierr); 68671352a93Sjeremylt if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) { 68771352a93Sjeremylt ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr); 68871352a93Sjeremylt } 68971352a93Sjeremylt if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE && 69071352a93Sjeremylt (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) { 69171352a93Sjeremylt ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr); 69271352a93Sjeremylt } 693fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr); 694fe2413ffSjeremylt } 69552d6035fSJeremy L Thompson // Destroy suboperators 696*1d102b48SJeremy L Thompson for (int i=0; i<(*op)->numsub; i++) 69752d6035fSJeremy L Thompson if ((*op)->suboperators[i]) { 69852d6035fSJeremy L Thompson ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr); 69952d6035fSJeremy L Thompson } 700d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr); 701d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr); 702d7b241e6Sjeremylt ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr); 703fe2413ffSjeremylt 704fe2413ffSjeremylt ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr); 705fe2413ffSjeremylt ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr); 70652d6035fSJeremy L Thompson ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr); 707d7b241e6Sjeremylt ierr = CeedFree(op); CeedChk(ierr); 708d7b241e6Sjeremylt return 0; 709d7b241e6Sjeremylt } 710d7b241e6Sjeremylt 711d7b241e6Sjeremylt /// @} 712