xref: /libCEED/interface/ceed-operator.c (revision 52d6035f927efec34920a771ebaa7a03e4ffa966)
1d7b241e6Sjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2d7b241e6Sjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3d7b241e6Sjeremylt // reserved. See files LICENSE and NOTICE for details.
4d7b241e6Sjeremylt //
5d7b241e6Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
6d7b241e6Sjeremylt // libraries and APIs for efficient high-order finite element and spectral
7d7b241e6Sjeremylt // element discretizations for exascale applications. For more information and
8d7b241e6Sjeremylt // source code availability see http://github.com/ceed.
9d7b241e6Sjeremylt //
10d7b241e6Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11d7b241e6Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
12d7b241e6Sjeremylt // of Science and the National Nuclear Security Administration) responsible for
13d7b241e6Sjeremylt // the planning and preparation of a capable exascale ecosystem, including
14d7b241e6Sjeremylt // software, applications, hardware, advanced system engineering and early
15d7b241e6Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
16d7b241e6Sjeremylt 
17d7b241e6Sjeremylt #include <ceed-impl.h>
18d863ab9bSjeremylt #include <ceed-backend.h>
19d7b241e6Sjeremylt #include <string.h>
20d7b241e6Sjeremylt 
21dfdf5a53Sjeremylt /// @file
22dfdf5a53Sjeremylt /// Implementation of public CeedOperator interfaces
23dfdf5a53Sjeremylt ///
24dfdf5a53Sjeremylt /// @addtogroup CeedOperator
25dfdf5a53Sjeremylt ///   @{
26d7b241e6Sjeremylt 
27d7b241e6Sjeremylt /**
28b11c1e72Sjeremylt   @brief Create an operator from element restriction, basis, and QFunction
29d7b241e6Sjeremylt 
30b11c1e72Sjeremylt   @param ceed    A Ceed object where the CeedOperator will be created
31d7b241e6Sjeremylt   @param qf      QFunction defining the action of the operator at quadrature points
32d7b241e6Sjeremylt   @param dqf     QFunction defining the action of the Jacobian of @a qf (or NULL)
33d7b241e6Sjeremylt   @param dqfT    QFunction defining the action of the transpose of the Jacobian
34d7b241e6Sjeremylt                    of @a qf (or NULL)
35b11c1e72Sjeremylt   @param[out] op Address of the variable where the newly created
36b11c1e72Sjeremylt                      CeedOperator will be stored
37b11c1e72Sjeremylt 
38b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
39dfdf5a53Sjeremylt 
40dfdf5a53Sjeremylt   @ref Basic
41d7b241e6Sjeremylt  */
42d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf,
43d7b241e6Sjeremylt                        CeedQFunction dqfT, CeedOperator *op) {
44d7b241e6Sjeremylt   int ierr;
45d7b241e6Sjeremylt 
465fe0d4faSjeremylt   if (!ceed->OperatorCreate) {
475fe0d4faSjeremylt     Ceed delegate;
485fe0d4faSjeremylt     ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr);
495fe0d4faSjeremylt 
505fe0d4faSjeremylt     if (!delegate)
515fe0d4faSjeremylt       return CeedError(ceed, 1, "Backend does not support OperatorCreate");
525fe0d4faSjeremylt 
535fe0d4faSjeremylt     ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr);
545fe0d4faSjeremylt     return 0;
555fe0d4faSjeremylt   }
565fe0d4faSjeremylt 
57d7b241e6Sjeremylt   ierr = CeedCalloc(1,op); CeedChk(ierr);
58d7b241e6Sjeremylt   (*op)->ceed = ceed;
59d7b241e6Sjeremylt   ceed->refcount++;
60d7b241e6Sjeremylt   (*op)->refcount = 1;
61d7b241e6Sjeremylt   (*op)->qf = qf;
62d7b241e6Sjeremylt   qf->refcount++;
63d7b241e6Sjeremylt   (*op)->dqf = dqf;
64d7b241e6Sjeremylt   if (dqf) dqf->refcount++;
65d7b241e6Sjeremylt   (*op)->dqfT = dqfT;
66d7b241e6Sjeremylt   if (dqfT) dqfT->refcount++;
67fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->inputfields); CeedChk(ierr);
68fe2413ffSjeremylt   ierr = CeedCalloc(16, &(*op)->outputfields); CeedChk(ierr);
69d7b241e6Sjeremylt   ierr = ceed->OperatorCreate(*op); CeedChk(ierr);
70d7b241e6Sjeremylt   return 0;
71d7b241e6Sjeremylt }
72d7b241e6Sjeremylt 
73d7b241e6Sjeremylt /**
74*52d6035fSJeremy L Thompson   @brief Create an operator that composes the action of several operators
75*52d6035fSJeremy L Thompson 
76*52d6035fSJeremy L Thompson   @param ceed    A Ceed object where the CeedOperator will be created
77*52d6035fSJeremy L Thompson   @param[out] op Address of the variable where the newly created
78*52d6035fSJeremy L Thompson                      Composite CeedOperator will be stored
79*52d6035fSJeremy L Thompson 
80*52d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
81*52d6035fSJeremy L Thompson 
82*52d6035fSJeremy L Thompson   @ref Basic
83*52d6035fSJeremy L Thompson  */
84*52d6035fSJeremy L Thompson int CeedCompositeOperatorCreate(Ceed ceed, CeedOperator *op) {
85*52d6035fSJeremy L Thompson   int ierr;
86*52d6035fSJeremy L Thompson 
87*52d6035fSJeremy L Thompson   if (!ceed->CompositeOperatorCreate) {
88*52d6035fSJeremy L Thompson     Ceed delegate;
89*52d6035fSJeremy L Thompson     ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr);
90*52d6035fSJeremy L Thompson 
91*52d6035fSJeremy L Thompson     if (!delegate)
92*52d6035fSJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support \
93*52d6035fSJeremy L Thompson                                    CompositeOperatorCreate");
94*52d6035fSJeremy L Thompson 
95*52d6035fSJeremy L Thompson     ierr = CeedCompositeOperatorCreate(delegate, op); CeedChk(ierr);
96*52d6035fSJeremy L Thompson     return 0;
97*52d6035fSJeremy L Thompson   }
98*52d6035fSJeremy L Thompson 
99*52d6035fSJeremy L Thompson   ierr = CeedCalloc(1,op); CeedChk(ierr);
100*52d6035fSJeremy L Thompson   (*op)->ceed = ceed;
101*52d6035fSJeremy L Thompson   ceed->refcount++;
102*52d6035fSJeremy L Thompson   (*op)->composite = true;
103*52d6035fSJeremy L Thompson   ierr = CeedCalloc(16, &(*op)->suboperators); CeedChk(ierr);
104*52d6035fSJeremy L Thompson   ierr = ceed->CompositeOperatorCreate(*op); CeedChk(ierr);
105*52d6035fSJeremy L Thompson   return 0;
106*52d6035fSJeremy L Thompson }
107*52d6035fSJeremy L Thompson 
108*52d6035fSJeremy L Thompson /**
109b11c1e72Sjeremylt   @brief Provide a field to a CeedOperator for use by its CeedQFunction
110d7b241e6Sjeremylt 
111d7b241e6Sjeremylt   This function is used to specify both active and passive fields to a
112d7b241e6Sjeremylt   CeedOperator.  For passive fields, a vector @arg v must be provided.  Passive
113d7b241e6Sjeremylt   fields can inputs or outputs (updated in-place when operator is applied).
114d7b241e6Sjeremylt 
115d7b241e6Sjeremylt   Active fields must be specified using this function, but their data (in a
116d7b241e6Sjeremylt   CeedVector) is passed in CeedOperatorApply().  There can be at most one active
117d7b241e6Sjeremylt   input and at most one active output.
118d7b241e6Sjeremylt 
119b11c1e72Sjeremylt   @param op         Ceedoperator on which to provide the field
120b11c1e72Sjeremylt   @param fieldname  Name of the field (to be matched with the name used by CeedQFunction)
121b11c1e72Sjeremylt   @param r          CeedElemRestriction
122b0e29e78Sjeremylt   @param lmode      CeedTransposeMode which specifies the ordering of the
123b0e29e78Sjeremylt                       components of the l-vector used by this CeedOperatorField,
124b0e29e78Sjeremylt                       CEED_NOTRANSPOSE indicates the component is the
125b0e29e78Sjeremylt                       outermost index and CEED_TRANSPOSE indicates the component
126b0e29e78Sjeremylt                       is the innermost index in ordering of the l-vector
127783c99b3SValeria Barra   @param b          CeedBasis in which the field resides or CEED_BASIS_COLLOCATED
128b11c1e72Sjeremylt                       if collocated with quadrature points
129b11c1e72Sjeremylt   @param v          CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE
130b11c1e72Sjeremylt                       if field is active or CEED_VECTOR_NONE if using
131b11c1e72Sjeremylt                       CEED_EVAL_WEIGHT in the qfunction
132b11c1e72Sjeremylt 
133b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
134dfdf5a53Sjeremylt 
135dfdf5a53Sjeremylt   @ref Basic
136b11c1e72Sjeremylt **/
137d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname,
1384dccadb6Sjeremylt                          CeedElemRestriction r, CeedTransposeMode lmode,
1394dccadb6Sjeremylt                          CeedBasis b, CeedVector v) {
140d7b241e6Sjeremylt   int ierr;
141*52d6035fSJeremy L Thompson   if (op->composite)
142*52d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Cannot add field to composite operator.");
143*52d6035fSJeremy L Thompson 
144d7b241e6Sjeremylt   CeedInt numelements;
145d7b241e6Sjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr);
146d7b241e6Sjeremylt   if (op->numelements && op->numelements != numelements)
147d7b241e6Sjeremylt     return CeedError(op->ceed, 1,
148d7b241e6Sjeremylt                      "ElemRestriction with %d elements incompatible with prior %d elements",
149d7b241e6Sjeremylt                      numelements, op->numelements);
150d7b241e6Sjeremylt   op->numelements = numelements;
151d7b241e6Sjeremylt 
152783c99b3SValeria Barra   if (b != CEED_BASIS_COLLOCATED) {
153d7b241e6Sjeremylt     CeedInt numqpoints;
154d7b241e6Sjeremylt     ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr);
155d7b241e6Sjeremylt     if (op->numqpoints && op->numqpoints != numqpoints)
156d7b241e6Sjeremylt       return CeedError(op->ceed, 1,
157d7b241e6Sjeremylt                        "Basis with %d quadrature points incompatible with prior %d points",
158d7b241e6Sjeremylt                        numqpoints, op->numqpoints);
159d7b241e6Sjeremylt     op->numqpoints = numqpoints;
160d7b241e6Sjeremylt   }
161d1bcdac9Sjeremylt   CeedOperatorField *ofield;
162d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numinputfields; i++) {
163fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->inputfields[i]).fieldname)) {
164d7b241e6Sjeremylt       ofield = &op->inputfields[i];
165d7b241e6Sjeremylt       goto found;
166d7b241e6Sjeremylt     }
167d7b241e6Sjeremylt   }
168d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numoutputfields; i++) {
169fe2413ffSjeremylt     if (!strcmp(fieldname, (*op->qf->outputfields[i]).fieldname)) {
170d7b241e6Sjeremylt       ofield = &op->outputfields[i];
171d7b241e6Sjeremylt       goto found;
172d7b241e6Sjeremylt     }
173d7b241e6Sjeremylt   }
174d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
175d7b241e6Sjeremylt                    fieldname);
176d7b241e6Sjeremylt found:
177fe2413ffSjeremylt   ierr = CeedCalloc(1, ofield); CeedChk(ierr);
178fe2413ffSjeremylt   (*ofield)->Erestrict = r;
179fe2413ffSjeremylt   (*ofield)->lmode = lmode;
180fe2413ffSjeremylt   (*ofield)->basis = b;
181fe2413ffSjeremylt   (*ofield)->vec = v;
182d7b241e6Sjeremylt   op->nfields += 1;
183d7b241e6Sjeremylt   return 0;
184d7b241e6Sjeremylt }
185d7b241e6Sjeremylt 
186d7b241e6Sjeremylt /**
187*52d6035fSJeremy L Thompson   @brief Add a sub-operator to a composite CeedOperator
188*52d6035fSJeremy L Thompson   @param[out] op Address of the composite CeedOperator
189*52d6035fSJeremy L Thompson   @param      op Address of the sub-operator CeedOperator
190*52d6035fSJeremy L Thompson 
191*52d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
192*52d6035fSJeremy L Thompson 
193*52d6035fSJeremy L Thompson   @ref Basic
194*52d6035fSJeremy L Thompson  */
195*52d6035fSJeremy L Thompson int CeedCompositeOperatorAddSub(CeedOperator compositeop,
196*52d6035fSJeremy L Thompson                                 CeedOperator subop) {
197*52d6035fSJeremy L Thompson   if (!compositeop->composite)
198*52d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
199*52d6035fSJeremy L Thompson                      "CeedOperator is not a composite operator");
200*52d6035fSJeremy L Thompson 
201*52d6035fSJeremy L Thompson   if (compositeop->numsub == CEED_COMPOSITE_MAX)
202*52d6035fSJeremy L Thompson     return CeedError(compositeop->ceed, 1,
203*52d6035fSJeremy L Thompson                      "Cannot add additional suboperators");
204*52d6035fSJeremy L Thompson 
205*52d6035fSJeremy L Thompson   compositeop->suboperators[compositeop->numsub] = subop;
206*52d6035fSJeremy L Thompson   subop->refcount++;
207*52d6035fSJeremy L Thompson   compositeop->numsub++;
208*52d6035fSJeremy L Thompson   return 0;
209*52d6035fSJeremy L Thompson }
210*52d6035fSJeremy L Thompson 
211*52d6035fSJeremy L Thompson /**
212b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
213d7b241e6Sjeremylt 
214d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
215d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
216d7b241e6Sjeremylt   CeedOperatorSetField().
217d7b241e6Sjeremylt 
218d7b241e6Sjeremylt   @param op        CeedOperator to apply
219b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
220b11c1e72Sjeremylt                      active inputs
221b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
222d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
223d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
224d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
225b11c1e72Sjeremylt 
226b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
227dfdf5a53Sjeremylt 
228dfdf5a53Sjeremylt   @ref Basic
229b11c1e72Sjeremylt **/
230d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
231d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
232d7b241e6Sjeremylt   int ierr;
233d7b241e6Sjeremylt   Ceed ceed = op->ceed;
234d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
235d7b241e6Sjeremylt 
236*52d6035fSJeremy L Thompson   if (op->composite) {
237*52d6035fSJeremy L Thompson     if (!op->numsub) return CeedError(ceed, 1, "No suboperators set");
238*52d6035fSJeremy L Thompson   } else {
239d7b241e6Sjeremylt     if (op->nfields == 0) return CeedError(ceed, 1, "No operator fields set");
240d7b241e6Sjeremylt     if (op->nfields < qf->numinputfields + qf->numoutputfields) return CeedError(
241d7b241e6Sjeremylt             ceed, 1, "Not all operator fields set");
242d7b241e6Sjeremylt     if (op->numelements == 0) return CeedError(ceed, 1,
243d7b241e6Sjeremylt                                        "At least one restriction required");
244d7b241e6Sjeremylt     if (op->numqpoints == 0) return CeedError(ceed, 1,
245783c99b3SValeria Barra                                       "At least one non-collocated basis required");
246*52d6035fSJeremy L Thompson   }
247d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
248d7b241e6Sjeremylt   return 0;
249d7b241e6Sjeremylt }
250d7b241e6Sjeremylt 
251d7b241e6Sjeremylt /**
2524ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
2534ce2993fSjeremylt 
2544ce2993fSjeremylt   @param op              CeedOperator
2554ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
2564ce2993fSjeremylt 
2574ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2584ce2993fSjeremylt 
25923617272Sjeremylt   @ref Advanced
2604ce2993fSjeremylt **/
2614ce2993fSjeremylt 
2624ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
2634ce2993fSjeremylt   *ceed = op->ceed;
2644ce2993fSjeremylt   return 0;
2654ce2993fSjeremylt }
2664ce2993fSjeremylt 
2674ce2993fSjeremylt /**
2684ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
2694ce2993fSjeremylt 
2704ce2993fSjeremylt   @param op              CeedOperator
2714ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
2724ce2993fSjeremylt 
2734ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2744ce2993fSjeremylt 
27523617272Sjeremylt   @ref Advanced
2764ce2993fSjeremylt **/
2774ce2993fSjeremylt 
2784ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
279*52d6035fSJeremy L Thompson   if (op->composite)
280*52d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
281*52d6035fSJeremy L Thompson 
2824ce2993fSjeremylt   *numelem = op->numelements;
2834ce2993fSjeremylt   return 0;
2844ce2993fSjeremylt }
2854ce2993fSjeremylt 
2864ce2993fSjeremylt /**
2874ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
2884ce2993fSjeremylt 
2894ce2993fSjeremylt   @param op              CeedOperator
2904ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
2914ce2993fSjeremylt 
2924ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
2934ce2993fSjeremylt 
29423617272Sjeremylt   @ref Advanced
2954ce2993fSjeremylt **/
2964ce2993fSjeremylt 
2974ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
298*52d6035fSJeremy L Thompson   if (op->composite)
299*52d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
300*52d6035fSJeremy L Thompson 
3014ce2993fSjeremylt   *numqpts = op->numqpoints;
3024ce2993fSjeremylt   return 0;
3034ce2993fSjeremylt }
3044ce2993fSjeremylt 
3054ce2993fSjeremylt /**
3064ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
3074ce2993fSjeremylt 
3084ce2993fSjeremylt   @param op              CeedOperator
3094ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
3104ce2993fSjeremylt 
3114ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3124ce2993fSjeremylt 
31323617272Sjeremylt   @ref Advanced
3144ce2993fSjeremylt **/
3154ce2993fSjeremylt 
3164ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
317*52d6035fSJeremy L Thompson   if (op->composite)
318*52d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operators");
3194ce2993fSjeremylt   *numargs = op->nfields;
3204ce2993fSjeremylt   return 0;
3214ce2993fSjeremylt }
3224ce2993fSjeremylt 
3234ce2993fSjeremylt /**
3244ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
3254ce2993fSjeremylt 
3264ce2993fSjeremylt   @param op              CeedOperator
3274ce2993fSjeremylt   @param[out] numelem    Variable to store setup status
3284ce2993fSjeremylt 
3294ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3304ce2993fSjeremylt 
33123617272Sjeremylt   @ref Advanced
3324ce2993fSjeremylt **/
3334ce2993fSjeremylt 
3344ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
3354ce2993fSjeremylt   *setupdone = op->setupdone;
3364ce2993fSjeremylt   return 0;
3374ce2993fSjeremylt }
3384ce2993fSjeremylt 
3394ce2993fSjeremylt /**
3404ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
3414ce2993fSjeremylt 
3424ce2993fSjeremylt   @param op              CeedOperator
3434ce2993fSjeremylt   @param[out] qf         Variable to store qfunction
3444ce2993fSjeremylt 
3454ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
3464ce2993fSjeremylt 
34723617272Sjeremylt   @ref Advanced
3484ce2993fSjeremylt **/
3494ce2993fSjeremylt 
3504ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
351*52d6035fSJeremy L Thompson   if (op->composite)
352*52d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
353*52d6035fSJeremy L Thompson 
3544ce2993fSjeremylt   *qf = op->qf;
3554ce2993fSjeremylt   return 0;
3564ce2993fSjeremylt }
3574ce2993fSjeremylt 
3584ce2993fSjeremylt /**
359*52d6035fSJeremy L Thompson   @brief Get the number of suboperators associated with a CeedOperator
360*52d6035fSJeremy L Thompson 
361*52d6035fSJeremy L Thompson   @param op              CeedOperator
362*52d6035fSJeremy L Thompson   @param[out] numsub     Variable to store number of suboperators
363*52d6035fSJeremy L Thompson 
364*52d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
365*52d6035fSJeremy L Thompson 
366*52d6035fSJeremy L Thompson   @ref Advanced
367*52d6035fSJeremy L Thompson **/
368*52d6035fSJeremy L Thompson 
369*52d6035fSJeremy L Thompson int CeedOperatorGetNumSub(CeedOperator op, CeedInt *numsub) {
370*52d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
371*52d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
372*52d6035fSJeremy L Thompson 
373*52d6035fSJeremy L Thompson   *numsub = op->numsub;
374*52d6035fSJeremy L Thompson   return 0;
375*52d6035fSJeremy L Thompson }
376*52d6035fSJeremy L Thompson 
377*52d6035fSJeremy L Thompson /**
378*52d6035fSJeremy L Thompson   @brief Get the list of suboperators associated with a CeedOperator
379*52d6035fSJeremy L Thompson 
380*52d6035fSJeremy L Thompson   @param op                CeedOperator
381*52d6035fSJeremy L Thompson   @param[out] suboperators Variable to store list of suboperators
382*52d6035fSJeremy L Thompson 
383*52d6035fSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
384*52d6035fSJeremy L Thompson 
385*52d6035fSJeremy L Thompson   @ref Advanced
386*52d6035fSJeremy L Thompson **/
387*52d6035fSJeremy L Thompson 
388*52d6035fSJeremy L Thompson int CeedOperatorGetSubList(CeedOperator op, CeedOperator* *suboperators) {
389*52d6035fSJeremy L Thompson   Ceed ceed = op->ceed;
390*52d6035fSJeremy L Thompson   if (!op->composite) return CeedError(ceed, 1, "Not a composite operator");
391*52d6035fSJeremy L Thompson 
392*52d6035fSJeremy L Thompson   *suboperators = op->suboperators;
393*52d6035fSJeremy L Thompson   return 0;
394*52d6035fSJeremy L Thompson }
395*52d6035fSJeremy L Thompson 
396*52d6035fSJeremy L Thompson /**
397fe2413ffSjeremylt   @brief Set the backend data of a CeedOperator
398fe2413ffSjeremylt 
399fe2413ffSjeremylt   @param[out] op         CeedOperator
400fe2413ffSjeremylt   @param data            Data to set
401fe2413ffSjeremylt 
402fe2413ffSjeremylt   @return An error code: 0 - success, otherwise - failure
403fe2413ffSjeremylt 
404fe2413ffSjeremylt   @ref Advanced
405fe2413ffSjeremylt **/
406fe2413ffSjeremylt 
407fe2413ffSjeremylt int CeedOperatorSetData(CeedOperator op, void* *data) {
408fe2413ffSjeremylt   op->data = *data;
409fe2413ffSjeremylt   return 0;
410fe2413ffSjeremylt }
411fe2413ffSjeremylt 
412fe2413ffSjeremylt /**
4134ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
4144ce2993fSjeremylt 
4154ce2993fSjeremylt   @param op              CeedOperator
4164ce2993fSjeremylt   @param[out] data       Variable to store data
4174ce2993fSjeremylt 
4184ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4194ce2993fSjeremylt 
42023617272Sjeremylt   @ref Advanced
4214ce2993fSjeremylt **/
4224ce2993fSjeremylt 
4234ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
4244ce2993fSjeremylt   *data = op->data;
4254ce2993fSjeremylt   return 0;
4264ce2993fSjeremylt }
4274ce2993fSjeremylt 
4284ce2993fSjeremylt /**
4294ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
4304ce2993fSjeremylt 
4314ce2993fSjeremylt   @param op              CeedOperator
4324ce2993fSjeremylt 
4334ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
4344ce2993fSjeremylt 
43523617272Sjeremylt   @ref Advanced
4364ce2993fSjeremylt **/
4374ce2993fSjeremylt 
4384ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
4394ce2993fSjeremylt   op->setupdone = 1;
4404ce2993fSjeremylt   return 0;
4414ce2993fSjeremylt }
4424ce2993fSjeremylt 
4434ce2993fSjeremylt /**
444d1bcdac9Sjeremylt   @brief Get the CeedOperatorFields of a CeedOperator
445d1bcdac9Sjeremylt 
446d1bcdac9Sjeremylt   @param op                 CeedOperator
447d1bcdac9Sjeremylt   @param[out] inputfields   Variable to store inputfields
448d1bcdac9Sjeremylt   @param[out] outputfields  Variable to store outputfields
449d1bcdac9Sjeremylt 
450d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
451d1bcdac9Sjeremylt 
452d1bcdac9Sjeremylt   @ref Advanced
453d1bcdac9Sjeremylt **/
454d1bcdac9Sjeremylt 
455d1bcdac9Sjeremylt int CeedOperatorGetFields(CeedOperator op,
456d1bcdac9Sjeremylt                           CeedOperatorField* *inputfields,
457d1bcdac9Sjeremylt                           CeedOperatorField* *outputfields) {
458*52d6035fSJeremy L Thompson   if (op->composite)
459*52d6035fSJeremy L Thompson     return CeedError(op->ceed, 1, "Not defined for composite operator");
460*52d6035fSJeremy L Thompson 
461d1bcdac9Sjeremylt   if (inputfields) *inputfields = op->inputfields;
462d1bcdac9Sjeremylt   if (outputfields) *outputfields = op->outputfields;
463d1bcdac9Sjeremylt   return 0;
464d1bcdac9Sjeremylt }
465d1bcdac9Sjeremylt 
466d1bcdac9Sjeremylt /**
4674dccadb6Sjeremylt   @brief Get the L vector CeedTransposeMode of a CeedOperatorField
4684dccadb6Sjeremylt 
4694dccadb6Sjeremylt   @param opfield         CeedOperatorField
4704dccadb6Sjeremylt   @param[out] lmode      Variable to store CeedTransposeMode
4714dccadb6Sjeremylt 
4724dccadb6Sjeremylt   @return An error code: 0 - success, otherwise - failure
4734dccadb6Sjeremylt 
4744dccadb6Sjeremylt   @ref Advanced
4754dccadb6Sjeremylt **/
4764dccadb6Sjeremylt 
4774dccadb6Sjeremylt int CeedOperatorFieldGetLMode(CeedOperatorField opfield,
4784dccadb6Sjeremylt                               CeedTransposeMode *lmode) {
479fe2413ffSjeremylt   *lmode = opfield->lmode;
4804dccadb6Sjeremylt   return 0;
4814dccadb6Sjeremylt }/**
482d1bcdac9Sjeremylt   @brief Get the CeedElemRestriction of a CeedOperatorField
483d1bcdac9Sjeremylt 
484d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
485d1bcdac9Sjeremylt   @param[out] rstr       Variable to store CeedElemRestriction
486d1bcdac9Sjeremylt 
487d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
488d1bcdac9Sjeremylt 
489d1bcdac9Sjeremylt   @ref Advanced
490d1bcdac9Sjeremylt **/
491d1bcdac9Sjeremylt 
492d1bcdac9Sjeremylt int CeedOperatorFieldGetElemRestriction(CeedOperatorField opfield,
493d1bcdac9Sjeremylt                                         CeedElemRestriction *rstr) {
494fe2413ffSjeremylt   *rstr = opfield->Erestrict;
495d1bcdac9Sjeremylt   return 0;
496d1bcdac9Sjeremylt }
497d1bcdac9Sjeremylt 
498d1bcdac9Sjeremylt /**
499d1bcdac9Sjeremylt   @brief Get the CeedBasis of a CeedOperatorField
500d1bcdac9Sjeremylt 
501d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
502d1bcdac9Sjeremylt   @param[out] basis      Variable to store CeedBasis
503d1bcdac9Sjeremylt 
504d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
505d1bcdac9Sjeremylt 
506d1bcdac9Sjeremylt   @ref Advanced
507d1bcdac9Sjeremylt **/
508d1bcdac9Sjeremylt 
509d1bcdac9Sjeremylt int CeedOperatorFieldGetBasis(CeedOperatorField opfield,
510d1bcdac9Sjeremylt                               CeedBasis *basis) {
511fe2413ffSjeremylt   *basis = opfield->basis;
512d1bcdac9Sjeremylt   return 0;
513d1bcdac9Sjeremylt }
514d1bcdac9Sjeremylt 
515d1bcdac9Sjeremylt /**
516d1bcdac9Sjeremylt   @brief Get the CeedVector of a CeedOperatorField
517d1bcdac9Sjeremylt 
518d1bcdac9Sjeremylt   @param opfield         CeedOperatorField
519d1bcdac9Sjeremylt   @param[out] vec        Variable to store CeedVector
520d1bcdac9Sjeremylt 
521d1bcdac9Sjeremylt   @return An error code: 0 - success, otherwise - failure
522d1bcdac9Sjeremylt 
523d1bcdac9Sjeremylt   @ref Advanced
524d1bcdac9Sjeremylt **/
525d1bcdac9Sjeremylt 
526d1bcdac9Sjeremylt int CeedOperatorFieldGetVector(CeedOperatorField opfield,
527d1bcdac9Sjeremylt                                CeedVector *vec) {
528fe2413ffSjeremylt   *vec = opfield->vec;
529d1bcdac9Sjeremylt   return 0;
530d1bcdac9Sjeremylt }
531d1bcdac9Sjeremylt 
532d1bcdac9Sjeremylt /**
533b11c1e72Sjeremylt   @brief Destroy a CeedOperator
534d7b241e6Sjeremylt 
535d7b241e6Sjeremylt   @param op CeedOperator to destroy
536b11c1e72Sjeremylt 
537b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
538dfdf5a53Sjeremylt 
539dfdf5a53Sjeremylt   @ref Basic
540b11c1e72Sjeremylt **/
541d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
542d7b241e6Sjeremylt   int ierr;
543d7b241e6Sjeremylt 
544d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
545d7b241e6Sjeremylt   if ((*op)->Destroy) {
546d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
547d7b241e6Sjeremylt   }
548fe2413ffSjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
549fe2413ffSjeremylt   // Free fields
550d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
551*52d6035fSJeremy L Thompson     if ((*op)->inputfields[i]) {
552fe2413ffSjeremylt       ierr = CeedFree(&(*op)->inputfields[i]); CeedChk(ierr);
553fe2413ffSjeremylt     }
554d0eb30a5Sjeremylt   }
555d0eb30a5Sjeremylt   for (int i=0; i<(*op)->nfields; i++) {
556d0eb30a5Sjeremylt     if ((*op)->outputfields[i]) {
557fe2413ffSjeremylt       ierr = CeedFree(&(*op)->outputfields[i]); CeedChk(ierr);
558fe2413ffSjeremylt     }
559d0eb30a5Sjeremylt   }
560*52d6035fSJeremy L Thompson   // Destroy suboperators
561*52d6035fSJeremy L Thompson   for (int i=0; i<(*op)->numsub; i++) {
562*52d6035fSJeremy L Thompson     if ((*op)->suboperators[i]) {
563*52d6035fSJeremy L Thompson       ierr = CeedOperatorDestroy(&(*op)->suboperators[i]); CeedChk(ierr);
564*52d6035fSJeremy L Thompson     }
565*52d6035fSJeremy L Thompson   }
566d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
567d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
568d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
569fe2413ffSjeremylt 
570fe2413ffSjeremylt   ierr = CeedFree(&(*op)->inputfields); CeedChk(ierr);
571fe2413ffSjeremylt   ierr = CeedFree(&(*op)->outputfields); CeedChk(ierr);
572*52d6035fSJeremy L Thompson   ierr = CeedFree(&(*op)->suboperators); CeedChk(ierr);
573d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
574d7b241e6Sjeremylt   return 0;
575d7b241e6Sjeremylt }
576d7b241e6Sjeremylt 
577d7b241e6Sjeremylt /// @}
578