Octopus
scaling_function.F90
Go to the documentation of this file.
1!! Copyright (C) 2011 X. Andrade
2!! Copyright (C) Luigi Genovese, Thierry Deutsch, CEA Grenoble, 2006
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include <global.h>
21
23 use, intrinsic :: iso_fortran_env
24 use blas_oct_m
26
27 implicit none
28
29 private
30
31 public :: &
34
36 integer :: m = 10
37 real(real64) :: ch(-10:10)
38 real(real64) :: cg(-10:10)
39 real(real64) :: cht(-10:10)
40 real(real64) :: cgt(-10:10)
41 end type lazy_8_filter_t
42
43contains
44
45 ! ---------------------------------------------------------
47 pure function lazy_8() result(filters)
48 type(lazy_8_filter_t) :: filters
49 integer :: i
50
51 filters%ch = 0._real64
52 filters%cht = 0._real64
53 filters%cg = 0._real64
54 filters%cgt = 0._real64
55
56 ! The normalization is chosen such that a constant function remains the
57 ! same constant on each level of the transform.
58 filters%ch(-7) = -5._real64/2048._real64
59 filters%ch(-5) = 49._real64/2048._real64
60 filters%ch(-3) = -245._real64/2048._real64
61 filters%ch(-1) = 1225._real64/2048._real64
62 filters%ch( 0) = 1._real64
63 filters%ch( 1) = 1225._real64/2048._real64
64 filters%ch( 3) = -245._real64/2048._real64
65 filters%ch( 5) = 49._real64/2048._real64
66 filters%ch( 7) = -5._real64/2048._real64
67 filters%cht(0) = 1._real64
68
69 ! g coefficients from h coefficients
70 do i = -filters%m, filters%m - 1
71 filters%cg(i + 1) = filters%cht(-i) * real((2*modulo(i,2)-1), real64)
72 filters%cgt(i + 1) = filters%ch(-i) * real((2*modulo(i,2)-1), real64)
73 end do
74 end function lazy_8
75
76 !!****h* BigDFT/scaling_function
77 !! NAME
78 !! scaling_function
79 !!
80 !! FUNCTION
81 !! Calculate the values of a scaling function in real uniform grid
82 !!
83 !! SOURCE
84 !!
85 subroutine scaling_function(itype,nd,nrange,a,x)
86 integer, intent(in) :: itype
87 integer, intent(in) :: nd
88 integer, intent(out) :: nrange
89 real(real64), dimension(0:nd), intent(out) :: a,x
90
91 real(real64), dimension(:), allocatable :: y
92 integer :: i,nt,ni
93
94 !Only itype=8,14,16,20,24,30,40,50,60,100
95 select case (itype)
96 case (8)
97 !O.K.
98 case default
99 message(1) = "Only interpolating functions 8, 14, 16, 20, 24, 30, 40, 50, 60, 100."
100 call messages_fatal(1)
101 end select
102!!$ write(unit=*,fmt="(1x,a,i0,a)") &
103!!$ "Use interpolating scaling functions of ",itype," order"
104
105 !Give the range of the scaling function
106 !from -itype to itype
107 ni=2*itype
108 nrange = ni
109 allocate(y(0:nd))
110
111 ! plot scaling function
112 x = 0.0_8
113 y = 0.0_8
114
115 nt=ni
116 x(nt/2-1)=1._real64
117 loop1: do
118 nt=2*nt
119 ! write(6,*) 'nd,nt',nd,nt
120 select case (itype)
121 case (8)
122 call back_trans_8(nd,nt,x,y)
123 end select
124 call blas_copy(nt, y(0), 1, x(0) ,1)
125 if (nt == nd) then
126 exit loop1
127 end if
128 end do loop1
129
130 !open (unit=1,file='scfunction',status='unknown')
131 do i=0,nd
132 a(i) = 1._real64 * i * ni / nd - (.5_real64 * ni - 1._real64)
133 !write(1,*) 1._real64*i*ni/nd-(.5_real64*ni-1._real64),x(i)
134 end do
135 !close(1)
136
137 deallocate(y)
138 end subroutine scaling_function
139 !!***
140
141 !!****h* BigDFT/scf_recursion
142 !! NAME
143 !! scf_recursion
144 !!
145 !! FUNCTION
146 !! Do iterations to go from p0gauss to pgauss
147 !! order interpolating scaling function
148 !!
149 !! SOURCE
150 !!
151 subroutine scf_recursion(itype,n_iter,n_range,kernel_scf,kern_1_scf)
152 integer, intent(in) :: itype,n_iter,n_range
153 real(kind=8), intent(inout) :: kernel_scf(-n_range:n_range)
154 real(kind=8), intent(out) :: kern_1_scf(-n_range:n_range)
155
156 !Only itype=8,14,16,20,24,30,40,50,60,100
157 select case (itype)
158 case (8)
159 !O.K.
160 case default
161 message(1) = "Only interpolating functions 8, 14, 16, 20, 24, 30, 40, 50, 60, 100."
162 call messages_fatal(1)
163 end select
164
165 select case (itype)
166 case (8)
167 call scf_recursion_8(n_iter,n_range,kernel_scf,kern_1_scf)
168 end select
169
170 end subroutine scf_recursion
171 !!***
172
173 !!****h* BigDFT/back_trans_8
174 !! NAME
175 !! back_trans_8
176 !!
177 !! FUNCTION
178 !!
179 !! SOURCE
180 !!
181 ! backward wavelet transform
182 ! nd: length of data set
183 ! nt length of data in data set to be transformed
184 ! m filter length (m has to be even!)
185 ! x input data, y output data
186 subroutine back_trans_8(nd,nt,x,y)
187 integer, intent(in) :: nd,nt
188 real(kind=8), intent(in) :: x(0:nd-1)
189 real(kind=8), intent(out) :: y(0:nd-1)
190
191 type(lazy_8_filter_t) :: filters
192 integer :: i,j,ind
193
194 filters = lazy_8()
195
196 do i=0,nt/2-1
197 y(2*i+0)=0._real64
198 y(2*i+1)=0._real64
199
200 do j=-filters%m/2,filters%m/2-1
201
202 ! periodically wrap index if necessary
203 ind=i-j
204 do
205 if (ind < 0) then
206 ind=ind+nt/2
207 cycle
208 end if
209 if (ind >= nt/2) then
210 ind=ind-nt/2
211 cycle
212 end if
213 exit
214 end do
215
216 y(2*i+0)=y(2*i+0) + filters%ch(2*j-0)*x(ind)+filters%cg(2*j-0)*x(ind+nt/2)
217 y(2*i+1)=y(2*i+1) + filters%ch(2*j+1)*x(ind)+filters%cg(2*j+1)*x(ind+nt/2)
218 end do
219
220 end do
221
222 end subroutine back_trans_8
223 !!***
224
225 !!****h* BigDFT/scf_recursion_8
226 !! NAME
227 !! scf_recursion_8
228 !!
229 !! FUNCTION
230 !! Do iterations to go from p0gauss to pgauss
231 !! 8th-order interpolating scaling function
232 !!
233 !! SOURCE
234 !!
235 subroutine scf_recursion_8(n_iter,n_range,kernel_scf,kern_1_scf)
236 integer, intent(in) :: n_iter,n_range
237 real(kind=8), intent(inout) :: kernel_scf(-n_range:n_range)
238 real(kind=8), intent(out) :: kern_1_scf(-n_range:n_range)
239
240 type(lazy_8_filter_t) :: filters
241 real(kind=8) :: kern,kern_tot
242 integer :: i_iter,i,j,ind
243
244 filters = lazy_8()
245
246 !Start the iteration to go from p0gauss to pgauss
247 loop_iter_scf: do i_iter=1,n_iter
248 kern_1_scf(:) = kernel_scf(:)
249 kernel_scf(:) = 0._real64
250 loop_iter_i: do i=0,n_range
251 kern_tot = 0._real64
252 do j=-filters%m,filters%m
253 ind = 2*i-j
254 if (abs(ind) > n_range) then
255 kern = 0._real64
256 else
257 kern = kern_1_scf(ind)
258 end if
259 kern_tot = kern_tot + filters%ch(j)*kern
260 end do
261 if (abs(kern_tot) <= 1d-150) then
262 !zero after (be sure because strictly == 0._real64)
263 exit loop_iter_i
264 else
265 kernel_scf( i) = 0.5_real64*kern_tot
266 kernel_scf(-i) = kernel_scf(i)
267 end if
268 end do loop_iter_i
269 end do loop_iter_scf
270 end subroutine scf_recursion_8
271 !!***
272
273end module scaling_function_oct_m
274
275!! Local Variables:
276!! mode: f90
277!! coding: utf-8
278!! End:
--------------— copy ---------------— Copies a vector, x, to a vector, y.
Definition: blas.F90:207
This module contains interfaces for BLAS routines You should not use these routines directly....
Definition: blas.F90:120
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine scf_recursion_8(n_iter, n_range, kernel_scf, kern_1_scf)
pure type(lazy_8_filter_t) function lazy_8()
Filters for interpolating scaling functions (order 8)
subroutine back_trans_8(nd, nt, x, y)
subroutine, public scaling_function(itype, nd, nrange, a, x)
subroutine, public scf_recursion(itype, n_iter, n_range, kernel_scf, kern_1_scf)