xref: /petsc/src/snes/interface/ftn-custom/zsnesf.c (revision 5b669ad3ce6cd664db9332dbc899e086ae7cd27f)
16dd63270SBarry Smith #include <petsc/private/ftnimpl.h>
2c6db04a5SJed Brown #include <petscsnes.h>
3665c2dedSJed Brown #include <petscviewer.h>
46dd63270SBarry Smith #include <petsc/private/ftnimpl.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 snesgetjacobian_                 SNESGETJACOBIAN
26a6570f20SBarry Smith   #define snesmonitordefault_              SNESMONITORDEFAULT
27a6570f20SBarry Smith   #define snesmonitorsolution_             SNESMONITORSOLUTION
28a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       SNESMONITORSOLUTIONUPDATE
29a6570f20SBarry Smith   #define snesmonitorset_                  SNESMONITORSET
30c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         SNESNEWTONTRSETPRECHECK
313b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        SNESNEWTONTRSETPOSTCHECK
3241ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       SNESNEWTONTRDCSETPRECHECK
3341ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      SNESNEWTONTRDCSETPOSTCHECK
345d83a8b1SBarry Smith   #define matmffdcomputejacobian_          MATMFFDCOMPUTEJACOBIAN
354e2a09fcSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
36df2570feSBarry Smith   #define snessetpicard_                   snessetpicard
37f51a5268SBarry Smith   #define snessetpicardnointerface_        snessetpicardnointerface
386ce558aeSBarry Smith   #define snessolve_                       snessolve
398d359177SBarry Smith   #define snescomputejacobiandefault_      snescomputejacobiandefault
408d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ snescomputejacobiandefaultcolor
418e27ec22SSatish Balay   #define snessetjacobian_                 snessetjacobian
42f51a5268SBarry Smith   #define snessetjacobiannointerface_      snessetjacobiannointerface
438e27ec22SSatish Balay   #define snessetfunction_                 snessetfunction
44f51a5268SBarry Smith   #define snessetfunctionnointerface_      snessetfunctionnointerface
45c00ad2bcSBarry Smith   #define snessetobjective_                snessetobjective
46f51a5268SBarry Smith   #define snessetobjectivenointerface_     snessetobjectivenointerface
47be95d8f1SBarry Smith   #define snessetngs_                      snessetngs
48dfef22ccSBarry Smith   #define snessetupdate_                   snessetupdate
498e27ec22SSatish Balay   #define snesgetfunction_                 snesgetfunction
50be95d8f1SBarry Smith   #define snesgetngs_                      snesgetngs
518e27ec22SSatish Balay   #define snessetconvergencetest_          snessetconvergencetest
528d359177SBarry Smith   #define snesconvergeddefault_            snesconvergeddefault
53e07f7f94SSatish Balay   #define snesconvergedskip_               snesconvergedskip
548e27ec22SSatish Balay   #define snesgetjacobian_                 snesgetjacobian
55a6570f20SBarry Smith   #define snesmonitordefault_              snesmonitordefault
56a6570f20SBarry Smith   #define snesmonitorsolution_             snesmonitorsolution
57a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       snesmonitorsolutionupdate
58a6570f20SBarry Smith   #define snesmonitorset_                  snesmonitorset
59c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         snesnewtontrsetprecheck
603b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        snesnewtontrsetpostcheck
6141ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       snesnewtontrdcsetprecheck
6241ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      snesnewtontrdcsetpostcheck
635d83a8b1SBarry Smith   #define matmffdcomputejacobian_          matmffdcomputejacobian
648e27ec22SSatish Balay #endif
658e27ec22SSatish Balay 
66f6291634SJed Brown static struct {
67f6291634SJed Brown   PetscFortranCallbackId function;
68c00ad2bcSBarry Smith   PetscFortranCallbackId objective;
69f6291634SJed Brown   PetscFortranCallbackId test;
70f6291634SJed Brown   PetscFortranCallbackId destroy;
71f6291634SJed Brown   PetscFortranCallbackId jacobian;
72f6291634SJed Brown   PetscFortranCallbackId monitor;
73f6291634SJed Brown   PetscFortranCallbackId mondestroy;
74be95d8f1SBarry Smith   PetscFortranCallbackId ngs;
75dfef22ccSBarry Smith   PetscFortranCallbackId update;
76c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck;
777cb011f5SBarry Smith   PetscFortranCallbackId trpostcheck;
7889e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
7989e00c7dSSatish Balay   PetscFortranCallbackId function_pgiptr;
80c00ad2bcSBarry Smith   PetscFortranCallbackId objective_pgiptr;
81c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck_pgiptr;
823c2ee7eaSBarry Smith   PetscFortranCallbackId trpostcheck_pgiptr;
8389e00c7dSSatish Balay #endif
84f6291634SJed Brown } _cb;
8590b77ac2SPeter Brune 
86c9368356SGlenn Hammond static PetscErrorCode ourtrprecheckfunction(SNES snes, Vec x, Vec y, PetscBool *changed_y, void *ctx)
87c9368356SGlenn Hammond {
88c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
89c9368356SGlenn Hammond   void *ptr;
903ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trprecheck_pgiptr, NULL, &ptr));
91c9368356SGlenn Hammond #endif
92c9368356SGlenn 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)));
93c9368356SGlenn Hammond }
94c9368356SGlenn Hammond 
9519caf8f3SSatish Balay PETSC_EXTERN void snesnewtontrsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
96c9368356SGlenn Hammond {
978434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFn *)func, ctx);
983ba16761SJacob Faibussowitsch   if (*ierr) return;
99c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
1003ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
1013ba16761SJacob Faibussowitsch   if (*ierr) return;
102c9368356SGlenn Hammond #endif
1033ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPreCheck(*snes, ourtrprecheckfunction, NULL);
104c9368356SGlenn Hammond }
105c9368356SGlenn Hammond 
10641ba4c6cSHeeho Park PETSC_EXTERN void snesnewtontrdcsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
10741ba4c6cSHeeho Park {
1088434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFn *)func, ctx);
1093ba16761SJacob Faibussowitsch   if (*ierr) return;
11041ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1113ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
1123ba16761SJacob Faibussowitsch   if (*ierr) return;
11341ba4c6cSHeeho Park #endif
1143ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPreCheck(*snes, ourtrprecheckfunction, NULL);
11541ba4c6cSHeeho Park }
11641ba4c6cSHeeho Park 
117c9368356SGlenn Hammond static PetscErrorCode ourtrpostcheckfunction(SNES snes, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *ctx)
1187cb011f5SBarry Smith {
1197cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1207cb011f5SBarry Smith   void *ptr;
1213ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trpostcheck_pgiptr, NULL, &ptr));
1227cb011f5SBarry Smith #endif
123c9368356SGlenn 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)));
1247cb011f5SBarry Smith }
1257cb011f5SBarry Smith 
12619caf8f3SSatish 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))
1277cb011f5SBarry Smith {
1288434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFn *)func, ctx);
1293ba16761SJacob Faibussowitsch   if (*ierr) return;
1307cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1313ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1323ba16761SJacob Faibussowitsch   if (*ierr) return;
1337cb011f5SBarry Smith #endif
1343ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
1357cb011f5SBarry Smith }
1367cb011f5SBarry Smith 
13741ba4c6cSHeeho 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))
13841ba4c6cSHeeho Park {
1398434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFn *)func, ctx);
1403ba16761SJacob Faibussowitsch   if (*ierr) return;
14141ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1423ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1433ba16761SJacob Faibussowitsch   if (*ierr) return;
14441ba4c6cSHeeho Park #endif
1453ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
14641ba4c6cSHeeho Park }
14741ba4c6cSHeeho Park 
1488e27ec22SSatish Balay static PetscErrorCode oursnesfunction(SNES snes, Vec x, Vec f, void *ctx)
1498e27ec22SSatish Balay {
15089e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
15189e00c7dSSatish Balay   void *ptr;
1523ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
15389e00c7dSSatish Balay #endif
15489e00c7dSSatish 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)));
1558e27ec22SSatish Balay }
156b8ebb45fSBarry Smith 
157c00ad2bcSBarry Smith static PetscErrorCode oursnesobjective(SNES snes, Vec x, PetscReal *v, void *ctx)
158c00ad2bcSBarry Smith {
159c00ad2bcSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
160c00ad2bcSBarry Smith   void *ptr;
161c00ad2bcSBarry Smith   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.objective_pgiptr, NULL, &ptr));
162c00ad2bcSBarry Smith #endif
163c00ad2bcSBarry 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)));
164c00ad2bcSBarry Smith }
165c00ad2bcSBarry Smith 
16606ee9f85SBarry Smith static PetscErrorCode oursnestest(SNES snes, PetscInt it, PetscReal a, PetscReal d, PetscReal c, SNESConvergedReason *reason, void *ctx)
1678e27ec22SSatish Balay {
168f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.test, (SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), (&snes, &it, &a, &d, &c, reason, _ctx, &ierr));
1697f7931b9SBarry Smith }
1707f7931b9SBarry Smith 
1717f7931b9SBarry Smith static PetscErrorCode ourdestroy(void *ctx)
1727f7931b9SBarry Smith {
173f6291634SJed Brown   PetscObjectUseFortranCallback(ctx, _cb.destroy, (void *, PetscErrorCode *), (_ctx, &ierr));
1748e27ec22SSatish Balay }
1758e27ec22SSatish Balay 
176d1e9a80fSBarry Smith static PetscErrorCode oursnesjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
1778e27ec22SSatish Balay {
178d1e9a80fSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
1798e27ec22SSatish Balay }
180f6291634SJed Brown 
181dfef22ccSBarry Smith static PetscErrorCode oursnesupdate(SNES snes, PetscInt i)
182dfef22ccSBarry Smith {
183dfef22ccSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.update, (SNES *, PetscInt *, PetscErrorCode *), (&snes, &i, &ierr));
184dfef22ccSBarry Smith }
185be95d8f1SBarry Smith static PetscErrorCode oursnesngs(SNES snes, Vec x, Vec b, void *ctx)
18690b77ac2SPeter Brune {
187be95d8f1SBarry Smith   PetscObjectUseFortranCallback(snes, _cb.ngs, (SNES *, Vec *, Vec *, void *, PetscErrorCode *), (&snes, &x, &b, _ctx, &ierr));
18890b77ac2SPeter Brune }
1898e27ec22SSatish Balay static PetscErrorCode oursnesmonitor(SNES snes, PetscInt i, PetscReal d, void *ctx)
1908e27ec22SSatish Balay {
191f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.monitor, (SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), (&snes, &i, &d, _ctx, &ierr));
1928e27ec22SSatish Balay }
193c2efdce3SBarry Smith static PetscErrorCode ourmondestroy(void **ctx)
1948e27ec22SSatish Balay {
195f6291634SJed Brown   SNES snes = (SNES)*ctx;
196f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.mondestroy, (void *, PetscErrorCode *), (_ctx, &ierr));
1978e27ec22SSatish Balay }
1988e27ec22SSatish Balay 
199*5b669ad3SBarry Smith PETSC_EXTERN void snescomputejacobiandefault_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
200*5b669ad3SBarry Smith PETSC_EXTERN void snescomputejacobiandefaultcolor_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
201*5b669ad3SBarry Smith PETSC_EXTERN void matmffdcomputejacobian_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
2028e27ec22SSatish Balay 
203f51a5268SBarry Smith PETSC_EXTERN void snessetjacobian_(SNES *snes, Mat *A, Mat *B, SNESJacobianFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
2048e27ec22SSatish Balay {
205f5b6597dSBarry Smith   CHKFORTRANNULLFUNCTION(func);
2068434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefault_) {
2078d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefault, ctx);
2088434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefaultcolor_) {
209e025ade3SBarry Smith     if (!ctx) {
210e025ade3SBarry Smith       *ierr = PETSC_ERR_ARG_NULL;
211e025ade3SBarry Smith       return;
212e025ade3SBarry Smith     }
2138d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefaultColor, *(MatFDColoring *)ctx);
2148434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)matmffdcomputejacobian_) {
215df66969eSBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, MatMFFDComputeJacobian, ctx);
2168e27ec22SSatish Balay   } else {
2178434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)func, ctx);
2180298fd71SBarry Smith     if (!*ierr) *ierr = SNESSetJacobian(*snes, *A, *B, oursnesjacobian, NULL);
2198e27ec22SSatish Balay   }
2208e27ec22SSatish Balay }
221f51a5268SBarry Smith 
222f51a5268SBarry Smith PETSC_EXTERN void snessetjacobiannointerface_(SNES *snes, Mat *A, Mat *B, SNESJacobianFn J, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
22317a42bb7SSatish Balay {
224f51a5268SBarry Smith   snessetjacobian_(snes, A, B, J, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
22517a42bb7SSatish Balay }
226f51a5268SBarry Smith 
227f51a5268SBarry Smith /*  func is currently ignored from Fortran */
228f51a5268SBarry Smith PETSC_EXTERN void snesgetjacobian_(SNES *snes, Mat *A, Mat *B, int *func, void **ctx, PetscErrorCode *ierr)
22917a42bb7SSatish Balay {
230f51a5268SBarry Smith   SNESJacobianFn *jfunc;
231f51a5268SBarry Smith   void           *jctx;
232f51a5268SBarry Smith 
233f51a5268SBarry Smith   CHKFORTRANNULL(ctx);
234f51a5268SBarry Smith   CHKFORTRANNULLOBJECT(A);
235f51a5268SBarry Smith   CHKFORTRANNULLOBJECT(B);
236f51a5268SBarry Smith   *ierr = SNESGetJacobian(*snes, A, B, &jfunc, &jctx);
237f51a5268SBarry Smith   if (*ierr) return;
238f51a5268SBarry Smith   if (jfunc == SNESComputeJacobianDefault || jfunc == SNESComputeJacobianDefaultColor || jfunc == MatMFFDComputeJacobian) {
239f51a5268SBarry Smith     if (ctx) *ctx = jctx;
240f51a5268SBarry Smith   } else {
241f51a5268SBarry Smith     *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.jacobian, NULL, ctx);
242f51a5268SBarry Smith   }
24317a42bb7SSatish Balay }
244f6dfbefdSBarry Smith 
245df2570feSBarry Smith static PetscErrorCode oursnespicardfunction(SNES snes, Vec x, Vec f, void *ctx)
246df2570feSBarry Smith {
247df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
248df2570feSBarry Smith   void *ptr;
2493ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
250df2570feSBarry Smith #endif
251df2570feSBarry 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)));
252df2570feSBarry Smith }
253df2570feSBarry Smith 
254df2570feSBarry Smith static PetscErrorCode oursnespicardjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
255df2570feSBarry Smith {
256df2570feSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
257df2570feSBarry Smith }
258df2570feSBarry Smith 
259f51a5268SBarry 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))
260df2570feSBarry Smith {
2618434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
262df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
2635975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2645975b3b6SBarry Smith   if (*ierr) return;
265df2570feSBarry Smith #endif
2668434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)J, ctx);
267df2570feSBarry Smith   if (!*ierr) *ierr = SNESSetPicard(*snes, *r, oursnespicardfunction, *A, *B, oursnespicardjacobian, NULL);
268df2570feSBarry Smith }
2698e27ec22SSatish Balay 
270f51a5268SBarry 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))
271f51a5268SBarry Smith {
272f51a5268SBarry Smith   snessetpicard_(snes, r, func, A, B, J, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
273f51a5268SBarry Smith }
274f51a5268SBarry Smith 
2758e27ec22SSatish Balay /*
2768e27ec22SSatish Balay    These are not usually called from Fortran but allow Fortran users
2778e27ec22SSatish Balay    to transparently set these monitors from .F code
2788e27ec22SSatish Balay */
2798e27ec22SSatish Balay 
2806b72add0SBarry Smith PETSC_EXTERN void snessetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
2818e27ec22SSatish Balay {
2828434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
2835975b3b6SBarry Smith   if (*ierr) return;
28489e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
2855975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2865975b3b6SBarry Smith   if (*ierr) return;
28789e00c7dSSatish Balay #endif
288aecf964fSBarry Smith   *ierr = SNESSetFunction(*snes, *r, oursnesfunction, NULL);
2898e27ec22SSatish Balay }
290c79ef259SPeter Brune 
291f51a5268SBarry Smith PETSC_EXTERN void snessetfunctionnointerface_(SNES *snes, Vec *r, SNESFunctionFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
292f51a5268SBarry Smith {
293f51a5268SBarry Smith   snessetfunction_(snes, r, func, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
294f51a5268SBarry Smith }
295f51a5268SBarry Smith 
296f51a5268SBarry Smith PETSC_EXTERN void snessetobjective_(SNES *snes, SNESObjectiveFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
297c00ad2bcSBarry Smith {
298c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective, (PetscVoidFn *)func, ctx);
299c00ad2bcSBarry Smith   if (*ierr) return;
300c00ad2bcSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
301c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective_pgiptr, NULL, ptr);
302c00ad2bcSBarry Smith   if (*ierr) return;
303c00ad2bcSBarry Smith #endif
304c00ad2bcSBarry Smith   *ierr = SNESSetObjective(*snes, oursnesobjective, NULL);
305c00ad2bcSBarry Smith }
306c00ad2bcSBarry Smith 
307f51a5268SBarry Smith PETSC_EXTERN void snessetobjectivenointerface_(SNES *snes, SNESObjectiveFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
308f51a5268SBarry Smith {
309f51a5268SBarry Smith   snessetobjective_(snes, func, ctx, ierr PETSC_F90_2PTR_PARAM(ptr));
310f51a5268SBarry Smith }
311f51a5268SBarry Smith 
31219caf8f3SSatish Balay PETSC_EXTERN void snessetngs_(SNES *snes, void (*func)(SNES *, Vec *, Vec *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
313c79ef259SPeter Brune {
3148434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.ngs, (PetscVoidFn *)func, ctx);
3155975b3b6SBarry Smith   if (*ierr) return;
316aecf964fSBarry Smith   *ierr = SNESSetNGS(*snes, oursnesngs, NULL);
317c79ef259SPeter Brune }
31819caf8f3SSatish Balay PETSC_EXTERN void snessetupdate_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscErrorCode *), PetscErrorCode *ierr)
319dfef22ccSBarry Smith {
3208434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.update, (PetscVoidFn *)func, NULL);
3215975b3b6SBarry Smith   if (*ierr) return;
322aecf964fSBarry Smith   *ierr = SNESSetUpdate(*snes, oursnesupdate);
323dfef22ccSBarry Smith }
3248e27ec22SSatish Balay 
3258e27ec22SSatish Balay /* the func argument is ignored */
3266b72add0SBarry Smith PETSC_EXTERN void snesgetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void **ctx, PetscErrorCode *ierr)
3278e27ec22SSatish Balay {
3288e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(r);
3295975b3b6SBarry Smith   *ierr = SNESGetFunction(*snes, r, NULL, NULL);
3305975b3b6SBarry Smith   if (*ierr) return;
3318434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)PETSC_NULL_FUNCTION_Fortran) return;
3320298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function, NULL, ctx);
3338e27ec22SSatish Balay }
334c79ef259SPeter Brune 
33519caf8f3SSatish Balay PETSC_EXTERN void snesgetngs_(SNES *snes, void *func, void **ctx, PetscErrorCode *ierr)
336c79ef259SPeter Brune {
337be95d8f1SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.ngs, NULL, ctx);
338c79ef259SPeter Brune }
339c79ef259SPeter Brune 
340ce78bad3SBarry Smith PETSC_EXTERN void snesconvergeddefault_(SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *);
341ce78bad3SBarry Smith PETSC_EXTERN void snesconvergedskip_(SNES, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *);
3423f149594SLisandro Dalcin 
34319caf8f3SSatish Balay PETSC_EXTERN void snessetconvergencetest_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), void *cctx, void (*destroy)(void *), PetscErrorCode *ierr)
3448e27ec22SSatish Balay {
3453f22127dSBarry Smith   CHKFORTRANNULLFUNCTION(destroy);
3463f149594SLisandro Dalcin 
3478434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergeddefault_) {
348dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedDefault, NULL, NULL);
3498434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergedskip_) {
350dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedSkip, NULL, NULL);
3518e27ec22SSatish Balay   } else {
3528434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.test, (PetscVoidFn *)func, cctx);
3535975b3b6SBarry Smith     if (*ierr) return;
3548434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.destroy, (PetscVoidFn *)destroy, cctx);
3555975b3b6SBarry Smith     if (*ierr) return;
356aecf964fSBarry Smith     *ierr = SNESSetConvergenceTest(*snes, oursnestest, *snes, ourdestroy);
3578e27ec22SSatish Balay   }
3588e27ec22SSatish Balay }
3598e27ec22SSatish Balay 
360ce78bad3SBarry Smith PETSC_EXTERN void snesmonitordefault_(SNES *, PetscInt *, PetscReal *, PetscViewerAndFormat **, PetscErrorCode *);
3618e27ec22SSatish Balay 
362ce78bad3SBarry Smith PETSC_EXTERN void snesmonitorsolution_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr);
3638e27ec22SSatish Balay 
364ce78bad3SBarry Smith PETSC_EXTERN void snesmonitorsolutionupdate_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr);
3658e27ec22SSatish Balay 
36619caf8f3SSatish Balay PETSC_EXTERN void snesmonitorset_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), void *mctx, void (*mondestroy)(void *, PetscErrorCode *), PetscErrorCode *ierr)
3678e27ec22SSatish Balay {
368aecf964fSBarry Smith   CHKFORTRANNULLFUNCTION(mondestroy);
3698434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitordefault_) {
37049abdd8aSBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode (*)(SNES, PetscInt, PetscReal, void *))SNESMonitorDefault, *(PetscViewerAndFormat **)mctx, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy);
3718434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolution_) {
37249abdd8aSBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode (*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolution, *(PetscViewerAndFormat **)mctx, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy);
3738434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolutionupdate_) {
37449abdd8aSBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode (*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolutionUpdate, *(PetscViewerAndFormat **)mctx, (PetscCtxDestroyFn *)PetscViewerAndFormatDestroy);
3758e27ec22SSatish Balay   } else {
3768434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.monitor, (PetscVoidFn *)func, mctx);
3775975b3b6SBarry Smith     if (*ierr) return;
3788434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.mondestroy, (PetscVoidFn *)mondestroy, mctx);
3795975b3b6SBarry Smith     if (*ierr) return;
380aecf964fSBarry Smith     *ierr = SNESMonitorSet(*snes, oursnesmonitor, *snes, ourmondestroy);
3818e27ec22SSatish Balay   }
3828e27ec22SSatish Balay }
383