Hi Adrian,

thanks.
Please find attached the modified version of the example.
Seems to work (at least compiles)

Martin


On Fri, 2018-11-09 at 13:04 +1300, Adrian Croucher wrote:
> hi Martin,
> 
> Sure, here it is.
> 
> - Adrian
> 
> On 9/11/18 12:34 PM, Martin Diehl wrote:
> > Dear Adrian,
> > 
> > I looked into the issue of passing in derived types with type bound
> > procedures again and it seems that casting to C pointers is a
> > suitable
> > alternative.
> > 
> > To investigate that, I modified ex5f.F90 from
> > src/snes/examples/tutorials in a branch of my PETSc fork:
> > 
> > https://bitbucket.org/m_diehl/petsc/src/5172a911a5cc8a6228f00f2435cc5cfe6ec569d9/?at=m.diehl%2FSNESSetConvergenceTestTypeFortran
> > 
> > 
> > Could you please send me your original minimal working example
> > again?
> > I've deleted it and would like to test the new approach there also.
> > 
> > many thanks
> > Martin
> > 
-- 
-----------------------------------------------
Max-Planck-Institut für Eisenforschung GmbH
Max-Planck-Straße 1
D-40237 Düsseldorf
 
Handelsregister B 2533 
Amtsgericht Düsseldorf
 
Geschäftsführung
Prof. Dr. Gerhard Dehm
Prof. Dr. Jörg Neugebauer
Prof. Dr. Dierk Raabe
Dr. Kai de Weldige
 
Ust.-Id.-Nr.: DE 11 93 58 514 
Steuernummer: 105 5891 1000
-------------------------------------------------
Please consider that invitations and e-mails of our institute are 
only valid if they end with …@mpie.de. 
If you are not sure of the validity please contact [email protected]

Bitte beachten Sie, dass Einladungen zu Veranstaltungen und E-Mails
aus unserem Haus nur mit der Endung …@mpie.de gültig sind. 
In Zweifelsfällen wenden Sie sich bitte an [email protected]
module context_module

#include <petsc/finclude/petsc.h>

  use petsc

  implicit none
  private

  type, public ::  context_type
     private
     PetscInt :: foo
   contains
     procedure, public :: init => context_init
  end type context_type

contains

  subroutine context_init(self, foo)
    class(context_type), intent(in out) :: self
    PetscInt, intent(in) :: foo
    self%foo = foo
  end subroutine context_init

end module context_module

!------------------------------------------------------------------------

program test_snes

  ! tests SNESSetConvergenceTest()
  
#include <petsc/finclude/petsc.h>
  use iso_c_binding
  use petsc
  use context_module

  implicit none

  SNES :: snes
  type(context_type),target :: context
  type(c_ptr) :: contextOut
  PetscErrorCode :: ierr

  call PetscInitialize(PETSC_NULL_CHARACTER, ierr)
  call SNESCreate(PETSC_COMM_WORLD, snes, ierr)
  call context%init(1)

  contextOut = c_loc(context) ! contextOut is a C pointer on context

  call SNESSetConvergenceTest(snes, convergence, contextOut, & ! pass in the pointer
       PETSC_NULL_FUNCTION, ierr)

  call SNESDestroy(snes, ierr)
  call PetscFinalize(ierr)

contains

  subroutine convergence(snes, num_iterations, xnorm, pnorm, &
       fnorm, reason, contextIn, ierr)

    SNES, intent(in) :: snes
    PetscInt, intent(in) :: num_iterations
    PetscReal, intent(in) :: xnorm, pnorm, fnorm
    SNESConvergedReason, intent(out) :: reason
    type(c_ptr), intent(in out) :: contextIn
    type(context_type), pointer :: context
    PetscErrorCode, intent(out) :: ierr
    
    call c_f_pointer(contextIn,context)  ! convert the C pointer to a Fortran pointer to use context as in the main program
    reason = 0
    ierr = 0

  end subroutine convergence
    
end program test_snes



Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to