1ce0a2cd1SBarry Smith #include "private/fortranimpl.h" 2f4e70085SSatish Balay #include "petscmat.h" 3f4e70085SSatish Balay 4f4e70085SSatish Balay #if defined(PETSC_HAVE_FORTRAN_CAPS) 5f4e70085SSatish Balay #define matshellsetoperation_ MATSHELLSETOPERATION 6f4e70085SSatish Balay #define matcreateshell_ MATCREATESHELL 7*c6866cfdSSatish Balay #define matshellgetcontext_ MATSHELLGETCONTEXT 8f4e70085SSatish Balay #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 9f4e70085SSatish Balay #define matcreateshell_ matcreateshell 10f4e70085SSatish Balay #define matshellsetoperation_ matshellsetoperation 11*c6866cfdSSatish Balay #define matshellgetcontext_ matshellgetcontext 12f4e70085SSatish Balay #endif 13f4e70085SSatish Balay 14f4e70085SSatish Balay EXTERN_C_BEGIN 15f4e70085SSatish Balay 16f4e70085SSatish Balay /* 17f4e70085SSatish Balay The MatShell Matrix Vector product requires a C routine. 18f4e70085SSatish Balay This C routine then calls the corresponding Fortran routine that was 19f4e70085SSatish Balay set by the user. 20f4e70085SSatish Balay */ 21f4e70085SSatish Balay void PETSC_STDCALL matcreateshell_(MPI_Comm *comm,PetscInt *m,PetscInt *n,PetscInt *M,PetscInt *N,void **ctx,Mat *mat,PetscErrorCode *ierr) 22f4e70085SSatish Balay { 23a542b6e8SBarry Smith *ierr = MatCreateShell(MPI_Comm_f2c(*(MPI_Fint *)&*comm),*m,*n,*M,*N,*ctx,mat); 245db8bc65SBarry Smith 25f4e70085SSatish Balay } 26f4e70085SSatish Balay 27f4e70085SSatish Balay static PetscErrorCode ourmult(Mat mat,Vec x,Vec y) 28f4e70085SSatish Balay { 29f4e70085SSatish Balay PetscErrorCode ierr = 0; 30f4e70085SSatish Balay (*(PetscErrorCode (PETSC_STDCALL *)(Mat*,Vec*,Vec*,PetscErrorCode*))(((PetscObject)mat)->fortran_func_pointers[0]))(&mat,&x,&y,&ierr); 31f4e70085SSatish Balay return ierr; 32f4e70085SSatish Balay } 33f4e70085SSatish Balay 34f4e70085SSatish Balay static PetscErrorCode ourmulttranspose(Mat mat,Vec x,Vec y) 35f4e70085SSatish Balay { 36f4e70085SSatish Balay PetscErrorCode ierr = 0; 37f4e70085SSatish Balay (*(PetscErrorCode (PETSC_STDCALL *)(Mat*,Vec*,Vec*,PetscErrorCode*))(((PetscObject)mat)->fortran_func_pointers[2]))(&mat,&x,&y,&ierr); 38f4e70085SSatish Balay return ierr; 39f4e70085SSatish Balay } 40f4e70085SSatish Balay 41f4e70085SSatish Balay static PetscErrorCode ourmultadd(Mat mat,Vec x,Vec y,Vec z) 42f4e70085SSatish Balay { 43f4e70085SSatish Balay PetscErrorCode ierr = 0; 44f4e70085SSatish Balay (*(PetscErrorCode (PETSC_STDCALL *)(Mat*,Vec*,Vec*,Vec*,PetscErrorCode*))(((PetscObject)mat)->fortran_func_pointers[1]))(&mat,&x,&y,&z,&ierr); 45f4e70085SSatish Balay return ierr; 46f4e70085SSatish Balay } 47f4e70085SSatish Balay 48f4e70085SSatish Balay static PetscErrorCode ourmulttransposeadd(Mat mat,Vec x,Vec y,Vec z) 49f4e70085SSatish Balay { 50f4e70085SSatish Balay PetscErrorCode ierr = 0; 51f4e70085SSatish Balay (*(PetscErrorCode (PETSC_STDCALL *)(Mat*,Vec*,Vec*,Vec*,PetscErrorCode*))(((PetscObject)mat)->fortran_func_pointers[3]))(&mat,&x,&y,&z,&ierr); 52f4e70085SSatish Balay return ierr; 53f4e70085SSatish Balay } 54f4e70085SSatish Balay 5522612f2fSMatthew Knepley static PetscErrorCode ourgetdiagonal(Mat mat,Vec x) 5622612f2fSMatthew Knepley { 5722612f2fSMatthew Knepley PetscErrorCode ierr = 0; 5822612f2fSMatthew Knepley (*(PetscErrorCode (PETSC_STDCALL *)(Mat*,Vec*,PetscErrorCode*))(((PetscObject)mat)->fortran_func_pointers[4]))(&mat,&x,&ierr); 5922612f2fSMatthew Knepley return ierr; 6022612f2fSMatthew Knepley } 6122612f2fSMatthew Knepley 62f4e70085SSatish Balay void PETSC_STDCALL matshellsetoperation_(Mat *mat,MatOperation *op,PetscErrorCode (PETSC_STDCALL *f)(Mat*,Vec*,Vec*,PetscErrorCode*),PetscErrorCode *ierr) 63f4e70085SSatish Balay { 64f787a65dSBarry Smith PetscObjectAllocateFortranPointers(*mat,5); 65f4e70085SSatish Balay if (*op == MATOP_MULT) { 66f68b968cSBarry Smith *ierr = MatShellSetOperation(*mat,*op,(PetscVoidFunction)ourmult); 67f68b968cSBarry Smith ((PetscObject)*mat)->fortran_func_pointers[0] = (PetscVoidFunction)f; 68f4e70085SSatish Balay } else if (*op == MATOP_MULT_TRANSPOSE) { 69f68b968cSBarry Smith *ierr = MatShellSetOperation(*mat,*op,(PetscVoidFunction)ourmulttranspose); 70f68b968cSBarry Smith ((PetscObject)*mat)->fortran_func_pointers[2] = (PetscVoidFunction)f; 71f4e70085SSatish Balay } else if (*op == MATOP_MULT_ADD) { 72f68b968cSBarry Smith *ierr = MatShellSetOperation(*mat,*op,(PetscVoidFunction)ourmultadd); 73f68b968cSBarry Smith ((PetscObject)*mat)->fortran_func_pointers[1] = (PetscVoidFunction)f; 74f4e70085SSatish Balay } else if (*op == MATOP_MULT_TRANSPOSE_ADD) { 75f68b968cSBarry Smith *ierr = MatShellSetOperation(*mat,*op,(PetscVoidFunction)ourmulttransposeadd); 76f68b968cSBarry Smith ((PetscObject)*mat)->fortran_func_pointers[3] = (PetscVoidFunction)f; 7722612f2fSMatthew Knepley } else if (*op == MATOP_GET_DIAGONAL) { 7822612f2fSMatthew Knepley *ierr = MatShellSetOperation(*mat,*op,(PetscVoidFunction)ourgetdiagonal); 7922612f2fSMatthew Knepley ((PetscObject)*mat)->fortran_func_pointers[4] = (PetscVoidFunction)f; 80f4e70085SSatish Balay } else { 81f4e70085SSatish Balay PetscError(__LINE__,"MatShellSetOperation_Fortran",__FILE__,__SDIR__,1,0, 82f4e70085SSatish Balay "Cannot set that matrix operation"); 83f4e70085SSatish Balay *ierr = 1; 84f4e70085SSatish Balay } 85f4e70085SSatish Balay } 86f4e70085SSatish Balay 87*c6866cfdSSatish Balay void PETSC_STDCALL matshellgetcontext_(Mat *mat,void **ctx,PetscErrorCode *ierr) 88*c6866cfdSSatish Balay { 89*c6866cfdSSatish Balay *ierr = MatShellGetContext(*mat,ctx); 90*c6866cfdSSatish Balay } 91*c6866cfdSSatish Balay 92*c6866cfdSSatish Balay 93f4e70085SSatish Balay EXTERN_C_END 94