xref: /petsc/src/snes/interface/ftn-custom/zsnesf.c (revision dfef5ea798a36ccc664ca1bbe435d183ec21e5c1)
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)
791f3e32bSBarry Smith   #define snesconvergedreasonview_         SNESCONVERGEDREASONVIEW
8df2570feSBarry Smith   #define snessetpicard_                   SNESSETPICARD
9df66969eSBarry Smith   #define matmffdcomputejacobian_          MATMFFDCOMPUTEJACOBIAN
106ce558aeSBarry Smith   #define snessolve_                       SNESSOLVE
118d359177SBarry Smith   #define snescomputejacobiandefault_      SNESCOMPUTEJACOBIANDEFAULT
128d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ SNESCOMPUTEJACOBIANDEFAULTCOLOR
138e27ec22SSatish Balay   #define snessetjacobian_                 SNESSETJACOBIAN
1417a42bb7SSatish Balay   #define snessetjacobian1_                SNESSETJACOBIAN1
1517a42bb7SSatish Balay   #define snessetjacobian2_                SNESSETJACOBIAN2
168e27ec22SSatish Balay   #define snesgetoptionsprefix_            SNESGETOPTIONSPREFIX
178e27ec22SSatish Balay   #define snesgettype_                     SNESGETTYPE
188e27ec22SSatish Balay   #define snessetfunction_                 SNESSETFUNCTION
19be95d8f1SBarry Smith   #define snessetngs_                      SNESSETNGS
20dfef22ccSBarry Smith   #define snessetupdate_                   SNESSETUPDATE
218e27ec22SSatish Balay   #define snesgetfunction_                 SNESGETFUNCTION
22be95d8f1SBarry Smith   #define snesgetngs_                      SNESGETNGS
238e27ec22SSatish Balay   #define snessetconvergencetest_          SNESSETCONVERGENCETEST
248d359177SBarry Smith   #define snesconvergeddefault_            SNESCONVERGEDDEFAULT
25e07f7f94SSatish Balay   #define snesconvergedskip_               SNESCONVERGEDSKIP
268e27ec22SSatish Balay   #define snesview_                        SNESVIEW
278e27ec22SSatish Balay   #define snesgetconvergencehistory_       SNESGETCONVERGENCEHISTORY
288e27ec22SSatish Balay   #define snesgetjacobian_                 SNESGETJACOBIAN
298e27ec22SSatish Balay   #define snessettype_                     SNESSETTYPE
308e27ec22SSatish Balay   #define snesappendoptionsprefix_         SNESAPPENDOPTIONSPREFIX
318e27ec22SSatish Balay   #define snessetoptionsprefix_            SNESSETOPTIONSPREFIX
32a6570f20SBarry Smith   #define snesmonitordefault_              SNESMONITORDEFAULT
33a6570f20SBarry Smith   #define snesmonitorsolution_             SNESMONITORSOLUTION
34a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       SNESMONITORSOLUTIONUPDATE
35a6570f20SBarry Smith   #define snesmonitorset_                  SNESMONITORSET
36c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         SNESNEWTONTRSETPRECHECK
373b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        SNESNEWTONTRSETPOSTCHECK
3841ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       SNESNEWTONTRDCSETPRECHECK
3941ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      SNESNEWTONTRDCSETPOSTCHECK
40fe2efc57SMark   #define snesviewfromoptions_             SNESVIEWFROMOPTIONS
41c4421ceaSFande Kong   #define snesgetconvergedreasonstring_    SNESGETCONVERGEDREASONSTRING
424e2a09fcSBarry Smith #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
4391f3e32bSBarry Smith   #define snesconvergedreasonview_         snesconvergedreasonview
44df2570feSBarry Smith   #define snessetpicard_                   snessetpicard
45df66969eSBarry Smith   #define matmffdcomputejacobian_          matmffdcomputejacobian
466ce558aeSBarry Smith   #define snessolve_                       snessolve
478d359177SBarry Smith   #define snescomputejacobiandefault_      snescomputejacobiandefault
488d359177SBarry Smith   #define snescomputejacobiandefaultcolor_ snescomputejacobiandefaultcolor
498e27ec22SSatish Balay   #define snessetjacobian_                 snessetjacobian
5017a42bb7SSatish Balay   #define snessetjacobian1_                snessetjacobian1
5117a42bb7SSatish Balay   #define snessetjacobian2_                snessetjacobian2
528e27ec22SSatish Balay   #define snesgetoptionsprefix_            snesgetoptionsprefix
538e27ec22SSatish Balay   #define snesgettype_                     snesgettype
548e27ec22SSatish Balay   #define snessetfunction_                 snessetfunction
55be95d8f1SBarry Smith   #define snessetngs_                      snessetngs
56dfef22ccSBarry Smith   #define snessetupdate_                   snessetupdate
578e27ec22SSatish Balay   #define snesgetfunction_                 snesgetfunction
58be95d8f1SBarry Smith   #define snesgetngs_                      snesgetngs
598e27ec22SSatish Balay   #define snessetconvergencetest_          snessetconvergencetest
608d359177SBarry Smith   #define snesconvergeddefault_            snesconvergeddefault
61e07f7f94SSatish Balay   #define snesconvergedskip_               snesconvergedskip
628e27ec22SSatish Balay   #define snesview_                        snesview
638e27ec22SSatish Balay   #define snesgetjacobian_                 snesgetjacobian
648e27ec22SSatish Balay   #define snesgetconvergencehistory_       snesgetconvergencehistory
658e27ec22SSatish Balay   #define snessettype_                     snessettype
668e27ec22SSatish Balay   #define snesappendoptionsprefix_         snesappendoptionsprefix
678e27ec22SSatish Balay   #define snessetoptionsprefix_            snessetoptionsprefix
68a6570f20SBarry Smith   #define snesmonitordefault_              snesmonitordefault
69a6570f20SBarry Smith   #define snesmonitorsolution_             snesmonitorsolution
70a6570f20SBarry Smith   #define snesmonitorsolutionupdate_       snesmonitorsolutionupdate
71a6570f20SBarry Smith   #define snesmonitorset_                  snesmonitorset
72c9368356SGlenn Hammond   #define snesnewtontrsetprecheck_         snesnewtontrsetprecheck
733b42469aSBarry Smith   #define snesnewtontrsetpostcheck_        snesnewtontrsetpostcheck
7441ba4c6cSHeeho Park   #define snesnewtontrdcsetprecheck_       snesnewtontrdcsetprecheck
7541ba4c6cSHeeho Park   #define snesnewtontrdcsetpostcheck_      snesnewtontrdcsetpostcheck
76fe2efc57SMark   #define snesviewfromoptions_             snesviewfromoptions
77c4421ceaSFande Kong   #define snesgetconvergedreasonstring_    snesgetconvergedreasonstring
788e27ec22SSatish Balay #endif
798e27ec22SSatish Balay 
80f6291634SJed Brown static struct {
81f6291634SJed Brown   PetscFortranCallbackId function;
82f6291634SJed Brown   PetscFortranCallbackId test;
83f6291634SJed Brown   PetscFortranCallbackId destroy;
84f6291634SJed Brown   PetscFortranCallbackId jacobian;
85f6291634SJed Brown   PetscFortranCallbackId monitor;
86f6291634SJed Brown   PetscFortranCallbackId mondestroy;
87be95d8f1SBarry Smith   PetscFortranCallbackId ngs;
88dfef22ccSBarry Smith   PetscFortranCallbackId update;
89c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck;
907cb011f5SBarry Smith   PetscFortranCallbackId trpostcheck;
9189e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
9289e00c7dSSatish Balay   PetscFortranCallbackId function_pgiptr;
93c9368356SGlenn Hammond   PetscFortranCallbackId trprecheck_pgiptr;
943c2ee7eaSBarry Smith   PetscFortranCallbackId trpostcheck_pgiptr;
9589e00c7dSSatish Balay #endif
96f6291634SJed Brown } _cb;
9790b77ac2SPeter Brune 
98c9368356SGlenn Hammond static PetscErrorCode ourtrprecheckfunction(SNES snes, Vec x, Vec y, PetscBool *changed_y, void *ctx)
99c9368356SGlenn Hammond {
100c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
101c9368356SGlenn Hammond   void *ptr;
1023ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trprecheck_pgiptr, NULL, &ptr));
103c9368356SGlenn Hammond #endif
104c9368356SGlenn 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)));
105c9368356SGlenn Hammond }
106c9368356SGlenn Hammond 
10719caf8f3SSatish Balay PETSC_EXTERN void snesnewtontrsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
108c9368356SGlenn Hammond {
1093ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFunction)func, ctx);
1103ba16761SJacob Faibussowitsch   if (*ierr) return;
111c9368356SGlenn Hammond #if defined(PETSC_HAVE_F90_2PTR_ARG)
1123ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
1133ba16761SJacob Faibussowitsch   if (*ierr) return;
114c9368356SGlenn Hammond #endif
1153ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPreCheck(*snes, ourtrprecheckfunction, NULL);
116c9368356SGlenn Hammond }
117c9368356SGlenn Hammond 
11841ba4c6cSHeeho Park PETSC_EXTERN void snesnewtontrdcsetprecheck_(SNES *snes, void (*func)(SNES, Vec, Vec, PetscBool *, void *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
11941ba4c6cSHeeho Park {
1203ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck, (PetscVoidFunction)func, ctx);
1213ba16761SJacob Faibussowitsch   if (*ierr) return;
12241ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1233ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trprecheck_pgiptr, NULL, ptr);
1243ba16761SJacob Faibussowitsch   if (*ierr) return;
12541ba4c6cSHeeho Park #endif
1263ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPreCheck(*snes, ourtrprecheckfunction, NULL);
12741ba4c6cSHeeho Park }
12841ba4c6cSHeeho Park 
129c9368356SGlenn Hammond static PetscErrorCode ourtrpostcheckfunction(SNES snes, Vec x, Vec y, Vec w, PetscBool *changed_y, PetscBool *changed_w, void *ctx)
1307cb011f5SBarry Smith {
1317cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1327cb011f5SBarry Smith   void *ptr;
1333ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.trpostcheck_pgiptr, NULL, &ptr));
1347cb011f5SBarry Smith #endif
135c9368356SGlenn 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)));
1367cb011f5SBarry Smith }
1377cb011f5SBarry Smith 
13819caf8f3SSatish 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))
1397cb011f5SBarry Smith {
1403ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFunction)func, ctx);
1413ba16761SJacob Faibussowitsch   if (*ierr) return;
1427cb011f5SBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
1433ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1443ba16761SJacob Faibussowitsch   if (*ierr) return;
1457cb011f5SBarry Smith #endif
1463ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
1477cb011f5SBarry Smith }
1487cb011f5SBarry Smith 
14941ba4c6cSHeeho 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))
15041ba4c6cSHeeho Park {
1513ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck, (PetscVoidFunction)func, ctx);
1523ba16761SJacob Faibussowitsch   if (*ierr) return;
15341ba4c6cSHeeho Park #if defined(PETSC_HAVE_F90_2PTR_ARG)
1543ba16761SJacob Faibussowitsch   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.trpostcheck_pgiptr, NULL, ptr);
1553ba16761SJacob Faibussowitsch   if (*ierr) return;
15641ba4c6cSHeeho Park #endif
1573ba16761SJacob Faibussowitsch   *ierr = SNESNewtonTRDCSetPostCheck(*snes, ourtrpostcheckfunction, NULL);
15841ba4c6cSHeeho Park }
15941ba4c6cSHeeho Park 
1608e27ec22SSatish Balay static PetscErrorCode oursnesfunction(SNES snes, Vec x, Vec f, void *ctx)
1618e27ec22SSatish Balay {
16289e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
16389e00c7dSSatish Balay   void *ptr;
1643ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
16589e00c7dSSatish Balay #endif
16689e00c7dSSatish 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)));
1678e27ec22SSatish Balay }
168b8ebb45fSBarry Smith 
16906ee9f85SBarry Smith static PetscErrorCode oursnestest(SNES snes, PetscInt it, PetscReal a, PetscReal d, PetscReal c, SNESConvergedReason *reason, void *ctx)
1708e27ec22SSatish Balay {
171f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.test, (SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), (&snes, &it, &a, &d, &c, reason, _ctx, &ierr));
1727f7931b9SBarry Smith }
1737f7931b9SBarry Smith 
1747f7931b9SBarry Smith static PetscErrorCode ourdestroy(void *ctx)
1757f7931b9SBarry Smith {
176f6291634SJed Brown   PetscObjectUseFortranCallback(ctx, _cb.destroy, (void *, PetscErrorCode *), (_ctx, &ierr));
1778e27ec22SSatish Balay }
1788e27ec22SSatish Balay 
179d1e9a80fSBarry Smith static PetscErrorCode oursnesjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
1808e27ec22SSatish Balay {
181d1e9a80fSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
1828e27ec22SSatish Balay }
183f6291634SJed Brown 
184dfef22ccSBarry Smith static PetscErrorCode oursnesupdate(SNES snes, PetscInt i)
185dfef22ccSBarry Smith {
186dfef22ccSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.update, (SNES *, PetscInt *, PetscErrorCode *), (&snes, &i, &ierr));
187dfef22ccSBarry Smith }
188be95d8f1SBarry Smith static PetscErrorCode oursnesngs(SNES snes, Vec x, Vec b, void *ctx)
18990b77ac2SPeter Brune {
190be95d8f1SBarry Smith   PetscObjectUseFortranCallback(snes, _cb.ngs, (SNES *, Vec *, Vec *, void *, PetscErrorCode *), (&snes, &x, &b, _ctx, &ierr));
19190b77ac2SPeter Brune }
1928e27ec22SSatish Balay static PetscErrorCode oursnesmonitor(SNES snes, PetscInt i, PetscReal d, void *ctx)
1938e27ec22SSatish Balay {
194f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.monitor, (SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), (&snes, &i, &d, _ctx, &ierr));
1958e27ec22SSatish Balay }
196c2efdce3SBarry Smith static PetscErrorCode ourmondestroy(void **ctx)
1978e27ec22SSatish Balay {
198f6291634SJed Brown   SNES snes = (SNES)*ctx;
199f6291634SJed Brown   PetscObjectUseFortranCallback(snes, _cb.mondestroy, (void *, PetscErrorCode *), (_ctx, &ierr));
2008e27ec22SSatish Balay }
2018e27ec22SSatish Balay 
2028e27ec22SSatish Balay /*
2038d359177SBarry Smith      snescomputejacobiandefault() and snescomputejacobiandefaultcolor()
2048e27ec22SSatish Balay   These can be used directly from Fortran but are mostly so that
2058e27ec22SSatish Balay   Fortran SNESSetJacobian() will properly handle the defaults being passed in.
2068e27ec22SSatish Balay */
207d1e9a80fSBarry Smith PETSC_EXTERN void matmffdcomputejacobian_(SNES *snes, Vec *x, Mat *m, Mat *p, void *ctx, PetscErrorCode *ierr)
208df66969eSBarry Smith {
209d1e9a80fSBarry Smith   *ierr = MatMFFDComputeJacobian(*snes, *x, *m, *p, ctx);
210df66969eSBarry Smith }
211d1e9a80fSBarry Smith PETSC_EXTERN void snescomputejacobiandefault_(SNES *snes, Vec *x, Mat *m, Mat *p, void *ctx, PetscErrorCode *ierr)
2128e27ec22SSatish Balay {
213d1e9a80fSBarry Smith   *ierr = SNESComputeJacobianDefault(*snes, *x, *m, *p, ctx);
2148e27ec22SSatish Balay }
215d1e9a80fSBarry Smith PETSC_EXTERN void snescomputejacobiandefaultcolor_(SNES *snes, Vec *x, Mat *m, Mat *p, void *ctx, PetscErrorCode *ierr)
2168e27ec22SSatish Balay {
217d1e9a80fSBarry Smith   *ierr = SNESComputeJacobianDefaultColor(*snes, *x, *m, *p, *(MatFDColoring *)ctx);
2188e27ec22SSatish Balay }
2198e27ec22SSatish Balay 
2205975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
2218e27ec22SSatish Balay {
222f5b6597dSBarry Smith   CHKFORTRANNULLFUNCTION(func);
2238d359177SBarry Smith   if ((PetscVoidFunction)func == (PetscVoidFunction)snescomputejacobiandefault_) {
2248d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefault, ctx);
2258d359177SBarry Smith   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snescomputejacobiandefaultcolor_) {
226e025ade3SBarry Smith     if (!ctx) {
227e025ade3SBarry Smith       *ierr = PETSC_ERR_ARG_NULL;
228e025ade3SBarry Smith       return;
229e025ade3SBarry Smith     }
2308d359177SBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, SNESComputeJacobianDefaultColor, *(MatFDColoring *)ctx);
231df66969eSBarry Smith   } else if ((PetscVoidFunction)func == (PetscVoidFunction)matmffdcomputejacobian_) {
232df66969eSBarry Smith     *ierr = SNESSetJacobian(*snes, *A, *B, MatMFFDComputeJacobian, ctx);
2338e27ec22SSatish Balay   } else {
234f6291634SJed Brown     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFunction)func, ctx);
2350298fd71SBarry Smith     if (!*ierr) *ierr = SNESSetJacobian(*snes, *A, *B, oursnesjacobian, NULL);
2368e27ec22SSatish Balay   }
2378e27ec22SSatish Balay }
2385975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian1_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
23917a42bb7SSatish Balay {
24017a42bb7SSatish Balay   snessetjacobian_(snes, A, B, func, ctx, ierr);
24117a42bb7SSatish Balay }
2425975b3b6SBarry Smith PETSC_EXTERN void snessetjacobian2_(SNES *snes, Mat *A, Mat *B, void (*func)(SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
24317a42bb7SSatish Balay {
24417a42bb7SSatish Balay   snessetjacobian_(snes, A, B, func, ctx, ierr);
24517a42bb7SSatish Balay }
246f6dfbefdSBarry Smith 
247df2570feSBarry Smith static PetscErrorCode oursnespicardfunction(SNES snes, Vec x, Vec f, void *ctx)
248df2570feSBarry Smith {
249df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
250df2570feSBarry Smith   void *ptr;
2513ba16761SJacob Faibussowitsch   PetscCall(PetscObjectGetFortranCallback((PetscObject)snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function_pgiptr, NULL, &ptr));
252df2570feSBarry Smith #endif
253df2570feSBarry 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)));
254df2570feSBarry Smith }
255df2570feSBarry Smith 
256df2570feSBarry Smith static PetscErrorCode oursnespicardjacobian(SNES snes, Vec x, Mat m, Mat p, void *ctx)
257df2570feSBarry Smith {
258df2570feSBarry Smith   PetscObjectUseFortranCallback(snes, _cb.jacobian, (SNES *, Vec *, Mat *, Mat *, void *, PetscErrorCode *), (&snes, &x, &m, &p, _ctx, &ierr));
259df2570feSBarry Smith }
260df2570feSBarry Smith 
2615975b3b6SBarry 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))
262df2570feSBarry Smith {
263df2570feSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFunction)func, ctx);
264df2570feSBarry Smith #if defined(PETSC_HAVE_F90_2PTR_ARG)
2655975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
2665975b3b6SBarry Smith   if (*ierr) return;
267df2570feSBarry Smith #endif
268df2570feSBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.jacobian, (PetscVoidFunction)J, ctx);
269df2570feSBarry Smith   if (!*ierr) *ierr = SNESSetPicard(*snes, *r, oursnespicardfunction, *A, *B, oursnespicardjacobian, NULL);
270df2570feSBarry Smith }
2718e27ec22SSatish Balay 
27219caf8f3SSatish Balay PETSC_EXTERN void snesgetoptionsprefix_(SNES *snes, char *prefix, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len)
2738e27ec22SSatish Balay {
2748e27ec22SSatish Balay   const char *tname;
2758e27ec22SSatish Balay 
2768e27ec22SSatish Balay   *ierr = SNESGetOptionsPrefix(*snes, &tname);
2775975b3b6SBarry Smith   *ierr = PetscStrncpy(prefix, tname, len);
2785975b3b6SBarry Smith   if (*ierr) return;
279d6a8cea5SBarry Smith   FIXRETURNCHAR(PETSC_TRUE, prefix, len);
2808e27ec22SSatish Balay }
2818e27ec22SSatish Balay 
28219caf8f3SSatish Balay PETSC_EXTERN void snesgettype_(SNES *snes, char *name, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len)
2838e27ec22SSatish Balay {
2848e27ec22SSatish Balay   const char *tname;
2858e27ec22SSatish Balay 
2868e27ec22SSatish Balay   *ierr = SNESGetType(*snes, &tname);
2875975b3b6SBarry Smith   *ierr = PetscStrncpy(name, tname, len);
2885975b3b6SBarry Smith   if (*ierr) return;
2897c363081SBarry Smith   FIXRETURNCHAR(PETSC_TRUE, name, len);
2908e27ec22SSatish Balay }
291e3da1266SHong Zhang 
2928e27ec22SSatish Balay /*
2938e27ec22SSatish Balay    These are not usually called from Fortran but allow Fortran users
2948e27ec22SSatish Balay    to transparently set these monitors from .F code
2958e27ec22SSatish Balay */
2968e27ec22SSatish Balay 
29719caf8f3SSatish Balay PETSC_EXTERN void snessetfunction_(SNES *snes, Vec *r, void (*func)(SNES *, Vec *, Vec *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
2988e27ec22SSatish Balay {
2995975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function, (PetscVoidFunction)func, ctx);
3005975b3b6SBarry Smith   if (*ierr) return;
30189e00c7dSSatish Balay #if defined(PETSC_HAVE_F90_2PTR_ARG)
3025975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.function_pgiptr, NULL, ptr);
3035975b3b6SBarry Smith   if (*ierr) return;
30489e00c7dSSatish Balay #endif
305aecf964fSBarry Smith   *ierr = SNESSetFunction(*snes, *r, oursnesfunction, NULL);
3068e27ec22SSatish Balay }
307c79ef259SPeter Brune 
30819caf8f3SSatish Balay PETSC_EXTERN void snessetngs_(SNES *snes, void (*func)(SNES *, Vec *, Vec *, void *, PetscErrorCode *), void *ctx, PetscErrorCode *ierr)
309c79ef259SPeter Brune {
3105975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.ngs, (PetscVoidFunction)func, ctx);
3115975b3b6SBarry Smith   if (*ierr) return;
312aecf964fSBarry Smith   *ierr = SNESSetNGS(*snes, oursnesngs, NULL);
313c79ef259SPeter Brune }
31419caf8f3SSatish Balay PETSC_EXTERN void snessetupdate_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscErrorCode *), PetscErrorCode *ierr)
315dfef22ccSBarry Smith {
3165975b3b6SBarry Smith   *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.update, (PetscVoidFunction)func, NULL);
3175975b3b6SBarry Smith   if (*ierr) return;
318aecf964fSBarry Smith   *ierr = SNESSetUpdate(*snes, oursnesupdate);
319dfef22ccSBarry Smith }
3208e27ec22SSatish Balay 
3218e27ec22SSatish Balay /* the func argument is ignored */
32219caf8f3SSatish Balay PETSC_EXTERN void snesgetfunction_(SNES *snes, Vec *r, void (*func)(SNES, Vec, Vec, void *), void **ctx, PetscErrorCode *ierr)
3238e27ec22SSatish Balay {
3248e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(r);
3255975b3b6SBarry Smith   *ierr = SNESGetFunction(*snes, r, NULL, NULL);
3265975b3b6SBarry Smith   if (*ierr) return;
327146935d7SSatish Balay   if ((PetscVoidFunction)func == (PetscVoidFunction)PETSC_NULL_FUNCTION_Fortran) return;
3280298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.function, NULL, ctx);
3298e27ec22SSatish Balay }
330c79ef259SPeter Brune 
33119caf8f3SSatish Balay PETSC_EXTERN void snesgetngs_(SNES *snes, void *func, void **ctx, PetscErrorCode *ierr)
332c79ef259SPeter Brune {
333be95d8f1SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.ngs, NULL, ctx);
334c79ef259SPeter Brune }
335c79ef259SPeter Brune 
33669c1e2abSSatish Balay PETSC_EXTERN void snesconvergeddefault_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3373f149594SLisandro Dalcin {
3388d359177SBarry Smith   *ierr = SNESConvergedDefault(*snes, *it, *a, *b, *c, r, ct);
3393f149594SLisandro Dalcin }
3403f149594SLisandro Dalcin 
341e07f7f94SSatish Balay PETSC_EXTERN void snesconvergedskip_(SNES *snes, PetscInt *it, PetscReal *a, PetscReal *b, PetscReal *c, SNESConvergedReason *r, void *ct, PetscErrorCode *ierr)
3423f149594SLisandro Dalcin {
343e2a6519dSDmitry Karpeev   *ierr = SNESConvergedSkip(*snes, *it, *a, *b, *c, r, ct);
3443f149594SLisandro Dalcin }
3453f149594SLisandro Dalcin 
34619caf8f3SSatish Balay PETSC_EXTERN void snessetconvergencetest_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, PetscReal *, PetscReal *, SNESConvergedReason *, void *, PetscErrorCode *), void *cctx, void (*destroy)(void *), PetscErrorCode *ierr)
3478e27ec22SSatish Balay {
3483f22127dSBarry Smith   CHKFORTRANNULLFUNCTION(destroy);
3493f149594SLisandro Dalcin 
3508d359177SBarry Smith   if ((PetscVoidFunction)func == (PetscVoidFunction)snesconvergeddefault_) {
351*dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedDefault, NULL, NULL);
352e07f7f94SSatish Balay   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesconvergedskip_) {
353*dfef5ea7SSatish Balay     *ierr = SNESSetConvergenceTest(*snes, SNESConvergedSkip, NULL, NULL);
3548e27ec22SSatish Balay   } else {
3555975b3b6SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.test, (PetscVoidFunction)func, cctx);
3565975b3b6SBarry Smith     if (*ierr) return;
3575975b3b6SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.destroy, (PetscVoidFunction)destroy, cctx);
3585975b3b6SBarry Smith     if (*ierr) return;
359aecf964fSBarry Smith     *ierr = SNESSetConvergenceTest(*snes, oursnestest, *snes, ourdestroy);
3608e27ec22SSatish Balay   }
3618e27ec22SSatish Balay }
3628e27ec22SSatish Balay 
36319caf8f3SSatish Balay PETSC_EXTERN void snesview_(SNES *snes, PetscViewer *viewer, PetscErrorCode *ierr)
3648e27ec22SSatish Balay {
3658e27ec22SSatish Balay   PetscViewer v;
3668e27ec22SSatish Balay   PetscPatchDefaultViewers_Fortran(viewer, v);
3678e27ec22SSatish Balay   *ierr = SNESView(*snes, v);
3688e27ec22SSatish Balay }
3698e27ec22SSatish Balay 
3708e27ec22SSatish Balay /*  func is currently ignored from Fortran */
37119caf8f3SSatish Balay PETSC_EXTERN void snesgetjacobian_(SNES *snes, Mat *A, Mat *B, int *func, void **ctx, PetscErrorCode *ierr)
3728e27ec22SSatish Balay {
3738e27ec22SSatish Balay   CHKFORTRANNULLINTEGER(ctx);
3748e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(A);
3758e27ec22SSatish Balay   CHKFORTRANNULLOBJECT(B);
376*dfef5ea7SSatish Balay   *ierr = SNESGetJacobian(*snes, A, B, NULL, NULL);
3775975b3b6SBarry Smith   if (*ierr) return;
3780298fd71SBarry Smith   *ierr = PetscObjectGetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, _cb.jacobian, NULL, ctx);
3798e27ec22SSatish Balay }
3808e27ec22SSatish Balay 
38119caf8f3SSatish Balay PETSC_EXTERN void snesgetconvergencehistory_(SNES *snes, PetscInt *na, PetscErrorCode *ierr)
3828e27ec22SSatish Balay {
3830298fd71SBarry Smith   *ierr = SNESGetConvergenceHistory(*snes, NULL, NULL, na);
3848e27ec22SSatish Balay }
3858e27ec22SSatish Balay 
38619caf8f3SSatish Balay PETSC_EXTERN void snessettype_(SNES *snes, char *type, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len)
3878e27ec22SSatish Balay {
3888e27ec22SSatish Balay   char *t;
3898e27ec22SSatish Balay 
3908e27ec22SSatish Balay   FIXCHAR(type, len, t);
3915975b3b6SBarry Smith   *ierr = SNESSetType(*snes, t);
3925975b3b6SBarry Smith   if (*ierr) return;
3938e27ec22SSatish Balay   FREECHAR(type, t);
3948e27ec22SSatish Balay }
3958e27ec22SSatish Balay 
39619caf8f3SSatish Balay PETSC_EXTERN void snesappendoptionsprefix_(SNES *snes, char *prefix, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len)
3978e27ec22SSatish Balay {
3988e27ec22SSatish Balay   char *t;
3998e27ec22SSatish Balay 
4008e27ec22SSatish Balay   FIXCHAR(prefix, len, t);
4015975b3b6SBarry Smith   *ierr = SNESAppendOptionsPrefix(*snes, t);
4025975b3b6SBarry Smith   if (*ierr) return;
4038e27ec22SSatish Balay   FREECHAR(prefix, t);
4048e27ec22SSatish Balay }
4058e27ec22SSatish Balay 
40619caf8f3SSatish Balay PETSC_EXTERN void snessetoptionsprefix_(SNES *snes, char *prefix, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len)
4078e27ec22SSatish Balay {
4088e27ec22SSatish Balay   char *t;
4098e27ec22SSatish Balay 
4108e27ec22SSatish Balay   FIXCHAR(prefix, len, t);
4115975b3b6SBarry Smith   *ierr = SNESSetOptionsPrefix(*snes, t);
4125975b3b6SBarry Smith   if (*ierr) return;
4138e27ec22SSatish Balay   FREECHAR(prefix, t);
4148e27ec22SSatish Balay }
4158e27ec22SSatish Balay 
41652f0073cSBarry Smith PETSC_EXTERN void snesmonitordefault_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
4178e27ec22SSatish Balay {
418410efd14SBarry Smith   *ierr = SNESMonitorDefault(*snes, *its, *fgnorm, *dummy);
4198e27ec22SSatish Balay }
4208e27ec22SSatish Balay 
42152f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolution_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
4228e27ec22SSatish Balay {
423410efd14SBarry Smith   *ierr = SNESMonitorSolution(*snes, *its, *fgnorm, *dummy);
4248e27ec22SSatish Balay }
4258e27ec22SSatish Balay 
42652f0073cSBarry Smith PETSC_EXTERN void snesmonitorsolutionupdate_(SNES *snes, PetscInt *its, PetscReal *fgnorm, PetscViewerAndFormat **dummy, PetscErrorCode *ierr)
4278e27ec22SSatish Balay {
428410efd14SBarry Smith   *ierr = SNESMonitorSolutionUpdate(*snes, *its, *fgnorm, *dummy);
4298e27ec22SSatish Balay }
4308e27ec22SSatish Balay 
43119caf8f3SSatish Balay PETSC_EXTERN void snesmonitorset_(SNES *snes, void (*func)(SNES *, PetscInt *, PetscReal *, void *, PetscErrorCode *), void *mctx, void (*mondestroy)(void *, PetscErrorCode *), PetscErrorCode *ierr)
4328e27ec22SSatish Balay {
433aecf964fSBarry Smith   CHKFORTRANNULLFUNCTION(mondestroy);
434a6570f20SBarry Smith   if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitordefault_) {
4351cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorDefault, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
436a6570f20SBarry Smith   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorsolution_) {
4371cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolution, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
438a6570f20SBarry Smith   } else if ((PetscVoidFunction)func == (PetscVoidFunction)snesmonitorsolutionupdate_) {
4391cb03803SBarry Smith     *ierr = SNESMonitorSet(*snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))SNESMonitorSolutionUpdate, *(PetscViewerAndFormat **)mctx, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy);
4408e27ec22SSatish Balay   } else {
4415975b3b6SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.monitor, (PetscVoidFunction)func, mctx);
4425975b3b6SBarry Smith     if (*ierr) return;
4435975b3b6SBarry Smith     *ierr = PetscObjectSetFortranCallback((PetscObject)*snes, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.mondestroy, (PetscVoidFunction)mondestroy, mctx);
4445975b3b6SBarry Smith     if (*ierr) return;
445aecf964fSBarry Smith     *ierr = SNESMonitorSet(*snes, oursnesmonitor, *snes, ourmondestroy);
4468e27ec22SSatish Balay   }
4478e27ec22SSatish Balay }
4488e27ec22SSatish Balay 
44919caf8f3SSatish Balay PETSC_EXTERN void snesviewfromoptions_(SNES *ao, PetscObject obj, char *type, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len)
450fe2efc57SMark {
451fe2efc57SMark   char *t;
452fe2efc57SMark 
453fe2efc57SMark   FIXCHAR(type, len, t);
454b14c0cbaSBlaise Bourdin   CHKFORTRANNULLOBJECT(obj);
4555975b3b6SBarry Smith   *ierr = SNESViewFromOptions(*ao, obj, t);
4565975b3b6SBarry Smith   if (*ierr) return;
457fe2efc57SMark   FREECHAR(type, t);
458fe2efc57SMark }
45991f3e32bSBarry Smith 
46091f3e32bSBarry Smith PETSC_EXTERN void snesconvergedreasonview_(SNES *snes, PetscViewer *viewer, PetscErrorCode *ierr)
46191f3e32bSBarry Smith {
46291f3e32bSBarry Smith   PetscViewer v;
46391f3e32bSBarry Smith   PetscPatchDefaultViewers_Fortran(viewer, v);
46491f3e32bSBarry Smith   *ierr = SNESConvergedReasonView(*snes, v);
46591f3e32bSBarry Smith }
466c4421ceaSFande Kong 
467c4421ceaSFande Kong PETSC_EXTERN void snesgetconvergedreasonstring_(SNES *snes, char *strreason, PetscErrorCode *ierr, PETSC_FORTRAN_CHARLEN_T len)
468c4421ceaSFande Kong {
469c4421ceaSFande Kong   const char *tstrreason;
470c4421ceaSFande Kong   *ierr = SNESGetConvergedReasonString(*snes, &tstrreason);
4715975b3b6SBarry Smith   *ierr = PetscStrncpy(strreason, tstrreason, len);
4725975b3b6SBarry Smith   if (*ierr) return;
473c4421ceaSFande Kong   FIXRETURNCHAR(PETSC_TRUE, strreason, len);
474c4421ceaSFande Kong }
475