xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-operator.c (revision 8795c9458136fc8cad6e4d699e4c8f3c99be02e2)
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
120*8795c945Sjeremylt   @param fieldname  Name of the field (to be matched with the name used by
121*8795c945Sjeremylt                       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.");
14452d6035fSJeremy L Thompson 
145d7b241e6Sjeremylt   CeedInt numelements;
146d7b241e6Sjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr);
147d7b241e6Sjeremylt   if (op->numelements && op->numelements != numelements)
148d7b241e6Sjeremylt     return CeedError(op->ceed, 1,
149d7b241e6Sjeremylt                      "ElemRestriction with %d elements incompatible with prior %d elements",
150d7b241e6Sjeremylt                      numelements, op->numelements);
151d7b241e6Sjeremylt   op->numelements = numelements;
152d7b241e6Sjeremylt 
153783c99b3SValeria Barra   if (b != CEED_BASIS_COLLOCATED) {
154d7b241e6Sjeremylt     CeedInt numqpoints;
155d7b241e6Sjeremylt     ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr);
156d7b241e6Sjeremylt     if (op->numqpoints && op->numqpoints != numqpoints)
157d7b241e6Sjeremylt       return CeedError(op->ceed, 1,
158d7b241e6Sjeremylt                        "Basis with %d quadrature points incompatible with prior %d points",
159d7b241e6Sjeremylt                        numqpoints, op->numqpoints);
160d7b241e6Sjeremylt     op->numqpoints = numqpoints;
161d7b241e6Sjeremylt   }
162d1bcdac9Sjeremylt   CeedOperatorField *ofield;
163d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numinputfields; i++) {
164fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) {
165d7b241e6Sjeremylt       ofield = &op->inputfields[i];
166d7b241e6Sjeremylt       goto found;
167d7b241e6Sjeremylt     }
168d7b241e6Sjeremylt   }
169d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numoutputfields; i++) {
170fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) {
171d7b241e6Sjeremylt       ofield = &op->outputfields[i];
172d7b241e6Sjeremylt       goto found;
173d7b241e6Sjeremylt     }
174d7b241e6Sjeremylt   }
175d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
176d7b241e6Sjeremylt                    fieldname);
177d7b241e6Sjeremylt found:
178fe2413ffSjeremylt   ierr = CeedCalloc(1, ofield); CeedChk(ierr);
179fe2413ffSjeremylt   (*ofield)->Erestrict = r;
180fe2413ffSjeremylt   (*ofield)->lmode = lmode;
181fe2413ffSjeremylt   (*ofield)->basis = b;
182fe2413ffSjeremylt   (*ofield)->vec = v;
183d7b241e6Sjeremylt   op->nfields += 1;
184d7b241e6Sjeremylt   return 0;
185d7b241e6Sjeremylt }
186d7b241e6Sjeremylt 
187d7b241e6Sjeremylt /**
18852d6035fSJeremy L Thompson   @brief Add a sub-operator to a composite CeedOperator
18952d6035fSJeremy L Thompson   @param[out] op Address of the composite CeedOperator
19052d6035fSJeremy L Thompson   @param      op Address of the sub-operator CeedOperator
19152d6035fSJeremy L Thompson 
19252d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
19352d6035fSJeremy L Thompson 
19452d6035fSJeremy L Thompson   @ref Basic
19552d6035fSJeremy L Thompson  */
19652d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
19752d6035fSJeremy L Thompson                                 CeedOperator subop) {
19852d6035fSJeremy L Thompson   if (!compositeop->composite)
19952d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
20052d6035fSJeremy L Thompson                      "CeedOperator is not a composite operator");
20152d6035fSJeremy L Thompson 
20252d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
20352d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
20452d6035fSJeremy L Thompson                      "Cannot add additional suboperators");
20552d6035fSJeremy L Thompson 
20652d6035fSJeremy L Thompson   compositeop->suboperators[compositeop->numsub] = subop;
20752d6035fSJeremy L Thompson   subop->refcount++;
20852d6035fSJeremy L Thompson   compositeop->numsub++;
20952d6035fSJeremy L Thompson   return 0;
21052d6035fSJeremy L Thompson }
21152d6035fSJeremy L Thompson 
21252d6035fSJeremy L Thompson /**
213b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
214d7b241e6Sjeremylt 
215d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
216d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
217d7b241e6Sjeremylt   CeedOperatorSetField().
218d7b241e6Sjeremylt 
219d7b241e6Sjeremylt   @param op        CeedOperator to apply
220b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
221b11c1e72Sjeremylt                      active inputs
222b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
223d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
224d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
225d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
226b11c1e72Sjeremylt 
227b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
228dfdf5a53Sjeremylt 
229dfdf5a53Sjeremylt   @ref Basic
230b11c1e72Sjeremylt **/
231d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
232d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
233d7b241e6Sjeremylt   int ierr;
234d7b241e6Sjeremylt   Ceed ceed = op->ceed;
235d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
236d7b241e6Sjeremylt 
23752d6035fSJeremy L Thompson   if (op->composite) {
23852d6035fSJeremy L Thompson     if (!op->numsub) return CeedError(ceed, 1, "No suboperators set");
23952d6035fSJeremy L Thompson   } else {
240d7b241e6Sjeremylt     if (op->nfields == 0) return CeedError(ceed, 1, "No operator fields set");
241d7b241e6Sjeremylt     if (op->nfields < qf->numinputfields + qf->numoutputfields) return CeedError(
242d7b241e6Sjeremylt             ceed, 1, "Not all operator fields set");
243d7b241e6Sjeremylt     if (op->numelements == 0) return CeedError(ceed, 1,
244d7b241e6Sjeremylt                                        "At least one restriction required");
245d7b241e6Sjeremylt     if (op->numqpoints == 0) return CeedError(ceed, 1,
246783c99b3SValeria Barra                                       "At least one non-collocated basis required");
24752d6035fSJeremy L Thompson   }
248d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
249d7b241e6Sjeremylt   return 0;
250d7b241e6Sjeremylt }
251d7b241e6Sjeremylt 
252d7b241e6Sjeremylt /**
2534ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
2544ce2993fSjeremylt 
2554ce2993fSjeremylt   @param op              CeedOperator
2564ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
2574ce2993fSjeremylt 
2584ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2594ce2993fSjeremylt 
26023617272Sjeremylt   @ref Advanced
2614ce2993fSjeremylt **/
2624ce2993fSjeremylt 
2634ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
2644ce2993fSjeremylt   *ceed = op->ceed;
2654ce2993fSjeremylt   return 0;
2664ce2993fSjeremylt }
2674ce2993fSjeremylt 
2684ce2993fSjeremylt /**
2694ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
2704ce2993fSjeremylt 
2714ce2993fSjeremylt   @param op              CeedOperator
2724ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
2734ce2993fSjeremylt 
2744ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2754ce2993fSjeremylt 
27623617272Sjeremylt   @ref Advanced
2774ce2993fSjeremylt **/
2784ce2993fSjeremylt 
2794ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
28052d6035fSJeremy L Thompson   if (op->composite)
28152d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
28252d6035fSJeremy L Thompson 
2834ce2993fSjeremylt   *numelem = op->numelements;
2844ce2993fSjeremylt   return 0;
2854ce2993fSjeremylt }
2864ce2993fSjeremylt 
2874ce2993fSjeremylt /**
2884ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
2894ce2993fSjeremylt 
2904ce2993fSjeremylt   @param op              CeedOperator
2914ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
2924ce2993fSjeremylt 
2934ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2944ce2993fSjeremylt 
29523617272Sjeremylt   @ref Advanced
2964ce2993fSjeremylt **/
2974ce2993fSjeremylt 
2984ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
29952d6035fSJeremy L Thompson   if (op->composite)
30052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
30152d6035fSJeremy L Thompson 
3024ce2993fSjeremylt   *numqpts = op->numqpoints;
3034ce2993fSjeremylt   return 0;
3044ce2993fSjeremylt }
3054ce2993fSjeremylt 
3064ce2993fSjeremylt /**
3074ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
3084ce2993fSjeremylt 
3094ce2993fSjeremylt   @param op              CeedOperator
3104ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
3114ce2993fSjeremylt 
3124ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3134ce2993fSjeremylt 
31423617272Sjeremylt   @ref Advanced
3154ce2993fSjeremylt **/
3164ce2993fSjeremylt 
3174ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
31852d6035fSJeremy L Thompson   if (op->composite)
31952d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
3204ce2993fSjeremylt   *numargs = op->nfields;
3214ce2993fSjeremylt   return 0;
3224ce2993fSjeremylt }
3234ce2993fSjeremylt 
3244ce2993fSjeremylt /**
3254ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
3264ce2993fSjeremylt 
3274ce2993fSjeremylt   @param op              CeedOperator
3284ce2993fSjeremylt   @param[out] numelem    Variable to store setup status
3294ce2993fSjeremylt 
3304ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3314ce2993fSjeremylt 
33223617272Sjeremylt   @ref Advanced
3334ce2993fSjeremylt **/
3344ce2993fSjeremylt 
3354ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
3364ce2993fSjeremylt   *setupdone = op->setupdone;
3374ce2993fSjeremylt   return 0;
3384ce2993fSjeremylt }
3394ce2993fSjeremylt 
3404ce2993fSjeremylt /**
3414ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
3424ce2993fSjeremylt 
3434ce2993fSjeremylt   @param op              CeedOperator
3448c91a0c9SJeremy L Thompson   @param[out] qf         Variable to store QFunction
3454ce2993fSjeremylt 
3464ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3474ce2993fSjeremylt 
34823617272Sjeremylt   @ref Advanced
3494ce2993fSjeremylt **/
3504ce2993fSjeremylt 
3514ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
35252d6035fSJeremy L Thompson   if (op->composite)
35352d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
35452d6035fSJeremy L Thompson 
3554ce2993fSjeremylt   *qf = op->qf;
3564ce2993fSjeremylt   return 0;
3574ce2993fSjeremylt }
3584ce2993fSjeremylt 
3594ce2993fSjeremylt /**
36052d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
36152d6035fSJeremy L Thompson 
36252d6035fSJeremy L Thompson   @param op              CeedOperator
36352d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
36452d6035fSJeremy L Thompson 
36552d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
36652d6035fSJeremy L Thompson 
36752d6035fSJeremy L Thompson   @ref Advanced
36852d6035fSJeremy L Thompson **/
36952d6035fSJeremy L Thompson 
37052d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
37152d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
37252d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
37352d6035fSJeremy L Thompson 
37452d6035fSJeremy L Thompson   *numsub = op->numsub;
37552d6035fSJeremy L Thompson   return 0;
37652d6035fSJeremy L Thompson }
37752d6035fSJeremy L Thompson 
37852d6035fSJeremy L Thompson /**
37952d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
38052d6035fSJeremy L Thompson 
38152d6035fSJeremy L Thompson   @param op                CeedOperator
38252d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
38352d6035fSJeremy L Thompson 
38452d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
38552d6035fSJeremy L Thompson 
38652d6035fSJeremy L Thompson   @ref Advanced
38752d6035fSJeremy L Thompson **/
38852d6035fSJeremy L Thompson 
38952d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
39052d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
39152d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
39252d6035fSJeremy L Thompson 
39352d6035fSJeremy L Thompson   *suboperators = op->suboperators;
39452d6035fSJeremy L Thompson   return 0;
39552d6035fSJeremy L Thompson }
39652d6035fSJeremy L Thompson 
39752d6035fSJeremy L Thompson /**
398fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
399fe2413ffSjeremylt 
400fe2413ffSjeremylt   @param[out] op         CeedOperator
401fe2413ffSjeremylt   @param data            Data to set
402fe2413ffSjeremylt 
403fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
404fe2413ffSjeremylt 
405fe2413ffSjeremylt   @ref Advanced
406fe2413ffSjeremylt **/
407fe2413ffSjeremylt 
408fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
409fe2413ffSjeremylt   op->data = *data;
410fe2413ffSjeremylt   return 0;
411fe2413ffSjeremylt }
412fe2413ffSjeremylt 
413fe2413ffSjeremylt /**
4144ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
4154ce2993fSjeremylt 
4164ce2993fSjeremylt   @param op              CeedOperator
4174ce2993fSjeremylt   @param[out] data       Variable to store data
4184ce2993fSjeremylt 
4194ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4204ce2993fSjeremylt 
42123617272Sjeremylt   @ref Advanced
4224ce2993fSjeremylt **/
4234ce2993fSjeremylt 
4244ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
4254ce2993fSjeremylt   *data = op->data;
4264ce2993fSjeremylt   return 0;
4274ce2993fSjeremylt }
4284ce2993fSjeremylt 
4294ce2993fSjeremylt /**
4304ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
4314ce2993fSjeremylt 
4324ce2993fSjeremylt   @param op              CeedOperator
4334ce2993fSjeremylt 
4344ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4354ce2993fSjeremylt 
43623617272Sjeremylt   @ref Advanced
4374ce2993fSjeremylt **/
4384ce2993fSjeremylt 
4394ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
4404ce2993fSjeremylt   op->setupdone = 1;
4414ce2993fSjeremylt   return 0;
4424ce2993fSjeremylt }
4434ce2993fSjeremylt 
4444ce2993fSjeremylt /**
445d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
446d1bcdac9Sjeremylt 
447d1bcdac9Sjeremylt   @param op                 CeedOperator
448d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
449d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
450d1bcdac9Sjeremylt 
451d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
452d1bcdac9Sjeremylt 
453d1bcdac9Sjeremylt   @ref Advanced
454d1bcdac9Sjeremylt **/
455d1bcdac9Sjeremylt 
456d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
457d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
458d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
45952d6035fSJeremy L Thompson   if (op->composite)
46052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
46152d6035fSJeremy L Thompson 
462d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
463d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
464d1bcdac9Sjeremylt   return 0;
465d1bcdac9Sjeremylt }
466d1bcdac9Sjeremylt 
467d1bcdac9Sjeremylt /**
4684dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
4694dccadb6Sjeremylt 
4704dccadb6Sjeremylt   @param opfield         CeedOperatorField
4714dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
4724dccadb6Sjeremylt 
4734dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
4744dccadb6Sjeremylt 
4754dccadb6Sjeremylt   @ref Advanced
4764dccadb6Sjeremylt **/
4774dccadb6Sjeremylt 
4784dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
4794dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
480fe2413ffSjeremylt   *lmode = opfield->lmode;
4814dccadb6Sjeremylt   return 0;
4824dccadb6Sjeremylt }/**
483d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
484d1bcdac9Sjeremylt 
485d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
486d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
487d1bcdac9Sjeremylt 
488d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
489d1bcdac9Sjeremylt 
490d1bcdac9Sjeremylt   @ref Advanced
491d1bcdac9Sjeremylt **/
492d1bcdac9Sjeremylt 
493d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
494d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
495fe2413ffSjeremylt   *rstr = opfield->Erestrict;
496d1bcdac9Sjeremylt   return 0;
497d1bcdac9Sjeremylt }
498d1bcdac9Sjeremylt 
499d1bcdac9Sjeremylt /**
500d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
501d1bcdac9Sjeremylt 
502d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
503d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
504d1bcdac9Sjeremylt 
505d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
506d1bcdac9Sjeremylt 
507d1bcdac9Sjeremylt   @ref Advanced
508d1bcdac9Sjeremylt **/
509d1bcdac9Sjeremylt 
510d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
511d1bcdac9Sjeremylt                               CeedBasis *basis) {
512fe2413ffSjeremylt   *basis = opfield->basis;
513d1bcdac9Sjeremylt   return 0;
514d1bcdac9Sjeremylt }
515d1bcdac9Sjeremylt 
516d1bcdac9Sjeremylt /**
517d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
518d1bcdac9Sjeremylt 
519d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
520d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
521d1bcdac9Sjeremylt 
522d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
523d1bcdac9Sjeremylt 
524d1bcdac9Sjeremylt   @ref Advanced
525d1bcdac9Sjeremylt **/
526d1bcdac9Sjeremylt 
527d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
528d1bcdac9Sjeremylt                                CeedVector *vec) {
529fe2413ffSjeremylt   *vec = opfield->vec;
530d1bcdac9Sjeremylt   return 0;
531d1bcdac9Sjeremylt }
532d1bcdac9Sjeremylt 
533d1bcdac9Sjeremylt /**
534b11c1e72Sjeremylt   @brief Destroy a CeedOperator
535d7b241e6Sjeremylt 
536d7b241e6Sjeremylt   @param op CeedOperator to destroy
537b11c1e72Sjeremylt 
538b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
539dfdf5a53Sjeremylt 
540dfdf5a53Sjeremylt   @ref Basic
541b11c1e72Sjeremylt **/
542d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
543d7b241e6Sjeremylt   int ierr;
544d7b241e6Sjeremylt 
545d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
546d7b241e6Sjeremylt   if ((*op)->Destroy) {
547d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
548d7b241e6Sjeremylt   }
549fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
550fe2413ffSjeremylt   // Free fields
551d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
55252d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
553fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
554fe2413ffSjeremylt     }
555d0eb30a5Sjeremylt   }
556d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
557d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
558fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
559fe2413ffSjeremylt     }
560d0eb30a5Sjeremylt   }
56152d6035fSJeremy L Thompson   // Destroy suboperators
56252d6035fSJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++) {
56352d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
56452d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
56552d6035fSJeremy L Thompson     }
56652d6035fSJeremy L Thompson   }
567d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
568d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
569d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
570fe2413ffSjeremylt 
571fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
572fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
57352d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
574d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
575d7b241e6Sjeremylt   return 0;
576d7b241e6Sjeremylt }
577d7b241e6Sjeremylt 
578d7b241e6Sjeremylt /// @}
579