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