1! ---
2! Copyright (C) 1996-2016	The SIESTA group
3!  This file is distributed under the terms of the
4!  GNU General Public License: see COPYING in the top directory
5!  or http://www.gnu.org/copyleft/gpl.txt .
6! See Docs/Contributors.txt for a list of contributors.
7! ---
8module m_ts_cctype
9! Module for containing the complex contour (will also handle the "close"
10! to the real axis transport contour).
11! The type can easily be streamlined and is containing all relevant information
12! in the type.
13!
14! The important information available is:
15!   1. Complex contour point
16!   2. Weight of point (for transport contour this is 0.0)
17!   3. Which part of the contour
18!   4. The type of contour (i.e. which method is used to create it)
19!
20
21  use m_ts_io_ctype, only : ts_c_io, CC_METHOD_LEN => c_N
22  use precision, only : dp
23
24  use m_gauss_fermi_inf, only : G_NF_MIN_kT, G_NF_MAX_kT
25
26  implicit none
27
28  private :: dp
29  public
30
31  ! Create a type to contain the contour information
32  type :: ts_cw
33     type(ts_c_io), pointer   :: c_io => null()
34     integer,     allocatable :: ID(:)
35     complex(dp), allocatable :: c(:), w(:,:)
36  end type ts_cw
37
38  type :: ts_c_idx
39     sequence
40     logical     :: exist = .false.
41     logical     :: fake  = .false.
42     complex(dp) :: e ! the energy for the curve
43     ! contains:
44     ! (1) : whether this is eq,noneq
45     ! (2) : index of the io contour
46     ! (3) : index of the point in the io(2)'th contour-array
47     integer     :: idx(3)
48  end type ts_c_idx
49
50!  ! maximum length of the string that returns the type
51!  integer, parameter :: CC_METHOD_LEN = 17
52
53  ! The following Fermi Gauss-Quadratures MUST be in success
54  ! I.e. NF_<x>kT == 10+x
55  integer, parameter :: CC_G_NF_MIN         = 4000 ! means G_NF_MIN_kT kT
56  integer, parameter :: CC_G_NF_MAX         = G_NF_MAX_kT - G_NF_MIN_kT + CC_G_NF_MIN ! means G_NF_MAX_kT kT
57  integer, parameter :: CC_G_NF_0kT         = CC_G_NF_MIN - G_NF_MIN_kT ! means 0 kT
58  integer, parameter :: CC_G_LEGENDRE       = 100
59  integer, parameter :: CC_TANH_SINH        = 101
60  integer, parameter :: CC_SIMP_MIX         = 102
61  integer, parameter :: CC_BOOLE_MIX        = 103
62  integer, parameter :: CC_MID              = 104
63  integer, parameter :: CC_CONTINUED_FRAC   = 105
64  integer, parameter :: CC_USER             = 106
65
66
67  ! Converts a method to a string format
68  interface method2str
69     module procedure method2str_int
70     module procedure method2str_ts_c_io
71  end interface method2str
72  private :: method2str_int, method2str_ts_c_io
73
74  ! Converts a method to a string format
75  interface longmethod2str
76     module procedure longmethod2str_int
77     module procedure longmethod2str_ts_c_io
78  end interface longmethod2str
79  private :: longmethod2str_int, longmethod2str_ts_c_io
80
81  ! Converts a method to the equivalent string format that is required as input
82  interface method2input
83     module procedure method2input_int
84     module procedure method2input_ts_c_io
85  end interface method2input
86  private :: method2input_int, method2input_ts_c_io
87
88  ! converts a string to the integer method
89  interface method
90     module procedure method_str
91     module procedure method_ts_c_io
92  end interface method
93  private :: method_str, method_ts_c_io
94
95contains
96
97  function method2str_ts_c_io(c) result(str)
98    type(ts_c_io), intent(in) :: c
99    character(len=CC_METHOD_LEN) :: str
100    str = method2str(method(c))
101  end function method2str_ts_c_io
102
103  function method2str_int(method) result(str)
104    integer, intent(in) :: method
105    character(len=CC_METHOD_LEN) :: str
106    select case ( method )
107    case ( CC_G_NF_MIN:CC_G_NF_MAX )
108       write(str,'(a,i0)') 'Gauss-Fermi_',method-CC_G_NF_0kT
109    case ( CC_G_LEGENDRE )
110       str = 'Gauss-Legendre'
111    case ( CC_TANH_SINH )
112       str = 'Tanh-Sinh'
113    case ( CC_SIMP_MIX )
114       str = 'Simpson 3/8-3'
115    case ( CC_BOOLE_MIX )
116       str = 'Boole-Simpson 3/8'
117    case ( CC_MID )
118       str = 'Mid-rule'
119    case ( CC_CONTINUED_FRAC )
120       str = 'Continued-fraction'
121    case ( CC_USER )
122       str = 'User'
123    case default
124       call die('Unknown method for the contour')
125    end select
126  end function method2str_int
127
128  function method2input_int(method) result(str)
129    integer, intent(in) :: method
130    character(len=CC_METHOD_LEN) :: str
131    select case ( method )
132    case ( CC_G_NF_MIN:CC_G_NF_MAX )
133       str = 'gauss-fermi'
134    case ( CC_G_LEGENDRE )
135       str = 'gauss-Legendre'
136    case ( CC_TANH_SINH )
137       str = 'Tanh-Sinh'
138    case ( CC_SIMP_MIX )
139       str = 'Simpson-mix'
140    case ( CC_BOOLE_MIX )
141       str = 'Boole-mix'
142    case ( CC_MID )
143       str = 'Mid-rule'
144    case ( CC_CONTINUED_FRAC )
145       str = 'Continued-fraction'
146    case ( CC_USER )
147       str = 'User defined'
148    case default
149       call die('Unknown method for the contour')
150    end select
151  end function method2input_int
152
153  function method2input_ts_c_io(c) result(str)
154    type(ts_c_io), intent(in) :: c
155    character(len=CC_METHOD_LEN) :: str
156    str = method2input(method(c))
157  end function method2input_ts_c_io
158
159  function longmethod2str_ts_c_io(c) result(str)
160    type(ts_c_io), intent(in) :: c
161    character(len=CC_METHOD_LEN*2) :: str
162    str = longmethod2str(method(c))
163  end function longmethod2str_ts_c_io
164
165  function longmethod2str_int(method) result(str)
166    integer, intent(in) :: method
167    character(len=CC_METHOD_LEN*2) :: str
168    select case ( method )
169    case ( CC_G_NF_MIN:CC_G_NF_MAX )
170       write(str,'(a,'' ('',i0,''kT)'')') 'Gauss-Fermi',method-CC_G_NF_0kT
171    case ( CC_G_LEGENDRE )
172       str = 'Gauss-Legendre'
173    case ( CC_TANH_SINH )
174       str = 'Tanh-Sinh'
175    case ( CC_SIMP_MIX )
176       str = 'Simpson-mix'
177    case ( CC_BOOLE_MIX )
178       str = 'Boole-mix'
179    case ( CC_MID )
180       str = 'Mid-rule'
181    case ( CC_CONTINUED_FRAC )
182       str = 'Continued fraction'
183    case ( CC_USER )
184       str = 'User defined'
185    case default
186       call die('Unknown method for the contour')
187    end select
188  end function longmethod2str_int
189
190  function method_str(str) result(method)
191    use fdf, only : leqi
192    character(len=*), intent(in) :: str
193    integer :: method
194    character(len=20) :: tmp
195    integer :: i
196    if ( leqi(str,'g-legendre') .or. leqi(str, 'gauss-legendre') ) then
197       method = CC_G_LEGENDRE
198    else if ( leqi(str,'tanh-sinh') ) then
199       method = CC_TANH_SINH
200    else if ( leqi(str,'simpson-mix') .or. &
201         leqi(str,'simpson') ) then
202       method = CC_SIMP_MIX
203    else if ( leqi(str,'boole-mix') .or. &
204         leqi(str,'boole') ) then
205       method = CC_BOOLE_MIX
206    else if ( leqi(str,'mid-rule') .or. &
207         leqi(str,'mid') ) then
208       method = CC_MID
209    else if ( leqi(str,'ozaki') .or. &
210         leqi(str,'continued-fraction') .or. &
211         leqi(str,'cont-frac') ) then
212       method = CC_CONTINUED_FRAC
213    else if ( leqi(str,'file') .or. &
214         leqi(str,'user') ) then
215       method = CC_USER
216    else if ( leqi(str,'g-fermi') .or. leqi(str, 'gauss-fermi') ) then
217       method = CC_G_NF_0kT
218       do i = G_NF_MIN_kT , G_NF_MAX_kT
219          write(tmp,'(a,i0,a)') 'g-fermi(',i,')'
220          if ( leqi(str,tmp) ) then
221             method = CC_G_NF_0kT + i
222             return
223          end if
224       end do
225    else
226       call die('Unknown method for the contour: '//trim(str))
227    end if
228  end function method_str
229
230  function method_ts_c_io(c) result(ret)
231    type(ts_c_io), intent(in) :: c
232    integer :: ret
233    ret = method(c%method)
234  end function method_ts_c_io
235
236end module m_ts_cctype
237