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