!-*- mode: F90; mode: font-lock; column-number-mode: true -*-! ! ! ! This file is distributed under the terms of the GNU ! ! General Public License. See the file `LICENSE' in ! ! the root directory of the present distribution, or ! ! http://www.gnu.org/copyleft/gpl.txt . ! ! ! !------------------------------------------------------------! ! Code to enable use of the POV-Ray ray-tracing software for ! ! the rendering of Wannier function isosurfaces from .xsf ! ! files generated by Wannier90. ! !------------------------------------------------------------! ! ! ! File parser from the Wannier90 package ! ! Copyright (C) 2007 Jonathan Yates, Arash Mostofi, ! ! Young-Su Lee, Nicola Marzari, Ivo Souza, David Vanderbilt ! ! ! !------------------------------------------------------------! module m_io use general implicit none ! Private data integer :: num_lines integer, parameter :: maxlen = 120 character(len=maxlen), allocatable :: in_data(:) logical :: ltmp public contains !=======================================! subroutine param_in_file !=======================================! ! Load the *.win file into a character ! ! array in_file, ignoring comments and ! ! blank lines and converting everything ! ! to lowercase characters ! !=======================================! !use w90_utility, only : utility_lowercase implicit none integer :: in_unit, tot_num_lines,ierr,line_counter,loop,in1,in2 character(len=maxlen) :: dummy in_unit=90 open (in_unit, file='w90pov.inp',form='formatted',status='old',err=101) num_lines=0;tot_num_lines=0 do read(in_unit, '(a)', iostat = ierr, err= 101, end =210 ) dummy dummy=adjustl(dummy) tot_num_lines=tot_num_lines+1 if( .not.dummy(1:1)=='!' .and. .not. dummy(1:1)=='#' ) then if(len(trim(dummy)) > 0 ) num_lines=num_lines+1 endif end do 101 print *,'error: can not read input file file w90pov.inp' stop 210 continue rewind(in_unit) allocate(in_data(num_lines),stat=ierr) if (ierr/=0) then print *,'Error allocating in_data in param_in_file' stop end if line_counter=0 do loop=1,tot_num_lines read(in_unit, '(a)', iostat = ierr, err= 101 ) dummy dummy=utility_lowercase(dummy) dummy=adjustl(dummy) if( dummy(1:1)=='!' .or. dummy(1:1)=='#' ) cycle if(len(trim(dummy)) == 0 ) cycle line_counter=line_counter+1 in1=index(dummy,'!') in2=index(dummy,'#') if(in1==0 .and. in2==0) in_data(line_counter)=dummy if(in1==0 .and. in2>0 ) in_data(line_counter)=dummy(:in2-1) if(in2==0 .and. in1>0 ) in_data(line_counter)=dummy(:in1-1) if(in2>0 .and. in1>0 ) in_data(line_counter)=dummy(:min(in1,in2)-1) end do close(in_unit) end subroutine param_in_file !===========================================================================! subroutine param_get_keyword(keyword,found,c_value,l_value,i_value,r_value) !===========================================================================! ! ! ! Finds the value of the required keyword. ! ! ! !===========================================================================! ! use w90_io, only : io_error implicit none character(*), intent(in) :: keyword logical , intent(out) :: found character(*) ,optional, intent(inout) :: c_value logical ,optional, intent(inout) :: l_value integer ,optional, intent(inout) :: i_value real(kind=q) ,optional, intent(inout) :: r_value integer :: kl, in,loop,itmp character(len=maxlen) :: dummy kl=len_trim(keyword) found=.false. do loop=1,num_lines in=index(in_data(loop),trim(keyword)) if (in==0 .or. in>1 ) cycle itmp=in+len(trim(keyword)) if (in_data(loop)(itmp:itmp)/='=' & .and. in_data(loop)(itmp:itmp)/=':' & .and. in_data(loop)(itmp:itmp)/=' ') cycle if (found) then print *, 'Error: Found keyword ',trim(keyword),' more than once in input file' stop endif found=.true. dummy=in_data(loop)(kl+1:) in_data(loop)(1:maxlen) = ' ' dummy=adjustl(dummy) if( dummy(1:1)=='=' .or. dummy(1:1)==':') then dummy=dummy(2:) dummy=adjustl(dummy) end if end do if(found) then if( present(c_value) ) c_value=dummy if( present(l_value) ) then if (index(dummy,'t') > 0) then l_value=.true. elseif (index(dummy,'f') > 0) then l_value=.false. else print *,'Error: Problem reading logical keyword ',trim(keyword) stop endif endif if( present(i_value) ) read(dummy,*,err=220,end=220) i_value if( present(r_value) ) read(dummy,*,err=220,end=220) r_value end if return 220 print *,'Error: Problem reading keyword ',trim(keyword) stop end subroutine param_get_keyword !=========================================================================================! subroutine param_get_keyword_vector(keyword,found,length,c_value,l_value,i_value,r_value) !=========================================================================================! ! ! ! Finds the values of the required keyword vector ! ! ! !=========================================================================================! ! use w90_io, only : io_error implicit none character(*), intent(in) :: keyword logical , intent(out) :: found integer, intent(in) :: length character(*) ,optional, intent(inout) :: c_value(length) logical ,optional, intent(inout) :: l_value(length) integer ,optional, intent(inout) :: i_value(length) real(kind=q) ,optional, intent(inout) :: r_value(length) integer :: kl, in,loop,i character(len=maxlen) :: dummy kl=len_trim(keyword) found=.false. do loop=1,num_lines in=index(in_data(loop),trim(keyword)) if (in==0 .or. in>1 ) cycle if (found) then print *, 'Error: Found keyword ',trim(keyword),' more than once in input file' stop endif found=.true. dummy=in_data(loop)(kl+1:) in_data(loop)(1:maxlen) = ' ' dummy=adjustl(dummy) if( dummy(1:1)=='=' .or. dummy(1:1)==':') then dummy=dummy(2:) dummy=adjustl(dummy) end if end do if(found) then if( present(c_value) ) read(dummy,*,err=230,end=230) (c_value(i),i=1,length) if( present(l_value) ) then ! I don't think we need this. Maybe read into a dummy charater ! array and convert each element to logical endif if( present(i_value) ) read(dummy,*,err=230,end=230) (i_value(i),i=1,length) if( present(r_value) ) read(dummy,*,err=230,end=230) (r_value(i),i=1,length) end if return 230 print *,'Error: Problem reading keyword ',trim(keyword),' in param_get_keyword_vector' stop end subroutine param_get_keyword_vector !=================================! function utility_lowercase(string)! !=================================! ! ! ! Takes a string and converts to ! ! lowercase characters ! ! ! !=================================! implicit none character(len=*), intent(in) :: string character(len=maxlen) :: utility_lowercase integer :: iA,iZ,idiff,ipos,ilett iA = ichar('A') iZ = ichar('Z') idiff = iZ-ichar('z') utility_lowercase = string do ipos=1,len(string) ilett = ichar(string(ipos:ipos)) if ((ilett.ge.iA).and.(ilett.le.iZ)) & utility_lowercase(ipos:ipos)=char(ilett-idiff) enddo utility_lowercase = trim(adjustl(utility_lowercase)) return end function utility_lowercase end module m_io