[petsc-users] Fortran external procedure in ctx()

Barry Smith bsmith at mcs.anl.gov
Sat Feb 5 19:28:52 CST 2011


On Feb 5, 2011, at 6:19 PM, Gaetan Kenway wrote:

> Hello 
> 
> I'm wondering if it is possible to put an external procedure reference in a ctx() in fortran.
> 
>  I'm in the process of writing a Newton--Krylov solver for an aero-structural system. My two different codes are wrapped with python and so each code is called through python for residual and preconditioning operations. Nominally this would be a good use of petsc4py but it doesn't allow for PCShell so it is no use to me. 

  Before making live hard by futzing around with Fortran or C lets make sure you really cannot do this in Python. What about using PCPYTHON? My guess is that this allows building your PC from pieces just like PCSHELL. 

   Barry

> 
> I then wrote up the solver in Fortran and attempted to use callbacks to python for computing the required information. Using f2py, I can pass my two call back functions cb1 and cb2 fortran. A schematic of the code is below:
> 
> subroutine solver(cb1, cb2)
> 
>    ! cb1 and cb2 are python callbacks set using f2py
>    external cb1,cb2
>    petscFortranAddress ctx(2)
> 
>    ! I would like to do the following, but this doesn't compile
>    ! ctx(1) = cb1
>    ! ctx(2) = cb2
> 
>   call SNESCreate(comm,snes,ierr)
>   call SNESSetFunction(snes,resVec,FormFunction,ctx,ierr)
> 
>   call KSPGetPC(ksp,pc,ierr)
>   call PCSetType(pc,PCSHELL,ierr)
> 
>   call PCShellSetContext(pc,ctx,ierr)
>   call PCShellSetApply(pc,applyaspc_fortran,ierr)
> 
> end subroutine solver
> 
> subroutine applyaspc_fortran(pc,inputVec,outputVec,ierr)
> 
>   PC      pc
>   Vec     inputVec,outputVec
>   PetscFortranAddress ctx(2)
>   external func
>   
>   call PCShellGetContext(pc,ctx,ierr)
>   func = ctx(2)
> 
>   call VecGetArrayF90(inputVec,states_in,ierr)
>   call VecGetArrayF90(outputVec,states_out,ierr)
> 
>   ! Call the callback to python
>   call func(states_in,states_out,shape(states_in))
> 
>   call VecRestoreArrayF90(inputVec,states_in,ierr)
>   call VecRestoreArrayF90(outputVec,states_out,ierr)
> end subroutine applyaspc_fortran
> 
> 
>  In general, in Fortran, is it possible to put an external function reference in a module such that I wouldn't have to try to pass it through the application ctx? I realize this may be impossible to do in Fortran. Would such a procedure be possible in C? I'm only using Fortran since I'm much more familiar with it then with C.
> 
> Sorry there isn't much to go on, but any suggestions would be greatly appreciated.
> 
> Gaetan



More information about the petsc-users mailing list