Date: 2026-03-31T13:23:24+00:00

Actual source code: znepf.c

      1: /*
      2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      4:    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain

      6:    This file is part of SLEPc.
      7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
      8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      9: */

     11: #include <petsc/private/ftnimpl.h>
     12: #include <slepcnep.h>

     14: #if defined(PETSC_HAVE_FORTRAN_CAPS)
     15: #define nepmonitorset_                    NEPMONITORSET
     16: #define nepmonitorall_                    NEPMONITORALL
     17: #define nepmonitorfirst_                  NEPMONITORFIRST
     18: #define nepmonitorconverged_              NEPMONITORCONVERGED
     19: #define nepmonitorconvergedcreate_        NEPMONITORCONVERGEDCREATE
     20: #define nepconvergedabsolute_             NEPCONVERGEDABSOLUTE
     21: #define nepconvergedrelative_             NEPCONVERGEDRELATIVE
     22: #define nepsetconvergencetestfunction_    NEPSETCONVERGENCETESTFUNCTION
     23: #define nepsetstoppingtestfunction_       NEPSETSTOPPINGTESTFUNCTION
     24: #define nepseteigenvaluecomparison_       NEPSETEIGENVALUECOMPARISON
     25: #define nepsetfunction_                   NEPSETFUNCTION
     26: #define nepgetfunction_                   NEPGETFUNCTION
     27: #define nepsetjacobian_                   NEPSETJACOBIAN
     28: #define nepgetjacobian_                   NEPGETJACOBIAN
     29: #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
     30: #define nepmonitorset_                    nepmonitorset
     31: #define nepmonitorall_                    nepmonitorall
     32: #define nepmonitorfirst_                  nepmonitorfirst
     33: #define nepmonitorconverged_              nepmonitorconverged
     34: #define nepmonitorconvergedcreate_        nepmonitorconvergedcreate
     35: #define nepconvergedabsolute_             nepconvergedabsolute
     36: #define nepconvergedrelative_             nepconvergedrelative
     37: #define nepsetconvergencetestfunction_    nepsetconvergencetestfunction
     38: #define nepsetstoppingtestfunction_       nepsetstoppingtestfunction
     39: #define nepseteigenvaluecomparison_       nepseteigenvaluecomparison
     40: #define nepsetfunction_                   nepsetfunction
     41: #define nepgetfunction_                   nepgetfunction
     42: #define nepsetjacobian_                   nepsetjacobian
     43: #define nepgetjacobian_                   nepgetjacobian
     44: #endif

     46: /*
     47:    These cannot be called from Fortran but allow Fortran users
     48:    to transparently set these monitors from .F code
     49: */
     50: SLEPC_EXTERN void nepmonitorall_(NEP*,PetscInt*,PetscInt*,PetscScalar*,PetscScalar*,PetscReal*,PetscInt*,PetscViewerAndFormat*,PetscErrorCode*);
     51: SLEPC_EXTERN void nepmonitorfirst_(NEP*,PetscInt*,PetscInt*,PetscScalar*,PetscScalar*,PetscReal*,PetscInt*,PetscViewerAndFormat*,PetscErrorCode*);
     52: SLEPC_EXTERN void nepmonitorconverged_(NEP*,PetscInt*,PetscInt*,PetscScalar*,PetscScalar*,PetscReal*,PetscInt*,PetscViewerAndFormat*,PetscErrorCode*);

     54: SLEPC_EXTERN void nepmonitorconvergedcreate_(PetscViewer *vin,PetscViewerFormat *format,void *ctx,PetscViewerAndFormat **vf,PetscErrorCode *ierr)
     55: {
     56:   PetscViewer v;
     57:   PetscPatchDefaultViewers_Fortran(vin,v);
     58:   CHKFORTRANNULLOBJECT(ctx);
     59:   *ierr = NEPMonitorConvergedCreate(v,*format,ctx,vf);
     60: }

     62: static struct {
     63:   PetscFortranCallbackId monitor;
     64:   PetscFortranCallbackId monitordestroy;
     65:   PetscFortranCallbackId convergence;
     66:   PetscFortranCallbackId convdestroy;
     67:   PetscFortranCallbackId stopping;
     68:   PetscFortranCallbackId stopdestroy;
     69:   PetscFortranCallbackId comparison;
     70:   PetscFortranCallbackId function;
     71:   PetscFortranCallbackId jacobian;
     72: #if defined(PETSC_HAVE_F90_2PTR_ARG)
     73:   PetscFortranCallbackId function_pgiptr;
     74:   PetscFortranCallbackId jacobian_pgiptr;
     75: #endif
     76: } _cb;

     78: /* These are not extern C because they are passed into non-extern C user level functions */
     79: static PetscErrorCode ourmonitor(NEP nep,PetscInt i,PetscInt nc,PetscScalar *er,PetscScalar *ei,PetscReal *d,PetscInt l,void *ctx)
     80: {
     81:   PetscObjectUseFortranCallback(nep,_cb.monitor,(NEP*,PetscInt*,PetscInt*,PetscScalar*,PetscScalar*,PetscReal*,PetscInt*,void*,PetscErrorCode*),(&nep,&i,&nc,er,ei,d,&l,_ctx,&ierr));
     82: }

     84: static PetscErrorCode ourdestroy(PetscCtxRt ctx)
     85: {
     86:   NEP nep = *(NEP*)ctx;
     87:   PetscObjectUseFortranCallback(nep,_cb.monitordestroy,(void*,PetscErrorCode*),(_ctx,&ierr));
     88: }

     90: static PetscErrorCode ourconvergence(NEP nep,PetscScalar eigr,PetscScalar eigi,PetscReal res,PetscReal *errest,void *ctx)
     91: {
     92:   PetscObjectUseFortranCallback(nep,_cb.convergence,(NEP*,PetscScalar*,PetscScalar*,PetscReal*,PetscReal*,void*,PetscErrorCode*),(&nep,&eigr,&eigi,&res,errest,_ctx,&ierr));
     93: }

     95: static PetscErrorCode ourconvdestroy(PetscCtxRt ctx)
     96: {
     97:   NEP nep = *(NEP*)ctx;
     98:   PetscObjectUseFortranCallback(nep,_cb.convdestroy,(void*,PetscErrorCode*),(_ctx,&ierr));
     99: }

    101: static PetscErrorCode ourstopping(NEP nep,PetscInt its,PetscInt max_it,PetscInt nconv,PetscInt nev,NEPConvergedReason *reason,void *ctx)
    102: {
    103:   PetscObjectUseFortranCallback(nep,_cb.stopping,(NEP*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,NEPConvergedReason*,void*,PetscErrorCode*),(&nep,&its,&max_it,&nconv,&nev,reason,_ctx,&ierr));
    104: }

    106: static PetscErrorCode ourstopdestroy(PetscCtxRt ctx)
    107: {
    108:   NEP nep = *(NEP*)ctx;
    109:   PetscObjectUseFortranCallback(nep,_cb.stopdestroy,(void*,PetscErrorCode*),(_ctx,&ierr));
    110: }

    112: static PetscErrorCode oureigenvaluecomparison(PetscScalar ar,PetscScalar ai,PetscScalar br,PetscScalar bi,PetscInt *r,void *ctx)
    113: {
    114:   NEP eps = (NEP)ctx;
    115:   PetscObjectUseFortranCallback(eps,_cb.comparison,(PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,PetscInt*,void*,PetscErrorCode*),(&ar,&ai,&br,&bi,r,_ctx,&ierr));
    116: }

    118: static PetscErrorCode ournepfunction(NEP nep,PetscScalar lambda,Mat T,Mat P,void *ctx)
    119: {
    120: #if defined(PETSC_HAVE_F90_2PTR_ARG)
    121:   void *ptr;
    122:   PetscCall(PetscObjectGetFortranCallback((PetscObject)nep,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function_pgiptr,NULL,&ptr));
    123: #endif
    124:   PetscObjectUseFortranCallback(nep,_cb.function,(NEP*,PetscScalar*,Mat*,Mat*,void*,PetscErrorCode* PETSC_F90_2PTR_PROTO_NOVAR),(&nep,&lambda,&T,&P,_ctx,&ierr PETSC_F90_2PTR_PARAM(ptr)));
    125: }

    127: static PetscErrorCode ournepjacobian(NEP nep,PetscScalar lambda,Mat J,void *ctx)
    128: {
    129: #if defined(PETSC_HAVE_F90_2PTR_ARG)
    130:   void *ptr;
    131:   PetscCall(PetscObjectGetFortranCallback((PetscObject)nep,PETSC_FORTRAN_CALLBACK_CLASS,_cb.jacobian_pgiptr,NULL,&ptr));
    132: #endif
    133:   PetscObjectUseFortranCallback(nep,_cb.jacobian,(NEP*,PetscScalar*,Mat*,void*,PetscErrorCode* PETSC_F90_2PTR_PROTO_NOVAR),(&nep,&lambda,&J,_ctx,&ierr PETSC_F90_2PTR_PARAM(ptr)));
    134: }

    136: SLEPC_EXTERN void nepmonitorset_(NEP *nep,void (*monitor)(NEP*,PetscInt*,PetscInt*,PetscScalar*,PetscScalar*,PetscReal*,PetscInt*,void*,PetscErrorCode*),void *mctx,void (*monitordestroy)(void*,PetscErrorCode*),PetscErrorCode *ierr)
    137: {
    138:   CHKFORTRANNULLOBJECT(mctx);
    139:   CHKFORTRANNULLFUNCTION(monitordestroy);
    140:   if ((PetscFortranCallbackFn*)monitor == (PetscFortranCallbackFn*)nepmonitorall_) {
    141:     *ierr = NEPMonitorSet(*nep,(NEPMonitorFn*)NEPMonitorAll,*(PetscViewerAndFormat**)mctx,(PetscCtxDestroyFn*)PetscViewerAndFormatDestroy);
    142:   } else if ((PetscFortranCallbackFn*)monitor == (PetscFortranCallbackFn*)nepmonitorconverged_) {
    143:     *ierr = NEPMonitorSet(*nep,(NEPMonitorFn*)NEPMonitorConverged,*(PetscViewerAndFormat**)mctx,(PetscCtxDestroyFn*)PetscViewerAndFormatDestroy);
    144:   } else if ((PetscFortranCallbackFn*)monitor == (PetscFortranCallbackFn*)nepmonitorfirst_) {
    145:     *ierr = NEPMonitorSet(*nep,(NEPMonitorFn*)NEPMonitorFirst,*(PetscViewerAndFormat**)mctx,(PetscCtxDestroyFn*)PetscViewerAndFormatDestroy);
    146:   } else {
    147:     *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitor,(PetscFortranCallbackFn*)monitor,mctx); if (*ierr) return;
    148:     *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.monitordestroy,(PetscFortranCallbackFn*)monitordestroy,mctx); if (*ierr) return;
    149:     *ierr = NEPMonitorSet(*nep,ourmonitor,*nep,ourdestroy);
    150:   }
    151: }

    153: SLEPC_EXTERN void nepconvergedabsolute_(NEP*,PetscScalar*,PetscScalar*,PetscReal*,PetscReal*,void*,PetscErrorCode*);
    154: SLEPC_EXTERN void nepconvergedrelative_(NEP*,PetscScalar*,PetscScalar*,PetscReal*,PetscReal*,void*,PetscErrorCode*);

    156: SLEPC_EXTERN void nepsetconvergencetestfunction_(NEP *nep,void (*func)(NEP*,PetscScalar*,PetscScalar*,PetscReal*,PetscReal*,void*,PetscErrorCode*),void *ctx,void (*destroy)(void*,PetscErrorCode*),PetscErrorCode *ierr)
    157: {
    158:   CHKFORTRANNULLOBJECT(ctx);
    159:   CHKFORTRANNULLFUNCTION(destroy);
    160:   if (func == nepconvergedabsolute_) {
    161:     *ierr = NEPSetConvergenceTest(*nep,NEP_CONV_ABS);
    162:   } else if (func == nepconvergedrelative_) {
    163:     *ierr = NEPSetConvergenceTest(*nep,NEP_CONV_REL);
    164:   } else {
    165:     *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.convergence,(PetscFortranCallbackFn*)func,ctx); if (*ierr) return;
    166:     *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.convdestroy,(PetscFortranCallbackFn*)destroy,ctx); if (*ierr) return;
    167:     *ierr = NEPSetConvergenceTestFunction(*nep,ourconvergence,*nep,ourconvdestroy);
    168:   }
    169: }

    171: SLEPC_EXTERN void nepstoppingbasic_(NEP*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,NEPConvergedReason*,void*,PetscErrorCode*);

    173: SLEPC_EXTERN void nepsetstoppingtestfunction_(NEP *nep,void (*func)(NEP*,PetscInt*,PetscInt*,PetscInt*,PetscInt*,NEPConvergedReason*,void*,PetscErrorCode*),void *ctx,void (*destroy)(void*,PetscErrorCode*),PetscErrorCode *ierr)
    174: {
    175:   CHKFORTRANNULLOBJECT(ctx);
    176:   CHKFORTRANNULLFUNCTION(destroy);
    177:   if (func == nepstoppingbasic_) {
    178:     *ierr = NEPSetStoppingTest(*nep,NEP_STOP_BASIC);
    179:   } else {
    180:     *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.stopping,(PetscFortranCallbackFn*)func,ctx); if (*ierr) return;
    181:     *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.stopdestroy,(PetscFortranCallbackFn*)destroy,ctx); if (*ierr) return;
    182:     *ierr = NEPSetStoppingTestFunction(*nep,ourstopping,*nep,ourstopdestroy);
    183:   }
    184: }

    186: SLEPC_EXTERN void nepseteigenvaluecomparison_(NEP *nep,void (*func)(PetscScalar*,PetscScalar*,PetscScalar*,PetscScalar*,PetscInt*,void*),void *ctx,PetscErrorCode *ierr)
    187: {
    188:   CHKFORTRANNULLOBJECT(ctx);
    189:   *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.comparison,(PetscFortranCallbackFn*)func,ctx); if (*ierr) return;
    190:   *ierr = NEPSetEigenvalueComparison(*nep,oureigenvaluecomparison,*nep);
    191: }

    193: SLEPC_EXTERN void nepsetfunction_(NEP *nep,Mat *A,Mat *B,void (*func)(NEP*,PetscScalar*,Mat*,Mat*,void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
    194: {
    195:   *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.function,(PetscFortranCallbackFn*)func,ctx);if (*ierr) return;
    196: #if defined(PETSC_HAVE_F90_2PTR_ARG)
    197:   *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.function_pgiptr,NULL,ptr);if (*ierr) return;
    198: #endif
    199:   *ierr = NEPSetFunction(*nep,*A,*B,ournepfunction,NULL);
    200: }

    202: /* func is currently ignored from Fortran */
    203: SLEPC_EXTERN void nepgetfunction_(NEP *nep,Mat *A,Mat *B,void *func,void **ctx,PetscErrorCode *ierr)
    204: {
    205:   CHKFORTRANNULLINTEGER(ctx);
    206:   CHKFORTRANNULLOBJECT(A);
    207:   CHKFORTRANNULLOBJECT(B);
    208:   *ierr = NEPGetFunction(*nep,A,B,NULL,NULL); if (*ierr) return;
    209:   *ierr = PetscObjectGetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,_cb.function,NULL,ctx);
    210: }

    212: SLEPC_EXTERN void nepsetjacobian_(NEP *nep,Mat *J,void (*func)(NEP*,PetscScalar*,Mat*,void*,PetscErrorCode*),void *ctx,PetscErrorCode *ierr PETSC_F90_2PTR_PROTO(ptr))
    213: {
    214:   *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.jacobian,(PetscFortranCallbackFn*)func,ctx);if (*ierr) return;
    215: #if defined(PETSC_HAVE_F90_2PTR_ARG)
    216:   *ierr = PetscObjectSetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,&_cb.jacobian_pgiptr,NULL,ptr);if (*ierr) return;
    217: #endif
    218:   *ierr = NEPSetJacobian(*nep,*J,ournepjacobian,NULL);
    219: }

    221: /* func is currently ignored from Fortran */
    222: SLEPC_EXTERN void nepgetjacobian_(NEP *nep,Mat *J,void *func,void **ctx,PetscErrorCode *ierr)
    223: {
    224:   CHKFORTRANNULLINTEGER(ctx);
    225:   CHKFORTRANNULLOBJECT(J);
    226:   *ierr = NEPGetJacobian(*nep,J,NULL,NULL); if (*ierr) return;
    227:   *ierr = PetscObjectGetFortranCallback((PetscObject)*nep,PETSC_FORTRAN_CALLBACK_CLASS,_cb.jacobian,NULL,ctx);
    228: }