xref: /petsc/src/mat/impls/shell/ftn-custom/zshellf.c (revision 86686b9b8e22012de9594ab220e0c9686f87f159)
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