xref: /petsc/src/snes/interface/ftn-custom/zsnesf.c (revision 49abdd8a111d9c2ef7fc48ade253ef64e07f9b37)
1af0996ceSBarry Smith #include <petsc/private/fortranimpl.h>
2c6db04a5SJed Brown #include <petscsnes.h>
3665c2dedSJed Brown #include <petscviewer.h>
48ad9143bSBarry Smith #include <petsc/private/f90impl.h>
58e27ec22SSatish Balay 
68e27ec22SSatish Balay #if defined(PETSC_HAVE_FORTRAN_CAPS)
7df2570feSBarry Smith   #define snessetpicard_                   SNESSETPICARD
8f51a5268SBarry Smith   #define snessetpicardnointerface_        SNESSETPICARDNOINTERFACE
96ce558aeSBarry Smith   #define snessolve_                       SNESSOLVE
108d359177SBarry Smith   #define snescomputejacobiandefault_      SNESCOMPUTEJACOBIANDEFAULT
118d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ SNESCOMPUTEJACOBIANDEFAULTCOLOR
128e27ec22SSatish Balay   #define snessetjacobian_                 SNESSETJACOBIAN
13f51a5268SBarry Smith   #define snessetjacobiannointerface_      SNESSETJACOBIANNOINTERFACE
148e27ec22SSatish Balay   #define snessetfunction_                 SNESSETFUNCTION
15f51a5268SBarry Smith   #define snessetfunctionnointerface_      SNESSETFUNCTIONNOINTERFACE
16c00ad2bcSBarry Smith   #define snessetobjective_                SNESSETOBJECTIVE
17f51a5268SBarry Smith   #define snessetobjectivenointerface_     SNESSETOBJECTIVENOINTERFACE
18be95d8f1SBarry Smith   #define snessetngs_                      SNESSETNGS
19dfef22ccSBarry Smith   #define snessetupdate_                   SNESSETUPDATE
208e27ec22SSatish Balay   #define snesgetfunction_                 SNESGETFUNCTION
21be95d8f1SBarry Smith   #define snesgetngs_                      SNESGETNGS
228e27ec22SSatish Balay   #define snessetconvergencetest_          SNESSETCONVERGENCETEST
238d359177SBarry Smith   #define snesconvergeddefault_            SNESCONVERGEDDEFAULT
24e07f7f94SSatish Balay   #define snesconvergedskip_               SNESCONVERGEDSKIP
258e27ec22SSatish Balay   #define snesgetconvergencehistory_       SNESGETCONVERGENCEHISTORY
268e27ec22SSatish Balay   #define snesgetjacobian_                 SNESGETJACOBIAN
27a6570f20SBarry Smith   #define snesmonitordefault_              SNESMONITORDEFAULT
28a6570f20SBarry Smith   #define snesmonitorsolution_             SNESMONITORSOLUTION
29a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       SNESMONITORSOLUTIONUPDATE
30a6570f20SBarry Smith   #define snesmonitorset_                  SNESMONITORSET
31c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         SNESNEWTONTRSETPRECHECK
323b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        SNESNEWTONTRSETPOSTCHECK
3341ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       SNESNEWTONTRDCSETPRECHECK
3441ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      SNESNEWTONTRDCSETPOSTCHECK
355d83a8b1SBarry Smith   #define matmffdcomputejacobian_          MATMFFDCOMPUTEJACOBIAN
364e2a09fcSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
37df2570feSBarry Smith   #define snessetpicard_                   snessetpicard
38f51a5268SBarry Smith   #define snessetpicardnointerface_        snessetpicardnointerface
396ce558aeSBarry Smith   #define snessolve_                       snessolve
408d359177SBarry Smith   #define snescomputejacobiandefault_      snescomputejacobiandefault
418d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ snescomputejacobiandefaultcolor
428e27ec22SSatish Balay   #define snessetjacobian_                 snessetjacobian
43f51a5268SBarry Smith   #define snessetjacobiannointerface_      snessetjacobiannointerface
448e27ec22SSatish Balay   #define snessetfunction_                 snessetfunction
45f51a5268SBarry Smith   #define snessetfunctionnointerface_      snessetfunctionnointerface
46c00ad2bcSBarry Smith   #define snessetobjective_                snessetobjective
47f51a5268SBarry Smith   #define snessetobjectivenointerface_     snessetobjectivenointerface
48be95d8f1SBarry Smith   #define snessetngs_                      snessetngs
49dfef22ccSBarry Smith   #define snessetupdate_                   snessetupdate
508e27ec22SSatish Balay   #define snesgetfunction_                 snesgetfunction
51be95d8f1SBarry Smith   #define snesgetngs_                      snesgetngs
528e27ec22SSatish Balay   #define snessetconvergencetest_          snessetconvergencetest
538d359177SBarry Smith   #define snesconvergeddefault_            snesconvergeddefault
54e07f7f94SSatish Balay   #define snesconvergedskip_               snesconvergedskip
558e27ec22SSatish Balay   #define snesgetjacobian_                 snesgetjacobian
568e27ec22SSatish Balay   #define snesgetconvergencehistory_       snesgetconvergencehistory
57a6570f20SBarry Smith   #define snesmonitordefault_              snesmonitordefault
58a6570f20SBarry Smith   #define snesmonitorsolution_             snesmonitorsolution
59a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       snesmonitorsolutionupdate
60a6570f20SBarry Smith   #define snesmonitorset_                  snesmonitorset
61c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         snesnewtontrsetprecheck
623b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        snesnewtontrsetpostcheck
6341ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       snesnewtontrdcsetprecheck
6441ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      snesnewtontrdcsetpostcheck
655d83a8b1SBarry Smith   #define matmffdcomputejacobian_          matmffdcomputejacobian
668e27ec22SSatish Balay #endif
678e27ec22SSatish Balay 
68f6291634SJed Brown static struct {
69f6291634SJed Brown   PetscFortranCallbackId function;
70c00ad2bcSBarry Smith   PetscFortranCallbackId objective;
71f6291634SJed Brown   PetscFortranCallbackId test;
72f6291634SJed Brown   PetscFortranCallbackId destroy;
73f6291634SJed Brown   PetscFortranCallbackId jacobian;
74f6291634SJed Brown   PetscFortranCallbackId monitor;
75f6291634SJed Brown   PetscFortranCallbackId mondestroy;
76be95d8f1SBarry Smith   PetscFortranCallbackId ngs;
77dfef22ccSBarry Smith   PetscFortranCallbackId update;
78c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck;
797cb011f5SBarry Smith   PetscFortranCallbackId trpostcheck;
8089e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
8189e00c7dSSatish Balay   PetscFortranCallbackId function_pgiptr;
82c00ad2bcSBarry Smith   PetscFortranCallbackId objective_pgiptr;
83c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck_pgiptr;
843c2ee7eaSBarry Smith   PetscFortranCallbackId trpostcheck_pgiptr;
8589e00c7dSSatish Balay #endif
86f6291634SJed Brown } _cb;
8790b77ac2SPeter Brune 
88c9368356SGlenn Hammond static PetscErrorCode ourtrprecheckfunction(SNES snes, Vec x, Vec y, PetscBool *changed_y, void *ctx)
89c9368356SGlenn Hammond {
90c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
91c9368356SGlenn Hammond   void *ptr;
923ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trprecheck_pgiptr, NULL, &ptr));
93c9368356SGlenn Hammond #endif
94c9368356SGlenn Hammond   PetscObjectUseFortranCallback(snes, _cb.trprecheck, (SNES *, Vec *, Vec *, PetscBool *, void *, PetscErrorCode *PETSC_F90_2PTR_PROTO_NOVAR), (&snes, &x, &y, changed_y, _ctx, &ierr PETSC_F90_2PTR_PARAM(ptr)));
95c9368356SGlenn Hammond }
96c9368356SGlenn Hammond 
9719caf8f3SSatish Balay PETSC_EXTERN void snesnewtontrsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
98c9368356SGlenn Hammond {
998434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFn *)func, ctx);
1003ba16761SJacob Faibussowitsch   if (*ierr) return;
101c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
1023ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
1033ba16761SJacob Faibussowitsch   if (*ierr) return;
104c9368356SGlenn Hammond #endif
1053ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPreCheck(*snes, ourtrprecheckfunction, NULL);
106c9368356SGlenn Hammond }
107c9368356SGlenn Hammond 
10841ba4c6cSHeeho Park PETSC_EXTERN void snesnewtontrdcsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
10941ba4c6cSHeeho Park {
1108434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFn *)func, ctx);
1113ba16761SJacob Faibussowitsch   if (*ierr) return;
11241ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1133ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
1143ba16761SJacob Faibussowitsch   if (*ierr) return;
11541ba4c6cSHeeho Park #endif
1163ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPreCheck(*snes, ourtrprecheckfunction, NULL);
11741ba4c6cSHeeho Park }
11841ba4c6cSHeeho Park 
119c9368356SGlenn Hammond static PetscErrorCode ourtrpostcheckfunction(SNES snes, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *ctx)
1207cb011f5SBarry Smith {
1217cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1227cb011f5SBarry Smith   void *ptr;
1233ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trpostcheck_pgiptr, NULL, &ptr));
1247cb011f5SBarry Smith #endif
125c9368356SGlenn Hammond   PetscObjectUseFortranCallback(snes, _cb.trpostcheck, (SNES *, Vec *, Vec *, Vec *, PetscBool *, PetscBool *, void *, PetscErrorCode *PETSC_F90_2PTR_PROTO_NOVAR), (&snes, &x, &y, &w, changed_y, changed_w, _ctx, &ierr PETSC_F90_2PTR_PARAM(ptr)));
1267cb011f5SBarry Smith }
1277cb011f5SBarry Smith 
12819caf8f3SSatish Balay PETSC_EXTERN void snesnewtontrsetpostcheck_(SNES *snes, void (*func)(SNES, Vec, Vec, Vec, PetscBool *, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
1297cb011f5SBarry Smith {
1308434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFn *)func, ctx);
1313ba16761SJacob Faibussowitsch   if (*ierr) return;
1327cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1333ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1343ba16761SJacob Faibussowitsch   if (*ierr) return;
1357cb011f5SBarry Smith #endif
1363ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
1377cb011f5SBarry Smith }
1387cb011f5SBarry Smith 
13941ba4c6cSHeeho Park PETSC_EXTERN void snesnewtontrdcsetpostcheck_(SNES *snes, void (*func)(SNES, Vec, Vec, Vec, PetscBool *, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
14041ba4c6cSHeeho Park {
1418434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFn *)func, ctx);
1423ba16761SJacob Faibussowitsch   if (*ierr) return;
14341ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1443ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1453ba16761SJacob Faibussowitsch   if (*ierr) return;
14641ba4c6cSHeeho Park #endif
1473ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
14841ba4c6cSHeeho Park }
14941ba4c6cSHeeho Park 
1508e27ec22SSatish Balay static PetscErrorCode oursnesfunction(SNES snes, Vec x, Vec f, void *ctx)
1518e27ec22SSatish Balay {
15289e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
15389e00c7dSSatish Balay   void *ptr;
1543ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
15589e00c7dSSatish Balay #endif
15689e00c7dSSatish Balay   PetscObjectUseFortranCallback(snes, _cb.function, (SNES *, Vec *, Vec *, void *, PetscErrorCode *PETSC_F90_2PTR_PROTO_NOVAR), (&snes, &x, &f, _ctx, &ierr PETSC_F90_2PTR_PARAM(ptr)));
1578e27ec22SSatish Balay }
158b8ebb45fSBarry Smith 
159c00ad2bcSBarry Smith static PetscErrorCode oursnesobjective(SNES snes, Vec x, PetscReal *v, void *ctx)
160c00ad2bcSBarry Smith {
161c00ad2bcSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
162c00ad2bcSBarry Smith   void *ptr;
163c00ad2bcSBarry Smith   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.objective_pgiptr, NULL, &ptr));
164c00ad2bcSBarry Smith #endif
165c00ad2bcSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.objective, (SNES *, Vec *, PetscReal *, void *, PetscErrorCode *PETSC_F90_2PTR_PROTO_NOVAR), (&snes, &x, v, _ctx, &ierr PETSC_F90_2PTR_PARAM(ptr)));
166c00ad2bcSBarry Smith }
167c00ad2bcSBarry Smith 
16806ee9f85SBarry Smith static PetscErrorCode oursnestest(SNES snes, PetscInt it, PetscReal a, PetscReal d, PetscReal c, SNESConvergedReason *reason, void *ctx)
1698e27ec22SSatish Balay {
170f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.test, (SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), (&snes, &it, &a, &d, &c, reason, _ctx, &ierr));
1717f7931b9SBarry Smith }
1727f7931b9SBarry Smith 
1737f7931b9SBarry Smith static PetscErrorCode ourdestroy(void *ctx)
1747f7931b9SBarry Smith {
175f6291634SJed Brown   PetscObjectUseFortranCallback(ctx, _cb.destroy, (void *, PetscErrorCode *), (_ctx, &ierr));
1768e27ec22SSatish Balay }
1778e27ec22SSatish Balay 
178d1e9a80fSBarry Smith static PetscErrorCode oursnesjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
1798e27ec22SSatish Balay {
180d1e9a80fSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
1818e27ec22SSatish Balay }
182f6291634SJed Brown 
183dfef22ccSBarry Smith static PetscErrorCode oursnesupdate(SNES snes, PetscInt i)
184dfef22ccSBarry Smith {
185dfef22ccSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.update, (SNES *, PetscInt *, PetscErrorCode *), (&snes, &i, &ierr));
186dfef22ccSBarry Smith }
187be95d8f1SBarry Smith static PetscErrorCode oursnesngs(SNES snes, Vec x, Vec b, void *ctx)
18890b77ac2SPeter Brune {
189be95d8f1SBarry Smith   PetscObjectUseFortranCallback(snes, _cb.ngs, (SNES *, Vec *, Vec *, void *, PetscErrorCode *), (&snes, &x, &b, _ctx, &ierr));
19090b77ac2SPeter Brune }
1918e27ec22SSatish Balay static PetscErrorCode oursnesmonitor(SNES snes, PetscInt i, PetscReal d, void *ctx)
1928e27ec22SSatish Balay {
193f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.monitor, (SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), (&snes, &i, &d, _ctx, &ierr));
1948e27ec22SSatish Balay }
195c2efdce3SBarry Smith static PetscErrorCode ourmondestroy(void **ctx)
1968e27ec22SSatish Balay {
197f6291634SJed Brown   SNES snes = (SNES)*ctx;
198f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.mondestroy, (void *, PetscErrorCode *), (_ctx, &ierr));
1998e27ec22SSatish Balay }
2008e27ec22SSatish Balay 
2015d83a8b1SBarry Smith /* these are generated automatically by bfort */
2025d83a8b1SBarry Smith PETSC_EXTERN void snescomputejacobiandefault_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
2035d83a8b1SBarry Smith PETSC_EXTERN void snescomputejacobiandefaultcolor_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
2045d83a8b1SBarry Smith PETSC_EXTERN void matmffdcomputejacobian_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
2058e27ec22SSatish Balay 
206f51a5268SBarry Smith PETSC_EXTERN void snessetjacobian_(SNES *snes, Mat *A, Mat *B, SNESJacobianFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
2078e27ec22SSatish Balay {
208f5b6597dSBarry Smith   CHKFORTRANNULLFUNCTION(func);
2098434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefault_) {
2108d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefault, ctx);
2118434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefaultcolor_) {
212e025ade3SBarry Smith     if (!ctx) {
213e025ade3SBarry Smith       *ierr = PETSC_ERR_ARG_NULL;
214e025ade3SBarry Smith       return;
215e025ade3SBarry Smith     }
2168d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefaultColor, *(MatFDColoring *)ctx);
2178434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)matmffdcomputejacobian_) {
218df66969eSBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, MatMFFDComputeJacobian, ctx);
2198e27ec22SSatish Balay   } else {
2208434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)func, ctx);
2210298fd71SBarry Smith     if (!*ierr) *ierr = SNESSetJacobian(*snes, *A, *B, oursnesjacobian, NULL);
2228e27ec22SSatish Balay   }
2238e27ec22SSatish Balay }
224f51a5268SBarry Smith 
225f51a5268SBarry Smith PETSC_EXTERN void snessetjacobiannointerface_(SNES *snes, Mat *A, Mat *B, SNESJacobianFn J, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
22617a42bb7SSatish Balay {
227f51a5268SBarry Smith   snessetjacobian_(snes, A, B, J, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
22817a42bb7SSatish Balay }
229f51a5268SBarry Smith 
230f51a5268SBarry Smith /*  func is currently ignored from Fortran */
231f51a5268SBarry Smith PETSC_EXTERN void snesgetjacobian_(SNES *snes, Mat *A, Mat *B, int *func, void **ctx, PetscErrorCode *ierr)
23217a42bb7SSatish Balay {
233f51a5268SBarry Smith   SNESJacobianFn *jfunc;
234f51a5268SBarry Smith   void           *jctx;
235f51a5268SBarry Smith 
236f51a5268SBarry Smith   CHKFORTRANNULL(ctx);
237f51a5268SBarry Smith   CHKFORTRANNULLOBJECT(A);
238f51a5268SBarry Smith   CHKFORTRANNULLOBJECT(B);
239f51a5268SBarry Smith   *ierr = SNESGetJacobian(*snes, A, B, &jfunc, &jctx);
240f51a5268SBarry Smith   if (*ierr) return;
241f51a5268SBarry Smith   if (jfunc == SNESComputeJacobianDefault || jfunc == SNESComputeJacobianDefaultColor || jfunc == MatMFFDComputeJacobian) {
242f51a5268SBarry Smith     if (ctx) *ctx = jctx;
243f51a5268SBarry Smith   } else {
244f51a5268SBarry Smith     *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.jacobian, NULL, ctx);
245f51a5268SBarry Smith   }
24617a42bb7SSatish Balay }
247f6dfbefdSBarry Smith 
248df2570feSBarry Smith static PetscErrorCode oursnespicardfunction(SNES snes, Vec x, Vec f, void *ctx)
249df2570feSBarry Smith {
250df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
251df2570feSBarry Smith   void *ptr;
2523ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
253df2570feSBarry Smith #endif
254df2570feSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.function, (SNES *, Vec *, Vec *, void *, PetscErrorCode *PETSC_F90_2PTR_PROTO_NOVAR), (&snes, &x, &f, _ctx, &ierr PETSC_F90_2PTR_PARAM(ptr)));
255df2570feSBarry Smith }
256df2570feSBarry Smith 
257df2570feSBarry Smith static PetscErrorCode oursnespicardjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
258df2570feSBarry Smith {
259df2570feSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
260df2570feSBarry Smith }
261df2570feSBarry Smith 
262f51a5268SBarry Smith PETSC_EXTERN void snessetpicard_(SNES *snes, Vec *r, SNESFunctionFn func, Mat *A, Mat *B, SNESJacobianFn J, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
263df2570feSBarry Smith {
2648434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
265df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
2665975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2675975b3b6SBarry Smith   if (*ierr) return;
268df2570feSBarry Smith #endif
2698434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)J, ctx);
270df2570feSBarry Smith   if (!*ierr) *ierr = SNESSetPicard(*snes, *r, oursnespicardfunction, *A, *B, oursnespicardjacobian, NULL);
271df2570feSBarry Smith }
2728e27ec22SSatish Balay 
273f51a5268SBarry Smith PETSC_EXTERN void snessetpicardnointerface_(SNES *snes, Vec *r, SNESFunctionFn func, Mat *A, Mat *B, SNESJacobianFn J, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
274f51a5268SBarry Smith {
275f51a5268SBarry Smith   snessetpicard_(snes, r, func, A, B, J, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
276f51a5268SBarry Smith }
277f51a5268SBarry Smith 
2788e27ec22SSatish Balay /*
2798e27ec22SSatish Balay    These are not usually called from Fortran but allow Fortran users
2808e27ec22SSatish Balay    to transparently set these monitors from .F code
2818e27ec22SSatish Balay */
2828e27ec22SSatish Balay 
2836b72add0SBarry Smith PETSC_EXTERN void snessetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
2848e27ec22SSatish Balay {
2858434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
2865975b3b6SBarry Smith   if (*ierr) return;
28789e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
2885975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2895975b3b6SBarry Smith   if (*ierr) return;
29089e00c7dSSatish Balay #endif
291aecf964fSBarry Smith   *ierr = SNESSetFunction(*snes, *r, oursnesfunction, NULL);
2928e27ec22SSatish Balay }
293c79ef259SPeter Brune 
294f51a5268SBarry Smith PETSC_EXTERN void snessetfunctionnointerface_(SNES *snes, Vec *r, SNESFunctionFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
295f51a5268SBarry Smith {
296f51a5268SBarry Smith   snessetfunction_(snes, r, func, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
297f51a5268SBarry Smith }
298f51a5268SBarry Smith 
299f51a5268SBarry Smith PETSC_EXTERN void snessetobjective_(SNES *snes, SNESObjectiveFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
300c00ad2bcSBarry Smith {
301c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective, (PetscVoidFn *)func, ctx);
302c00ad2bcSBarry Smith   if (*ierr) return;
303c00ad2bcSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
304c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective_pgiptr, NULL, ptr);
305c00ad2bcSBarry Smith   if (*ierr) return;
306c00ad2bcSBarry Smith #endif
307c00ad2bcSBarry Smith   *ierr = SNESSetObjective(*snes, oursnesobjective, NULL);
308c00ad2bcSBarry Smith }
309c00ad2bcSBarry Smith 
310f51a5268SBarry Smith PETSC_EXTERN void snessetobjectivenointerface_(SNES *snes, SNESObjectiveFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
311f51a5268SBarry Smith {
312f51a5268SBarry Smith   snessetobjective_(snes, func, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
313f51a5268SBarry Smith }
314f51a5268SBarry Smith 
31519caf8f3SSatish Balay PETSC_EXTERN void snessetngs_(SNES *snes, void (*func)(SNES *, Vec *, Vec *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
316c79ef259SPeter Brune {
3178434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.ngs, (PetscVoidFn *)func, ctx);
3185975b3b6SBarry Smith   if (*ierr) return;
319aecf964fSBarry Smith   *ierr = SNESSetNGS(*snes, oursnesngs, NULL);
320c79ef259SPeter Brune }
32119caf8f3SSatish Balay PETSC_EXTERN void snessetupdate_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscErrorCode *), PetscErrorCode *ierr)
322dfef22ccSBarry Smith {
3238434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.update, (PetscVoidFn *)func, NULL);
3245975b3b6SBarry Smith   if (*ierr) return;
325aecf964fSBarry Smith   *ierr = SNESSetUpdate(*snes, oursnesupdate);
326dfef22ccSBarry Smith }
3278e27ec22SSatish Balay 
3288e27ec22SSatish Balay /* the func argument is ignored */
3296b72add0SBarry Smith PETSC_EXTERN void snesgetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void **ctx, PetscErrorCode *ierr)
3308e27ec22SSatish Balay {
3318e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(r);
3325975b3b6SBarry Smith   *ierr = SNESGetFunction(*snes, r, NULL, NULL);
3335975b3b6SBarry Smith   if (*ierr) return;
3348434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)PETSC_NULL_FUNCTION_Fortran) return;
3350298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function, NULL, ctx);
3368e27ec22SSatish Balay }
337c79ef259SPeter Brune 
33819caf8f3SSatish Balay PETSC_EXTERN void snesgetngs_(SNES *snes, void *func, void **ctx, PetscErrorCode *ierr)
339c79ef259SPeter Brune {
340be95d8f1SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.ngs, NULL, ctx);
341c79ef259SPeter Brune }
342c79ef259SPeter Brune 
34369c1e2abSSatish Balay PETSC_EXTERN void snesconvergeddefault_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3443f149594SLisandro Dalcin {
3458d359177SBarry Smith   *ierr = SNESConvergedDefault(*snes, *it, *a, *b, *c, r, ct);
3463f149594SLisandro Dalcin }
3473f149594SLisandro Dalcin 
348e07f7f94SSatish Balay PETSC_EXTERN void snesconvergedskip_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3493f149594SLisandro Dalcin {
350e2a6519dSDmitry Karpeev   *ierr = SNESConvergedSkip(*snes, *it, *a, *b, *c, r, ct);
3513f149594SLisandro Dalcin }
3523f149594SLisandro Dalcin 
35319caf8f3SSatish Balay PETSC_EXTERN void snessetconvergencetest_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), void *cctx, void (*destroy)(void *), PetscErrorCode *ierr)
3548e27ec22SSatish Balay {
3553f22127dSBarry Smith   CHKFORTRANNULLFUNCTION(destroy);
3563f149594SLisandro Dalcin 
3578434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergeddefault_) {
358dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedDefault, NULL, NULL);
3598434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergedskip_) {
360dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedSkip, NULL, NULL);
3618e27ec22SSatish Balay   } else {
3628434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.test, (PetscVoidFn *)func, cctx);
3635975b3b6SBarry Smith     if (*ierr) return;
3648434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.destroy, (PetscVoidFn *)destroy, cctx);
3655975b3b6SBarry Smith     if (*ierr) return;
366aecf964fSBarry Smith     *ierr = SNESSetConvergenceTest(*snes, oursnestest, *snes, ourdestroy);
3678e27ec22SSatish Balay   }
3688e27ec22SSatish Balay }
3698e27ec22SSatish Balay 
37019caf8f3SSatish Balay PETSC_EXTERN void snesgetconvergencehistory_(SNES *snes, PetscInt *na, PetscErrorCode *ierr)
3718e27ec22SSatish Balay {
3720298fd71SBarry Smith   *ierr = SNESGetConvergenceHistory(*snes, NULL, NULL, na);
3738e27ec22SSatish Balay }
3748e27ec22SSatish Balay 
37552f0073cSBarry Smith PETSC_EXTERN void snesmonitordefault_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3768e27ec22SSatish Balay {
377410efd14SBarry Smith   *ierr = SNESMonitorDefault(*snes, *its, *fgnorm, *dummy);
3788e27ec22SSatish Balay }
3798e27ec22SSatish Balay 
38052f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolution_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3818e27ec22SSatish Balay {
382410efd14SBarry Smith   *ierr = SNESMonitorSolution(*snes, *its, *fgnorm, *dummy);
3838e27ec22SSatish Balay }
3848e27ec22SSatish Balay 
38552f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolutionupdate_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3868e27ec22SSatish Balay {
387410efd14SBarry Smith   *ierr = SNESMonitorSolutionUpdate(*snes, *its, *fgnorm, *dummy);
3888e27ec22SSatish Balay }
3898e27ec22SSatish Balay 
39019caf8f3SSatish Balay PETSC_EXTERN void snesmonitorset_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), void *mctx, void (*mondestroy)(void *, PetscErrorCode *), PetscErrorCode *ierr)
3918e27ec22SSatish Balay {
392aecf964fSBarry Smith   CHKFORTRANNULLFUNCTION(mondestroy);
3938434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitordefault_) {
394*49abdd8aSBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode (*)(SNES, PetscInt, PetscReal, void *))SNESMonitorDefault, *(PetscViewerAndFormat **)mctx, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy);
3958434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolution_) {
396*49abdd8aSBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode (*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolution, *(PetscViewerAndFormat **)mctx, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy);
3978434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolutionupdate_) {
398*49abdd8aSBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode (*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolutionUpdate, *(PetscViewerAndFormat **)mctx, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy);
3998e27ec22SSatish Balay   } else {
4008434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.monitor, (PetscVoidFn *)func, mctx);
4015975b3b6SBarry Smith     if (*ierr) return;
4028434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.mondestroy, (PetscVoidFn *)mondestroy, mctx);
4035975b3b6SBarry Smith     if (*ierr) return;
404aecf964fSBarry Smith     *ierr = SNESMonitorSet(*snes, oursnesmonitor, *snes, ourmondestroy);
4058e27ec22SSatish Balay   }
4068e27ec22SSatish Balay }
407