xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-operator.c (revision 71352a93feb46d64460982869139c1c908591595)
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)
53c042f62fSJeremy L Thompson       // LCOV_EXCL_START
545fe0d4faSjeremylt       return CeedError(ceed, 1, "Backend does not support OperatorCreate");
55c042f62fSJeremy 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)
96c042f62fSJeremy L Thompson       // LCOV_EXCL_START
97c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support CompositeOperatorCreate");
98c042f62fSJeremy 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)
148c042f62fSJeremy L Thompson     // LCOV_EXCL_START
14952d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Cannot add field to composite operator.");
150c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1518b067b84SJed Brown   if (!r)
152c042f62fSJeremy L Thompson     // LCOV_EXCL_START
153c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1,
154c042f62fSJeremy L Thompson                      "ElemRestriction r for field \"%s\" must be non-NULL.",
155c042f62fSJeremy L Thompson                      fieldname);
156c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1578b067b84SJed Brown   if (!b)
158c042f62fSJeremy L Thompson     // LCOV_EXCL_START
159c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.",
160c042f62fSJeremy L Thompson                      fieldname);
161c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1628b067b84SJed Brown   if (!v)
163c042f62fSJeremy L Thompson     // LCOV_EXCL_START
164c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.",
165c042f62fSJeremy L Thompson                      fieldname);
166c042f62fSJeremy 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)
171c042f62fSJeremy 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);
175c042f62fSJeremy 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)
182c042f62fSJeremy 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);
186c042f62fSJeremy 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   }
202c042f62fSJeremy L Thompson   // LCOV_EXCL_START
203d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
204d7b241e6Sjeremylt                    fieldname);
205c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
206d7b241e6Sjeremylt found:
207fe2413ffSjeremylt   ierr = CeedCalloc(1, ofield); CeedChk(ierr);
208fe2413ffSjeremylt   (*ofield)->Erestrict = r;
209*71352a93Sjeremylt   r->refcount += 1;
210fe2413ffSjeremylt   (*ofield)->lmode = lmode;
211fe2413ffSjeremylt   (*ofield)->basis = b;
212*71352a93Sjeremylt   if (b != CEED_BASIS_COLLOCATED)
213*71352a93Sjeremylt     b->refcount += 1;
214fe2413ffSjeremylt   (*ofield)->vec = v;
215*71352a93Sjeremylt   if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE)
216*71352a93Sjeremylt     v->refcount += 1;
217d7b241e6Sjeremylt   op->nfields += 1;
218d7b241e6Sjeremylt   return 0;
219d7b241e6Sjeremylt }
220d7b241e6Sjeremylt 
221d7b241e6Sjeremylt /**
22252d6035fSJeremy L Thompson   @brief Add a sub-operator to a composite CeedOperator
223288c0443SJeremy L Thompson 
224288c0443SJeremy L Thompson   @param[out] compositeop Address of the composite CeedOperator
225288c0443SJeremy L Thompson   @param      subop       Address of the sub-operator CeedOperator
22652d6035fSJeremy L Thompson 
22752d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
22852d6035fSJeremy L Thompson 
22952d6035fSJeremy L Thompson   @ref Basic
23052d6035fSJeremy L Thompson  */
23152d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
23252d6035fSJeremy L Thompson                                 CeedOperator subop) {
23352d6035fSJeremy L Thompson   if (!compositeop->composite)
234c042f62fSJeremy L Thompson     // LCOV_EXCL_START
23552d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
23652d6035fSJeremy L Thompson                      "CeedOperator is not a composite operator");
237c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
23852d6035fSJeremy L Thompson 
23952d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
240c042f62fSJeremy L Thompson     // LCOV_EXCL_START
24152d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
24252d6035fSJeremy L Thompson                      "Cannot add additional suboperators");
243c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
24452d6035fSJeremy L Thompson 
24552d6035fSJeremy L Thompson   compositeop->suboperators[compositeop->numsub] = subop;
24652d6035fSJeremy L Thompson   subop->refcount++;
24752d6035fSJeremy L Thompson   compositeop->numsub++;
24852d6035fSJeremy L Thompson   return 0;
24952d6035fSJeremy L Thompson }
25052d6035fSJeremy L Thompson 
25152d6035fSJeremy L Thompson /**
252b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
253d7b241e6Sjeremylt 
254d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
255d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
256d7b241e6Sjeremylt   CeedOperatorSetField().
257d7b241e6Sjeremylt 
258d7b241e6Sjeremylt   @param op        CeedOperator to apply
259b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
260b11c1e72Sjeremylt                      active inputs
261b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
262d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
263d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
264d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
265b11c1e72Sjeremylt 
266b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
267dfdf5a53Sjeremylt 
268dfdf5a53Sjeremylt   @ref Basic
269b11c1e72Sjeremylt **/
270d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
271d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
272d7b241e6Sjeremylt   int ierr;
273d7b241e6Sjeremylt   Ceed ceed = op->ceed;
274d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
275d7b241e6Sjeremylt 
27652d6035fSJeremy L Thompson   if (op->composite) {
277c042f62fSJeremy L Thompson     if (!op->numsub)
278c042f62fSJeremy L Thompson       // LCOV_EXCL_START
279c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "No suboperators set");
280c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
28152d6035fSJeremy L Thompson   } else {
282c042f62fSJeremy L Thompson     if (op->nfields == 0)
283c042f62fSJeremy L Thompson       // LCOV_EXCL_START
284c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "No operator fields set");
285c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
286c042f62fSJeremy L Thompson     if (op->nfields < qf->numinputfields + qf->numoutputfields)
287c042f62fSJeremy L Thompson       // LCOV_EXCL_START
288c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "Not all operator fields set");
289c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
290c042f62fSJeremy L Thompson     if (op->numelements == 0)
291c042f62fSJeremy L Thompson       // LCOV_EXCL_START
292c042f62fSJeremy L Thompson       return CeedError(ceed, 1,"At least one restriction required");
293c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
294c042f62fSJeremy L Thompson     if (op->numqpoints == 0)
295c042f62fSJeremy L Thompson       // LCOV_EXCL_START
296c042f62fSJeremy L Thompson       return CeedError(ceed, 1,"At least one non-collocated basis required");
297c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
29852d6035fSJeremy L Thompson   }
299d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
300d7b241e6Sjeremylt   return 0;
301d7b241e6Sjeremylt }
302d7b241e6Sjeremylt 
303d7b241e6Sjeremylt /**
3044ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
3054ce2993fSjeremylt 
3064ce2993fSjeremylt   @param op              CeedOperator
3074ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
3084ce2993fSjeremylt 
3094ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3104ce2993fSjeremylt 
31123617272Sjeremylt   @ref Advanced
3124ce2993fSjeremylt **/
3134ce2993fSjeremylt 
3144ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
3154ce2993fSjeremylt   *ceed = op->ceed;
3164ce2993fSjeremylt   return 0;
3174ce2993fSjeremylt }
3184ce2993fSjeremylt 
3194ce2993fSjeremylt /**
3204ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
3214ce2993fSjeremylt 
3224ce2993fSjeremylt   @param op              CeedOperator
3234ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
3244ce2993fSjeremylt 
3254ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3264ce2993fSjeremylt 
32723617272Sjeremylt   @ref Advanced
3284ce2993fSjeremylt **/
3294ce2993fSjeremylt 
3304ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
33152d6035fSJeremy L Thompson   if (op->composite)
332c042f62fSJeremy L Thompson     // LCOV_EXCL_START
33352d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
334c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
33552d6035fSJeremy L Thompson 
3364ce2993fSjeremylt   *numelem = op->numelements;
3374ce2993fSjeremylt   return 0;
3384ce2993fSjeremylt }
3394ce2993fSjeremylt 
3404ce2993fSjeremylt /**
3414ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
3424ce2993fSjeremylt 
3434ce2993fSjeremylt   @param op              CeedOperator
3444ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
3454ce2993fSjeremylt 
3464ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3474ce2993fSjeremylt 
34823617272Sjeremylt   @ref Advanced
3494ce2993fSjeremylt **/
3504ce2993fSjeremylt 
3514ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
35252d6035fSJeremy L Thompson   if (op->composite)
353c042f62fSJeremy L Thompson     // LCOV_EXCL_START
35452d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
355c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
35652d6035fSJeremy L Thompson 
3574ce2993fSjeremylt   *numqpts = op->numqpoints;
3584ce2993fSjeremylt   return 0;
3594ce2993fSjeremylt }
3604ce2993fSjeremylt 
3614ce2993fSjeremylt /**
3624ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
3634ce2993fSjeremylt 
3644ce2993fSjeremylt   @param op              CeedOperator
3654ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
3664ce2993fSjeremylt 
3674ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3684ce2993fSjeremylt 
36923617272Sjeremylt   @ref Advanced
3704ce2993fSjeremylt **/
3714ce2993fSjeremylt 
3724ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
37352d6035fSJeremy L Thompson   if (op->composite)
374c042f62fSJeremy L Thompson     // LCOV_EXCL_START
37552d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
376c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
377c042f62fSJeremy L Thompson 
3784ce2993fSjeremylt   *numargs = op->nfields;
3794ce2993fSjeremylt   return 0;
3804ce2993fSjeremylt }
3814ce2993fSjeremylt 
3824ce2993fSjeremylt /**
3834ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
3844ce2993fSjeremylt 
3854ce2993fSjeremylt   @param op             CeedOperator
386288c0443SJeremy L Thompson   @param[out] setupdone Variable to store setup status
3874ce2993fSjeremylt 
3884ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3894ce2993fSjeremylt 
39023617272Sjeremylt   @ref Advanced
3914ce2993fSjeremylt **/
3924ce2993fSjeremylt 
3934ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
3944ce2993fSjeremylt   *setupdone = op->setupdone;
3954ce2993fSjeremylt   return 0;
3964ce2993fSjeremylt }
3974ce2993fSjeremylt 
3984ce2993fSjeremylt /**
3994ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
4004ce2993fSjeremylt 
4014ce2993fSjeremylt   @param op              CeedOperator
4028c91a0c9SJeremy L Thompson   @param[out] qf         Variable to store QFunction
4034ce2993fSjeremylt 
4044ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4054ce2993fSjeremylt 
40623617272Sjeremylt   @ref Advanced
4074ce2993fSjeremylt **/
4084ce2993fSjeremylt 
4094ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
41052d6035fSJeremy L Thompson   if (op->composite)
411c042f62fSJeremy L Thompson     // LCOV_EXCL_START
41252d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
413c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
41452d6035fSJeremy L Thompson 
4154ce2993fSjeremylt   *qf = op->qf;
4164ce2993fSjeremylt   return 0;
4174ce2993fSjeremylt }
4184ce2993fSjeremylt 
4194ce2993fSjeremylt /**
42052d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
42152d6035fSJeremy L Thompson 
42252d6035fSJeremy L Thompson   @param op              CeedOperator
42352d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
42452d6035fSJeremy L Thompson 
42552d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
42652d6035fSJeremy L Thompson 
42752d6035fSJeremy L Thompson   @ref Advanced
42852d6035fSJeremy L Thompson **/
42952d6035fSJeremy L Thompson 
43052d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
431c042f62fSJeremy L Thompson   if (!op->composite)
432c042f62fSJeremy L Thompson     // LCOV_EXCL_START
433c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not a composite operator");
434c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
43552d6035fSJeremy L Thompson 
43652d6035fSJeremy L Thompson   *numsub = op->numsub;
43752d6035fSJeremy L Thompson   return 0;
43852d6035fSJeremy L Thompson }
43952d6035fSJeremy L Thompson 
44052d6035fSJeremy L Thompson /**
44152d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
44252d6035fSJeremy L Thompson 
44352d6035fSJeremy L Thompson   @param op                CeedOperator
44452d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
44552d6035fSJeremy L Thompson 
44652d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
44752d6035fSJeremy L Thompson 
44852d6035fSJeremy L Thompson   @ref Advanced
44952d6035fSJeremy L Thompson **/
45052d6035fSJeremy L Thompson 
45152d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
452c042f62fSJeremy L Thompson   if (!op->composite)
453c042f62fSJeremy L Thompson     // LCOV_EXCL_START
454c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not a composite operator");
455c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
45652d6035fSJeremy L Thompson 
45752d6035fSJeremy L Thompson   *suboperators = op->suboperators;
45852d6035fSJeremy L Thompson   return 0;
45952d6035fSJeremy L Thompson }
46052d6035fSJeremy L Thompson 
46152d6035fSJeremy L Thompson /**
462fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
463fe2413ffSjeremylt 
464fe2413ffSjeremylt   @param[out] op         CeedOperator
465fe2413ffSjeremylt   @param data            Data to set
466fe2413ffSjeremylt 
467fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
468fe2413ffSjeremylt 
469fe2413ffSjeremylt   @ref Advanced
470fe2413ffSjeremylt **/
471fe2413ffSjeremylt 
472fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
473fe2413ffSjeremylt   op->data = *data;
474fe2413ffSjeremylt   return 0;
475fe2413ffSjeremylt }
476fe2413ffSjeremylt 
477fe2413ffSjeremylt /**
4784ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
4794ce2993fSjeremylt 
4804ce2993fSjeremylt   @param op              CeedOperator
4814ce2993fSjeremylt   @param[out] data       Variable to store data
4824ce2993fSjeremylt 
4834ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4844ce2993fSjeremylt 
48523617272Sjeremylt   @ref Advanced
4864ce2993fSjeremylt **/
4874ce2993fSjeremylt 
4884ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
4894ce2993fSjeremylt   *data = op->data;
4904ce2993fSjeremylt   return 0;
4914ce2993fSjeremylt }
4924ce2993fSjeremylt 
4934ce2993fSjeremylt /**
4944ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
4954ce2993fSjeremylt 
4964ce2993fSjeremylt   @param op              CeedOperator
4974ce2993fSjeremylt 
4984ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4994ce2993fSjeremylt 
50023617272Sjeremylt   @ref Advanced
5014ce2993fSjeremylt **/
5024ce2993fSjeremylt 
5034ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
5044ce2993fSjeremylt   op->setupdone = 1;
5054ce2993fSjeremylt   return 0;
5064ce2993fSjeremylt }
5074ce2993fSjeremylt 
5084ce2993fSjeremylt /**
509d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
510d1bcdac9Sjeremylt 
511d1bcdac9Sjeremylt   @param op                 CeedOperator
512d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
513d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
514d1bcdac9Sjeremylt 
515d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
516d1bcdac9Sjeremylt 
517d1bcdac9Sjeremylt   @ref Advanced
518d1bcdac9Sjeremylt **/
519d1bcdac9Sjeremylt 
520d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
521d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
522d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
52352d6035fSJeremy L Thompson   if (op->composite)
524c042f62fSJeremy L Thompson     // LCOV_EXCL_START
52552d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
526c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
52752d6035fSJeremy L Thompson 
528d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
529d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
530d1bcdac9Sjeremylt   return 0;
531d1bcdac9Sjeremylt }
532d1bcdac9Sjeremylt 
533d1bcdac9Sjeremylt /**
5344dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
5354dccadb6Sjeremylt 
5364dccadb6Sjeremylt   @param opfield         CeedOperatorField
5374dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
5384dccadb6Sjeremylt 
5394dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
5404dccadb6Sjeremylt 
5414dccadb6Sjeremylt   @ref Advanced
5424dccadb6Sjeremylt **/
5434dccadb6Sjeremylt 
5444dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
5454dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
546fe2413ffSjeremylt   *lmode = opfield->lmode;
5474dccadb6Sjeremylt   return 0;
5482b8e417aSjeremylt }
5492b8e417aSjeremylt 
5502b8e417aSjeremylt /**
551d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
552d1bcdac9Sjeremylt 
553d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
554d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
555d1bcdac9Sjeremylt 
556d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
557d1bcdac9Sjeremylt 
558d1bcdac9Sjeremylt   @ref Advanced
559d1bcdac9Sjeremylt **/
560d1bcdac9Sjeremylt 
561d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
562d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
563fe2413ffSjeremylt   *rstr = opfield->Erestrict;
564d1bcdac9Sjeremylt   return 0;
565d1bcdac9Sjeremylt }
566d1bcdac9Sjeremylt 
567d1bcdac9Sjeremylt /**
568d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
569d1bcdac9Sjeremylt 
570d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
571d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
572d1bcdac9Sjeremylt 
573d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
574d1bcdac9Sjeremylt 
575d1bcdac9Sjeremylt   @ref Advanced
576d1bcdac9Sjeremylt **/
577d1bcdac9Sjeremylt 
578d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
579d1bcdac9Sjeremylt                               CeedBasis *basis) {
580fe2413ffSjeremylt   *basis = opfield->basis;
581d1bcdac9Sjeremylt   return 0;
582d1bcdac9Sjeremylt }
583d1bcdac9Sjeremylt 
584d1bcdac9Sjeremylt /**
585d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
586d1bcdac9Sjeremylt 
587d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
588d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
589d1bcdac9Sjeremylt 
590d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
591d1bcdac9Sjeremylt 
592d1bcdac9Sjeremylt   @ref Advanced
593d1bcdac9Sjeremylt **/
594d1bcdac9Sjeremylt 
595d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
596d1bcdac9Sjeremylt                                CeedVector *vec) {
597fe2413ffSjeremylt   *vec = opfield->vec;
598d1bcdac9Sjeremylt   return 0;
599d1bcdac9Sjeremylt }
600d1bcdac9Sjeremylt 
601d1bcdac9Sjeremylt /**
602b11c1e72Sjeremylt   @brief Destroy a CeedOperator
603d7b241e6Sjeremylt 
604d7b241e6Sjeremylt   @param op CeedOperator to destroy
605b11c1e72Sjeremylt 
606b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
607dfdf5a53Sjeremylt 
608dfdf5a53Sjeremylt   @ref Basic
609b11c1e72Sjeremylt **/
610d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
611d7b241e6Sjeremylt   int ierr;
612d7b241e6Sjeremylt 
613d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
614d7b241e6Sjeremylt   if ((*op)->Destroy) {
615d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
616d7b241e6Sjeremylt   }
617fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
618fe2413ffSjeremylt   // Free fields
619d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
62052d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
621*71352a93Sjeremylt       ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict);
622*71352a93Sjeremylt       CeedChk(ierr);
623*71352a93Sjeremylt       if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) {
624*71352a93Sjeremylt         ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr);
625*71352a93Sjeremylt       }
626*71352a93Sjeremylt       if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE &&
627*71352a93Sjeremylt           (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) {
628*71352a93Sjeremylt         ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr);
629*71352a93Sjeremylt       }
630fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
631fe2413ffSjeremylt     }
632d0eb30a5Sjeremylt   }
633d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
634d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
635*71352a93Sjeremylt       ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict);
636*71352a93Sjeremylt       CeedChk(ierr);
637*71352a93Sjeremylt       if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) {
638*71352a93Sjeremylt         ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr);
639*71352a93Sjeremylt       }
640*71352a93Sjeremylt       if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE &&
641*71352a93Sjeremylt           (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) {
642*71352a93Sjeremylt         ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr);
643*71352a93Sjeremylt       }
644fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
645fe2413ffSjeremylt     }
646d0eb30a5Sjeremylt   }
64752d6035fSJeremy L Thompson   // Destroy suboperators
64852d6035fSJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++) {
64952d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
65052d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
65152d6035fSJeremy L Thompson     }
65252d6035fSJeremy L Thompson   }
653d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
654d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
655d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
656fe2413ffSjeremylt 
657fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
658fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
65952d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
660d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
661d7b241e6Sjeremylt   return 0;
662d7b241e6Sjeremylt }
663d7b241e6Sjeremylt 
664d7b241e6Sjeremylt /// @}
665