xref: /petsc/src/ts/interface/ftn-custom/ztsf.c (revision 487a658c8b32ba712a1dc8280daad2fd70c1dcd9)
1 #include <petsc/private/fortranimpl.h>
2 #include <petscts.h>
3 #include <petscviewer.h>
4 #include <petsc/private/f90impl.h>
5 
6 #if defined(PETSC_HAVE_FORTRAN_CAPS)
7 #define tsmonitorlgsettransform_             TSMONITORLGSETTRANSFORM
8 #define tssetrhsfunction_                    TSSETRHSFUNCTION
9 #define tsgetrhsfunction_                    TSGETRHSFUNCTION
10 #define tssetrhsjacobian_                    TSSETRHSJACOBIAN
11 #define tsgetrhsjacobian_                    TSGETRHSJACOBIAN
12 #define tssetifunction_                      TSSETIFUNCTION
13 #define tsgetifunction_                      TSGETIFUNCTION
14 #define tssetijacobian_                      TSSETIJACOBIAN
15 #define tsgetijacobian_                      TSGETIJACOBIAN
16 #define tsview_                              TSVIEW
17 #define tssetoptionsprefix_                  TSSETOPTIONSPREFIX
18 #define tsgetoptionsprefix_                  TSGETOPTIONSPREFIX
19 #define tsappendoptionsprefix_               TSAPPENDOPTIONSPREFIX
20 #define tsmonitorset_                        TSMONITORSET
21 #define tscomputerhsfunctionlinear_          TSCOMPUTERHSFUNCTIONLINEAR
22 #define tscomputerhsjacobianconstant_        TSCOMPUTERHSJACOBIANCONSTANT
23 #define tscomputeifunctionlinear_            TSCOMPUTEIFUNCTIONLINEAR
24 #define tscomputeijacobianconstant_          TSCOMPUTEIJACOBIANCONSTANT
25 #define tsmonitordefault_                    TSMONITORDEFAULT
26 #define tssetprestep_                        TSSETPRESTEP
27 #define tssetpoststep_                       TSSETPOSTSTEP
28 #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
29 #define tsmonitorlgsettransform_             tsmonitorlgsettransform
30 #define tssetrhsfunction_                    tssetrhsfunction
31 #define tsgetrhsfunction_                    tsgetrhsfunction
32 #define tssetrhsjacobian_                    tssetrhsjacobian
33 #define tsgetrhsjacobian_                    tsgetrhsjacobian
34 #define tssetifunction_                      tssetifunction
35 #define tsgetifunction_                      tsgetifunction
36 #define tssetijacobian_                      tssetijacobian
37 #define tsgetijacobian_                      tsgetijacobian
38 #define tsview_                              tsview
39 #define tssetoptionsprefix_                  tssetoptionsprefix
40 #define tsgetoptionsprefix_                  tsgetoptionsprefix
41 #define tsappendoptionsprefix_               tsappendoptionsprefix
42 #define tsmonitorset_                        tsmonitorset
43 #define tscomputerhsfunctionlinear_          tscomputerhsfunctionlinear
44 #define tscomputerhsjacobianconstant_        tscomputerhsjacobianconstant
45 #define tscomputeifunctionlinear_            tscomputeifunctionlinear
46 #define tscomputeijacobianconstant_          tscomputeijacobianconstant
47 #define tsmonitordefault_                    tsmonitordefault
48 #define tssetprestep_                        tssetprestep
49 #define tssetpoststep_                       tssetpoststep
50 #endif
51 
52 static struct {
53   PetscFortranCallbackId prestep;
54   PetscFortranCallbackId poststep;
55   PetscFortranCallbackId rhsfunction;
56   PetscFortranCallbackId rhsjacobian;
57   PetscFortranCallbackId ifunction;
58   PetscFortranCallbackId ijacobian;
59   PetscFortranCallbackId monitor;
60   PetscFortranCallbackId mondestroy;
61   PetscFortranCallbackId transform;
62 #if defined(PETSC_HAVE_F90_2PTR_ARG)
63   PetscFortranCallbackId function_pgiptr;
64 #endif
65 } _cb;
66 
67 static PetscErrorCode ourprestep(TS ts)
68 {
69 #if defined(PETSC_HAVE_F90_2PTR_ARG) && defined(foo)
70   void* ptr;
71   PetscObjectGetFortranCallback((PetscObject)ts,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
72 #endif
73   PetscObjectUseFortranCallback(ts,_cb.prestep,(TS*,PetscErrorCode* /* PETSC_F90_2PTR_PROTO_NOVAR */),(&ts,&ierr /* PETSC_F90_2PTR_PARAM(ptr) */));
74   return 0;
75 }
76 static PetscErrorCode ourpoststep(TS ts)
77 {
78 #if defined(PETSC_HAVE_F90_2PTR_ARG) && defined(foo)
79   void* ptr;
80   PetscObjectGetFortranCallback((PetscObject)ts,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
81 #endif
82   PetscObjectUseFortranCallback(ts,_cb.poststep,(TS*,PetscErrorCode* /* PETSC_F90_2PTR_PROTO_NOVAR */),(&ts,&ierr /* PETSC_F90_2PTR_PARAM(ptr) */));
83   return 0;
84 }
85 static PetscErrorCode ourrhsfunction(TS ts,PetscReal d,Vec x,Vec f,void *ctx)
86 {
87 #if defined(PETSC_HAVE_F90_2PTR_ARG) && defined(foo)
88   void* ptr;
89   PetscObjectGetFortranCallback((PetscObject)ts,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
90 #endif
91   PetscObjectUseFortranCallback(ts,_cb.rhsfunction,(TS*,PetscReal*,Vec*, Vec*, void*,PetscErrorCode* /* PETSC_F90_2PTR_PROTO_NOVAR */),(&ts,&d,&x,&f,_ctx,&ierr /* PETSC_F90_2PTR_PARAM(ptr) */));
92   return 0;
93 }
94 static PetscErrorCode ourifunction(TS ts,PetscReal d,Vec x,Vec xdot,Vec f,void *ctx)
95 {
96 #if defined(PETSC_HAVE_F90_2PTR_ARG) && defined(foo)
97   void* ptr;
98   PetscObjectGetFortranCallback((PetscObject)ts,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
99 #endif
100   PetscObjectUseFortranCallback(ts,_cb.ifunction,(TS*,PetscReal*,Vec*, Vec*, Vec*, void*,PetscErrorCode* /* PETSC_F90_2PTR_PROTO_NOVAR */),(&ts,&d,&x,&xdot,&f,_ctx,&ierr /* PETSC_F90_2PTR_PARAM(ptr) */));
101   return 0;
102 }
103 static PetscErrorCode ourrhsjacobian(TS ts,PetscReal d,Vec x,Mat m,Mat p,void *ctx)
104 {
105 #if defined(PETSC_HAVE_F90_2PTR_ARG) && defined(foo)
106   void* ptr;
107   PetscObjectGetFortranCallback((PetscObject)ts,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
108 #endif
109   PetscObjectUseFortranCallback(ts,_cb.rhsjacobian,(TS*,PetscReal*, Vec*, Mat*, Mat*, void*,PetscErrorCode* /* PETSC_F90_2PTR_PROTO_NOVAR */),(&ts,&d,&x,&m,&p,_ctx,&ierr /* PETSC_F90_2PTR_PARAM(ptr) */));
110   return 0;
111 }
112 static PetscErrorCode ourijacobian(TS ts,PetscReal d,Vec x,Vec xdot,PetscReal shift,Mat m,Mat p,void *ctx)
113 {
114 #if defined(PETSC_HAVE_F90_2PTR_ARG) && defined(foo)
115   void* ptr;
116   PetscObjectGetFortranCallback((PetscObject)ts,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
117 #endif
118   PetscObjectUseFortranCallback(ts,_cb.ijacobian,(TS*,PetscReal*,Vec*, Vec*, PetscReal *,Mat*, Mat*, void*,PetscErrorCode* /* PETSC_F90_2PTR_PROTO_NOVAR */),(&ts,&d,&x,&xdot,&shift,&m,&p,_ctx,&ierr /* PETSC_F90_2PTR_PARAM(ptr) */));
119   return 0;
120 }
121 
122 static PetscErrorCode ourmonitordestroy(void **ctx)
123 {
124   TS ts = (TS)*ctx;
125   PetscObjectUseFortranCallback(ts,_cb.mondestroy,(void*,PetscErrorCode*),(_ctx,&ierr));
126 }
127 
128 /*
129    Note ctx is the same as ts so we need to get the Fortran context out of the TS
130 */
131 static PetscErrorCode ourmonitor(TS ts,PetscInt i,PetscReal d,Vec v,void *ctx)
132 {
133   PetscObjectUseFortranCallback(ts,_cb.monitor,(TS*,PetscInt*,PetscReal*,Vec *,void*,PetscErrorCode*),(&ts,&i,&d,&v,_ctx,&ierr));
134   return 0;
135 }
136 
137 /*
138    Currently does not handle destroy or context
139 */
140 static PetscErrorCode ourtransform(void *ctx,Vec x,Vec *xout)
141 {
142   PetscObjectUseFortranCallback((TS)ctx,_cb.transform,(void*,Vec *,Vec *,PetscErrorCode*),(_ctx,&x,xout,&ierr));
143 }
144 
145 PETSC_EXTERN void PETSC_STDCALL tsmonitorlgsettransform_(TS *ts,void (PETSC_STDCALL*f)(void*,Vec*,Vec*,PetscErrorCode*),PetscErrorCode (PETSC_STDCALL*d)(void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr)
146 {
147   *ierr = TSMonitorLGSetTransform(*ts,ourtransform,NULL,NULL); if (*ierr) return;
148   *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.transform,(PetscVoidFunction)f,ctx);
149 }
150 
151 PETSC_EXTERN void PETSC_STDCALL tssetprestep_(TS *ts,PetscErrorCode (PETSC_STDCALL*f)(TS*,PetscErrorCode*),PetscErrorCode *ierr)
152 {
153   *ierr = TSSetPreStep(*ts,ourprestep);if (*ierr) return;
154   *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.prestep,(PetscVoidFunction)f,NULL);
155 }
156 
157 PETSC_EXTERN void PETSC_STDCALL tssetpoststep_(TS *ts,PetscErrorCode (PETSC_STDCALL *f)(TS*,PetscErrorCode*),PetscErrorCode *ierr)
158 {
159   *ierr = TSSetPostStep(*ts,ourpoststep);if (*ierr) return;
160   *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.poststep,(PetscVoidFunction)f,NULL);
161 }
162 
163 PETSC_EXTERN void tscomputerhsfunctionlinear_(TS *ts,PetscReal *t,Vec *X,Vec *F,void *ctx,PetscErrorCode *ierr)
164 {
165   *ierr = TSComputeRHSFunctionLinear(*ts,*t,*X,*F,ctx);
166 }
167 PETSC_EXTERN void PETSC_STDCALL tssetrhsfunction_(TS *ts,Vec *r,PetscErrorCode (PETSC_STDCALL*f)(TS*,PetscReal*,Vec*,Vec*,void*,PetscErrorCode*),void *fP,PetscErrorCode *ierr)
168 {
169   Vec R;
170   CHKFORTRANNULLOBJECT(r);
171   CHKFORTRANNULLFUNCTION(f);
172   CHKFORTRANNULLOBJECT(fP);
173   R = r ? *r : (Vec)NULL;
174   if ((PetscVoidFunction)f == (PetscVoidFunction)tscomputerhsfunctionlinear_) {
175     *ierr = TSSetRHSFunction(*ts,R,TSComputeRHSFunctionLinear,fP);
176   } else {
177     *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.rhsfunction,(PetscVoidFunction)f,fP);
178     *ierr = TSSetRHSFunction(*ts,R,ourrhsfunction,NULL);
179   }
180 }
181 PETSC_EXTERN void PETSC_STDCALL tsgetrhsfunction_(TS *ts,Vec *r,void *func,void **ctx,PetscErrorCode *ierr)
182 {
183   CHKFORTRANNULLINTEGER(ctx);
184   CHKFORTRANNULLOBJECT(r);
185   *ierr = TSGetRHSFunction(*ts,r,NULL,ctx);
186 }
187 
188 PETSC_EXTERN void tscomputeifunctionlinear_(TS *ts,PetscReal *t,Vec *X,Vec *Xdot,Vec *F,void *ctx,PetscErrorCode *ierr)
189 {
190   *ierr = TSComputeIFunctionLinear(*ts,*t,*X,*Xdot,*F,ctx);
191 }
192 PETSC_EXTERN void PETSC_STDCALL tssetifunction_(TS *ts,Vec *r,PetscErrorCode (PETSC_STDCALL*f)(TS*,PetscReal*,Vec*,Vec*,Vec*,void*,PetscErrorCode*),void *fP,PetscErrorCode *ierr)
193 {
194   Vec R;
195   CHKFORTRANNULLOBJECT(r);
196   CHKFORTRANNULLFUNCTION(f);
197   CHKFORTRANNULLOBJECT(fP);
198   R = r ? *r : (Vec)NULL;
199   if ((PetscVoidFunction)f == (PetscVoidFunction)tscomputeifunctionlinear_) {
200     *ierr = TSSetIFunction(*ts,R,TSComputeIFunctionLinear,fP);
201   } else {
202     *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.ifunction,(PetscVoidFunction)f,fP);
203     *ierr = TSSetIFunction(*ts,R,ourifunction,NULL);
204   }
205 }
206 PETSC_EXTERN void PETSC_STDCALL tsgetifunction_(TS *ts,Vec *r,void *func,void **ctx,PetscErrorCode *ierr)
207 {
208   CHKFORTRANNULLINTEGER(ctx);
209   CHKFORTRANNULLOBJECT(r);
210   *ierr = TSGetIFunction(*ts,r,NULL,ctx);
211 }
212 
213 /* ---------------------------------------------------------*/
214 PETSC_EXTERN void tscomputerhsjacobianconstant_(TS *ts,PetscReal *t,Vec *X,Mat *A,Mat *B,void *ctx,PetscErrorCode *ierr)
215 {
216   *ierr = TSComputeRHSJacobianConstant(*ts,*t,*X,*A,*B,ctx);
217 }
218 PETSC_EXTERN void PETSC_STDCALL tssetrhsjacobian_(TS *ts,Mat *A,Mat *B,void (PETSC_STDCALL*f)(TS*,PetscReal*,Vec*,Mat*,Mat*,void*,PetscErrorCode*),void *fP,PetscErrorCode *ierr)
219 {
220   CHKFORTRANNULLFUNCTION(f);
221   if ((PetscVoidFunction)f == (PetscVoidFunction)tscomputerhsjacobianconstant_) {
222     *ierr = TSSetRHSJacobian(*ts,*A,*B,TSComputeRHSJacobianConstant,fP);
223   } else {
224     *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.rhsjacobian,(PetscVoidFunction)f,fP);
225     *ierr = TSSetRHSJacobian(*ts,*A,*B,ourrhsjacobian,NULL);
226   }
227 }
228 
229 PETSC_EXTERN void tscomputeijacobianconstant_(TS *ts,PetscReal *t,Vec *X,Vec *Xdot,PetscReal *shift,Mat *A,Mat *B,void *ctx,PetscErrorCode *ierr)
230 {
231   *ierr = TSComputeIJacobianConstant(*ts,*t,*X,*Xdot,*shift,*A,*B,ctx);
232 }
233 PETSC_EXTERN void PETSC_STDCALL tssetijacobian_(TS *ts,Mat *A,Mat *B,void (PETSC_STDCALL*f)(TS*,PetscReal*,Vec*,Mat*,Mat*,void*,PetscErrorCode*),void *fP,PetscErrorCode *ierr)
234 {
235   CHKFORTRANNULLFUNCTION(f);
236   if ((PetscVoidFunction)f == (PetscVoidFunction)tscomputeijacobianconstant_) {
237     *ierr = TSSetIJacobian(*ts,*A,*B,TSComputeIJacobianConstant,fP);
238   } else {
239     *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.ijacobian,(PetscVoidFunction)f,fP);
240     *ierr = TSSetIJacobian(*ts,*A,*B,ourijacobian,NULL);
241   }
242 }
243 PETSC_EXTERN void PETSC_STDCALL tsgetijacobian_(TS *ts,Mat *J,Mat *M,int *func,void **ctx,PetscErrorCode *ierr)
244 {
245   CHKFORTRANNULLINTEGER(ctx);
246   CHKFORTRANNULLOBJECT(J);
247   CHKFORTRANNULLOBJECT(M);
248   *ierr = TSGetIJacobian(*ts,J,M,0,ctx);
249 }
250 
251 PETSC_EXTERN void tsmonitordefault_(TS *ts,PetscInt *its,PetscReal *fgnorm,Vec *u,PetscViewerAndFormat **dummy,PetscErrorCode *ierr)
252 {
253   *ierr = TSMonitorDefault(*ts,*its,*fgnorm,*u,*dummy);
254 }
255 
256 /* ---------------------------------------------------------*/
257 
258 /* PETSC_EXTERN void PETSC_STDCALL tsmonitordefault_(TS*,PetscInt*,PetscReal*,Vec*,void*,PetscErrorCode*); */
259 
260 PETSC_EXTERN void PETSC_STDCALL tsmonitorset_(TS *ts,void (PETSC_STDCALL*func)(TS*,PetscInt*,PetscReal*,Vec*,void*,PetscErrorCode*),void *mctx,void (PETSC_STDCALL*d)(void*,PetscErrorCode*),PetscErrorCode *ierr)
261 {
262   CHKFORTRANNULLFUNCTION(d);
263   if ((PetscVoidFunction)func == (PetscVoidFunction) tsmonitordefault_) {
264     *ierr = TSMonitorSet(*ts,(PetscErrorCode (*)(TS,PetscInt,PetscReal,Vec,void*))TSMonitorDefault,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
265   } else {
266     *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitor,(PetscVoidFunction)func,mctx);
267     *ierr = PetscObjectSetFortranCallback((PetscObject)*ts,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.mondestroy,(PetscVoidFunction)d,mctx);
268     *ierr = TSMonitorSet(*ts,ourmonitor,*ts,ourmonitordestroy);
269   }
270 }
271 
272 /* ---------------------------------------------------------*/
273 /*  func is currently ignored from Fortran */
274 PETSC_EXTERN void PETSC_STDCALL tsgetrhsjacobian_(TS *ts,Mat *J,Mat *M,int *func,void **ctx,PetscErrorCode *ierr)
275 {
276   *ierr = TSGetRHSJacobian(*ts,J,M,0,ctx);
277 }
278 
279 PETSC_EXTERN void PETSC_STDCALL tsview_(TS *ts,PetscViewer *viewer, PetscErrorCode *ierr)
280 {
281   PetscViewer v;
282   PetscPatchDefaultViewers_Fortran(viewer,v);
283   *ierr = TSView(*ts,v);
284 }
285 
286 PETSC_EXTERN void PETSC_STDCALL tssetoptionsprefix_(TS *ts,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
287 {
288   char *t;
289   FIXCHAR(prefix,len,t);
290   *ierr = TSSetOptionsPrefix(*ts,t);
291   FREECHAR(prefix,t);
292 }
293 PETSC_EXTERN void PETSC_STDCALL tsgetoptionsprefix_(TS *ts,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
294 {
295   const char *tname;
296 
297   *ierr = TSGetOptionsPrefix(*ts,&tname);
298   *ierr = PetscStrncpy(prefix,tname,len);
299   FIXRETURNCHAR(PETSC_TRUE,prefix,len);
300 }
301 PETSC_EXTERN void PETSC_STDCALL tsappendoptionsprefix_(TS *ts,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
302 {
303   char *t;
304   FIXCHAR(prefix,len,t);
305   *ierr = TSAppendOptionsPrefix(*ts,t);
306   FREECHAR(prefix,t);
307 }
308 
309