Octopus
qshep.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
21module qshep_oct_m
22 use debug_oct_m
23 use global_oct_m
26
27 implicit none
28
29 private
30 public :: &
31 qshep_t, &
32 qshep_init, &
35
36 type qshepr_t
37 private
38 integer(int64) :: npoints, nq, nw, nr, dim
39 integer(int64), allocatable :: lcell(:, :, :), lnext(:)
40 real(real64), allocatable :: rsq(:), a(:, :)
41 real(real64) :: xmin, ymin, dx, dy, rmax, xyzmin(3), xyzdel(3)
42
43 real(real64), allocatable :: x(:), y(:), z(:)
44 end type qshepr_t
45
46 type qshep_t
47 private
48 integer(int64) :: kind
49 type(qshepr_t) :: re, im
50 end type qshep_t
51
52 interface qshep_init
53 module procedure dqshep_init, zqshep_init
54 end interface
55
56 interface qshep_interpolate
58 end interface qshep_interpolate
59
60 interface
61 real(real64) function qs2val(px, py, n, x, y, f, nr, lcell, lnext, xmin, &
62 ymin, dx, dy, rmax, rsq, a)
63 use, intrinsic :: iso_fortran_env
64 implicit none
65 real(real64) :: px
66 real(real64) :: py
67 integer(int64) :: n
68 real(real64) :: x(n)
69 real(real64) :: y(n)
70 real(real64) :: f(n)
71 integer(int64) :: nr
72 integer(int64) :: lcell(nr, nr)
73 integer(int64) :: lnext(n)
74 real(real64) :: xmin
75 real(real64) :: ymin
76 real(real64) :: dx
77 real(real64) :: dy
78 real(real64) :: rmax
79 real(real64) :: rsq(n)
80 real(real64) :: a(5, n)
81 end function qs2val
82
83 subroutine qs2grd(px, py, n, x, y, f, nr, lcell, lnext, xmin, &
84 ymin, dx, dy, rmax, rsq, a, q, qx, qy, ier)
85 use, intrinsic :: iso_fortran_env
86 implicit none
87 real(real64) :: px
88 real(real64) :: py
89 integer(int64) :: n
90 real(real64) :: x(n)
91 real(real64) :: y(n)
92 real(real64) :: f(n)
93 integer(int64) :: nr
94 integer(int64) :: lcell(nr, nr)
95 integer(int64) :: lnext(n)
96 real(real64) :: xmin
97 real(real64) :: ymin
98 real(real64) :: dx
99 real(real64) :: dy
100 real(real64) :: rmax
101 real(real64) :: rsq(n)
102 real(real64) :: a(5, n)
103 real(real64) :: q
104 real(real64) :: qx
105 real(real64) :: qy
106 integer(int64) :: ier
107 end subroutine qs2grd
108
109 real(real64) function qs3val(px, py, pz, n, x, y, z, f, nr, lcell, lnext, xyzmin, &
110 xyzdel, rmax, rsq, a)
111 use, intrinsic :: iso_fortran_env
112 implicit none
113 real(real64) :: px
114 real(real64) :: py
115 real(real64) :: pz
116 integer(int64) :: n
117 real(real64) :: x(n)
118 real(real64) :: y(n)
119 real(real64) :: z(n)
120 real(real64) :: f(n)
121 integer(int64) :: nr
122 integer(int64) :: lcell(nr, nr, nr)
123 integer(int64) :: lnext(n)
124 real(real64) :: xyzmin(3)
125 real(real64) :: xyzdel(3)
126 real(real64) :: rmax
127 real(real64) :: rsq(n)
128 real(real64) :: a(9, n)
129 end function qs3val
130
131 subroutine qs3grd(px, py, pz, n, x, y, z, f, nr, lcell, lnext, xyzmin, &
132 xyzdel, rmax, rsq, a, q, qx, qy, qz, ier)
133 use, intrinsic :: iso_fortran_env
134 implicit none
135 real(real64) :: px
136 real(real64) :: py
137 real(real64) :: pz
138 integer(int64) :: n
139 real(real64) :: x(n)
140 real(real64) :: y(n)
141 real(real64) :: z(n)
142 real(real64) :: f(n)
143 integer(int64) :: nr
144 integer(int64) :: lcell(nr, nr, nr)
145 integer(int64) :: lnext(n)
146 real(real64) :: xyzmin(3)
147 real(real64) :: xyzdel(3)
148 real(real64) :: rmax
149 real(real64) :: rsq(n)
150 real(real64) :: a(9, n)
151 real(real64) :: q
152 real(real64) :: qx
153 real(real64) :: qy
154 real(real64) :: qz
155 integer(int64) :: ier
156 end subroutine qs3grd
157 end interface
158
159contains
160
161 ! ------------------------------------------------------------------------------
162 subroutine dqshep_init(interp, npoints, f, x, y, z)
163 type(qshep_t), intent(out) :: interp
164 integer(int64), intent(in) :: npoints
165 real(real64), intent(in) :: f(:)
166 real(real64) :: x(:), y(:)
167 real(real64), optional :: z(:)
168
169 push_sub(dqshep_init)
170
171 interp%kind = 0
172 call qshepr_init(interp%re, npoints, f, x, y, z = z)
173
174 pop_sub(dqshep_init)
175 end subroutine dqshep_init
177
178 ! ------------------------------------------------------------------------------
179 subroutine zqshep_init(interp, npoints, f, x, y, z)
180 type(qshep_t), intent(out) :: interp
181 integer(int64), intent(in) :: npoints
182 complex(real64), intent(in) :: f(:)
183 real(real64) :: x(:), y(:)
184 real(real64), optional :: z(:)
185
186 push_sub(zqshep_init)
187
188 interp%kind = 1
189 call qshepr_init(interp%re, npoints, real(f), x, y, z = z)
190 call qshepr_init(interp%im, npoints, aimag(f), x, y, z = z)
191
192 pop_sub(zqshep_init)
193 end subroutine zqshep_init
194
195
196 ! ------------------------------------------------------------------------------
197 subroutine qshepr_init(interp, npoints, f, x, y, z)
198 type(qshepr_t), intent(out) :: interp
199 integer(int64), intent(in) :: npoints
200 real(real64), intent(in) :: f(:)
201 real(real64), target :: x(:), y(:)
202 real(real64), target, optional :: z(:)
203
204 integer(int64) :: ier
205
206 push_sub(qshepr_init)
207
208 interp%npoints = npoints
209
210 if (present(z)) then
211 interp%dim = 3
212 else
213 interp%dim = 2
214 end if
215
216 select case (interp%dim)
217 case (2)
218 interp%nq = 13
219 interp%nw = 19
220 interp%nr = nint(sqrt(interp%npoints/3.0_8))
221 safe_allocate(interp%lcell(1:interp%nr, 1:interp%nr, 1))
222 safe_allocate(interp%a(1:5, 1:npoints))
223 case (3)
224 interp%nq = 17 ! This is the recommended value in qshep3d.f90
225 interp%nw = 16 ! The recommended value in qshep3d.f90 is 32, but this speeds up things.
226 interp%nr = nint((interp%npoints/3.0_8)**(1.0_8/3.0_8))
227 safe_allocate(interp%lcell(1:interp%nr, 1:interp%nr, 1:interp%nr))
228 safe_allocate(interp%a(1:9, 1:interp%npoints))
229 end select
230
231 safe_allocate(interp%lnext(1:npoints))
232 safe_allocate(interp%rsq(1:npoints))
233
234 select case (interp%dim)
235 case (2)
236 call qshep2(npoints, x, y, f, interp%nq, interp%nw, interp%nr, interp%lcell(:, :, 1), &
237 interp%lnext, interp%xmin, interp%ymin, interp%dx, interp%dy, &
238 interp%rmax, interp%rsq, interp%a, ier)
239 safe_allocate(interp%x(1:npoints))
240 safe_allocate(interp%y(1:npoints))
241 interp%x(1:npoints) = x(1:npoints)
242 interp%y(1:npoints) = y(1:npoints)
243 case (3)
244 call qshep3(npoints, x, y, z, f, interp%nq, interp%nw, interp%nr, interp%lcell, &
245 interp%lnext, interp%xyzmin, interp%xyzdel, interp%rmax, interp%rsq, &
246 interp%a, ier)
247 safe_allocate(interp%x(1:npoints))
248 safe_allocate(interp%y(1:npoints))
249 safe_allocate(interp%z(1:npoints))
250 interp%x(1:npoints) = x(1:npoints)
251 interp%y(1:npoints) = y(1:npoints)
252 interp%z(1:npoints) = z(1:npoints)
253 end select
254
255 pop_sub(qshepr_init)
256 end subroutine qshepr_init
257
258
259 ! ------------------------------------------------------------------------------
260 real(real64) function qshep_interpolater(interp, f, p, gf) result(v)
261 type(qshepr_t), intent(in) :: interp
262 real(real64), intent(in) :: f(:)
263 real(real64), intent(in) :: p(:)
264 real(real64), optional, intent(inout) :: gf(:)
265
266 integer(int64) :: ier
267
268 push_sub(qshep_interpolater)
269
270 select case (interp%dim)
271 case (2)
272 if (present(gf)) then
273 call qs2grd( p(1), p(2), interp%npoints, interp%x, interp%y, &
274 f, interp%nr, interp%lcell(:, :, 1), interp%lnext, interp%xmin, &
275 interp%ymin, interp%dx, interp%dy, interp%rmax, interp%rsq, interp%a, &
276 v, gf(1), gf(2), ier)
277 else
278 v = qs2val( p(1), p(2), interp%npoints, interp%x, interp%y, &
279 f, interp%nr, interp%lcell(:, :, 1), interp%lnext, interp%xmin, &
280 interp%ymin, interp%dx, interp%dy, interp%rmax, interp%rsq, interp%a)
281 end if
282 case (3)
283 if (present(gf)) then
284 call qs3grd( p(1), p(2), p(3), interp%npoints, interp%x, interp%y, interp%z, &
285 f, interp%nr, interp%lcell, interp%lnext, interp%xyzmin, &
286 interp%xyzdel, interp%rmax, interp%rsq, interp%a , &
287 v, gf(1), gf(2), gf(3), ier)
288 else
289 v = qs3val(p(1), p(2), p(3), interp%npoints, interp%x, interp%y, interp%z, &
290 f, interp%nr, interp%lcell, interp%lnext, interp%xyzmin, &
291 interp%xyzdel, interp%rmax, interp%rsq, interp%a)
292 end if
293 end select
294
295 pop_sub(qshep_interpolater)
296 end function qshep_interpolater
297
298
299 ! ------------------------------------------------------------------------------
300 real(real64) function dqshep_interpolate(interp, f, p, gf) result(v)
301 type(qshep_t), intent(in) :: interp
302 real(real64), intent(in) :: f(:)
303 real(real64), intent(in) :: p(:)
304 real(real64), optional, intent(inout) :: gf(:)
305
306 push_sub(dqshep_interpolate)
307
308 v = qshep_interpolater(interp%re, f, p, gf = gf)
309
310 pop_sub(dqshep_interpolate)
311 end function dqshep_interpolate
312
313
314 ! ------------------------------------------------------------------------------
315 complex(real64) function zqshep_interpolate(interp, f, p, gf) result(v)
316 type(qshep_t), intent(in) :: interp
317 complex(real64), intent(in) :: f(:)
318 real(real64), intent(in) :: p(:)
319 complex(real64), optional, intent(inout) :: gf(:)
320
321 integer(int64) :: i
322 real(real64), allocatable :: rgf(:), igf(:)
323
324 push_sub(zqshep_interpolate)
325
326 if (present(gf)) then
327 safe_allocate(rgf(1:size(gf)))
328 safe_allocate(igf(1:size(gf)))
329 v = cmplx(qshep_interpolater(interp%re, real(f), p, rgf), &
330 qshep_interpolater(interp%im, aimag(f), p, igf), 8)
331 do i = 1, size(gf)
332 gf(i) = cmplx( rgf(i), igf(i), 8)
333 end do
334 safe_deallocate_a(rgf)
335 safe_deallocate_a(igf)
336 else
337 v = cmplx(qshep_interpolater(interp%re, real(f), p), &
338 qshep_interpolater(interp%im, aimag(f), p), 8)
339 end if
340
341 pop_sub(zqshep_interpolate)
342 end function zqshep_interpolate
343
344
345 ! ------------------------------------------------------------------------------
346 subroutine qshep_end(interp)
347 type(qshep_t), intent(inout) :: interp
348
349 push_sub(qshep_end)
350
351 call qshepr_end(interp%re)
352 if (interp%kind == 1) call qshepr_end(interp%im)
354 pop_sub(qshep_end)
355 end subroutine qshep_end
356
357
358 ! ------------------------------------------------------------------------------
359 subroutine qshepr_end(interp)
360 type(qshepr_t), intent(inout) :: interp
361
362 push_sub(qshepr_end)
363
364 safe_deallocate_a(interp%lcell)
365 safe_deallocate_a(interp%lnext)
366 safe_deallocate_a(interp%rsq)
367 safe_deallocate_a(interp%a)
368 safe_deallocate_a(interp%x)
369 safe_deallocate_a(interp%y)
370 safe_deallocate_a(interp%z)
371
372 pop_sub(qshepr_end)
373 end subroutine qshepr_end
374
375end module qshep_oct_m
376
377!! Local Variables:
378!! mode: f90
379!! coding: utf-8
380!! End:
double sqrt(double __x) __attribute__((__nothrow__
subroutine dqshep_init(interp, npoints, f, x, y, z)
Definition: qshep.F90:256
complex(real64) function zqshep_interpolate(interp, f, p, gf)
Definition: qshep.F90:409
subroutine zqshep_init(interp, npoints, f, x, y, z)
Definition: qshep.F90:273
subroutine qshepr_init(interp, npoints, f, x, y, z)
Definition: qshep.F90:291
subroutine, public qshep_end(interp)
Definition: qshep.F90:440
real(real64) function dqshep_interpolate(interp, f, p, gf)
Definition: qshep.F90:394
real(real64) function qshep_interpolater(interp, f, p, gf)
Definition: qshep.F90:354
subroutine qshepr_end(interp)
Definition: qshep.F90:453