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