xref: /petsc/src/snes/interface/ftn-custom/zsnesf.c (revision 5d83a8b16d06840f96948f1a43aa9c83c769a60a)
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
86ce558aeSBarry Smith   #define snessolve_                       SNESSOLVE
98d359177SBarry Smith   #define snescomputejacobiandefault_      SNESCOMPUTEJACOBIANDEFAULT
108d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ SNESCOMPUTEJACOBIANDEFAULTCOLOR
118e27ec22SSatish Balay   #define snessetjacobian_                 SNESSETJACOBIAN
1217a42bb7SSatish Balay   #define snessetjacobian1_                SNESSETJACOBIAN1
1317a42bb7SSatish Balay   #define snessetjacobian2_                SNESSETJACOBIAN2
148e27ec22SSatish Balay   #define snessetfunction_                 SNESSETFUNCTION
15c00ad2bcSBarry Smith   #define snessetobjective_                SNESSETOBJECTIVE
16be95d8f1SBarry Smith   #define snessetngs_                      SNESSETNGS
17dfef22ccSBarry Smith   #define snessetupdate_                   SNESSETUPDATE
188e27ec22SSatish Balay   #define snesgetfunction_                 SNESGETFUNCTION
19be95d8f1SBarry Smith   #define snesgetngs_                      SNESGETNGS
208e27ec22SSatish Balay   #define snessetconvergencetest_          SNESSETCONVERGENCETEST
218d359177SBarry Smith   #define snesconvergeddefault_            SNESCONVERGEDDEFAULT
22e07f7f94SSatish Balay   #define snesconvergedskip_               SNESCONVERGEDSKIP
238e27ec22SSatish Balay   #define snesgetconvergencehistory_       SNESGETCONVERGENCEHISTORY
248e27ec22SSatish Balay   #define snesgetjacobian_                 SNESGETJACOBIAN
25a6570f20SBarry Smith   #define snesmonitordefault_              SNESMONITORDEFAULT
26a6570f20SBarry Smith   #define snesmonitorsolution_             SNESMONITORSOLUTION
27a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       SNESMONITORSOLUTIONUPDATE
28a6570f20SBarry Smith   #define snesmonitorset_                  SNESMONITORSET
29c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         SNESNEWTONTRSETPRECHECK
303b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        SNESNEWTONTRSETPOSTCHECK
3141ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       SNESNEWTONTRDCSETPRECHECK
3241ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      SNESNEWTONTRDCSETPOSTCHECK
33*5d83a8b1SBarry Smith   #define matmffdcomputejacobian_          MATMFFDCOMPUTEJACOBIAN
344e2a09fcSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
35df2570feSBarry Smith   #define snessetpicard_                   snessetpicard
366ce558aeSBarry Smith   #define snessolve_                       snessolve
378d359177SBarry Smith   #define snescomputejacobiandefault_      snescomputejacobiandefault
388d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ snescomputejacobiandefaultcolor
398e27ec22SSatish Balay   #define snessetjacobian_                 snessetjacobian
4017a42bb7SSatish Balay   #define snessetjacobian1_                snessetjacobian1
4117a42bb7SSatish Balay   #define snessetjacobian2_                snessetjacobian2
428e27ec22SSatish Balay   #define snessetfunction_                 snessetfunction
43c00ad2bcSBarry Smith   #define snessetobjective_                snessetobjective
44be95d8f1SBarry Smith   #define snessetngs_                      snessetngs
45dfef22ccSBarry Smith   #define snessetupdate_                   snessetupdate
468e27ec22SSatish Balay   #define snesgetfunction_                 snesgetfunction
47be95d8f1SBarry Smith   #define snesgetngs_                      snesgetngs
488e27ec22SSatish Balay   #define snessetconvergencetest_          snessetconvergencetest
498d359177SBarry Smith   #define snesconvergeddefault_            snesconvergeddefault
50e07f7f94SSatish Balay   #define snesconvergedskip_               snesconvergedskip
518e27ec22SSatish Balay   #define snesgetjacobian_                 snesgetjacobian
528e27ec22SSatish Balay   #define snesgetconvergencehistory_       snesgetconvergencehistory
53a6570f20SBarry Smith   #define snesmonitordefault_              snesmonitordefault
54a6570f20SBarry Smith   #define snesmonitorsolution_             snesmonitorsolution
55a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       snesmonitorsolutionupdate
56a6570f20SBarry Smith   #define snesmonitorset_                  snesmonitorset
57c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         snesnewtontrsetprecheck
583b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        snesnewtontrsetpostcheck
5941ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       snesnewtontrdcsetprecheck
6041ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      snesnewtontrdcsetpostcheck
61*5d83a8b1SBarry Smith   #define matmffdcomputejacobian_          matmffdcomputejacobian
628e27ec22SSatish Balay #endif
638e27ec22SSatish Balay 
64f6291634SJed Brown static struct {
65f6291634SJed Brown   PetscFortranCallbackId function;
66c00ad2bcSBarry Smith   PetscFortranCallbackId objective;
67f6291634SJed Brown   PetscFortranCallbackId test;
68f6291634SJed Brown   PetscFortranCallbackId destroy;
69f6291634SJed Brown   PetscFortranCallbackId jacobian;
70f6291634SJed Brown   PetscFortranCallbackId monitor;
71f6291634SJed Brown   PetscFortranCallbackId mondestroy;
72be95d8f1SBarry Smith   PetscFortranCallbackId ngs;
73dfef22ccSBarry Smith   PetscFortranCallbackId update;
74c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck;
757cb011f5SBarry Smith   PetscFortranCallbackId trpostcheck;
7689e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
7789e00c7dSSatish Balay   PetscFortranCallbackId function_pgiptr;
78c00ad2bcSBarry Smith   PetscFortranCallbackId objective_pgiptr;
79c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck_pgiptr;
803c2ee7eaSBarry Smith   PetscFortranCallbackId trpostcheck_pgiptr;
8189e00c7dSSatish Balay #endif
82f6291634SJed Brown } _cb;
8390b77ac2SPeter Brune 
84c9368356SGlenn Hammond static PetscErrorCode ourtrprecheckfunction(SNES snes, Vec x, Vec y, PetscBool *changed_y, void *ctx)
85c9368356SGlenn Hammond {
86c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
87c9368356SGlenn Hammond   void *ptr;
883ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trprecheck_pgiptr, NULL, &ptr));
89c9368356SGlenn Hammond #endif
90c9368356SGlenn 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)));
91c9368356SGlenn Hammond }
92c9368356SGlenn Hammond 
9319caf8f3SSatish Balay PETSC_EXTERN void snesnewtontrsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
94c9368356SGlenn Hammond {
958434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFn *)func, ctx);
963ba16761SJacob Faibussowitsch   if (*ierr) return;
97c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
983ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
993ba16761SJacob Faibussowitsch   if (*ierr) return;
100c9368356SGlenn Hammond #endif
1013ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPreCheck(*snes, ourtrprecheckfunction, NULL);
102c9368356SGlenn Hammond }
103c9368356SGlenn Hammond 
10441ba4c6cSHeeho Park PETSC_EXTERN void snesnewtontrdcsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
10541ba4c6cSHeeho Park {
1068434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFn *)func, ctx);
1073ba16761SJacob Faibussowitsch   if (*ierr) return;
10841ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1093ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
1103ba16761SJacob Faibussowitsch   if (*ierr) return;
11141ba4c6cSHeeho Park #endif
1123ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPreCheck(*snes, ourtrprecheckfunction, NULL);
11341ba4c6cSHeeho Park }
11441ba4c6cSHeeho Park 
115c9368356SGlenn Hammond static PetscErrorCode ourtrpostcheckfunction(SNES snes, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *ctx)
1167cb011f5SBarry Smith {
1177cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1187cb011f5SBarry Smith   void *ptr;
1193ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trpostcheck_pgiptr, NULL, &ptr));
1207cb011f5SBarry Smith #endif
121c9368356SGlenn 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)));
1227cb011f5SBarry Smith }
1237cb011f5SBarry Smith 
12419caf8f3SSatish 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))
1257cb011f5SBarry Smith {
1268434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFn *)func, ctx);
1273ba16761SJacob Faibussowitsch   if (*ierr) return;
1287cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1293ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1303ba16761SJacob Faibussowitsch   if (*ierr) return;
1317cb011f5SBarry Smith #endif
1323ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
1337cb011f5SBarry Smith }
1347cb011f5SBarry Smith 
13541ba4c6cSHeeho 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))
13641ba4c6cSHeeho Park {
1378434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFn *)func, ctx);
1383ba16761SJacob Faibussowitsch   if (*ierr) return;
13941ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1403ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1413ba16761SJacob Faibussowitsch   if (*ierr) return;
14241ba4c6cSHeeho Park #endif
1433ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
14441ba4c6cSHeeho Park }
14541ba4c6cSHeeho Park 
1468e27ec22SSatish Balay static PetscErrorCode oursnesfunction(SNES snes, Vec x, Vec f, void *ctx)
1478e27ec22SSatish Balay {
14889e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
14989e00c7dSSatish Balay   void *ptr;
1503ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
15189e00c7dSSatish Balay #endif
15289e00c7dSSatish 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)));
1538e27ec22SSatish Balay }
154b8ebb45fSBarry Smith 
155c00ad2bcSBarry Smith static PetscErrorCode oursnesobjective(SNES snes, Vec x, PetscReal *v, void *ctx)
156c00ad2bcSBarry Smith {
157c00ad2bcSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
158c00ad2bcSBarry Smith   void *ptr;
159c00ad2bcSBarry Smith   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.objective_pgiptr, NULL, &ptr));
160c00ad2bcSBarry Smith #endif
161c00ad2bcSBarry 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)));
162c00ad2bcSBarry Smith }
163c00ad2bcSBarry Smith 
16406ee9f85SBarry Smith static PetscErrorCode oursnestest(SNES snes, PetscInt it, PetscReal a, PetscReal d, PetscReal c, SNESConvergedReason *reason, void *ctx)
1658e27ec22SSatish Balay {
166f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.test, (SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), (&snes, &it, &a, &d, &c, reason, _ctx, &ierr));
1677f7931b9SBarry Smith }
1687f7931b9SBarry Smith 
1697f7931b9SBarry Smith static PetscErrorCode ourdestroy(void *ctx)
1707f7931b9SBarry Smith {
171f6291634SJed Brown   PetscObjectUseFortranCallback(ctx, _cb.destroy, (void *, PetscErrorCode *), (_ctx, &ierr));
1728e27ec22SSatish Balay }
1738e27ec22SSatish Balay 
174d1e9a80fSBarry Smith static PetscErrorCode oursnesjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
1758e27ec22SSatish Balay {
176d1e9a80fSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
1778e27ec22SSatish Balay }
178f6291634SJed Brown 
179dfef22ccSBarry Smith static PetscErrorCode oursnesupdate(SNES snes, PetscInt i)
180dfef22ccSBarry Smith {
181dfef22ccSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.update, (SNES *, PetscInt *, PetscErrorCode *), (&snes, &i, &ierr));
182dfef22ccSBarry Smith }
183be95d8f1SBarry Smith static PetscErrorCode oursnesngs(SNES snes, Vec x, Vec b, void *ctx)
18490b77ac2SPeter Brune {
185be95d8f1SBarry Smith   PetscObjectUseFortranCallback(snes, _cb.ngs, (SNES *, Vec *, Vec *, void *, PetscErrorCode *), (&snes, &x, &b, _ctx, &ierr));
18690b77ac2SPeter Brune }
1878e27ec22SSatish Balay static PetscErrorCode oursnesmonitor(SNES snes, PetscInt i, PetscReal d, void *ctx)
1888e27ec22SSatish Balay {
189f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.monitor, (SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), (&snes, &i, &d, _ctx, &ierr));
1908e27ec22SSatish Balay }
191c2efdce3SBarry Smith static PetscErrorCode ourmondestroy(void **ctx)
1928e27ec22SSatish Balay {
193f6291634SJed Brown   SNES snes = (SNES)*ctx;
194f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.mondestroy, (void *, PetscErrorCode *), (_ctx, &ierr));
1958e27ec22SSatish Balay }
1968e27ec22SSatish Balay 
197*5d83a8b1SBarry Smith /* these are generated automatically by bfort */
198*5d83a8b1SBarry Smith PETSC_EXTERN void snescomputejacobiandefault_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
199*5d83a8b1SBarry Smith PETSC_EXTERN void snescomputejacobiandefaultcolor_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
200*5d83a8b1SBarry Smith PETSC_EXTERN void matmffdcomputejacobian_(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *);
2018e27ec22SSatish Balay 
2025975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
2038e27ec22SSatish Balay {
204f5b6597dSBarry Smith   CHKFORTRANNULLFUNCTION(func);
2058434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefault_) {
2068d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefault, ctx);
2078434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefaultcolor_) {
208e025ade3SBarry Smith     if (!ctx) {
209e025ade3SBarry Smith       *ierr = PETSC_ERR_ARG_NULL;
210e025ade3SBarry Smith       return;
211e025ade3SBarry Smith     }
2128d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefaultColor, *(MatFDColoring *)ctx);
2138434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)matmffdcomputejacobian_) {
214df66969eSBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, MatMFFDComputeJacobian, ctx);
2158e27ec22SSatish Balay   } else {
2168434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)func, ctx);
2170298fd71SBarry Smith     if (!*ierr) *ierr = SNESSetJacobian(*snes, *A, *B, oursnesjacobian, NULL);
2188e27ec22SSatish Balay   }
2198e27ec22SSatish Balay }
2205975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian1_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
22117a42bb7SSatish Balay {
22217a42bb7SSatish Balay   snessetjacobian_(snes, A, B, func, ctx, ierr);
22317a42bb7SSatish Balay }
2245975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian2_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
22517a42bb7SSatish Balay {
22617a42bb7SSatish Balay   snessetjacobian_(snes, A, B, func, ctx, ierr);
22717a42bb7SSatish Balay }
228f6dfbefdSBarry Smith 
229df2570feSBarry Smith static PetscErrorCode oursnespicardfunction(SNES snes, Vec x, Vec f, void *ctx)
230df2570feSBarry Smith {
231df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
232df2570feSBarry Smith   void *ptr;
2333ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
234df2570feSBarry Smith #endif
235df2570feSBarry 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)));
236df2570feSBarry Smith }
237df2570feSBarry Smith 
238df2570feSBarry Smith static PetscErrorCode oursnespicardjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
239df2570feSBarry Smith {
240df2570feSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
241df2570feSBarry Smith }
242df2570feSBarry Smith 
2435975b3b6SBarry Smith PETSC_EXTERN void snessetpicard_(SNES *snes, Vec *r, void (*func)(SNES *, Vec *, Vec *, void *, PetscErrorCode *), Mat *A, Mat *B, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
244df2570feSBarry Smith {
2458434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
246df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
2475975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2485975b3b6SBarry Smith   if (*ierr) return;
249df2570feSBarry Smith #endif
2508434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)J, ctx);
251df2570feSBarry Smith   if (!*ierr) *ierr = SNESSetPicard(*snes, *r, oursnespicardfunction, *A, *B, oursnespicardjacobian, NULL);
252df2570feSBarry Smith }
2538e27ec22SSatish Balay 
2548e27ec22SSatish Balay /*
2558e27ec22SSatish Balay    These are not usually called from Fortran but allow Fortran users
2568e27ec22SSatish Balay    to transparently set these monitors from .F code
2578e27ec22SSatish Balay */
2588e27ec22SSatish Balay 
2596b72add0SBarry Smith PETSC_EXTERN void snessetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
2608e27ec22SSatish Balay {
2618434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
2625975b3b6SBarry Smith   if (*ierr) return;
26389e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
2645975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2655975b3b6SBarry Smith   if (*ierr) return;
26689e00c7dSSatish Balay #endif
267aecf964fSBarry Smith   *ierr = SNESSetFunction(*snes, *r, oursnesfunction, NULL);
2688e27ec22SSatish Balay }
269c79ef259SPeter Brune 
270c00ad2bcSBarry Smith PETSC_EXTERN void snessetobjective_(SNES *snes, void (*func)(SNES *, Vec *, PetscReal *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
271c00ad2bcSBarry Smith {
272c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective, (PetscVoidFn *)func, ctx);
273c00ad2bcSBarry Smith   if (*ierr) return;
274c00ad2bcSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
275c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective_pgiptr, NULL, ptr);
276c00ad2bcSBarry Smith   if (*ierr) return;
277c00ad2bcSBarry Smith #endif
278c00ad2bcSBarry Smith   *ierr = SNESSetObjective(*snes, oursnesobjective, NULL);
279c00ad2bcSBarry Smith }
280c00ad2bcSBarry Smith 
28119caf8f3SSatish Balay PETSC_EXTERN void snessetngs_(SNES *snes, void (*func)(SNES *, Vec *, Vec *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
282c79ef259SPeter Brune {
2838434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.ngs, (PetscVoidFn *)func, ctx);
2845975b3b6SBarry Smith   if (*ierr) return;
285aecf964fSBarry Smith   *ierr = SNESSetNGS(*snes, oursnesngs, NULL);
286c79ef259SPeter Brune }
28719caf8f3SSatish Balay PETSC_EXTERN void snessetupdate_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscErrorCode *), PetscErrorCode *ierr)
288dfef22ccSBarry Smith {
2898434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.update, (PetscVoidFn *)func, NULL);
2905975b3b6SBarry Smith   if (*ierr) return;
291aecf964fSBarry Smith   *ierr = SNESSetUpdate(*snes, oursnesupdate);
292dfef22ccSBarry Smith }
2938e27ec22SSatish Balay 
2948e27ec22SSatish Balay /* the func argument is ignored */
2956b72add0SBarry Smith PETSC_EXTERN void snesgetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void **ctx, PetscErrorCode *ierr)
2968e27ec22SSatish Balay {
2978e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(r);
2985975b3b6SBarry Smith   *ierr = SNESGetFunction(*snes, r, NULL, NULL);
2995975b3b6SBarry Smith   if (*ierr) return;
3008434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)PETSC_NULL_FUNCTION_Fortran) return;
3010298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function, NULL, ctx);
3028e27ec22SSatish Balay }
303c79ef259SPeter Brune 
30419caf8f3SSatish Balay PETSC_EXTERN void snesgetngs_(SNES *snes, void *func, void **ctx, PetscErrorCode *ierr)
305c79ef259SPeter Brune {
306be95d8f1SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.ngs, NULL, ctx);
307c79ef259SPeter Brune }
308c79ef259SPeter Brune 
30969c1e2abSSatish Balay PETSC_EXTERN void snesconvergeddefault_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3103f149594SLisandro Dalcin {
3118d359177SBarry Smith   *ierr = SNESConvergedDefault(*snes, *it, *a, *b, *c, r, ct);
3123f149594SLisandro Dalcin }
3133f149594SLisandro Dalcin 
314e07f7f94SSatish Balay PETSC_EXTERN void snesconvergedskip_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3153f149594SLisandro Dalcin {
316e2a6519dSDmitry Karpeev   *ierr = SNESConvergedSkip(*snes, *it, *a, *b, *c, r, ct);
3173f149594SLisandro Dalcin }
3183f149594SLisandro Dalcin 
31919caf8f3SSatish Balay PETSC_EXTERN void snessetconvergencetest_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), void *cctx, void (*destroy)(void *), PetscErrorCode *ierr)
3208e27ec22SSatish Balay {
3213f22127dSBarry Smith   CHKFORTRANNULLFUNCTION(destroy);
3223f149594SLisandro Dalcin 
3238434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergeddefault_) {
324dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedDefault, NULL, NULL);
3258434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergedskip_) {
326dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedSkip, NULL, NULL);
3278e27ec22SSatish Balay   } else {
3288434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.test, (PetscVoidFn *)func, cctx);
3295975b3b6SBarry Smith     if (*ierr) return;
3308434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.destroy, (PetscVoidFn *)destroy, cctx);
3315975b3b6SBarry Smith     if (*ierr) return;
332aecf964fSBarry Smith     *ierr = SNESSetConvergenceTest(*snes, oursnestest, *snes, ourdestroy);
3338e27ec22SSatish Balay   }
3348e27ec22SSatish Balay }
3358e27ec22SSatish Balay 
3368e27ec22SSatish Balay /*  func is currently ignored from Fortran */
33719caf8f3SSatish Balay PETSC_EXTERN void snesgetjacobian_(SNES *snes, Mat *A, Mat *B, int *func, void **ctx, PetscErrorCode *ierr)
3388e27ec22SSatish Balay {
3398e27ec22SSatish Balay   CHKFORTRANNULLINTEGER(ctx);
3408e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(A);
3418e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(B);
342dfef5ea7SSatish Balay   *ierr = SNESGetJacobian(*snes, A, B, NULL, NULL);
3435975b3b6SBarry Smith   if (*ierr) return;
3440298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.jacobian, NULL, ctx);
3458e27ec22SSatish Balay }
3468e27ec22SSatish Balay 
34719caf8f3SSatish Balay PETSC_EXTERN void snesgetconvergencehistory_(SNES *snes, PetscInt *na, PetscErrorCode *ierr)
3488e27ec22SSatish Balay {
3490298fd71SBarry Smith   *ierr = SNESGetConvergenceHistory(*snes, NULL, NULL, na);
3508e27ec22SSatish Balay }
3518e27ec22SSatish Balay 
35252f0073cSBarry Smith PETSC_EXTERN void snesmonitordefault_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3538e27ec22SSatish Balay {
354410efd14SBarry Smith   *ierr = SNESMonitorDefault(*snes, *its, *fgnorm, *dummy);
3558e27ec22SSatish Balay }
3568e27ec22SSatish Balay 
35752f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolution_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3588e27ec22SSatish Balay {
359410efd14SBarry Smith   *ierr = SNESMonitorSolution(*snes, *its, *fgnorm, *dummy);
3608e27ec22SSatish Balay }
3618e27ec22SSatish Balay 
36252f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolutionupdate_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3638e27ec22SSatish Balay {
364410efd14SBarry Smith   *ierr = SNESMonitorSolutionUpdate(*snes, *its, *fgnorm, *dummy);
3658e27ec22SSatish Balay }
3668e27ec22SSatish Balay 
36719caf8f3SSatish Balay PETSC_EXTERN void snesmonitorset_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), void *mctx, void (*mondestroy)(void *, PetscErrorCode *), PetscErrorCode *ierr)
3688e27ec22SSatish Balay {
369aecf964fSBarry Smith   CHKFORTRANNULLFUNCTION(mondestroy);
3708434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitordefault_) {
3711cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorDefault, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
3728434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolution_) {
3731cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolution, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
3748434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolutionupdate_) {
3751cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolutionUpdate, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
3768e27ec22SSatish Balay   } else {
3778434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.monitor, (PetscVoidFn *)func, mctx);
3785975b3b6SBarry Smith     if (*ierr) return;
3798434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.mondestroy, (PetscVoidFn *)mondestroy, mctx);
3805975b3b6SBarry Smith     if (*ierr) return;
381aecf964fSBarry Smith     *ierr = SNESMonitorSet(*snes, oursnesmonitor, *snes, ourmondestroy);
3828e27ec22SSatish Balay   }
3838e27ec22SSatish Balay }
384