Hi there,

I'm stuck getting a call to the SLEPC routine "NEPNLEIGSSetSingularitiesFunction" to work from within Fortran. To be more precise: To get started with the solution of a non-linear eigenvalue-problem, I am first trying to write a Fortran version of slepc-3.8.1/.../nep/examples/tutorials/ex27.c, and then use it as a template for my own code. But I haven't gotten far...

Let me attach the source of the current state of my attempt to translate ex27.c to Fortran code. When trying to compile the attached source, my compiler complains:

nleigs.o: In function `MAIN__':
nleigs.f90:(.text+0x213): undefined reference to `nepnleigssetsingularitiesfunction_'

Does someone maybe see what I'm doing wrong? Do I maybe need to add a USE statement in addition to

USE slepcsys
USE slepcnep

?
I'm quite confused about the C++ pointers and how to deal with them when calling C++ functions from Fortran, so I don't really understand what's going on here. I will greatly appreciate your help!

Thanks,
Samuel
! ----------------------------------------------------
!                user-defined context
! ----------------------------------------------------
MODULE solver_context
#include "slepc/finclude/slepc.h"
  ! ------
  USE slepcsys
  USE slepcnep
  ! ------
  IMPLICIT NONE

  TYPE :: MatCtx
     PetscScalar :: lambda,kappa
     PetscReal :: h
  END TYPE MatCtx

END MODULE solver_context

! ----------------------------------------------------
!                    main program
! ----------------------------------------------------
!
!   Solve T(lambda)x=0 using NLEIGS solver
!      with T(lambda) = -D+sqrt(lambda)*I
!      where D is the Laplacian operator in 1 dimension
!      and with the interpolation interval [.01,16]
!
PROGRAM main
#include "slepc/finclude/slepc.h"
  ! ------
  USE slepcsys
  USE slepcnep
  ! ------
  USE solver_context
  IMPLICIT NONE
  NEP :: nep
  Mat :: F,A(2)
  NEPType :: type
  PetscInt :: n=100,nev,Istart,Iend,i
  PetscErrorCode :: ierr
  PetscBool :: terse,split=PETSC_TRUE
  RG :: rg
  FN :: fn(2)
  PetscScalar :: coeffs
  PetscBool :: flg
  ! ----
  CHARACTER(LEN=128) :: string
  TYPE(MatCtx),TARGET :: ctx
  TYPE(MatCtx),POINTER :: ctx_pt

  ! NOTE: Any user-defined Fortran routines (such as ComputeSingularities)
  !       MUST be declared as external.
  external ComputeSingularities

  !
  CALL SlepcInitialize(PETSC_NULL_CHARACTER,ierr)
  CALL PetscOptionsGetInt(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,"-n",n,flg,ierr)
  CALL PetscOptionsGetBool(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,"-split",split,flg,ierr)
  WRITE(string,*) 'Square root eigenproblem, n=',n,'\n In split form: ',split,'\n'
  CALL PetscPrintf(PETSC_COMM_WORLD,TRIM(string),ierr)
  
  ! ------------------------------------------------------
  ! Create nonlinear eigensolver context
  ! ------------------------------------------------------
  CALL NEPCreate(PETSC_COMM_WORLD,nep,ierr)

  ! ------------------------------------------------------
  ! Select the NLEIGS solver and set required options for it
  ! ------------------------------------------------------
  CALL NEPSetType(nep,NEPNLEIGS,ierr)
  ctx_pt => ctx
  CALL NEPNLEIGSSetSingularitiesFunction(nep,ComputeSingularities,ctx_pt,ierr)


  !
  CALL SlepcFinalize(ierr)

END PROGRAM main


! ComputeSingularities --------------------------------------
! Computes maxnp points (at most) in the complex plane where the
! function T(.) is not analytic.
SUBROUTINE ComputeSingularities(nep,maxnp,xi,ctx_pt,ierr)
#include "slepc/finclude/slepc.h"
  USE solver_context
  ! ---
  USE slepcsys
  USE slepcnep
  IMPLICIT NONE
  NEP :: nep
  PetscInt :: maxnp
  PetscScalar :: xi(0:maxnp-1)
  TYPE(MatCtx), POINTER :: ctx_pt
  PetscErrorCode :: ierr
  ! ---
  PetscReal :: h
  PetscInt :: i

  h = 11.0/(maxnp-1)
  xi(0) = -1e-5
  xi(maxnp-1) = -1e+6
  DO i=1,maxnp-2
     xi(i) = -10**(-5+h*i)
  END DO

END SUBROUTINE ComputeSingularities

Reply via email to