xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-operator.c (revision c042f62f62e10e1321eb699b116e67a6568d5716)
1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details.
4d7b241e6Sjeremylt //
5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral
7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and
8d7b241e6Sjeremylt // source code availability see http://github.com/ceed.
9d7b241e6Sjeremylt //
10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for
13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including
14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early
15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
16d7b241e6Sjeremylt 
17d7b241e6Sjeremylt #include <ceed-impl.h>
18d863ab9bSjeremylt #include <ceed-backend.h>
19d7b241e6Sjeremylt #include <string.h>
20d7b241e6Sjeremylt 
21dfdf5a53Sjeremylt /// @file
22dfdf5a53Sjeremylt /// Implementation of public CeedOperator interfaces
23dfdf5a53Sjeremylt ///
24dfdf5a53Sjeremylt /// @addtogroup CeedOperator
25dfdf5a53Sjeremylt ///   @{
26d7b241e6Sjeremylt 
27d7b241e6Sjeremylt /**
280219ea01SJeremy L Thompson   @brief Create a CeedOperator and associate a CeedQFunction. A CeedBasis and
290219ea01SJeremy L Thompson            CeedElemRestriction can be associated with CeedQFunction fields with
300219ea01SJeremy L Thompson            \ref CeedOperatorSetField.
31d7b241e6Sjeremylt 
32b11c1e72Sjeremylt   @param ceed    A Ceed object where the CeedOperator will be created
33d7b241e6Sjeremylt   @param qf      QFunction defining the action of the operator at quadrature points
34d7b241e6Sjeremylt   @param dqf     QFunction defining the action of the Jacobian of @a qf (or NULL)
35d7b241e6Sjeremylt   @param dqfT    QFunction defining the action of the transpose of the Jacobian
36d7b241e6Sjeremylt                    of @a qf (or NULL)
37b11c1e72Sjeremylt   @param[out] op Address of the variable where the newly created
38b11c1e72Sjeremylt                      CeedOperator will be stored
39b11c1e72Sjeremylt 
40b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
41dfdf5a53Sjeremylt 
42dfdf5a53Sjeremylt   @ref Basic
43d7b241e6Sjeremylt  */
44d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf,
45d7b241e6Sjeremylt                        CeedQFunction dqfT, CeedOperator *op) {
46d7b241e6Sjeremylt   int ierr;
47d7b241e6Sjeremylt 
485fe0d4faSjeremylt   if (!ceed->OperatorCreate) {
495fe0d4faSjeremylt     Ceed delegate;
50aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr);
515fe0d4faSjeremylt 
525fe0d4faSjeremylt     if (!delegate)
53*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
545fe0d4faSjeremylt       return CeedError(ceed, 1, "Backend does not support OperatorCreate");
55*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
565fe0d4faSjeremylt 
575fe0d4faSjeremylt     ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr);
585fe0d4faSjeremylt     return 0;
595fe0d4faSjeremylt   }
605fe0d4faSjeremylt 
61d7b241e6Sjeremylt   ierr = CeedCalloc(1,op); CeedChk(ierr);
62d7b241e6Sjeremylt   (*op)->ceed = ceed;
63d7b241e6Sjeremylt   ceed->refcount++;
64d7b241e6Sjeremylt   (*op)->refcount = 1;
65d7b241e6Sjeremylt   (*op)->qf = qf;
66d7b241e6Sjeremylt   qf->refcount++;
67d7b241e6Sjeremylt   (*op)->dqf = dqf;
68d7b241e6Sjeremylt   if (dqf) dqf->refcount++;
69d7b241e6Sjeremylt   (*op)->dqfT = dqfT;
70d7b241e6Sjeremylt   if (dqfT) dqfT->refcount++;
71fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr);
72fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr);
73d7b241e6Sjeremylt   ierr = ceed->OperatorCreate(*op); CeedChk(ierr);
74d7b241e6Sjeremylt   return 0;
75d7b241e6Sjeremylt }
76d7b241e6Sjeremylt 
77d7b241e6Sjeremylt /**
7852d6035fSJeremy L Thompson   @brief Create an operator that composes the action of several operators
7952d6035fSJeremy L Thompson 
8052d6035fSJeremy L Thompson   @param ceed    A Ceed object where the CeedOperator will be created
8152d6035fSJeremy L Thompson   @param[out] op Address of the variable where the newly created
8252d6035fSJeremy L Thompson                      Composite CeedOperator will be stored
8352d6035fSJeremy L Thompson 
8452d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
8552d6035fSJeremy L Thompson 
8652d6035fSJeremy L Thompson   @ref Basic
8752d6035fSJeremy L Thompson  */
8852d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) {
8952d6035fSJeremy L Thompson   int ierr;
9052d6035fSJeremy L Thompson 
9152d6035fSJeremy L Thompson   if (!ceed->CompositeOperatorCreate) {
9252d6035fSJeremy L Thompson     Ceed delegate;
93aefd8378Sjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "Operator"); CeedChk(ierr);
9452d6035fSJeremy L Thompson 
9552d6035fSJeremy L Thompson     if (!delegate)
96*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
97*c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support CompositeOperatorCreate");
98*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
9952d6035fSJeremy L Thompson 
10052d6035fSJeremy L Thompson     ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr);
10152d6035fSJeremy L Thompson     return 0;
10252d6035fSJeremy L Thompson   }
10352d6035fSJeremy L Thompson 
10452d6035fSJeremy L Thompson   ierr = CeedCalloc(1,op); CeedChk(ierr);
10552d6035fSJeremy L Thompson   (*op)->ceed = ceed;
10652d6035fSJeremy L Thompson   ceed->refcount++;
10752d6035fSJeremy L Thompson   (*op)->composite = true;
10852d6035fSJeremy L Thompson   ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr);
10952d6035fSJeremy L Thompson   ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr);
11052d6035fSJeremy L Thompson   return 0;
11152d6035fSJeremy L Thompson }
11252d6035fSJeremy L Thompson 
11352d6035fSJeremy L Thompson /**
114b11c1e72Sjeremylt   @brief Provide a field to a CeedOperator for use by its CeedQFunction
115d7b241e6Sjeremylt 
116d7b241e6Sjeremylt   This function is used to specify both active and passive fields to a
117d7b241e6Sjeremylt   CeedOperator.  For passive fields, a vector @arg v must be provided.  Passive
118d7b241e6Sjeremylt   fields can inputs or outputs (updated in-place when operator is applied).
119d7b241e6Sjeremylt 
120d7b241e6Sjeremylt   Active fields must be specified using this function, but their data (in a
121d7b241e6Sjeremylt   CeedVector) is passed in CeedOperatorApply().  There can be at most one active
122d7b241e6Sjeremylt   input and at most one active output.
123d7b241e6Sjeremylt 
1248c91a0c9SJeremy L Thompson   @param op         CeedOperator on which to provide the field
1258795c945Sjeremylt   @param fieldname  Name of the field (to be matched with the name used by
1268795c945Sjeremylt                       CeedQFunction)
127b11c1e72Sjeremylt   @param r          CeedElemRestriction
128b0e29e78Sjeremylt   @param lmode      CeedTransposeMode which specifies the ordering of the
129b0e29e78Sjeremylt                       components of the l-vector used by this CeedOperatorField,
130b0e29e78Sjeremylt                       CEED_NOTRANSPOSE indicates the component is the
131b0e29e78Sjeremylt                       outermost index and CEED_TRANSPOSE indicates the component
132b0e29e78Sjeremylt                       is the innermost index in ordering of the l-vector
133783c99b3SValeria Barra   @param b          CeedBasis in which the field resides or CEED_BASIS_COLLOCATED
134b11c1e72Sjeremylt                       if collocated with quadrature points
135b11c1e72Sjeremylt   @param v          CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE
136b11c1e72Sjeremylt                       if field is active or CEED_VECTOR_NONE if using
1378c91a0c9SJeremy L Thompson                       CEED_EVAL_WEIGHT in the QFunction
138b11c1e72Sjeremylt 
139b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
140dfdf5a53Sjeremylt 
141dfdf5a53Sjeremylt   @ref Basic
142b11c1e72Sjeremylt **/
143d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname,
1444dccadb6Sjeremylt                          CeedElemRestriction r, CeedTransposeMode lmode,
1454dccadb6Sjeremylt                          CeedBasis b, CeedVector v) {
146d7b241e6Sjeremylt   int ierr;
14752d6035fSJeremy L Thompson   if (op->composite)
148*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
14952d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Cannot add field to composite operator.");
150*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1518b067b84SJed Brown   if (!r)
152*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
153*c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1,
154*c042f62fSJeremy L Thompson                      "ElemRestriction r for field \"%s\" must be non-NULL.",
155*c042f62fSJeremy L Thompson                      fieldname);
156*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1578b067b84SJed Brown   if (!b)
158*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
159*c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.",
160*c042f62fSJeremy L Thompson                      fieldname);
161*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1628b067b84SJed Brown   if (!v)
163*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
164*c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.",
165*c042f62fSJeremy L Thompson                      fieldname);
166*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
16752d6035fSJeremy L Thompson 
168d7b241e6Sjeremylt   CeedInt numelements;
169d7b241e6Sjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr);
170d7b241e6Sjeremylt   if (op->numelements && op->numelements != numelements)
171*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
172d7b241e6Sjeremylt     return CeedError(op->ceed, 1,
173d7b241e6Sjeremylt                      "ElemRestriction with %d elements incompatible with prior %d elements",
174d7b241e6Sjeremylt                      numelements, op->numelements);
175*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
176d7b241e6Sjeremylt   op->numelements = numelements;
177d7b241e6Sjeremylt 
178783c99b3SValeria Barra   if (b != CEED_BASIS_COLLOCATED) {
179d7b241e6Sjeremylt     CeedInt numqpoints;
180d7b241e6Sjeremylt     ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr);
181d7b241e6Sjeremylt     if (op->numqpoints && op->numqpoints != numqpoints)
182*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
183d7b241e6Sjeremylt       return CeedError(op->ceed, 1,
184d7b241e6Sjeremylt                        "Basis with %d quadrature points incompatible with prior %d points",
185d7b241e6Sjeremylt                        numqpoints, op->numqpoints);
186*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
187d7b241e6Sjeremylt     op->numqpoints = numqpoints;
188d7b241e6Sjeremylt   }
189d1bcdac9Sjeremylt   CeedOperatorField *ofield;
190d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numinputfields; i++) {
191fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) {
192d7b241e6Sjeremylt       ofield = &op->inputfields[i];
193d7b241e6Sjeremylt       goto found;
194d7b241e6Sjeremylt     }
195d7b241e6Sjeremylt   }
196d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numoutputfields; i++) {
197fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) {
198d7b241e6Sjeremylt       ofield = &op->outputfields[i];
199d7b241e6Sjeremylt       goto found;
200d7b241e6Sjeremylt     }
201d7b241e6Sjeremylt   }
202*c042f62fSJeremy L Thompson   // LCOV_EXCL_START
203d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
204d7b241e6Sjeremylt                    fieldname);
205*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
206d7b241e6Sjeremylt found:
207fe2413ffSjeremylt   ierr = CeedCalloc(1, ofield); CeedChk(ierr);
208fe2413ffSjeremylt   (*ofield)->Erestrict = r;
209fe2413ffSjeremylt   (*ofield)->lmode = lmode;
210fe2413ffSjeremylt   (*ofield)->basis = b;
211fe2413ffSjeremylt   (*ofield)->vec = v;
212d7b241e6Sjeremylt   op->nfields += 1;
213d7b241e6Sjeremylt   return 0;
214d7b241e6Sjeremylt }
215d7b241e6Sjeremylt 
216d7b241e6Sjeremylt /**
21752d6035fSJeremy L Thompson   @brief Add a sub-operator to a composite CeedOperator
218288c0443SJeremy L Thompson 
219288c0443SJeremy L Thompson   @param[out] compositeop Address of the composite CeedOperator
220288c0443SJeremy L Thompson   @param      subop       Address of the sub-operator CeedOperator
22152d6035fSJeremy L Thompson 
22252d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
22352d6035fSJeremy L Thompson 
22452d6035fSJeremy L Thompson   @ref Basic
22552d6035fSJeremy L Thompson  */
22652d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
22752d6035fSJeremy L Thompson                                 CeedOperator subop) {
22852d6035fSJeremy L Thompson   if (!compositeop->composite)
229*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
23052d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
23152d6035fSJeremy L Thompson                      "CeedOperator is not a composite operator");
232*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
23352d6035fSJeremy L Thompson 
23452d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
235*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
23652d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
23752d6035fSJeremy L Thompson                      "Cannot add additional suboperators");
238*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
23952d6035fSJeremy L Thompson 
24052d6035fSJeremy L Thompson   compositeop->suboperators[compositeop->numsub] = subop;
24152d6035fSJeremy L Thompson   subop->refcount++;
24252d6035fSJeremy L Thompson   compositeop->numsub++;
24352d6035fSJeremy L Thompson   return 0;
24452d6035fSJeremy L Thompson }
24552d6035fSJeremy L Thompson 
24652d6035fSJeremy L Thompson /**
247b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
248d7b241e6Sjeremylt 
249d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
250d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
251d7b241e6Sjeremylt   CeedOperatorSetField().
252d7b241e6Sjeremylt 
253d7b241e6Sjeremylt   @param op        CeedOperator to apply
254b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
255b11c1e72Sjeremylt                      active inputs
256b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
257d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
258d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
259d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
260b11c1e72Sjeremylt 
261b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
262dfdf5a53Sjeremylt 
263dfdf5a53Sjeremylt   @ref Basic
264b11c1e72Sjeremylt **/
265d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
266d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
267d7b241e6Sjeremylt   int ierr;
268d7b241e6Sjeremylt   Ceed ceed = op->ceed;
269d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
270d7b241e6Sjeremylt 
27152d6035fSJeremy L Thompson   if (op->composite) {
272*c042f62fSJeremy L Thompson     if (!op->numsub)
273*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
274*c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "No suboperators set");
275*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
27652d6035fSJeremy L Thompson   } else {
277*c042f62fSJeremy L Thompson     if (op->nfields == 0)
278*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
279*c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "No operator fields set");
280*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
281*c042f62fSJeremy L Thompson     if (op->nfields < qf->numinputfields + qf->numoutputfields)
282*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
283*c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "Not all operator fields set");
284*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
285*c042f62fSJeremy L Thompson     if (op->numelements == 0)
286*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
287*c042f62fSJeremy L Thompson       return CeedError(ceed, 1,"At least one restriction required");
288*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
289*c042f62fSJeremy L Thompson     if (op->numqpoints == 0)
290*c042f62fSJeremy L Thompson       // LCOV_EXCL_START
291*c042f62fSJeremy L Thompson       return CeedError(ceed, 1,"At least one non-collocated basis required");
292*c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
29352d6035fSJeremy L Thompson   }
294d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
295d7b241e6Sjeremylt   return 0;
296d7b241e6Sjeremylt }
297d7b241e6Sjeremylt 
298d7b241e6Sjeremylt /**
2994ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
3004ce2993fSjeremylt 
3014ce2993fSjeremylt   @param op              CeedOperator
3024ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
3034ce2993fSjeremylt 
3044ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3054ce2993fSjeremylt 
30623617272Sjeremylt   @ref Advanced
3074ce2993fSjeremylt **/
3084ce2993fSjeremylt 
3094ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
3104ce2993fSjeremylt   *ceed = op->ceed;
3114ce2993fSjeremylt   return 0;
3124ce2993fSjeremylt }
3134ce2993fSjeremylt 
3144ce2993fSjeremylt /**
3154ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
3164ce2993fSjeremylt 
3174ce2993fSjeremylt   @param op              CeedOperator
3184ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
3194ce2993fSjeremylt 
3204ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3214ce2993fSjeremylt 
32223617272Sjeremylt   @ref Advanced
3234ce2993fSjeremylt **/
3244ce2993fSjeremylt 
3254ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
32652d6035fSJeremy L Thompson   if (op->composite)
327*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
32852d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
329*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
33052d6035fSJeremy L Thompson 
3314ce2993fSjeremylt   *numelem = op->numelements;
3324ce2993fSjeremylt   return 0;
3334ce2993fSjeremylt }
3344ce2993fSjeremylt 
3354ce2993fSjeremylt /**
3364ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
3374ce2993fSjeremylt 
3384ce2993fSjeremylt   @param op              CeedOperator
3394ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
3404ce2993fSjeremylt 
3414ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3424ce2993fSjeremylt 
34323617272Sjeremylt   @ref Advanced
3444ce2993fSjeremylt **/
3454ce2993fSjeremylt 
3464ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
34752d6035fSJeremy L Thompson   if (op->composite)
348*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
34952d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
350*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
35152d6035fSJeremy L Thompson 
3524ce2993fSjeremylt   *numqpts = op->numqpoints;
3534ce2993fSjeremylt   return 0;
3544ce2993fSjeremylt }
3554ce2993fSjeremylt 
3564ce2993fSjeremylt /**
3574ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
3584ce2993fSjeremylt 
3594ce2993fSjeremylt   @param op              CeedOperator
3604ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
3614ce2993fSjeremylt 
3624ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3634ce2993fSjeremylt 
36423617272Sjeremylt   @ref Advanced
3654ce2993fSjeremylt **/
3664ce2993fSjeremylt 
3674ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
36852d6035fSJeremy L Thompson   if (op->composite)
369*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
37052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
371*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
372*c042f62fSJeremy L Thompson 
3734ce2993fSjeremylt   *numargs = op->nfields;
3744ce2993fSjeremylt   return 0;
3754ce2993fSjeremylt }
3764ce2993fSjeremylt 
3774ce2993fSjeremylt /**
3784ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
3794ce2993fSjeremylt 
3804ce2993fSjeremylt   @param op             CeedOperator
381288c0443SJeremy L Thompson   @param[out] setupdone Variable to store setup status
3824ce2993fSjeremylt 
3834ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3844ce2993fSjeremylt 
38523617272Sjeremylt   @ref Advanced
3864ce2993fSjeremylt **/
3874ce2993fSjeremylt 
3884ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
3894ce2993fSjeremylt   *setupdone = op->setupdone;
3904ce2993fSjeremylt   return 0;
3914ce2993fSjeremylt }
3924ce2993fSjeremylt 
3934ce2993fSjeremylt /**
3944ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
3954ce2993fSjeremylt 
3964ce2993fSjeremylt   @param op              CeedOperator
3978c91a0c9SJeremy L Thompson   @param[out] qf         Variable to store QFunction
3984ce2993fSjeremylt 
3994ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4004ce2993fSjeremylt 
40123617272Sjeremylt   @ref Advanced
4024ce2993fSjeremylt **/
4034ce2993fSjeremylt 
4044ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
40552d6035fSJeremy L Thompson   if (op->composite)
406*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
40752d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
408*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
40952d6035fSJeremy L Thompson 
4104ce2993fSjeremylt   *qf = op->qf;
4114ce2993fSjeremylt   return 0;
4124ce2993fSjeremylt }
4134ce2993fSjeremylt 
4144ce2993fSjeremylt /**
41552d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
41652d6035fSJeremy L Thompson 
41752d6035fSJeremy L Thompson   @param op              CeedOperator
41852d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
41952d6035fSJeremy L Thompson 
42052d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
42152d6035fSJeremy L Thompson 
42252d6035fSJeremy L Thompson   @ref Advanced
42352d6035fSJeremy L Thompson **/
42452d6035fSJeremy L Thompson 
42552d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
426*c042f62fSJeremy L Thompson   if (!op->composite)
427*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
428*c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not a composite operator");
429*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
43052d6035fSJeremy L Thompson 
43152d6035fSJeremy L Thompson   *numsub = op->numsub;
43252d6035fSJeremy L Thompson   return 0;
43352d6035fSJeremy L Thompson }
43452d6035fSJeremy L Thompson 
43552d6035fSJeremy L Thompson /**
43652d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
43752d6035fSJeremy L Thompson 
43852d6035fSJeremy L Thompson   @param op                CeedOperator
43952d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
44052d6035fSJeremy L Thompson 
44152d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
44252d6035fSJeremy L Thompson 
44352d6035fSJeremy L Thompson   @ref Advanced
44452d6035fSJeremy L Thompson **/
44552d6035fSJeremy L Thompson 
44652d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
447*c042f62fSJeremy L Thompson   if (!op->composite)
448*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
449*c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not a composite operator");
450*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
45152d6035fSJeremy L Thompson 
45252d6035fSJeremy L Thompson   *suboperators = op->suboperators;
45352d6035fSJeremy L Thompson   return 0;
45452d6035fSJeremy L Thompson }
45552d6035fSJeremy L Thompson 
45652d6035fSJeremy L Thompson /**
457fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
458fe2413ffSjeremylt 
459fe2413ffSjeremylt   @param[out] op         CeedOperator
460fe2413ffSjeremylt   @param data            Data to set
461fe2413ffSjeremylt 
462fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
463fe2413ffSjeremylt 
464fe2413ffSjeremylt   @ref Advanced
465fe2413ffSjeremylt **/
466fe2413ffSjeremylt 
467fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
468fe2413ffSjeremylt   op->data = *data;
469fe2413ffSjeremylt   return 0;
470fe2413ffSjeremylt }
471fe2413ffSjeremylt 
472fe2413ffSjeremylt /**
4734ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
4744ce2993fSjeremylt 
4754ce2993fSjeremylt   @param op              CeedOperator
4764ce2993fSjeremylt   @param[out] data       Variable to store data
4774ce2993fSjeremylt 
4784ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4794ce2993fSjeremylt 
48023617272Sjeremylt   @ref Advanced
4814ce2993fSjeremylt **/
4824ce2993fSjeremylt 
4834ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
4844ce2993fSjeremylt   *data = op->data;
4854ce2993fSjeremylt   return 0;
4864ce2993fSjeremylt }
4874ce2993fSjeremylt 
4884ce2993fSjeremylt /**
4894ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
4904ce2993fSjeremylt 
4914ce2993fSjeremylt   @param op              CeedOperator
4924ce2993fSjeremylt 
4934ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4944ce2993fSjeremylt 
49523617272Sjeremylt   @ref Advanced
4964ce2993fSjeremylt **/
4974ce2993fSjeremylt 
4984ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
4994ce2993fSjeremylt   op->setupdone = 1;
5004ce2993fSjeremylt   return 0;
5014ce2993fSjeremylt }
5024ce2993fSjeremylt 
5034ce2993fSjeremylt /**
504d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
505d1bcdac9Sjeremylt 
506d1bcdac9Sjeremylt   @param op                 CeedOperator
507d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
508d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
509d1bcdac9Sjeremylt 
510d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
511d1bcdac9Sjeremylt 
512d1bcdac9Sjeremylt   @ref Advanced
513d1bcdac9Sjeremylt **/
514d1bcdac9Sjeremylt 
515d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
516d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
517d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
51852d6035fSJeremy L Thompson   if (op->composite)
519*c042f62fSJeremy L Thompson     // LCOV_EXCL_START
52052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
521*c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
52252d6035fSJeremy L Thompson 
523d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
524d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
525d1bcdac9Sjeremylt   return 0;
526d1bcdac9Sjeremylt }
527d1bcdac9Sjeremylt 
528d1bcdac9Sjeremylt /**
5294dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
5304dccadb6Sjeremylt 
5314dccadb6Sjeremylt   @param opfield         CeedOperatorField
5324dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
5334dccadb6Sjeremylt 
5344dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
5354dccadb6Sjeremylt 
5364dccadb6Sjeremylt   @ref Advanced
5374dccadb6Sjeremylt **/
5384dccadb6Sjeremylt 
5394dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
5404dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
541fe2413ffSjeremylt   *lmode = opfield->lmode;
5424dccadb6Sjeremylt   return 0;
5434dccadb6Sjeremylt }/**
544d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
545d1bcdac9Sjeremylt 
546d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
547d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
548d1bcdac9Sjeremylt 
549d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
550d1bcdac9Sjeremylt 
551d1bcdac9Sjeremylt   @ref Advanced
552d1bcdac9Sjeremylt **/
553d1bcdac9Sjeremylt 
554d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
555d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
556fe2413ffSjeremylt   *rstr = opfield->Erestrict;
557d1bcdac9Sjeremylt   return 0;
558d1bcdac9Sjeremylt }
559d1bcdac9Sjeremylt 
560d1bcdac9Sjeremylt /**
561d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
562d1bcdac9Sjeremylt 
563d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
564d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
565d1bcdac9Sjeremylt 
566d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
567d1bcdac9Sjeremylt 
568d1bcdac9Sjeremylt   @ref Advanced
569d1bcdac9Sjeremylt **/
570d1bcdac9Sjeremylt 
571d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
572d1bcdac9Sjeremylt                               CeedBasis *basis) {
573fe2413ffSjeremylt   *basis = opfield->basis;
574d1bcdac9Sjeremylt   return 0;
575d1bcdac9Sjeremylt }
576d1bcdac9Sjeremylt 
577d1bcdac9Sjeremylt /**
578d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
579d1bcdac9Sjeremylt 
580d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
581d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
582d1bcdac9Sjeremylt 
583d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
584d1bcdac9Sjeremylt 
585d1bcdac9Sjeremylt   @ref Advanced
586d1bcdac9Sjeremylt **/
587d1bcdac9Sjeremylt 
588d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
589d1bcdac9Sjeremylt                                CeedVector *vec) {
590fe2413ffSjeremylt   *vec = opfield->vec;
591d1bcdac9Sjeremylt   return 0;
592d1bcdac9Sjeremylt }
593d1bcdac9Sjeremylt 
594d1bcdac9Sjeremylt /**
595b11c1e72Sjeremylt   @brief Destroy a CeedOperator
596d7b241e6Sjeremylt 
597d7b241e6Sjeremylt   @param op CeedOperator to destroy
598b11c1e72Sjeremylt 
599b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
600dfdf5a53Sjeremylt 
601dfdf5a53Sjeremylt   @ref Basic
602b11c1e72Sjeremylt **/
603d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
604d7b241e6Sjeremylt   int ierr;
605d7b241e6Sjeremylt 
606d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
607d7b241e6Sjeremylt   if ((*op)->Destroy) {
608d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
609d7b241e6Sjeremylt   }
610fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
611fe2413ffSjeremylt   // Free fields
612d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
61352d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
614fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
615fe2413ffSjeremylt     }
616d0eb30a5Sjeremylt   }
617d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
618d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
619fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
620fe2413ffSjeremylt     }
621d0eb30a5Sjeremylt   }
62252d6035fSJeremy L Thompson   // Destroy suboperators
62352d6035fSJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++) {
62452d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
62552d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
62652d6035fSJeremy L Thompson     }
62752d6035fSJeremy L Thompson   }
628d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
629d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
630d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
631fe2413ffSjeremylt 
632fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
633fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
63452d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
635d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
636d7b241e6Sjeremylt   return 0;
637d7b241e6Sjeremylt }
638d7b241e6Sjeremylt 
639d7b241e6Sjeremylt /// @}
640