xref: /libCEED/rust/libceed-sys/c-src/interface/ceed-operator.c (revision 4ce2993fee6e7bc9b86526ee90098d0dc489fc60)
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>
18d7b241e6Sjeremylt #include <string.h>
19d7b241e6Sjeremylt 
20dfdf5a53Sjeremylt /// @file
21dfdf5a53Sjeremylt /// Implementation of public CeedOperator interfaces
22dfdf5a53Sjeremylt ///
23dfdf5a53Sjeremylt /// @addtogroup CeedOperator
24dfdf5a53Sjeremylt ///   @{
25d7b241e6Sjeremylt 
26d7b241e6Sjeremylt /**
27b11c1e72Sjeremylt   @brief Create an operator from element restriction, basis, and QFunction
28d7b241e6Sjeremylt 
29b11c1e72Sjeremylt   @param ceed    A Ceed object where the CeedOperator will be created
30d7b241e6Sjeremylt   @param qf      QFunction defining the action of the operator at quadrature points
31d7b241e6Sjeremylt   @param dqf     QFunction defining the action of the Jacobian of @a qf (or NULL)
32d7b241e6Sjeremylt   @param dqfT    QFunction defining the action of the transpose of the Jacobian
33d7b241e6Sjeremylt                    of @a qf (or NULL)
34b11c1e72Sjeremylt   @param[out] op Address of the variable where the newly created
35b11c1e72Sjeremylt                      CeedOperator will be stored
36b11c1e72Sjeremylt 
37b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
38dfdf5a53Sjeremylt 
39dfdf5a53Sjeremylt   @ref Basic
40d7b241e6Sjeremylt  */
41d7b241e6Sjeremylt int CeedOperatorCreate(Ceed ceed, CeedQFunction qf, CeedQFunction dqf,
42d7b241e6Sjeremylt                        CeedQFunction dqfT, CeedOperator *op) {
43d7b241e6Sjeremylt   int ierr;
44d7b241e6Sjeremylt 
455fe0d4faSjeremylt   if (!ceed->OperatorCreate) {
465fe0d4faSjeremylt     Ceed delegate;
475fe0d4faSjeremylt     ierr = CeedGetDelegate(ceed, &delegate); CeedChk(ierr);
485fe0d4faSjeremylt 
495fe0d4faSjeremylt     if (!delegate)
505fe0d4faSjeremylt       return CeedError(ceed, 1, "Backend does not support OperatorCreate");
515fe0d4faSjeremylt 
525fe0d4faSjeremylt     ierr = CeedOperatorCreate(delegate, qf, dqf, dqfT, op); CeedChk(ierr);
535fe0d4faSjeremylt     return 0;
545fe0d4faSjeremylt   }
555fe0d4faSjeremylt 
56d7b241e6Sjeremylt   ierr = CeedCalloc(1,op); CeedChk(ierr);
57d7b241e6Sjeremylt   (*op)->ceed = ceed;
58d7b241e6Sjeremylt   ceed->refcount++;
59d7b241e6Sjeremylt   (*op)->refcount = 1;
60d7b241e6Sjeremylt   (*op)->qf = qf;
61d7b241e6Sjeremylt   qf->refcount++;
62d7b241e6Sjeremylt   (*op)->dqf = dqf;
63d7b241e6Sjeremylt   if (dqf) dqf->refcount++;
64d7b241e6Sjeremylt   (*op)->dqfT = dqfT;
65d7b241e6Sjeremylt   if (dqfT) dqfT->refcount++;
66d7b241e6Sjeremylt   ierr = ceed->OperatorCreate(*op); CeedChk(ierr);
67d7b241e6Sjeremylt   return 0;
68d7b241e6Sjeremylt }
69d7b241e6Sjeremylt 
70d7b241e6Sjeremylt /**
71b11c1e72Sjeremylt   @brief Provide a field to a CeedOperator for use by its CeedQFunction
72d7b241e6Sjeremylt 
73d7b241e6Sjeremylt   This function is used to specify both active and passive fields to a
74d7b241e6Sjeremylt   CeedOperator.  For passive fields, a vector @arg v must be provided.  Passive
75d7b241e6Sjeremylt   fields can inputs or outputs (updated in-place when operator is applied).
76d7b241e6Sjeremylt 
77d7b241e6Sjeremylt   Active fields must be specified using this function, but their data (in a
78d7b241e6Sjeremylt   CeedVector) is passed in CeedOperatorApply().  There can be at most one active
79d7b241e6Sjeremylt   input and at most one active output.
80d7b241e6Sjeremylt 
81b11c1e72Sjeremylt   @param op         Ceedoperator on which to provide the field
82b11c1e72Sjeremylt   @param fieldname  Name of the field (to be matched with the name used by CeedQFunction)
83b11c1e72Sjeremylt   @param r          CeedElemRestriction
84783c99b3SValeria Barra   @param b          CeedBasis in which the field resides or CEED_BASIS_COLLOCATED
85b11c1e72Sjeremylt                       if collocated with quadrature points
86b11c1e72Sjeremylt   @param v          CeedVector to be used by CeedOperator or CEED_VECTOR_ACTIVE
87b11c1e72Sjeremylt                       if field is active or CEED_VECTOR_NONE if using
88b11c1e72Sjeremylt                       CEED_EVAL_WEIGHT in the qfunction
89b11c1e72Sjeremylt 
90b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
91dfdf5a53Sjeremylt 
92dfdf5a53Sjeremylt   @ref Basic
93b11c1e72Sjeremylt **/
94d7b241e6Sjeremylt int CeedOperatorSetField(CeedOperator op, const char *fieldname,
95d7b241e6Sjeremylt                          CeedElemRestriction r, CeedBasis b,
96d7b241e6Sjeremylt                          CeedVector v) {
97d7b241e6Sjeremylt   int ierr;
98d7b241e6Sjeremylt   CeedInt numelements;
99d7b241e6Sjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &numelements); CeedChk(ierr);
100d7b241e6Sjeremylt   if (op->numelements && op->numelements != numelements)
101d7b241e6Sjeremylt     return CeedError(op->ceed, 1,
102d7b241e6Sjeremylt                      "ElemRestriction with %d elements incompatible with prior %d elements",
103d7b241e6Sjeremylt                      numelements, op->numelements);
104d7b241e6Sjeremylt   op->numelements = numelements;
105d7b241e6Sjeremylt 
106783c99b3SValeria Barra   if (b != CEED_BASIS_COLLOCATED) {
107d7b241e6Sjeremylt     CeedInt numqpoints;
108d7b241e6Sjeremylt     ierr = CeedBasisGetNumQuadraturePoints(b, &numqpoints); CeedChk(ierr);
109d7b241e6Sjeremylt     if (op->numqpoints && op->numqpoints != numqpoints)
110d7b241e6Sjeremylt       return CeedError(op->ceed, 1,
111d7b241e6Sjeremylt                        "Basis with %d quadrature points incompatible with prior %d points",
112d7b241e6Sjeremylt                        numqpoints, op->numqpoints);
113d7b241e6Sjeremylt     op->numqpoints = numqpoints;
114d7b241e6Sjeremylt   }
115d7b241e6Sjeremylt   struct CeedOperatorField *ofield;
116d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numinputfields; i++) {
117d7b241e6Sjeremylt     if (!strcmp(fieldname, op->qf->inputfields[i].fieldname)) {
118d7b241e6Sjeremylt       ofield = &op->inputfields[i];
119d7b241e6Sjeremylt       goto found;
120d7b241e6Sjeremylt     }
121d7b241e6Sjeremylt   }
122d7b241e6Sjeremylt   for (CeedInt i=0; i<op->qf->numoutputfields; i++) {
123d7b241e6Sjeremylt     if (!strcmp(fieldname, op->qf->outputfields[i].fieldname)) {
124d7b241e6Sjeremylt       ofield = &op->outputfields[i];
125d7b241e6Sjeremylt       goto found;
126d7b241e6Sjeremylt     }
127d7b241e6Sjeremylt   }
128d7b241e6Sjeremylt   return CeedError(op->ceed, 1, "QFunction has no knowledge of field '%s'",
129d7b241e6Sjeremylt                    fieldname);
130d7b241e6Sjeremylt found:
131d7b241e6Sjeremylt   ofield->Erestrict = r;
132d7b241e6Sjeremylt   ofield->basis = b;
133d7b241e6Sjeremylt   ofield->vec = v;
134d7b241e6Sjeremylt   op->nfields += 1;
135d7b241e6Sjeremylt   return 0;
136d7b241e6Sjeremylt }
137d7b241e6Sjeremylt 
138d7b241e6Sjeremylt /**
139b11c1e72Sjeremylt   @brief Apply CeedOperator to a vector
140d7b241e6Sjeremylt 
141d7b241e6Sjeremylt   This computes the action of the operator on the specified (active) input,
142d7b241e6Sjeremylt   yielding its (active) output.  All inputs and outputs must be specified using
143d7b241e6Sjeremylt   CeedOperatorSetField().
144d7b241e6Sjeremylt 
145d7b241e6Sjeremylt   @param op        CeedOperator to apply
146b11c1e72Sjeremylt   @param[in] in    CeedVector containing input state or NULL if there are no
147b11c1e72Sjeremylt                      active inputs
148b11c1e72Sjeremylt   @param[out] out  CeedVector to store result of applying operator (must be
149d7b241e6Sjeremylt                      distinct from @a in) or NULL if there are no active outputs
150d7b241e6Sjeremylt   @param request   Address of CeedRequest for non-blocking completion, else
151d7b241e6Sjeremylt                      CEED_REQUEST_IMMEDIATE
152b11c1e72Sjeremylt 
153b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
154dfdf5a53Sjeremylt 
155dfdf5a53Sjeremylt   @ref Basic
156b11c1e72Sjeremylt **/
157d7b241e6Sjeremylt int CeedOperatorApply(CeedOperator op, CeedVector in,
158d7b241e6Sjeremylt                       CeedVector out, CeedRequest *request) {
159d7b241e6Sjeremylt   int ierr;
160d7b241e6Sjeremylt   Ceed ceed = op->ceed;
161d7b241e6Sjeremylt   CeedQFunction qf = op->qf;
162d7b241e6Sjeremylt 
163d7b241e6Sjeremylt   if (op->nfields == 0) return CeedError(ceed, 1, "No operator fields set");
164d7b241e6Sjeremylt   if (op->nfields < qf->numinputfields + qf->numoutputfields) return CeedError(
165d7b241e6Sjeremylt           ceed, 1, "Not all operator fields set");
166d7b241e6Sjeremylt   if (op->numelements == 0) return CeedError(ceed, 1,
167d7b241e6Sjeremylt                                      "At least one restriction required");
168d7b241e6Sjeremylt   if (op->numqpoints == 0) return CeedError(ceed, 1,
169783c99b3SValeria Barra                                     "At least one non-collocated basis required");
170d7b241e6Sjeremylt   ierr = op->Apply(op, in, out, request); CeedChk(ierr);
171d7b241e6Sjeremylt   return 0;
172d7b241e6Sjeremylt }
173d7b241e6Sjeremylt 
174d7b241e6Sjeremylt /**
175*4ce2993fSjeremylt   @brief Get the Ceed associated with a CeedOperator
176*4ce2993fSjeremylt 
177*4ce2993fSjeremylt   @param op              CeedOperator
178*4ce2993fSjeremylt   @param[out] ceed       Variable to store Ceed
179*4ce2993fSjeremylt 
180*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
181*4ce2993fSjeremylt 
182*4ce2993fSjeremylt   @ref Utility
183*4ce2993fSjeremylt **/
184*4ce2993fSjeremylt 
185*4ce2993fSjeremylt int CeedOperatorGetCeed(CeedOperator op, Ceed *ceed) {
186*4ce2993fSjeremylt   *ceed = op->ceed;
187*4ce2993fSjeremylt   return 0;
188*4ce2993fSjeremylt }
189*4ce2993fSjeremylt 
190*4ce2993fSjeremylt /**
191*4ce2993fSjeremylt   @brief Get the number of elements associated with a CeedOperator
192*4ce2993fSjeremylt 
193*4ce2993fSjeremylt   @param op              CeedOperator
194*4ce2993fSjeremylt   @param[out] numelem    Variable to store number of elements
195*4ce2993fSjeremylt 
196*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
197*4ce2993fSjeremylt 
198*4ce2993fSjeremylt   @ref Utility
199*4ce2993fSjeremylt **/
200*4ce2993fSjeremylt 
201*4ce2993fSjeremylt int CeedOperatorGetNumElements(CeedOperator op, CeedInt *numelem) {
202*4ce2993fSjeremylt   *numelem = op->numelements;
203*4ce2993fSjeremylt   return 0;
204*4ce2993fSjeremylt }
205*4ce2993fSjeremylt 
206*4ce2993fSjeremylt /**
207*4ce2993fSjeremylt   @brief Get the number of quadrature points associated with a CeedOperator
208*4ce2993fSjeremylt 
209*4ce2993fSjeremylt   @param op              CeedOperator
210*4ce2993fSjeremylt   @param[out] numqpts    Variable to store vector number of quadrature points
211*4ce2993fSjeremylt 
212*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
213*4ce2993fSjeremylt 
214*4ce2993fSjeremylt   @ref Utility
215*4ce2993fSjeremylt **/
216*4ce2993fSjeremylt 
217*4ce2993fSjeremylt int CeedOperatorGetNumQuadraturePoints(CeedOperator op, CeedInt *numqpts) {
218*4ce2993fSjeremylt   *numqpts = op->numqpoints;
219*4ce2993fSjeremylt   return 0;
220*4ce2993fSjeremylt }
221*4ce2993fSjeremylt 
222*4ce2993fSjeremylt /**
223*4ce2993fSjeremylt   @brief Get the number of arguments associated with a CeedOperator
224*4ce2993fSjeremylt 
225*4ce2993fSjeremylt   @param op              CeedOperator
226*4ce2993fSjeremylt   @param[out] numargs    Variable to store vector number of arguments
227*4ce2993fSjeremylt 
228*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
229*4ce2993fSjeremylt 
230*4ce2993fSjeremylt   @ref Utility
231*4ce2993fSjeremylt **/
232*4ce2993fSjeremylt 
233*4ce2993fSjeremylt int CeedOperatorGetNumArgs(CeedOperator op, CeedInt *numargs) {
234*4ce2993fSjeremylt   *numargs = op->nfields;
235*4ce2993fSjeremylt   return 0;
236*4ce2993fSjeremylt }
237*4ce2993fSjeremylt 
238*4ce2993fSjeremylt /**
239*4ce2993fSjeremylt   @brief Get the setup status of a CeedOperator
240*4ce2993fSjeremylt 
241*4ce2993fSjeremylt   @param op              CeedOperator
242*4ce2993fSjeremylt   @param[out] numelem    Variable to store setup status
243*4ce2993fSjeremylt 
244*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
245*4ce2993fSjeremylt 
246*4ce2993fSjeremylt   @ref Utility
247*4ce2993fSjeremylt **/
248*4ce2993fSjeremylt 
249*4ce2993fSjeremylt int CeedOperatorGetSetupStatus(CeedOperator op, bool *setupdone) {
250*4ce2993fSjeremylt   *setupdone = op->setupdone;
251*4ce2993fSjeremylt   return 0;
252*4ce2993fSjeremylt }
253*4ce2993fSjeremylt 
254*4ce2993fSjeremylt /**
255*4ce2993fSjeremylt   @brief Get the QFunction associated with a CeedOperator
256*4ce2993fSjeremylt 
257*4ce2993fSjeremylt   @param op              CeedOperator
258*4ce2993fSjeremylt   @param[out] qf         Variable to store qfunction
259*4ce2993fSjeremylt 
260*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
261*4ce2993fSjeremylt 
262*4ce2993fSjeremylt   @ref Utility
263*4ce2993fSjeremylt **/
264*4ce2993fSjeremylt 
265*4ce2993fSjeremylt int CeedOperatorGetQFunction(CeedOperator op, CeedQFunction *qf) {
266*4ce2993fSjeremylt   *qf = op->qf;
267*4ce2993fSjeremylt   return 0;
268*4ce2993fSjeremylt }
269*4ce2993fSjeremylt 
270*4ce2993fSjeremylt /**
271*4ce2993fSjeremylt   @brief Get the backend data of a CeedOperator
272*4ce2993fSjeremylt 
273*4ce2993fSjeremylt   @param op              CeedOperator
274*4ce2993fSjeremylt   @param[out] data       Variable to store data
275*4ce2993fSjeremylt 
276*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
277*4ce2993fSjeremylt 
278*4ce2993fSjeremylt   @ref Utility
279*4ce2993fSjeremylt **/
280*4ce2993fSjeremylt 
281*4ce2993fSjeremylt int CeedOperatorGetData(CeedOperator op, void* *data) {
282*4ce2993fSjeremylt   *data = op->data;
283*4ce2993fSjeremylt   return 0;
284*4ce2993fSjeremylt }
285*4ce2993fSjeremylt 
286*4ce2993fSjeremylt /**
287*4ce2993fSjeremylt   @brief Set the setup flag of a CeedOperator to True
288*4ce2993fSjeremylt 
289*4ce2993fSjeremylt   @param op              CeedOperator
290*4ce2993fSjeremylt 
291*4ce2993fSjeremylt   @return An error code: 0 - success, otherwise - failure
292*4ce2993fSjeremylt 
293*4ce2993fSjeremylt   @ref Utility
294*4ce2993fSjeremylt **/
295*4ce2993fSjeremylt 
296*4ce2993fSjeremylt int CeedOperatorSetSetupDone(CeedOperator op) {
297*4ce2993fSjeremylt   op->setupdone = 1;
298*4ce2993fSjeremylt   return 0;
299*4ce2993fSjeremylt }
300*4ce2993fSjeremylt 
301*4ce2993fSjeremylt /**
302b11c1e72Sjeremylt   @brief Destroy a CeedOperator
303d7b241e6Sjeremylt 
304d7b241e6Sjeremylt   @param op CeedOperator to destroy
305b11c1e72Sjeremylt 
306b11c1e72Sjeremylt   @return An error code: 0 - success, otherwise - failure
307dfdf5a53Sjeremylt 
308dfdf5a53Sjeremylt   @ref Basic
309b11c1e72Sjeremylt **/
310d7b241e6Sjeremylt int CeedOperatorDestroy(CeedOperator *op) {
311d7b241e6Sjeremylt   int ierr;
312d7b241e6Sjeremylt 
313d7b241e6Sjeremylt   if (!*op || --(*op)->refcount > 0) return 0;
314d7b241e6Sjeremylt   if ((*op)->Destroy) {
315d7b241e6Sjeremylt     ierr = (*op)->Destroy(*op); CeedChk(ierr);
316d7b241e6Sjeremylt   }
317d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->qf); CeedChk(ierr);
318d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqf); CeedChk(ierr);
319d7b241e6Sjeremylt   ierr = CeedQFunctionDestroy(&(*op)->dqfT); CeedChk(ierr);
320d7b241e6Sjeremylt   ierr = CeedDestroy(&(*op)->ceed); CeedChk(ierr);
321d7b241e6Sjeremylt   ierr = CeedFree(op); CeedChk(ierr);
322d7b241e6Sjeremylt   return 0;
323d7b241e6Sjeremylt }
324d7b241e6Sjeremylt 
325d7b241e6Sjeremylt /// @}
326