1af0996ceSBarry Smith #include <petsc/private/fortranimpl.h> 2c6db04a5SJed Brown #include <petscmat.h> 3f4e70085SSatish Balay 4f4e70085SSatish Balay #if defined(PETSC_HAVE_FORTRAN_CAPS) 5f4e70085SSatish Balay #define matshellsetoperation_ MATSHELLSETOPERATION 6f4e70085SSatish Balay #define matcreateshell_ MATCREATESHELL 7f4e70085SSatish Balay #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE) 8f4e70085SSatish Balay #define matcreateshell_ matcreateshell 9f4e70085SSatish Balay #define matshellsetoperation_ matshellsetoperation 10f4e70085SSatish Balay #endif 11f4e70085SSatish Balay 12*86686b9bSAlex Fikl /** 13*86686b9bSAlex Fikl * Subset of MatOperation that is supported by the Fortran wrappers. 14*86686b9bSAlex Fikl */ 15*86686b9bSAlex Fikl enum FortranMatOperation { 16*86686b9bSAlex Fikl FORTRAN_MATOP_MULT = 0, 17*86686b9bSAlex Fikl FORTRAN_MATOP_MULT_ADD = 1, 18*86686b9bSAlex Fikl FORTRAN_MATOP_MULT_TRANSPOSE = 2, 19*86686b9bSAlex Fikl FORTRAN_MATOP_MULT_TRANSPOSE_ADD = 3, 20*86686b9bSAlex Fikl FORTRAN_MATOP_SOR = 4, 21*86686b9bSAlex Fikl FORTRAN_MATOP_TRANSPOSE = 5, 22*86686b9bSAlex Fikl FORTRAN_MATOP_GET_DIAGONAL = 6, 23*86686b9bSAlex Fikl FORTRAN_MATOP_DIAGONAL_SCALE = 7, 24*86686b9bSAlex Fikl FORTRAN_MATOP_ZERO_ENTRIES = 8, 25*86686b9bSAlex Fikl FORTRAN_MATOP_AXPY = 9, 26*86686b9bSAlex Fikl FORTRAN_MATOP_SHIFT = 10, 27*86686b9bSAlex Fikl FORTRAN_MATOP_DIAGONAL_SET = 11, 28*86686b9bSAlex Fikl FORTRAN_MATOP_DESTROY = 12, 29*86686b9bSAlex Fikl FORTRAN_MATOP_VIEW = 13, 30*86686b9bSAlex Fikl FORTRAN_MATOP_GET_VECS = 14, 31*86686b9bSAlex Fikl 32*86686b9bSAlex Fikl FORTRAN_MATOP_SIZE = 15 33*86686b9bSAlex Fikl }; 34*86686b9bSAlex Fikl 35f4e70085SSatish Balay /* 36f4e70085SSatish Balay The MatShell Matrix Vector product requires a C routine. 37f4e70085SSatish Balay This C routine then calls the corresponding Fortran routine that was 38f4e70085SSatish Balay set by the user. 39f4e70085SSatish Balay */ 408cc058d9SJed Brown PETSC_EXTERN void PETSC_STDCALL matcreateshell_(MPI_Comm *comm, PetscInt *m, PetscInt *n, PetscInt *M, PetscInt *N, void *ctx, Mat *mat, PetscErrorCode *ierr) 41f4e70085SSatish Balay { 422e843561SJed Brown *ierr = MatCreateShell(MPI_Comm_f2c(*(MPI_Fint*)&*comm), *m, *n, *M, *N, ctx, mat); 43f4e70085SSatish Balay } 44f4e70085SSatish Balay 45f4e70085SSatish Balay static PetscErrorCode ourmult(Mat mat, Vec x, Vec y) 46f4e70085SSatish Balay { 47f4e70085SSatish Balay PetscErrorCode ierr = 0; 48f4e70085SSatish Balay 49*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_MULT]))(&mat, &x, &y, &ierr); 50f4e70085SSatish Balay return ierr; 51f4e70085SSatish Balay } 52f4e70085SSatish Balay 53f4e70085SSatish Balay static PetscErrorCode ourmultadd(Mat mat, Vec x, Vec y, Vec z) 54f4e70085SSatish Balay { 55f4e70085SSatish Balay PetscErrorCode ierr = 0; 56*86686b9bSAlex Fikl 57*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, Vec*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_MULT_ADD]))(&mat, &x, &y, &z, &ierr); 58*86686b9bSAlex Fikl return ierr; 59*86686b9bSAlex Fikl } 60*86686b9bSAlex Fikl 61*86686b9bSAlex Fikl static PetscErrorCode ourmulttranspose(Mat mat, Vec x, Vec y) 62*86686b9bSAlex Fikl { 63*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 64*86686b9bSAlex Fikl 65*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_MULT_TRANSPOSE]))(&mat, &x, &y, &ierr); 66f4e70085SSatish Balay return ierr; 67f4e70085SSatish Balay } 68f4e70085SSatish Balay 69f4e70085SSatish Balay static PetscErrorCode ourmulttransposeadd(Mat mat, Vec x, Vec y, Vec z) 70f4e70085SSatish Balay { 71f4e70085SSatish Balay PetscErrorCode ierr = 0; 72f4e70085SSatish Balay 73*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, Vec*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_MULT_TRANSPOSE_ADD]))(&mat, &x, &y, &z, &ierr); 742950f7e7SBarry Smith return ierr; 752950f7e7SBarry Smith } 762950f7e7SBarry Smith 773446fae8SBarry Smith static PetscErrorCode oursor(Mat mat, Vec b, PetscReal omega, MatSORType flg, PetscReal shift, PetscInt its, PetscInt lits, Vec x) 783446fae8SBarry Smith { 793446fae8SBarry Smith PetscErrorCode ierr = 0; 80*86686b9bSAlex Fikl 81*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, PetscReal*, MatSORType*, PetscReal*, PetscInt*, PetscInt*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_SOR]))(&mat, &b, &omega, &flg, &shift, &its, &lits, &x, &ierr); 82*86686b9bSAlex Fikl return ierr; 83*86686b9bSAlex Fikl } 84*86686b9bSAlex Fikl 85*86686b9bSAlex Fikl static PetscErrorCode ourtranspose(Mat mat, MatReuse reuse, Mat *B) 86*86686b9bSAlex Fikl { 87*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 88*86686b9bSAlex Fikl Mat *b = (!B ? (Mat *) PETSC_NULL_OBJECT_Fortran : B); 89*86686b9bSAlex Fikl 90*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, MatReuse*, Mat *, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_TRANSPOSE]))(&mat, &reuse, b, &ierr); 91*86686b9bSAlex Fikl return ierr; 92*86686b9bSAlex Fikl } 93*86686b9bSAlex Fikl 94*86686b9bSAlex Fikl static PetscErrorCode ourgetdiagonal(Mat mat, Vec x) 95*86686b9bSAlex Fikl { 96*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 97*86686b9bSAlex Fikl 98*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_GET_DIAGONAL]))(&mat, &x, &ierr); 99*86686b9bSAlex Fikl return ierr; 100*86686b9bSAlex Fikl } 101*86686b9bSAlex Fikl 102*86686b9bSAlex Fikl static PetscErrorCode ourdiagonalscale(Mat mat, Vec l, Vec r) 103*86686b9bSAlex Fikl { 104*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 105*86686b9bSAlex Fikl Vec *a = (!l ? (Vec*) PETSC_NULL_OBJECT_Fortran : &l); 106*86686b9bSAlex Fikl Vec *b = (!r ? (Vec*) PETSC_NULL_OBJECT_Fortran : &r); 107*86686b9bSAlex Fikl 108*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_DIAGONAL_SCALE]))(&mat, a, b, &ierr); 109*86686b9bSAlex Fikl return ierr; 110*86686b9bSAlex Fikl } 111*86686b9bSAlex Fikl 112*86686b9bSAlex Fikl static PetscErrorCode ourzeroentries(Mat mat) 113*86686b9bSAlex Fikl { 114*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 115*86686b9bSAlex Fikl 116*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_ZERO_ENTRIES]))(&mat, &ierr); 117*86686b9bSAlex Fikl return ierr; 118*86686b9bSAlex Fikl } 119*86686b9bSAlex Fikl 120*86686b9bSAlex Fikl static PetscErrorCode ouraxpy(Mat mat, PetscScalar a, Mat X, MatStructure str) 121*86686b9bSAlex Fikl { 122*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 123*86686b9bSAlex Fikl 124*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, PetscScalar*, Mat*, MatStructure*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_AXPY]))(&mat, &a, &X, &str, &ierr); 1253446fae8SBarry Smith return ierr; 1263446fae8SBarry Smith } 1273446fae8SBarry Smith 128cdf26a31SSatish Balay static PetscErrorCode ourshift(Mat mat, PetscScalar a) 129cdf26a31SSatish Balay { 130cdf26a31SSatish Balay PetscErrorCode ierr = 0; 131*86686b9bSAlex Fikl 132*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, PetscScalar*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_SHIFT]))(&mat, &a, &ierr); 133*86686b9bSAlex Fikl return ierr; 134*86686b9bSAlex Fikl } 135*86686b9bSAlex Fikl 136*86686b9bSAlex Fikl static PetscErrorCode ourdiagonalset(Mat mat, Vec x, InsertMode ins) 137*86686b9bSAlex Fikl { 138*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 139*86686b9bSAlex Fikl 140*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, InsertMode*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_DIAGONAL_SET]))(&mat, &x, &ins, &ierr); 141*86686b9bSAlex Fikl return ierr; 142*86686b9bSAlex Fikl } 143*86686b9bSAlex Fikl 144*86686b9bSAlex Fikl static PetscErrorCode ourdestroy(Mat mat) 145*86686b9bSAlex Fikl { 146*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 147*86686b9bSAlex Fikl 148*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_DESTROY]))(&mat, &ierr); 149*86686b9bSAlex Fikl return ierr; 150*86686b9bSAlex Fikl } 151*86686b9bSAlex Fikl 152*86686b9bSAlex Fikl static PetscErrorCode ourview(Mat mat, PetscViewer v) 153*86686b9bSAlex Fikl { 154*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 155*86686b9bSAlex Fikl 156*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, PetscViewer*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_VIEW]))(&mat, &v, &ierr); 157*86686b9bSAlex Fikl return ierr; 158*86686b9bSAlex Fikl } 159*86686b9bSAlex Fikl 160*86686b9bSAlex Fikl static PetscErrorCode ourgetvecs(Mat mat, Vec *l, Vec *r) 161*86686b9bSAlex Fikl { 162*86686b9bSAlex Fikl PetscErrorCode ierr = 0; 163*86686b9bSAlex Fikl Vec *a = (!l ? (Vec *) PETSC_NULL_OBJECT_Fortran : l); 164*86686b9bSAlex Fikl Vec *b = (!r ? (Vec *) PETSC_NULL_OBJECT_Fortran : r); 165*86686b9bSAlex Fikl 166*86686b9bSAlex Fikl (*(PetscErrorCode (PETSC_STDCALL *)(Mat*, Vec*, Vec*, PetscErrorCode*))(((PetscObject) mat)->fortran_func_pointers[FORTRAN_MATOP_GET_VECS]))(&mat, a, b, &ierr); 167cdf26a31SSatish Balay return ierr; 168cdf26a31SSatish Balay } 169cdf26a31SSatish Balay 1708cc058d9SJed Brown PETSC_EXTERN void PETSC_STDCALL matshellsetoperation_(Mat *mat, MatOperation *op, PetscErrorCode (PETSC_STDCALL *f)(Mat*, Vec*, Vec*, PetscErrorCode*), PetscErrorCode *ierr) 171f4e70085SSatish Balay { 172e32f2f54SBarry Smith MPI_Comm comm; 173e32f2f54SBarry Smith 174e32f2f54SBarry Smith *ierr = PetscObjectGetComm((PetscObject) *mat, &comm);if (*ierr) return; 175*86686b9bSAlex Fikl PetscObjectAllocateFortranPointers(*mat, FORTRAN_MATOP_SIZE); 176*86686b9bSAlex Fikl 177*86686b9bSAlex Fikl switch (*op) { 178*86686b9bSAlex Fikl case MATOP_MULT: 179f68b968cSBarry Smith *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourmult); 180*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_MULT] = (PetscVoidFunction) f; 181*86686b9bSAlex Fikl break; 182*86686b9bSAlex Fikl case MATOP_MULT_ADD: 183f68b968cSBarry Smith *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourmultadd); 184*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_MULT_ADD] = (PetscVoidFunction) f; 185*86686b9bSAlex Fikl break; 186*86686b9bSAlex Fikl case MATOP_MULT_TRANSPOSE: 187*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourmulttranspose); 188*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_MULT_TRANSPOSE] = (PetscVoidFunction) f; 189*86686b9bSAlex Fikl break; 190*86686b9bSAlex Fikl case MATOP_MULT_TRANSPOSE_ADD: 191f68b968cSBarry Smith *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourmulttransposeadd); 192*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_MULT_TRANSPOSE_ADD] = (PetscVoidFunction) f; 193*86686b9bSAlex Fikl break; 194*86686b9bSAlex Fikl case MATOP_SOR: 1953446fae8SBarry Smith *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) oursor); 196*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_SOR] = (PetscVoidFunction) f; 197*86686b9bSAlex Fikl break; 198*86686b9bSAlex Fikl case MATOP_TRANSPOSE: 199*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourtranspose); 200*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_TRANSPOSE] = (PetscVoidFunction) f; 201*86686b9bSAlex Fikl break; 202*86686b9bSAlex Fikl case MATOP_GET_DIAGONAL: 203*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourgetdiagonal); 204*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_GET_DIAGONAL] = (PetscVoidFunction) f; 205*86686b9bSAlex Fikl break; 206*86686b9bSAlex Fikl case MATOP_DIAGONAL_SCALE: 207*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourdiagonalscale); 208*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_DIAGONAL_SCALE] = (PetscVoidFunction) f; 209*86686b9bSAlex Fikl break; 210*86686b9bSAlex Fikl case MATOP_ZERO_ENTRIES: 211*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourzeroentries); 212*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_ZERO_ENTRIES] = (PetscVoidFunction) f; 213*86686b9bSAlex Fikl break; 214*86686b9bSAlex Fikl case MATOP_AXPY: 215*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ouraxpy); 216*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_AXPY] = (PetscVoidFunction) f; 217*86686b9bSAlex Fikl break; 218*86686b9bSAlex Fikl case MATOP_SHIFT: 219cdf26a31SSatish Balay *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourshift); 220*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_SHIFT] = (PetscVoidFunction) f; 221*86686b9bSAlex Fikl break; 222*86686b9bSAlex Fikl case MATOP_DIAGONAL_SET: 223*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourdiagonalset); 224*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_DIAGONAL_SET] = (PetscVoidFunction) f; 225*86686b9bSAlex Fikl break; 226*86686b9bSAlex Fikl case MATOP_DESTROY: 227*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourdestroy); 228*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_DESTROY] = (PetscVoidFunction) f; 229*86686b9bSAlex Fikl break; 230*86686b9bSAlex Fikl case MATOP_VIEW: 231*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourview); 232*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_VIEW] = (PetscVoidFunction) f; 233*86686b9bSAlex Fikl break; 234*86686b9bSAlex Fikl case MATOP_GET_VECS: 235*86686b9bSAlex Fikl *ierr = MatShellSetOperation(*mat, *op, (PetscVoidFunction) ourgetvecs); 236*86686b9bSAlex Fikl ((PetscObject)*mat)->fortran_func_pointers[FORTRAN_MATOP_GET_VECS] = (PetscVoidFunction) f; 237*86686b9bSAlex Fikl break; 238*86686b9bSAlex Fikl default: 239*86686b9bSAlex Fikl PetscError(comm, __LINE__, "MatShellSetOperation_Fortran", __FILE__, PETSC_ERR_ARG_WRONG, PETSC_ERROR_INITIAL, "Cannot set that matrix operation"); 240f4e70085SSatish Balay *ierr = 1; 241f4e70085SSatish Balay } 242f4e70085SSatish Balay } 243