xref: /petsc/src/snes/interface/ftn-custom/zsnesf.c (revision 6b72add09e2614d1c97fc1b624e79eae8adfe66c)
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
8df66969eSBarry Smith   #define matmffdcomputejacobian_          MATMFFDCOMPUTEJACOBIAN
96ce558aeSBarry Smith   #define snessolve_                       SNESSOLVE
108d359177SBarry Smith   #define snescomputejacobiandefault_      SNESCOMPUTEJACOBIANDEFAULT
118d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ SNESCOMPUTEJACOBIANDEFAULTCOLOR
128e27ec22SSatish Balay   #define snessetjacobian_                 SNESSETJACOBIAN
1317a42bb7SSatish Balay   #define snessetjacobian1_                SNESSETJACOBIAN1
1417a42bb7SSatish Balay   #define snessetjacobian2_                SNESSETJACOBIAN2
158e27ec22SSatish Balay   #define snessetfunction_                 SNESSETFUNCTION
16c00ad2bcSBarry Smith   #define snessetobjective_                SNESSETOBJECTIVE
17be95d8f1SBarry Smith   #define snessetngs_                      SNESSETNGS
18dfef22ccSBarry Smith   #define snessetupdate_                   SNESSETUPDATE
198e27ec22SSatish Balay   #define snesgetfunction_                 SNESGETFUNCTION
20be95d8f1SBarry Smith   #define snesgetngs_                      SNESGETNGS
218e27ec22SSatish Balay   #define snessetconvergencetest_          SNESSETCONVERGENCETEST
228d359177SBarry Smith   #define snesconvergeddefault_            SNESCONVERGEDDEFAULT
23e07f7f94SSatish Balay   #define snesconvergedskip_               SNESCONVERGEDSKIP
248e27ec22SSatish Balay   #define snesgetconvergencehistory_       SNESGETCONVERGENCEHISTORY
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
344e2a09fcSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
35df2570feSBarry Smith   #define snessetpicard_                   snessetpicard
36df66969eSBarry Smith   #define matmffdcomputejacobian_          matmffdcomputejacobian
376ce558aeSBarry Smith   #define snessolve_                       snessolve
388d359177SBarry Smith   #define snescomputejacobiandefault_      snescomputejacobiandefault
398d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ snescomputejacobiandefaultcolor
408e27ec22SSatish Balay   #define snessetjacobian_                 snessetjacobian
4117a42bb7SSatish Balay   #define snessetjacobian1_                snessetjacobian1
4217a42bb7SSatish Balay   #define snessetjacobian2_                snessetjacobian2
438e27ec22SSatish Balay   #define snessetfunction_                 snessetfunction
44c00ad2bcSBarry Smith   #define snessetobjective_                snessetobjective
45be95d8f1SBarry Smith   #define snessetngs_                      snessetngs
46dfef22ccSBarry Smith   #define snessetupdate_                   snessetupdate
478e27ec22SSatish Balay   #define snesgetfunction_                 snesgetfunction
48be95d8f1SBarry Smith   #define snesgetngs_                      snesgetngs
498e27ec22SSatish Balay   #define snessetconvergencetest_          snessetconvergencetest
508d359177SBarry Smith   #define snesconvergeddefault_            snesconvergeddefault
51e07f7f94SSatish Balay   #define snesconvergedskip_               snesconvergedskip
528e27ec22SSatish Balay   #define snesgetjacobian_                 snesgetjacobian
538e27ec22SSatish Balay   #define snesgetconvergencehistory_       snesgetconvergencehistory
54a6570f20SBarry Smith   #define snesmonitordefault_              snesmonitordefault
55a6570f20SBarry Smith   #define snesmonitorsolution_             snesmonitorsolution
56a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       snesmonitorsolutionupdate
57a6570f20SBarry Smith   #define snesmonitorset_                  snesmonitorset
58c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         snesnewtontrsetprecheck
593b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        snesnewtontrsetpostcheck
6041ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       snesnewtontrdcsetprecheck
6141ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      snesnewtontrdcsetpostcheck
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 
1978e27ec22SSatish Balay /*
1988d359177SBarry Smith      snescomputejacobiandefault() and snescomputejacobiandefaultcolor()
1998e27ec22SSatish Balay   These can be used directly from Fortran but are mostly so that
2008e27ec22SSatish Balay   Fortran SNESSetJacobian() will properly handle the defaults being passed in.
2018e27ec22SSatish Balay */
202d1e9a80fSBarry Smith PETSC_EXTERN void matmffdcomputejacobian_(SNES *snes, Vec *x, Mat *m, Mat *p, void *ctx, PetscErrorCode *ierr)
203df66969eSBarry Smith {
204d1e9a80fSBarry Smith   *ierr = MatMFFDComputeJacobian(*snes, *x, *m, *p, ctx);
205df66969eSBarry Smith }
206d1e9a80fSBarry Smith PETSC_EXTERN void snescomputejacobiandefault_(SNES *snes, Vec *x, Mat *m, Mat *p, void *ctx, PetscErrorCode *ierr)
2078e27ec22SSatish Balay {
208d1e9a80fSBarry Smith   *ierr = SNESComputeJacobianDefault(*snes, *x, *m, *p, ctx);
2098e27ec22SSatish Balay }
210d1e9a80fSBarry Smith PETSC_EXTERN void snescomputejacobiandefaultcolor_(SNES *snes, Vec *x, Mat *m, Mat *p, void *ctx, PetscErrorCode *ierr)
2118e27ec22SSatish Balay {
212d1e9a80fSBarry Smith   *ierr = SNESComputeJacobianDefaultColor(*snes, *x, *m, *p, *(MatFDColoring *)ctx);
2138e27ec22SSatish Balay }
2148e27ec22SSatish Balay 
2155975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
2168e27ec22SSatish Balay {
217f5b6597dSBarry Smith   CHKFORTRANNULLFUNCTION(func);
2188434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefault_) {
2198d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefault, ctx);
2208434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snescomputejacobiandefaultcolor_) {
221e025ade3SBarry Smith     if (!ctx) {
222e025ade3SBarry Smith       *ierr = PETSC_ERR_ARG_NULL;
223e025ade3SBarry Smith       return;
224e025ade3SBarry Smith     }
2258d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefaultColor, *(MatFDColoring *)ctx);
2268434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)matmffdcomputejacobian_) {
227df66969eSBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, MatMFFDComputeJacobian, ctx);
2288e27ec22SSatish Balay   } else {
2298434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)func, ctx);
2300298fd71SBarry Smith     if (!*ierr) *ierr = SNESSetJacobian(*snes, *A, *B, oursnesjacobian, NULL);
2318e27ec22SSatish Balay   }
2328e27ec22SSatish Balay }
2335975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian1_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
23417a42bb7SSatish Balay {
23517a42bb7SSatish Balay   snessetjacobian_(snes, A, B, func, ctx, ierr);
23617a42bb7SSatish Balay }
2375975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian2_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
23817a42bb7SSatish Balay {
23917a42bb7SSatish Balay   snessetjacobian_(snes, A, B, func, ctx, ierr);
24017a42bb7SSatish Balay }
241f6dfbefdSBarry Smith 
242df2570feSBarry Smith static PetscErrorCode oursnespicardfunction(SNES snes, Vec x, Vec f, void *ctx)
243df2570feSBarry Smith {
244df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
245df2570feSBarry Smith   void *ptr;
2463ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
247df2570feSBarry Smith #endif
248df2570feSBarry 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)));
249df2570feSBarry Smith }
250df2570feSBarry Smith 
251df2570feSBarry Smith static PetscErrorCode oursnespicardjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
252df2570feSBarry Smith {
253df2570feSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
254df2570feSBarry Smith }
255df2570feSBarry Smith 
2565975b3b6SBarry 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))
257df2570feSBarry Smith {
2588434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
259df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
2605975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2615975b3b6SBarry Smith   if (*ierr) return;
262df2570feSBarry Smith #endif
2638434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFn *)J, ctx);
264df2570feSBarry Smith   if (!*ierr) *ierr = SNESSetPicard(*snes, *r, oursnespicardfunction, *A, *B, oursnespicardjacobian, NULL);
265df2570feSBarry Smith }
2668e27ec22SSatish Balay 
2678e27ec22SSatish Balay /*
2688e27ec22SSatish Balay    These are not usually called from Fortran but allow Fortran users
2698e27ec22SSatish Balay    to transparently set these monitors from .F code
2708e27ec22SSatish Balay */
2718e27ec22SSatish Balay 
272*6b72add0SBarry Smith PETSC_EXTERN void snessetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
2738e27ec22SSatish Balay {
2748434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFn *)func, ctx);
2755975b3b6SBarry Smith   if (*ierr) return;
27689e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
2775975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2785975b3b6SBarry Smith   if (*ierr) return;
27989e00c7dSSatish Balay #endif
280aecf964fSBarry Smith   *ierr = SNESSetFunction(*snes, *r, oursnesfunction, NULL);
2818e27ec22SSatish Balay }
282c79ef259SPeter Brune 
283c00ad2bcSBarry Smith PETSC_EXTERN void snessetobjective_(SNES *snes, void (*func)(SNES *, Vec *, PetscReal *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
284c00ad2bcSBarry Smith {
285c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective, (PetscVoidFn *)func, ctx);
286c00ad2bcSBarry Smith   if (*ierr) return;
287c00ad2bcSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
288c00ad2bcSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.objective_pgiptr, NULL, ptr);
289c00ad2bcSBarry Smith   if (*ierr) return;
290c00ad2bcSBarry Smith #endif
291c00ad2bcSBarry Smith   *ierr = SNESSetObjective(*snes, oursnesobjective, NULL);
292c00ad2bcSBarry Smith }
293c00ad2bcSBarry Smith 
29419caf8f3SSatish Balay PETSC_EXTERN void snessetngs_(SNES *snes, void (*func)(SNES *, Vec *, Vec *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
295c79ef259SPeter Brune {
2968434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.ngs, (PetscVoidFn *)func, ctx);
2975975b3b6SBarry Smith   if (*ierr) return;
298aecf964fSBarry Smith   *ierr = SNESSetNGS(*snes, oursnesngs, NULL);
299c79ef259SPeter Brune }
30019caf8f3SSatish Balay PETSC_EXTERN void snessetupdate_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscErrorCode *), PetscErrorCode *ierr)
301dfef22ccSBarry Smith {
3028434afd1SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.update, (PetscVoidFn *)func, NULL);
3035975b3b6SBarry Smith   if (*ierr) return;
304aecf964fSBarry Smith   *ierr = SNESSetUpdate(*snes, oursnesupdate);
305dfef22ccSBarry Smith }
3068e27ec22SSatish Balay 
3078e27ec22SSatish Balay /* the func argument is ignored */
308*6b72add0SBarry Smith PETSC_EXTERN void snesgetfunction_(SNES *snes, Vec *r, SNESFunctionFn func, void **ctx, PetscErrorCode *ierr)
3098e27ec22SSatish Balay {
3108e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(r);
3115975b3b6SBarry Smith   *ierr = SNESGetFunction(*snes, r, NULL, NULL);
3125975b3b6SBarry Smith   if (*ierr) return;
3138434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)PETSC_NULL_FUNCTION_Fortran) return;
3140298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function, NULL, ctx);
3158e27ec22SSatish Balay }
316c79ef259SPeter Brune 
31719caf8f3SSatish Balay PETSC_EXTERN void snesgetngs_(SNES *snes, void *func, void **ctx, PetscErrorCode *ierr)
318c79ef259SPeter Brune {
319be95d8f1SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.ngs, NULL, ctx);
320c79ef259SPeter Brune }
321c79ef259SPeter Brune 
32269c1e2abSSatish Balay PETSC_EXTERN void snesconvergeddefault_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3233f149594SLisandro Dalcin {
3248d359177SBarry Smith   *ierr = SNESConvergedDefault(*snes, *it, *a, *b, *c, r, ct);
3253f149594SLisandro Dalcin }
3263f149594SLisandro Dalcin 
327e07f7f94SSatish Balay PETSC_EXTERN void snesconvergedskip_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3283f149594SLisandro Dalcin {
329e2a6519dSDmitry Karpeev   *ierr = SNESConvergedSkip(*snes, *it, *a, *b, *c, r, ct);
3303f149594SLisandro Dalcin }
3313f149594SLisandro Dalcin 
33219caf8f3SSatish Balay PETSC_EXTERN void snessetconvergencetest_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), void *cctx, void (*destroy)(void *), PetscErrorCode *ierr)
3338e27ec22SSatish Balay {
3343f22127dSBarry Smith   CHKFORTRANNULLFUNCTION(destroy);
3353f149594SLisandro Dalcin 
3368434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergeddefault_) {
337dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedDefault, NULL, NULL);
3388434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesconvergedskip_) {
339dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedSkip, NULL, NULL);
3408e27ec22SSatish Balay   } else {
3418434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.test, (PetscVoidFn *)func, cctx);
3425975b3b6SBarry Smith     if (*ierr) return;
3438434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.destroy, (PetscVoidFn *)destroy, cctx);
3445975b3b6SBarry Smith     if (*ierr) return;
345aecf964fSBarry Smith     *ierr = SNESSetConvergenceTest(*snes, oursnestest, *snes, ourdestroy);
3468e27ec22SSatish Balay   }
3478e27ec22SSatish Balay }
3488e27ec22SSatish Balay 
3498e27ec22SSatish Balay /*  func is currently ignored from Fortran */
35019caf8f3SSatish Balay PETSC_EXTERN void snesgetjacobian_(SNES *snes, Mat *A, Mat *B, int *func, void **ctx, PetscErrorCode *ierr)
3518e27ec22SSatish Balay {
3528e27ec22SSatish Balay   CHKFORTRANNULLINTEGER(ctx);
3538e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(A);
3548e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(B);
355dfef5ea7SSatish Balay   *ierr = SNESGetJacobian(*snes, A, B, NULL, NULL);
3565975b3b6SBarry Smith   if (*ierr) return;
3570298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.jacobian, NULL, ctx);
3588e27ec22SSatish Balay }
3598e27ec22SSatish Balay 
36019caf8f3SSatish Balay PETSC_EXTERN void snesgetconvergencehistory_(SNES *snes, PetscInt *na, PetscErrorCode *ierr)
3618e27ec22SSatish Balay {
3620298fd71SBarry Smith   *ierr = SNESGetConvergenceHistory(*snes, NULL, NULL, na);
3638e27ec22SSatish Balay }
3648e27ec22SSatish Balay 
36552f0073cSBarry Smith PETSC_EXTERN void snesmonitordefault_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3668e27ec22SSatish Balay {
367410efd14SBarry Smith   *ierr = SNESMonitorDefault(*snes, *its, *fgnorm, *dummy);
3688e27ec22SSatish Balay }
3698e27ec22SSatish Balay 
37052f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolution_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3718e27ec22SSatish Balay {
372410efd14SBarry Smith   *ierr = SNESMonitorSolution(*snes, *its, *fgnorm, *dummy);
3738e27ec22SSatish Balay }
3748e27ec22SSatish Balay 
37552f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolutionupdate_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
3768e27ec22SSatish Balay {
377410efd14SBarry Smith   *ierr = SNESMonitorSolutionUpdate(*snes, *its, *fgnorm, *dummy);
3788e27ec22SSatish Balay }
3798e27ec22SSatish Balay 
38019caf8f3SSatish Balay PETSC_EXTERN void snesmonitorset_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), void *mctx, void (*mondestroy)(void *, PetscErrorCode *), PetscErrorCode *ierr)
3818e27ec22SSatish Balay {
382aecf964fSBarry Smith   CHKFORTRANNULLFUNCTION(mondestroy);
3838434afd1SBarry Smith   if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitordefault_) {
3841cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorDefault, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
3858434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolution_) {
3861cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolution, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
3878434afd1SBarry Smith   } else if ((PetscVoidFn *)func == (PetscVoidFn *)snesmonitorsolutionupdate_) {
3881cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolutionUpdate, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
3898e27ec22SSatish Balay   } else {
3908434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.monitor, (PetscVoidFn *)func, mctx);
3915975b3b6SBarry Smith     if (*ierr) return;
3928434afd1SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.mondestroy, (PetscVoidFn *)mondestroy, mctx);
3935975b3b6SBarry Smith     if (*ierr) return;
394aecf964fSBarry Smith     *ierr = SNESMonitorSet(*snes, oursnesmonitor, *snes, ourmondestroy);
3958e27ec22SSatish Balay   }
3968e27ec22SSatish Balay }
397