xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-operator.c (revision 288c044332e33f37503f09b6484fec9d0a55fba1)
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.");
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
189*288c0443SJeremy L Thompson 
190*288c0443SJeremy L Thompson   @param[out] compositeop Address of the composite CeedOperator
191*288c0443SJeremy L Thompson   @param      subop       Address of the sub-operator CeedOperator
19252d6035fSJeremy L Thompson 
19352d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
19452d6035fSJeremy L Thompson 
19552d6035fSJeremy L Thompson   @ref Basic
19652d6035fSJeremy L Thompson  */
19752d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
19852d6035fSJeremy L Thompson                                 CeedOperator subop) {
19952d6035fSJeremy L Thompson   if (!compositeop->composite)
20052d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
20152d6035fSJeremy L Thompson                      "CeedOperator is not a composite operator");
20252d6035fSJeremy L Thompson 
20352d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
20452d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
20552d6035fSJeremy L Thompson                      "Cannot add additional suboperators");
20652d6035fSJeremy L Thompson 
20752d6035fSJeremy L Thompson   compositeop->suboperators[compositeop->numsub] = subop;
20852d6035fSJeremy L Thompson   subop->refcount++;
20952d6035fSJeremy L Thompson   compositeop->numsub++;
21052d6035fSJeremy L Thompson   return 0;
21152d6035fSJeremy L Thompson }
21252d6035fSJeremy L Thompson 
21352d6035fSJeremy L Thompson /**
214b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
215d7b241e6Sjeremylt 
216d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
217d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
218d7b241e6Sjeremylt   CeedOperatorSetField().
219d7b241e6Sjeremylt 
220d7b241e6Sjeremylt   @param op        CeedOperator to apply
221b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
222b11c1e72Sjeremylt                      active inputs
223b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
224d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
225d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
226d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
227b11c1e72Sjeremylt 
228b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
229dfdf5a53Sjeremylt 
230dfdf5a53Sjeremylt   @ref Basic
231b11c1e72Sjeremylt **/
232d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
233d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
234d7b241e6Sjeremylt   int ierr;
235d7b241e6Sjeremylt   Ceed ceed = op->ceed;
236d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
237d7b241e6Sjeremylt 
23852d6035fSJeremy L Thompson   if (op->composite) {
23952d6035fSJeremy L Thompson     if (!op->numsub) return CeedError(ceed, 1, "No suboperators set");
24052d6035fSJeremy L Thompson   } else {
241d7b241e6Sjeremylt     if (op->nfields == 0) return CeedError(ceed, 1, "No operator fields set");
242d7b241e6Sjeremylt     if (op->nfields < qf->numinputfields + qf->numoutputfields) return CeedError(
243d7b241e6Sjeremylt             ceed, 1, "Not all operator fields set");
244d7b241e6Sjeremylt     if (op->numelements == 0) return CeedError(ceed, 1,
245d7b241e6Sjeremylt                                        "At least one restriction required");
246d7b241e6Sjeremylt     if (op->numqpoints == 0) return CeedError(ceed, 1,
247783c99b3SValeria Barra                                       "At least one non-collocated basis required");
24852d6035fSJeremy L Thompson   }
249d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
250d7b241e6Sjeremylt   return 0;
251d7b241e6Sjeremylt }
252d7b241e6Sjeremylt 
253d7b241e6Sjeremylt /**
2544ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
2554ce2993fSjeremylt 
2564ce2993fSjeremylt   @param op              CeedOperator
2574ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
2584ce2993fSjeremylt 
2594ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2604ce2993fSjeremylt 
26123617272Sjeremylt   @ref Advanced
2624ce2993fSjeremylt **/
2634ce2993fSjeremylt 
2644ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
2654ce2993fSjeremylt   *ceed = op->ceed;
2664ce2993fSjeremylt   return 0;
2674ce2993fSjeremylt }
2684ce2993fSjeremylt 
2694ce2993fSjeremylt /**
2704ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
2714ce2993fSjeremylt 
2724ce2993fSjeremylt   @param op              CeedOperator
2734ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
2744ce2993fSjeremylt 
2754ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2764ce2993fSjeremylt 
27723617272Sjeremylt   @ref Advanced
2784ce2993fSjeremylt **/
2794ce2993fSjeremylt 
2804ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
28152d6035fSJeremy L Thompson   if (op->composite)
28252d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
28352d6035fSJeremy L Thompson 
2844ce2993fSjeremylt   *numelem = op->numelements;
2854ce2993fSjeremylt   return 0;
2864ce2993fSjeremylt }
2874ce2993fSjeremylt 
2884ce2993fSjeremylt /**
2894ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
2904ce2993fSjeremylt 
2914ce2993fSjeremylt   @param op              CeedOperator
2924ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
2934ce2993fSjeremylt 
2944ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2954ce2993fSjeremylt 
29623617272Sjeremylt   @ref Advanced
2974ce2993fSjeremylt **/
2984ce2993fSjeremylt 
2994ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
30052d6035fSJeremy L Thompson   if (op->composite)
30152d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
30252d6035fSJeremy L Thompson 
3034ce2993fSjeremylt   *numqpts = op->numqpoints;
3044ce2993fSjeremylt   return 0;
3054ce2993fSjeremylt }
3064ce2993fSjeremylt 
3074ce2993fSjeremylt /**
3084ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
3094ce2993fSjeremylt 
3104ce2993fSjeremylt   @param op              CeedOperator
3114ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
3124ce2993fSjeremylt 
3134ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3144ce2993fSjeremylt 
31523617272Sjeremylt   @ref Advanced
3164ce2993fSjeremylt **/
3174ce2993fSjeremylt 
3184ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
31952d6035fSJeremy L Thompson   if (op->composite)
32052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
3214ce2993fSjeremylt   *numargs = op->nfields;
3224ce2993fSjeremylt   return 0;
3234ce2993fSjeremylt }
3244ce2993fSjeremylt 
3254ce2993fSjeremylt /**
3264ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
3274ce2993fSjeremylt 
3284ce2993fSjeremylt   @param op             CeedOperator
329*288c0443SJeremy L Thompson   @param[out] setupdone Variable to store setup status
3304ce2993fSjeremylt 
3314ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3324ce2993fSjeremylt 
33323617272Sjeremylt   @ref Advanced
3344ce2993fSjeremylt **/
3354ce2993fSjeremylt 
3364ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
3374ce2993fSjeremylt   *setupdone = op->setupdone;
3384ce2993fSjeremylt   return 0;
3394ce2993fSjeremylt }
3404ce2993fSjeremylt 
3414ce2993fSjeremylt /**
3424ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
3434ce2993fSjeremylt 
3444ce2993fSjeremylt   @param op              CeedOperator
3458c91a0c9SJeremy L Thompson   @param[out] qf         Variable to store QFunction
3464ce2993fSjeremylt 
3474ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3484ce2993fSjeremylt 
34923617272Sjeremylt   @ref Advanced
3504ce2993fSjeremylt **/
3514ce2993fSjeremylt 
3524ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
35352d6035fSJeremy L Thompson   if (op->composite)
35452d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
35552d6035fSJeremy L Thompson 
3564ce2993fSjeremylt   *qf = op->qf;
3574ce2993fSjeremylt   return 0;
3584ce2993fSjeremylt }
3594ce2993fSjeremylt 
3604ce2993fSjeremylt /**
36152d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
36252d6035fSJeremy L Thompson 
36352d6035fSJeremy L Thompson   @param op              CeedOperator
36452d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
36552d6035fSJeremy L Thompson 
36652d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
36752d6035fSJeremy L Thompson 
36852d6035fSJeremy L Thompson   @ref Advanced
36952d6035fSJeremy L Thompson **/
37052d6035fSJeremy L Thompson 
37152d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
37252d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
37352d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
37452d6035fSJeremy L Thompson 
37552d6035fSJeremy L Thompson   *numsub = op->numsub;
37652d6035fSJeremy L Thompson   return 0;
37752d6035fSJeremy L Thompson }
37852d6035fSJeremy L Thompson 
37952d6035fSJeremy L Thompson /**
38052d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
38152d6035fSJeremy L Thompson 
38252d6035fSJeremy L Thompson   @param op                CeedOperator
38352d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
38452d6035fSJeremy L Thompson 
38552d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
38652d6035fSJeremy L Thompson 
38752d6035fSJeremy L Thompson   @ref Advanced
38852d6035fSJeremy L Thompson **/
38952d6035fSJeremy L Thompson 
39052d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
39152d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
39252d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
39352d6035fSJeremy L Thompson 
39452d6035fSJeremy L Thompson   *suboperators = op->suboperators;
39552d6035fSJeremy L Thompson   return 0;
39652d6035fSJeremy L Thompson }
39752d6035fSJeremy L Thompson 
39852d6035fSJeremy L Thompson /**
399fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
400fe2413ffSjeremylt 
401fe2413ffSjeremylt   @param[out] op         CeedOperator
402fe2413ffSjeremylt   @param data            Data to set
403fe2413ffSjeremylt 
404fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
405fe2413ffSjeremylt 
406fe2413ffSjeremylt   @ref Advanced
407fe2413ffSjeremylt **/
408fe2413ffSjeremylt 
409fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
410fe2413ffSjeremylt   op->data = *data;
411fe2413ffSjeremylt   return 0;
412fe2413ffSjeremylt }
413fe2413ffSjeremylt 
414fe2413ffSjeremylt /**
4154ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
4164ce2993fSjeremylt 
4174ce2993fSjeremylt   @param op              CeedOperator
4184ce2993fSjeremylt   @param[out] data       Variable to store data
4194ce2993fSjeremylt 
4204ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4214ce2993fSjeremylt 
42223617272Sjeremylt   @ref Advanced
4234ce2993fSjeremylt **/
4244ce2993fSjeremylt 
4254ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
4264ce2993fSjeremylt   *data = op->data;
4274ce2993fSjeremylt   return 0;
4284ce2993fSjeremylt }
4294ce2993fSjeremylt 
4304ce2993fSjeremylt /**
4314ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
4324ce2993fSjeremylt 
4334ce2993fSjeremylt   @param op              CeedOperator
4344ce2993fSjeremylt 
4354ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4364ce2993fSjeremylt 
43723617272Sjeremylt   @ref Advanced
4384ce2993fSjeremylt **/
4394ce2993fSjeremylt 
4404ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
4414ce2993fSjeremylt   op->setupdone = 1;
4424ce2993fSjeremylt   return 0;
4434ce2993fSjeremylt }
4444ce2993fSjeremylt 
4454ce2993fSjeremylt /**
446d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
447d1bcdac9Sjeremylt 
448d1bcdac9Sjeremylt   @param op                 CeedOperator
449d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
450d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
451d1bcdac9Sjeremylt 
452d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
453d1bcdac9Sjeremylt 
454d1bcdac9Sjeremylt   @ref Advanced
455d1bcdac9Sjeremylt **/
456d1bcdac9Sjeremylt 
457d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
458d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
459d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
46052d6035fSJeremy L Thompson   if (op->composite)
46152d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
46252d6035fSJeremy L Thompson 
463d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
464d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
465d1bcdac9Sjeremylt   return 0;
466d1bcdac9Sjeremylt }
467d1bcdac9Sjeremylt 
468d1bcdac9Sjeremylt /**
4694dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
4704dccadb6Sjeremylt 
4714dccadb6Sjeremylt   @param opfield         CeedOperatorField
4724dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
4734dccadb6Sjeremylt 
4744dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
4754dccadb6Sjeremylt 
4764dccadb6Sjeremylt   @ref Advanced
4774dccadb6Sjeremylt **/
4784dccadb6Sjeremylt 
4794dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
4804dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
481fe2413ffSjeremylt   *lmode = opfield->lmode;
4824dccadb6Sjeremylt   return 0;
4834dccadb6Sjeremylt }/**
484d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
485d1bcdac9Sjeremylt 
486d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
487d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
488d1bcdac9Sjeremylt 
489d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
490d1bcdac9Sjeremylt 
491d1bcdac9Sjeremylt   @ref Advanced
492d1bcdac9Sjeremylt **/
493d1bcdac9Sjeremylt 
494d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
495d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
496fe2413ffSjeremylt   *rstr = opfield->Erestrict;
497d1bcdac9Sjeremylt   return 0;
498d1bcdac9Sjeremylt }
499d1bcdac9Sjeremylt 
500d1bcdac9Sjeremylt /**
501d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
502d1bcdac9Sjeremylt 
503d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
504d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
505d1bcdac9Sjeremylt 
506d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
507d1bcdac9Sjeremylt 
508d1bcdac9Sjeremylt   @ref Advanced
509d1bcdac9Sjeremylt **/
510d1bcdac9Sjeremylt 
511d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
512d1bcdac9Sjeremylt                               CeedBasis *basis) {
513fe2413ffSjeremylt   *basis = opfield->basis;
514d1bcdac9Sjeremylt   return 0;
515d1bcdac9Sjeremylt }
516d1bcdac9Sjeremylt 
517d1bcdac9Sjeremylt /**
518d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
519d1bcdac9Sjeremylt 
520d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
521d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
522d1bcdac9Sjeremylt 
523d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
524d1bcdac9Sjeremylt 
525d1bcdac9Sjeremylt   @ref Advanced
526d1bcdac9Sjeremylt **/
527d1bcdac9Sjeremylt 
528d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
529d1bcdac9Sjeremylt                                CeedVector *vec) {
530fe2413ffSjeremylt   *vec = opfield->vec;
531d1bcdac9Sjeremylt   return 0;
532d1bcdac9Sjeremylt }
533d1bcdac9Sjeremylt 
534d1bcdac9Sjeremylt /**
535b11c1e72Sjeremylt   @brief Destroy a CeedOperator
536d7b241e6Sjeremylt 
537d7b241e6Sjeremylt   @param op CeedOperator to destroy
538b11c1e72Sjeremylt 
539b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
540dfdf5a53Sjeremylt 
541dfdf5a53Sjeremylt   @ref Basic
542b11c1e72Sjeremylt **/
543d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
544d7b241e6Sjeremylt   int ierr;
545d7b241e6Sjeremylt 
546d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
547d7b241e6Sjeremylt   if ((*op)->Destroy) {
548d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
549d7b241e6Sjeremylt   }
550fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
551fe2413ffSjeremylt   // Free fields
552d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
55352d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
554fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
555fe2413ffSjeremylt     }
556d0eb30a5Sjeremylt   }
557d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
558d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
559fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
560fe2413ffSjeremylt     }
561d0eb30a5Sjeremylt   }
56252d6035fSJeremy L Thompson   // Destroy suboperators
56352d6035fSJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++) {
56452d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
56552d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
56652d6035fSJeremy L Thompson     }
56752d6035fSJeremy L Thompson   }
568d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
569d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
570d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
571fe2413ffSjeremylt 
572fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
573fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
57452d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
575d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
576d7b241e6Sjeremylt   return 0;
577d7b241e6Sjeremylt }
578d7b241e6Sjeremylt 
579d7b241e6Sjeremylt /// @}
580