xref: /petsc/src/snes/interface/ftn-custom/zsnesf.c (revision 7cb011f58c32087171e6c65e6b5293ee2291f1f1)
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 snesnewtontrssetpostcheck_       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 snesnewtontrssetpostcheck_       snesnewtontrssetpostcheck
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 #endif
77 } _cb;
78 
79 static PetscErrorCode ourtrpostcheckfunction(SNES snes,Vec x,Vec y,Vec w,PetscBool *changed_w,void *ctx)
80 {
81 #if defined(PETSC_HAVE_F90_2PTR_ARG)
82   void* ptr;
83   PetscObjectGetFortranCallback((PetscObject)snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
84 #endif
85   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)));
86 }
87 
88 PETSC_EXTERN void PETSC_STDCALL snesnewtontrsetpostcheck_(SNES *snes, void (PETSC_STDCALL *func)(SNES,Vec,Vec,Vec,PetscBool*,void*),void *ctx,PetscErrorCode *ierr)
89 {
90   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.trpostcheck,(PetscVoidFunction)func,ctx);if (*ierr) return;
91 #if defined(PETSC_HAVE_F90_2PTR_ARG)
92   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.function_pgiptr,NULL,ptr);if (*ierr) return;
93 #endif
94   SNESNewtonTRSetPostCheck(*snes,ourtrpostcheckfunction,NULL);
95 }
96 
97 
98 
99 static PetscErrorCode oursnesfunction(SNES snes,Vec x,Vec f,void *ctx)
100 {
101 #if defined(PETSC_HAVE_F90_2PTR_ARG)
102   void* ptr;
103   PetscObjectGetFortranCallback((PetscObject)snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr);
104 #endif
105   PetscObjectUseFortranCallback(snes,_cb.function,(SNES*,Vec*,Vec*,void*,PetscErrorCode* PETSC_F90_2PTR_PROTO_NOVAR),(&snes,&x,&f,_ctx,&ierr PETSC_F90_2PTR_PARAM(ptr)));
106 }
107 
108 static PetscErrorCode oursnestest(SNES snes,PetscInt it,PetscReal a,PetscReal d,PetscReal c,SNESConvergedReason *reason,void *ctx)
109 {
110   PetscObjectUseFortranCallback(snes,_cb.test,(SNES*,PetscInt*,PetscReal*,PetscReal*,PetscReal*,SNESConvergedReason*,void*,PetscErrorCode*),(&snes,&it,&a,&d,&c,reason,_ctx,&ierr));
111 }
112 
113 static PetscErrorCode ourdestroy(void *ctx)
114 {
115   PetscObjectUseFortranCallback(ctx,_cb.destroy,(void*,PetscErrorCode*),(_ctx,&ierr));
116 }
117 
118 static PetscErrorCode oursnesjacobian(SNES snes,Vec x,Mat m,Mat p,void *ctx)
119 {
120   PetscObjectUseFortranCallback(snes,_cb.jacobian,(SNES*,Vec*,Mat*,Mat*,void*,PetscErrorCode*),(&snes,&x,&m,&p,_ctx,&ierr));
121 }
122 
123 static PetscErrorCode oursnesupdate(SNES snes,PetscInt i)
124 {
125   PetscObjectUseFortranCallback(snes,_cb.update,(SNES*,PetscInt *,PetscErrorCode*),(&snes,&i,&ierr));
126 }
127 static PetscErrorCode oursnesngs(SNES snes,Vec x,Vec b,void *ctx)
128 {
129   PetscObjectUseFortranCallback(snes,_cb.ngs,(SNES*,Vec*,Vec*,void*,PetscErrorCode*),(&snes,&x,&b,_ctx,&ierr));
130 }
131 static PetscErrorCode oursnesmonitor(SNES snes,PetscInt i,PetscReal d,void *ctx)
132 {
133   PetscObjectUseFortranCallback(snes,_cb.monitor,(SNES*,PetscInt*,PetscReal*,void*,PetscErrorCode*),(&snes,&i,&d,_ctx,&ierr));
134 }
135 static PetscErrorCode ourmondestroy(void **ctx)
136 {
137   SNES snes = (SNES)*ctx;
138   PetscObjectUseFortranCallback(snes,_cb.mondestroy,(void*,PetscErrorCode*),(_ctx,&ierr));
139 }
140 
141 /* ---------------------------------------------------------*/
142 /*
143      snescomputejacobiandefault() and snescomputejacobiandefaultcolor()
144   These can be used directly from Fortran but are mostly so that
145   Fortran SNESSetJacobian() will properly handle the defaults being passed in.
146 
147   functions, hence no STDCALL
148 */
149 PETSC_EXTERN void matmffdcomputejacobian_(SNES *snes,Vec *x,Mat *m,Mat *p,void *ctx,PetscErrorCode *ierr)
150 {
151   *ierr = MatMFFDComputeJacobian(*snes,*x,*m,*p,ctx);
152 }
153 PETSC_EXTERN void snescomputejacobiandefault_(SNES *snes,Vec *x,Mat *m,Mat *p,void *ctx,PetscErrorCode *ierr)
154 {
155   *ierr = SNESComputeJacobianDefault(*snes,*x,*m,*p,ctx);
156 }
157 PETSC_EXTERN void  snescomputejacobiandefaultcolor_(SNES *snes,Vec *x,Mat *m,Mat *p,void *ctx,PetscErrorCode *ierr)
158 {
159   *ierr = SNESComputeJacobianDefaultColor(*snes,*x,*m,*p,*(MatFDColoring*)ctx);
160 }
161 
162 PETSC_EXTERN void PETSC_STDCALL snessetjacobian_(SNES *snes,Mat *A,Mat *B,
163                                     void (PETSC_STDCALL *func)(SNES*,Vec*,Mat*,Mat*,void*,PetscErrorCode*),
164                                     void *ctx,PetscErrorCode *ierr)
165 {
166   CHKFORTRANNULLFUNCTION(func);
167   if ((PetscVoidFunction)func == (PetscVoidFunction)snescomputejacobiandefault_) {
168     *ierr = SNESSetJacobian(*snes,*A,*B,SNESComputeJacobianDefault,ctx);
169   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snescomputejacobiandefaultcolor_) {
170     if (!ctx) {
171       *ierr = PETSC_ERR_ARG_NULL;
172       return;
173     }
174     *ierr = SNESSetJacobian(*snes,*A,*B,SNESComputeJacobianDefaultColor,*(MatFDColoring*)ctx);
175   } else if ((PetscVoidFunction)func == (PetscVoidFunction)matmffdcomputejacobian_) {
176     *ierr = SNESSetJacobian(*snes,*A,*B,MatMFFDComputeJacobian,ctx);
177   } else {
178     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.jacobian,(PetscVoidFunction)func,ctx);
179     if (!*ierr) *ierr = SNESSetJacobian(*snes,*A,*B,oursnesjacobian,NULL);
180   }
181 }
182 /* -------------------------------------------------------------*/
183 
184 PETSC_EXTERN void PETSC_STDCALL snesgetoptionsprefix_(SNES *snes,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
185 {
186   const char *tname;
187 
188   *ierr = SNESGetOptionsPrefix(*snes,&tname);
189   *ierr = PetscStrncpy(prefix,tname,len);if (*ierr) return;
190   FIXRETURNCHAR(PETSC_TRUE,prefix,len);
191 }
192 
193 PETSC_EXTERN void PETSC_STDCALL snesgettype_(SNES *snes,char* name PETSC_MIXED_LEN(len), PetscErrorCode *ierr PETSC_END_LEN(len))
194 {
195   const char *tname;
196 
197   *ierr = SNESGetType(*snes,&tname);
198   *ierr = PetscStrncpy(name,tname,len);if (*ierr) return;
199   FIXRETURNCHAR(PETSC_TRUE,name,len);
200 }
201 
202 /* ---------------------------------------------------------*/
203 
204 /*
205    These are not usually called from Fortran but allow Fortran users
206    to transparently set these monitors from .F code
207 
208    functions, hence no STDCALL
209 */
210 
211 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))
212 {
213   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.function,(PetscVoidFunction)func,ctx);if (*ierr) return;
214 #if defined(PETSC_HAVE_F90_2PTR_ARG)
215   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.function_pgiptr,NULL,ptr);if (*ierr) return;
216 #endif
217   *ierr = SNESSetFunction(*snes,*r,oursnesfunction,NULL);
218 }
219 
220 
221 PETSC_EXTERN void PETSC_STDCALL snessetngs_(SNES *snes,void (PETSC_STDCALL *func)(SNES*,Vec*,Vec*,void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr)
222 {
223   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.ngs,(PetscVoidFunction)func,ctx);if (*ierr) return;
224   *ierr = SNESSetNGS(*snes,oursnesngs,NULL);
225 }
226 PETSC_EXTERN void PETSC_STDCALL snessetupdate_(SNES *snes,void (PETSC_STDCALL *func)(SNES*,PetscInt*,PetscErrorCode*),PetscErrorCode *ierr)
227 {
228   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.update,(PetscVoidFunction)func,NULL);if (*ierr) return;
229   *ierr = SNESSetUpdate(*snes,oursnesupdate);
230 }
231 /* ---------------------------------------------------------*/
232 
233 /* the func argument is ignored */
234 PETSC_EXTERN void PETSC_STDCALL snesgetfunction_(SNES *snes,Vec *r,void (PETSC_STDCALL *func)(SNES,Vec,Vec,void*),void **ctx,PetscErrorCode *ierr)
235 {
236   CHKFORTRANNULLOBJECT(r);
237   *ierr = SNESGetFunction(*snes,r,NULL,NULL); if (*ierr) return;
238   if ((PetscVoidFunction)func == (PetscVoidFunction)PETSC_NULL_FUNCTION_Fortran) return;
239   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function,NULL,ctx);
240 }
241 
242 PETSC_EXTERN void PETSC_STDCALL snesgetngs_(SNES *snes,void *func,void **ctx,PetscErrorCode *ierr)
243 {
244   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.ngs,NULL,ctx);
245 }
246 
247 /*----------------------------------------------------------------------*/
248 
249 PETSC_EXTERN void snesconvergeddefault_(SNES *snes,PetscInt *it,PetscReal *a,PetscReal *b,PetscReal *c,SNESConvergedReason *r, void *ct,PetscErrorCode *ierr)
250 {
251   *ierr = SNESConvergedDefault(*snes,*it,*a,*b,*c,r,ct);
252 }
253 
254 PETSC_EXTERN void snesconvergedskip_(SNES *snes,PetscInt *it,PetscReal *a,PetscReal *b,PetscReal *c,SNESConvergedReason *r,void *ct,PetscErrorCode *ierr)
255 {
256   *ierr = SNESConvergedSkip(*snes,*it,*a,*b,*c,r,ct);
257 }
258 
259 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)
260 {
261   CHKFORTRANNULLFUNCTION(destroy);
262 
263   if ((PetscVoidFunction)func == (PetscVoidFunction)snesconvergeddefault_) {
264     *ierr = SNESSetConvergenceTest(*snes,SNESConvergedDefault,0,0);
265   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesconvergedskip_) {
266     *ierr = SNESSetConvergenceTest(*snes,SNESConvergedSkip,0,0);
267   } else {
268     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.test,(PetscVoidFunction)func,cctx);if (*ierr) return;
269     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.destroy,(PetscVoidFunction)destroy,cctx);if (*ierr) return;
270     *ierr = SNESSetConvergenceTest(*snes,oursnestest,*snes,ourdestroy);
271   }
272 }
273 /*----------------------------------------------------------------------*/
274 
275 PETSC_EXTERN void PETSC_STDCALL snesview_(SNES *snes,PetscViewer *viewer, PetscErrorCode *ierr)
276 {
277   PetscViewer v;
278   PetscPatchDefaultViewers_Fortran(viewer,v);
279   *ierr = SNESView(*snes,v);
280 }
281 
282 /*  func is currently ignored from Fortran */
283 PETSC_EXTERN void PETSC_STDCALL snesgetjacobian_(SNES *snes,Mat *A,Mat *B,int *func,void **ctx,PetscErrorCode *ierr)
284 {
285   CHKFORTRANNULLINTEGER(ctx);
286   CHKFORTRANNULLOBJECT(A);
287   CHKFORTRANNULLOBJECT(B);
288   *ierr = SNESGetJacobian(*snes,A,B,0,NULL); if (*ierr) return;
289   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,_cb.jacobian,NULL,ctx);
290 
291 }
292 
293 PETSC_EXTERN void PETSC_STDCALL snesgetconvergencehistory_(SNES *snes,PetscInt *na,PetscErrorCode *ierr)
294 {
295   *ierr = SNESGetConvergenceHistory(*snes,NULL,NULL,na);
296 }
297 
298 PETSC_EXTERN void PETSC_STDCALL snessettype_(SNES *snes,char* type PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
299 {
300   char *t;
301 
302   FIXCHAR(type,len,t);
303   *ierr = SNESSetType(*snes,t);if (*ierr) return;
304   FREECHAR(type,t);
305 }
306 
307 PETSC_EXTERN void PETSC_STDCALL snesappendoptionsprefix_(SNES *snes,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
308 {
309   char *t;
310 
311   FIXCHAR(prefix,len,t);
312   *ierr = SNESAppendOptionsPrefix(*snes,t);if (*ierr) return;
313   FREECHAR(prefix,t);
314 }
315 
316 PETSC_EXTERN void PETSC_STDCALL snessetoptionsprefix_(SNES *snes,char* prefix PETSC_MIXED_LEN(len),PetscErrorCode *ierr PETSC_END_LEN(len))
317 {
318   char *t;
319 
320   FIXCHAR(prefix,len,t);
321   *ierr = SNESSetOptionsPrefix(*snes,t);if (*ierr) return;
322   FREECHAR(prefix,t);
323 }
324 
325 /*----------------------------------------------------------------------*/
326 /* functions, hence no STDCALL */
327 
328 PETSC_EXTERN void snesmonitorlgresidualnorm_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscObject *dummy,PetscErrorCode *ierr)
329 {
330   *ierr = SNESMonitorLGResidualNorm(*snes,*its,*fgnorm,dummy);
331 }
332 
333 PETSC_EXTERN void snesmonitordefault_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscViewerAndFormat **dummy,PetscErrorCode *ierr)
334 {
335   *ierr = SNESMonitorDefault(*snes,*its,*fgnorm,*dummy);
336 }
337 
338 PETSC_EXTERN void snesmonitorsolution_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscViewerAndFormat **dummy,PetscErrorCode *ierr)
339 {
340   *ierr = SNESMonitorSolution(*snes,*its,*fgnorm,*dummy);
341 }
342 
343 PETSC_EXTERN void snesmonitorsolutionupdate_(SNES *snes,PetscInt *its,PetscReal *fgnorm,PetscViewerAndFormat **dummy,PetscErrorCode *ierr)
344 {
345   *ierr = SNESMonitorSolutionUpdate(*snes,*its,*fgnorm,*dummy);
346 }
347 
348 
349 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)
350 {
351   CHKFORTRANNULLFUNCTION(mondestroy);
352   if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitordefault_) {
353     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorDefault,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
354   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorsolution_) {
355     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorSolution,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
356   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorsolutionupdate_) {
357     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorSolutionUpdate,*(PetscViewerAndFormat**)mctx,(PetscErrorCode (*)(void **))PetscViewerAndFormatDestroy);
358   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorlgresidualnorm_) {
359     *ierr = SNESMonitorSet(*snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))SNESMonitorLGResidualNorm,0,0);
360   } else {
361     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitor,(PetscVoidFunction)func,mctx);if (*ierr) return;
362     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.mondestroy,(PetscVoidFunction)mondestroy,mctx);if (*ierr) return;
363     *ierr = SNESMonitorSet(*snes,oursnesmonitor,*snes,ourmondestroy);
364   }
365 }
366 
367