Line data Source code
1 : !--------------------------------------------------------------------------------
2 : ! Copyright (c) 2016 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
3 : ! This file is part of FLEUR and available as free software under the conditions
4 : ! of the MIT license as expressed in the LICENSE file in more detail.
5 : !--------------------------------------------------------------------------------
6 :
7 : module m_elemental
8 : PRIVATE
9 : !Module to call the elemental library for parallel diagonalization
10 : !complex only version at present!
11 : #ifdef CPP_ELEMENTAL
12 : ! This is the interface defined in fleur_elemental.cpp
13 : interface
14 : subroutine fl_el_initialize(n,hmat,smat,mpi_com) bind (c)
15 : use, intrinsic :: iso_c_binding
16 : integer(kind=c_int),value :: n,mpi_com
17 : complex(kind=c_double_complex),dimension(*),intent(in) :: hmat,smat
18 : end subroutine
19 : end interface
20 :
21 : interface
22 : subroutine fl_el_diagonalize(neig,direct,nex,deg,tol,mode,opt,z) bind (c)
23 : use, intrinsic :: iso_c_binding
24 : integer(kind=c_int),value :: neig,direct,nex,deg,mode,opt
25 : real(kind=c_double),value :: tol
26 : complex(kind=c_double_complex),dimension(*),intent(in):: z
27 : end subroutine
28 : end interface
29 :
30 : interface
31 : subroutine fl_el_eigenvalues(neig,eig) bind (c)
32 : use, intrinsic :: iso_c_binding
33 : integer(kind=c_int),value :: neig
34 : real(kind=c_double),dimension(*),intent(out):: eig
35 : end subroutine
36 : end interface
37 :
38 : interface
39 : subroutine fl_el_eigenvectors(neig,eig,z) bind (c)
40 : use, intrinsic :: iso_c_binding
41 : integer(kind=c_int),value :: neig
42 : real(kind=c_double),dimension(*),intent(out) :: eig
43 : complex(kind=c_double_complex),dimension(*),intent(out):: z
44 : end subroutine
45 : end interface
46 : #endif
47 : PUBLIC elemental
48 :
49 : CONTAINS
50 :
51 0 : SUBROUTINE elemental(m,n,SUB_COMM,a,b,z,eig,num,direct)
52 : !
53 : !----------------------------------------------------
54 : !- Parallel eigensystem solver - driver routine based on chani; dw'12
55 : !
56 : ! m ........ actual (=leading) dimension of full a & b matrices
57 : ! must be problem size, as input a, b are one-dimensional
58 : ! and shall be redistributed to two-dimensional matrices
59 : ! actual (=leading) dimension of eigenvector z(,)
60 : ! n ........ number of columns of full (sub)matrix ( about n/np)
61 : ! SUB_COMM.. communicator for MPI
62 : ! a,b .... packed (sub)matrices, here expanded to non-packed
63 : ! z,eig .... eigenvectors and values, output
64 : ! num ...... number of ev's searched (and found) on this node
65 : ! On input, overall number of ev's searched,
66 : ! On output, local number of ev's found
67 : !
68 : !----------------------------------------------------
69 : !
70 : use m_juDFT
71 : IMPLICIT NONE
72 : INTEGER, INTENT (IN) :: m,n,direct
73 : INTEGER, INTENT (IN) :: SUB_COMM
74 : INTEGER, INTENT (INOUT) :: num
75 : REAL, INTENT (OUT) :: eig(:)
76 : COMPLEX, ALLOCATABLE, INTENT (INOUT) :: a(:),b(:)
77 : COMPLEX, INTENT (INOUT) :: z(:,:)
78 :
79 : INTEGER ::neig,nex,deg,mode,opt
80 : REAL :: tol
81 : INTEGER :: isize,ierr
82 : #ifdef CPP_ELEMENTAL
83 : !Initialize the matrices in elemental
84 : CALL fl_el_initialize(m,a,b,SUB_COMM)
85 : DEALLOCATE(a,b)
86 :
87 : !call diagonalization
88 : neig=num
89 : nex=40
90 : deg=15
91 : tol=1E-8
92 : mode=0 !random vectors!?
93 : opt=1 !opt multiple
94 :
95 : print*, "Elemental: seeking",neig," eigenvalues with direct:",direct
96 : call fl_el_diagonalize(neig,direct,nex,deg,tol,mode,opt,z(:m,:))
97 :
98 : CALL MPI_COMM_SIZE(SUB_COMM,isize,ierr)
99 : num=min(size(z,2),neig/isize)
100 : print*, "Elemental provides ",num," local eigenvalues"
101 :
102 : call fl_el_eigenvectors(num,eig,z(:m,:))
103 :
104 : #endif
105 0 : END subroutine
106 : END module
|