xref: /libCEED/interface/ceed-operator.c (revision 0219ea01e2c00bd70a330a05b50ef0218d6ddcb0)
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 /**
28*0219ea01SJeremy L Thompson   @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and
29*0219ea01SJeremy L Thompson            CeedElemRestriction can be associated with CeedQFunction fields with
30*0219ea01SJeremy L Thompson            \ref CeedOperatorSetField.
31d7b241e6Sjeremylt 
32b11c1e72Sjeremylt   @param ceed    A Ceed object where the CeedOperator will be created
33d7b241e6Sjeremylt   @param qf      QFunction defining the action of the operator at quadrature points
34d7b241e6Sjeremylt   @param dqf     QFunction defining the action of the Jacobian of @a qf (or NULL)
35d7b241e6Sjeremylt   @param dqfT    QFunction defining the action of the transpose of the Jacobian
36d7b241e6Sjeremylt                    of @a qf (or NULL)
37b11c1e72Sjeremylt   @param[out] op Address of the variable where the newly created
38b11c1e72Sjeremylt                      CeedOperator will be stored
39b11c1e72Sjeremylt 
40b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
41dfdf5a53Sjeremylt 
42dfdf5a53Sjeremylt   @ref Basic
43d7b241e6Sjeremylt  */
44d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf,
45d7b241e6Sjeremylt                        CeedQFunction dqfT, CeedOperator *op) {
46d7b241e6Sjeremylt   int ierr;
47d7b241e6Sjeremylt 
485fe0d4faSjeremylt   if (!ceed->OperatorCreate) {
495fe0d4faSjeremylt     Ceed delegate;
50aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr);
515fe0d4faSjeremylt 
525fe0d4faSjeremylt     if (!delegate)
535fe0d4faSjeremylt       return CeedError(ceed, 1, "Backend does not support OperatorCreate");
545fe0d4faSjeremylt 
555fe0d4faSjeremylt     ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr);
565fe0d4faSjeremylt     return 0;
575fe0d4faSjeremylt   }
585fe0d4faSjeremylt 
59d7b241e6Sjeremylt   ierr = CeedCalloc(1,op); CeedChk(ierr);
60d7b241e6Sjeremylt   (*op)->ceed = ceed;
61d7b241e6Sjeremylt   ceed->refcount++;
62d7b241e6Sjeremylt   (*op)->refcount = 1;
63d7b241e6Sjeremylt   (*op)->qf = qf;
64d7b241e6Sjeremylt   qf->refcount++;
65d7b241e6Sjeremylt   (*op)->dqf = dqf;
66d7b241e6Sjeremylt   if (dqf) dqf->refcount++;
67d7b241e6Sjeremylt   (*op)->dqfT = dqfT;
68d7b241e6Sjeremylt   if (dqfT) dqfT->refcount++;
69fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr);
70fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr);
71d7b241e6Sjeremylt   ierr = ceed->OperatorCreate(*op); CeedChk(ierr);
72d7b241e6Sjeremylt   return 0;
73d7b241e6Sjeremylt }
74d7b241e6Sjeremylt 
75d7b241e6Sjeremylt /**
7652d6035fSJeremy L Thompson   @brief Create an operator that composes the action of several operators
7752d6035fSJeremy L Thompson 
7852d6035fSJeremy L Thompson   @param ceed    A Ceed object where the CeedOperator will be created
7952d6035fSJeremy L Thompson   @param[out] op Address of the variable where the newly created
8052d6035fSJeremy L Thompson                      Composite CeedOperator will be stored
8152d6035fSJeremy L Thompson 
8252d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8352d6035fSJeremy L Thompson 
8452d6035fSJeremy L Thompson   @ref Basic
8552d6035fSJeremy L Thompson  */
8652d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) {
8752d6035fSJeremy L Thompson   int ierr;
8852d6035fSJeremy L Thompson 
8952d6035fSJeremy L Thompson   if (!ceed->CompositeOperatorCreate) {
9052d6035fSJeremy L Thompson     Ceed delegate;
91aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr);
9252d6035fSJeremy L Thompson 
9352d6035fSJeremy L Thompson     if (!delegate)
9452d6035fSJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support \
9552d6035fSJeremy L Thompson                                    CompositeOperatorCreate");
9652d6035fSJeremy L Thompson 
9752d6035fSJeremy L Thompson     ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr);
9852d6035fSJeremy L Thompson     return 0;
9952d6035fSJeremy L Thompson   }
10052d6035fSJeremy L Thompson 
10152d6035fSJeremy L Thompson   ierr = CeedCalloc(1,op); CeedChk(ierr);
10252d6035fSJeremy L Thompson   (*op)->ceed = ceed;
10352d6035fSJeremy L Thompson   ceed->refcount++;
10452d6035fSJeremy L Thompson   (*op)->composite = true;
10552d6035fSJeremy L Thompson   ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr);
10652d6035fSJeremy L Thompson   ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr);
10752d6035fSJeremy L Thompson   return 0;
10852d6035fSJeremy L Thompson }
10952d6035fSJeremy L Thompson 
11052d6035fSJeremy L Thompson /**
111b11c1e72Sjeremylt   @brief Provide a field to a CeedOperator for use by its CeedQFunction
112d7b241e6Sjeremylt 
113d7b241e6Sjeremylt   This function is used to specify both active and passive fields to a
114d7b241e6Sjeremylt   CeedOperator.  For passive fields, a vector @arg v must be provided.  Passive
115d7b241e6Sjeremylt   fields can inputs or outputs (updated in-place when operator is applied).
116d7b241e6Sjeremylt 
117d7b241e6Sjeremylt   Active fields must be specified using this function, but their data (in a
118d7b241e6Sjeremylt   CeedVector) is passed in CeedOperatorApply().  There can be at most one active
119d7b241e6Sjeremylt   input and at most one active output.
120d7b241e6Sjeremylt 
1218c91a0c9SJeremy L Thompson   @param op         CeedOperator on which to provide the field
1228795c945Sjeremylt   @param fieldname  Name of the field (to be matched with the name used by
1238795c945Sjeremylt                       CeedQFunction)
124b11c1e72Sjeremylt   @param r          CeedElemRestriction
125b0e29e78Sjeremylt   @param lmode      CeedTransposeMode which specifies the ordering of the
126b0e29e78Sjeremylt                       components of the l-vector used by this CeedOperatorField,
127b0e29e78Sjeremylt                       CEED_NOTRANSPOSE indicates the component is the
128b0e29e78Sjeremylt                       outermost index and CEED_TRANSPOSE indicates the component
129b0e29e78Sjeremylt                       is the innermost index in ordering of the l-vector
130783c99b3SValeria Barra   @param b          CeedBasis in which the field resides or CEED_BASIS_COLLOCATED
131b11c1e72Sjeremylt                       if collocated with quadrature points
132b11c1e72Sjeremylt   @param v          CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE
133b11c1e72Sjeremylt                       if field is active or CEED_VECTOR_NONE if using
1348c91a0c9SJeremy L Thompson                       CEED_EVAL_WEIGHT in the QFunction
135b11c1e72Sjeremylt 
136b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
137dfdf5a53Sjeremylt 
138dfdf5a53Sjeremylt   @ref Basic
139b11c1e72Sjeremylt **/
140d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname,
1414dccadb6Sjeremylt                          CeedElemRestriction r, CeedTransposeMode lmode,
1424dccadb6Sjeremylt                          CeedBasis b, CeedVector v) {
143d7b241e6Sjeremylt   int ierr;
14452d6035fSJeremy L Thompson   if (op->composite)
14552d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Cannot add field to composite operator.");
1468b067b84SJed Brown   if (!r)
1478b067b84SJed Brown     return CeedError(op->ceed, 1, "ElemRestriction r for field \"%s\" must be non-NULL.", fieldname);
1488b067b84SJed Brown   if (!b)
1498b067b84SJed Brown     return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.", fieldname);
1508b067b84SJed Brown   if (!v)
1518b067b84SJed Brown     return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.", fieldname);
15252d6035fSJeremy L Thompson 
153d7b241e6Sjeremylt   CeedInt numelements;
154d7b241e6Sjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr);
155d7b241e6Sjeremylt   if (op->numelements && op->numelements != numelements)
156d7b241e6Sjeremylt     return CeedError(op->ceed, 1,
157d7b241e6Sjeremylt                      "ElemRestriction with %d elements incompatible with prior %d elements",
158d7b241e6Sjeremylt                      numelements, op->numelements);
159d7b241e6Sjeremylt   op->numelements = numelements;
160d7b241e6Sjeremylt 
161783c99b3SValeria Barra   if (b != CEED_BASIS_COLLOCATED) {
162d7b241e6Sjeremylt     CeedInt numqpoints;
163d7b241e6Sjeremylt     ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr);
164d7b241e6Sjeremylt     if (op->numqpoints && op->numqpoints != numqpoints)
165d7b241e6Sjeremylt       return CeedError(op->ceed, 1,
166d7b241e6Sjeremylt                        "Basis with %d quadrature points incompatible with prior %d points",
167d7b241e6Sjeremylt                        numqpoints, op->numqpoints);
168d7b241e6Sjeremylt     op->numqpoints = numqpoints;
169d7b241e6Sjeremylt   }
170d1bcdac9Sjeremylt   CeedOperatorField *ofield;
171d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numinputfields; i++) {
172fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) {
173d7b241e6Sjeremylt       ofield = &op->inputfields[i];
174d7b241e6Sjeremylt       goto found;
175d7b241e6Sjeremylt     }
176d7b241e6Sjeremylt   }
177d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numoutputfields; i++) {
178fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) {
179d7b241e6Sjeremylt       ofield = &op->outputfields[i];
180d7b241e6Sjeremylt       goto found;
181d7b241e6Sjeremylt     }
182d7b241e6Sjeremylt   }
183d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
184d7b241e6Sjeremylt                    fieldname);
185d7b241e6Sjeremylt found:
186fe2413ffSjeremylt   ierr = CeedCalloc(1, ofield); CeedChk(ierr);
187fe2413ffSjeremylt   (*ofield)->Erestrict = r;
188fe2413ffSjeremylt   (*ofield)->lmode = lmode;
189fe2413ffSjeremylt   (*ofield)->basis = b;
190fe2413ffSjeremylt   (*ofield)->vec = v;
191d7b241e6Sjeremylt   op->nfields += 1;
192d7b241e6Sjeremylt   return 0;
193d7b241e6Sjeremylt }
194d7b241e6Sjeremylt 
195d7b241e6Sjeremylt /**
19652d6035fSJeremy L Thompson   @brief Add a sub-operator to a composite CeedOperator
197288c0443SJeremy L Thompson 
198288c0443SJeremy L Thompson   @param[out] compositeop Address of the composite CeedOperator
199288c0443SJeremy L Thompson   @param      subop       Address of the sub-operator CeedOperator
20052d6035fSJeremy L Thompson 
20152d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
20252d6035fSJeremy L Thompson 
20352d6035fSJeremy L Thompson   @ref Basic
20452d6035fSJeremy L Thompson  */
20552d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
20652d6035fSJeremy L Thompson                                 CeedOperator subop) {
20752d6035fSJeremy L Thompson   if (!compositeop->composite)
20852d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
20952d6035fSJeremy L Thompson                      "CeedOperator is not a composite operator");
21052d6035fSJeremy L Thompson 
21152d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
21252d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
21352d6035fSJeremy L Thompson                      "Cannot add additional suboperators");
21452d6035fSJeremy L Thompson 
21552d6035fSJeremy L Thompson   compositeop->suboperators[compositeop->numsub] = subop;
21652d6035fSJeremy L Thompson   subop->refcount++;
21752d6035fSJeremy L Thompson   compositeop->numsub++;
21852d6035fSJeremy L Thompson   return 0;
21952d6035fSJeremy L Thompson }
22052d6035fSJeremy L Thompson 
22152d6035fSJeremy L Thompson /**
222b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
223d7b241e6Sjeremylt 
224d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
225d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
226d7b241e6Sjeremylt   CeedOperatorSetField().
227d7b241e6Sjeremylt 
228d7b241e6Sjeremylt   @param op        CeedOperator to apply
229b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
230b11c1e72Sjeremylt                      active inputs
231b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
232d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
233d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
234d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
235b11c1e72Sjeremylt 
236b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
237dfdf5a53Sjeremylt 
238dfdf5a53Sjeremylt   @ref Basic
239b11c1e72Sjeremylt **/
240d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
241d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
242d7b241e6Sjeremylt   int ierr;
243d7b241e6Sjeremylt   Ceed ceed = op->ceed;
244d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
245d7b241e6Sjeremylt 
24652d6035fSJeremy L Thompson   if (op->composite) {
24752d6035fSJeremy L Thompson     if (!op->numsub) return CeedError(ceed, 1, "No suboperators set");
24852d6035fSJeremy L Thompson   } else {
249d7b241e6Sjeremylt     if (op->nfields == 0) return CeedError(ceed, 1, "No operator fields set");
250d7b241e6Sjeremylt     if (op->nfields < qf->numinputfields + qf->numoutputfields) return CeedError(
251d7b241e6Sjeremylt             ceed, 1, "Not all operator fields set");
252d7b241e6Sjeremylt     if (op->numelements == 0) return CeedError(ceed, 1,
253d7b241e6Sjeremylt                                        "At least one restriction required");
254d7b241e6Sjeremylt     if (op->numqpoints == 0) return CeedError(ceed, 1,
255783c99b3SValeria Barra                                       "At least one non-collocated basis required");
25652d6035fSJeremy L Thompson   }
257d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
258d7b241e6Sjeremylt   return 0;
259d7b241e6Sjeremylt }
260d7b241e6Sjeremylt 
261d7b241e6Sjeremylt /**
2624ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
2634ce2993fSjeremylt 
2644ce2993fSjeremylt   @param op              CeedOperator
2654ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
2664ce2993fSjeremylt 
2674ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2684ce2993fSjeremylt 
26923617272Sjeremylt   @ref Advanced
2704ce2993fSjeremylt **/
2714ce2993fSjeremylt 
2724ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
2734ce2993fSjeremylt   *ceed = op->ceed;
2744ce2993fSjeremylt   return 0;
2754ce2993fSjeremylt }
2764ce2993fSjeremylt 
2774ce2993fSjeremylt /**
2784ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
2794ce2993fSjeremylt 
2804ce2993fSjeremylt   @param op              CeedOperator
2814ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
2824ce2993fSjeremylt 
2834ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2844ce2993fSjeremylt 
28523617272Sjeremylt   @ref Advanced
2864ce2993fSjeremylt **/
2874ce2993fSjeremylt 
2884ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
28952d6035fSJeremy L Thompson   if (op->composite)
29052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
29152d6035fSJeremy L Thompson 
2924ce2993fSjeremylt   *numelem = op->numelements;
2934ce2993fSjeremylt   return 0;
2944ce2993fSjeremylt }
2954ce2993fSjeremylt 
2964ce2993fSjeremylt /**
2974ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
2984ce2993fSjeremylt 
2994ce2993fSjeremylt   @param op              CeedOperator
3004ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
3014ce2993fSjeremylt 
3024ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3034ce2993fSjeremylt 
30423617272Sjeremylt   @ref Advanced
3054ce2993fSjeremylt **/
3064ce2993fSjeremylt 
3074ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
30852d6035fSJeremy L Thompson   if (op->composite)
30952d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
31052d6035fSJeremy L Thompson 
3114ce2993fSjeremylt   *numqpts = op->numqpoints;
3124ce2993fSjeremylt   return 0;
3134ce2993fSjeremylt }
3144ce2993fSjeremylt 
3154ce2993fSjeremylt /**
3164ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
3174ce2993fSjeremylt 
3184ce2993fSjeremylt   @param op              CeedOperator
3194ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
3204ce2993fSjeremylt 
3214ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3224ce2993fSjeremylt 
32323617272Sjeremylt   @ref Advanced
3244ce2993fSjeremylt **/
3254ce2993fSjeremylt 
3264ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
32752d6035fSJeremy L Thompson   if (op->composite)
32852d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
3294ce2993fSjeremylt   *numargs = op->nfields;
3304ce2993fSjeremylt   return 0;
3314ce2993fSjeremylt }
3324ce2993fSjeremylt 
3334ce2993fSjeremylt /**
3344ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
3354ce2993fSjeremylt 
3364ce2993fSjeremylt   @param op             CeedOperator
337288c0443SJeremy L Thompson   @param[out] setupdone Variable to store setup status
3384ce2993fSjeremylt 
3394ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3404ce2993fSjeremylt 
34123617272Sjeremylt   @ref Advanced
3424ce2993fSjeremylt **/
3434ce2993fSjeremylt 
3444ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
3454ce2993fSjeremylt   *setupdone = op->setupdone;
3464ce2993fSjeremylt   return 0;
3474ce2993fSjeremylt }
3484ce2993fSjeremylt 
3494ce2993fSjeremylt /**
3504ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
3514ce2993fSjeremylt 
3524ce2993fSjeremylt   @param op              CeedOperator
3538c91a0c9SJeremy L Thompson   @param[out] qf         Variable to store QFunction
3544ce2993fSjeremylt 
3554ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3564ce2993fSjeremylt 
35723617272Sjeremylt   @ref Advanced
3584ce2993fSjeremylt **/
3594ce2993fSjeremylt 
3604ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
36152d6035fSJeremy L Thompson   if (op->composite)
36252d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
36352d6035fSJeremy L Thompson 
3644ce2993fSjeremylt   *qf = op->qf;
3654ce2993fSjeremylt   return 0;
3664ce2993fSjeremylt }
3674ce2993fSjeremylt 
3684ce2993fSjeremylt /**
36952d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
37052d6035fSJeremy L Thompson 
37152d6035fSJeremy L Thompson   @param op              CeedOperator
37252d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
37352d6035fSJeremy L Thompson 
37452d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
37552d6035fSJeremy L Thompson 
37652d6035fSJeremy L Thompson   @ref Advanced
37752d6035fSJeremy L Thompson **/
37852d6035fSJeremy L Thompson 
37952d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
38052d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
38152d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
38252d6035fSJeremy L Thompson 
38352d6035fSJeremy L Thompson   *numsub = op->numsub;
38452d6035fSJeremy L Thompson   return 0;
38552d6035fSJeremy L Thompson }
38652d6035fSJeremy L Thompson 
38752d6035fSJeremy L Thompson /**
38852d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
38952d6035fSJeremy L Thompson 
39052d6035fSJeremy L Thompson   @param op                CeedOperator
39152d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
39252d6035fSJeremy L Thompson 
39352d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
39452d6035fSJeremy L Thompson 
39552d6035fSJeremy L Thompson   @ref Advanced
39652d6035fSJeremy L Thompson **/
39752d6035fSJeremy L Thompson 
39852d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
39952d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
40052d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
40152d6035fSJeremy L Thompson 
40252d6035fSJeremy L Thompson   *suboperators = op->suboperators;
40352d6035fSJeremy L Thompson   return 0;
40452d6035fSJeremy L Thompson }
40552d6035fSJeremy L Thompson 
40652d6035fSJeremy L Thompson /**
407fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
408fe2413ffSjeremylt 
409fe2413ffSjeremylt   @param[out] op         CeedOperator
410fe2413ffSjeremylt   @param data            Data to set
411fe2413ffSjeremylt 
412fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
413fe2413ffSjeremylt 
414fe2413ffSjeremylt   @ref Advanced
415fe2413ffSjeremylt **/
416fe2413ffSjeremylt 
417fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
418fe2413ffSjeremylt   op->data = *data;
419fe2413ffSjeremylt   return 0;
420fe2413ffSjeremylt }
421fe2413ffSjeremylt 
422fe2413ffSjeremylt /**
4234ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
4244ce2993fSjeremylt 
4254ce2993fSjeremylt   @param op              CeedOperator
4264ce2993fSjeremylt   @param[out] data       Variable to store data
4274ce2993fSjeremylt 
4284ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4294ce2993fSjeremylt 
43023617272Sjeremylt   @ref Advanced
4314ce2993fSjeremylt **/
4324ce2993fSjeremylt 
4334ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
4344ce2993fSjeremylt   *data = op->data;
4354ce2993fSjeremylt   return 0;
4364ce2993fSjeremylt }
4374ce2993fSjeremylt 
4384ce2993fSjeremylt /**
4394ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
4404ce2993fSjeremylt 
4414ce2993fSjeremylt   @param op              CeedOperator
4424ce2993fSjeremylt 
4434ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4444ce2993fSjeremylt 
44523617272Sjeremylt   @ref Advanced
4464ce2993fSjeremylt **/
4474ce2993fSjeremylt 
4484ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
4494ce2993fSjeremylt   op->setupdone = 1;
4504ce2993fSjeremylt   return 0;
4514ce2993fSjeremylt }
4524ce2993fSjeremylt 
4534ce2993fSjeremylt /**
454d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
455d1bcdac9Sjeremylt 
456d1bcdac9Sjeremylt   @param op                 CeedOperator
457d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
458d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
459d1bcdac9Sjeremylt 
460d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
461d1bcdac9Sjeremylt 
462d1bcdac9Sjeremylt   @ref Advanced
463d1bcdac9Sjeremylt **/
464d1bcdac9Sjeremylt 
465d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
466d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
467d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
46852d6035fSJeremy L Thompson   if (op->composite)
46952d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
47052d6035fSJeremy L Thompson 
471d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
472d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
473d1bcdac9Sjeremylt   return 0;
474d1bcdac9Sjeremylt }
475d1bcdac9Sjeremylt 
476d1bcdac9Sjeremylt /**
4774dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
4784dccadb6Sjeremylt 
4794dccadb6Sjeremylt   @param opfield         CeedOperatorField
4804dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
4814dccadb6Sjeremylt 
4824dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
4834dccadb6Sjeremylt 
4844dccadb6Sjeremylt   @ref Advanced
4854dccadb6Sjeremylt **/
4864dccadb6Sjeremylt 
4874dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
4884dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
489fe2413ffSjeremylt   *lmode = opfield->lmode;
4904dccadb6Sjeremylt   return 0;
4914dccadb6Sjeremylt }/**
492d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
493d1bcdac9Sjeremylt 
494d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
495d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
496d1bcdac9Sjeremylt 
497d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
498d1bcdac9Sjeremylt 
499d1bcdac9Sjeremylt   @ref Advanced
500d1bcdac9Sjeremylt **/
501d1bcdac9Sjeremylt 
502d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
503d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
504fe2413ffSjeremylt   *rstr = opfield->Erestrict;
505d1bcdac9Sjeremylt   return 0;
506d1bcdac9Sjeremylt }
507d1bcdac9Sjeremylt 
508d1bcdac9Sjeremylt /**
509d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
510d1bcdac9Sjeremylt 
511d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
512d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
513d1bcdac9Sjeremylt 
514d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
515d1bcdac9Sjeremylt 
516d1bcdac9Sjeremylt   @ref Advanced
517d1bcdac9Sjeremylt **/
518d1bcdac9Sjeremylt 
519d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
520d1bcdac9Sjeremylt                               CeedBasis *basis) {
521fe2413ffSjeremylt   *basis = opfield->basis;
522d1bcdac9Sjeremylt   return 0;
523d1bcdac9Sjeremylt }
524d1bcdac9Sjeremylt 
525d1bcdac9Sjeremylt /**
526d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
527d1bcdac9Sjeremylt 
528d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
529d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
530d1bcdac9Sjeremylt 
531d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
532d1bcdac9Sjeremylt 
533d1bcdac9Sjeremylt   @ref Advanced
534d1bcdac9Sjeremylt **/
535d1bcdac9Sjeremylt 
536d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
537d1bcdac9Sjeremylt                                CeedVector *vec) {
538fe2413ffSjeremylt   *vec = opfield->vec;
539d1bcdac9Sjeremylt   return 0;
540d1bcdac9Sjeremylt }
541d1bcdac9Sjeremylt 
542d1bcdac9Sjeremylt /**
543b11c1e72Sjeremylt   @brief Destroy a CeedOperator
544d7b241e6Sjeremylt 
545d7b241e6Sjeremylt   @param op CeedOperator to destroy
546b11c1e72Sjeremylt 
547b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
548dfdf5a53Sjeremylt 
549dfdf5a53Sjeremylt   @ref Basic
550b11c1e72Sjeremylt **/
551d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
552d7b241e6Sjeremylt   int ierr;
553d7b241e6Sjeremylt 
554d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
555d7b241e6Sjeremylt   if ((*op)->Destroy) {
556d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
557d7b241e6Sjeremylt   }
558fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
559fe2413ffSjeremylt   // Free fields
560d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
56152d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
562fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
563fe2413ffSjeremylt     }
564d0eb30a5Sjeremylt   }
565d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
566d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
567fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
568fe2413ffSjeremylt     }
569d0eb30a5Sjeremylt   }
57052d6035fSJeremy L Thompson   // Destroy suboperators
57152d6035fSJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++) {
57252d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
57352d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
57452d6035fSJeremy L Thompson     }
57552d6035fSJeremy L Thompson   }
576d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
577d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
578d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
579fe2413ffSjeremylt 
580fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
581fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
58252d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
583d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
584d7b241e6Sjeremylt   return 0;
585d7b241e6Sjeremylt }
586d7b241e6Sjeremylt 
587d7b241e6Sjeremylt /// @}
588