LCOV - code coverage report
Current view: top level - diagonalization - elpa_20180525.F90 (source / functions) Hit Total Coverage
Test: combined.info Lines: 43 45 95.6 %
Date: 2019-09-08 04:53:50 Functions: 1 1 100.0 %

          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_elpa
       8             : CONTAINS
       9         884 :   SUBROUTINE elpa_diag(hmat,smat,ne,eig,ev)
      10             :     !
      11             :     !----------------------------------------------------
      12             :     !- Parallel eigensystem solver - driver routine based on chani; dw'12
      13             :     !  Uses the ELPA for the actual diagonalization
      14             :     !
      15             :     !
      16             :     ! hmat ..... Hamiltonian matrix
      17             :     ! smat ..... overlap matrix
      18             :     ! ne ....... number of ev's searched (and found) on this node
      19             :     !            On input, overall number of ev's searched,
      20             :     !            On output, local number of ev's found
      21             :     ! eig ...... eigenvalues, output
      22             :     ! ev ....... eigenvectors, output
      23             :     !
      24             :     !----------------------------------------------------
      25             :     USE m_juDFT
      26             :     USE m_types_mpimat
      27             :     USE m_types_mat
      28             :     USE elpa
      29             :     IMPLICIT NONE
      30             : 
      31             :     CLASS(t_mat),INTENT(INOUT)    :: hmat,smat
      32             :     CLASS(t_mat),ALLOCATABLE,INTENT(OUT)::ev
      33             :     REAL,INTENT(out)              :: eig(:)
      34             :     INTEGER,INTENT(INOUT)         :: ne
      35             :     
      36             :     !...  Local variables
      37             :     !
      38             :     INTEGER           :: num, np,myid
      39             :     INTEGER           :: err
      40             :     INTEGER           :: i
      41         884 :     REAL,ALLOCATABLE      :: eig2(:)
      42         884 :     TYPE(t_mpimat)        :: ev_dist
      43             :     INTEGER               :: kernel
      44             :     CLASS(elpa_t),pointer :: elpa_obj
      45             : 
      46             : 
      47             :     SELECT TYPE(hmat)
      48             :     TYPE IS (t_mpimat)
      49         884 :     SELECT TYPE(smat)
      50             :     TYPE IS (t_mpimat)
      51         884 :        CALL MPI_BARRIER(hmat%blacsdata%mpi_com,err)    
      52         884 :        CALL MPI_COMM_SIZE(hmat%blacsdata%mpi_com,np,err)
      53         884 :        CALL MPI_COMM_RANK(hmat%blacsdata%mpi_com,myid,err)
      54         884 :        err = elpa_init(20180525)
      55         884 :        elpa_obj => elpa_allocate()
      56             :        
      57         884 :        ALLOCATE ( eig2(hmat%global_size1), stat=err ) ! The eigenvalue array
      58         884 :        IF (err.NE.0) CALL juDFT_error('Failed to allocated "eig2"', calledby ='elpa')
      59             : 
      60         884 :        CALL ev_dist%init(hmat)! Eigenvectors
      61         884 :        IF (err.NE.0) CALL juDFT_error('Failed to allocated "ev_dist"',calledby ='elpa')
      62             :        
      63             :        ! Blocking factor
      64         884 :        IF (hmat%blacsdata%blacs_desc(5).NE.hmat%blacsdata%blacs_desc(6)) CALL judft_error("Different block sizes for rows/columns not supported")
      65         884 :        CALL elpa_obj%set("na", hmat%global_size1, err)
      66         884 :        CALL elpa_obj%set("nev", ne, err)
      67         884 :        CALL elpa_obj%set("local_nrows", hmat%matsize1, err)
      68         884 :        CALL elpa_obj%set("local_ncols", hmat%matsize2, err)
      69         884 :        CALL elpa_obj%set("nblk",hmat%blacsdata%blacs_desc(5), err)
      70         884 :        CALL elpa_obj%set("mpi_comm_parent", hmat%blacsdata%mpi_com, err)
      71         884 :        CALL elpa_obj%set("process_row", hmat%blacsdata%myrow, err)
      72         884 :        CALL elpa_obj%set("process_col", hmat%blacsdata%mycol, err)
      73         884 :        CALL elpa_obj%set("blacs_context", hmat%blacsdata%blacs_desc(2), err)
      74         884 :        CALL elpa_obj%set("solver", ELPA_SOLVER_2STAGE)
      75         884 :        err = elpa_obj%setup()
      76             : 
      77         884 :        CALL hmat%generate_full_matrix()
      78         884 :        CALL smat%generate_full_matrix()
      79             :        
      80         884 :        IF (hmat%l_real) THEN
      81         210 :           CALL elpa_obj%generalized_eigenvectors(hmat%data_r,smat%data_r,eig2, ev_dist%data_r, .FALSE.,err)
      82             :        ELSE
      83         674 :           CALL elpa_obj%generalized_eigenvectors(hmat%data_c,smat%data_c,eig2, ev_dist%data_c, .FALSE., err)
      84             :        ENDIF
      85             :        
      86         884 :        CALL elpa_deallocate(elpa_obj)
      87         884 :        CALL elpa_uninit()
      88             :        ! END of ELPA stuff
      89             :        !
      90             :        !     Each process has all eigenvalues in output
      91         884 :        eig(:ne) = eig2(:ne)    
      92         884 :        DEALLOCATE(eig2)
      93             :        !
      94             :        !
      95             :        !     Redistribute eigenvectors  from ScaLAPACK distribution to each process, i.e. for
      96             :        !     process i these are eigenvectors i+1, np+i+1, 2*np+i+1...
      97             :        !     Only num=num2/np eigenvectors per process
      98             :        !
      99         884 :        num=ne
     100         884 :        ne=0
     101       20958 :        DO i=myid+1,num,np
     102         884 :           ne=ne+1
     103             :        ENDDO
     104             :        !
     105             :        !
     106         884 :        ALLOCATE(t_mpimat::ev)
     107         884 :        CALL ev%init(hmat%l_real,hmat%global_size1,hmat%global_size1,hmat%blacsdata%mpi_com,.FALSE.)
     108        1768 :        CALL ev%copy(ev_dist,1,1)
     109             :     CLASS DEFAULT
     110           0 :        CALL judft_error("Wrong type (1) in scalapack")
     111             :     END SELECT
     112             :  CLASS DEFAULT
     113           0 :     CALL judft_error("Wrong type (2) in scalapack")
     114             :  END SELECT
     115             :  
     116         884 : END SUBROUTINE elpa_diag
     117        2652 : END MODULE m_elpa

Generated by: LCOV version 1.13