xref: /libCEED/interface/ceed-fortran.c (revision d7b241e67f6e33d9b297db3da3be4f167f32bbee)
1*d7b241e6Sjeremylt // Fortran interface
2*d7b241e6Sjeremylt #include <ceed.h>
3*d7b241e6Sjeremylt #include <ceed-impl.h>
4*d7b241e6Sjeremylt #include <ceed-fortran-name.h>
5*d7b241e6Sjeremylt 
6*d7b241e6Sjeremylt #include <stdlib.h>
7*d7b241e6Sjeremylt #include <string.h>
8*d7b241e6Sjeremylt 
9*d7b241e6Sjeremylt #define FORTRAN_REQUEST_IMMEDIATE -1
10*d7b241e6Sjeremylt #define FORTRAN_REQUEST_ORDERED -2
11*d7b241e6Sjeremylt #define FORTRAN_NULL -3
12*d7b241e6Sjeremylt #define FORTRAN_BASIS_COLOCATED -1
13*d7b241e6Sjeremylt #define FORTRAN_QDATA_NONE -1
14*d7b241e6Sjeremylt #define FORTRAN_VECTOR_ACTIVE -1
15*d7b241e6Sjeremylt #define FORTRAN_VECTOR_NONE -2
16*d7b241e6Sjeremylt 
17*d7b241e6Sjeremylt static Ceed *Ceed_dict = NULL;
18*d7b241e6Sjeremylt static int Ceed_count = 0;
19*d7b241e6Sjeremylt static int Ceed_n = 0;
20*d7b241e6Sjeremylt static int Ceed_count_max = 0;
21*d7b241e6Sjeremylt 
22*d7b241e6Sjeremylt #define fCeedInit FORTRAN_NAME(ceedinit,CEEDINIT)
23*d7b241e6Sjeremylt void fCeedInit(const char* resource, int *ceed, int *err) {
24*d7b241e6Sjeremylt   if (Ceed_count == Ceed_count_max) {
25*d7b241e6Sjeremylt     Ceed_count_max += Ceed_count_max/2 + 1;
26*d7b241e6Sjeremylt     CeedRealloc(Ceed_count_max, &Ceed_dict);
27*d7b241e6Sjeremylt   }
28*d7b241e6Sjeremylt 
29*d7b241e6Sjeremylt   Ceed *ceed_ = &Ceed_dict[Ceed_count];
30*d7b241e6Sjeremylt   *err = CeedInit(resource, ceed_);
31*d7b241e6Sjeremylt 
32*d7b241e6Sjeremylt   if (*err == 0) {
33*d7b241e6Sjeremylt     *ceed = Ceed_count++;
34*d7b241e6Sjeremylt     Ceed_n++;
35*d7b241e6Sjeremylt   }
36*d7b241e6Sjeremylt }
37*d7b241e6Sjeremylt 
38*d7b241e6Sjeremylt #define fCeedDestroy FORTRAN_NAME(ceeddestroy,CEEDDESTROY)
39*d7b241e6Sjeremylt void fCeedDestroy(int *ceed, int *err) {
40*d7b241e6Sjeremylt   *err = CeedDestroy(&Ceed_dict[*ceed]);
41*d7b241e6Sjeremylt 
42*d7b241e6Sjeremylt   if (*err == 0) {
43*d7b241e6Sjeremylt     Ceed_n--;
44*d7b241e6Sjeremylt     if (Ceed_n == 0) {
45*d7b241e6Sjeremylt       CeedFree(&Ceed_dict);
46*d7b241e6Sjeremylt       Ceed_count = 0;
47*d7b241e6Sjeremylt       Ceed_count_max = 0;
48*d7b241e6Sjeremylt     }
49*d7b241e6Sjeremylt   }
50*d7b241e6Sjeremylt }
51*d7b241e6Sjeremylt 
52*d7b241e6Sjeremylt static CeedVector *CeedVector_dict = NULL;
53*d7b241e6Sjeremylt static int CeedVector_count = 0;
54*d7b241e6Sjeremylt static int CeedVector_n = 0;
55*d7b241e6Sjeremylt static int CeedVector_count_max = 0;
56*d7b241e6Sjeremylt 
57*d7b241e6Sjeremylt #define fCeedVectorCreate FORTRAN_NAME(ceedvectorcreate,CEEDVECTORCREATE)
58*d7b241e6Sjeremylt void fCeedVectorCreate(int *ceed, int *length, int *vec, int *err) {
59*d7b241e6Sjeremylt   if (CeedVector_count == CeedVector_count_max) {
60*d7b241e6Sjeremylt     CeedVector_count_max += CeedVector_count_max/2 + 1;
61*d7b241e6Sjeremylt     CeedRealloc(CeedVector_count_max, &CeedVector_dict);
62*d7b241e6Sjeremylt   }
63*d7b241e6Sjeremylt 
64*d7b241e6Sjeremylt   CeedVector* vec_ = &CeedVector_dict[CeedVector_count];
65*d7b241e6Sjeremylt   *err = CeedVectorCreate(Ceed_dict[*ceed], *length, vec_);
66*d7b241e6Sjeremylt 
67*d7b241e6Sjeremylt   if (*err == 0) {
68*d7b241e6Sjeremylt     *vec = CeedVector_count++;
69*d7b241e6Sjeremylt     CeedVector_n++;
70*d7b241e6Sjeremylt   }
71*d7b241e6Sjeremylt }
72*d7b241e6Sjeremylt 
73*d7b241e6Sjeremylt #define fCeedVectorSetArray FORTRAN_NAME(ceedvectorsetarray,CEEDVECTORSETARRAY)
74*d7b241e6Sjeremylt void fCeedVectorSetArray(int *vec, int *memtype, int *copymode,
75*d7b241e6Sjeremylt                          CeedScalar *array, int *err) {
76*d7b241e6Sjeremylt   *err = CeedVectorSetArray(CeedVector_dict[*vec], *memtype, *copymode, array);
77*d7b241e6Sjeremylt }
78*d7b241e6Sjeremylt 
79*d7b241e6Sjeremylt #define fCeedVectorSetValue FORTRAN_NAME(ceedvectorsetvalue,CEEDVECTORSETVALUE)
80*d7b241e6Sjeremylt void fCeedVectorSetValue(int *vec, CeedScalar *value, int *err) {
81*d7b241e6Sjeremylt   *err = CeedVectorSetValue(CeedVector_dict[*vec], *value);
82*d7b241e6Sjeremylt }
83*d7b241e6Sjeremylt 
84*d7b241e6Sjeremylt #define fCeedVectorGetArray FORTRAN_NAME(ceedvectorgetarray,CEEDVECTORGETARRAY)
85*d7b241e6Sjeremylt //TODO Need Fixing, double pointer
86*d7b241e6Sjeremylt void fCeedVectorGetArray(int *vec, int *memtype, CeedScalar *array, int *err) {
87*d7b241e6Sjeremylt   CeedScalar *b;
88*d7b241e6Sjeremylt   CeedVector vec_ = CeedVector_dict[*vec];
89*d7b241e6Sjeremylt   *err = CeedVectorGetArray(vec_, *memtype, &b);
90*d7b241e6Sjeremylt   if (*err == 0)
91*d7b241e6Sjeremylt     memcpy(array, b, sizeof(CeedScalar)*vec_->length);
92*d7b241e6Sjeremylt }
93*d7b241e6Sjeremylt 
94*d7b241e6Sjeremylt #define fCeedVectorGetArrayRead \
95*d7b241e6Sjeremylt     FORTRAN_NAME(ceedvectorgetarrayread,CEEDVECTORGETARRAYREAD)
96*d7b241e6Sjeremylt //TODO Need Fixing, double pointer
97*d7b241e6Sjeremylt void fCeedVectorGetArrayRead(int *vec, int *memtype, CeedScalar *array,
98*d7b241e6Sjeremylt                              int *err) {
99*d7b241e6Sjeremylt   const CeedScalar *b;
100*d7b241e6Sjeremylt   *err = CeedVectorGetArrayRead(CeedVector_dict[*vec], *memtype, &b);
101*d7b241e6Sjeremylt   CeedVector vec_ = CeedVector_dict[*vec];
102*d7b241e6Sjeremylt   if (*err == 0)
103*d7b241e6Sjeremylt     memcpy(array, b, sizeof(CeedScalar)*vec_->length);
104*d7b241e6Sjeremylt }
105*d7b241e6Sjeremylt 
106*d7b241e6Sjeremylt #define fCeedVectorRestoreArray \
107*d7b241e6Sjeremylt     FORTRAN_NAME(ceedvectorrestorearray,CEEDVECTORRESTOREARRAY)
108*d7b241e6Sjeremylt void fCeedVectorRestoreArray(int *vec, CeedScalar *array, int *err) {
109*d7b241e6Sjeremylt   *err = CeedVectorRestoreArray(CeedVector_dict[*vec], &array);
110*d7b241e6Sjeremylt }
111*d7b241e6Sjeremylt 
112*d7b241e6Sjeremylt #define fCeedVectorRestoreArrayRead \
113*d7b241e6Sjeremylt     FORTRAN_NAME(ceedvectorrestorearrayread,CEEDVECTORRESTOREARRAYREAD)
114*d7b241e6Sjeremylt void fCeedVectorRestoreArrayRead(int *vec, const CeedScalar *array, int *err) {
115*d7b241e6Sjeremylt   *err = CeedVectorRestoreArrayRead(CeedVector_dict[*vec], &array);
116*d7b241e6Sjeremylt }
117*d7b241e6Sjeremylt 
118*d7b241e6Sjeremylt #define fCeedVectorView FORTRAN_NAME(ceedvectorview,CEEDVECTORVIEW)
119*d7b241e6Sjeremylt void fCeedVectorView(int *vec, int *err) {
120*d7b241e6Sjeremylt   *err = CeedVectorView(CeedVector_dict[*vec], "%12.8f", stdout);
121*d7b241e6Sjeremylt }
122*d7b241e6Sjeremylt 
123*d7b241e6Sjeremylt #define fCeedVectorDestroy FORTRAN_NAME(ceedvectordestroy,CEEDVECTORDESTROY)
124*d7b241e6Sjeremylt void fCeedVectorDestroy(int *vec, int *err) {
125*d7b241e6Sjeremylt   *err = CeedVectorDestroy(&CeedVector_dict[*vec]);
126*d7b241e6Sjeremylt 
127*d7b241e6Sjeremylt   if (*err == 0) {
128*d7b241e6Sjeremylt     CeedVector_n--;
129*d7b241e6Sjeremylt     if (CeedVector_n == 0) {
130*d7b241e6Sjeremylt       CeedFree(&CeedVector_dict);
131*d7b241e6Sjeremylt       CeedVector_count = 0;
132*d7b241e6Sjeremylt       CeedVector_count_max = 0;
133*d7b241e6Sjeremylt     }
134*d7b241e6Sjeremylt   }
135*d7b241e6Sjeremylt }
136*d7b241e6Sjeremylt 
137*d7b241e6Sjeremylt static CeedElemRestriction *CeedElemRestriction_dict = NULL;
138*d7b241e6Sjeremylt static int CeedElemRestriction_count = 0;
139*d7b241e6Sjeremylt static int CeedElemRestriction_n = 0;
140*d7b241e6Sjeremylt static int CeedElemRestriction_count_max = 0;
141*d7b241e6Sjeremylt 
142*d7b241e6Sjeremylt #define fCeedElemRestrictionCreate \
143*d7b241e6Sjeremylt     FORTRAN_NAME(ceedelemrestrictioncreate, CEEDELEMRESTRICTIONCREATE)
144*d7b241e6Sjeremylt void fCeedElemRestrictionCreate(int *ceed, int *nelements,
145*d7b241e6Sjeremylt                                 int *esize, int *ndof, int *ncomp, int *memtype, int *copymode,
146*d7b241e6Sjeremylt                                 const int *indices, int *elemrestriction, int *err) {
147*d7b241e6Sjeremylt   if (CeedElemRestriction_count == CeedElemRestriction_count_max) {
148*d7b241e6Sjeremylt     CeedElemRestriction_count_max += CeedElemRestriction_count_max/2 + 1;
149*d7b241e6Sjeremylt     CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict);
150*d7b241e6Sjeremylt   }
151*d7b241e6Sjeremylt 
152*d7b241e6Sjeremylt   const int *indices_ = indices;
153*d7b241e6Sjeremylt 
154*d7b241e6Sjeremylt   CeedElemRestriction *elemrestriction_ =
155*d7b241e6Sjeremylt     &CeedElemRestriction_dict[CeedElemRestriction_count];
156*d7b241e6Sjeremylt   *err = CeedElemRestrictionCreate(Ceed_dict[*ceed], *nelements, *esize, *ndof,
157*d7b241e6Sjeremylt                                    *ncomp,
158*d7b241e6Sjeremylt                                    *memtype, *copymode, indices_, elemrestriction_);
159*d7b241e6Sjeremylt 
160*d7b241e6Sjeremylt   if (*err == 0) {
161*d7b241e6Sjeremylt     *elemrestriction = CeedElemRestriction_count++;
162*d7b241e6Sjeremylt     CeedElemRestriction_n++;
163*d7b241e6Sjeremylt   }
164*d7b241e6Sjeremylt }
165*d7b241e6Sjeremylt 
166*d7b241e6Sjeremylt #define fCeedElemRestrictionCreateIdentity \
167*d7b241e6Sjeremylt     FORTRAN_NAME(ceedelemrestrictioncreateidentity, CEEDELEMRESTRICTIONCREATEIDENTITY)
168*d7b241e6Sjeremylt void fCeedElemRestrictionCreateIdentity(int *ceed, int *nelements,
169*d7b241e6Sjeremylt                                 int *esize, int *ndof, int *ncomp,
170*d7b241e6Sjeremylt                                 int *elemrestriction, int *err) {
171*d7b241e6Sjeremylt   if (CeedElemRestriction_count == CeedElemRestriction_count_max) {
172*d7b241e6Sjeremylt     CeedElemRestriction_count_max += CeedElemRestriction_count_max/2 + 1;
173*d7b241e6Sjeremylt     CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict);
174*d7b241e6Sjeremylt   }
175*d7b241e6Sjeremylt 
176*d7b241e6Sjeremylt   CeedElemRestriction *elemrestriction_ =
177*d7b241e6Sjeremylt     &CeedElemRestriction_dict[CeedElemRestriction_count];
178*d7b241e6Sjeremylt   *err = CeedElemRestrictionCreateIdentity(Ceed_dict[*ceed], *nelements, *esize, *ndof,
179*d7b241e6Sjeremylt                                    *ncomp, elemrestriction_);
180*d7b241e6Sjeremylt 
181*d7b241e6Sjeremylt   if (*err == 0) {
182*d7b241e6Sjeremylt     *elemrestriction = CeedElemRestriction_count++;
183*d7b241e6Sjeremylt     CeedElemRestriction_n++;
184*d7b241e6Sjeremylt   }
185*d7b241e6Sjeremylt }
186*d7b241e6Sjeremylt 
187*d7b241e6Sjeremylt #define fCeedElemRestrictionCreateBlocked \
188*d7b241e6Sjeremylt     FORTRAN_NAME(ceedelemrestrictioncreateblocked,CEEDELEMRESTRICTIONCREATEBLOCKED)
189*d7b241e6Sjeremylt void fCeedElemRestrictionCreateBlocked(int *ceed, int *nelements,
190*d7b241e6Sjeremylt                                        int *esize, int *blocksize, int *ndof, int *ncomp,
191*d7b241e6Sjeremylt                                        int *mtype, int *cmode,
192*d7b241e6Sjeremylt                                        int *blkindices, int *elemrestriction, int *err) {
193*d7b241e6Sjeremylt 
194*d7b241e6Sjeremylt   if (CeedElemRestriction_count == CeedElemRestriction_count_max) {
195*d7b241e6Sjeremylt     CeedElemRestriction_count_max += CeedElemRestriction_count_max/2 + 1;
196*d7b241e6Sjeremylt     CeedRealloc(CeedElemRestriction_count_max, &CeedElemRestriction_dict);
197*d7b241e6Sjeremylt   }
198*d7b241e6Sjeremylt 
199*d7b241e6Sjeremylt   CeedElemRestriction *elemrestriction_ =
200*d7b241e6Sjeremylt     &CeedElemRestriction_dict[CeedElemRestriction_count];
201*d7b241e6Sjeremylt   *err = CeedElemRestrictionCreateBlocked(Ceed_dict[*ceed], *nelements, *esize,
202*d7b241e6Sjeremylt                                           *blocksize, *ndof, *ncomp, *mtype, *cmode, blkindices,
203*d7b241e6Sjeremylt                                           elemrestriction_);
204*d7b241e6Sjeremylt 
205*d7b241e6Sjeremylt   if (*err == 0) {
206*d7b241e6Sjeremylt     *elemrestriction = CeedElemRestriction_count++;
207*d7b241e6Sjeremylt     CeedElemRestriction_n++;
208*d7b241e6Sjeremylt   }
209*d7b241e6Sjeremylt }
210*d7b241e6Sjeremylt 
211*d7b241e6Sjeremylt static CeedRequest *CeedRequest_dict = NULL;
212*d7b241e6Sjeremylt static int CeedRequest_count = 0;
213*d7b241e6Sjeremylt static int CeedRequest_n = 0;
214*d7b241e6Sjeremylt static int CeedRequest_count_max = 0;
215*d7b241e6Sjeremylt 
216*d7b241e6Sjeremylt #define fCeedElemRestrictionApply \
217*d7b241e6Sjeremylt     FORTRAN_NAME(ceedelemrestrictionapply,CEEDELEMRESTRICTIONAPPLY)
218*d7b241e6Sjeremylt void fCeedElemRestrictionApply(int *elemr, int *tmode, int *lmode,
219*d7b241e6Sjeremylt                                int *uvec, int *ruvec, int *rqst, int *err) {
220*d7b241e6Sjeremylt   int createRequest = 1;
221*d7b241e6Sjeremylt   // Check if input is CEED_REQUEST_ORDERED(-2) or CEED_REQUEST_IMMEDIATE(-1)
222*d7b241e6Sjeremylt   if (*rqst == FORTRAN_REQUEST_IMMEDIATE || *rqst == FORTRAN_REQUEST_ORDERED)
223*d7b241e6Sjeremylt     createRequest = 0;
224*d7b241e6Sjeremylt 
225*d7b241e6Sjeremylt   if (createRequest && CeedRequest_count == CeedRequest_count_max) {
226*d7b241e6Sjeremylt     CeedRequest_count_max += CeedRequest_count_max/2 + 1;
227*d7b241e6Sjeremylt     CeedRealloc(CeedRequest_count_max, &CeedRequest_dict);
228*d7b241e6Sjeremylt   }
229*d7b241e6Sjeremylt 
230*d7b241e6Sjeremylt   CeedRequest *rqst_;
231*d7b241e6Sjeremylt   if      (*rqst == FORTRAN_REQUEST_IMMEDIATE) rqst_ = CEED_REQUEST_IMMEDIATE;
232*d7b241e6Sjeremylt   else if (*rqst == FORTRAN_REQUEST_ORDERED  ) rqst_ = CEED_REQUEST_ORDERED;
233*d7b241e6Sjeremylt   else rqst_ = &CeedRequest_dict[CeedRequest_count];
234*d7b241e6Sjeremylt 
235*d7b241e6Sjeremylt   *err = CeedElemRestrictionApply(CeedElemRestriction_dict[*elemr], *tmode,
236*d7b241e6Sjeremylt                                   *lmode, CeedVector_dict[*uvec], CeedVector_dict[*ruvec], rqst_);
237*d7b241e6Sjeremylt 
238*d7b241e6Sjeremylt   if (*err == 0 && createRequest) {
239*d7b241e6Sjeremylt     *rqst = CeedRequest_count++;
240*d7b241e6Sjeremylt     CeedRequest_n++;
241*d7b241e6Sjeremylt   }
242*d7b241e6Sjeremylt }
243*d7b241e6Sjeremylt 
244*d7b241e6Sjeremylt #define fCeedRequestWait FORTRAN_NAME(ceedrequestwait, CEEDREQUESTWAIT)
245*d7b241e6Sjeremylt void fCeedRequestWait(int *rqst, int *err) {
246*d7b241e6Sjeremylt   // TODO Uncomment this once CeedRequestWait is implemented
247*d7b241e6Sjeremylt   //*err = CeedRequestWait(&CeedRequest_dict[*rqst]);
248*d7b241e6Sjeremylt 
249*d7b241e6Sjeremylt   if (*err == 0) {
250*d7b241e6Sjeremylt     CeedRequest_n--;
251*d7b241e6Sjeremylt     if (CeedRequest_n == 0) {
252*d7b241e6Sjeremylt       CeedFree(&CeedRequest_dict);
253*d7b241e6Sjeremylt       CeedRequest_count = 0;
254*d7b241e6Sjeremylt       CeedRequest_count_max = 0;
255*d7b241e6Sjeremylt     }
256*d7b241e6Sjeremylt   }
257*d7b241e6Sjeremylt }
258*d7b241e6Sjeremylt 
259*d7b241e6Sjeremylt #define fCeedElemRestrictionDestroy \
260*d7b241e6Sjeremylt     FORTRAN_NAME(ceedelemrestrictiondestroy,CEEDELEMRESTRICTIONDESTROY)
261*d7b241e6Sjeremylt void fCeedElemRestrictionDestroy(int *elem, int *err) {
262*d7b241e6Sjeremylt   *err = CeedElemRestrictionDestroy(&CeedElemRestriction_dict[*elem]);
263*d7b241e6Sjeremylt 
264*d7b241e6Sjeremylt   if (*err == 0) {
265*d7b241e6Sjeremylt     CeedElemRestriction_n--;
266*d7b241e6Sjeremylt     if (CeedElemRestriction_n == 0) {
267*d7b241e6Sjeremylt       CeedFree(&CeedElemRestriction_dict);
268*d7b241e6Sjeremylt       CeedElemRestriction_count = 0;
269*d7b241e6Sjeremylt       CeedElemRestriction_count_max = 0;
270*d7b241e6Sjeremylt     }
271*d7b241e6Sjeremylt   }
272*d7b241e6Sjeremylt }
273*d7b241e6Sjeremylt 
274*d7b241e6Sjeremylt static CeedBasis *CeedBasis_dict = NULL;
275*d7b241e6Sjeremylt static int CeedBasis_count = 0;
276*d7b241e6Sjeremylt static int CeedBasis_n = 0;
277*d7b241e6Sjeremylt static int CeedBasis_count_max = 0;
278*d7b241e6Sjeremylt 
279*d7b241e6Sjeremylt #define fCeedBasisCreateTensorH1Lagrange \
280*d7b241e6Sjeremylt     FORTRAN_NAME(ceedbasiscreatetensorh1lagrange, CEEDBASISCREATETENSORH1LAGRANGE)
281*d7b241e6Sjeremylt void fCeedBasisCreateTensorH1Lagrange(int *ceed, int *dim,
282*d7b241e6Sjeremylt                                       int *ndof, int *P, int *Q, int *quadmode, int *basis,
283*d7b241e6Sjeremylt                                       int *err) {
284*d7b241e6Sjeremylt   if (CeedBasis_count == CeedBasis_count_max) {
285*d7b241e6Sjeremylt     CeedBasis_count_max += CeedBasis_count_max/2 + 1;
286*d7b241e6Sjeremylt     CeedRealloc(CeedBasis_count_max, &CeedBasis_dict);
287*d7b241e6Sjeremylt   }
288*d7b241e6Sjeremylt 
289*d7b241e6Sjeremylt   *err = CeedBasisCreateTensorH1Lagrange(Ceed_dict[*ceed], *dim, *ndof, *P, *Q,
290*d7b241e6Sjeremylt                                          *quadmode, &CeedBasis_dict[CeedBasis_count]);
291*d7b241e6Sjeremylt 
292*d7b241e6Sjeremylt   if (*err == 0) {
293*d7b241e6Sjeremylt     *basis = CeedBasis_count++;
294*d7b241e6Sjeremylt     CeedBasis_n++;
295*d7b241e6Sjeremylt   }
296*d7b241e6Sjeremylt }
297*d7b241e6Sjeremylt 
298*d7b241e6Sjeremylt #define fCeedBasisCreateTensorH1 \
299*d7b241e6Sjeremylt     FORTRAN_NAME(ceedbasiscreatetensorh1, CEEDBASISCREATETENSORH1)
300*d7b241e6Sjeremylt void fCeedBasisCreateTensorH1(int *ceed, int *dim, int *ndof, int *P1d,
301*d7b241e6Sjeremylt                               int *Q1d, const CeedScalar *interp1d, const CeedScalar *grad1d,
302*d7b241e6Sjeremylt                               const CeedScalar *qref1d, const CeedScalar *qweight1d, int *basis, int *err) {
303*d7b241e6Sjeremylt   if (CeedBasis_count == CeedBasis_count_max) {
304*d7b241e6Sjeremylt     CeedBasis_count_max += CeedBasis_count_max/2 + 1;
305*d7b241e6Sjeremylt     CeedRealloc(CeedBasis_count_max, &CeedBasis_dict);
306*d7b241e6Sjeremylt   }
307*d7b241e6Sjeremylt 
308*d7b241e6Sjeremylt   *err = CeedBasisCreateTensorH1(Ceed_dict[*ceed], *dim, *ndof, *P1d, *Q1d,
309*d7b241e6Sjeremylt                                  interp1d, grad1d,
310*d7b241e6Sjeremylt                                  qref1d, qweight1d, &CeedBasis_dict[CeedBasis_count]);
311*d7b241e6Sjeremylt 
312*d7b241e6Sjeremylt   if (*err == 0) {
313*d7b241e6Sjeremylt     *basis = CeedBasis_count++;
314*d7b241e6Sjeremylt     CeedBasis_n++;
315*d7b241e6Sjeremylt   }
316*d7b241e6Sjeremylt }
317*d7b241e6Sjeremylt 
318*d7b241e6Sjeremylt #define fCeedBasisView FORTRAN_NAME(ceedbasisview, CEEDBASISVIEW)
319*d7b241e6Sjeremylt void fCeedBasisView(int *basis, int *err) {
320*d7b241e6Sjeremylt   *err = CeedBasisView(CeedBasis_dict[*basis], stdout);
321*d7b241e6Sjeremylt }
322*d7b241e6Sjeremylt 
323*d7b241e6Sjeremylt #define fCeedQRFactorization \
324*d7b241e6Sjeremylt     FORTRAN_NAME(ceedqrfactorization, CEEDQRFACTORIZATION)
325*d7b241e6Sjeremylt void fCeedQRFactorization(CeedScalar *mat, CeedScalar *tau, int *m, int *n,
326*d7b241e6Sjeremylt                           int *err) {
327*d7b241e6Sjeremylt   *err = CeedQRFactorization(mat, tau, *m, *n);
328*d7b241e6Sjeremylt }
329*d7b241e6Sjeremylt 
330*d7b241e6Sjeremylt #define fCeedBasisGetColocatedGrad \
331*d7b241e6Sjeremylt     FORTRAN_NAME(ceedbasisgetcolocatedgrad, CEEDBASISGETCOLOCATEDGRAD)
332*d7b241e6Sjeremylt void fCeedBasisGetColocatedGrad(int *basis, CeedScalar *colograd1d,
333*d7b241e6Sjeremylt                                 int *err) {
334*d7b241e6Sjeremylt   *err = CeedBasisGetColocatedGrad(CeedBasis_dict[*basis], colograd1d);
335*d7b241e6Sjeremylt }
336*d7b241e6Sjeremylt 
337*d7b241e6Sjeremylt #define fCeedBasisApply FORTRAN_NAME(ceedbasisapply, CEEDBASISAPPLY)
338*d7b241e6Sjeremylt void fCeedBasisApply(int *basis, int *nelem, int *tmode, int *emode,
339*d7b241e6Sjeremylt                      const CeedScalar *u, CeedScalar *v, int *err) {
340*d7b241e6Sjeremylt   *err = CeedBasisApply(CeedBasis_dict[*basis], *nelem, *tmode, *emode, u, v);
341*d7b241e6Sjeremylt }
342*d7b241e6Sjeremylt 
343*d7b241e6Sjeremylt #define fCeedBasisGetNumNodes \
344*d7b241e6Sjeremylt     FORTRAN_NAME(ceedbasisgetnumnodes, CEEDBASISGETNUMNODES)
345*d7b241e6Sjeremylt void fCeedBasisGetNumNodes(int *basis, int *P, int *err) {
346*d7b241e6Sjeremylt   *err = CeedBasisGetNumNodes(CeedBasis_dict[*basis], P);
347*d7b241e6Sjeremylt }
348*d7b241e6Sjeremylt 
349*d7b241e6Sjeremylt #define fCeedBasisGetNumQuadraturePoints \
350*d7b241e6Sjeremylt     FORTRAN_NAME(ceedbasisgetnumquadraturepoints, CEEDBASISGETNUMQUADRATUREPOINTS)
351*d7b241e6Sjeremylt void fCeedBasisGetNumQuadraturePoints(int *basis, int *Q, int *err) {
352*d7b241e6Sjeremylt   *err = CeedBasisGetNumQuadraturePoints(CeedBasis_dict[*basis], Q);
353*d7b241e6Sjeremylt }
354*d7b241e6Sjeremylt 
355*d7b241e6Sjeremylt #define fCeedBasisDestroy FORTRAN_NAME(ceedbasisdestroy,CEEDBASISDESTROY)
356*d7b241e6Sjeremylt void fCeedBasisDestroy(int *basis, int *err) {
357*d7b241e6Sjeremylt   *err = CeedBasisDestroy(&CeedBasis_dict[*basis]);
358*d7b241e6Sjeremylt 
359*d7b241e6Sjeremylt   if (*err == 0) {
360*d7b241e6Sjeremylt     CeedBasis_n--;
361*d7b241e6Sjeremylt     if (CeedBasis_n == 0) {
362*d7b241e6Sjeremylt       CeedFree(&CeedBasis_dict);
363*d7b241e6Sjeremylt       CeedBasis_count = 0;
364*d7b241e6Sjeremylt       CeedBasis_count_max = 0;
365*d7b241e6Sjeremylt     }
366*d7b241e6Sjeremylt   }
367*d7b241e6Sjeremylt }
368*d7b241e6Sjeremylt 
369*d7b241e6Sjeremylt #define fCeedGaussQuadrature FORTRAN_NAME(ceedgaussquadrature, CEEDGAUSSQUADRATURE)
370*d7b241e6Sjeremylt void fCeedGaussQuadrature(int *Q, CeedScalar *qref1d, CeedScalar *qweight1d,
371*d7b241e6Sjeremylt                           int *err) {
372*d7b241e6Sjeremylt   *err = CeedGaussQuadrature(*Q, qref1d, qweight1d);
373*d7b241e6Sjeremylt }
374*d7b241e6Sjeremylt 
375*d7b241e6Sjeremylt #define fCeedLobattoQuadrature \
376*d7b241e6Sjeremylt     FORTRAN_NAME(ceedlobattoquadrature, CEEDLOBATTOQUADRATURE)
377*d7b241e6Sjeremylt void fCeedLobattoQuadrature(int *Q, CeedScalar *qref1d, CeedScalar *qweight1d,
378*d7b241e6Sjeremylt                             int *err) {
379*d7b241e6Sjeremylt   *err = CeedLobattoQuadrature(*Q, qref1d, qweight1d);
380*d7b241e6Sjeremylt }
381*d7b241e6Sjeremylt 
382*d7b241e6Sjeremylt static CeedQFunction *CeedQFunction_dict = NULL;
383*d7b241e6Sjeremylt static int CeedQFunction_count = 0;
384*d7b241e6Sjeremylt static int CeedQFunction_n = 0;
385*d7b241e6Sjeremylt static int CeedQFunction_count_max = 0;
386*d7b241e6Sjeremylt 
387*d7b241e6Sjeremylt struct fContext {
388*d7b241e6Sjeremylt   void (*f)(void *ctx, int *nq,
389*d7b241e6Sjeremylt             const CeedScalar *u,const CeedScalar *u1,const CeedScalar *u2,
390*d7b241e6Sjeremylt             const CeedScalar *u3,
391*d7b241e6Sjeremylt             const CeedScalar *u4,const CeedScalar *u5,const CeedScalar *u6,
392*d7b241e6Sjeremylt             const CeedScalar *u7,
393*d7b241e6Sjeremylt             const CeedScalar *u8,const CeedScalar *u9,const CeedScalar *u10,
394*d7b241e6Sjeremylt             const CeedScalar *u11,
395*d7b241e6Sjeremylt             const CeedScalar *u12,const CeedScalar *u13,const CeedScalar *u14,
396*d7b241e6Sjeremylt             const CeedScalar *u15,
397*d7b241e6Sjeremylt             CeedScalar *v,CeedScalar *v1, CeedScalar *v2,CeedScalar *v3,
398*d7b241e6Sjeremylt             CeedScalar *v4,CeedScalar *v5, CeedScalar *v6,CeedScalar *v7,
399*d7b241e6Sjeremylt             CeedScalar *v8,CeedScalar *v9, CeedScalar *v10,CeedScalar *v11,
400*d7b241e6Sjeremylt             CeedScalar *v12,CeedScalar *v13, CeedScalar *v14,CeedScalar *v15, int *err);
401*d7b241e6Sjeremylt   void *innerctx;
402*d7b241e6Sjeremylt };
403*d7b241e6Sjeremylt 
404*d7b241e6Sjeremylt static int CeedQFunctionFortranStub(void *ctx, int nq,
405*d7b241e6Sjeremylt                                     const CeedScalar *const *u, CeedScalar *const *v) {
406*d7b241e6Sjeremylt   struct fContext *fctx = ctx;
407*d7b241e6Sjeremylt   int ierr;
408*d7b241e6Sjeremylt 
409*d7b241e6Sjeremylt   CeedScalar ctx_=1.0;
410*d7b241e6Sjeremylt   fctx->f((void*)&ctx_,&nq,u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],
411*d7b241e6Sjeremylt           u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15],
412*d7b241e6Sjeremylt           v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],
413*d7b241e6Sjeremylt           v[8],v[9],v[10],v[11],v[12],v[13],v[14],v[15],&ierr);
414*d7b241e6Sjeremylt   return ierr;
415*d7b241e6Sjeremylt }
416*d7b241e6Sjeremylt 
417*d7b241e6Sjeremylt #define fCeedQFunctionCreateInterior \
418*d7b241e6Sjeremylt     FORTRAN_NAME(ceedqfunctioncreateinterior, CEEDQFUNCTIONCREATEINTERIOR)
419*d7b241e6Sjeremylt void fCeedQFunctionCreateInterior(int* ceed, int* vlength,
420*d7b241e6Sjeremylt                                   void (*f)(void *ctx, int *nq,
421*d7b241e6Sjeremylt                                       const CeedScalar *u,const CeedScalar *u1,const CeedScalar *u2,
422*d7b241e6Sjeremylt                                       const CeedScalar *u3,
423*d7b241e6Sjeremylt                                       const CeedScalar *u4,const CeedScalar *u5,const CeedScalar *u6,
424*d7b241e6Sjeremylt                                       const CeedScalar *u7,
425*d7b241e6Sjeremylt                                       const CeedScalar *u8,const CeedScalar *u9,const CeedScalar *u10,
426*d7b241e6Sjeremylt                                       const CeedScalar *u11,
427*d7b241e6Sjeremylt                                       const CeedScalar *u12,const CeedScalar *u13,const CeedScalar *u14,
428*d7b241e6Sjeremylt                                       const CeedScalar *u15,
429*d7b241e6Sjeremylt                                       CeedScalar *v,CeedScalar *v1, CeedScalar *v2,CeedScalar *v3,
430*d7b241e6Sjeremylt                                       CeedScalar *v4,CeedScalar *v5, CeedScalar *v6,CeedScalar *v7,
431*d7b241e6Sjeremylt                                       CeedScalar *v8,CeedScalar *v9, CeedScalar *v10,CeedScalar *v11,
432*d7b241e6Sjeremylt                                       CeedScalar *v12,CeedScalar *v13, CeedScalar *v14,CeedScalar *v15,
433*d7b241e6Sjeremylt                                       int *err),
434*d7b241e6Sjeremylt                                   const char *focca, int *qf, int *err) {
435*d7b241e6Sjeremylt   if (CeedQFunction_count == CeedQFunction_count_max) {
436*d7b241e6Sjeremylt     CeedQFunction_count_max += CeedQFunction_count_max/2 + 1;
437*d7b241e6Sjeremylt     CeedRealloc(CeedQFunction_count_max, &CeedQFunction_dict);
438*d7b241e6Sjeremylt   }
439*d7b241e6Sjeremylt 
440*d7b241e6Sjeremylt   CeedQFunction *qf_ = &CeedQFunction_dict[CeedQFunction_count];
441*d7b241e6Sjeremylt   *err = CeedQFunctionCreateInterior(Ceed_dict[*ceed], *vlength,
442*d7b241e6Sjeremylt                                      CeedQFunctionFortranStub,focca, qf_);
443*d7b241e6Sjeremylt 
444*d7b241e6Sjeremylt   if (*err == 0) {
445*d7b241e6Sjeremylt     *qf = CeedQFunction_count++;
446*d7b241e6Sjeremylt     CeedQFunction_n++;
447*d7b241e6Sjeremylt   }
448*d7b241e6Sjeremylt 
449*d7b241e6Sjeremylt   struct fContext *fctx;
450*d7b241e6Sjeremylt   *err = CeedMalloc(1, &fctx);
451*d7b241e6Sjeremylt   if (*err) return;
452*d7b241e6Sjeremylt   fctx->f = f; fctx->innerctx = NULL;
453*d7b241e6Sjeremylt 
454*d7b241e6Sjeremylt   *err = CeedQFunctionSetContext(*qf_, fctx, sizeof(struct fContext));
455*d7b241e6Sjeremylt 
456*d7b241e6Sjeremylt }
457*d7b241e6Sjeremylt 
458*d7b241e6Sjeremylt #define fCeedQFunctionAddInput \
459*d7b241e6Sjeremylt     FORTRAN_NAME(ceedqfunctionaddinput,CEEDQFUNCTIONADDINPUT)
460*d7b241e6Sjeremylt void fCeedQFunctionAddInput(int *qf, const char *fieldname,
461*d7b241e6Sjeremylt                             CeedInt *ncomp, CeedEvalMode *emode, int *err) {
462*d7b241e6Sjeremylt   CeedQFunction qf_ = CeedQFunction_dict[*qf];
463*d7b241e6Sjeremylt 
464*d7b241e6Sjeremylt   *err = CeedQFunctionAddInput(qf_, fieldname, *ncomp, *emode);
465*d7b241e6Sjeremylt }
466*d7b241e6Sjeremylt 
467*d7b241e6Sjeremylt #define fCeedQFunctionAddOutput \
468*d7b241e6Sjeremylt     FORTRAN_NAME(ceedqfunctionaddoutput,CEEDQFUNCTIONADDOUTPUT)
469*d7b241e6Sjeremylt void fCeedQFunctionAddOutput(int *qf, const char *fieldname,
470*d7b241e6Sjeremylt                              CeedInt *ncomp, CeedEvalMode *emode, int *err) {
471*d7b241e6Sjeremylt   CeedQFunction qf_ = CeedQFunction_dict[*qf];
472*d7b241e6Sjeremylt 
473*d7b241e6Sjeremylt   *err = CeedQFunctionAddOutput(qf_, fieldname, *ncomp, *emode);
474*d7b241e6Sjeremylt }
475*d7b241e6Sjeremylt 
476*d7b241e6Sjeremylt #define fCeedQFunctionApply \
477*d7b241e6Sjeremylt     FORTRAN_NAME(ceedqfunctionapply,CEEDQFUNCTIONAPPLY)
478*d7b241e6Sjeremylt //TODO Need Fixing, double pointer
479*d7b241e6Sjeremylt void fCeedQFunctionApply(int *qf, int *Q,
480*d7b241e6Sjeremylt                          const CeedScalar *u,const CeedScalar *u1,const CeedScalar *u2,
481*d7b241e6Sjeremylt                          const CeedScalar *u3,
482*d7b241e6Sjeremylt                          const CeedScalar *u4,const CeedScalar *u5,const CeedScalar *u6,
483*d7b241e6Sjeremylt                          const CeedScalar *u7,
484*d7b241e6Sjeremylt                          const CeedScalar *u8,const CeedScalar *u9,const CeedScalar *u10,
485*d7b241e6Sjeremylt                          const CeedScalar *u11,
486*d7b241e6Sjeremylt                          const CeedScalar *u12,const CeedScalar *u13,const CeedScalar *u14,
487*d7b241e6Sjeremylt                          const CeedScalar *u15,
488*d7b241e6Sjeremylt                          CeedScalar *v,CeedScalar *v1, CeedScalar *v2,CeedScalar *v3,
489*d7b241e6Sjeremylt                          CeedScalar *v4,CeedScalar *v5, CeedScalar *v6,CeedScalar *v7,
490*d7b241e6Sjeremylt                          CeedScalar *v8,CeedScalar *v9, CeedScalar *v10,CeedScalar *v11,
491*d7b241e6Sjeremylt                          CeedScalar *v12,CeedScalar *v13, CeedScalar *v14,CeedScalar *v15, int *err) {
492*d7b241e6Sjeremylt   CeedQFunction qf_ = CeedQFunction_dict[*qf];
493*d7b241e6Sjeremylt   const CeedScalar **in;
494*d7b241e6Sjeremylt   *err = CeedCalloc(16, &in);
495*d7b241e6Sjeremylt   if (*err) return;
496*d7b241e6Sjeremylt   in[0] = u;
497*d7b241e6Sjeremylt   in[1] = u1;
498*d7b241e6Sjeremylt   in[2] = u2;
499*d7b241e6Sjeremylt   in[3] = u3;
500*d7b241e6Sjeremylt   in[4] = u4;
501*d7b241e6Sjeremylt   in[5] = u5;
502*d7b241e6Sjeremylt   in[6] = u6;
503*d7b241e6Sjeremylt   in[7] = u7;
504*d7b241e6Sjeremylt   in[8] = u8;
505*d7b241e6Sjeremylt   in[9] = u9;
506*d7b241e6Sjeremylt   in[10] = u10;
507*d7b241e6Sjeremylt   in[11] = u11;
508*d7b241e6Sjeremylt   in[12] = u12;
509*d7b241e6Sjeremylt   in[13] = u13;
510*d7b241e6Sjeremylt   in[14] = u14;
511*d7b241e6Sjeremylt   in[15] = u15;
512*d7b241e6Sjeremylt   CeedScalar **out;
513*d7b241e6Sjeremylt   *err = CeedCalloc(16, &out);
514*d7b241e6Sjeremylt   if (*err) return;
515*d7b241e6Sjeremylt   out[0] = v;
516*d7b241e6Sjeremylt   out[1] = v1;
517*d7b241e6Sjeremylt   out[2] = v2;
518*d7b241e6Sjeremylt   out[3] = v3;
519*d7b241e6Sjeremylt   out[4] = v4;
520*d7b241e6Sjeremylt   out[5] = v5;
521*d7b241e6Sjeremylt   out[6] = v6;
522*d7b241e6Sjeremylt   out[7] = v7;
523*d7b241e6Sjeremylt   out[8] = v8;
524*d7b241e6Sjeremylt   out[9] = v9;
525*d7b241e6Sjeremylt   out[10] = v10;
526*d7b241e6Sjeremylt   out[11] = v11;
527*d7b241e6Sjeremylt   out[12] = v12;
528*d7b241e6Sjeremylt   out[13] = v13;
529*d7b241e6Sjeremylt   out[14] = v14;
530*d7b241e6Sjeremylt   out[15] = v15;
531*d7b241e6Sjeremylt   *err = CeedQFunctionApply(qf_, *Q, (const CeedScalar * const*)in, out);
532*d7b241e6Sjeremylt   if (*err) return;
533*d7b241e6Sjeremylt 
534*d7b241e6Sjeremylt   *err = CeedFree(&in);
535*d7b241e6Sjeremylt   if (*err) return;
536*d7b241e6Sjeremylt   *err = CeedFree(&out);
537*d7b241e6Sjeremylt }
538*d7b241e6Sjeremylt 
539*d7b241e6Sjeremylt #define fCeedQFunctionDestroy \
540*d7b241e6Sjeremylt     FORTRAN_NAME(ceedqfunctiondestroy,CEEDQFUNCTIONDESTROY)
541*d7b241e6Sjeremylt void fCeedQFunctionDestroy(int *qf, int *err) {
542*d7b241e6Sjeremylt   CeedFree(&CeedQFunction_dict[*qf]->ctx);
543*d7b241e6Sjeremylt   *err = CeedQFunctionDestroy(&CeedQFunction_dict[*qf]);
544*d7b241e6Sjeremylt 
545*d7b241e6Sjeremylt   if (*err) return;
546*d7b241e6Sjeremylt   CeedQFunction_n--;
547*d7b241e6Sjeremylt   if (CeedQFunction_n == 0) {
548*d7b241e6Sjeremylt     *err = CeedFree(&CeedQFunction_dict);
549*d7b241e6Sjeremylt     CeedQFunction_count = 0;
550*d7b241e6Sjeremylt     CeedQFunction_count_max = 0;
551*d7b241e6Sjeremylt   }
552*d7b241e6Sjeremylt }
553*d7b241e6Sjeremylt 
554*d7b241e6Sjeremylt static CeedOperator *CeedOperator_dict = NULL;
555*d7b241e6Sjeremylt static int CeedOperator_count = 0;
556*d7b241e6Sjeremylt static int CeedOperator_n = 0;
557*d7b241e6Sjeremylt static int CeedOperator_count_max = 0;
558*d7b241e6Sjeremylt 
559*d7b241e6Sjeremylt #define fCeedOperatorCreate \
560*d7b241e6Sjeremylt     FORTRAN_NAME(ceedoperatorcreate, CEEDOPERATORCREATE)
561*d7b241e6Sjeremylt void fCeedOperatorCreate(int* ceed,
562*d7b241e6Sjeremylt                          int* qf, int* dqf, int* dqfT, int *op, int *err) {
563*d7b241e6Sjeremylt   if (CeedOperator_count == CeedOperator_count_max)
564*d7b241e6Sjeremylt     CeedOperator_count_max += CeedOperator_count_max/2 + 1,
565*d7b241e6Sjeremylt                               CeedOperator_dict =
566*d7b241e6Sjeremylt                                 realloc(CeedOperator_dict, sizeof(CeedOperator)*CeedOperator_count_max);
567*d7b241e6Sjeremylt 
568*d7b241e6Sjeremylt   CeedOperator *op_ = &CeedOperator_dict[CeedOperator_count];
569*d7b241e6Sjeremylt 
570*d7b241e6Sjeremylt   CeedQFunction dqf_  = NULL, dqfT_ = NULL;
571*d7b241e6Sjeremylt   if (*dqf  != FORTRAN_NULL) dqf_  = CeedQFunction_dict[*dqf ];
572*d7b241e6Sjeremylt   if (*dqfT != FORTRAN_NULL) dqfT_ = CeedQFunction_dict[*dqfT];
573*d7b241e6Sjeremylt 
574*d7b241e6Sjeremylt   *err = CeedOperatorCreate(Ceed_dict[*ceed], CeedQFunction_dict[*qf], dqf_,
575*d7b241e6Sjeremylt                             dqfT_, op_);
576*d7b241e6Sjeremylt   if (*err) return;
577*d7b241e6Sjeremylt   *op = CeedOperator_count++;
578*d7b241e6Sjeremylt   CeedOperator_n++;
579*d7b241e6Sjeremylt }
580*d7b241e6Sjeremylt 
581*d7b241e6Sjeremylt #define fCeedOperatorSetField \
582*d7b241e6Sjeremylt     FORTRAN_NAME(ceedoperatorsetfield,CEEDOPERATORSETFIELD)
583*d7b241e6Sjeremylt void fCeedOperatorSetField(int *op, const char *fieldname,
584*d7b241e6Sjeremylt                            int *r, int *b, int *v, int *err) {
585*d7b241e6Sjeremylt   CeedElemRestriction r_;
586*d7b241e6Sjeremylt   CeedBasis b_;
587*d7b241e6Sjeremylt   CeedVector v_;
588*d7b241e6Sjeremylt 
589*d7b241e6Sjeremylt   CeedOperator op_ = CeedOperator_dict[*op];
590*d7b241e6Sjeremylt 
591*d7b241e6Sjeremylt   if (*r == FORTRAN_NULL) {
592*d7b241e6Sjeremylt     r_ = NULL;
593*d7b241e6Sjeremylt   } else {
594*d7b241e6Sjeremylt     r_ = CeedElemRestriction_dict[*r];
595*d7b241e6Sjeremylt   }
596*d7b241e6Sjeremylt   if (*b == FORTRAN_NULL) {
597*d7b241e6Sjeremylt     b_ = NULL;
598*d7b241e6Sjeremylt   } else if (*b == FORTRAN_BASIS_COLOCATED) {
599*d7b241e6Sjeremylt     b_ = CEED_BASIS_COLOCATED;
600*d7b241e6Sjeremylt   } else {
601*d7b241e6Sjeremylt     b_ = CeedBasis_dict[*b];
602*d7b241e6Sjeremylt   }
603*d7b241e6Sjeremylt   if (*v == FORTRAN_NULL) {
604*d7b241e6Sjeremylt     v_ = NULL;
605*d7b241e6Sjeremylt   } else if (*v == FORTRAN_VECTOR_ACTIVE) {
606*d7b241e6Sjeremylt     v_ = CEED_VECTOR_ACTIVE;
607*d7b241e6Sjeremylt   } else if (*v == FORTRAN_VECTOR_NONE) {
608*d7b241e6Sjeremylt     v_ = CEED_VECTOR_NONE;
609*d7b241e6Sjeremylt   } else {
610*d7b241e6Sjeremylt     v_ = CeedVector_dict[*v];
611*d7b241e6Sjeremylt   }
612*d7b241e6Sjeremylt 
613*d7b241e6Sjeremylt   *err = CeedOperatorSetField(op_, fieldname, r_, b_, v_);
614*d7b241e6Sjeremylt }
615*d7b241e6Sjeremylt 
616*d7b241e6Sjeremylt #define fCeedOperatorApply FORTRAN_NAME(ceedoperatorapply, CEEDOPERATORAPPLY)
617*d7b241e6Sjeremylt void fCeedOperatorApply(int *op, int *ustatevec,
618*d7b241e6Sjeremylt                         int *resvec, int *rqst, int *err) {
619*d7b241e6Sjeremylt   // TODO What vector arguments can be NULL?
620*d7b241e6Sjeremylt   CeedVector resvec_;
621*d7b241e6Sjeremylt   if (*resvec == FORTRAN_NULL) resvec_ = NULL;
622*d7b241e6Sjeremylt   else resvec_ = CeedVector_dict[*resvec];
623*d7b241e6Sjeremylt 
624*d7b241e6Sjeremylt   int createRequest = 1;
625*d7b241e6Sjeremylt   // Check if input is CEED_REQUEST_ORDERED(-2) or CEED_REQUEST_IMMEDIATE(-1)
626*d7b241e6Sjeremylt   if (*rqst == -1 || *rqst == -2) {
627*d7b241e6Sjeremylt     createRequest = 0;
628*d7b241e6Sjeremylt   }
629*d7b241e6Sjeremylt 
630*d7b241e6Sjeremylt   if (createRequest && CeedRequest_count == CeedRequest_count_max) {
631*d7b241e6Sjeremylt     CeedRequest_count_max += CeedRequest_count_max/2 + 1;
632*d7b241e6Sjeremylt     CeedRealloc(CeedRequest_count_max, &CeedRequest_dict);
633*d7b241e6Sjeremylt   }
634*d7b241e6Sjeremylt 
635*d7b241e6Sjeremylt   CeedRequest *rqst_;
636*d7b241e6Sjeremylt   if (*rqst == -1) rqst_ = CEED_REQUEST_IMMEDIATE;
637*d7b241e6Sjeremylt   else if (*rqst == -2) rqst_ = CEED_REQUEST_ORDERED;
638*d7b241e6Sjeremylt   else rqst_ = &CeedRequest_dict[CeedRequest_count];
639*d7b241e6Sjeremylt 
640*d7b241e6Sjeremylt   *err = CeedOperatorApply(CeedOperator_dict[*op],
641*d7b241e6Sjeremylt                            CeedVector_dict[*ustatevec], resvec_, rqst_);
642*d7b241e6Sjeremylt   if (*err) return;
643*d7b241e6Sjeremylt   if (createRequest) {
644*d7b241e6Sjeremylt     *rqst = CeedRequest_count++;
645*d7b241e6Sjeremylt     CeedRequest_n++;
646*d7b241e6Sjeremylt   }
647*d7b241e6Sjeremylt }
648*d7b241e6Sjeremylt 
649*d7b241e6Sjeremylt #define fCeedOperatorApplyJacobian \
650*d7b241e6Sjeremylt     FORTRAN_NAME(ceedoperatorapplyjacobian, CEEDOPERATORAPPLYJACOBIAN)
651*d7b241e6Sjeremylt void fCeedOperatorApplyJacobian(int *op, int *qdatavec, int *ustatevec,
652*d7b241e6Sjeremylt                                 int *dustatevec, int *dresvec, int *rqst, int *err) {
653*d7b241e6Sjeremylt // TODO Uncomment this when CeedOperatorApplyJacobian is implemented
654*d7b241e6Sjeremylt //  *err = CeedOperatorApplyJacobian(CeedOperator_dict[*op], CeedVector_dict[*qdatavec],
655*d7b241e6Sjeremylt //             CeedVector_dict[*ustatevec], CeedVector_dict[*dustatevec],
656*d7b241e6Sjeremylt //             CeedVector_dict[*dresvec], &CeedRequest_dict[*rqst]);
657*d7b241e6Sjeremylt }
658*d7b241e6Sjeremylt 
659*d7b241e6Sjeremylt #define fCeedOperatorDestroy \
660*d7b241e6Sjeremylt     FORTRAN_NAME(ceedoperatordestroy, CEEDOPERATORDESTROY)
661*d7b241e6Sjeremylt void fCeedOperatorDestroy(int *op, int *err) {
662*d7b241e6Sjeremylt   *err = CeedOperatorDestroy(&CeedOperator_dict[*op]);
663*d7b241e6Sjeremylt   if (*err) return;
664*d7b241e6Sjeremylt   CeedOperator_n--;
665*d7b241e6Sjeremylt   if (CeedOperator_n == 0) {
666*d7b241e6Sjeremylt     *err = CeedFree(&CeedOperator_dict);
667*d7b241e6Sjeremylt     CeedOperator_count = 0;
668*d7b241e6Sjeremylt     CeedOperator_count_max = 0;
669*d7b241e6Sjeremylt   }
670*d7b241e6Sjeremylt }
671