xref: /petsc/src/snes/interface/ftn-custom/zsnesf.c (revision 534a8f05a7a8aff70dd8cfd53d9cd834400a8dbf)
1 #include <petsc/private/fortranimpl.h>
2 #include <petscsnes.h>
3 #include <petscviewer.h>
4 #include <petsc/private/f90impl.h>
5 
6 #if defined(PETSC_HAVE_FORTRAN_CAPS)
7 #define matmffdcomputejacobian_          MATMFFDCOMPUTEJACOBIAN
8 #define snessolve_                       SNESSOLVE
9 #define snescomputejacobiandefault_      SNESCOMPUTEJACOBIANDEFAULT
10 #define snescomputejacobiandefaultcolor_ SNESCOMPUTEJACOBIANDEFAULTCOLOR
11 #define snessetjacobian_                 SNESSETJACOBIAN
12 #define snesgetoptionsprefix_            SNESGETOPTIONSPREFIX
13 #define snesgettype_                     SNESGETTYPE
14 #define snessetfunction_                 SNESSETFUNCTION
15 #define snessetngs_                       SNESSETNGS
16 #define snessetupdate_                    SNESSETUPDATE
17 #define snesgetfunction_                 SNESGETFUNCTION
18 #define snesgetngs_                       SNESGETNGS
19 #define snessetconvergencetest_          SNESSETCONVERGENCETEST
20 #define snesconvergeddefault_            SNESCONVERGEDDEFAULT
21 #define snesconvergedskip_               SNESCONVERGEDSKIP
22 #define snesview_                        SNESVIEW
23 #define snesgetconvergencehistory_       SNESGETCONVERGENCEHISTORY
24 #define snesgetjacobian_                 SNESGETJACOBIAN
25 #define snessettype_                     SNESSETTYPE
26 #define snesappendoptionsprefix_         SNESAPPENDOPTIONSPREFIX
27 #define snessetoptionsprefix_            SNESSETOPTIONSPREFIX
28 #define snesmonitordefault_              SNESMONITORDEFAULT
29 #define snesmonitorsolution_             SNESMONITORSOLUTION
30 #define snesmonitorlgresidualnorm_       SNESMONITORLGRESIDUALNORM
31 #define snesmonitorsolutionupdate_       SNESMONITORSOLUTIONUPDATE
32 #define snesmonitorset_                  SNESMONITORSET
33 #define snesnewtontrsetpostcheck_        SNESNEWTONTRSETPOSTCHECK
34 #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
35 #define matmffdcomputejacobian_          matmffdcomputejacobian
36 #define snessolve_                       snessolve
37 #define snescomputejacobiandefault_      snescomputejacobiandefault
38 #define snescomputejacobiandefaultcolor_ snescomputejacobiandefaultcolor
39 #define snessetjacobian_                 snessetjacobian
40 #define snesgetoptionsprefix_            snesgetoptionsprefix
41 #define snesgettype_                     snesgettype
42 #define snessetfunction_                 snessetfunction
43 #define snessetngs_                       snessetngs
44 #define snessetupdate_                    snessetupdate
45 #define snesgetfunction_                 snesgetfunction
46 #define snesgetngs_                       snesgetngs
47 #define snessetconvergencetest_          snessetconvergencetest
48 #define snesconvergeddefault_            snesconvergeddefault
49 #define snesconvergedskip_               snesconvergedskip
50 #define snesview_                        snesview
51 #define snesgetjacobian_                 snesgetjacobian
52 #define snesgetconvergencehistory_       snesgetconvergencehistory
53 #define snessettype_                     snessettype
54 #define snesappendoptionsprefix_         snesappendoptionsprefix
55 #define snessetoptionsprefix_            snessetoptionsprefix
56 #define snesmonitorlgresidualnorm_       snesmonitorlgresidualnorm
57 #define snesmonitordefault_              snesmonitordefault
58 #define snesmonitorsolution_             snesmonitorsolution
59 #define snesmonitorsolutionupdate_       snesmonitorsolutionupdate
60 #define snesmonitorset_                  snesmonitorset
61 #define snesnewtontrsetpostcheck_        snesnewtontrsetpostcheck
62 #endif
63 
64 static struct {
65   PetscFortranCallbackId function;
66   PetscFortranCallbackId test;
67   PetscFortranCallbackId destroy;
68   PetscFortranCallbackId jacobian;
69   PetscFortranCallbackId monitor;
70   PetscFortranCallbackId mondestroy;
71   PetscFortranCallbackId ngs;
72   PetscFortranCallbackId update;
73   PetscFortranCallbackId trpostcheck;
74 #if defined(PETSC_HAVE_F90_2PTR_ARG)
75   PetscFortranCallbackId function_pgiptr;
76   PetscFortranCallbackId trpostcheck_pgiptr;
77 #endif
78 } _cb;
79 
80 static PetscErrorCode ourtrpostcheckfunction(SNES snes,Vec x,Vec y,Vec w,PetscBool *changed_w,void *ctx)
81 {
82 #if defined(PETSC_HAVE_F90_2PTR_ARG)
83   void* ptr;
84   PetscObjectGetFortranCallback((PetscObject)snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.trpostcheck_pgiptr,NULL,&ptr);
85 #endif
86   PetscObjectUseFortranCallback(snes,_cb.trpostcheck,(SNES*,Vec*,Vec*,Vec *,PetscBool *,void*,PetscErrorCode* PETSC_F90_2PTR_PROTO_NOVAR),(&snes,&x,&y,&w,changed_w,_ctx,&ierr PETSC_F90_2PTR_PARAM(ptr)));
87 }
88 
89 PETSC_EXTERN void PETSC_STDCALL snesnewtontrsetpostcheck_(SNES *snes, void (PETSC_STDCALL *func)(SNES,Vec,Vec,Vec,PetscBool*,void*),void *ctx,PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
90 {
91   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.trpostcheck,(PetscVoidFunction)func,ctx);if (*ierr) return;
92 #if defined(PETSC_HAVE_F90_2PTR_ARG)
93   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.trpostcheck_pgiptr,NULL,ptr);if (*ierr) return;
94 #endif
95   SNESNewtonTRSetPostCheck(*snes,ourtrpostcheckfunction,NULL);
96 }
97 
98 
99 
100 static PetscErrorCode oursnesfunction(SNES snes,Vec x,Vec f,void *ctx)
101 {
102 #if defined(PETSC_HAVE_F90_2PTR_ARG)
103   void* ptr;
104   PetscObjectGetFortranCallback((PetscObject)snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
105 #endif
106   PetscObjectUseFortranCallback(snes,_cb.function,(SNES*,Vec*,Vec*,void*,PetscErrorCode* PETSC_F90_2PTR_PROTO_NOVAR),(&snes,&x,&f,_ctx,&ierr PETSC_F90_2PTR_PARAM(ptr)));
107 }
108 
109 static PetscErrorCode oursnestest(SNES snes,PetscInt it,PetscReal a,PetscReal d,PetscReal c,SNESConvergedReason *reason,void *ctx)
110 {
111   PetscObjectUseFortranCallback(snes,_cb.test,(SNES*,PetscInt*,PetscReal*,PetscReal*,PetscReal*,SNESConvergedReason*,void*,PetscErrorCode*),(&snes,&it,&a,&d,&c,reason,_ctx,&ierr));
112 }
113 
114 static PetscErrorCode ourdestroy(void *ctx)
115 {
116   PetscObjectUseFortranCallback(ctx,_cb.destroy,(void*,PetscErrorCode*),(_ctx,&ierr));
117 }
118 
119 static PetscErrorCode oursnesjacobian(SNES snes,Vec x,Mat m,Mat p,void *ctx)
120 {
121   PetscObjectUseFortranCallback(snes,_cb.jacobian,(SNES*,Vec*,Mat*,Mat*,void*,PetscErrorCode*),(&snes,&x,&m,&p,_ctx,&ierr));
122 }
123 
124 static PetscErrorCode oursnesupdate(SNES snes,PetscInt i)
125 {
126   PetscObjectUseFortranCallback(snes,_cb.update,(SNES*,PetscInt *,PetscErrorCode*),(&snes,&i,&ierr));
127 }
128 static PetscErrorCode oursnesngs(SNES snes,Vec x,Vec b,void *ctx)
129 {
130   PetscObjectUseFortranCallback(snes,_cb.ngs,(SNES*,Vec*,Vec*,void*,PetscErrorCode*),(&snes,&x,&b,_ctx,&ierr));
131 }
132 static PetscErrorCode oursnesmonitor(SNES snes,PetscInt i,PetscReal d,void *ctx)
133 {
134   PetscObjectUseFortranCallback(snes,_cb.monitor,(SNES*,PetscInt*,PetscReal*,void*,PetscErrorCode*),(&snes,&i,&d,_ctx,&ierr));
135 }
136 static PetscErrorCode ourmondestroy(void **ctx)
137 {
138   SNES snes = (SNES)*ctx;
139   PetscObjectUseFortranCallback(snes,_cb.mondestroy,(void*,PetscErrorCode*),(_ctx,&ierr));
140 }
141 
142 /* ---------------------------------------------------------*/
143 /*
144      snescomputejacobiandefault() and snescomputejacobiandefaultcolor()
145   These can be used directly from Fortran but are mostly so that
146   Fortran SNESSetJacobian() will properly handle the defaults being passed in.
147 
148   functions, hence no STDCALL
149 */
150 PETSC_EXTERN void matmffdcomputejacobian_(SNES *snes,Vec *x,Mat *m,Mat *p,void *ctx,PetscErrorCode *ierr)
151 {
152   *ierr = MatMFFDComputeJacobian(*snes,*x,*m,*p,ctx);
153 }
154 PETSC_EXTERN void snescomputejacobiandefault_(SNES *snes,Vec *x,Mat *m,Mat *p,void *ctx,PetscErrorCode *ierr)
155 {
156   *ierr = SNESComputeJacobianDefault(*snes,*x,*m,*p,ctx);
157 }
158 PETSC_EXTERN void  snescomputejacobiandefaultcolor_(SNES *snes,Vec *x,Mat *m,Mat *p,void *ctx,PetscErrorCode *ierr)
159 {
160   *ierr = SNESComputeJacobianDefaultColor(*snes,*x,*m,*p,*(MatFDColoring*)ctx);
161 }
162 
163 PETSC_EXTERN void PETSC_STDCALL snessetjacobian_(SNES *snes,Mat *A,Mat *B,
164                                     void (PETSC_STDCALL *func)(SNES*,Vec*,Mat*,Mat*,void*,PetscErrorCode*),
165                                     void *ctx,PetscErrorCode *ierr)
166 {
167   CHKFORTRANNULLFUNCTION(func);
168   if ((PetscVoidFunction)func == (PetscVoidFunction)snescomputejacobiandefault_) {
169     *ierr = SNESSetJacobian(*snes,*A,*B,SNESComputeJacobianDefault,ctx);
170   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snescomputejacobiandefaultcolor_) {
171     if (!ctx) {
172       *ierr = PETSC_ERR_ARG_NULL;
173       return;
174     }
175     *ierr = SNESSetJacobian(*snes,*A,*B,SNESComputeJacobianDefaultColor,*(MatFDColoring*)ctx);
176   } else if ((PetscVoidFunction)func == (PetscVoidFunction)matmffdcomputejacobian_) {
177     *ierr = SNESSetJacobian(*snes,*A,*B,MatMFFDComputeJacobian,ctx);
178   } else {
179     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.jacobian,(PetscVoidFunction)func,ctx);
180     if (!*ierr) *ierr = SNESSetJacobian(*snes,*A,*B,oursnesjacobian,NULL);
181   }
182 }
183 /* -------------------------------------------------------------*/
184 
185 PETSC_EXTERN void PETSC_STDCALL snesgetoptionsprefix_(SNES *snes,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
186 {
187   const char *tname;
188 
189   *ierr = SNESGetOptionsPrefix(*snes,&tname);
190   *ierr = PetscStrncpy(prefix,tname,len);if (*ierr) return;
191   FIXRETURNCHAR(PETSC_TRUE,prefix,len);
192 }
193 
194 PETSC_EXTERN void PETSC_STDCALL snesgettype_(SNES *snes,char* name PETSC_MIXED_LEN(len), PetscErrorCode *ierr PETSC_END_LEN(len))
195 {
196   const char *tname;
197 
198   *ierr = SNESGetType(*snes,&tname);
199   *ierr = PetscStrncpy(name,tname,len);if (*ierr) return;
200   FIXRETURNCHAR(PETSC_TRUE,name,len);
201 }
202 
203 /* ---------------------------------------------------------*/
204 
205 /*
206    These are not usually called from Fortran but allow Fortran users
207    to transparently set these monitors from .F code
208 
209    functions, hence no STDCALL
210 */
211 
212 PETSC_EXTERN void PETSC_STDCALL snessetfunction_(SNES *snes,Vec *r,void (PETSC_STDCALL *func)(SNES*,Vec*,Vec*,void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
213 {
214   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.function,(PetscVoidFunction)func,ctx);if (*ierr) return;
215 #if defined(PETSC_HAVE_F90_2PTR_ARG)
216   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.function_pgiptr,NULL,ptr);if (*ierr) return;
217 #endif
218   *ierr = SNESSetFunction(*snes,*r,oursnesfunction,NULL);
219 }
220 
221 
222 PETSC_EXTERN void PETSC_STDCALL snessetngs_(SNES *snes,void (PETSC_STDCALL *func)(SNES*,Vec*,Vec*,void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr)
223 {
224   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.ngs,(PetscVoidFunction)func,ctx);if (*ierr) return;
225   *ierr = SNESSetNGS(*snes,oursnesngs,NULL);
226 }
227 PETSC_EXTERN void PETSC_STDCALL snessetupdate_(SNES *snes,void (PETSC_STDCALL *func)(SNES*,PetscInt*,PetscErrorCode*),PetscErrorCode *ierr)
228 {
229   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.update,(PetscVoidFunction)func,NULL);if (*ierr) return;
230   *ierr = SNESSetUpdate(*snes,oursnesupdate);
231 }
232 /* ---------------------------------------------------------*/
233 
234 /* the func argument is ignored */
235 PETSC_EXTERN void PETSC_STDCALL snesgetfunction_(SNES *snes,Vec *r,void (PETSC_STDCALL *func)(SNES,Vec,Vec,void*),void **ctx,PetscErrorCode *ierr)
236 {
237   CHKFORTRANNULLOBJECT(r);
238   *ierr = SNESGetFunction(*snes,r,NULL,NULL); if (*ierr) return;
239   if ((PetscVoidFunction)func == (PetscVoidFunction)PETSC_NULL_FUNCTION_Fortran) return;
240   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function,NULL,ctx);
241 }
242 
243 PETSC_EXTERN void PETSC_STDCALL snesgetngs_(SNES *snes,void *func,void **ctx,PetscErrorCode *ierr)
244 {
245   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.ngs,NULL,ctx);
246 }
247 
248 /*----------------------------------------------------------------------*/
249 
250 PETSC_EXTERN void snesconvergeddefault_(SNES *snes,PetscInt *it,PetscReal *a,PetscReal *b,PetscReal *c,SNESConvergedReason *r, void *ct,PetscErrorCode *ierr)
251 {
252   *ierr = SNESConvergedDefault(*snes,*it,*a,*b,*c,r,ct);
253 }
254 
255 PETSC_EXTERN void snesconvergedskip_(SNES *snes,PetscInt *it,PetscReal *a,PetscReal *b,PetscReal *c,SNESConvergedReason *r,void *ct,PetscErrorCode *ierr)
256 {
257   *ierr = SNESConvergedSkip(*snes,*it,*a,*b,*c,r,ct);
258 }
259 
260 PETSC_EXTERN void PETSC_STDCALL snessetconvergencetest_(SNES *snes,void (PETSC_STDCALL *func)(SNES*,PetscInt*,PetscReal*,PetscReal*,PetscReal*,SNESConvergedReason*,void*,PetscErrorCode*), void *cctx,void (PETSC_STDCALL *destroy)(void*),PetscErrorCode *ierr)
261 {
262   CHKFORTRANNULLFUNCTION(destroy);
263 
264   if ((PetscVoidFunction)func == (PetscVoidFunction)snesconvergeddefault_) {
265     *ierr = SNESSetConvergenceTest(*snes,SNESConvergedDefault,0,0);
266   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesconvergedskip_) {
267     *ierr = SNESSetConvergenceTest(*snes,SNESConvergedSkip,0,0);
268   } else {
269     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.test,(PetscVoidFunction)func,cctx);if (*ierr) return;
270     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.destroy,(PetscVoidFunction)destroy,cctx);if (*ierr) return;
271     *ierr = SNESSetConvergenceTest(*snes,oursnestest,*snes,ourdestroy);
272   }
273 }
274 /*----------------------------------------------------------------------*/
275 
276 PETSC_EXTERN void PETSC_STDCALL snesview_(SNES *snes,PetscViewer *viewer, PetscErrorCode *ierr)
277 {
278   PetscViewer v;
279   PetscPatchDefaultViewers_Fortran(viewer,v);
280   *ierr = SNESView(*snes,v);
281 }
282 
283 /*  func is currently ignored from Fortran */
284 PETSC_EXTERN void PETSC_STDCALL snesgetjacobian_(SNES *snes,Mat *A,Mat *B,int *func,void **ctx,PetscErrorCode *ierr)
285 {
286   CHKFORTRANNULLINTEGER(ctx);
287   CHKFORTRANNULLOBJECT(A);
288   CHKFORTRANNULLOBJECT(B);
289   *ierr = SNESGetJacobian(*snes,A,B,0,NULL); if (*ierr) return;
290   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.jacobian,NULL,ctx);
291 
292 }
293 
294 PETSC_EXTERN void PETSC_STDCALL snesgetconvergencehistory_(SNES *snes,PetscInt *na,PetscErrorCode *ierr)
295 {
296   *ierr = SNESGetConvergenceHistory(*snes,NULL,NULL,na);
297 }
298 
299 PETSC_EXTERN void PETSC_STDCALL snessettype_(SNES *snes,char* type PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
300 {
301   char *t;
302 
303   FIXCHAR(type,len,t);
304   *ierr = SNESSetType(*snes,t);if (*ierr) return;
305   FREECHAR(type,t);
306 }
307 
308 PETSC_EXTERN void PETSC_STDCALL snesappendoptionsprefix_(SNES *snes,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
309 {
310   char *t;
311 
312   FIXCHAR(prefix,len,t);
313   *ierr = SNESAppendOptionsPrefix(*snes,t);if (*ierr) return;
314   FREECHAR(prefix,t);
315 }
316 
317 PETSC_EXTERN void PETSC_STDCALL snessetoptionsprefix_(SNES *snes,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
318 {
319   char *t;
320 
321   FIXCHAR(prefix,len,t);
322   *ierr = SNESSetOptionsPrefix(*snes,t);if (*ierr) return;
323   FREECHAR(prefix,t);
324 }
325 
326 /*----------------------------------------------------------------------*/
327 /* functions, hence no STDCALL */
328 
329 PETSC_EXTERN void snesmonitorlgresidualnorm_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscObject *dummy,PetscErrorCode *ierr)
330 {
331   *ierr = SNESMonitorLGResidualNorm(*snes,*its,*fgnorm,dummy);
332 }
333 
334 PETSC_EXTERN void snesmonitordefault_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscViewerAndFormat **dummy,PetscErrorCode *ierr)
335 {
336   *ierr = SNESMonitorDefault(*snes,*its,*fgnorm,*dummy);
337 }
338 
339 PETSC_EXTERN void snesmonitorsolution_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscViewerAndFormat **dummy,PetscErrorCode *ierr)
340 {
341   *ierr = SNESMonitorSolution(*snes,*its,*fgnorm,*dummy);
342 }
343 
344 PETSC_EXTERN void snesmonitorsolutionupdate_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscViewerAndFormat **dummy,PetscErrorCode *ierr)
345 {
346   *ierr = SNESMonitorSolutionUpdate(*snes,*its,*fgnorm,*dummy);
347 }
348 
349 
350 PETSC_EXTERN void PETSC_STDCALL snesmonitorset_(SNES *snes,void (PETSC_STDCALL *func)(SNES*,PetscInt*,PetscReal*,void*,PetscErrorCode*),void *mctx,void (PETSC_STDCALL *mondestroy)(void*,PetscErrorCode*),PetscErrorCode *ierr)
351 {
352   CHKFORTRANNULLFUNCTION(mondestroy);
353   if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitordefault_) {
354     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorDefault,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
355   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorsolution_) {
356     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorSolution,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
357   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorsolutionupdate_) {
358     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorSolutionUpdate,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
359   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorlgresidualnorm_) {
360     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorLGResidualNorm,0,0);
361   } else {
362     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitor,(PetscVoidFunction)func,mctx);if (*ierr) return;
363     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.mondestroy,(PetscVoidFunction)mondestroy,mctx);if (*ierr) return;
364     *ierr = SNESMonitorSet(*snes,oursnesmonitor,*snes,ourmondestroy);
365   }
366 }
367 
368