Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 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 844 : 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 844 : CALL timeset(routineN, handle)
67 :
68 844 : CALL cite_reference(Genovese2006)
69 844 : CALL cite_reference(Genovese2007)
70 :
71 844 : IF (ASSOCIATED(wavelet)) THEN
72 0 : CALL ps_wavelet_release(wavelet)
73 : NULLIFY (wavelet)
74 : END IF
75 :
76 4220 : ALLOCATE (wavelet)
77 :
78 844 : nx = pw_grid%npts(1)
79 844 : ny = pw_grid%npts(2)
80 844 : nz = pw_grid%npts(3)
81 :
82 844 : hx = pw_grid%dr(1)
83 844 : hy = pw_grid%dr(2)
84 844 : hz = pw_grid%dr(3)
85 :
86 2532 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
87 :
88 844 : iproc = pw_grid%para%group%mepos
89 :
90 : NULLIFY (wavelet%karray, wavelet%rho_z_sliced)
91 :
92 844 : wavelet%geocode = poisson_params%wavelet_geocode
93 844 : wavelet%method = poisson_params%wavelet_method
94 844 : wavelet%special_dimension = poisson_params%wavelet_special_dimension
95 844 : wavelet%itype_scf = poisson_params%wavelet_scf_type
96 844 : wavelet%datacode = "D"
97 :
98 844 : IF (poisson_params%wavelet_method == WAVELET0D) THEN
99 530 : IF (hx .NE. hy) &
100 0 : CPABORT("Poisson solver for non cubic cells not yet implemented")
101 530 : IF (hz .NE. hy) &
102 0 : CPABORT("Poisson solver for non cubic cells not yet implemented")
103 : END IF
104 :
105 844 : CALL RS_z_slice_distribution(wavelet, pw_grid)
106 :
107 844 : CALL timestop(handle)
108 844 : END SUBROUTINE ps_wavelet_create
109 :
110 : ! **************************************************************************************************
111 : !> \brief ...
112 : !> \param wavelet ...
113 : !> \param pw_grid ...
114 : ! **************************************************************************************************
115 844 : 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 844 : CALL timeset(routineN, handle)
129 2532 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
130 844 : iproc = pw_grid%para%group%mepos
131 844 : geocode = wavelet%geocode
132 844 : nx = pw_grid%npts(1)
133 844 : ny = pw_grid%npts(2)
134 844 : nz = pw_grid%npts(3)
135 844 : hx = pw_grid%dr(1)
136 844 : hy = pw_grid%dr(2)
137 844 : hz = pw_grid%dr(3)
138 :
139 : !calculate Dimensions for the z-distributed density and for the kernel
140 :
141 844 : 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 532 : 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 530 : ELSE IF (geocode == 'F') THEN
146 530 : 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 844 : wavelet%PS_grid(1) = md1
150 844 : wavelet%PS_grid(2) = md3
151 844 : wavelet%PS_grid(3) = md2
152 844 : z_dim = md2/nproc
153 : !!!!!!!!! indices y and z are interchanged !!!!!!!
154 4220 : 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 844 : pw_grid%para%group)
158 :
159 844 : CALL timestop(handle)
160 844 : END SUBROUTINE RS_z_slice_distribution
161 :
162 : ! **************************************************************************************************
163 : !> \brief ...
164 : !> \param density ...
165 : !> \param wavelet ...
166 : !> \param pw_grid ...
167 : ! **************************************************************************************************
168 32035 : 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 32035 : 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 32035 : REAL(KIND=dp), DIMENSION(:), POINTER :: rbuf, sbuf
184 :
185 32035 : CALL timeset(routineN, handle)
186 :
187 32035 : CPASSERT(ASSOCIATED(wavelet))
188 :
189 96105 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
190 32035 : iproc = pw_grid%para%group%mepos
191 32035 : md2 = wavelet%PS_grid(3)
192 32035 : m2 = pw_grid%npts(3)
193 128140 : lb(:) = pw_grid%bounds_local(1, :)
194 128140 : ub(:) = pw_grid%bounds_local(2, :)
195 32035 : local_z_dim = MAX((md2/nproc), 1)
196 :
197 192210 : ALLOCATE (sbuf(PRODUCT(pw_grid%npts_local)))
198 192210 : ALLOCATE (rbuf(PRODUCT(wavelet%PS_grid)/nproc))
199 224245 : ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
200 :
201 913784598 : rbuf = 0.0_dp
202 32035 : ii = 1
203 948830 : DO k = lb(3), ub(3)
204 33339509 : DO j = lb(2), ub(2)
205 927368550 : DO i = lb(1), ub(1)
206 894061076 : sbuf(ii) = density%array(i, j, k)
207 926451755 : ii = ii + 1
208 : END DO
209 : END DO
210 : END DO
211 :
212 32035 : should_warn = 0
213 32035 : IF (wavelet%geocode == 'S' .OR. wavelet%geocode == 'F') THEN
214 15474 : max_val_low = 0._dp
215 15474 : max_val_up = 0._dp
216 16571765 : IF (lb(2) == pw_grid%bounds(1, 2)) max_val_low = MAXVAL(ABS(density%array(:, lb(2), :)))
217 16571765 : IF (ub(2) == pw_grid%bounds(2, 2)) max_val_up = MAXVAL(ABS(density%array(:, ub(2), :)))
218 15474 : IF (max_val_low .GE. 0.0001_dp) should_warn = 1
219 15474 : IF (max_val_up .GE. 0.0001_dp) should_warn = 1
220 15474 : IF (wavelet%geocode == 'F') THEN
221 15456 : max_val_low = 0._dp
222 15456 : max_val_up = 0._dp
223 16369118 : IF (lb(1) == pw_grid%bounds(1, 1)) max_val_low = MAXVAL(ABS(density%array(lb(1), :, :)))
224 16369118 : IF (ub(1) == pw_grid%bounds(2, 1)) max_val_up = MAXVAL(ABS(density%array(ub(1), :, :)))
225 15456 : IF (max_val_low .GE. 0.0001_dp) should_warn = 1
226 15456 : IF (max_val_up .GE. 0.0001_dp) should_warn = 1
227 15456 : max_val_low = 0._dp
228 15456 : max_val_up = 0._dp
229 16544531 : IF (lb(3) == pw_grid%bounds(1, 3)) max_val_low = MAXVAL(ABS(density%array(:, :, lb(3))))
230 16544531 : IF (ub(3) == pw_grid%bounds(2, 3)) max_val_up = MAXVAL(ABS(density%array(:, :, ub(3))))
231 15456 : IF (max_val_low .GE. 0.0001_dp) should_warn = 1
232 15456 : IF (max_val_up .GE. 0.0001_dp) should_warn = 1
233 : END IF
234 : END IF
235 :
236 32035 : CALL pw_grid%para%group%max(should_warn)
237 32035 : IF (should_warn > 0 .AND. iproc == 0) THEN
238 4293 : CPWARN("Density non-zero on the edges of the unit cell: wrong results in WAVELET solver")
239 : END IF
240 76742 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
241 121449 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
242 134121 : cart_pos = (/i, j/)
243 44707 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
244 44707 : IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
245 44707 : IF (dest*local_z_dim .LE. m2) THEN
246 44707 : IF ((dest + 1)*local_z_dim .LE. m2) THEN
247 40314 : 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 44707 : lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
258 44707 : loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
259 89414 : IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
260 44707 : IF (iproc*local_z_dim .LE. m2) THEN
261 44707 : IF ((iproc + 1)*local_z_dim .LE. m2) THEN
262 40314 : 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 32035 : sdispl(1) = 0
276 32035 : rdispl(1) = 0
277 44707 : DO i = 2, nproc
278 12672 : sdispl(i) = sdispl(i - 1) + scount(i - 1)
279 44707 : rdispl(i) = rdispl(i - 1) + rcount(i - 1)
280 : END DO
281 2721598237 : 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 937458346 : wavelet%rho_z_sliced = 0.0_dp
285 :
286 76742 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
287 121449 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
288 134121 : cart_pos = (/i, j/)
289 44707 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
290 :
291 44707 : lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
292 44707 : loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
293 89414 : IF (iproc*local_z_dim .LE. m2) THEN
294 44707 : 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 44707 : ii = 1
300 961502 : DO k = 1, loz
301 33352181 : DO l = loy(1), loy(2)
302 927368550 : DO m = lox(1), lox(2)
303 894061076 : wavelet%rho_z_sliced(m, l, k) = rbuf(ii + rdispl(dest + 1))
304 926451755 : ii = ii + 1
305 : END DO
306 : END DO
307 : END DO
308 : END IF
309 : END DO
310 : END DO
311 :
312 32035 : DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
313 :
314 32035 : CALL timestop(handle)
315 :
316 32035 : END SUBROUTINE cp2k_distribution_to_z_slices
317 :
318 : ! **************************************************************************************************
319 : !> \brief ...
320 : !> \param density ...
321 : !> \param wavelet ...
322 : !> \param pw_grid ...
323 : ! **************************************************************************************************
324 32035 : 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 32035 : 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 32035 : REAL(KIND=dp), DIMENSION(:), POINTER :: rbuf, sbuf
336 :
337 0 : CPASSERT(ASSOCIATED(wavelet))
338 :
339 96105 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
340 32035 : iproc = pw_grid%para%group%mepos
341 32035 : md2 = wavelet%PS_grid(3)
342 32035 : m2 = pw_grid%npts(3)
343 :
344 128140 : lb(:) = pw_grid%bounds_local(1, :)
345 128140 : ub(:) = pw_grid%bounds_local(2, :)
346 :
347 32035 : local_z_dim = MAX((md2/nproc), 1)
348 :
349 192210 : ALLOCATE (rbuf(PRODUCT(pw_grid%npts_local)))
350 192210 : ALLOCATE (sbuf(PRODUCT(wavelet%PS_grid)/nproc))
351 224245 : ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
352 76742 : scount = 0
353 76742 : rcount = 0
354 894093111 : rbuf = 0.0_dp
355 32035 : ii = 1
356 32035 : IF (iproc*local_z_dim .LE. m2) THEN
357 32035 : 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 32035 : min_x = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), 0)
367 32035 : min_y = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), 0)
368 76742 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
369 121449 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
370 134121 : cart_pos = (/i, j/)
371 44707 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
372 44707 : IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
373 44707 : IF (dest*local_z_dim .LE. m2) THEN
374 44707 : IF ((dest + 1)*local_z_dim .LE. m2) THEN
375 40314 : 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 44707 : lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
386 44707 : loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
387 89414 : IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
388 44707 : scount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*loz)
389 961502 : DO k = lox(1) - min_x(1) + 1, lox(2) - min_x(1) + 1
390 33352181 : DO l = loy(1) - min_y(1) + 1, loy(2) - min_y(1) + 1
391 927368550 : DO m = 1, loz
392 894061076 : sbuf(ii) = wavelet%rho_z_sliced(k, l, m)
393 926451755 : 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 32035 : sdispl(1) = 0
403 32035 : rdispl(1) = 0
404 44707 : DO i = 2, nproc
405 12672 : sdispl(i) = sdispl(i - 1) + scount(i - 1)
406 44707 : rdispl(i) = rdispl(i - 1) + rcount(i - 1)
407 : END DO
408 2701906750 : 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 76742 : DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
413 121449 : DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
414 134121 : cart_pos = (/i, j/)
415 44707 : CALL pw_grid%para%group%rank_cart(cart_pos, dest)
416 89414 : IF (dest*local_z_dim .LE. m2) THEN
417 44707 : 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 44707 : ii = 1
423 44707 : IF (lb(3) + (dest*local_z_dim) .LE. ub(3)) THEN
424 961502 : DO m = lb(1), ub(1)
425 33352181 : DO l = lb(2), ub(2)
426 927368550 : DO k = lb(3) + (dest*local_z_dim), lb(3) + (dest*local_z_dim) + loz - 1
427 894061076 : density%array(m, l, k) = rbuf(ii + rdispl(dest + 1))
428 926451755 : 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 32035 : DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
437 :
438 32035 : END SUBROUTINE z_slices_to_cp2k_distribution
439 :
440 : ! **************************************************************************************************
441 : !> \brief ...
442 : !> \param wavelet ...
443 : !> \param pw_grid ...
444 : ! **************************************************************************************************
445 32035 : 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 32035 : CALL timeset(routineN, handle)
457 96105 : nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
458 32035 : iproc = pw_grid%para%group%mepos
459 32035 : geocode = wavelet%geocode
460 32035 : nx = pw_grid%npts(1)
461 32035 : ny = pw_grid%npts(2)
462 32035 : nz = pw_grid%npts(3)
463 32035 : hx = pw_grid%dr(1)
464 32035 : hy = pw_grid%dr(2)
465 32035 : hz = pw_grid%dr(3)
466 :
467 : CALL PSolver(geocode, iproc, nproc, nx, ny, nz, hx, hy, hz, &
468 32035 : wavelet%rho_z_sliced, wavelet%karray, pw_grid)
469 32035 : CALL timestop(handle)
470 32035 : END SUBROUTINE ps_wavelet_solve
471 :
472 : END MODULE ps_wavelet_methods
|