Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Definition and initialisation of the ps_wavelet data type.
10 : !> \history 01.2014 Renamed from ps_wavelet_types to disentangle dependencies (Ole Schuett)
11 : !> \author Florian Schiffmann (09.2007,fschiff)
12 : ! **************************************************************************************************
13 : MODULE ps_wavelet_methods
14 :
15 : USE bibliography, ONLY: Genovese2006,&
16 : Genovese2007,&
17 : cite_reference
18 : USE kinds, ONLY: dp
19 : USE ps_wavelet_kernel, ONLY: createKernel
20 : USE ps_wavelet_types, ONLY: WAVELET0D,&
21 : ps_wavelet_release,&
22 : ps_wavelet_type
23 : USE ps_wavelet_util, ONLY: F_FFT_dimensions,&
24 : PSolver,&
25 : P_FFT_dimensions,&
26 : S_FFT_dimensions
27 : USE pw_grid_types, ONLY: pw_grid_type
28 : USE pw_poisson_types, ONLY: pw_poisson_parameter_type
29 : USE pw_types, ONLY: pw_r3d_rs_type
30 : USE util, ONLY: get_limit
31 : #include "../base/base_uses.f90"
32 :
33 : IMPLICIT NONE
34 :
35 : PRIVATE
36 :
37 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ps_wavelet_methods'
38 :
39 : ! *** Public data types ***
40 :
41 : PUBLIC :: ps_wavelet_create, &
42 : cp2k_distribution_to_z_slices, &
43 : z_slices_to_cp2k_distribution, &
44 : ps_wavelet_solve
45 :
46 : CONTAINS
47 :
48 : ! **************************************************************************************************
49 : !> \brief creates the ps_wavelet_type which is needed for the link to
50 : !> the Poisson Solver of Luigi Genovese
51 : !> \param poisson_params ...
52 : !> \param wavelet wavelet to create
53 : !> \param pw_grid the grid that is used to create the wavelet kernel
54 : !> \author Flroian Schiffmann
55 : ! **************************************************************************************************
56 840 : SUBROUTINE ps_wavelet_create(poisson_params, wavelet, pw_grid)
57 : TYPE(pw_poisson_parameter_type), INTENT(IN) :: poisson_params
58 : TYPE(ps_wavelet_type), POINTER :: wavelet
59 : TYPE(pw_grid_type), POINTER :: pw_grid
60 :
61 : CHARACTER(len=*), PARAMETER :: routineN = 'ps_wavelet_create'
62 :
63 : INTEGER :: handle, iproc, nproc, nx, ny, nz
64 : REAL(KIND=dp) :: hx, hy, hz
65 :
66 840 : CALL timeset(routineN, handle)
67 :
68 840 : CALL cite_reference(Genovese2006)
69 840 : CALL cite_reference(Genovese2007)
70 :
71 840 : IF (ASSOCIATED(wavelet)) THEN
72 0 : CALL ps_wavelet_release(wavelet)
73 : NULLIFY (wavelet)
74 : END IF
75 :
76 4200 : ALLOCATE (wavelet)
77 :
78 840 : nx = pw_grid%npts(1)
79 840 : ny = pw_grid%npts(2)
80 840 : nz = pw_grid%npts(3)
81 :
82 840 : hx = pw_grid%dr(1)
83 840 : hy = pw_grid%dr(2)
84 840 : hz = pw_grid%dr(3)
85 :
86 2520 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
87 :
88 840 : iproc = pw_grid%para%group%mepos
89 :
90 : NULLIFY (wavelet%karray, wavelet%rho_z_sliced)
91 :
92 840 : wavelet%geocode = poisson_params%wavelet_geocode
93 840 : wavelet%method = poisson_params%wavelet_method
94 840 : wavelet%special_dimension = poisson_params%wavelet_special_dimension
95 840 : wavelet%itype_scf = poisson_params%wavelet_scf_type
96 840 : wavelet%datacode = "D"
97 :
98 840 : IF (poisson_params%wavelet_method == WAVELET0D) THEN
99 526 : IF (hx .NE. hy) &
100 0 : CPABORT("Poisson solver for non cubic cells not yet implemented")
101 526 : IF (hz .NE. hy) &
102 0 : CPABORT("Poisson solver for non cubic cells not yet implemented")
103 : END IF
104 :
105 840 : CALL RS_z_slice_distribution(wavelet, pw_grid)
106 :
107 840 : CALL timestop(handle)
108 840 : END SUBROUTINE ps_wavelet_create
109 :
110 : ! **************************************************************************************************
111 : !> \brief ...
112 : !> \param wavelet ...
113 : !> \param pw_grid ...
114 : ! **************************************************************************************************
115 840 : SUBROUTINE RS_z_slice_distribution(wavelet, pw_grid)
116 :
117 : TYPE(ps_wavelet_type), POINTER :: wavelet
118 : TYPE(pw_grid_type), POINTER :: pw_grid
119 :
120 : CHARACTER(len=*), PARAMETER :: routineN = 'RS_z_slice_distribution'
121 :
122 : CHARACTER(LEN=1) :: geocode
123 : INTEGER :: handle, iproc, m1, m2, m3, md1, md2, &
124 : md3, n1, n2, n3, nd1, nd2, nd3, nproc, &
125 : nx, ny, nz, z_dim
126 : REAL(KIND=dp) :: hx, hy, hz
127 :
128 840 : CALL timeset(routineN, handle)
129 2520 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
130 840 : iproc = pw_grid%para%group%mepos
131 840 : geocode = wavelet%geocode
132 840 : nx = pw_grid%npts(1)
133 840 : ny = pw_grid%npts(2)
134 840 : nz = pw_grid%npts(3)
135 840 : hx = pw_grid%dr(1)
136 840 : hy = pw_grid%dr(2)
137 840 : hz = pw_grid%dr(3)
138 :
139 : !calculate Dimensions for the z-distributed density and for the kernel
140 :
141 840 : IF (geocode == 'P') THEN
142 312 : CALL P_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
143 528 : ELSE IF (geocode == 'S') THEN
144 2 : CALL S_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
145 526 : ELSE IF (geocode == 'F') THEN
146 526 : CALL F_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
147 : END IF
148 :
149 840 : wavelet%PS_grid(1) = md1
150 840 : wavelet%PS_grid(2) = md3
151 840 : wavelet%PS_grid(3) = md2
152 840 : z_dim = md2/nproc
153 : !!!!!!!!! indices y and z are interchanged !!!!!!!
154 4200 : ALLOCATE (wavelet%rho_z_sliced(md1, md3, z_dim))
155 :
156 : CALL createKernel(geocode, nx, ny, nz, hx, hy, hz, wavelet%itype_scf, iproc, nproc, wavelet%karray, &
157 840 : pw_grid%para%group)
158 :
159 840 : CALL timestop(handle)
160 840 : END SUBROUTINE RS_z_slice_distribution
161 :
162 : ! **************************************************************************************************
163 : !> \brief ...
164 : !> \param density ...
165 : !> \param wavelet ...
166 : !> \param pw_grid ...
167 : ! **************************************************************************************************
168 31915 : SUBROUTINE cp2k_distribution_to_z_slices(density, wavelet, pw_grid)
169 :
170 : TYPE(pw_r3d_rs_type), INTENT(IN) :: density
171 : TYPE(ps_wavelet_type), POINTER :: wavelet
172 : TYPE(pw_grid_type), POINTER :: pw_grid
173 :
174 : CHARACTER(len=*), PARAMETER :: routineN = 'cp2k_distribution_to_z_slices'
175 :
176 : INTEGER :: dest, handle, i, ii, iproc, j, k, l, &
177 : local_z_dim, loz, m, m2, md2, nproc, &
178 : should_warn
179 31915 : INTEGER, ALLOCATABLE, DIMENSION(:) :: rcount, rdispl, scount, sdispl, tmp
180 : INTEGER, DIMENSION(2) :: cart_pos, lox, loy
181 : INTEGER, DIMENSION(3) :: lb, ub
182 : REAL(KIND=dp) :: max_val_low, max_val_up
183 31915 : REAL(KIND=dp), DIMENSION(:), POINTER :: rbuf, sbuf
184 :
185 31915 : CALL timeset(routineN, handle)
186 :
187 31915 : CPASSERT(ASSOCIATED(wavelet))
188 :
189 95745 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
190 31915 : iproc = pw_grid%para%group%mepos
191 31915 : md2 = wavelet%PS_grid(3)
192 31915 : m2 = pw_grid%npts(3)
193 127660 : lb(:) = pw_grid%bounds_local(1, :)
194 127660 : ub(:) = pw_grid%bounds_local(2, :)
195 31915 : local_z_dim = MAX((md2/nproc), 1)
196 :
197 191490 : ALLOCATE (sbuf(PRODUCT(pw_grid%npts_local)))
198 191490 : ALLOCATE (rbuf(PRODUCT(wavelet%PS_grid)/nproc))
199 223405 : ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
200 :
201 891389598 : rbuf = 0.0_dp
202 31915 : ii = 1
203 940070 : DO k = lb(3), ub(3)
204 32708669 : DO j = lb(2), ub(2)
205 904342950 : DO i = lb(1), ub(1)
206 871666196 : sbuf(ii) = density%array(i, j, k)
207 903434795 : ii = ii + 1
208 : END DO
209 : END DO
210 : END DO
211 :
212 31915 : should_warn = 0
213 31915 : IF (wavelet%geocode == 'S' .OR. wavelet%geocode == 'F') THEN
214 15354 : max_val_low = 0._dp
215 15354 : max_val_up = 0._dp
216 16251965 : IF (lb(2) == pw_grid%bounds(1, 2)) max_val_low = MAXVAL(ABS(density%array(:, lb(2), :)))
217 16251965 : IF (ub(2) == pw_grid%bounds(2, 2)) max_val_up = MAXVAL(ABS(density%array(:, ub(2), :)))
218 15354 : IF (max_val_low .GE. 0.0001_dp) should_warn = 1
219 15354 : IF (max_val_up .GE. 0.0001_dp) should_warn = 1
220 15354 : IF (wavelet%geocode == 'F') THEN
221 15336 : max_val_low = 0._dp
222 15336 : max_val_up = 0._dp
223 16053638 : IF (lb(1) == pw_grid%bounds(1, 1)) max_val_low = MAXVAL(ABS(density%array(lb(1), :, :)))
224 16053638 : IF (ub(1) == pw_grid%bounds(2, 1)) max_val_up = MAXVAL(ABS(density%array(ub(1), :, :)))
225 15336 : IF (max_val_low .GE. 0.0001_dp) should_warn = 1
226 15336 : IF (max_val_up .GE. 0.0001_dp) should_warn = 1
227 15336 : max_val_low = 0._dp
228 15336 : max_val_up = 0._dp
229 16224731 : IF (lb(3) == pw_grid%bounds(1, 3)) max_val_low = MAXVAL(ABS(density%array(:, :, lb(3))))
230 16224731 : IF (ub(3) == pw_grid%bounds(2, 3)) max_val_up = MAXVAL(ABS(density%array(:, :, ub(3))))
231 15336 : IF (max_val_low .GE. 0.0001_dp) should_warn = 1
232 15336 : IF (max_val_up .GE. 0.0001_dp) should_warn = 1
233 : END IF
234 : END IF
235 :
236 31915 : CALL pw_grid%para%group%max(should_warn)
237 31915 : IF (should_warn > 0 .AND. iproc == 0) THEN
238 4291 : CPWARN("Density non-zero on the edges of the unit cell: wrong results in WAVELET solver")
239 : END IF
240 76382 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
241 120849 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
242 133401 : cart_pos = (/i, j/)
243 44467 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
244 44467 : IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
245 44467 : IF (dest*local_z_dim .LE. m2) THEN
246 44467 : IF ((dest + 1)*local_z_dim .LE. m2) THEN
247 40074 : scount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
248 : ELSE
249 4393 : scount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*MOD(m2, local_z_dim))
250 : END IF
251 : ELSE
252 0 : scount(dest + 1) = 0
253 : END IF
254 : ELSE
255 0 : scount(dest + 1) = 0
256 : END IF
257 44467 : lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
258 44467 : loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
259 88934 : IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
260 44467 : IF (iproc*local_z_dim .LE. m2) THEN
261 44467 : IF ((iproc + 1)*local_z_dim .LE. m2) THEN
262 40074 : rcount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*local_z_dim)
263 : ELSE
264 4393 : rcount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*MOD(m2, local_z_dim))
265 : END IF
266 : ELSE
267 0 : rcount(dest + 1) = 0
268 : END IF
269 : ELSE
270 0 : rcount(dest + 1) = 0
271 : END IF
272 :
273 : END DO
274 : END DO
275 31915 : sdispl(1) = 0
276 31915 : rdispl(1) = 0
277 44467 : DO i = 2, nproc
278 12552 : sdispl(i) = sdispl(i - 1) + scount(i - 1)
279 44467 : rdispl(i) = rdispl(i - 1) + rcount(i - 1)
280 : END DO
281 2654413477 : CALL pw_grid%para%group%alltoall(sbuf, scount, sdispl, rbuf, rcount, rdispl)
282 : !!!! and now, how to put the right cubes to the right position!!!!!!
283 :
284 914747986 : wavelet%rho_z_sliced = 0.0_dp
285 :
286 76382 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
287 120849 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
288 133401 : cart_pos = (/i, j/)
289 44467 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
290 :
291 44467 : lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
292 44467 : loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
293 88934 : IF (iproc*local_z_dim .LE. m2) THEN
294 44467 : IF ((iproc + 1)*local_z_dim .LE. m2) THEN
295 : loz = local_z_dim
296 : ELSE
297 4393 : loz = MOD(m2, local_z_dim)
298 : END IF
299 44467 : ii = 1
300 952622 : DO k = 1, loz
301 32721221 : DO l = loy(1), loy(2)
302 904342950 : DO m = lox(1), lox(2)
303 871666196 : wavelet%rho_z_sliced(m, l, k) = rbuf(ii + rdispl(dest + 1))
304 903434795 : ii = ii + 1
305 : END DO
306 : END DO
307 : END DO
308 : END IF
309 : END DO
310 : END DO
311 :
312 31915 : DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
313 :
314 31915 : CALL timestop(handle)
315 :
316 31915 : END SUBROUTINE cp2k_distribution_to_z_slices
317 :
318 : ! **************************************************************************************************
319 : !> \brief ...
320 : !> \param density ...
321 : !> \param wavelet ...
322 : !> \param pw_grid ...
323 : ! **************************************************************************************************
324 31915 : SUBROUTINE z_slices_to_cp2k_distribution(density, wavelet, pw_grid)
325 :
326 : TYPE(pw_r3d_rs_type), INTENT(IN) :: density
327 : TYPE(ps_wavelet_type), POINTER :: wavelet
328 : TYPE(pw_grid_type), POINTER :: pw_grid
329 :
330 : INTEGER :: dest, i, ii, iproc, j, k, l, &
331 : local_z_dim, loz, m, m2, md2, nproc
332 31915 : INTEGER, ALLOCATABLE, DIMENSION(:) :: rcount, rdispl, scount, sdispl, tmp
333 : INTEGER, DIMENSION(2) :: cart_pos, lox, loy, min_x, min_y
334 : INTEGER, DIMENSION(3) :: lb, ub
335 31915 : REAL(KIND=dp), DIMENSION(:), POINTER :: rbuf, sbuf
336 :
337 0 : CPASSERT(ASSOCIATED(wavelet))
338 :
339 95745 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
340 31915 : iproc = pw_grid%para%group%mepos
341 31915 : md2 = wavelet%PS_grid(3)
342 31915 : m2 = pw_grid%npts(3)
343 :
344 127660 : lb(:) = pw_grid%bounds_local(1, :)
345 127660 : ub(:) = pw_grid%bounds_local(2, :)
346 :
347 31915 : local_z_dim = MAX((md2/nproc), 1)
348 :
349 191490 : ALLOCATE (rbuf(PRODUCT(pw_grid%npts_local)))
350 191490 : ALLOCATE (sbuf(PRODUCT(wavelet%PS_grid)/nproc))
351 223405 : ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
352 76382 : scount = 0
353 76382 : rcount = 0
354 871698111 : rbuf = 0.0_dp
355 31915 : ii = 1
356 31915 : IF (iproc*local_z_dim .LE. m2) THEN
357 31915 : IF ((iproc + 1)*local_z_dim .LE. m2) THEN
358 : loz = local_z_dim
359 : ELSE
360 2706 : loz = MOD(m2, local_z_dim)
361 : END IF
362 : ELSE
363 : loz = 0
364 : END IF
365 :
366 31915 : min_x = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), 0)
367 31915 : min_y = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), 0)
368 76382 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
369 120849 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
370 133401 : cart_pos = (/i, j/)
371 44467 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
372 44467 : IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
373 44467 : IF (dest*local_z_dim .LE. m2) THEN
374 44467 : IF ((dest + 1)*local_z_dim .LE. m2) THEN
375 40074 : rcount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
376 : ELSE
377 4393 : rcount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*MOD(m2, local_z_dim))
378 : END IF
379 : ELSE
380 0 : rcount(dest + 1) = 0
381 : END IF
382 : ELSE
383 0 : rcount(dest + 1) = 0
384 : END IF
385 44467 : lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
386 44467 : loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
387 88934 : IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
388 44467 : scount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*loz)
389 952622 : DO k = lox(1) - min_x(1) + 1, lox(2) - min_x(1) + 1
390 32721221 : DO l = loy(1) - min_y(1) + 1, loy(2) - min_y(1) + 1
391 904342950 : DO m = 1, loz
392 871666196 : sbuf(ii) = wavelet%rho_z_sliced(k, l, m)
393 903434795 : ii = ii + 1
394 : END DO
395 : END DO
396 : END DO
397 : ELSE
398 0 : scount(dest + 1) = 0
399 : END IF
400 : END DO
401 : END DO
402 31915 : sdispl(1) = 0
403 31915 : rdispl(1) = 0
404 44467 : DO i = 2, nproc
405 12552 : sdispl(i) = sdispl(i - 1) + scount(i - 1)
406 44467 : rdispl(i) = rdispl(i - 1) + rcount(i - 1)
407 : END DO
408 2634721990 : CALL pw_grid%para%group%alltoall(sbuf, scount, sdispl, rbuf, rcount, rdispl)
409 :
410 : !!!! and now, how to put the right cubes to the right position!!!!!!
411 :
412 76382 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
413 120849 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
414 133401 : cart_pos = (/i, j/)
415 44467 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
416 88934 : IF (dest*local_z_dim .LE. m2) THEN
417 44467 : IF ((dest + 1)*local_z_dim .LE. m2) THEN
418 : loz = local_z_dim
419 : ELSE
420 4393 : loz = MOD(m2, local_z_dim)
421 : END IF
422 44467 : ii = 1
423 44467 : IF (lb(3) + (dest*local_z_dim) .LE. ub(3)) THEN
424 952622 : DO m = lb(1), ub(1)
425 32721221 : DO l = lb(2), ub(2)
426 904342950 : DO k = lb(3) + (dest*local_z_dim), lb(3) + (dest*local_z_dim) + loz - 1
427 871666196 : density%array(m, l, k) = rbuf(ii + rdispl(dest + 1))
428 903434795 : ii = ii + 1
429 : END DO
430 : END DO
431 : END DO
432 : END IF
433 : END IF
434 : END DO
435 : END DO
436 31915 : DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
437 :
438 31915 : END SUBROUTINE z_slices_to_cp2k_distribution
439 :
440 : ! **************************************************************************************************
441 : !> \brief ...
442 : !> \param wavelet ...
443 : !> \param pw_grid ...
444 : ! **************************************************************************************************
445 31915 : SUBROUTINE ps_wavelet_solve(wavelet, pw_grid)
446 :
447 : TYPE(ps_wavelet_type), POINTER :: wavelet
448 : TYPE(pw_grid_type), POINTER :: pw_grid
449 :
450 : CHARACTER(len=*), PARAMETER :: routineN = 'ps_wavelet_solve'
451 :
452 : CHARACTER(LEN=1) :: geocode
453 : INTEGER :: handle, iproc, nproc, nx, ny, nz
454 : REAL(KIND=dp) :: hx, hy, hz
455 :
456 31915 : CALL timeset(routineN, handle)
457 95745 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
458 31915 : iproc = pw_grid%para%group%mepos
459 31915 : geocode = wavelet%geocode
460 31915 : nx = pw_grid%npts(1)
461 31915 : ny = pw_grid%npts(2)
462 31915 : nz = pw_grid%npts(3)
463 31915 : hx = pw_grid%dr(1)
464 31915 : hy = pw_grid%dr(2)
465 31915 : hz = pw_grid%dr(3)
466 :
467 : CALL PSolver(geocode, iproc, nproc, nx, ny, nz, hx, hy, hz, &
468 31915 : wavelet%rho_z_sliced, wavelet%karray, pw_grid)
469 31915 : CALL timestop(handle)
470 31915 : END SUBROUTINE ps_wavelet_solve
471 :
472 : END MODULE ps_wavelet_methods
|