ponweist / Wannier90-PRACE

Optimizations for Wannier90 (fork repository - see http://wannier.org for the official version).
GNU General Public License v2.0
1 stars 0 forks source link

Cleanup logic for matrix initializations #14

Closed ponweist closed 9 years ago

ponweist commented 9 years ago

Problem

Currently, the logic for matrix initializations is complex and error-prone (see #13). Moreover, it introduces unwanted interdependencies between modules, e.g. in kslice.F90 we have

    if (plot_fermi_lines) then
       if(index(berry_task,'morb')>0) then
          call get_morb_R   !HH_R is included
       elseif((index(berry_task,'ahc')>0).OR.(index(berry_task,'kubo')>0)) then
          call get_ahc_R  !HH_R is included
       else
          call get_HH_R
       endif
    endif

However, the module kslice should not care about parameters belonging to the berry module.

Proposed solution

For each matrix object in _getoper.F90, add a corresponding logical flag, indicating if it will be needed for calculations, e.g.

  ! <0n|H|Rm>
  !
  complex(kind=dp), allocatable, save :: HH_R(:,:,:)
  logical, save                       :: need_HH_R = .false.

  ! <0n|r|Rm>
  !
  complex(kind=dp), allocatable, save :: AA_R(:,:,:,:)
  logical, save                       :: need_AA_R = .false.

  ! same for other matrix objects

In _getoper.F90, provide a routine for setting these flags to .true.:

  subroutine require(HH_R, AA_R, ...)
     logical, optional, intent(in) :: HH_R, AA_R, ...

     if(present(HH_R)) then
        if(HH_R) then
           need_HH_R = .true.
        end if
     end if
     ! same for AA_R, ...     
  end subroutine

Join all initialization code (get_ahc_R, get_morb_R, get_SS_R, ...) into a single routine:

subroutine initialize()
   ! read input files / common initializations

   if(need_HH_R) then
     ! code for initializing HH_R
   end if

   ! similarly for AA_R, ....
end subroutine

The code in the main program postw90.F90 would look like

  ! call require() for each matrix object needed by any of the individual calculation modules
  ! (kpath/kslice/berry)
  if(kpath) call k_path_require() 
  if(kslice) call k_slice_require()
  if(berry) call berry_require()

  call initialize()
  deallocate(v_matrix)

  if(kpath) call k_path 
  if(kslice) call k_slice
  if(berry) call berry_main
malwi commented 9 years ago

You are absolutely right. I am in the middle of it. It is a good idea.

About the report: it seems simple.

G.

2014-09-29 16:01 GMT+02:00 Thomas Ponweiser notifications@github.com:

Problem

Currently, the logic for matrix initializations is complex and error-prone (see #13 https://github.com/ponweist/Wannier90/issues/13). Moreover, it introduces unwanted interdependencies between modules, e.g. in kslice.F90 we have

if (plot_fermi_lines) then       if(index(berry_task,'morb')>0) then          call get_morb_R   !HH_R is included
   elseif((index(berry_task,'ahc')>0).OR.(index(berry_task,'kubo')>0)) then          call get_ahc_R  !HH_R is included
   else          call get_HH_R
   endif    endif

However, the module kslice should not care about parameters belonging to the berry module. Proposed solution

For each matrix object in _getoper.F90, add a corresponding logical flag, indicating if it will be needed for calculations, e.g.

! <0n|H|Rm> ! complex(kind=dp), allocatable, save :: HH_R(:,:,:) logical, save :: need_HH_R = .false.

! <0n|r|Rm> ! complex(kind=dp), allocatable, save :: AA_R(:,:,:,:) logical, save :: need_AA_R = .false.

! same for other matrix objects

In _getoper.F90, provide a routine for setting these flags to .true.:

subroutine require(HH_R, AA_R, ...) logical, optional, intent(in) :: HH_R, AA_R, ...

 if(present(HH_R)) then        if(HH_R) then           need_HH_R = .true.
    end if     end if
 ! same for AA_R, ...

end subroutine

Join all initialization code (get_ahc_R, get_morb_R, get_SS_R, ...) into a single routine:

subroutine initialize() ! read input files / common initializations

if(need_HH_R) then ! code for initializing HH_R end if

! similarly for AA_R, ....end subroutine

The code in the main program postw90.F90 would look like

! call require() for each matrix object needed by any of the individual calculation modules ! (kpath/kslice/berry) if(kpath) call k_path_require() if(kslice) call k_slice_require() if(berry) call berry_require()

call initialize() deallocate(v_matrix)

if(kpath) call k_path if(kslice) call k_slice if(berry) call berry_main

Reply to this email directly or view it on GitHub https://github.com/ponweist/Wannier90/issues/14.

ponweist commented 9 years ago

Fixed in 35e705238863b176c6f00f02190413c05da24779.