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

Ethan Coon ecoon at lanl.gov
Mon Feb 7 10:26:21 CST 2011


On Sat, 2011-02-05 at 19:19 -0500, 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. 

Maybe it's not clear to me what you're trying to do, but I think that
petsc4py can make PCShells just fine.  

I've attached an example in pure python which uses petsc4py to generate
both Mat and PC shells to solve the saddle point problem that arises
from using Lagrange Multipliers to apply boundary conditions to
Laplace's equation.

Both the Schur complement and the full, block matrix are stored as Mat
shells, and a PC shell is used to store the PC of the full matrix
[[ A^-1, 0], [0, S]] and to do the inner solve required within the
MatShell for S.

Ethan


> 
> 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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: lm_solver.py
Type: text/x-python
Size: 8826 bytes
Desc: not available
URL: <http://lists.mcs.anl.gov/pipermail/petsc-users/attachments/20110207/0a0d613a/attachment.py>


More information about the petsc-users mailing list