xref: /petsc/src/ksp/pc/impls/mg/ftn-custom/zmgfuncf.c (revision 2205254efee3a00a594e5e2a3a70f74dcb40bc03)
1 #include <petsc-private/fortranimpl.h>
2 #include <petscpc.h>
3 #include <petscpcmg.h>
4 
5 #if defined(PETSC_HAVE_FORTRAN_CAPS)
6 #define pcmgsetresidual_           PCMGSETRESIDUAL
7 #define pcmgdefaultresidual_       PCMGDEFAULTRESIDUAL
8 #elif !defined(PETSC_HAVE_FORTRAN_UNDERSCORE)
9 #define pcmgsetresidual_           pcmgsetresidual
10 #define pcmgdefaultresidual_       pcmgdefaultresidual
11 #endif
12 
13 typedef PetscErrorCode (*MVVVV)(Mat,Vec,Vec,Vec);
14 static PetscErrorCode ourresidualfunction(Mat mat,Vec b,Vec x,Vec R)
15 {
16   PetscErrorCode ierr = 0;
17   (*(void (PETSC_STDCALL *)(Mat*,Vec*,Vec*,Vec*,PetscErrorCode*))(((PetscObject)mat)->fortran_func_pointers[0]))(&mat,&b,&x,&R,&ierr);
18   return 0;
19 }
20 
21 EXTERN_C_BEGIN
22 void pcmgdefaultresidual_(Mat *mat,Vec *b,Vec *x,Vec *r, PetscErrorCode *ierr)
23 {
24   *ierr = PCMGDefaultResidual(*mat,*b,*x,*r);
25 }
26 
27 void PETSC_STDCALL pcmgsetresidual_(PC *pc,PetscInt *l,PetscErrorCode (*residual)(Mat*,Vec*,Vec*,Vec*,PetscErrorCode*),Mat *mat, PetscErrorCode *ierr)
28 {
29   MVVVV rr;
30   if ((PetscVoidFunction)residual == (PetscVoidFunction)pcmgdefaultresidual_) rr = PCMGDefaultResidual;
31   else {
32     PetscObjectAllocateFortranPointers(*mat,1);
33     /*  Attach the residual computer to the Mat, this is not ideal but the only object/context passed in the residual computer */
34     ((PetscObject)*mat)->fortran_func_pointers[0] = (PetscVoidFunction)residual;
35 
36     rr = ourresidualfunction;
37   }
38   *ierr = PCMGSetResidual(*pc,*l,rr,*mat);
39 }
40 
41 EXTERN_C_END
42