ALF  dev.
A QMC Code for fermionic models
log_mesh_mod.F90
1 
2  Module log_mesh
3  use iso_fortran_env, only: output_unit, error_unit
4  use runtime_error_mod
5  use files_mod
6 
7  Type logmesh
8  Real (Kind=Kind(0.d0)) :: lambda, center, log_lambda
9  Real (Kind=Kind(0.d0)) :: range
10  Real (Kind=Kind(0.d0)) :: om_st, om_en, dom
11  Real (Kind=Kind(0.d0)) :: precision
12  Integer :: nom,nw
13  Real (Kind=Kind(0.d0)), pointer :: xom(:),dxom(:)
14  Character(len=10) :: type
15  end Type logmesh
16 
17  Interface lookup_log_mesh
18  module procedure lookup_log_mesh_r, lookup_log_mesh_c
19  end Interface
20  Interface inter_log_mesh
21  module procedure inter_log_mesh_r, inter_log_mesh_c
22  end Interface
23 
24  Contains
25 
26 
27 
28  subroutine make_log_mesh ( Mesh, Lambda, Center, Rng, Type, Nw_1 )
29 
30  Implicit None
31 
32  type(logmesh) :: mesh
33  Real (Kind=Kind(0.d0)) :: lambda, center, rng
34  Integer, Optional :: nw_1
35  Integer :: n, nw
36  Character(len=10) :: type
37 
38  Real (Kind=Kind(0.d0)) :: dom, om_st, om_en
39 
40  mesh%Center = center
41  mesh%Range = rng
42  If (str_to_upper(type) == "LOG" ) Then
43  om_st = center - rng
44  om_en = center + rng
45  mesh%Om_st = om_st
46  mesh%Om_en = om_en
47  mesh%Lambda = lambda
48  mesh%Type = "Log"
49  if (Present(nw_1) ) then
50  nw = nw_1
51  else
52  nw = nint(10.d0*log(10.d0)/log(lambda))
53  endif
54  mesh%Nw = nw
55  mesh%Nom = 2*nw + 3
56  mesh%Log_Lambda = log(lambda)
57  Allocate ( mesh%Xom(2*nw + 3), mesh%DXom(2*nw+3) )
58  Do n = 0,nw
59  mesh%xom (n+1 ) = center - rng * (lambda**(-n))
60  enddo
61  mesh%xom (nw+2 ) = center
62  do n = nw,0,-1
63  mesh%xom(nw+3 +(nw-n) ) = center + rng * (lambda**(-n))
64  enddo
65  mesh%Precision = mesh%Lambda**(-mesh%Nw)
66  elseif (str_to_upper(type) == "LIN" ) then
67  mesh%Type = "Lin"
68  If ( Present(nw_1) ) then
69  nw = nw_1
70  mesh%Nw = nw
71  mesh%Nom = 2*nw + 1
72  mesh%Type = "Lin"
73  Allocate ( mesh%Xom(2*nw + 1), mesh%DXom(2*nw+1) )
74  om_st = center - rng
75  om_en = center + rng
76  dom = rng/dble(nw_1)
77  mesh%Dom = dom
78  mesh%Om_st = om_st
79  mesh%Om_en = om_en
80  do n = 1,mesh%Nom
81  mesh%xom(n) = om_st + dble(n-1)*dom
82  enddo
83  else
84  Write(error_unit,*) 'Make_log_mesh: You need to include Nw for the Lin Mesh'
85  Call terminate_on_error(error_generic,__file__,__line__)
86  endif
87  else
88  Write(error_unit,*) 'Make_log_mesh: Mesh has no type!!'
89  Call terminate_on_error(error_generic,__file__,__line__)
90  endif
91  do n = 1,mesh%Nom-1
92  mesh%DXom(n) = mesh%xom (n+1) - mesh%xom (n )
93  enddo
94 
95  end subroutine make_log_mesh
96 
97  subroutine clear_log_mesh ( Mesh )
98  Implicit None
99 
100  type(logmesh) :: mesh
101 
102  deallocate ( mesh%Xom, mesh%DXom )
103 
104  end subroutine clear_log_mesh
105 
106  Integer Function m_find(X,Mesh)
107 
108  Implicit None
109 
110  type(logmesh) :: mesh
111  Real (Kind=Kind(0.d0)) :: x
112  Integer :: m
113 
114  if ( str_to_upper(mesh%Type) == "LOG" ) then
115  if ( x > (mesh%OM_en) .or. x < (mesh%Om_st) ) then
116  m = 0
117  else
118  if ( x < mesh%Xom(mesh%Nw+1) ) then
119  m = 2 - int( log( (mesh%Center - x)/mesh%Range ) / mesh%Log_Lambda )
120  !Write(6,*) 'Hi 1', X
121  elseif ( x > mesh%Xom(mesh%Nw+3) ) then
122  m = 2*mesh%Nw + 3 + int( log( (x- mesh%Center) /mesh%Range ) / mesh%Log_Lambda )
123  !Write(6,*) 'Hi 2', X, Mesh%Center + Mesh%Range
124  elseif ( x > mesh%Center ) then
125  m = mesh%Nw+3
126  else
127  m = mesh%Nw+2
128  endif
129  endif
130  m_find = m
131  else
132  m_find = int((x - mesh%Om_st)/mesh%dom) + 2
133  if (m_find > mesh%Nom) m_find=mesh%Nom
134  if (m_find < 2 ) m_find=2
135  endif
136 
137 
138  !Write(6,*)
139  !Write(6,*) 'Point: ', X
140  !if ( m > 0 ) then
141  ! Write(6,*) 'Your point lies inbetween ', Mesh%Xom(m-1), ' and ', Mesh%Xom(m)
142  !else
143  ! Write(6,*) 'Out of range '
144  !endif
145 
146  end Function m_find
147 !*******
148  Real(Kind=Kind(0.d0)) Function lookup_log_mesh_r(f, x,Mesh,m_1)
149 
150  Implicit None
151 
152  type(logmesh) :: mesh
153  Real (Kind=Kind(0.d0)), dimension(:) :: f
154  Real (Kind=Kind(0.d0)) :: x
155  Integer , Optional :: m_1
156 
157  Integer :: m
158  Real (Kind=Kind(0.d0)) :: x1,x2,y1,y2,a,b
159 
160  m = m_find(x,mesh)
161  if (m == 0 ) then
162  lookup_log_mesh_r = 0.d0
163  else
164  x1 = mesh%xom(m-1)
165  x2 = mesh%xom(m )
166  y1 = f(m-1)
167  y2 = f(m)
168  a = (y1-y2)/(x1-x2)
169  b = (x1*y2 - x2*y1)/(x1-x2)
170  lookup_log_mesh_r = a*x + b
171  endif
172 
173  If ( Present(m_1) ) m_1 = m
174 
175  end Function lookup_log_mesh_r
176 
177 
178 
179 !*******
180 !!$ Complex (Kind=Kind(0.d0)) Function Lookup_log_mesh_C(f, x,Mesh,m_1)
181 !!$
182 !!$ Implicit None
183 !!$
184 !!$ Type (logmesh) :: Mesh
185 !!$ Complex (Kind=Kind(0.d0)), dimension(:) :: f
186 !!$ Real (Kind=Kind(0.d0)) :: X
187 !!$ Integer , Optional :: m_1
188 !!$
189 !!$
190 !!$ Integer :: n, m
191 !!$ Complex (Kind=Kind(0.d0)) :: X1,X2,Y1,Y2,a,b
192 !!$
193 !!$ m = m_find(X,Mesh)
194 !!$ if (m == 0 ) then
195 !!$ Lookup_log_mesh_C = cmplx(0.d0,0.d0)
196 !!$ else
197 !!$ x1 = cmplx( Mesh%xom(m-1),0.d0 )
198 !!$ x2 = cmplx( Mesh%xom(m ),0.d0 )
199 !!$ y1 = f(m-1)
200 !!$ y2 = f(m )
201 !!$ a = (y1-y2)/(x1-x2)
202 !!$ b = (x1*y2 - x2*y1)/(x1-x2)
203 !!$ Lookup_log_mesh_C = a*cmplx( x , 0.d0 ) + b
204 !!$ endif
205 !!$
206 !!$ If ( Present(m_1) ) m_1 = m
207 !!$
208 !!$ end Function Lookup_log_mesh_C
209 
210  Complex (Kind=Kind(0.d0)) Function lookup_log_mesh_c(f, x,Mesh,m_1)
211 
212  Implicit None
213 
214  type(logmesh) :: mesh
215  Complex (Kind=Kind(0.d0)), dimension(:) :: f
216  Real (Kind=Kind(0.d0)) :: x
217  Integer , Optional :: m_1
218 
219 
220  Integer :: m
221  Complex (Kind=Kind(0.d0)) :: z1,z2, z
222  Real (Kind=Kind(0.d0)) :: x1,x2,t
223 
224  m = m_find(x,mesh)
225  if (m == 0 ) then
226  lookup_log_mesh_c = cmplx(0.d0, 0.d0, kind(0.d0))
227  else
228  x1 = mesh%xom(m-1)
229  x2 = mesh%xom(m )
230  t = (x1 - x)/(x2-x1)
231  z1 = f(m-1)
232  z2 = f(m )
233  z = z1 + (z1-z2)*t
234  lookup_log_mesh_c = z
235  endif
236 
237  If ( Present(m_1) ) m_1 = m
238 
239  end Function lookup_log_mesh_c
240 
241 
242 !******
243  Real (Kind=Kind(0.d0)) Function inter_log_mesh_r(f,Mesh)
244 
245  Implicit None
246 
247  type(logmesh) :: mesh
248  Real (Kind=Kind(0.d0)), dimension(:) :: f
249  Real (Kind=Kind(0.d0)) :: x
250  Integer :: n
251 
252  x = 0.d0
253  do n = 1,mesh%Nom-1
254  x = x + mesh%DXom(n) * (f(n+1) + f(n) )
255  enddo
256  inter_log_mesh_r = x / 2.d0
257 
258  end Function inter_log_mesh_r
259 
260 !******
261  Complex (Kind=Kind(0.d0)) Function inter_log_mesh_c(f,Mesh)
262 
263  Implicit None
264 
265  type(logmesh) :: mesh
266  Complex (Kind=Kind(0.d0)), dimension(:) :: f
267  Complex (Kind=Kind(0.d0)) :: z
268  Integer :: n
269 
270  z = cmplx(0.d0, 0.d0, kind(0.d0))
271  do n = 1,mesh%Nom-1
272  z = z + mesh%DXom(n) * ( f(n+1) + f(n) )
273  enddo
274  inter_log_mesh_c = z /2.d0
275 
276  end Function inter_log_mesh_c
277 
278 
279 
280  subroutine print_log_mesh(Mesh)
281 
282  Implicit None
283 
284  type(logmesh) :: mesh
285 
286  Integer :: n
287 
288  If (str_to_upper(mesh%Type) == "LOG" ) Then
289  Open (unit=10,file="Log_Mesh", status="unknown" )
290  Write(10,*) '# Log Mesh : '
291  Write(10,*) '# Lambda : ', mesh%Lambda
292  Write(10,*) '# Range : ', mesh%Range
293  Write(10,*) '# Center : ', mesh%Center
294  Write(10,*) '# Nom : ', mesh%Nom
295  Write(10,*) '# Precision : ', mesh%Lambda**(-mesh%Nw)
296  do n = 1,mesh%Nom
297  write(10,"(F16.8)") mesh%xom(n)
298  enddo
299  close(10)
300  endif
301 
302  If (str_to_upper(mesh%Type) == "LIN" ) Then
303  Open (unit=10,file="Lin_Mesh", status="unknown" )
304  Write(10,*) '# Lin Mesh : '
305  Write(10,*) '# Range : ', mesh%Range
306  Write(10,*) '# Center : ', mesh%Center
307  Write(10,*) '# Nom : ', mesh%Nom
308  Write(10,*) '# Dom : ', mesh%dom
309  do n = 1,mesh%Nom
310  write(10,"(F16.8)") mesh%xom(n)
311  enddo
312  close(10)
313  endif
314 
315 
316 
317  end subroutine print_log_mesh
318 
319 
320  end Module log_mesh