xref: /libCEED/interface/ceed-operator.c (revision 8b067b84f843731ea3f7eb73e31f61efee53b5f0)
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 /**
28b11c1e72Sjeremylt   @brief Create an operator from element restriction, basis, and QFunction
29d7b241e6Sjeremylt 
30b11c1e72Sjeremylt   @param ceed    A Ceed object where the CeedOperator will be created
31d7b241e6Sjeremylt   @param qf      QFunction defining the action of the operator at quadrature points
32d7b241e6Sjeremylt   @param dqf     QFunction defining the action of the Jacobian of @a qf (or NULL)
33d7b241e6Sjeremylt   @param dqfT    QFunction defining the action of the transpose of the Jacobian
34d7b241e6Sjeremylt                    of @a qf (or NULL)
35b11c1e72Sjeremylt   @param[out] op Address of the variable where the newly created
36b11c1e72Sjeremylt                      CeedOperator will be stored
37b11c1e72Sjeremylt 
38b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
39dfdf5a53Sjeremylt 
40dfdf5a53Sjeremylt   @ref Basic
41d7b241e6Sjeremylt  */
42d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf,
43d7b241e6Sjeremylt                        CeedQFunction dqfT, CeedOperator *op) {
44d7b241e6Sjeremylt   int ierr;
45d7b241e6Sjeremylt 
465fe0d4faSjeremylt   if (!ceed->OperatorCreate) {
475fe0d4faSjeremylt     Ceed delegate;
48aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr);
495fe0d4faSjeremylt 
505fe0d4faSjeremylt     if (!delegate)
515fe0d4faSjeremylt       return CeedError(ceed, 1, "Backend does not support OperatorCreate");
525fe0d4faSjeremylt 
535fe0d4faSjeremylt     ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr);
545fe0d4faSjeremylt     return 0;
555fe0d4faSjeremylt   }
565fe0d4faSjeremylt 
57d7b241e6Sjeremylt   ierr = CeedCalloc(1,op); CeedChk(ierr);
58d7b241e6Sjeremylt   (*op)->ceed = ceed;
59d7b241e6Sjeremylt   ceed->refcount++;
60d7b241e6Sjeremylt   (*op)->refcount = 1;
61d7b241e6Sjeremylt   (*op)->qf = qf;
62d7b241e6Sjeremylt   qf->refcount++;
63d7b241e6Sjeremylt   (*op)->dqf = dqf;
64d7b241e6Sjeremylt   if (dqf) dqf->refcount++;
65d7b241e6Sjeremylt   (*op)->dqfT = dqfT;
66d7b241e6Sjeremylt   if (dqfT) dqfT->refcount++;
67fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr);
68fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr);
69d7b241e6Sjeremylt   ierr = ceed->OperatorCreate(*op); CeedChk(ierr);
70d7b241e6Sjeremylt   return 0;
71d7b241e6Sjeremylt }
72d7b241e6Sjeremylt 
73d7b241e6Sjeremylt /**
7452d6035fSJeremy L Thompson   @brief Create an operator that composes the action of several operators
7552d6035fSJeremy L Thompson 
7652d6035fSJeremy L Thompson   @param ceed    A Ceed object where the CeedOperator will be created
7752d6035fSJeremy L Thompson   @param[out] op Address of the variable where the newly created
7852d6035fSJeremy L Thompson                      Composite CeedOperator will be stored
7952d6035fSJeremy L Thompson 
8052d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8152d6035fSJeremy L Thompson 
8252d6035fSJeremy L Thompson   @ref Basic
8352d6035fSJeremy L Thompson  */
8452d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) {
8552d6035fSJeremy L Thompson   int ierr;
8652d6035fSJeremy L Thompson 
8752d6035fSJeremy L Thompson   if (!ceed->CompositeOperatorCreate) {
8852d6035fSJeremy L Thompson     Ceed delegate;
89aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr);
9052d6035fSJeremy L Thompson 
9152d6035fSJeremy L Thompson     if (!delegate)
9252d6035fSJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support \
9352d6035fSJeremy L Thompson                                    CompositeOperatorCreate");
9452d6035fSJeremy L Thompson 
9552d6035fSJeremy L Thompson     ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr);
9652d6035fSJeremy L Thompson     return 0;
9752d6035fSJeremy L Thompson   }
9852d6035fSJeremy L Thompson 
9952d6035fSJeremy L Thompson   ierr = CeedCalloc(1,op); CeedChk(ierr);
10052d6035fSJeremy L Thompson   (*op)->ceed = ceed;
10152d6035fSJeremy L Thompson   ceed->refcount++;
10252d6035fSJeremy L Thompson   (*op)->composite = true;
10352d6035fSJeremy L Thompson   ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr);
10452d6035fSJeremy L Thompson   ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr);
10552d6035fSJeremy L Thompson   return 0;
10652d6035fSJeremy L Thompson }
10752d6035fSJeremy L Thompson 
10852d6035fSJeremy L Thompson /**
109b11c1e72Sjeremylt   @brief Provide a field to a CeedOperator for use by its CeedQFunction
110d7b241e6Sjeremylt 
111d7b241e6Sjeremylt   This function is used to specify both active and passive fields to a
112d7b241e6Sjeremylt   CeedOperator.  For passive fields, a vector @arg v must be provided.  Passive
113d7b241e6Sjeremylt   fields can inputs or outputs (updated in-place when operator is applied).
114d7b241e6Sjeremylt 
115d7b241e6Sjeremylt   Active fields must be specified using this function, but their data (in a
116d7b241e6Sjeremylt   CeedVector) is passed in CeedOperatorApply().  There can be at most one active
117d7b241e6Sjeremylt   input and at most one active output.
118d7b241e6Sjeremylt 
1198c91a0c9SJeremy L Thompson   @param op         CeedOperator on which to provide the field
1208795c945Sjeremylt   @param fieldname  Name of the field (to be matched with the name used by
1218795c945Sjeremylt                       CeedQFunction)
122b11c1e72Sjeremylt   @param r          CeedElemRestriction
123b0e29e78Sjeremylt   @param lmode      CeedTransposeMode which specifies the ordering of the
124b0e29e78Sjeremylt                       components of the l-vector used by this CeedOperatorField,
125b0e29e78Sjeremylt                       CEED_NOTRANSPOSE indicates the component is the
126b0e29e78Sjeremylt                       outermost index and CEED_TRANSPOSE indicates the component
127b0e29e78Sjeremylt                       is the innermost index in ordering of the l-vector
128783c99b3SValeria Barra   @param b          CeedBasis in which the field resides or CEED_BASIS_COLLOCATED
129b11c1e72Sjeremylt                       if collocated with quadrature points
130b11c1e72Sjeremylt   @param v          CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE
131b11c1e72Sjeremylt                       if field is active or CEED_VECTOR_NONE if using
1328c91a0c9SJeremy L Thompson                       CEED_EVAL_WEIGHT in the QFunction
133b11c1e72Sjeremylt 
134b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
135dfdf5a53Sjeremylt 
136dfdf5a53Sjeremylt   @ref Basic
137b11c1e72Sjeremylt **/
138d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname,
1394dccadb6Sjeremylt                          CeedElemRestriction r, CeedTransposeMode lmode,
1404dccadb6Sjeremylt                          CeedBasis b, CeedVector v) {
141d7b241e6Sjeremylt   int ierr;
14252d6035fSJeremy L Thompson   if (op->composite)
14352d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Cannot add field to composite operator.");
144*8b067b84SJed Brown   if (!r)
145*8b067b84SJed Brown     return CeedError(op->ceed, 1, "ElemRestriction r for field \"%s\" must be non-NULL.", fieldname);
146*8b067b84SJed Brown   if (!b)
147*8b067b84SJed Brown     return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", fieldname);
148*8b067b84SJed Brown   if (!v)
149*8b067b84SJed Brown     return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", fieldname);
15052d6035fSJeremy L Thompson 
151d7b241e6Sjeremylt   CeedInt numelements;
152d7b241e6Sjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr);
153d7b241e6Sjeremylt   if (op->numelements && op->numelements != numelements)
154d7b241e6Sjeremylt     return CeedError(op->ceed, 1,
155d7b241e6Sjeremylt                      "ElemRestriction with %d elements incompatible with prior %d elements",
156d7b241e6Sjeremylt                      numelements, op->numelements);
157d7b241e6Sjeremylt   op->numelements = numelements;
158d7b241e6Sjeremylt 
159783c99b3SValeria Barra   if (b != CEED_BASIS_COLLOCATED) {
160d7b241e6Sjeremylt     CeedInt numqpoints;
161d7b241e6Sjeremylt     ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr);
162d7b241e6Sjeremylt     if (op->numqpoints && op->numqpoints != numqpoints)
163d7b241e6Sjeremylt       return CeedError(op->ceed, 1,
164d7b241e6Sjeremylt                        "Basis with %d quadrature points incompatible with prior %d points",
165d7b241e6Sjeremylt                        numqpoints, op->numqpoints);
166d7b241e6Sjeremylt     op->numqpoints = numqpoints;
167d7b241e6Sjeremylt   }
168d1bcdac9Sjeremylt   CeedOperatorField *ofield;
169d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numinputfields; i++) {
170fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) {
171d7b241e6Sjeremylt       ofield = &op->inputfields[i];
172d7b241e6Sjeremylt       goto found;
173d7b241e6Sjeremylt     }
174d7b241e6Sjeremylt   }
175d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numoutputfields; i++) {
176fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) {
177d7b241e6Sjeremylt       ofield = &op->outputfields[i];
178d7b241e6Sjeremylt       goto found;
179d7b241e6Sjeremylt     }
180d7b241e6Sjeremylt   }
181d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
182d7b241e6Sjeremylt                    fieldname);
183d7b241e6Sjeremylt found:
184fe2413ffSjeremylt   ierr = CeedCalloc(1, ofield); CeedChk(ierr);
185fe2413ffSjeremylt   (*ofield)->Erestrict = r;
186fe2413ffSjeremylt   (*ofield)->lmode = lmode;
187fe2413ffSjeremylt   (*ofield)->basis = b;
188fe2413ffSjeremylt   (*ofield)->vec = v;
189d7b241e6Sjeremylt   op->nfields += 1;
190d7b241e6Sjeremylt   return 0;
191d7b241e6Sjeremylt }
192d7b241e6Sjeremylt 
193d7b241e6Sjeremylt /**
19452d6035fSJeremy L Thompson   @brief Add a sub-operator to a composite CeedOperator
195288c0443SJeremy L Thompson 
196288c0443SJeremy L Thompson   @param[out] compositeop Address of the composite CeedOperator
197288c0443SJeremy L Thompson   @param      subop       Address of the sub-operator CeedOperator
19852d6035fSJeremy L Thompson 
19952d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
20052d6035fSJeremy L Thompson 
20152d6035fSJeremy L Thompson   @ref Basic
20252d6035fSJeremy L Thompson  */
20352d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
20452d6035fSJeremy L Thompson                                 CeedOperator subop) {
20552d6035fSJeremy L Thompson   if (!compositeop->composite)
20652d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
20752d6035fSJeremy L Thompson                      "CeedOperator is not a composite operator");
20852d6035fSJeremy L Thompson 
20952d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
21052d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
21152d6035fSJeremy L Thompson                      "Cannot add additional suboperators");
21252d6035fSJeremy L Thompson 
21352d6035fSJeremy L Thompson   compositeop->suboperators[compositeop->numsub] = subop;
21452d6035fSJeremy L Thompson   subop->refcount++;
21552d6035fSJeremy L Thompson   compositeop->numsub++;
21652d6035fSJeremy L Thompson   return 0;
21752d6035fSJeremy L Thompson }
21852d6035fSJeremy L Thompson 
21952d6035fSJeremy L Thompson /**
220b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
221d7b241e6Sjeremylt 
222d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
223d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
224d7b241e6Sjeremylt   CeedOperatorSetField().
225d7b241e6Sjeremylt 
226d7b241e6Sjeremylt   @param op        CeedOperator to apply
227b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
228b11c1e72Sjeremylt                      active inputs
229b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
230d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
231d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
232d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
233b11c1e72Sjeremylt 
234b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
235dfdf5a53Sjeremylt 
236dfdf5a53Sjeremylt   @ref Basic
237b11c1e72Sjeremylt **/
238d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
239d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
240d7b241e6Sjeremylt   int ierr;
241d7b241e6Sjeremylt   Ceed ceed = op->ceed;
242d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
243d7b241e6Sjeremylt 
24452d6035fSJeremy L Thompson   if (op->composite) {
24552d6035fSJeremy L Thompson     if (!op->numsub) return CeedError(ceed, 1, "No suboperators set");
24652d6035fSJeremy L Thompson   } else {
247d7b241e6Sjeremylt     if (op->nfields == 0) return CeedError(ceed, 1, "No operator fields set");
248d7b241e6Sjeremylt     if (op->nfields < qf->numinputfields + qf->numoutputfields) return CeedError(
249d7b241e6Sjeremylt             ceed, 1, "Not all operator fields set");
250d7b241e6Sjeremylt     if (op->numelements == 0) return CeedError(ceed, 1,
251d7b241e6Sjeremylt                                        "At least one restriction required");
252d7b241e6Sjeremylt     if (op->numqpoints == 0) return CeedError(ceed, 1,
253783c99b3SValeria Barra                                       "At least one non-collocated basis required");
25452d6035fSJeremy L Thompson   }
255d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
256d7b241e6Sjeremylt   return 0;
257d7b241e6Sjeremylt }
258d7b241e6Sjeremylt 
259d7b241e6Sjeremylt /**
2604ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
2614ce2993fSjeremylt 
2624ce2993fSjeremylt   @param op              CeedOperator
2634ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
2644ce2993fSjeremylt 
2654ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2664ce2993fSjeremylt 
26723617272Sjeremylt   @ref Advanced
2684ce2993fSjeremylt **/
2694ce2993fSjeremylt 
2704ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
2714ce2993fSjeremylt   *ceed = op->ceed;
2724ce2993fSjeremylt   return 0;
2734ce2993fSjeremylt }
2744ce2993fSjeremylt 
2754ce2993fSjeremylt /**
2764ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
2774ce2993fSjeremylt 
2784ce2993fSjeremylt   @param op              CeedOperator
2794ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
2804ce2993fSjeremylt 
2814ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2824ce2993fSjeremylt 
28323617272Sjeremylt   @ref Advanced
2844ce2993fSjeremylt **/
2854ce2993fSjeremylt 
2864ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
28752d6035fSJeremy L Thompson   if (op->composite)
28852d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
28952d6035fSJeremy L Thompson 
2904ce2993fSjeremylt   *numelem = op->numelements;
2914ce2993fSjeremylt   return 0;
2924ce2993fSjeremylt }
2934ce2993fSjeremylt 
2944ce2993fSjeremylt /**
2954ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
2964ce2993fSjeremylt 
2974ce2993fSjeremylt   @param op              CeedOperator
2984ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
2994ce2993fSjeremylt 
3004ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3014ce2993fSjeremylt 
30223617272Sjeremylt   @ref Advanced
3034ce2993fSjeremylt **/
3044ce2993fSjeremylt 
3054ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
30652d6035fSJeremy L Thompson   if (op->composite)
30752d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
30852d6035fSJeremy L Thompson 
3094ce2993fSjeremylt   *numqpts = op->numqpoints;
3104ce2993fSjeremylt   return 0;
3114ce2993fSjeremylt }
3124ce2993fSjeremylt 
3134ce2993fSjeremylt /**
3144ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
3154ce2993fSjeremylt 
3164ce2993fSjeremylt   @param op              CeedOperator
3174ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
3184ce2993fSjeremylt 
3194ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3204ce2993fSjeremylt 
32123617272Sjeremylt   @ref Advanced
3224ce2993fSjeremylt **/
3234ce2993fSjeremylt 
3244ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
32552d6035fSJeremy L Thompson   if (op->composite)
32652d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
3274ce2993fSjeremylt   *numargs = op->nfields;
3284ce2993fSjeremylt   return 0;
3294ce2993fSjeremylt }
3304ce2993fSjeremylt 
3314ce2993fSjeremylt /**
3324ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
3334ce2993fSjeremylt 
3344ce2993fSjeremylt   @param op             CeedOperator
335288c0443SJeremy L Thompson   @param[out] setupdone Variable to store setup status
3364ce2993fSjeremylt 
3374ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3384ce2993fSjeremylt 
33923617272Sjeremylt   @ref Advanced
3404ce2993fSjeremylt **/
3414ce2993fSjeremylt 
3424ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
3434ce2993fSjeremylt   *setupdone = op->setupdone;
3444ce2993fSjeremylt   return 0;
3454ce2993fSjeremylt }
3464ce2993fSjeremylt 
3474ce2993fSjeremylt /**
3484ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
3494ce2993fSjeremylt 
3504ce2993fSjeremylt   @param op              CeedOperator
3518c91a0c9SJeremy L Thompson   @param[out] qf         Variable to store QFunction
3524ce2993fSjeremylt 
3534ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3544ce2993fSjeremylt 
35523617272Sjeremylt   @ref Advanced
3564ce2993fSjeremylt **/
3574ce2993fSjeremylt 
3584ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
35952d6035fSJeremy L Thompson   if (op->composite)
36052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
36152d6035fSJeremy L Thompson 
3624ce2993fSjeremylt   *qf = op->qf;
3634ce2993fSjeremylt   return 0;
3644ce2993fSjeremylt }
3654ce2993fSjeremylt 
3664ce2993fSjeremylt /**
36752d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
36852d6035fSJeremy L Thompson 
36952d6035fSJeremy L Thompson   @param op              CeedOperator
37052d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
37152d6035fSJeremy L Thompson 
37252d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
37352d6035fSJeremy L Thompson 
37452d6035fSJeremy L Thompson   @ref Advanced
37552d6035fSJeremy L Thompson **/
37652d6035fSJeremy L Thompson 
37752d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
37852d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
37952d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
38052d6035fSJeremy L Thompson 
38152d6035fSJeremy L Thompson   *numsub = op->numsub;
38252d6035fSJeremy L Thompson   return 0;
38352d6035fSJeremy L Thompson }
38452d6035fSJeremy L Thompson 
38552d6035fSJeremy L Thompson /**
38652d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
38752d6035fSJeremy L Thompson 
38852d6035fSJeremy L Thompson   @param op                CeedOperator
38952d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
39052d6035fSJeremy L Thompson 
39152d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
39252d6035fSJeremy L Thompson 
39352d6035fSJeremy L Thompson   @ref Advanced
39452d6035fSJeremy L Thompson **/
39552d6035fSJeremy L Thompson 
39652d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
39752d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
39852d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
39952d6035fSJeremy L Thompson 
40052d6035fSJeremy L Thompson   *suboperators = op->suboperators;
40152d6035fSJeremy L Thompson   return 0;
40252d6035fSJeremy L Thompson }
40352d6035fSJeremy L Thompson 
40452d6035fSJeremy L Thompson /**
405fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
406fe2413ffSjeremylt 
407fe2413ffSjeremylt   @param[out] op         CeedOperator
408fe2413ffSjeremylt   @param data            Data to set
409fe2413ffSjeremylt 
410fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
411fe2413ffSjeremylt 
412fe2413ffSjeremylt   @ref Advanced
413fe2413ffSjeremylt **/
414fe2413ffSjeremylt 
415fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
416fe2413ffSjeremylt   op->data = *data;
417fe2413ffSjeremylt   return 0;
418fe2413ffSjeremylt }
419fe2413ffSjeremylt 
420fe2413ffSjeremylt /**
4214ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
4224ce2993fSjeremylt 
4234ce2993fSjeremylt   @param op              CeedOperator
4244ce2993fSjeremylt   @param[out] data       Variable to store data
4254ce2993fSjeremylt 
4264ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4274ce2993fSjeremylt 
42823617272Sjeremylt   @ref Advanced
4294ce2993fSjeremylt **/
4304ce2993fSjeremylt 
4314ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
4324ce2993fSjeremylt   *data = op->data;
4334ce2993fSjeremylt   return 0;
4344ce2993fSjeremylt }
4354ce2993fSjeremylt 
4364ce2993fSjeremylt /**
4374ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
4384ce2993fSjeremylt 
4394ce2993fSjeremylt   @param op              CeedOperator
4404ce2993fSjeremylt 
4414ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4424ce2993fSjeremylt 
44323617272Sjeremylt   @ref Advanced
4444ce2993fSjeremylt **/
4454ce2993fSjeremylt 
4464ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
4474ce2993fSjeremylt   op->setupdone = 1;
4484ce2993fSjeremylt   return 0;
4494ce2993fSjeremylt }
4504ce2993fSjeremylt 
4514ce2993fSjeremylt /**
452d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
453d1bcdac9Sjeremylt 
454d1bcdac9Sjeremylt   @param op                 CeedOperator
455d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
456d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
457d1bcdac9Sjeremylt 
458d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
459d1bcdac9Sjeremylt 
460d1bcdac9Sjeremylt   @ref Advanced
461d1bcdac9Sjeremylt **/
462d1bcdac9Sjeremylt 
463d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
464d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
465d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
46652d6035fSJeremy L Thompson   if (op->composite)
46752d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
46852d6035fSJeremy L Thompson 
469d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
470d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
471d1bcdac9Sjeremylt   return 0;
472d1bcdac9Sjeremylt }
473d1bcdac9Sjeremylt 
474d1bcdac9Sjeremylt /**
4754dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
4764dccadb6Sjeremylt 
4774dccadb6Sjeremylt   @param opfield         CeedOperatorField
4784dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
4794dccadb6Sjeremylt 
4804dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
4814dccadb6Sjeremylt 
4824dccadb6Sjeremylt   @ref Advanced
4834dccadb6Sjeremylt **/
4844dccadb6Sjeremylt 
4854dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
4864dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
487fe2413ffSjeremylt   *lmode = opfield->lmode;
4884dccadb6Sjeremylt   return 0;
4894dccadb6Sjeremylt }/**
490d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
491d1bcdac9Sjeremylt 
492d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
493d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
494d1bcdac9Sjeremylt 
495d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
496d1bcdac9Sjeremylt 
497d1bcdac9Sjeremylt   @ref Advanced
498d1bcdac9Sjeremylt **/
499d1bcdac9Sjeremylt 
500d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
501d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
502fe2413ffSjeremylt   *rstr = opfield->Erestrict;
503d1bcdac9Sjeremylt   return 0;
504d1bcdac9Sjeremylt }
505d1bcdac9Sjeremylt 
506d1bcdac9Sjeremylt /**
507d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
508d1bcdac9Sjeremylt 
509d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
510d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
511d1bcdac9Sjeremylt 
512d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
513d1bcdac9Sjeremylt 
514d1bcdac9Sjeremylt   @ref Advanced
515d1bcdac9Sjeremylt **/
516d1bcdac9Sjeremylt 
517d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
518d1bcdac9Sjeremylt                               CeedBasis *basis) {
519fe2413ffSjeremylt   *basis = opfield->basis;
520d1bcdac9Sjeremylt   return 0;
521d1bcdac9Sjeremylt }
522d1bcdac9Sjeremylt 
523d1bcdac9Sjeremylt /**
524d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
525d1bcdac9Sjeremylt 
526d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
527d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
528d1bcdac9Sjeremylt 
529d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
530d1bcdac9Sjeremylt 
531d1bcdac9Sjeremylt   @ref Advanced
532d1bcdac9Sjeremylt **/
533d1bcdac9Sjeremylt 
534d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
535d1bcdac9Sjeremylt                                CeedVector *vec) {
536fe2413ffSjeremylt   *vec = opfield->vec;
537d1bcdac9Sjeremylt   return 0;
538d1bcdac9Sjeremylt }
539d1bcdac9Sjeremylt 
540d1bcdac9Sjeremylt /**
541b11c1e72Sjeremylt   @brief Destroy a CeedOperator
542d7b241e6Sjeremylt 
543d7b241e6Sjeremylt   @param op CeedOperator to destroy
544b11c1e72Sjeremylt 
545b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
546dfdf5a53Sjeremylt 
547dfdf5a53Sjeremylt   @ref Basic
548b11c1e72Sjeremylt **/
549d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
550d7b241e6Sjeremylt   int ierr;
551d7b241e6Sjeremylt 
552d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
553d7b241e6Sjeremylt   if ((*op)->Destroy) {
554d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
555d7b241e6Sjeremylt   }
556fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
557fe2413ffSjeremylt   // Free fields
558d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
55952d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
560fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
561fe2413ffSjeremylt     }
562d0eb30a5Sjeremylt   }
563d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
564d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
565fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
566fe2413ffSjeremylt     }
567d0eb30a5Sjeremylt   }
56852d6035fSJeremy L Thompson   // Destroy suboperators
56952d6035fSJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++) {
57052d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
57152d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
57252d6035fSJeremy L Thompson     }
57352d6035fSJeremy L Thompson   }
574d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
575d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
576d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
577fe2413ffSjeremylt 
578fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
579fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
58052d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
581d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
582d7b241e6Sjeremylt   return 0;
583d7b241e6Sjeremylt }
584d7b241e6Sjeremylt 
585d7b241e6Sjeremylt /// @}
586