xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-operator.c (revision 1d102b48beba01a4e67ef28409a80cc546ae2651)
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
97*1d102b48SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support "
98*1d102b48SJeremy L Thompson                        "CompositeOperatorCreate");
99c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
10052d6035fSJeremy L Thompson 
10152d6035fSJeremy L Thompson     ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr);
10252d6035fSJeremy L Thompson     return 0;
10352d6035fSJeremy L Thompson   }
10452d6035fSJeremy L Thompson 
10552d6035fSJeremy L Thompson   ierr = CeedCalloc(1,op); CeedChk(ierr);
10652d6035fSJeremy L Thompson   (*op)->ceed = ceed;
10752d6035fSJeremy L Thompson   ceed->refcount++;
10852d6035fSJeremy L Thompson   (*op)->composite = true;
10952d6035fSJeremy L Thompson   ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr);
11052d6035fSJeremy L Thompson   ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr);
11152d6035fSJeremy L Thompson   return 0;
11252d6035fSJeremy L Thompson }
11352d6035fSJeremy L Thompson 
11452d6035fSJeremy L Thompson /**
115b11c1e72Sjeremylt   @brief Provide a field to a CeedOperator for use by its CeedQFunction
116d7b241e6Sjeremylt 
117d7b241e6Sjeremylt   This function is used to specify both active and passive fields to a
118d7b241e6Sjeremylt   CeedOperator.  For passive fields, a vector @arg v must be provided.  Passive
119d7b241e6Sjeremylt   fields can inputs or outputs (updated in-place when operator is applied).
120d7b241e6Sjeremylt 
121d7b241e6Sjeremylt   Active fields must be specified using this function, but their data (in a
122d7b241e6Sjeremylt   CeedVector) is passed in CeedOperatorApply().  There can be at most one active
123d7b241e6Sjeremylt   input and at most one active output.
124d7b241e6Sjeremylt 
1258c91a0c9SJeremy L Thompson   @param op         CeedOperator on which to provide the field
1268795c945Sjeremylt   @param fieldname  Name of the field (to be matched with the name used by
1278795c945Sjeremylt                       CeedQFunction)
128b11c1e72Sjeremylt   @param r          CeedElemRestriction
129b0e29e78Sjeremylt   @param lmode      CeedTransposeMode which specifies the ordering of the
130b0e29e78Sjeremylt                       components of the l-vector used by this CeedOperatorField,
131b0e29e78Sjeremylt                       CEED_NOTRANSPOSE indicates the component is the
132b0e29e78Sjeremylt                       outermost index and CEED_TRANSPOSE indicates the component
133b0e29e78Sjeremylt                       is the innermost index in ordering of the l-vector
134783c99b3SValeria Barra   @param b          CeedBasis in which the field resides or CEED_BASIS_COLLOCATED
135b11c1e72Sjeremylt                       if collocated with quadrature points
136b11c1e72Sjeremylt   @param v          CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE
137b11c1e72Sjeremylt                       if field is active or CEED_VECTOR_NONE if using
1388c91a0c9SJeremy L Thompson                       CEED_EVAL_WEIGHT in the QFunction
139b11c1e72Sjeremylt 
140b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
141dfdf5a53Sjeremylt 
142dfdf5a53Sjeremylt   @ref Basic
143b11c1e72Sjeremylt **/
144d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname,
1454dccadb6Sjeremylt                          CeedElemRestriction r, CeedTransposeMode lmode,
1464dccadb6Sjeremylt                          CeedBasis b, CeedVector v) {
147d7b241e6Sjeremylt   int ierr;
14852d6035fSJeremy L Thompson   if (op->composite)
149c042f62fSJeremy L Thompson     // LCOV_EXCL_START
15052d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Cannot add field to composite operator.");
151c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1528b067b84SJed Brown   if (!r)
153c042f62fSJeremy L Thompson     // LCOV_EXCL_START
154c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1,
155c042f62fSJeremy L Thompson                      "ElemRestriction r for field \"%s\" must be non-NULL.",
156c042f62fSJeremy L Thompson                      fieldname);
157c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1588b067b84SJed Brown   if (!b)
159c042f62fSJeremy L Thompson     // LCOV_EXCL_START
160c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Basis b for field \"%s\" must be non-NULL.",
161c042f62fSJeremy L Thompson                      fieldname);
162c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
1638b067b84SJed Brown   if (!v)
164c042f62fSJeremy L Thompson     // LCOV_EXCL_START
165c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Vector v for field \"%s\" must be non-NULL.",
166c042f62fSJeremy L Thompson                      fieldname);
167c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
16852d6035fSJeremy L Thompson 
169d7b241e6Sjeremylt   CeedInt numelements;
170d7b241e6Sjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr);
171d7b241e6Sjeremylt   if (op->numelements && op->numelements != numelements)
172c042f62fSJeremy L Thompson     // LCOV_EXCL_START
173d7b241e6Sjeremylt     return CeedError(op->ceed, 1,
174*1d102b48SJeremy L Thompson                      "ElemRestriction with %d elements incompatible with prior "
175*1d102b48SJeremy L Thompson                      "%d elements", numelements, op->numelements);
176c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
177d7b241e6Sjeremylt   op->numelements = numelements;
178d7b241e6Sjeremylt 
179783c99b3SValeria Barra   if (b != CEED_BASIS_COLLOCATED) {
180d7b241e6Sjeremylt     CeedInt numqpoints;
181d7b241e6Sjeremylt     ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr);
182d7b241e6Sjeremylt     if (op->numqpoints && op->numqpoints != numqpoints)
183c042f62fSJeremy L Thompson       // LCOV_EXCL_START
184*1d102b48SJeremy L Thompson       return CeedError(op->ceed, 1, "Basis with %d quadrature points "
185*1d102b48SJeremy L Thompson                        "incompatible with prior %d points", numqpoints,
186*1d102b48SJeremy L Thompson                        op->numqpoints);
187c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
188d7b241e6Sjeremylt     op->numqpoints = numqpoints;
189d7b241e6Sjeremylt   }
190d1bcdac9Sjeremylt   CeedOperatorField *ofield;
191d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numinputfields; i++) {
192fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) {
193d7b241e6Sjeremylt       ofield = &op->inputfields[i];
194d7b241e6Sjeremylt       goto found;
195d7b241e6Sjeremylt     }
196d7b241e6Sjeremylt   }
197d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numoutputfields; i++) {
198fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) {
199d7b241e6Sjeremylt       ofield = &op->outputfields[i];
200d7b241e6Sjeremylt       goto found;
201d7b241e6Sjeremylt     }
202d7b241e6Sjeremylt   }
203c042f62fSJeremy L Thompson   // LCOV_EXCL_START
204d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
205d7b241e6Sjeremylt                    fieldname);
206c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
207d7b241e6Sjeremylt found:
208fe2413ffSjeremylt   ierr = CeedCalloc(1, ofield); CeedChk(ierr);
209fe2413ffSjeremylt   (*ofield)->Erestrict = r;
21071352a93Sjeremylt   r->refcount += 1;
211fe2413ffSjeremylt   (*ofield)->lmode = lmode;
212fe2413ffSjeremylt   (*ofield)->basis = b;
21371352a93Sjeremylt   if (b != CEED_BASIS_COLLOCATED)
21471352a93Sjeremylt     b->refcount += 1;
215fe2413ffSjeremylt   (*ofield)->vec = v;
21671352a93Sjeremylt   if (v != CEED_VECTOR_ACTIVE && v != CEED_VECTOR_NONE)
21771352a93Sjeremylt     v->refcount += 1;
218d7b241e6Sjeremylt   op->nfields += 1;
219d7b241e6Sjeremylt   return 0;
220d7b241e6Sjeremylt }
221d7b241e6Sjeremylt 
222d7b241e6Sjeremylt /**
22352d6035fSJeremy L Thompson   @brief Add a sub-operator to a composite CeedOperator
224288c0443SJeremy L Thompson 
225288c0443SJeremy L Thompson   @param[out] compositeop Address of the composite CeedOperator
226288c0443SJeremy L Thompson   @param      subop       Address of the sub-operator CeedOperator
22752d6035fSJeremy L Thompson 
22852d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
22952d6035fSJeremy L Thompson 
23052d6035fSJeremy L Thompson   @ref Basic
23152d6035fSJeremy L Thompson  */
23252d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
23352d6035fSJeremy L Thompson                                 CeedOperator subop) {
23452d6035fSJeremy L Thompson   if (!compositeop->composite)
235c042f62fSJeremy L Thompson     // LCOV_EXCL_START
236*1d102b48SJeremy L Thompson     return CeedError(compositeop->ceed, 1, "CeedOperator is not a composite "
237*1d102b48SJeremy L Thompson                      "operator");
238c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
23952d6035fSJeremy L Thompson 
24052d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
241c042f62fSJeremy L Thompson     // LCOV_EXCL_START
242*1d102b48SJeremy L Thompson     return CeedError(compositeop->ceed, 1, "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 /**
252*1d102b48SJeremy L Thompson   @brief Assemble a linear CeedQFunction associated with a CeedOperator
253*1d102b48SJeremy L Thompson 
254*1d102b48SJeremy L Thompson   This returns a CeedVector containing a matrix at each quadrature point
255*1d102b48SJeremy L Thompson     providing the action of the CeedQFunction associated with the CeedOperator.
256*1d102b48SJeremy L Thompson     The vector 'assembled' is of shape
257*1d102b48SJeremy L Thompson       [num_elements, num_input_fields, num_output_fields, num_quad_points]
258*1d102b48SJeremy L Thompson     and contains column-major matrices representing the action of the
259*1d102b48SJeremy L Thompson     CeedQFunction for a corresponding quadrature point on an element. Inputs and
260*1d102b48SJeremy L Thompson     outputs are in the order provided by the user when adding CeedOperator fields.
261*1d102b48SJeremy L Thompson     For example, a QFunction with inputs 'u' and 'gradu' and outputs 'gradv' and
262*1d102b48SJeremy L Thompson     'v', provided in that order, would result in an assembled QFunction that
263*1d102b48SJeremy L Thompson     consists of (1 + dim) x (dim + 1) matrices at each quadrature point acting
264*1d102b48SJeremy L Thompson     on the input [u, du_0, du_1] and producing the output [dv_0, dv_1, v].
265*1d102b48SJeremy L Thompson 
266*1d102b48SJeremy L Thompson   @param op             CeedOperator to assemble CeedQFunction
267*1d102b48SJeremy L Thompson   @param[out] assembled CeedVector to store assembled Ceed QFunction at
268*1d102b48SJeremy L Thompson                           quadrature points
269*1d102b48SJeremy L Thompson   @param[out] rstr      CeedElemRestriction for CeedVector containing assembled
270*1d102b48SJeremy L Thompson                           CeedQFunction
271*1d102b48SJeremy L Thompson   @param request        Address of CeedRequest for non-blocking completion, else
272*1d102b48SJeremy L Thompson                           CEED_REQUEST_IMMEDIATE
273*1d102b48SJeremy L Thompson 
274*1d102b48SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
275*1d102b48SJeremy L Thompson 
276*1d102b48SJeremy L Thompson   @ref Advanced
277*1d102b48SJeremy L Thompson **/
278*1d102b48SJeremy L Thompson int CeedOperatorAssembleLinearQFunction(CeedOperator op, CeedVector *assembled,
279*1d102b48SJeremy L Thompson     CeedElemRestriction *rstr, CeedRequest *request) {
280*1d102b48SJeremy L Thompson   int ierr;
281*1d102b48SJeremy L Thompson   Ceed ceed = op->ceed;
282*1d102b48SJeremy L Thompson   CeedQFunction qf = op->qf;
283*1d102b48SJeremy L Thompson 
284*1d102b48SJeremy L Thompson   if (op->composite) {
285*1d102b48SJeremy L Thompson     return CeedError(ceed, 1, "Cannot assemble QFunction for composite operator");
286*1d102b48SJeremy L Thompson   } else {
287*1d102b48SJeremy L Thompson     if (op->nfields == 0)
288*1d102b48SJeremy L Thompson       return CeedError(ceed, 1, "No operator fields set");
289*1d102b48SJeremy L Thompson     if (op->nfields < qf->numinputfields + qf->numoutputfields)
290*1d102b48SJeremy L Thompson       return CeedError( ceed, 1, "Not all operator fields set");
291*1d102b48SJeremy L Thompson     if (op->numelements == 0)
292*1d102b48SJeremy L Thompson       return CeedError(ceed, 1, "At least one restriction required");
293*1d102b48SJeremy L Thompson     if (op->numqpoints == 0)
294*1d102b48SJeremy L Thompson       return CeedError(ceed, 1, "At least one non-collocated basis required");
295*1d102b48SJeremy L Thompson   }
296*1d102b48SJeremy L Thompson   ierr = op->AssembleLinearQFunction(op, assembled, rstr, request);
297*1d102b48SJeremy L Thompson   CeedChk(ierr);
298*1d102b48SJeremy L Thompson   return 0;
299*1d102b48SJeremy L Thompson }
300*1d102b48SJeremy L Thompson 
301*1d102b48SJeremy L Thompson /**
302b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
303d7b241e6Sjeremylt 
304d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
305d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
306d7b241e6Sjeremylt   CeedOperatorSetField().
307d7b241e6Sjeremylt 
308d7b241e6Sjeremylt   @param op        CeedOperator to apply
309b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
310b11c1e72Sjeremylt                      active inputs
311b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
312d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
313d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
314d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
315b11c1e72Sjeremylt 
316b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
317dfdf5a53Sjeremylt 
318dfdf5a53Sjeremylt   @ref Basic
319b11c1e72Sjeremylt **/
320d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
321d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
322d7b241e6Sjeremylt   int ierr;
323d7b241e6Sjeremylt   Ceed ceed = op->ceed;
324d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
325d7b241e6Sjeremylt 
32652d6035fSJeremy L Thompson   if (op->composite) {
327c042f62fSJeremy L Thompson     if (!op->numsub)
328c042f62fSJeremy L Thompson       // LCOV_EXCL_START
329c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "No suboperators set");
330c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
33152d6035fSJeremy L Thompson   } else {
332c042f62fSJeremy L Thompson     if (op->nfields == 0)
333c042f62fSJeremy L Thompson       // LCOV_EXCL_START
334c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "No operator fields set");
335c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
336c042f62fSJeremy L Thompson     if (op->nfields < qf->numinputfields + qf->numoutputfields)
337c042f62fSJeremy L Thompson       // LCOV_EXCL_START
338c042f62fSJeremy L Thompson       return CeedError(ceed, 1, "Not all operator fields set");
339c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
340c042f62fSJeremy L Thompson     if (op->numelements == 0)
341c042f62fSJeremy L Thompson       // LCOV_EXCL_START
342c042f62fSJeremy L Thompson       return CeedError(ceed, 1,"At least one restriction required");
343c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
344c042f62fSJeremy L Thompson     if (op->numqpoints == 0)
345c042f62fSJeremy L Thompson       // LCOV_EXCL_START
346c042f62fSJeremy L Thompson       return CeedError(ceed, 1,"At least one non-collocated basis required");
347c042f62fSJeremy L Thompson     // LCOV_EXCL_STOP
34852d6035fSJeremy L Thompson   }
349d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
350d7b241e6Sjeremylt   return 0;
351d7b241e6Sjeremylt }
352d7b241e6Sjeremylt 
353d7b241e6Sjeremylt /**
3544ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
3554ce2993fSjeremylt 
3564ce2993fSjeremylt   @param op              CeedOperator
3574ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
3584ce2993fSjeremylt 
3594ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3604ce2993fSjeremylt 
36123617272Sjeremylt   @ref Advanced
3624ce2993fSjeremylt **/
3634ce2993fSjeremylt 
3644ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
3654ce2993fSjeremylt   *ceed = op->ceed;
3664ce2993fSjeremylt   return 0;
3674ce2993fSjeremylt }
3684ce2993fSjeremylt 
3694ce2993fSjeremylt /**
3704ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
3714ce2993fSjeremylt 
3724ce2993fSjeremylt   @param op              CeedOperator
3734ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
3744ce2993fSjeremylt 
3754ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3764ce2993fSjeremylt 
37723617272Sjeremylt   @ref Advanced
3784ce2993fSjeremylt **/
3794ce2993fSjeremylt 
3804ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
38152d6035fSJeremy L Thompson   if (op->composite)
382c042f62fSJeremy L Thompson     // LCOV_EXCL_START
38352d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
384c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
38552d6035fSJeremy L Thompson 
3864ce2993fSjeremylt   *numelem = op->numelements;
3874ce2993fSjeremylt   return 0;
3884ce2993fSjeremylt }
3894ce2993fSjeremylt 
3904ce2993fSjeremylt /**
3914ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
3924ce2993fSjeremylt 
3934ce2993fSjeremylt   @param op              CeedOperator
3944ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
3954ce2993fSjeremylt 
3964ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3974ce2993fSjeremylt 
39823617272Sjeremylt   @ref Advanced
3994ce2993fSjeremylt **/
4004ce2993fSjeremylt 
4014ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
40252d6035fSJeremy L Thompson   if (op->composite)
403c042f62fSJeremy L Thompson     // LCOV_EXCL_START
40452d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
405c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
40652d6035fSJeremy L Thompson 
4074ce2993fSjeremylt   *numqpts = op->numqpoints;
4084ce2993fSjeremylt   return 0;
4094ce2993fSjeremylt }
4104ce2993fSjeremylt 
4114ce2993fSjeremylt /**
4124ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
4134ce2993fSjeremylt 
4144ce2993fSjeremylt   @param op              CeedOperator
4154ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
4164ce2993fSjeremylt 
4174ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4184ce2993fSjeremylt 
41923617272Sjeremylt   @ref Advanced
4204ce2993fSjeremylt **/
4214ce2993fSjeremylt 
4224ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
42352d6035fSJeremy L Thompson   if (op->composite)
424c042f62fSJeremy L Thompson     // LCOV_EXCL_START
42552d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
426c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
427c042f62fSJeremy L Thompson 
4284ce2993fSjeremylt   *numargs = op->nfields;
4294ce2993fSjeremylt   return 0;
4304ce2993fSjeremylt }
4314ce2993fSjeremylt 
4324ce2993fSjeremylt /**
4334ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
4344ce2993fSjeremylt 
4354ce2993fSjeremylt   @param op             CeedOperator
436288c0443SJeremy L Thompson   @param[out] setupdone Variable to store setup status
4374ce2993fSjeremylt 
4384ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4394ce2993fSjeremylt 
44023617272Sjeremylt   @ref Advanced
4414ce2993fSjeremylt **/
4424ce2993fSjeremylt 
4434ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
4444ce2993fSjeremylt   *setupdone = op->setupdone;
4454ce2993fSjeremylt   return 0;
4464ce2993fSjeremylt }
4474ce2993fSjeremylt 
4484ce2993fSjeremylt /**
4494ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
4504ce2993fSjeremylt 
4514ce2993fSjeremylt   @param op              CeedOperator
4528c91a0c9SJeremy L Thompson   @param[out] qf         Variable to store QFunction
4534ce2993fSjeremylt 
4544ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4554ce2993fSjeremylt 
45623617272Sjeremylt   @ref Advanced
4574ce2993fSjeremylt **/
4584ce2993fSjeremylt 
4594ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
46052d6035fSJeremy L Thompson   if (op->composite)
461c042f62fSJeremy L Thompson     // LCOV_EXCL_START
46252d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
463c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
46452d6035fSJeremy L Thompson 
4654ce2993fSjeremylt   *qf = op->qf;
4664ce2993fSjeremylt   return 0;
4674ce2993fSjeremylt }
4684ce2993fSjeremylt 
4694ce2993fSjeremylt /**
47052d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
47152d6035fSJeremy L Thompson 
47252d6035fSJeremy L Thompson   @param op              CeedOperator
47352d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
47452d6035fSJeremy L Thompson 
47552d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
47652d6035fSJeremy L Thompson 
47752d6035fSJeremy L Thompson   @ref Advanced
47852d6035fSJeremy L Thompson **/
47952d6035fSJeremy L Thompson 
48052d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
481c042f62fSJeremy L Thompson   if (!op->composite)
482c042f62fSJeremy L Thompson     // LCOV_EXCL_START
483c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not a composite operator");
484c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
48552d6035fSJeremy L Thompson 
48652d6035fSJeremy L Thompson   *numsub = op->numsub;
48752d6035fSJeremy L Thompson   return 0;
48852d6035fSJeremy L Thompson }
48952d6035fSJeremy L Thompson 
49052d6035fSJeremy L Thompson /**
49152d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
49252d6035fSJeremy L Thompson 
49352d6035fSJeremy L Thompson   @param op                CeedOperator
49452d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
49552d6035fSJeremy L Thompson 
49652d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
49752d6035fSJeremy L Thompson 
49852d6035fSJeremy L Thompson   @ref Advanced
49952d6035fSJeremy L Thompson **/
50052d6035fSJeremy L Thompson 
50152d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
502c042f62fSJeremy L Thompson   if (!op->composite)
503c042f62fSJeremy L Thompson     // LCOV_EXCL_START
504c042f62fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not a composite operator");
505c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
50652d6035fSJeremy L Thompson 
50752d6035fSJeremy L Thompson   *suboperators = op->suboperators;
50852d6035fSJeremy L Thompson   return 0;
50952d6035fSJeremy L Thompson }
51052d6035fSJeremy L Thompson 
51152d6035fSJeremy L Thompson /**
512fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
513fe2413ffSjeremylt 
514fe2413ffSjeremylt   @param[out] op         CeedOperator
515fe2413ffSjeremylt   @param data            Data to set
516fe2413ffSjeremylt 
517fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
518fe2413ffSjeremylt 
519fe2413ffSjeremylt   @ref Advanced
520fe2413ffSjeremylt **/
521fe2413ffSjeremylt 
522fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
523fe2413ffSjeremylt   op->data = *data;
524fe2413ffSjeremylt   return 0;
525fe2413ffSjeremylt }
526fe2413ffSjeremylt 
527fe2413ffSjeremylt /**
5284ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
5294ce2993fSjeremylt 
5304ce2993fSjeremylt   @param op              CeedOperator
5314ce2993fSjeremylt   @param[out] data       Variable to store data
5324ce2993fSjeremylt 
5334ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5344ce2993fSjeremylt 
53523617272Sjeremylt   @ref Advanced
5364ce2993fSjeremylt **/
5374ce2993fSjeremylt 
5384ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
5394ce2993fSjeremylt   *data = op->data;
5404ce2993fSjeremylt   return 0;
5414ce2993fSjeremylt }
5424ce2993fSjeremylt 
5434ce2993fSjeremylt /**
5444ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
5454ce2993fSjeremylt 
5464ce2993fSjeremylt   @param op              CeedOperator
5474ce2993fSjeremylt 
5484ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
5494ce2993fSjeremylt 
55023617272Sjeremylt   @ref Advanced
5514ce2993fSjeremylt **/
5524ce2993fSjeremylt 
5534ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
5544ce2993fSjeremylt   op->setupdone = 1;
5554ce2993fSjeremylt   return 0;
5564ce2993fSjeremylt }
5574ce2993fSjeremylt 
5584ce2993fSjeremylt /**
559d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
560d1bcdac9Sjeremylt 
561d1bcdac9Sjeremylt   @param op                 CeedOperator
562d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
563d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
564d1bcdac9Sjeremylt 
565d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
566d1bcdac9Sjeremylt 
567d1bcdac9Sjeremylt   @ref Advanced
568d1bcdac9Sjeremylt **/
569d1bcdac9Sjeremylt 
570d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
571d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
572d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
57352d6035fSJeremy L Thompson   if (op->composite)
574c042f62fSJeremy L Thompson     // LCOV_EXCL_START
57552d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
576c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
57752d6035fSJeremy L Thompson 
578d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
579d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
580d1bcdac9Sjeremylt   return 0;
581d1bcdac9Sjeremylt }
582d1bcdac9Sjeremylt 
583d1bcdac9Sjeremylt /**
5844dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
5854dccadb6Sjeremylt 
5864dccadb6Sjeremylt   @param opfield         CeedOperatorField
5874dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
5884dccadb6Sjeremylt 
5894dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
5904dccadb6Sjeremylt 
5914dccadb6Sjeremylt   @ref Advanced
5924dccadb6Sjeremylt **/
5934dccadb6Sjeremylt 
5944dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
5954dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
596fe2413ffSjeremylt   *lmode = opfield->lmode;
5974dccadb6Sjeremylt   return 0;
5982b8e417aSjeremylt }
5992b8e417aSjeremylt 
6002b8e417aSjeremylt /**
601d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
602d1bcdac9Sjeremylt 
603d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
604d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
605d1bcdac9Sjeremylt 
606d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
607d1bcdac9Sjeremylt 
608d1bcdac9Sjeremylt   @ref Advanced
609d1bcdac9Sjeremylt **/
610d1bcdac9Sjeremylt 
611d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
612d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
613fe2413ffSjeremylt   *rstr = opfield->Erestrict;
614d1bcdac9Sjeremylt   return 0;
615d1bcdac9Sjeremylt }
616d1bcdac9Sjeremylt 
617d1bcdac9Sjeremylt /**
618d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
619d1bcdac9Sjeremylt 
620d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
621d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
622d1bcdac9Sjeremylt 
623d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
624d1bcdac9Sjeremylt 
625d1bcdac9Sjeremylt   @ref Advanced
626d1bcdac9Sjeremylt **/
627d1bcdac9Sjeremylt 
628d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
629d1bcdac9Sjeremylt                               CeedBasis *basis) {
630fe2413ffSjeremylt   *basis = opfield->basis;
631d1bcdac9Sjeremylt   return 0;
632d1bcdac9Sjeremylt }
633d1bcdac9Sjeremylt 
634d1bcdac9Sjeremylt /**
635d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
636d1bcdac9Sjeremylt 
637d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
638d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
639d1bcdac9Sjeremylt 
640d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
641d1bcdac9Sjeremylt 
642d1bcdac9Sjeremylt   @ref Advanced
643d1bcdac9Sjeremylt **/
644d1bcdac9Sjeremylt 
645d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
646d1bcdac9Sjeremylt                                CeedVector *vec) {
647fe2413ffSjeremylt   *vec = opfield->vec;
648d1bcdac9Sjeremylt   return 0;
649d1bcdac9Sjeremylt }
650d1bcdac9Sjeremylt 
651d1bcdac9Sjeremylt /**
652b11c1e72Sjeremylt   @brief Destroy a CeedOperator
653d7b241e6Sjeremylt 
654d7b241e6Sjeremylt   @param op CeedOperator to destroy
655b11c1e72Sjeremylt 
656b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
657dfdf5a53Sjeremylt 
658dfdf5a53Sjeremylt   @ref Basic
659b11c1e72Sjeremylt **/
660d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
661d7b241e6Sjeremylt   int ierr;
662d7b241e6Sjeremylt 
663d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
664d7b241e6Sjeremylt   if ((*op)->Destroy) {
665d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
666d7b241e6Sjeremylt   }
667fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
668fe2413ffSjeremylt   // Free fields
669*1d102b48SJeremy L Thompson   for (int i=0; i<(*op)->nfields; i++)
67052d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
67171352a93Sjeremylt       ierr = CeedElemRestrictionDestroy(&(*op)->inputfields[i]->Erestrict);
67271352a93Sjeremylt       CeedChk(ierr);
67371352a93Sjeremylt       if ((*op)->inputfields[i]->basis != CEED_BASIS_COLLOCATED) {
67471352a93Sjeremylt         ierr = CeedBasisDestroy(&(*op)->inputfields[i]->basis); CeedChk(ierr);
67571352a93Sjeremylt       }
67671352a93Sjeremylt       if ((*op)->inputfields[i]->vec != CEED_VECTOR_ACTIVE &&
67771352a93Sjeremylt           (*op)->inputfields[i]->vec != CEED_VECTOR_NONE ) {
67871352a93Sjeremylt         ierr = CeedVectorDestroy(&(*op)->inputfields[i]->vec); CeedChk(ierr);
67971352a93Sjeremylt       }
680fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
681fe2413ffSjeremylt     }
682*1d102b48SJeremy L Thompson   for (int i=0; i<(*op)->nfields; i++)
683d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
68471352a93Sjeremylt       ierr = CeedElemRestrictionDestroy(&(*op)->outputfields[i]->Erestrict);
68571352a93Sjeremylt       CeedChk(ierr);
68671352a93Sjeremylt       if ((*op)->outputfields[i]->basis != CEED_BASIS_COLLOCATED) {
68771352a93Sjeremylt         ierr = CeedBasisDestroy(&(*op)->outputfields[i]->basis); CeedChk(ierr);
68871352a93Sjeremylt       }
68971352a93Sjeremylt       if ((*op)->outputfields[i]->vec != CEED_VECTOR_ACTIVE &&
69071352a93Sjeremylt           (*op)->outputfields[i]->vec != CEED_VECTOR_NONE ) {
69171352a93Sjeremylt         ierr = CeedVectorDestroy(&(*op)->outputfields[i]->vec); CeedChk(ierr);
69271352a93Sjeremylt       }
693fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
694fe2413ffSjeremylt     }
69552d6035fSJeremy L Thompson   // Destroy suboperators
696*1d102b48SJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++)
69752d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
69852d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
69952d6035fSJeremy L Thompson     }
700d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
701d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
702d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
703fe2413ffSjeremylt 
704fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
705fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
70652d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
707d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
708d7b241e6Sjeremylt   return 0;
709d7b241e6Sjeremylt }
710d7b241e6Sjeremylt 
711d7b241e6Sjeremylt /// @}
712