Actual source code: zmgfuncf.c

  1: #include <petsc/private/ftnimpl.h>
  2: #include <petscpc.h>
  3: #include <petsc/private/pcmgimpl.h>

  5: #if PetscDefined(HAVE_FORTRAN_CAPS)
  6:   #define pcmgsetresidual_              PCMGSETRESIDUAL
  7:   #define pcmgresidualdefault_          PCMGRESIDUALDEFAULT
  8:   #define pcmgsetresidualtranspose_     PCMGSETRESIDUALTRANSPOSE
  9:   #define pcmgresidualtransposedefault_ PCMGRESIDUALTRANSPOSEDEFAULT
 10: #elif !PetscDefined(HAVE_FORTRAN_UNDERSCORE)
 11:   #define pcmgsetresidual_              pcmgsetresidual
 12:   #define pcmgresidualdefault_          pcmgresidualdefault
 13:   #define pcmgsetresidualtranspose_     pcmgsetresidualtranspose
 14:   #define pcmgresidualtransposedefault_ pcmgresidualtransposedefault
 15: #endif

 17: typedef PetscErrorCode (*MVVVV)(Mat, Vec, Vec, Vec);

 19: static struct {
 20:   PetscFortranCallbackId residual;
 21:   PetscFortranCallbackId residualtranspose;
 22: } _cb;

 24: static PetscErrorCode ourresidualfunction(Mat mat, Vec b, Vec x, Vec R)
 25: {
 26:   PetscObjectUseFortranCallback(mat, _cb.residual, (Mat *, Vec *, Vec *, Vec *, PetscErrorCode *), (&mat, &b, &x, &R, &ierr));
 27: }

 29: PETSC_EXTERN void pcmgresidualdefault_(Mat *, Vec *, Vec *, Vec *, PetscErrorCode *);

 31: PETSC_EXTERN void pcmgsetresidual_(PC *pc, PetscInt *l, void (*residual)(Mat *, Vec *, Vec *, Vec *, PetscErrorCode *), Mat *mat, PetscErrorCode *ierr)
 32: {
 33:   MVVVV rr;

 35:   CHKFORTRANNULLFUNCTION(residual);
 36:   if (!residual) rr = NULL;
 37:   else if (residual == pcmgresidualdefault_) rr = PCMGResidualDefault;
 38:   else {
 39:     /* The Mat is the only object passed to the residual computer. A keyed callback is used so that this does not collide with
 40:        the Fortran callbacks of a MATSHELL or MATMFFD, which are stored in fortran_func_pointers[] */
 41:     *ierr = PetscObjectSetFortranCallback((PetscObject)*mat, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.residual, (PetscFortranCallbackFn *)residual, NULL);
 42:     if (*ierr) return;
 43:     rr = ourresidualfunction;
 44:   }
 45:   *ierr = PCMGSetResidual(*pc, *l, rr, *mat);
 46: }

 48: static PetscErrorCode ourresidualtransposefunction(Mat mat, Vec b, Vec x, Vec R)
 49: {
 50:   PetscObjectUseFortranCallback(mat, _cb.residualtranspose, (Mat *, Vec *, Vec *, Vec *, PetscErrorCode *), (&mat, &b, &x, &R, &ierr));
 51: }

 53: PETSC_EXTERN void pcmgresidualtransposedefault_(Mat *, Vec *, Vec *, Vec *, PetscErrorCode *);

 55: PETSC_EXTERN void pcmgsetresidualtranspose_(PC *pc, PetscInt *l, void (*residualt)(Mat *, Vec *, Vec *, Vec *, PetscErrorCode *), Mat *mat, PetscErrorCode *ierr)
 56: {
 57:   MVVVV rr;

 59:   CHKFORTRANNULLFUNCTION(residualt);
 60:   if (!residualt) rr = NULL;
 61:   else if (residualt == pcmgresidualtransposedefault_) rr = PCMGResidualTransposeDefault;
 62:   else {
 63:     *ierr = PetscObjectSetFortranCallback((PetscObject)*mat, PETSC_FORTRAN_CALLBACK_CLASS, &_cb.residualtranspose, (PetscFortranCallbackFn *)residualt, NULL);
 64:     if (*ierr) return;
 65:     rr = ourresidualtransposefunction;
 66:   }
 67:   *ierr = PCMGSetResidualTranspose(*pc, *l, rr, *mat);
 68: }