36 #include "../base/base_uses.f90"
41 LOGICAL,
PRIVATE,
PARAMETER :: debug_this_module = .true.
42 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'pw_spline_utils'
52 (/125._dp/216._dp, 25._dp/432._dp, 5._dp/864._dp, 1._dp/1728._dp/), &
54 (/8._dp/(27._dp), 2._dp/(27._dp), 1._dp/(27._dp*2._dp), &
55 1._dp/(27._dp*8._dp)/), &
57 (/27._dp/(64._dp), 9._dp/(64._dp*2_dp), 3._dp/(64._dp*4._dp), &
58 1._dp/(64._dp*8._dp)/), &
60 (/15625._dp/17576._dp, 625._dp/35152._dp, 25._dp/70304._dp, &
63 (/46._dp/27._dp, -2._dp/(27._dp), -1._dp/(27._dp*2._dp), &
64 -1._dp/(27._dp*8._dp)/), &
66 (/64._dp/3._dp, -8._dp/3._dp, -1._dp/3._dp, -1._dp/24._dp/), &
68 (/2._dp/3._dp, 23._dp/48._dp, 1._dp/6._dp, 1._dp/48._dp/)
71 (/2.0_dp/9.0_dp, 1.0_dp/18.0_dp, 1.0_dp/72.0_dp/), &
73 (/9.0_dp/32.0_dp, 3.0_dp/64.0_dp, 1.0_dp/128.0_dp/), &
75 (/25._dp/72._dp, 5._dp/144, 1._dp/288._dp/), &
77 (/625._dp/1352._dp, 25._dp/2704._dp, 1._dp/5408._dp/), &
79 (/1._dp/6_dp, 2._dp/3._dp, 1._dp/6._dp/), &
81 (/0.517977704_dp, 0.464044595_dp, 0.17977701e-1_dp/)
96 pw_spline_precond_type, &
107 TYPE pw_spline_precond_type
109 REAL(kind=
dp),
DIMENSION(4) :: coeffs = 0.0_dp
110 REAL(kind=
dp),
DIMENSION(3) :: coeffs_1d = 0.0_dp
111 LOGICAL :: sharpen = .false., normalize = .false.,
pbc = .false., transpose = .false.
112 TYPE(pw_pool_type),
POINTER :: pool => null()
113 END TYPE pw_spline_precond_type
129 TYPE(pw_c1d_gs_type),
INTENT(IN) :: spline_g
131 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_spline2_interpolate_values_g'
133 INTEGER :: handle, i, ii, j, k
134 INTEGER,
DIMENSION(2, 3) :: gbo
135 INTEGER,
DIMENSION(3) :: n_tot
136 REAL(kind=
dp) :: c23, coeff
137 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cosivals, cosjvals, coskvals
139 CALL timeset(routinen, handle)
141 n_tot(1:3) = spline_g%pw_grid%npts(1:3)
142 gbo = spline_g%pw_grid%bounds
144 cpassert(.NOT. spline_g%pw_grid%spherical)
145 cpassert(spline_g%pw_grid%grid_span ==
fullspace)
147 ALLOCATE (cosivals(gbo(1, 1):gbo(2, 1)), cosjvals(gbo(1, 2):gbo(2, 2)), &
148 coskvals(gbo(1, 3):gbo(2, 3)))
150 coeff =
twopi/n_tot(1)
152 DO i = gbo(1, 1), gbo(2, 1)
153 cosivals(i) = cos(coeff*real(i,
dp))
155 coeff =
twopi/n_tot(2)
157 DO j = gbo(1, 2), gbo(2, 2)
158 cosjvals(j) = cos(coeff*real(j,
dp))
160 coeff =
twopi/n_tot(3)
162 DO k = gbo(1, 3), gbo(2, 3)
163 coskvals(k) = cos(coeff*real(k,
dp))
167 DO ii = 1,
SIZE(spline_g%array)
168 i = spline_g%pw_grid%g_hat(1, ii)
169 j = spline_g%pw_grid%g_hat(2, ii)
170 k = spline_g%pw_grid%g_hat(3, ii)
172 c23 = cosjvals(j)*coskvals(k)
173 coeff = 64.0_dp/(cosivals(i)*c23 + &
174 (cosivals(i)*cosjvals(j) + cosivals(i)*coskvals(k) + c23)*3.0_dp + &
175 (cosivals(i) + cosjvals(j) + coskvals(k))*9.0_dp + &
178 spline_g%array(ii) = spline_g%array(ii)*coeff
181 DEALLOCATE (cosivals, cosjvals, coskvals)
183 CALL timestop(handle)
200 TYPE(pw_c1d_gs_type),
INTENT(IN) :: spline_g
202 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_spline3_interpolate_values_g'
204 INTEGER :: handle, i, ii, j, k
205 INTEGER,
DIMENSION(2, 3) :: gbo
206 INTEGER,
DIMENSION(3) :: n_tot
207 REAL(kind=
dp) :: c23, coeff
208 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cosivals, cosjvals, coskvals
210 CALL timeset(routinen, handle)
212 n_tot(1:3) = spline_g%pw_grid%npts(1:3)
213 gbo = spline_g%pw_grid%bounds
215 cpassert(.NOT. spline_g%pw_grid%spherical)
216 cpassert(spline_g%pw_grid%grid_span ==
fullspace)
218 ALLOCATE (cosivals(gbo(1, 1):gbo(2, 1)), &
219 cosjvals(gbo(1, 2):gbo(2, 2)), &
220 coskvals(gbo(1, 3):gbo(2, 3)))
222 coeff =
twopi/n_tot(1)
224 DO i = gbo(1, 1), gbo(2, 1)
225 cosivals(i) = cos(coeff*real(i,
dp))
227 coeff =
twopi/n_tot(2)
229 DO j = gbo(1, 2), gbo(2, 2)
230 cosjvals(j) = cos(coeff*real(j,
dp))
232 coeff =
twopi/n_tot(3)
234 DO k = gbo(1, 3), gbo(2, 3)
235 coskvals(k) = cos(coeff*real(k,
dp))
239 DO ii = 1,
SIZE(spline_g%array)
240 i = spline_g%pw_grid%g_hat(1, ii)
241 j = spline_g%pw_grid%g_hat(2, ii)
242 k = spline_g%pw_grid%g_hat(3, ii)
250 c23 = cosjvals(j)*coskvals(k)
251 coeff = 27.0_dp/(cosivals(i)*c23 + &
252 (cosivals(i)*cosjvals(j) + cosivals(i)*coskvals(k) + c23)*2.0_dp + &
253 (cosivals(i) + cosjvals(j) + coskvals(k))*4.0_dp + &
256 spline_g%array(ii) = spline_g%array(ii)*coeff
259 DEALLOCATE (cosivals, cosjvals, coskvals)
261 CALL timestop(handle)
275 TYPE(pw_r3d_rs_type),
DIMENSION(3),
INTENT(IN) :: deriv_vals_r
276 LOGICAL,
INTENT(in),
OPTIONAL :: transpose
277 REAL(kind=
dp),
INTENT(in),
OPTIONAL :: scale
279 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_spline_scale_deriv'
281 INTEGER :: handle, i, idir, j, k
282 INTEGER,
DIMENSION(2, 3) :: bo
283 INTEGER,
DIMENSION(3) :: n_tot
284 LOGICAL :: diag, my_transpose
285 REAL(kind=
dp) :: dval1, dval2, dval3, my_scale, scalef
286 REAL(kind=
dp),
DIMENSION(3, 3) :: dh_inv, h_grid
287 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: ddata, ddata2, ddata3
289 CALL timeset(routinen, handle)
291 my_transpose = .false.
292 IF (
PRESENT(transpose)) my_transpose = transpose
294 IF (
PRESENT(scale)) my_scale = scale
295 n_tot(1:3) = deriv_vals_r(1)%pw_grid%npts(1:3)
296 bo = deriv_vals_r(1)%pw_grid%bounds_local
297 dh_inv = deriv_vals_r(1)%pw_grid%dh_inv
301 IF (my_transpose)
THEN
304 h_grid(j, i) = my_scale*dh_inv(i, j)
305 IF (i /= j .AND. h_grid(j, i) /= 0.0_dp) diag = .false.
311 h_grid(i, j) = my_scale*dh_inv(i, j)
312 IF (i /= j .AND. h_grid(i, j) /= 0.0_dp) diag = .false.
319 ddata => deriv_vals_r(idir)%array
320 scalef = h_grid(idir, idir)
321 CALL dscal((bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1), &
325 ddata => deriv_vals_r(1)%array
326 ddata2 => deriv_vals_r(2)%array
327 ddata3 => deriv_vals_r(3)%array
330 DO k = bo(1, 3), bo(2, 3)
331 DO j = bo(1, 2), bo(2, 2)
332 DO i = bo(1, 1), bo(2, 1)
334 dval1 = ddata(i, j, k)
335 dval2 = ddata2(i, j, k)
336 dval3 = ddata3(i, j, k)
338 ddata(i, j, k) = h_grid(1, 1)*dval1 + &
339 h_grid(2, 1)*dval2 + h_grid(3, 1)*dval3
340 ddata2(i, j, k) = h_grid(1, 2)*dval1 + &
341 h_grid(2, 2)*dval2 + h_grid(3, 2)*dval3
342 ddata3(i, j, k) = h_grid(1, 3)*dval1 + &
343 h_grid(2, 3)*dval2 + h_grid(3, 3)*dval3
350 CALL timestop(handle)
366 TYPE(pw_c1d_gs_type),
INTENT(IN) :: spline_g
367 INTEGER,
INTENT(in) :: idir
369 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_spline3_deriv_g'
370 REAL(kind=
dp),
PARAMETER :: inv9 = 1.0_dp/9.0_dp
372 INTEGER :: handle, i, ii, j, k
373 INTEGER,
DIMENSION(2, 3) :: bo, gbo
374 INTEGER,
DIMENSION(3) :: n, n_tot
375 REAL(kind=
dp) :: coeff, tmp
376 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: csivals, csjvals, cskvals
378 CALL timeset(routinen, handle)
380 n(1:3) = spline_g%pw_grid%npts_local(1:3)
381 n_tot(1:3) = spline_g%pw_grid%npts(1:3)
382 bo = spline_g%pw_grid%bounds_local
383 gbo = spline_g%pw_grid%bounds
385 cpassert(.NOT. spline_g%pw_grid%spherical)
386 cpassert(spline_g%pw_grid%grid_span ==
fullspace)
388 ALLOCATE (csivals(gbo(1, 1):gbo(2, 1)), &
389 csjvals(gbo(1, 2):gbo(2, 2)), &
390 cskvals(gbo(1, 3):gbo(2, 3)))
392 coeff =
twopi/n_tot(1)
395 DO i = gbo(1, 1), gbo(2, 1)
396 csivals(i) = sin(coeff*real(i,
dp))
400 DO i = gbo(1, 1), gbo(2, 1)
401 csivals(i) = cos(coeff*real(i,
dp))
404 coeff =
twopi/n_tot(2)
407 DO j = gbo(1, 2), gbo(2, 2)
408 csjvals(j) = sin(coeff*real(j,
dp))
412 DO j = gbo(1, 2), gbo(2, 2)
413 csjvals(j) = cos(coeff*real(j,
dp))
416 coeff =
twopi/n_tot(3)
419 DO k = gbo(1, 3), gbo(2, 3)
420 cskvals(k) = sin(coeff*real(k,
dp))
424 DO k = gbo(1, 3), gbo(2, 3)
425 cskvals(k) = cos(coeff*real(k,
dp))
433 DO ii = 1,
SIZE(spline_g%array)
434 i = spline_g%pw_grid%g_hat(1, ii)
435 j = spline_g%pw_grid%g_hat(2, ii)
436 k = spline_g%pw_grid%g_hat(3, ii)
441 tmp = csivals(i)*csjvals(j)
442 coeff = (tmp*cskvals(k) + &
443 (tmp + csivals(i)*cskvals(k))*2.0_dp + &
444 csivals(i)*4.0_dp)*inv9
446 spline_g%array(ii) = spline_g%array(ii)* &
447 cmplx(0.0_dp, coeff,
dp)
452 DO ii = 1,
SIZE(spline_g%array)
453 i = spline_g%pw_grid%g_hat(1, ii)
454 j = spline_g%pw_grid%g_hat(2, ii)
455 k = spline_g%pw_grid%g_hat(3, ii)
457 tmp = csivals(i)*csjvals(j)
458 coeff = (tmp*cskvals(k) + &
459 (tmp + csjvals(j)*cskvals(k))*2.0_dp + &
460 csjvals(j)*4.0_dp)*inv9
462 spline_g%array(ii) = spline_g%array(ii)* &
463 cmplx(0.0_dp, coeff,
dp)
468 DO ii = 1,
SIZE(spline_g%array)
469 i = spline_g%pw_grid%g_hat(1, ii)
470 j = spline_g%pw_grid%g_hat(2, ii)
471 k = spline_g%pw_grid%g_hat(3, ii)
473 tmp = csivals(i)*cskvals(k)
474 coeff = (tmp*csjvals(j) + &
475 (tmp + csjvals(j)*cskvals(k))*2.0_dp + &
476 cskvals(k)*4.0_dp)*inv9
478 spline_g%array(ii) = spline_g%array(ii)* &
479 cmplx(0.0_dp, coeff,
dp)
483 DEALLOCATE (csivals, csjvals, cskvals)
485 CALL timestop(handle)
501 TYPE(pw_c1d_gs_type),
INTENT(IN) :: spline_g
502 INTEGER,
INTENT(in) :: idir
504 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_spline2_deriv_g'
505 REAL(kind=
dp),
PARAMETER :: inv16 = 1.0_dp/16.0_dp
507 INTEGER :: handle, i, ii, j, k
508 INTEGER,
DIMENSION(2, 3) :: bo
509 INTEGER,
DIMENSION(3) :: n, n_tot
510 REAL(kind=
dp) :: coeff, tmp
511 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: csivals, csjvals, cskvals
513 CALL timeset(routinen, handle)
515 n(1:3) = spline_g%pw_grid%npts_local(1:3)
516 n_tot(1:3) = spline_g%pw_grid%npts(1:3)
517 bo = spline_g%pw_grid%bounds
519 cpassert(.NOT. spline_g%pw_grid%spherical)
520 cpassert(spline_g%pw_grid%grid_span ==
fullspace)
522 ALLOCATE (csivals(bo(1, 1):bo(2, 1)), csjvals(bo(1, 2):bo(2, 2)), &
523 cskvals(bo(1, 3):bo(2, 3)))
525 coeff =
twopi/n_tot(1)
528 DO i = bo(1, 1), bo(2, 1)
529 csivals(i) = sin(coeff*real(i,
dp))
533 DO i = bo(1, 1), bo(2, 1)
534 csivals(i) = cos(coeff*real(i,
dp))
537 coeff =
twopi/n_tot(2)
540 DO j = bo(1, 2), bo(2, 2)
541 csjvals(j) = sin(coeff*real(j,
dp))
545 DO j = bo(1, 2), bo(2, 2)
546 csjvals(j) = cos(coeff*real(j,
dp))
549 coeff =
twopi/n_tot(3)
552 DO k = bo(1, 3), bo(2, 3)
553 cskvals(k) = sin(coeff*real(k,
dp))
557 DO k = bo(1, 3), bo(2, 3)
558 cskvals(k) = cos(coeff*real(k,
dp))
566 DO ii = 1,
SIZE(spline_g%array)
567 i = spline_g%pw_grid%g_hat(1, ii)
568 j = spline_g%pw_grid%g_hat(2, ii)
569 k = spline_g%pw_grid%g_hat(3, ii)
574 tmp = csivals(i)*csjvals(j)
575 coeff = (tmp*cskvals(k) + &
576 (tmp + csivals(i)*cskvals(k))*3.0_dp + &
577 csivals(i)*9.0_dp)*inv16
579 spline_g%array(ii) = spline_g%array(ii)* &
580 cmplx(0.0_dp, coeff,
dp)
585 DO ii = 1,
SIZE(spline_g%array)
586 i = spline_g%pw_grid%g_hat(1, ii)
587 j = spline_g%pw_grid%g_hat(2, ii)
588 k = spline_g%pw_grid%g_hat(3, ii)
590 tmp = csivals(i)*csjvals(j)
591 coeff = (tmp*cskvals(k) + &
592 (tmp + csjvals(j)*cskvals(k))*3.0_dp + &
593 csjvals(j)*9.0_dp)*inv16
595 spline_g%array(ii) = spline_g%array(ii)* &
596 cmplx(0.0_dp, coeff,
dp)
601 DO ii = 1,
SIZE(spline_g%array)
602 i = spline_g%pw_grid%g_hat(1, ii)
603 j = spline_g%pw_grid%g_hat(2, ii)
604 k = spline_g%pw_grid%g_hat(3, ii)
606 tmp = csivals(i)*cskvals(k)
607 coeff = (tmp*csjvals(j) + &
608 (tmp + csjvals(j)*cskvals(k))*3.0_dp + &
609 cskvals(k)*9.0_dp)*inv16
611 spline_g%array(ii) = spline_g%array(ii)* &
612 cmplx(0.0_dp, coeff,
dp)
616 DEALLOCATE (csivals, csjvals, cskvals)
618 CALL timestop(handle)
636 SUBROUTINE pw_compose_stripe(weights, in_val, in_val_first, in_val_last, &
638 REAL(kind=
dp),
DIMENSION(0:2),
INTENT(in) :: weights
639 REAL(kind=
dp),
DIMENSION(*),
INTENT(in) :: in_val
640 REAL(kind=
dp),
INTENT(in) :: in_val_first, in_val_last
641 REAL(kind=
dp),
DIMENSION(*),
INTENT(inout) :: out_val
645 REAL(kind=
dp) :: v0, v1, v2
653 IF (weights(1) == 0.0_dp)
THEN
655 DO i = 1, n_el - 3, 3
657 out_val(i) = out_val(i) + &
661 out_val(i + 1) = out_val(i + 1) + &
665 out_val(i + 2) = out_val(i + 2) + &
671 DO i = 1, n_el - 3, 3
673 out_val(i) = out_val(i) + &
678 out_val(i + 1) = out_val(i + 1) + &
683 out_val(i + 2) = out_val(i + 2) + &
689 SELECT CASE (
modulo(n_el - 1, 3))
692 out_val(n_el) = out_val(n_el) + &
698 out_val(n_el - 1) = out_val(n_el - 1) + &
703 out_val(n_el) = out_val(n_el) + &
708 v2 = in_val(n_el - 1)
709 out_val(n_el - 2) = out_val(n_el - 2) + &
714 out_val(n_el - 1) = out_val(n_el - 1) + &
719 out_val(n_el) = out_val(n_el) + &
725 END SUBROUTINE pw_compose_stripe
739 SUBROUTINE pw_nn_compose_r_work(weights, in_val, out_val, pw_in, bo)
740 REAL(kind=
dp),
DIMENSION(0:2, 0:2, 0:2) :: weights
741 INTEGER,
DIMENSION(2, 3) :: bo
742 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in
743 REAL(kind=
dp),
DIMENSION(bo(1, 1):bo(2, 1), bo(1, &
2):bo(2, 2), bo(1, 3):bo(2, 3)),
INTENT(inout) :: out_val
744 REAL(kind=
dp),
DIMENSION(bo(1, 1):bo(2, 1), bo(1, &
2):bo(2, 2), bo(1, 3):bo(2, 3)),
INTENT(in) :: in_val
746 INTEGER :: i, j, jw, k, kw, myj, myk
747 INTEGER,
DIMENSION(2, 3) :: gbo
748 INTEGER,
DIMENSION(3) :: s
749 LOGICAL :: has_boundary, yderiv, zderiv
750 REAL(kind=
dp) :: in_val_f, in_val_l
751 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: l_boundary, tmp, u_boundary
753 zderiv = all(weights(:, :, 1) == 0.0_dp)
754 yderiv = all(weights(:, 1, :) == 0.0_dp)
755 bo = pw_in%pw_grid%bounds_local
756 gbo = pw_in%pw_grid%bounds
758 s(i) = bo(2, i) - bo(1, i) + 1
760 IF (any(s < 1))
RETURN
761 has_boundary = any(pw_in%pw_grid%bounds_local(:, 1) /= &
762 pw_in%pw_grid%bounds(:, 1))
763 IF (has_boundary)
THEN
764 ALLOCATE (l_boundary(bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)), &
765 u_boundary(bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)), &
766 tmp(bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
767 tmp(:, :) = pw_in%array(bo(2, 1), :, :)
768 CALL pw_in%pw_grid%para%group%sendrecv(tmp, pw_in%pw_grid%para%pos_of_x( &
769 gbo(1, 1) +
modulo(bo(2, 1) + 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)), &
770 l_boundary, pw_in%pw_grid%para%pos_of_x( &
771 gbo(1, 1) +
modulo(bo(1, 1) - 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)))
772 tmp(:, :) = pw_in%array(bo(1, 1), :, :)
773 CALL pw_in%pw_grid%para%group%sendrecv(tmp, pw_in%pw_grid%para%pos_of_x( &
774 gbo(1, 1) +
modulo(bo(1, 1) - 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)), &
775 u_boundary, pw_in%pw_grid%para%pos_of_x( &
776 gbo(1, 1) +
modulo(bo(2, 1) + 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)))
785 myk = bo(1, 3) +
modulo(k + kw - 1, s(3))
786 IF (zderiv .AND. kw == 1) cycle
789 myj = bo(1, 2) +
modulo(j + jw - 1, s(2))
790 IF (yderiv .AND. jw == 1) cycle
791 IF (has_boundary)
THEN
792 in_val_f = l_boundary(myj, myk)
793 in_val_l = u_boundary(myj, myk)
795 in_val_f = in_val(bo(2, 1), myj, myk)
796 in_val_l = in_val(bo(1, 1), myj, myk)
798 CALL pw_compose_stripe(weights=weights(:, jw, kw), &
799 in_val=in_val(:, myj, myk), &
800 in_val_first=in_val_f, in_val_last=in_val_l, &
801 out_val=out_val(:, bo(1, 2) + j, bo(1, 3) + k), n_el=s(1))
806 IF (has_boundary)
THEN
807 DEALLOCATE (l_boundary, u_boundary)
809 END SUBROUTINE pw_nn_compose_r_work
820 SUBROUTINE pw_nn_compose_r(weights, pw_in, pw_out)
821 REAL(kind=
dp),
DIMENSION(0:2, 0:2, 0:2) :: weights
822 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in, pw_out
824 CHARACTER(len=*),
PARAMETER :: routinen =
'pw_nn_compose_r'
828 CALL timeset(routinen, handle)
829 IF (.NOT. all(pw_in%pw_grid%bounds_local(:, 2:3) == pw_in%pw_grid%bounds(:, 2:3)))
THEN
830 cpabort(
"wrong pw distribution")
832 CALL pw_nn_compose_r_work(weights=weights, in_val=pw_in%array, &
833 out_val=pw_out%array, pw_in=pw_in, bo=pw_in%pw_grid%bounds_local)
834 CALL timestop(handle)
835 END SUBROUTINE pw_nn_compose_r
854 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in, pw_out
855 REAL(kind=
dp),
DIMENSION(4),
INTENT(in) :: coeffs
858 REAL(kind=
dp),
DIMENSION(-1:1, -1:1, -1:1) :: weights
863 weights(i, j, k) = coeffs(abs(i) + abs(j) + abs(k) + 1)
868 CALL pw_nn_compose_r(weights=weights, pw_in=pw_in, pw_out=pw_out)
897 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in, pw_out
898 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: coeffs
901 INTEGER :: i, idirval, j, k
902 REAL(kind=
dp),
DIMENSION(-1:1, -1:1, -1:1) :: weights
915 cpabort(
"invalid idir ("//trim(cp_to_string(idir))//
")")
917 IF (idirval == 0)
THEN
918 weights(i, j, k) = 0.0_dp
920 weights(i, j, k) = real(idirval,
dp)*coeffs(abs(i) + abs(j) + abs(k))
926 CALL pw_nn_compose_r(weights=weights, pw_in=pw_in, pw_out=pw_out)
974 weights_1d, w_border0, w_border1, pbc, safe_computation)
975 TYPE(pw_r3d_rs_type),
INTENT(IN) :: coarse_coeffs_pw, fine_values_pw
976 REAL(kind=
dp),
DIMENSION(4),
INTENT(in) :: weights_1d
977 REAL(kind=
dp),
INTENT(in) :: w_border0
978 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: w_border1
979 LOGICAL,
INTENT(in) ::
pbc
980 LOGICAL,
INTENT(in),
OPTIONAL :: safe_computation
982 CHARACTER(len=*),
PARAMETER :: routinen =
'add_coarse2fine'
984 INTEGER :: coarse_slice_size, f_shift(3), fi, fi_lb, fi_ub, fj, fk, handle, handle2, i, ii, &
985 ij, ik, ip, j, k, my_lb, my_ub, n_procs, p, p_lb, p_old, p_ub, rcv_tot_size, rest_b, &
986 s(3), send_tot_size, sf, shift, ss, x, x_att, xx
987 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: rcv_offset, rcv_size, real_rcv_size, &
988 send_offset, send_size, sent_size
989 INTEGER,
DIMENSION(2, 3) :: coarse_bo, coarse_gbo, fine_bo, &
990 fine_gbo, my_coarse_bo
991 INTEGER,
DIMENSION(:),
POINTER :: pos_of_x
992 LOGICAL :: has_i_lbound, has_i_ubound, is_split, &
994 REAL(kind=
dp) :: v0, v1, v2, v3, wi, wj, wk
995 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: rcv_buf, send_buf
996 REAL(kind=
dp),
DIMENSION(3) :: w_0, ww0
997 REAL(kind=
dp),
DIMENSION(4) :: w_1, ww1
998 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: coarse_coeffs, fine_values
1000 CALL timeset(routinen, handle)
1003 IF (
PRESENT(safe_computation)) safe_calc = safe_computation
1004 ii = coarse_coeffs_pw%pw_grid%para%group%compare(fine_values_pw%pw_grid%para%group)
1008 my_coarse_bo = coarse_coeffs_pw%pw_grid%bounds_local
1009 coarse_gbo = coarse_coeffs_pw%pw_grid%bounds
1010 fine_bo = fine_values_pw%pw_grid%bounds_local
1011 fine_gbo = fine_values_pw%pw_grid%bounds
1012 f_shift = fine_gbo(1, :) - 2*coarse_gbo(1, :)
1015 coarse_bo(i, j) = floor((fine_bo(i, j) - f_shift(j))/2.)
1018 IF (fine_bo(1, 1) <= fine_bo(2, 1))
THEN
1019 coarse_bo(1, 1) = floor((fine_bo(1, 1) - 2 - f_shift(1))/2.)
1020 coarse_bo(2, 1) = floor((fine_bo(2, 1) + 3 - f_shift(1))/2.)
1022 coarse_bo(1, 1) = coarse_gbo(2, 1)
1023 coarse_bo(2, 1) = coarse_gbo(2, 1) - 1
1025 is_split = any(coarse_gbo(:, 1) /= my_coarse_bo(:, 1))
1026 IF (.NOT. is_split .OR. .NOT.
pbc)
THEN
1027 coarse_bo(1, 1) = max(coarse_gbo(1, 1), coarse_bo(1, 1))
1028 coarse_bo(2, 1) = min(coarse_gbo(2, 1), coarse_bo(2, 1))
1030 has_i_ubound = (fine_gbo(2, 1) /= fine_bo(2, 1)) .OR.
pbc .AND. is_split
1031 has_i_lbound = (fine_gbo(1, 1) /= fine_bo(1, 1)) .OR.
pbc .AND. is_split
1034 cpassert(all(fine_gbo(1, :) == 2*coarse_gbo(1, :) + f_shift))
1035 cpassert(all(fine_gbo(2, :) == 2*coarse_gbo(2, :) + 1 + f_shift))
1037 cpassert(all(fine_gbo(2, :) == 2*coarse_gbo(2, :) + f_shift))
1038 cpassert(all(fine_gbo(1, :) == 2*coarse_gbo(1, :) + f_shift))
1041 coarse_coeffs => coarse_coeffs_pw%array
1043 s(i) = coarse_gbo(2, i) - coarse_gbo(1, i) + 1
1048 CALL timeset(routinen//
"_comm", handle2)
1049 coarse_slice_size = (coarse_bo(2, 2) - coarse_bo(1, 2) + 1)* &
1050 (coarse_bo(2, 3) - coarse_bo(1, 3) + 1)
1051 n_procs = coarse_coeffs_pw%pw_grid%para%group_size
1052 ALLOCATE (send_size(0:n_procs - 1), send_offset(0:n_procs - 1), &
1053 sent_size(0:n_procs - 1), rcv_size(0:n_procs - 1), &
1054 rcv_offset(0:n_procs - 1), real_rcv_size(0:n_procs - 1))
1058 pos_of_x => coarse_coeffs_pw%pw_grid%para%pos_of_x
1059 p_old = pos_of_x(coarse_gbo(1, 1) &
1060 +
modulo(coarse_bo(1, 1) - coarse_gbo(1, 1), s(1)))
1062 DO x = coarse_bo(1, 1), coarse_bo(2, 1)
1063 p = pos_of_x(coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1)))
1064 rcv_size(p) = rcv_size(p) + coarse_slice_size
1069 pos_of_x => fine_values_pw%pw_grid%para%pos_of_x
1070 sf = fine_gbo(2, 1) - fine_gbo(1, 1) + 1
1071 fi_lb = 2*my_coarse_bo(1, 1) - 3 + f_shift(1)
1072 fi_ub = 2*my_coarse_bo(2, 1) + 3 + f_shift(1)
1074 fi_lb = max(fi_lb, fine_gbo(1, 1))
1075 fi_ub = min(fi_ub, fine_gbo(2, 1))
1077 fi_ub = min(fi_ub, fi_lb + sf - 1)
1079 p_old = pos_of_x(fine_gbo(1, 1) +
modulo(fi_lb - fine_gbo(1, 1), sf))
1080 p_lb = floor((fi_lb - 2 - f_shift(1))/2.)
1083 p = pos_of_x(fine_gbo(1, 1) +
modulo(x - fine_gbo(1, 1), sf))
1084 IF (p /= p_old)
THEN
1085 p_ub = floor((x - 1 + 3 - f_shift(1))/2.)
1087 send_size(p_old) = send_size(p_old) + (min(p_ub, my_coarse_bo(2, 1)) &
1088 - max(p_lb, my_coarse_bo(1, 1)) + 1)*coarse_slice_size
1091 DO xx = p_lb, coarse_gbo(1, 1) - 1
1092 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), s(1))
1093 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1094 send_size(p_old) = send_size(p_old) + coarse_slice_size
1097 DO xx = coarse_gbo(2, 1) + 1, p_ub
1098 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), s(1))
1099 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1100 send_size(p_old) = send_size(p_old) + coarse_slice_size
1106 p_lb = floor((x - 2 - f_shift(1))/2.)
1109 p_ub = floor((fi_ub + 3 - f_shift(1))/2.)
1111 send_size(p_old) = send_size(p_old) + (min(p_ub, my_coarse_bo(2, 1)) &
1112 - max(p_lb, my_coarse_bo(1, 1)) + 1)*coarse_slice_size
1115 DO xx = p_lb, coarse_gbo(1, 1) - 1
1116 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), s(1))
1117 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1118 send_size(p_old) = send_size(p_old) + coarse_slice_size
1121 DO xx = coarse_gbo(2, 1) + 1, p_ub
1122 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), s(1))
1123 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1124 send_size(p_old) = send_size(p_old) + coarse_slice_size
1131 DO ip = 0, n_procs - 1
1132 send_offset(ip) = send_tot_size
1133 send_tot_size = send_tot_size + send_size(ip)
1135 ALLOCATE (send_buf(0:send_tot_size - 1))
1138 DO ip = 0, n_procs - 1
1139 rcv_offset(ip) = rcv_tot_size
1140 rcv_tot_size = rcv_tot_size + rcv_size(ip)
1142 IF (.NOT. rcv_tot_size == (coarse_bo(2, 1) - coarse_bo(1, 1) + 1)*coarse_slice_size)
THEN
1143 cpabort(
"Error calculating rcv_tot_size ")
1145 ALLOCATE (rcv_buf(0:rcv_tot_size - 1))
1149 p_old = pos_of_x(fine_gbo(1, 1) +
modulo(fi_lb - fine_gbo(1, 1), sf))
1150 p_lb = floor((fi_lb - 2 - f_shift(1))/2.)
1151 sent_size(:) = send_offset
1152 ss = my_coarse_bo(2, 1) - my_coarse_bo(1, 1) + 1
1154 p = pos_of_x(fine_gbo(1, 1) +
modulo(x - fine_gbo(1, 1), sf))
1155 IF (p /= p_old)
THEN
1156 shift = floor((fine_gbo(1, 1) +
modulo(x - 1 - fine_gbo(1, 1), sf) - f_shift(1))/2._dp) - &
1157 floor((x - 1 - f_shift(1))/2._dp)
1158 p_ub = floor((x - 1 + 3 - f_shift(1))/2._dp)
1161 DO xx = p_lb + shift, coarse_gbo(1, 1) - 1
1162 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), sf)
1163 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1164 CALL dcopy(coarse_slice_size, &
1165 coarse_coeffs(x_att, my_coarse_bo(1, 2), &
1166 my_coarse_bo(1, 3)), ss, send_buf(sent_size(p_old)), 1)
1167 sent_size(p_old) = sent_size(p_old) + coarse_slice_size
1172 ii = sent_size(p_old)
1173 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
1174 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
1175 DO i = max(p_lb + shift, my_coarse_bo(1, 1)), min(p_ub + shift, my_coarse_bo(2, 1))
1176 send_buf(ii) = coarse_coeffs(i, j, k)
1181 sent_size(p_old) = ii
1184 DO xx = coarse_gbo(2, 1) + 1, p_ub + shift
1185 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), s(1))
1186 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1187 CALL dcopy(coarse_slice_size, &
1188 coarse_coeffs(x_att, my_coarse_bo(1, 2), &
1189 my_coarse_bo(1, 3)), ss, &
1190 send_buf(sent_size(p_old)), 1)
1191 sent_size(p_old) = sent_size(p_old) + coarse_slice_size
1197 p_lb = floor((x - 2 - f_shift(1))/2.)
1200 shift = floor((fine_gbo(1, 1) +
modulo(x - 1 - fine_gbo(1, 1), sf) - f_shift(1))/2._dp) - &
1201 floor((x - 1 - f_shift(1))/2._dp)
1202 p_ub = floor((fi_ub + 3 - f_shift(1))/2.)
1205 DO xx = p_lb + shift, coarse_gbo(1, 1) - 1
1206 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), s(1))
1207 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1208 CALL dcopy(coarse_slice_size, &
1209 coarse_coeffs(x_att, my_coarse_bo(1, 2), &
1210 my_coarse_bo(1, 3)), ss, send_buf(sent_size(p_old)), 1)
1211 sent_size(p_old) = sent_size(p_old) + coarse_slice_size
1216 ii = sent_size(p_old)
1217 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
1218 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
1219 DO i = max(p_lb + shift, my_coarse_bo(1, 1)), min(p_ub + shift, my_coarse_bo(2, 1))
1220 send_buf(ii) = coarse_coeffs(i, j, k)
1225 sent_size(p_old) = ii
1228 DO xx = coarse_gbo(2, 1) + 1, p_ub + shift
1229 x_att = coarse_gbo(1, 1) +
modulo(xx - coarse_gbo(1, 1), s(1))
1230 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
1231 CALL dcopy(coarse_slice_size, &
1232 coarse_coeffs(x_att, my_coarse_bo(1, 2), &
1233 my_coarse_bo(1, 3)), ss, send_buf(sent_size(p_old)), 1)
1234 sent_size(p_old) = sent_size(p_old) + coarse_slice_size
1239 cpassert(all(sent_size(:n_procs - 2) == send_offset(1:)))
1240 cpassert(sent_size(n_procs - 1) == send_tot_size)
1242 CALL coarse_coeffs_pw%pw_grid%para%group%alltoall(send_size, real_rcv_size, 1)
1243 cpassert(all(real_rcv_size == rcv_size))
1245 CALL coarse_coeffs_pw%pw_grid%para%group%alltoall(sb=send_buf, scount=send_size, sdispl=send_offset, &
1246 rb=rcv_buf, rcount=rcv_size, rdispl=rcv_offset)
1251 ALLOCATE (coarse_coeffs(coarse_bo(1, 1):coarse_bo(2, 1), &
1252 coarse_bo(1, 2):coarse_bo(2, 2), &
1253 coarse_bo(1, 3):coarse_bo(2, 3)))
1255 my_lb = max(coarse_gbo(1, 1), coarse_bo(1, 1))
1256 my_ub = min(coarse_gbo(2, 1), coarse_bo(2, 1))
1257 pos_of_x => coarse_coeffs_pw%pw_grid%para%pos_of_x
1258 sent_size(:) = rcv_offset
1259 ss = coarse_bo(2, 1) - coarse_bo(1, 1) + 1
1260 DO x = my_ub + 1, coarse_bo(2, 1)
1261 p_old = pos_of_x(coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1)))
1262 CALL dcopy(coarse_slice_size, &
1263 rcv_buf(sent_size(p_old)), 1, &
1264 coarse_coeffs(x, coarse_bo(1, 2), &
1265 coarse_bo(1, 3)), ss)
1266 sent_size(p_old) = sent_size(p_old) + coarse_slice_size
1268 p_old = pos_of_x(coarse_gbo(1, 1) &
1269 +
modulo(my_lb - coarse_gbo(1, 1), s(1)))
1272 p = pos_of_x(coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1)))
1273 IF (p /= p_old)
THEN
1276 ii = sent_size(p_old)
1277 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
1278 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
1280 coarse_coeffs(i, j, k) = rcv_buf(ii)
1285 sent_size(p_old) = ii
1290 rcv_size(p) = rcv_size(p) + coarse_slice_size
1293 ii = sent_size(p_old)
1294 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
1295 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
1297 coarse_coeffs(i, j, k) = rcv_buf(ii)
1302 sent_size(p_old) = ii
1303 DO x = coarse_bo(1, 1), my_lb - 1
1304 p_old = pos_of_x(coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1)))
1305 CALL dcopy(coarse_slice_size, &
1306 rcv_buf(sent_size(p_old)), 1, &
1307 coarse_coeffs(x, coarse_bo(1, 2), &
1308 coarse_bo(1, 3)), ss)
1309 sent_size(p_old) = sent_size(p_old) + coarse_slice_size
1312 cpassert(all(sent_size(0:n_procs - 2) == rcv_offset(1:)))
1313 cpassert(sent_size(n_procs - 1) == rcv_tot_size)
1316 DEALLOCATE (send_size, send_offset, rcv_size, rcv_offset)
1317 DEALLOCATE (send_buf, rcv_buf, real_rcv_size)
1318 CALL timestop(handle2)
1321 fine_values => fine_values_pw%array
1322 w_0 = (/weights_1d(3), weights_1d(1), weights_1d(3)/)
1323 w_1 = (/weights_1d(4), weights_1d(2), weights_1d(2), weights_1d(4)/)
1325 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
1328 wk = weights_1d(abs(ik) + 1)
1329 fk = fine_gbo(1, 3) +
modulo(2*k + ik - fine_gbo(1, 3) + f_shift(3), 2*s(3))
1331 fk = 2*k + ik + f_shift(3)
1332 IF (fk <= fine_bo(1, 3) + 1 .OR. fk >= fine_bo(2, 3) - 1)
THEN
1333 IF (fk < fine_bo(1, 3) .OR. fk > fine_bo(2, 3)) cycle
1334 IF (fk == fine_bo(1, 3) .OR. fk == fine_bo(2, 3))
THEN
1337 ELSE IF (fk == 2*coarse_bo(1, 3) + 1 + f_shift(3))
THEN
1363 wk = weights_1d(abs(ik) + 1)
1366 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
1369 wj = weights_1d(abs(ij) + 1)*wk
1370 fj = fine_gbo(1, 2) +
modulo(2*j + ij - fine_gbo(1, 2) + f_shift(2), 2*s(2))
1372 fj = 2*j + ij + f_shift(2)
1373 IF (fj <= fine_bo(1, 2) + 1 .OR. fj >= fine_bo(2, 2) - 1)
THEN
1374 IF (fj < fine_bo(1, 2) .OR. fj > fine_bo(2, 2)) cycle
1375 IF (fj == fine_bo(1, 2) .OR. fj == fine_bo(2, 2))
THEN
1378 ELSE IF (fj == 2*coarse_bo(1, 2) + 1 + f_shift(2))
THEN
1381 wj = w_border1(1)*wk
1383 wj = w_border1(2)*wk
1385 wj = w_border1(3)*wk
1392 wj = w_border1(1)*wk
1394 wj = w_border1(2)*wk
1396 wj = w_border1(3)*wk
1402 wj = weights_1d(abs(ij) + 1)*wk
1406 IF (fine_bo(2, 1) - fine_bo(1, 1) < 7 .OR. safe_calc)
THEN
1408 DO i = coarse_bo(1, 1), coarse_bo(2, 1)
1410 IF (
pbc .AND. .NOT. is_split)
THEN
1411 wi = weights_1d(abs(ii) + 1)*wj
1412 fi = fine_gbo(1, 1) +
modulo(2*i + ii - fine_gbo(1, 1) + f_shift(1), 2*s(1))
1414 fi = 2*i + ii + f_shift(1)
1415 IF (fi < fine_bo(1, 1) .OR. fi > fine_bo(2, 1)) cycle
1416 IF (.NOT.
pbc .AND. (fi <= fine_gbo(1, 1) + 1 .OR. &
1417 fi >= fine_gbo(2, 1) - 1))
THEN
1418 IF (fi == fine_gbo(1, 1) .OR. fi == fine_gbo(2, 1))
THEN
1421 ELSE IF (fi == fine_gbo(1, 1) + 1)
THEN
1424 wi = w_border1(1)*wj
1426 wi = w_border1(2)*wj
1428 wi = w_border1(3)*wj
1435 wi = w_border1(1)*wj
1437 wi = w_border1(2)*wj
1439 wi = w_border1(3)*wj
1445 wi = weights_1d(abs(ii) + 1)*wj
1448 fine_values(fi, fj, fk) = &
1449 fine_values(fi, fj, fk) + &
1450 wi*coarse_coeffs(i, j, k)
1458 IF (
pbc .AND. .NOT. is_split)
THEN
1459 v3 = coarse_coeffs(coarse_bo(2, 1), j, k)
1461 fi = 2*i + f_shift(1)
1462 v0 = coarse_coeffs(i, j, k)
1463 v1 = coarse_coeffs(i + 1, j, k)
1464 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1465 ww0(1)*v3 + ww0(2)*v0 + ww0(3)*v1
1466 v2 = coarse_coeffs(i + 2, j, k)
1468 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1469 ww1(1)*v3 + ww1(2)*v0 + ww1(3)*v1 + ww1(4)*v2
1470 ELSE IF (.NOT. has_i_lbound)
THEN
1472 fi = 2*i + f_shift(1)
1473 v0 = coarse_coeffs(i, j, k)
1474 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1476 v1 = coarse_coeffs(i + 1, j, k)
1477 v2 = coarse_coeffs(i + 2, j, k)
1479 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1480 wj*(w_border1(1)*v0 + w_border1(2)*v1 + &
1484 v0 = coarse_coeffs(i, j, k)
1485 v1 = coarse_coeffs(i + 1, j, k)
1486 v2 = coarse_coeffs(i + 2, j, k)
1487 fi = 2*i + f_shift(1) + 1
1488 IF (.NOT. (fi + 1 == fine_bo(1, 1) .OR. &
1489 fi + 2 == fine_bo(1, 1)))
THEN
1490 CALL cp_abort(__location__, &
1491 "unexpected start index "// &
1492 trim(cp_to_string(coarse_bo(1, 1)))//
" "// &
1493 trim(cp_to_string(fi)))
1497 IF (fi >= fine_bo(1, 1))
THEN
1498 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1499 ww0(1)*v0 + ww0(2)*v1 + &
1502 cpassert(fi + 1 == fine_bo(1, 1))
1506 DO i = coarse_bo(1, 1) + 3, floor((fine_bo(2, 1) - f_shift(1))/2.) - 3, 4
1507 v3 = coarse_coeffs(i, j, k)
1509 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1510 (ww1(1)*v0 + ww1(2)*v1 + &
1511 ww1(3)*v2 + ww1(4)*v3)
1513 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1514 (ww0(1)*v1 + ww0(2)*v2 + &
1516 v0 = coarse_coeffs(i + 1, j, k)
1518 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1519 (ww1(4)*v0 + ww1(1)*v1 + &
1520 ww1(2)*v2 + ww1(3)*v3)
1522 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1523 (ww0(1)*v2 + ww0(2)*v3 + &
1525 v1 = coarse_coeffs(i + 2, j, k)
1527 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1528 (ww1(3)*v0 + ww1(4)*v1 + &
1529 ww1(1)*v2 + ww1(2)*v3)
1531 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1532 (ww0(1)*v3 + ww0(2)*v0 + &
1534 v2 = coarse_coeffs(i + 3, j, k)
1536 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1537 (ww1(2)*v0 + ww1(3)*v1 + &
1538 ww1(4)*v2 + ww1(1)*v3)
1540 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1541 (ww0(1)*v0 + ww0(2)*v1 + &
1546 rest_b =
modulo(floor((fine_bo(2, 1) - f_shift(1))/2.) - coarse_bo(1, 1) - 3 + 1, 4)
1547 IF (rest_b > 0)
THEN
1548 i = floor((fine_bo(2, 1) - f_shift(1))/2.) - rest_b + 1
1549 v3 = coarse_coeffs(i, j, k)
1551 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1552 (ww1(1)*v0 + ww1(2)*v1 + &
1553 ww1(3)*v2 + ww1(4)*v3)
1555 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1556 (ww0(1)*v1 + ww0(2)*v2 + &
1558 IF (rest_b > 1)
THEN
1559 v0 = coarse_coeffs(i + 1, j, k)
1561 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1562 (ww1(4)*v0 + ww1(1)*v1 + &
1563 ww1(2)*v2 + ww1(3)*v3)
1565 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1566 (ww0(1)*v2 + ww0(2)*v3 + &
1568 IF (rest_b > 2)
THEN
1569 v1 = coarse_coeffs(i + 2, j, k)
1571 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1572 (ww1(3)*v0 + ww1(4)*v1 + &
1573 ww1(1)*v2 + ww1(2)*v3)
1575 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1576 (ww0(1)*v3 + ww0(2)*v0 + &
1578 IF (
pbc .AND. .NOT. is_split)
THEN
1579 v2 = coarse_coeffs(coarse_bo(1, 1), j, k)
1581 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1582 ww1(1)*v3 + ww1(2)*v0 + ww1(3)*v1 + ww1(4)*v2
1584 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1585 ww0(1)*v0 + ww0(2)*v1 + ww0(3)*v2
1586 v3 = coarse_coeffs(coarse_bo(1, 1) + 1, j, k)
1588 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1589 ww1(1)*v0 + ww1(2)*v1 + ww1(3)*v2 + ww1(4)*v3
1590 ELSE IF (has_i_ubound)
THEN
1591 v2 = coarse_coeffs(i + 3, j, k)
1593 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1594 ww1(1)*v3 + ww1(2)*v0 + ww1(3)*v1 + ww1(4)*v2
1596 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1597 ww0(1)*v0 + ww0(2)*v1 + ww0(3)*v2
1598 IF (fi + 1 == fine_bo(2, 1))
THEN
1599 v3 = coarse_coeffs(i + 4, j, k)
1601 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1602 ww1(1)*v0 + ww1(2)*v1 + ww1(3)*v2 + ww1(4)*v3
1606 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1607 wj*(w_border1(3)*v3 + w_border1(2)*v0 + &
1610 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1613 ELSE IF (
pbc .AND. .NOT. is_split)
THEN
1614 v1 = coarse_coeffs(coarse_bo(1, 1), j, k)
1616 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1617 ww1(1)*v2 + ww1(2)*v3 + ww1(3)*v0 + ww1(4)*v1
1619 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1620 ww0(1)*v3 + ww0(2)*v0 + ww0(3)*v1
1621 v2 = coarse_coeffs(coarse_bo(1, 1) + 1, j, k)
1623 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1624 ww1(1)*v3 + ww1(2)*v0 + ww1(3)*v1 + ww1(4)*v2
1625 ELSE IF (has_i_ubound)
THEN
1626 v1 = coarse_coeffs(i + 2, j, k)
1628 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1629 ww1(1)*v2 + ww1(2)*v3 + ww1(3)*v0 + ww1(4)*v1
1631 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1632 ww0(1)*v3 + ww0(2)*v0 + ww0(3)*v1
1633 IF (fi + 1 == fine_bo(2, 1))
THEN
1634 v2 = coarse_coeffs(i + 3, j, k)
1636 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1637 ww1(1)*v3 + ww1(2)*v0 + ww1(3)*v1 + ww1(4)*v2
1641 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1642 wj*(w_border1(3)*v2 + w_border1(2)*v3 + &
1645 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1648 ELSE IF (
pbc .AND. .NOT. is_split)
THEN
1649 v0 = coarse_coeffs(coarse_bo(1, 1), j, k)
1651 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1652 ww1(1)*v1 + ww1(2)*v2 + ww1(3)*v3 + ww1(4)*v0
1654 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1655 ww0(1)*v2 + ww0(2)*v3 + ww0(3)*v0
1656 v1 = coarse_coeffs(coarse_bo(1, 1) + 1, j, k)
1658 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1659 ww1(1)*v2 + ww1(2)*v3 + ww1(3)*v0 + ww1(4)*v1
1660 ELSE IF (has_i_ubound)
THEN
1661 v0 = coarse_coeffs(i + 1, j, k)
1663 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1664 ww1(1)*v1 + ww1(2)*v2 + ww1(3)*v3 + ww1(4)*v0
1666 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1667 ww0(1)*v2 + ww0(2)*v3 + ww0(3)*v0
1668 IF (fi + 1 == fine_bo(2, 1))
THEN
1669 v1 = coarse_coeffs(i + 2, j, k)
1671 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1672 ww1(1)*v2 + ww1(2)*v3 + ww1(3)*v0 + ww1(4)*v1
1676 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1677 wj*(w_border1(3)*v1 + w_border1(2)*v2 + &
1680 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1683 ELSE IF (
pbc .AND. .NOT. is_split)
THEN
1684 v3 = coarse_coeffs(coarse_bo(1, 1), j, k)
1686 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1687 ww1(1)*v0 + ww1(2)*v1 + ww1(3)*v2 + ww1(4)*v3
1689 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1690 ww0(1)*v1 + ww0(2)*v2 + ww0(3)*v3
1691 v0 = coarse_coeffs(coarse_bo(1, 1) + 1, j, k)
1693 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1694 ww1(1)*v1 + ww1(2)*v2 + ww1(3)*v3 + ww1(4)*v0
1695 ELSE IF (has_i_ubound)
THEN
1696 v3 = coarse_coeffs(i, j, k)
1698 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1699 ww1(1)*v0 + ww1(2)*v1 + ww1(3)*v2 + ww1(4)*v3
1701 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1702 ww0(1)*v1 + ww0(2)*v2 + ww0(3)*v3
1703 IF (fi + 1 == fine_bo(2, 1))
THEN
1704 v0 = coarse_coeffs(i + 1, j, k)
1706 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1707 ww1(1)*v1 + ww1(2)*v2 + ww1(3)*v3 + ww1(4)*v0
1711 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1712 wj*(w_border1(3)*v0 + w_border1(2)*v1 + &
1715 fine_values(fi, fj, fk) = fine_values(fi, fj, fk) + &
1718 cpassert(fi == fine_bo(2, 1))
1727 DEALLOCATE (coarse_coeffs)
1729 CALL timestop(handle)
1769 weights_1d, w_border0, w_border1, pbc, safe_computation)
1770 TYPE(pw_r3d_rs_type),
INTENT(IN) :: fine_values_pw, coarse_coeffs_pw
1771 REAL(kind=
dp),
DIMENSION(4),
INTENT(in) :: weights_1d
1772 REAL(kind=
dp),
INTENT(in) :: w_border0
1773 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: w_border1
1774 LOGICAL,
INTENT(in) ::
pbc
1775 LOGICAL,
INTENT(in),
OPTIONAL :: safe_computation
1777 CHARACTER(len=*),
PARAMETER :: routinen =
'add_fine2coarse'
1779 INTEGER :: coarse_slice_size, f_shift(3), fi, fj, fk, handle, handle2, i, ii, ij, ik, ip, j, &
1780 k, n_procs, p, p_old, rcv_tot_size, rest_b, s(3), send_tot_size, ss, x, x_att
1781 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: pp_lb, pp_ub, rcv_offset, rcv_size, &
1782 real_rcv_size, send_offset, send_size, &
1784 INTEGER,
DIMENSION(2, 3) :: coarse_bo, coarse_gbo, fine_bo, &
1785 fine_gbo, my_coarse_bo
1786 INTEGER,
DIMENSION(:),
POINTER :: pos_of_x
1787 LOGICAL :: has_i_lbound, has_i_ubound, is_split, &
1788 local_data, safe_calc
1789 REAL(kind=
dp) :: vv0, vv1, vv2, vv3, vv4, vv5, vv6, vv7, &
1791 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: rcv_buf, send_buf
1792 REAL(kind=
dp),
DIMENSION(3) :: w_0, ww0
1793 REAL(kind=
dp),
DIMENSION(4) :: w_1, ww1
1794 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: coarse_coeffs, fine_values
1796 CALL timeset(routinen, handle)
1799 IF (
PRESENT(safe_computation)) safe_calc = safe_computation
1801 my_coarse_bo = coarse_coeffs_pw%pw_grid%bounds_local
1802 coarse_gbo = coarse_coeffs_pw%pw_grid%bounds
1803 fine_bo = fine_values_pw%pw_grid%bounds_local
1804 fine_gbo = fine_values_pw%pw_grid%bounds
1805 f_shift = fine_gbo(1, :) - 2*coarse_gbo(1, :)
1806 is_split = any(coarse_gbo(:, 1) /= my_coarse_bo(:, 1))
1807 coarse_bo = my_coarse_bo
1808 IF (fine_bo(1, 1) <= fine_bo(2, 1))
THEN
1809 coarse_bo(1, 1) = floor(real(fine_bo(1, 1) - f_shift(1),
dp)/2._dp) - 1
1810 coarse_bo(2, 1) = floor(real(fine_bo(2, 1) + 1 - f_shift(1),
dp)/2._dp) + 1
1812 coarse_bo(1, 1) = coarse_gbo(2, 1)
1813 coarse_bo(2, 1) = coarse_gbo(2, 1) - 1
1815 IF (.NOT. is_split .OR. .NOT.
pbc)
THEN
1816 coarse_bo(1, 1) = max(coarse_gbo(1, 1), coarse_bo(1, 1))
1817 coarse_bo(2, 1) = min(coarse_gbo(2, 1), coarse_bo(2, 1))
1819 has_i_ubound = (fine_gbo(2, 1) /= fine_bo(2, 1)) .OR.
pbc .AND. is_split
1820 has_i_lbound = (fine_gbo(1, 1) /= fine_bo(1, 1)) .OR.
pbc .AND. is_split
1823 cpassert(all(fine_gbo(1, :) == 2*coarse_gbo(1, :) + f_shift))
1824 cpassert(all(fine_gbo(2, :) == 2*coarse_gbo(2, :) + f_shift + 1))
1826 cpassert(all(fine_gbo(2, :) == 2*coarse_gbo(2, :) + f_shift))
1827 cpassert(all(fine_gbo(1, :) == 2*coarse_gbo(1, :) + f_shift))
1829 cpassert(coarse_gbo(2, 1) - coarse_gbo(1, 2) > 1)
1830 local_data = is_split
1831 IF (local_data)
THEN
1832 ALLOCATE (coarse_coeffs(coarse_bo(1, 1):coarse_bo(2, 1), &
1833 coarse_bo(1, 2):coarse_bo(2, 2), &
1834 coarse_bo(1, 3):coarse_bo(2, 3)))
1835 coarse_coeffs = 0._dp
1837 coarse_coeffs => coarse_coeffs_pw%array
1840 fine_values => fine_values_pw%array
1841 w_0 = (/weights_1d(3), weights_1d(1), weights_1d(3)/)
1842 w_1 = (/weights_1d(4), weights_1d(2), weights_1d(2), weights_1d(4)/)
1845 s(i) = coarse_gbo(2, i) - coarse_gbo(1, i) + 1
1847 IF (any(s < 1))
RETURN
1849 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
1852 wk = weights_1d(abs(ik) + 1)
1853 fk = fine_gbo(1, 3) +
modulo(2*k + ik - fine_gbo(1, 3) + f_shift(3), 2*s(3))
1855 fk = 2*k + ik + f_shift(3)
1856 IF (fk <= fine_bo(1, 3) + 1 .OR. fk >= fine_bo(2, 3) - 1)
THEN
1857 IF (fk < fine_bo(1, 3) .OR. fk > fine_bo(2, 3)) cycle
1858 IF (fk == fine_bo(1, 3) .OR. fk == fine_bo(2, 3))
THEN
1861 ELSE IF (fk == fine_bo(1, 3) + 1)
THEN
1887 wk = weights_1d(abs(ik) + 1)
1890 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
1893 fj = fine_gbo(1, 2) +
modulo(2*j + ij - fine_gbo(1, 2) + f_shift(2), &
1895 wj = weights_1d(abs(ij) + 1)*wk
1897 fj = 2*j + ij + f_shift(2)
1898 IF (fj <= fine_bo(1, 2) + 1 .OR. fj >= fine_bo(2, 2) - 1)
THEN
1899 IF (fj < fine_bo(1, 2) .OR. fj > fine_bo(2, 2)) cycle
1900 IF (fj == fine_bo(1, 2) .OR. fj == fine_bo(2, 2))
THEN
1903 ELSE IF (fj == fine_bo(1, 2) + 1)
THEN
1906 wj = w_border1(1)*wk
1908 wj = w_border1(2)*wk
1910 wj = w_border1(3)*wk
1918 wj = w_border1(1)*wk
1920 wj = w_border1(2)*wk
1922 wj = w_border1(3)*wk
1929 wj = weights_1d(abs(ij) + 1)*wk
1933 IF (coarse_bo(2, 1) - coarse_bo(1, 1) < 7 .OR. safe_calc)
THEN
1934 DO i = coarse_bo(1, 1), coarse_bo(2, 1)
1936 IF (
pbc .AND. .NOT. is_split)
THEN
1937 wi = weights_1d(abs(ii) + 1)*wj
1938 fi = fine_gbo(1, 1) +
modulo(2*i + ii - fine_gbo(1, 1) + f_shift(1), 2*s(1))
1940 fi = 2*i + ii + f_shift(1)
1941 IF (fi < fine_bo(1, 1) .OR. fi > fine_bo(2, 1)) cycle
1942 IF (((.NOT.
pbc) .AND. fi <= fine_gbo(1, 1) + 1) .OR. &
1943 ((.NOT.
pbc) .AND. fi >= fine_gbo(2, 1) - 1))
THEN
1944 IF (fi == fine_gbo(1, 1) .OR. fi == fine_gbo(2, 1))
THEN
1947 ELSE IF (fi == fine_gbo(1, 1) + 1)
THEN
1950 wi = w_border1(1)*wj
1952 wi = w_border1(2)*wj
1954 wi = w_border1(3)*wj
1961 wi = w_border1(1)*wj
1963 wi = w_border1(2)*wj
1965 wi = w_border1(3)*wj
1971 wi = weights_1d(abs(ii) + 1)*wj
1974 coarse_coeffs(i, j, k) = &
1975 coarse_coeffs(i, j, k) + &
1976 wi*fine_values(fi, fj, fk)
1982 IF (
pbc .AND. .NOT. is_split)
THEN
1983 i = coarse_bo(1, 1) - 1
1984 vv2 = fine_values(fine_bo(2, 1) - 2, fj, fk)
1985 vv3 = fine_values(fine_bo(2, 1) - 1, fj, fk)
1986 vv4 = fine_values(fine_bo(2, 1), fj, fk)
1988 vv5 = fine_values(fi, fj, fk)
1990 vv6 = fine_values(fi, fj, fk)
1992 vv7 = fine_values(fi, fj, fk)
1993 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
1994 + ww1(4)*vv2 + ww0(3)*vv3 + ww1(3)*vv4 + ww0(2)*vv5 + ww1(2)*vv6 + ww0(1)*vv7
1995 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) &
1996 + ww1(4)*vv4 + ww0(3)*vv5 + ww1(3)*vv6 + ww0(2)*vv7
1997 coarse_coeffs(i + 3, j, k) = coarse_coeffs(i + 3, j, k) &
1998 + ww1(4)*vv6 + ww0(3)*vv7
1999 ELSE IF (has_i_lbound)
THEN
2001 fi = fine_bo(1, 1) - 1
2002 IF (i + 1 == floor((fine_bo(1, 1) + 1 - f_shift(1))/2._dp))
THEN
2004 vv0 = fine_values(fi, fj, fk)
2005 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) + &
2007 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) + &
2009 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) + &
2014 fi = 2*i + f_shift(1)
2015 vv0 = fine_values(fi, fj, fk)
2017 vv1 = fine_values(fi, fj, fk)
2019 vv2 = fine_values(fi, fj, fk)
2020 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) + &
2021 (vv0*w_border0 + vv1*w_border1(1))*wj + vv2*ww0(1)
2022 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) + &
2023 wj*w_border1(2)*vv1 + ww0(2)*vv2
2024 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) + &
2025 wj*w_border1(3)*vv1 + ww0(3)*vv2
2027 DO i = coarse_bo(1, 1) + 3, floor((fine_bo(2, 1) - f_shift(1))/2._dp) - 3, 4
2029 vv0 = fine_values(fi, fj, fk)
2031 vv1 = fine_values(fi, fj, fk)
2033 vv2 = fine_values(fi, fj, fk)
2035 vv3 = fine_values(fi, fj, fk)
2037 vv4 = fine_values(fi, fj, fk)
2039 vv5 = fine_values(fi, fj, fk)
2041 vv6 = fine_values(fi, fj, fk)
2043 vv7 = fine_values(fi, fj, fk)
2044 coarse_coeffs(i - 3, j, k) = coarse_coeffs(i - 3, j, k) &
2046 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2047 + ww1(2)*vv0 + ww0(1)*vv1 + ww1(1)*vv2
2048 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2049 + ww1(3)*vv0 + ww0(2)*vv1 + ww1(2)*vv2 + ww0(1)*vv3 + ww1(1)*vv4
2050 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2051 + ww1(4)*vv0 + ww0(3)*vv1 + ww1(3)*vv2 + ww0(2)*vv3 + ww1(2)*vv4 + ww0(1)*vv5 + ww1(1)*vv6
2052 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2053 + ww1(4)*vv2 + ww0(3)*vv3 + ww1(3)*vv4 + ww0(2)*vv5 + ww1(2)*vv6 + ww0(1)*vv7
2054 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) &
2055 + ww1(4)*vv4 + ww0(3)*vv5 + ww1(3)*vv6 + ww0(2)*vv7
2056 coarse_coeffs(i + 3, j, k) = coarse_coeffs(i + 3, j, k) &
2057 + ww1(4)*vv6 + ww0(3)*vv7
2059 IF (.NOT. floor((fine_bo(2, 1) - f_shift(1))/2._dp) - coarse_bo(1, 1) >= 4)
THEN
2060 cpabort(
"FLOOR((fine_bo(2,1)-f_shift(1))/2._dp)-coarse_bo(1,1)>=4")
2062 rest_b =
modulo(floor((fine_bo(2, 1) - f_shift(1))/2._dp) - coarse_bo(1, 1) - 6, 4)
2063 i = floor((fine_bo(2, 1) - f_shift(1))/2._dp) - 3 - rest_b + 4
2064 cpassert(fi == (i - 2)*2 + f_shift(1))
2065 IF (rest_b > 0)
THEN
2067 vv0 = fine_values(fi, fj, fk)
2069 vv1 = fine_values(fi, fj, fk)
2070 coarse_coeffs(i - 3, j, k) = coarse_coeffs(i - 3, j, k) &
2072 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2073 + ww1(2)*vv0 + ww0(1)*vv1
2074 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2075 + ww1(3)*vv0 + ww0(2)*vv1
2076 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2077 + ww1(4)*vv0 + ww0(3)*vv1
2078 IF (rest_b > 1)
THEN
2080 vv2 = fine_values(fi, fj, fk)
2082 vv3 = fine_values(fi, fj, fk)
2083 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2085 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2086 + ww1(2)*vv2 + ww0(1)*vv3
2087 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2088 + ww1(3)*vv2 + ww0(2)*vv3
2089 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2090 + ww1(4)*vv2 + ww0(3)*vv3
2091 IF (rest_b > 2)
THEN
2093 vv4 = fine_values(fi, fj, fk)
2095 vv5 = fine_values(fi, fj, fk)
2097 vv6 = fine_values(fi, fj, fk)
2099 vv7 = fine_values(fi, fj, fk)
2100 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2102 IF (has_i_ubound)
THEN
2103 IF (coarse_bo(2, 1) - 2 == floor((fine_bo(2, 1) - f_shift(1))/2._dp))
THEN
2105 vv0 = fine_values(fi, fj, fk)
2106 coarse_coeffs(i + 4, j, k) = coarse_coeffs(i + 4, j, k) &
2111 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2112 + ww1(2)*vv4 + ww0(1)*vv5 + ww1(1)*vv6
2113 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2114 + ww1(3)*vv4 + ww0(2)*vv5 + ww1(2)*vv6 + ww0(1)*vv7 + vv0*ww1(1)
2115 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) &
2116 + ww1(4)*vv4 + ww0(3)*vv5 + ww1(3)*vv6 + ww0(2)*vv7 + vv0*ww1(2)
2117 coarse_coeffs(i + 3, j, k) = coarse_coeffs(i + 3, j, k) &
2118 + ww1(4)*vv6 + ww0(3)*vv7 + vv0*ww1(3)
2119 ELSEIF (
pbc .AND. .NOT. is_split)
THEN
2121 vv0 = fine_values(fi, fj, fk)
2122 vv1 = fine_values(fine_bo(1, 1), fj, fk)
2123 vv2 = fine_values(fine_bo(1, 1) + 1, fj, fk)
2124 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2125 + ww1(2)*vv4 + ww0(1)*vv5 + ww1(1)*vv6
2126 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2127 + ww1(3)*vv4 + ww0(2)*vv5 + ww1(2)*vv6 + ww0(1)*vv7 + vv0*ww1(1)
2128 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) &
2129 + ww1(4)*vv4 + ww0(3)*vv5 + ww1(3)*vv6 + ww0(2)*vv7 + vv0*ww1(2) &
2130 + vv1*ww0(1) + vv2*ww1(1)
2132 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2133 + ww1(2)*vv4 + ww0(1)*vv5 + wj*w_border1(3)*vv6
2134 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2135 + ww1(3)*vv4 + ww0(2)*vv5 + wj*w_border1(2)*vv6
2136 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) &
2137 + ww1(4)*vv4 + ww0(3)*vv5 + wj*w_border1(1)*vv6 + w_border0*wj*vv7
2141 vv4 = fine_values(fi, fj, fk)
2143 vv5 = fine_values(fi, fj, fk)
2144 IF (has_i_ubound)
THEN
2145 IF (coarse_bo(2, 1) - 2 == floor((fine_bo(2, 1) - f_shift(1))/2._dp))
THEN
2147 vv6 = fine_values(fi, fj, fk)
2148 coarse_coeffs(i + 3, j, k) = coarse_coeffs(i + 3, j, k) &
2153 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2155 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2156 + ww1(2)*vv4 + ww0(1)*vv5 + ww1(1)*vv6
2157 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2158 + ww1(3)*vv4 + ww0(2)*vv5 + ww1(2)*vv6
2159 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) &
2160 + ww1(4)*vv4 + ww0(3)*vv5 + ww1(3)*vv6
2161 ELSEIF (
pbc .AND. .NOT. is_split)
THEN
2163 vv6 = fine_values(fi, fj, fk)
2164 vv7 = fine_values(fine_bo(1, 1), fj, fk)
2165 vv0 = fine_values(fine_bo(1, 1) + 1, fj, fk)
2166 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2168 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2169 + ww1(4)*vv0 + ww0(3)*vv1 + ww1(3)*vv2 + ww0(2)*vv3 + &
2170 ww1(2)*vv4 + ww0(1)*vv5 + ww1(1)*vv6
2171 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2172 + ww1(4)*vv2 + ww0(3)*vv3 + ww1(3)*vv4 + ww0(2)*vv5 + ww1(2)*vv6 &
2173 + ww0(1)*vv7 + ww1(1)*vv0
2175 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2176 + wj*w_border1(3)*vv4
2177 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2178 + wj*w_border1(2)*vv4
2179 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2180 + wj*(w_border1(1)*vv4 + w_border0*vv5)
2185 vv2 = fine_values(fi, fj, fk)
2187 vv3 = fine_values(fi, fj, fk)
2188 IF (has_i_ubound)
THEN
2189 IF (coarse_bo(2, 1) - 2 == floor((fine_bo(2, 1) - f_shift(1))/2._dp))
THEN
2191 vv4 = fine_values(fi, fj, fk)
2192 coarse_coeffs(i + 2, j, k) = coarse_coeffs(i + 2, j, k) &
2197 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2199 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2200 + ww1(2)*vv2 + ww0(1)*vv3 + ww1(1)*vv4
2201 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2202 + ww1(3)*vv2 + ww0(2)*vv3 + ww1(2)*vv4
2203 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2204 + ww1(4)*vv2 + ww0(3)*vv3 + ww1(3)*vv4
2205 ELSEIF (
pbc .AND. .NOT. is_split)
THEN
2207 vv4 = fine_values(fi, fj, fk)
2208 vv5 = fine_values(fine_bo(1, 1), fj, fk)
2209 vv6 = fine_values(fine_bo(1, 1) + 1, fj, fk)
2210 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2212 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2213 + ww1(2)*vv2 + ww0(1)*vv3 + ww1(1)*vv4
2214 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2215 + ww1(3)*vv2 + ww0(2)*vv3 + ww1(2)*vv4 + vv5*ww0(1) + ww1(1)*vv6
2217 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2218 + wj*w_border1(3)*vv2
2219 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2220 + wj*w_border1(2)*vv2
2221 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2222 + wj*(w_border1(1)*vv2 + w_border0*vv3)
2227 vv0 = fine_values(fi, fj, fk)
2229 vv1 = fine_values(fi, fj, fk)
2230 IF (has_i_ubound)
THEN
2231 IF (coarse_bo(2, 1) - 2 == floor((fine_bo(2, 1) - f_shift(1))/2._dp))
THEN
2233 vv2 = fine_values(fi, fj, fk)
2234 coarse_coeffs(i + 1, j, k) = coarse_coeffs(i + 1, j, k) &
2239 coarse_coeffs(i - 3, j, k) = coarse_coeffs(i - 3, j, k) &
2241 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2242 + ww1(2)*vv0 + ww0(1)*vv1 + ww1(1)*vv2
2243 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2244 + ww1(3)*vv0 + ww0(2)*vv1 + ww1(2)*vv2
2245 coarse_coeffs(i, j, k) = coarse_coeffs(i, j, k) &
2246 + ww1(4)*vv0 + ww0(3)*vv1 + ww1(3)*vv2
2247 ELSEIF (
pbc .AND. .NOT. is_split)
THEN
2249 vv2 = fine_values(fi, fj, fk)
2250 vv3 = fine_values(fine_bo(1, 1), fk, fk)
2251 vv4 = fine_values(fine_bo(1, 1) + 1, fk, fk)
2252 coarse_coeffs(i - 3, j, k) = coarse_coeffs(i - 3, j, k) &
2254 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2255 + ww1(2)*vv0 + ww0(1)*vv1 + ww1(1)*vv2
2256 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2257 + ww1(3)*vv0 + ww0(2)*vv1 + ww1(2)*vv2 + ww0(1)*vv3 + ww1(1)*vv4
2259 coarse_coeffs(i - 3, j, k) = coarse_coeffs(i - 3, j, k) &
2260 + wj*w_border1(3)*vv0
2261 coarse_coeffs(i - 2, j, k) = coarse_coeffs(i - 2, j, k) &
2262 + wj*w_border1(2)*vv0
2263 coarse_coeffs(i - 1, j, k) = coarse_coeffs(i - 1, j, k) &
2264 + wj*(w_border1(1)*vv0 + w_border0*vv1)
2267 cpassert(fi == fine_bo(2, 1))
2276 CALL timeset(routinen//
"_comm", handle2)
2277 coarse_slice_size = (coarse_bo(2, 2) - coarse_bo(1, 2) + 1)* &
2278 (coarse_bo(2, 3) - coarse_bo(1, 3) + 1)
2279 n_procs = coarse_coeffs_pw%pw_grid%para%group_size
2280 ALLOCATE (send_size(0:n_procs - 1), send_offset(0:n_procs - 1), &
2281 sent_size(0:n_procs - 1), rcv_size(0:n_procs - 1), &
2282 rcv_offset(0:n_procs - 1), pp_lb(0:n_procs - 1), &
2283 pp_ub(0:n_procs - 1), real_rcv_size(0:n_procs - 1))
2287 pos_of_x => coarse_coeffs_pw%pw_grid%para%pos_of_x
2289 DO x = coarse_bo(1, 1), coarse_bo(2, 1)
2290 p = pos_of_x(coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1)))
2291 send_size(p) = send_size(p) + coarse_slice_size
2296 pos_of_x => fine_values_pw%pw_grid%para%pos_of_x
2297 p_old = pos_of_x(fine_gbo(1, 1))
2298 pp_lb = fine_gbo(2, 1)
2299 pp_ub = fine_gbo(2, 1) - 1
2300 pp_lb(p_old) = fine_gbo(1, 1)
2301 DO x = fine_gbo(1, 1), fine_gbo(2, 1)
2303 IF (p /= p_old)
THEN
2304 pp_ub(p_old) = x - 1
2309 pp_ub(p_old) = fine_gbo(2, 1)
2311 DO ip = 0, n_procs - 1
2312 IF (pp_lb(ip) <= pp_ub(ip))
THEN
2313 pp_lb(ip) = floor(real(pp_lb(ip) - f_shift(1),
dp)/2._dp) - 1
2314 pp_ub(ip) = floor(real(pp_ub(ip) + 1 - f_shift(1),
dp)/2._dp) + 1
2316 pp_lb(ip) = coarse_gbo(2, 1)
2317 pp_ub(ip) = coarse_gbo(2, 1) - 1
2319 IF (.NOT. is_split .OR. .NOT.
pbc)
THEN
2320 pp_lb(ip) = max(pp_lb(ip), coarse_gbo(1, 1))
2321 pp_ub(ip) = min(pp_ub(ip), coarse_gbo(2, 1))
2326 DO ip = 0, n_procs - 1
2327 DO x = pp_lb(ip), coarse_gbo(1, 1) - 1
2328 x_att = coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1))
2329 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
2330 rcv_size(ip) = rcv_size(ip) + coarse_slice_size
2333 rcv_size(ip) = rcv_size(ip) + coarse_slice_size* &
2335 min(pp_ub(ip), my_coarse_bo(2, 1)) - max(pp_lb(ip), my_coarse_bo(1, 1)) + 1)
2336 DO x = coarse_gbo(2, 1) + 1, pp_ub(ip)
2337 x_att = coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1))
2338 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
2339 rcv_size(ip) = rcv_size(ip) + coarse_slice_size
2347 DO ip = 0, n_procs - 1
2348 send_offset(ip) = send_tot_size
2349 send_tot_size = send_tot_size + send_size(ip)
2351 IF (send_tot_size /= (coarse_bo(2, 1) - coarse_bo(1, 1) + 1)*coarse_slice_size) &
2352 cpabort(
"Error calculating send_tot_size")
2353 ALLOCATE (send_buf(0:send_tot_size - 1))
2356 DO ip = 0, n_procs - 1
2357 rcv_offset(ip) = rcv_tot_size
2358 rcv_tot_size = rcv_tot_size + rcv_size(ip)
2360 ALLOCATE (rcv_buf(0:rcv_tot_size - 1))
2364 pos_of_x => coarse_coeffs_pw%pw_grid%para%pos_of_x
2365 p_old = pos_of_x(coarse_gbo(1, 1) &
2366 +
modulo(coarse_bo(1, 1) - coarse_gbo(1, 1), s(1)))
2367 sent_size(:) = send_offset
2368 ss = coarse_bo(2, 1) - coarse_bo(1, 1) + 1
2369 DO x = coarse_bo(1, 1), coarse_bo(2, 1)
2370 p = pos_of_x(coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1)))
2371 CALL dcopy(coarse_slice_size, &
2372 coarse_coeffs(x, coarse_bo(1, 2), &
2373 coarse_bo(1, 3)), ss, send_buf(sent_size(p)), 1)
2374 sent_size(p) = sent_size(p) + coarse_slice_size
2377 IF (any(sent_size(0:n_procs - 2) /= send_offset(1:n_procs - 1))) &
2378 cpabort(
"error 1 filling send buffer")
2379 IF (sent_size(n_procs - 1) /= send_tot_size) &
2380 cpabort(
"error 2 filling send buffer")
2382 IF (local_data)
THEN
2383 DEALLOCATE (coarse_coeffs)
2385 NULLIFY (coarse_coeffs)
2388 cpassert(all(sent_size(:n_procs - 2) == send_offset(1:)))
2389 cpassert(sent_size(n_procs - 1) == send_tot_size)
2391 CALL coarse_coeffs_pw%pw_grid%para%group%alltoall(send_size, real_rcv_size, 1)
2393 cpassert(all(real_rcv_size == rcv_size))
2395 CALL coarse_coeffs_pw%pw_grid%para%group%alltoall(sb=send_buf, scount=send_size, sdispl=send_offset, &
2396 rb=rcv_buf, rcount=rcv_size, rdispl=rcv_offset)
2400 sent_size(:) = rcv_offset
2401 DO ip = 0, n_procs - 1
2403 DO x = pp_lb(ip), coarse_gbo(1, 1) - 1
2404 x_att = coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1))
2405 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
2407 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
2408 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
2409 coarse_coeffs_pw%array(x_att, j, k) = coarse_coeffs_pw%array(x_att, j, k) + rcv_buf(ii)
2418 DO x_att = max(pp_lb(ip), my_coarse_bo(1, 1)), min(pp_ub(ip), my_coarse_bo(2, 1))
2419 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
2420 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
2421 coarse_coeffs_pw%array(x_att, j, k) = coarse_coeffs_pw%array(x_att, j, k) + rcv_buf(ii)
2428 DO x = coarse_gbo(2, 1) + 1, pp_ub(ip)
2429 x_att = coarse_gbo(1, 1) +
modulo(x - coarse_gbo(1, 1), s(1))
2430 IF (x_att >= my_coarse_bo(1, 1) .AND. x_att <= my_coarse_bo(2, 1))
THEN
2432 DO k = coarse_bo(1, 3), coarse_bo(2, 3)
2433 DO j = coarse_bo(1, 2), coarse_bo(2, 2)
2434 coarse_coeffs_pw%array(x_att, j, k) = coarse_coeffs_pw%array(x_att, j, k) + rcv_buf(ii)
2444 IF (any(sent_size(0:n_procs - 2) /= rcv_offset(1:n_procs - 1))) &
2445 cpabort(
"error 1 handling the rcv buffer")
2446 IF (sent_size(n_procs - 1) /= rcv_tot_size) &
2447 cpabort(
"error 2 handling the rcv buffer")
2450 DEALLOCATE (send_size, send_offset, rcv_size, rcv_offset)
2451 DEALLOCATE (send_buf, rcv_buf, real_rcv_size)
2452 DEALLOCATE (pp_ub, pp_lb)
2453 CALL timestop(handle2)
2455 cpassert(.NOT. local_data)
2458 CALL timestop(handle)
2472 pool, pbc, transpose)
2474 INTEGER,
INTENT(in) :: precond_kind
2475 TYPE(pw_pool_type),
INTENT(IN),
POINTER :: pool
2476 LOGICAL,
INTENT(in) ::
pbc, transpose
2497 INTEGER,
INTENT(in) :: precond_kind
2498 LOGICAL,
INTENT(in),
OPTIONAL ::
pbc, transpose
2500 LOGICAL :: do_3d_coeff
2504 do_3d_coeff = .false.
2507 SELECT CASE (precond_kind)
2510 preconditioner%coeffs_1d = (/-1.66_dp*0.25_dp, 1.66_dp, -1.66_dp*0.25_dp/)
2513 do_3d_coeff = .true.
2520 do_3d_coeff = .true.
2527 do_3d_coeff = .true.
2532 do_3d_coeff = .true.
2539 do_3d_coeff = .true.
2543 IF (do_3d_coeff)
THEN
2594 TYPE(pw_r3d_rs_type),
INTENT(IN) :: in_v
2595 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: out_v
2599 CALL pw_copy(in_v, out_v)
2645 FUNCTION find_coeffs(values, coeffs, linOp, preconditioner, pool, &
2646 eps_r, eps_x, max_iter, sumtype)
RESULT(res)
2648 TYPE(pw_r3d_rs_type),
INTENT(IN) :: values
2649 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: coeffs
2651 SUBROUTINE linop(pw_in, pw_out)
2653 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in
2654 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: pw_out
2655 END SUBROUTINE linop
2658 TYPE(pw_pool_type),
POINTER :: pool
2659 REAL(kind=
dp),
INTENT(in) :: eps_r, eps_x
2660 INTEGER,
INTENT(in) :: max_iter
2661 INTEGER,
INTENT(in),
OPTIONAL :: sumtype
2664 INTEGER :: i, iiter, iter, j, k
2665 INTEGER,
DIMENSION(2, 3) :: bo
2667 REAL(kind=
dp) :: alpha, beta, eps_r_att, eps_x_att, r_z, &
2669 TYPE(cp_logger_type),
POINTER :: logger
2670 TYPE(pw_r3d_rs_type) :: ap, p, r, z
2676 CALL pool%create_pw(r)
2677 CALL pool%create_pw(z)
2678 CALL pool%create_pw(p)
2679 CALL pool%create_pw(ap)
2682 ext_do:
DO iiter = 1, max_iter, 10
2684 CALL linop(pw_in=coeffs, pw_out=r)
2686 CALL pw_axpy(values, r)
2689 r_z = pw_integral_ab(r, z, sumtype)
2691 DO iter = iiter, min(iiter + 9, max_iter)
2692 eps_r_att = sqrt(pw_integral_ab(r, r, sumtype))
2693 IF (eps_r_att == 0._dp)
THEN
2698 CALL linop(pw_in=p, pw_out=ap)
2699 alpha = r_z/pw_integral_ab(ap, p, sumtype)
2701 CALL pw_axpy(p, coeffs, alpha=alpha)
2703 eps_x_att = alpha*sqrt(pw_integral_ab(p, p, sumtype))
2704 IF (eps_r_att < eps_r .AND. eps_x_att < eps_x) last = .true.
2712 CALL pw_axpy(ap, r, alpha=-alpha)
2716 r_z_new = pw_integral_ab(r, z, sumtype)
2720 bo = p%pw_grid%bounds_local
2721 DO k = bo(1, 3), bo(2, 3)
2722 DO j = bo(1, 2), bo(2, 2)
2723 DO i = bo(1, 1), bo(2, 1)
2724 p%array(i, j, k) = z%array(i, j, k) + beta*p%array(i, j, k)
2733 CALL pool%give_back_pw(r)
2734 CALL pool%give_back_pw(z)
2735 CALL pool%give_back_pw(p)
2736 CALL pool%give_back_pw(ap)
2755 sharpen, normalize, transpose, smooth_boundary)
2756 REAL(kind=
dp),
DIMENSION(-1:1) :: weights_1d
2757 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in, pw_out
2758 LOGICAL,
INTENT(in),
OPTIONAL :: sharpen, normalize, transpose, &
2761 INTEGER :: first_index, i, j, jw, k, kw, &
2762 last_index, myj, myk, n_els
2763 INTEGER,
DIMENSION(2, 3) :: bo, gbo
2764 INTEGER,
DIMENSION(3) :: s
2765 LOGICAL :: has_l_boundary, has_u_boundary, &
2766 is_split, my_normalize, my_sharpen, &
2767 my_smooth_boundary, my_transpose
2768 REAL(kind=
dp) :: in_val_f, in_val_l, in_val_tmp, w_j, w_k
2769 REAL(kind=
dp),
DIMENSION(-1:1) :: w
2770 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: l_boundary, tmp, u_boundary
2771 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: in_val, out_val
2773 bo = pw_in%pw_grid%bounds_local
2774 gbo = pw_in%pw_grid%bounds
2775 in_val => pw_in%array
2776 out_val => pw_out%array
2777 my_sharpen = .false.
2778 IF (
PRESENT(sharpen)) my_sharpen = sharpen
2779 my_normalize = .false.
2780 IF (
PRESENT(normalize)) my_normalize = normalize
2781 my_transpose = .false.
2782 IF (
PRESENT(transpose)) my_transpose = transpose
2783 my_smooth_boundary = .false.
2784 IF (
PRESENT(smooth_boundary)) my_smooth_boundary = smooth_boundary
2785 cpassert(.NOT. my_normalize .OR. my_sharpen)
2786 cpassert(.NOT. my_smooth_boundary .OR. .NOT. my_sharpen)
2788 s(i) = bo(2, i) - bo(1, i) + 1
2790 IF (any(s < 1))
RETURN
2791 is_split = any(pw_in%pw_grid%bounds_local(:, 1) /= &
2792 pw_in%pw_grid%bounds(:, 1))
2793 has_l_boundary = (gbo(1, 1) == bo(1, 1))
2794 has_u_boundary = (gbo(2, 1) == bo(2, 1))
2796 ALLOCATE (l_boundary(bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)), &
2797 u_boundary(bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)), &
2798 tmp(bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
2799 tmp(:, :) = pw_in%array(bo(2, 1), :, :)
2800 CALL pw_in%pw_grid%para%group%sendrecv(tmp, pw_in%pw_grid%para%pos_of_x( &
2801 gbo(1, 1) +
modulo(bo(2, 1) + 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)), &
2802 l_boundary, pw_in%pw_grid%para%pos_of_x( &
2803 gbo(1, 1) +
modulo(bo(1, 1) - 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)))
2804 tmp(:, :) = pw_in%array(bo(1, 1), :, :)
2805 CALL pw_in%pw_grid%para%group%sendrecv(tmp, pw_in%pw_grid%para%pos_of_x( &
2806 gbo(1, 1) +
modulo(bo(1, 1) - 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)), &
2807 u_boundary, pw_in%pw_grid%para%pos_of_x( &
2808 gbo(1, 1) +
modulo(bo(2, 1) + 1 - gbo(1, 1), gbo(2, 1) - gbo(1, 1) + 1)))
2813 IF (has_l_boundary)
THEN
2815 first_index = bo(1, 1) + 1
2817 first_index = bo(1, 1)
2819 IF (has_u_boundary)
THEN
2821 last_index = bo(2, 1) - 1
2823 last_index = bo(2, 1)
2830 DO k = bo(1, 3), bo(2, 3)
2833 IF (my_transpose)
THEN
2834 IF (k >= gbo(2, 3) - 1 .OR. k <= gbo(1, 3) + 1)
THEN
2835 IF (k == gbo(2, 3) .OR. k == gbo(1, 3))
THEN
2836 IF (myk < gbo(2, 3) .AND. myk > gbo(1, 3))
THEN
2837 w_k = weights_1d(kw)
2838 IF (my_smooth_boundary)
THEN
2839 w_k = weights_1d(kw)/weights_1d(0)
2841 ELSE IF (kw == 0)
THEN
2847 IF (myk == gbo(2, 3) .OR. myk == gbo(1, 3)) cycle
2848 w_k = weights_1d(kw)
2851 w_k = weights_1d(kw)
2854 IF (k >= gbo(2, 3) - 1 .OR. k <= gbo(1, 3) + 1)
THEN
2855 IF (k == gbo(2, 3) .OR. k == gbo(1, 3))
THEN
2859 IF (my_smooth_boundary .AND. ((k == gbo(1, 3) + 1 .AND. myk == gbo(1, 3)) .OR. &
2860 (k == gbo(2, 3) - 1 .AND. myk == gbo(2, 3))))
THEN
2861 w_k = weights_1d(kw)/weights_1d(0)
2863 w_k = weights_1d(kw)
2867 w_k = weights_1d(kw)
2870 DO j = bo(1, 2), bo(2, 2)
2873 IF (j < gbo(2, 2) - 1 .AND. j > gbo(1, 2) + 1)
THEN
2874 w_j = w_k*weights_1d(jw)
2876 IF (my_transpose)
THEN
2877 IF (j == gbo(2, 2) .OR. j == gbo(1, 2))
THEN
2878 IF (myj < gbo(2, 2) .AND. myj > gbo(1, 2))
THEN
2879 w_j = weights_1d(jw)*w_k
2880 IF (my_smooth_boundary)
THEN
2881 w_j = weights_1d(jw)/weights_1d(0)*w_k
2883 ELSE IF (jw == 0)
THEN
2889 IF (myj == gbo(2, 2) .OR. myj == gbo(1, 2)) cycle
2890 w_j = w_k*weights_1d(jw)
2893 IF (j == gbo(2, 2) .OR. j == gbo(1, 2))
THEN
2896 ELSE IF (my_smooth_boundary .AND. ((j == gbo(1, 2) + 1 .AND. myj == gbo(1, 2)) .OR. &
2897 (j == gbo(2, 2) - 1 .AND. myj == gbo(2, 2))))
THEN
2898 w_j = w_k*weights_1d(jw)/weights_1d(0)
2900 w_j = w_k*weights_1d(jw)
2905 IF (has_l_boundary)
THEN
2906 IF (my_transpose)
THEN
2908 cpassert(.NOT. has_u_boundary)
2909 in_val_tmp = u_boundary(myj, myk)
2911 in_val_tmp = in_val(bo(1, 1) + 1, myj, myk)
2913 IF (my_sharpen)
THEN
2914 IF (kw == 0 .AND. jw == 0)
THEN
2915 IF (my_normalize)
THEN
2916 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) + &
2917 (2.0_dp - w_j)*in_val(bo(1, 1), myj, myk) - &
2918 in_val_tmp*weights_1d(1)*w_j
2920 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) + &
2921 in_val(bo(1, 1), myj, myk)*w_j - &
2922 in_val_tmp*weights_1d(1)*w_j
2925 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) - &
2926 in_val(bo(1, 1), myj, myk)*w_j - &
2927 in_val_tmp*weights_1d(1)*w_j
2929 ELSE IF (my_smooth_boundary)
THEN
2930 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) + &
2931 w_j*(in_val(bo(1, 1), myj, myk) + &
2932 in_val_tmp*weights_1d(1)/weights_1d(0))
2934 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) + &
2935 w_j*(in_val(bo(1, 1), myj, myk) + &
2936 in_val_tmp*weights_1d(1))
2940 in_val_f = in_val(bo(1, 1), myj, myk)
2941 IF (my_sharpen)
THEN
2942 IF (kw == 0 .AND. jw == 0)
THEN
2943 IF (my_normalize)
THEN
2944 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) + &
2945 (2.0_dp - w_j)*in_val_f
2947 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) + &
2951 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) - &
2955 out_val(bo(1, 1), j, k) = out_val(bo(1, 1), j, k) + &
2960 in_val_f = l_boundary(myj, myk)
2962 IF (has_u_boundary)
THEN
2963 IF (my_transpose)
THEN
2964 in_val_l = in_val(bo(2, 1), myj, myk)
2966 cpassert(.NOT. has_l_boundary)
2967 in_val_tmp = l_boundary(myj, myk)
2969 in_val_tmp = in_val(bo(2, 1) - 1, myj, myk)
2971 IF (my_sharpen)
THEN
2972 IF (kw == 0 .AND. jw == 0)
THEN
2973 IF (my_normalize)
THEN
2974 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) + &
2975 in_val_l*(2._dp - w_j) - &
2976 in_val_tmp*weights_1d(1)*w_j
2978 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) + &
2980 in_val_tmp*weights_1d(1)*w_j
2983 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) - &
2985 in_val_tmp*weights_1d(1)*w_j
2987 ELSE IF (my_smooth_boundary)
THEN
2988 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) + &
2989 w_j*(in_val_l + in_val_tmp*weights_1d(1)/weights_1d(0))
2991 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) + &
2992 w_j*(in_val_l + in_val_tmp*weights_1d(1))
2996 in_val_l = in_val(bo(2, 1), myj, myk)
2997 IF (my_sharpen)
THEN
2998 IF (kw == 0 .AND. jw == 0)
THEN
2999 IF (my_normalize)
THEN
3000 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) + &
3001 in_val_l*(2._dp - w_j)
3003 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) + &
3007 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) - &
3011 out_val(bo(2, 1), j, k) = out_val(bo(2, 1), j, k) + &
3016 in_val_l = u_boundary(myj, myk)
3018 IF (last_index >= first_index)
THEN
3019 IF (my_transpose)
THEN
3020 IF (bo(1, 1) - 1 == gbo(1, 1))
THEN
3022 ELSE IF (bo(2, 1) + 1 == gbo(2, 1))
THEN
3026 IF (my_sharpen)
THEN
3028 IF (kw == 0 .AND. jw == 0)
THEN
3029 IF (my_normalize)
THEN
3038 IF (my_smooth_boundary .AND. (.NOT. my_transpose))
THEN
3039 IF (gbo(1, 1) + 1 >= bo(1, 1) .AND. &
3040 gbo(1, 1) + 1 <= bo(2, 1) .AND. gbo(2, 1) - gbo(1, 1) > 2)
THEN
3041 IF (gbo(1, 1) >= bo(1, 1))
THEN
3042 out_val(gbo(1, 1) + 1, j, k) = out_val(gbo(1, 1) + 1, j, k) + &
3043 in_val(gbo(1, 1), myj, myk)*w_j*weights_1d(-1)* &
3044 (1._dp/weights_1d(0) - 1._dp)
3046 out_val(gbo(1, 1) + 1, j, k) = out_val(gbo(1, 1) + 1, j, k) + &
3047 l_boundary(myj, myk)*w_j*weights_1d(-1)* &
3048 (1._dp/weights_1d(0) - 1._dp)
3052 CALL pw_compose_stripe(weights=w, &
3053 in_val=in_val(first_index:last_index, myj, myk), &
3054 in_val_first=in_val_f, in_val_last=in_val_l, &
3055 out_val=out_val(first_index:last_index, j, k), &
3063 IF (my_smooth_boundary .AND. (.NOT. my_transpose))
THEN
3064 IF (gbo(2, 1) - 1 >= bo(1, 1) .AND. &
3065 gbo(2, 1) - 1 <= bo(2, 1) .AND. gbo(2, 1) - gbo(1, 1) > 2)
THEN
3066 IF (gbo(2, 1) <= bo(2, 1))
THEN
3067 out_val(gbo(2, 1) - 1, j, k) = out_val(gbo(2, 1) - 1, j, k) + &
3068 in_val(gbo(2, 1), myj, myk)*w_j*weights_1d(1)* &
3069 (1._dp/weights_1d(0) - 1._dp)
3071 out_val(gbo(2, 1) - 1, j, k) = out_val(gbo(2, 1) - 1, j, k) + &
3072 u_boundary(myj, myk)*w_j*weights_1d(1)* &
3073 (1._dp/weights_1d(0) - 1._dp)
3085 DEALLOCATE (l_boundary, u_boundary)
3096 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in
3097 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: pw_out
3099 CALL pw_zero(pw_out)
3101 pw_out=pw_out, sharpen=.false., normalize=.false.)
3112 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in
3113 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: pw_out
3115 CALL pw_zero(pw_out)
3117 pw_out=pw_out, sharpen=.false., normalize=.false., transpose=.true.)
3128 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw_in
3129 TYPE(pw_r3d_rs_type),
INTENT(INOUT) :: pw_out
3131 CALL pw_zero(pw_out)
3149 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: vec
3150 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw
3151 REAL(kind=
dp) :: val
3153 INTEGER :: i, ivec(3), j, k, npts(3)
3154 INTEGER,
DIMENSION(2, 3) :: bo, bo_l
3155 INTEGER,
DIMENSION(4) :: ii, ij, ik
3157 REAL(kind=
dp) :: a1, a2, a3, b1, b2, b3, c1, c2, c3, d1, d2, d3, dr1, dr2, dr3, e1, e2, e3, &
3158 f1, f2, f3, g1, g2, g3, h1, h2, h3, p1, p2, p3, q1, q2, q3, r1, r2, r3, s1, s2, s3, s4, &
3159 t1, t2, t3, t4, u1, u2, u3, v1, v2, v3, v4, xd1, xd2, xd3
3160 REAL(kind=
dp),
DIMENSION(4, 4, 4) :: box
3161 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: grid
3165 npts = pw%pw_grid%npts
3166 ivec = floor(vec/pw%pw_grid%dr)
3167 dr1 = pw%pw_grid%dr(1)
3168 dr2 = pw%pw_grid%dr(2)
3169 dr3 = pw%pw_grid%dr(3)
3171 xd1 = (vec(1)/dr1) - real(ivec(1), kind=
dp)
3172 xd2 = (vec(2)/dr2) - real(ivec(2), kind=
dp)
3173 xd3 = (vec(3)/dr3) - real(ivec(3), kind=
dp)
3174 grid => pw%array(:, :, :)
3175 bo = pw%pw_grid%bounds
3176 bo_l = pw%pw_grid%bounds_local
3178 ik(1) =
modulo(ivec(3) - 1, npts(3)) + bo(1, 3)
3179 ik(2) =
modulo(ivec(3), npts(3)) + bo(1, 3)
3180 ik(3) =
modulo(ivec(3) + 1, npts(3)) + bo(1, 3)
3181 ik(4) =
modulo(ivec(3) + 2, npts(3)) + bo(1, 3)
3183 ij(1) =
modulo(ivec(2) - 1, npts(2)) + bo(1, 2)
3184 ij(2) =
modulo(ivec(2), npts(2)) + bo(1, 2)
3185 ij(3) =
modulo(ivec(2) + 1, npts(2)) + bo(1, 2)
3186 ij(4) =
modulo(ivec(2) + 2, npts(2)) + bo(1, 2)
3188 ii(1) =
modulo(ivec(1) - 1, npts(1)) + bo(1, 1)
3189 ii(2) =
modulo(ivec(1), npts(1)) + bo(1, 1)
3190 ii(3) =
modulo(ivec(1) + 1, npts(1)) + bo(1, 1)
3191 ii(4) =
modulo(ivec(1) + 2, npts(1)) + bo(1, 1)
3197 ii(i) >= bo_l(1, 1) .AND. &
3198 ii(i) <= bo_l(2, 1) .AND. &
3199 ij(j) >= bo_l(1, 2) .AND. &
3200 ij(j) <= bo_l(2, 2) .AND. &
3201 ik(k) >= bo_l(1, 3) .AND. &
3202 ik(k) <= bo_l(2, 3) &
3204 box(i, j, k) = grid(ii(i) + 1 - bo_l(1, 1), &
3205 ij(j) + 1 - bo_l(1, 2), &
3206 ik(k) + 1 - bo_l(1, 3))
3208 box(i, j, k) = 0.0_dp
3251 t1 = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*a1 + 12.0_dp*a2 - a3)
3252 t2 = -22.0_dp/3.0_dp + 10.0_dp*b1 - 4.0_dp*b2 + 0.5_dp*b3
3253 t3 = 2.0_dp/3.0_dp - 2.0_dp*c1 + 2.0_dp*c2 - 0.5_dp*c3
3254 t4 = 1.0_dp/6.0_dp*d3
3255 s1 = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*e1 + 12.0_dp*e2 - e3)
3256 s2 = -22.0_dp/3.0_dp + 10.0_dp*f1 - 4.0_dp*f2 + 0.5_dp*f3
3257 s3 = 2.0_dp/3.0_dp - 2.0_dp*g1 + 2.0_dp*g2 - 0.5_dp*g3
3258 s4 = 1.0_dp/6.0_dp*h3
3259 v1 = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*p1 + 12.0_dp*p2 - p3)
3260 v2 = -22.0_dp/3.0_dp + 10.0_dp*q1 - 4.0_dp*q2 + 0.5_dp*q3
3261 v3 = 2.0_dp/3.0_dp - 2.0_dp*r1 + 2.0_dp*r2 - 0.5_dp*r3
3262 v4 = 1.0_dp/6.0_dp*u3
3264 val = ((box(1, 1, 1)*t1 + box(2, 1, 1)*t2 + box(3, 1, 1)*t3 + box(4, 1, 1)*t4)*s1 + &
3265 (box(1, 2, 1)*t1 + box(2, 2, 1)*t2 + box(3, 2, 1)*t3 + box(4, 2, 1)*t4)*s2 + &
3266 (box(1, 3, 1)*t1 + box(2, 3, 1)*t2 + box(3, 3, 1)*t3 + box(4, 3, 1)*t4)*s3 + &
3267 (box(1, 4, 1)*t1 + box(2, 4, 1)*t2 + box(3, 4, 1)*t3 + box(4, 4, 1)*t4)*s4)*v1 + &
3268 ((box(1, 1, 2)*t1 + box(2, 1, 2)*t2 + box(3, 1, 2)*t3 + box(4, 1, 2)*t4)*s1 + &
3269 (box(1, 2, 2)*t1 + box(2, 2, 2)*t2 + box(3, 2, 2)*t3 + box(4, 2, 2)*t4)*s2 + &
3270 (box(1, 3, 2)*t1 + box(2, 3, 2)*t2 + box(3, 3, 2)*t3 + box(4, 3, 2)*t4)*s3 + &
3271 (box(1, 4, 2)*t1 + box(2, 4, 2)*t2 + box(3, 4, 2)*t3 + box(4, 4, 2)*t4)*s4)*v2 + &
3272 ((box(1, 1, 3)*t1 + box(2, 1, 3)*t2 + box(3, 1, 3)*t3 + box(4, 1, 3)*t4)*s1 + &
3273 (box(1, 2, 3)*t1 + box(2, 2, 3)*t2 + box(3, 2, 3)*t3 + box(4, 2, 3)*t4)*s2 + &
3274 (box(1, 3, 3)*t1 + box(2, 3, 3)*t2 + box(3, 3, 3)*t3 + box(4, 3, 3)*t4)*s3 + &
3275 (box(1, 4, 3)*t1 + box(2, 4, 3)*t2 + box(3, 4, 3)*t3 + box(4, 4, 3)*t4)*s4)*v3 + &
3276 ((box(1, 1, 4)*t1 + box(2, 1, 4)*t2 + box(3, 1, 4)*t3 + box(4, 1, 4)*t4)*s1 + &
3277 (box(1, 2, 4)*t1 + box(2, 2, 4)*t2 + box(3, 2, 4)*t3 + box(4, 2, 4)*t4)*s2 + &
3278 (box(1, 3, 4)*t1 + box(2, 3, 4)*t2 + box(3, 3, 4)*t3 + box(4, 3, 4)*t4)*s3 + &
3279 (box(1, 4, 4)*t1 + box(2, 4, 4)*t2 + box(3, 4, 4)*t3 + box(4, 4, 4)*t4)*s4)*v4
3281 IF (my_mpsum)
CALL pw%pw_grid%para%group%sum(val)
3298 REAL(kind=
dp),
DIMENSION(3),
INTENT(in) :: vec
3299 TYPE(pw_r3d_rs_type),
INTENT(IN) :: pw
3300 REAL(kind=
dp) :: val(3)
3302 INTEGER :: i, ivec(3), j, k, npts(3)
3303 INTEGER,
DIMENSION(2, 3) :: bo, bo_l
3304 INTEGER,
DIMENSION(4) :: ii, ij, ik
3306 REAL(kind=
dp) :: a1, a2, a3, b1, b2, b3, c1, c2, c3, d1, d2, d3, dr1, dr1i, dr2, dr2i, dr3, &
3307 dr3i, e1, e2, e3, f1, f2, f3, g1, g2, g3, h1, h2, h3, p1, p2, p3, q1, q2, q3, r1, r2, r3, &
3308 s1, s1d, s1o, s2, s2d, s2o, s3, s3d, s3o, s4, s4d, s4o, t1, t1d, t1o, t2, t2d, t2o, t3, &
3309 t3d, t3o, t4, t4d, t4o, u1, u2, u3, v1, v1d, v1o, v2, v2d, v2o, v3, v3d, v3o, v4, v4d, &
3311 REAL(kind=
dp),
DIMENSION(4, 4, 4) :: box
3312 REAL(kind=
dp),
DIMENSION(:, :, :),
POINTER :: grid
3316 npts = pw%pw_grid%npts
3317 ivec = floor(vec/pw%pw_grid%dr)
3318 dr1 = pw%pw_grid%dr(1)
3319 dr2 = pw%pw_grid%dr(2)
3320 dr3 = pw%pw_grid%dr(3)
3324 xd1 = (vec(1)/dr1) - real(ivec(1), kind=
dp)
3325 xd2 = (vec(2)/dr2) - real(ivec(2), kind=
dp)
3326 xd3 = (vec(3)/dr3) - real(ivec(3), kind=
dp)
3327 grid => pw%array(:, :, :)
3328 bo = pw%pw_grid%bounds
3329 bo_l = pw%pw_grid%bounds_local
3331 ik(1) =
modulo(ivec(3) - 1, npts(3)) + bo(1, 3)
3332 ik(2) =
modulo(ivec(3), npts(3)) + bo(1, 3)
3333 ik(3) =
modulo(ivec(3) + 1, npts(3)) + bo(1, 3)
3334 ik(4) =
modulo(ivec(3) + 2, npts(3)) + bo(1, 3)
3336 ij(1) =
modulo(ivec(2) - 1, npts(2)) + bo(1, 2)
3337 ij(2) =
modulo(ivec(2), npts(2)) + bo(1, 2)
3338 ij(3) =
modulo(ivec(2) + 1, npts(2)) + bo(1, 2)
3339 ij(4) =
modulo(ivec(2) + 2, npts(2)) + bo(1, 2)
3341 ii(1) =
modulo(ivec(1) - 1, npts(1)) + bo(1, 1)
3342 ii(2) =
modulo(ivec(1), npts(1)) + bo(1, 1)
3343 ii(3) =
modulo(ivec(1) + 1, npts(1)) + bo(1, 1)
3344 ii(4) =
modulo(ivec(1) + 2, npts(1)) + bo(1, 1)
3350 ii(i) >= bo_l(1, 1) .AND. &
3351 ii(i) <= bo_l(2, 1) .AND. &
3352 ij(j) >= bo_l(1, 2) .AND. &
3353 ij(j) <= bo_l(2, 2) .AND. &
3354 ik(k) >= bo_l(1, 3) .AND. &
3355 ik(k) <= bo_l(2, 3) &
3357 box(i, j, k) = grid(ii(i) + 1 - bo_l(1, 1), &
3358 ij(j) + 1 - bo_l(1, 2), &
3359 ik(k) + 1 - bo_l(1, 3))
3361 box(i, j, k) = 0.0_dp
3404 t1o = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*a1 + 12.0_dp*a2 - a3)
3405 t2o = -22.0_dp/3.0_dp + 10.0_dp*b1 - 4.0_dp*b2 + 0.5_dp*b3
3406 t3o = 2.0_dp/3.0_dp - 2.0_dp*c1 + 2.0_dp*c2 - 0.5_dp*c3
3407 t4o = 1.0_dp/6.0_dp*d3
3408 s1o = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*e1 + 12.0_dp*e2 - e3)
3409 s2o = -22.0_dp/3.0_dp + 10.0_dp*f1 - 4.0_dp*f2 + 0.5_dp*f3
3410 s3o = 2.0_dp/3.0_dp - 2.0_dp*g1 + 2.0_dp*g2 - 0.5_dp*g3
3411 s4o = 1.0_dp/6.0_dp*h3
3412 v1o = 1.0_dp/6.0_dp*(64.0_dp - 48.0_dp*p1 + 12.0_dp*p2 - p3)
3413 v2o = -22.0_dp/3.0_dp + 10.0_dp*q1 - 4.0_dp*q2 + 0.5_dp*q3
3414 v3o = 2.0_dp/3.0_dp - 2.0_dp*r1 + 2.0_dp*r2 - 0.5_dp*r3
3415 v4o = 1.0_dp/6.0_dp*u3
3417 t1d = -8.0_dp + 4.0_dp*a1 - 0.5_dp*a2
3418 t2d = 10.0_dp - 8.0_dp*b1 + 1.5_dp*b2
3419 t3d = -2.0_dp + 4.0_dp*c1 - 1.5_dp*c2
3421 s1d = -8.0_dp + 4.0_dp*e1 - 0.5_dp*e2
3422 s2d = 10.0_dp - 8.0_dp*f1 + 1.5_dp*f2
3423 s3d = -2.0_dp + 4.0_dp*g1 - 1.5_dp*g2
3425 v1d = -8.0_dp + 4.0_dp*p1 - 0.5_dp*p2
3426 v2d = 10.0_dp - 8.0_dp*q1 + 1.5_dp*q2
3427 v3d = -2.0_dp + 4.0_dp*r1 - 1.5_dp*r2
3442 val(1) = ((box(1, 1, 1)*t1 + box(2, 1, 1)*t2 + box(3, 1, 1)*t3 + box(4, 1, 1)*t4)*s1 + &
3443 (box(1, 2, 1)*t1 + box(2, 2, 1)*t2 + box(3, 2, 1)*t3 + box(4, 2, 1)*t4)*s2 + &
3444 (box(1, 3, 1)*t1 + box(2, 3, 1)*t2 + box(3, 3, 1)*t3 + box(4, 3, 1)*t4)*s3 + &
3445 (box(1, 4, 1)*t1 + box(2, 4, 1)*t2 + box(3, 4, 1)*t3 + box(4, 4, 1)*t4)*s4)*v1 + &
3446 ((box(1, 1, 2)*t1 + box(2, 1, 2)*t2 + box(3, 1, 2)*t3 + box(4, 1, 2)*t4)*s1 + &
3447 (box(1, 2, 2)*t1 + box(2, 2, 2)*t2 + box(3, 2, 2)*t3 + box(4, 2, 2)*t4)*s2 + &
3448 (box(1, 3, 2)*t1 + box(2, 3, 2)*t2 + box(3, 3, 2)*t3 + box(4, 3, 2)*t4)*s3 + &
3449 (box(1, 4, 2)*t1 + box(2, 4, 2)*t2 + box(3, 4, 2)*t3 + box(4, 4, 2)*t4)*s4)*v2 + &
3450 ((box(1, 1, 3)*t1 + box(2, 1, 3)*t2 + box(3, 1, 3)*t3 + box(4, 1, 3)*t4)*s1 + &
3451 (box(1, 2, 3)*t1 + box(2, 2, 3)*t2 + box(3, 2, 3)*t3 + box(4, 2, 3)*t4)*s2 + &
3452 (box(1, 3, 3)*t1 + box(2, 3, 3)*t2 + box(3, 3, 3)*t3 + box(4, 3, 3)*t4)*s3 + &
3453 (box(1, 4, 3)*t1 + box(2, 4, 3)*t2 + box(3, 4, 3)*t3 + box(4, 4, 3)*t4)*s4)*v3 + &
3454 ((box(1, 1, 4)*t1 + box(2, 1, 4)*t2 + box(3, 1, 4)*t3 + box(4, 1, 4)*t4)*s1 + &
3455 (box(1, 2, 4)*t1 + box(2, 2, 4)*t2 + box(3, 2, 4)*t3 + box(4, 2, 4)*t4)*s2 + &
3456 (box(1, 3, 4)*t1 + box(2, 3, 4)*t2 + box(3, 3, 4)*t3 + box(4, 3, 4)*t4)*s3 + &
3457 (box(1, 4, 4)*t1 + box(2, 4, 4)*t2 + box(3, 4, 4)*t3 + box(4, 4, 4)*t4)*s4)*v4
3471 val(2) = ((box(1, 1, 1)*t1 + box(2, 1, 1)*t2 + box(3, 1, 1)*t3 + box(4, 1, 1)*t4)*s1 + &
3472 (box(1, 2, 1)*t1 + box(2, 2, 1)*t2 + box(3, 2, 1)*t3 + box(4, 2, 1)*t4)*s2 + &
3473 (box(1, 3, 1)*t1 + box(2, 3, 1)*t2 + box(3, 3, 1)*t3 + box(4, 3, 1)*t4)*s3 + &
3474 (box(1, 4, 1)*t1 + box(2, 4, 1)*t2 + box(3, 4, 1)*t3 + box(4, 4, 1)*t4)*s4)*v1 + &
3475 ((box(1, 1, 2)*t1 + box(2, 1, 2)*t2 + box(3, 1, 2)*t3 + box(4, 1, 2)*t4)*s1 + &
3476 (box(1, 2, 2)*t1 + box(2, 2, 2)*t2 + box(3, 2, 2)*t3 + box(4, 2, 2)*t4)*s2 + &
3477 (box(1, 3, 2)*t1 + box(2, 3, 2)*t2 + box(3, 3, 2)*t3 + box(4, 3, 2)*t4)*s3 + &
3478 (box(1, 4, 2)*t1 + box(2, 4, 2)*t2 + box(3, 4, 2)*t3 + box(4, 4, 2)*t4)*s4)*v2 + &
3479 ((box(1, 1, 3)*t1 + box(2, 1, 3)*t2 + box(3, 1, 3)*t3 + box(4, 1, 3)*t4)*s1 + &
3480 (box(1, 2, 3)*t1 + box(2, 2, 3)*t2 + box(3, 2, 3)*t3 + box(4, 2, 3)*t4)*s2 + &
3481 (box(1, 3, 3)*t1 + box(2, 3, 3)*t2 + box(3, 3, 3)*t3 + box(4, 3, 3)*t4)*s3 + &
3482 (box(1, 4, 3)*t1 + box(2, 4, 3)*t2 + box(3, 4, 3)*t3 + box(4, 4, 3)*t4)*s4)*v3 + &
3483 ((box(1, 1, 4)*t1 + box(2, 1, 4)*t2 + box(3, 1, 4)*t3 + box(4, 1, 4)*t4)*s1 + &
3484 (box(1, 2, 4)*t1 + box(2, 2, 4)*t2 + box(3, 2, 4)*t3 + box(4, 2, 4)*t4)*s2 + &
3485 (box(1, 3, 4)*t1 + box(2, 3, 4)*t2 + box(3, 3, 4)*t3 + box(4, 3, 4)*t4)*s3 + &
3486 (box(1, 4, 4)*t1 + box(2, 4, 4)*t2 + box(3, 4, 4)*t3 + box(4, 4, 4)*t4)*s4)*v4
3500 val(3) = ((box(1, 1, 1)*t1 + box(2, 1, 1)*t2 + box(3, 1, 1)*t3 + box(4, 1, 1)*t4)*s1 + &
3501 (box(1, 2, 1)*t1 + box(2, 2, 1)*t2 + box(3, 2, 1)*t3 + box(4, 2, 1)*t4)*s2 + &
3502 (box(1, 3, 1)*t1 + box(2, 3, 1)*t2 + box(3, 3, 1)*t3 + box(4, 3, 1)*t4)*s3 + &
3503 (box(1, 4, 1)*t1 + box(2, 4, 1)*t2 + box(3, 4, 1)*t3 + box(4, 4, 1)*t4)*s4)*v1 + &
3504 ((box(1, 1, 2)*t1 + box(2, 1, 2)*t2 + box(3, 1, 2)*t3 + box(4, 1, 2)*t4)*s1 + &
3505 (box(1, 2, 2)*t1 + box(2, 2, 2)*t2 + box(3, 2, 2)*t3 + box(4, 2, 2)*t4)*s2 + &
3506 (box(1, 3, 2)*t1 + box(2, 3, 2)*t2 + box(3, 3, 2)*t3 + box(4, 3, 2)*t4)*s3 + &
3507 (box(1, 4, 2)*t1 + box(2, 4, 2)*t2 + box(3, 4, 2)*t3 + box(4, 4, 2)*t4)*s4)*v2 + &
3508 ((box(1, 1, 3)*t1 + box(2, 1, 3)*t2 + box(3, 1, 3)*t3 + box(4, 1, 3)*t4)*s1 + &
3509 (box(1, 2, 3)*t1 + box(2, 2, 3)*t2 + box(3, 2, 3)*t3 + box(4, 2, 3)*t4)*s2 + &
3510 (box(1, 3, 3)*t1 + box(2, 3, 3)*t2 + box(3, 3, 3)*t3 + box(4, 3, 3)*t4)*s3 + &
3511 (box(1, 4, 3)*t1 + box(2, 4, 3)*t2 + box(3, 4, 3)*t3 + box(4, 4, 3)*t4)*s4)*v3 + &
3512 ((box(1, 1, 4)*t1 + box(2, 1, 4)*t2 + box(3, 1, 4)*t3 + box(4, 1, 4)*t4)*s1 + &
3513 (box(1, 2, 4)*t1 + box(2, 2, 4)*t2 + box(3, 2, 4)*t3 + box(4, 2, 4)*t4)*s2 + &
3514 (box(1, 3, 4)*t1 + box(2, 3, 4)*t2 + box(3, 3, 4)*t3 + box(4, 3, 4)*t4)*s3 + &
3515 (box(1, 4, 4)*t1 + box(2, 4, 4)*t2 + box(3, 4, 4)*t3 + box(4, 4, 4)*t4)*s4)*v4
3517 IF (my_mpsum)
CALL pw%pw_grid%para%group%sum(val)
3522 subroutine pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
...
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public twopi
Interface to the message passing library MPI.
integer, parameter, public mp_comm_congruent
computes preconditioners, and implements methods to apply them currently used in qs_ot
integer, parameter, public pw_mode_local
integer, parameter, public fullspace
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public pw_pool_release(pool)
releases the given pool (see cp2k/doc/ReferenceCounting.html)
different utils that are useful to manipulate splines on the regular grid of a pw
logical function, public find_coeffs(values, coeffs, linOp, preconditioner, pool, eps_r, eps_x, max_iter, sumtype)
solves iteratively (CG) a systmes of linear equations linOp(coeffs)=values (for example those needed ...
subroutine, public add_fine2coarse(fine_values_pw, coarse_coeffs_pw, weights_1d, w_border0, w_border1, pbc, safe_computation)
low level function that adds a coarse grid (without boundary) to a fine grid.
integer, parameter, public precond_spl3_3
subroutine, public pw_spline_precond_release(preconditioner)
releases the preconditioner
subroutine, public pw_spline_precond_create(preconditioner, precond_kind, pool, pbc, transpose)
...
subroutine, public pw_nn_deriv_r(pw_in, pw_out, coeffs, idir)
calculates a nearest neighbor central derivative. for the x dir: pw_outarray(i,j,k)=( pw_in(i+1,...
subroutine, public pw_spline_do_precond(preconditioner, in_v, out_v)
applies the preconditioner to the system of equations to find the coefficients of the spline
subroutine, public pw_spline3_deriv_g(spline_g, idir)
calculates the FFT of the values of the x,y,z (idir=1,2,3) derivative of the cubic spline
subroutine, public pw_spline_precond_set_kind(preconditioner, precond_kind, pbc, transpose)
switches the types of precoditioner to use
real(kind=dp), dimension(4), parameter, public spl3_1d_transf_coeffs
real(kind=dp), dimension(3), parameter, public spl3_1d_transf_border1
real(kind=dp), dimension(4), parameter, public spline2_coeffs
subroutine, public add_coarse2fine(coarse_coeffs_pw, fine_values_pw, weights_1d, w_border0, w_border1, pbc, safe_computation)
low level function that adds a coarse grid to a fine grid. If pbc is true periodic boundary condition...
real(kind=dp) function, dimension(3), public eval_d_interp_spl3_pbc(vec, pw)
Evaluates the derivatives of the PBC interpolated Spline (pw) function on the generic input vector (v...
real(kind=dp) function, public eval_interp_spl3_pbc(vec, pw)
Evaluates the PBC interpolated Spline (pw) function on the generic input vector (vec)
real(kind=dp), dimension(3), parameter, public spline3_deriv_coeffs
integer, parameter, public precond_spl3_aint
subroutine, public pw_spline_scale_deriv(deriv_vals_r, transpose, scale)
rescales the derivatives from gridspacing=1 to the real derivatives
real(kind=dp), dimension(3), parameter, public spline2_deriv_coeffs
subroutine, public pw_nn_smear_r(pw_in, pw_out, coeffs)
calculates the values of a nearest neighbor smearing
real(kind=dp), dimension(4), parameter, public spline3_coeffs
subroutine, public spl3_nopbc(pw_in, pw_out)
...
real(kind=dp), dimension(3), parameter, public nn50_deriv_coeffs
subroutine, public pw_spline3_interpolate_values_g(spline_g)
calculates the FFT of the coefficients of the2 cubic spline that interpolates the given values
subroutine, public pw_spline2_interpolate_values_g(spline_g)
calculates the FFT of the coefficients of the quadratic spline that interpolates the given values
subroutine, public spl3_nopbct(pw_in, pw_out)
...
real(kind=dp), dimension(3), parameter, public nn10_deriv_coeffs
real(kind=dp), dimension(4), parameter, public spl3_precond1_coeff
real(kind=dp), dimension(3), parameter, public spl3_1d_coeffs0
subroutine, public pw_spline2_deriv_g(spline_g, idir)
calculates the FFT of the values of the x,y,z (idir=1,2,3) derivative of the quadratic spline
real(kind=dp), dimension(4), parameter, public spl3_aint_coeff
subroutine, public spl3_pbc(pw_in, pw_out)
...
integer, parameter, public no_precond
subroutine pw_nn_compose_r_no_pbc(weights_1d, pw_in, pw_out, sharpen, normalize, transpose, smooth_boundary)
adds to pw_out pw_in composed with the weights pw_outarray(i,j,k)=pw_outarray(i,j,...
integer, parameter, public precond_spl3_2
real(kind=dp), dimension(4), parameter, public nn10_coeffs
integer, parameter, public precond_spl3_aint2
real(kind=dp), dimension(4), parameter, public nn50_coeffs
integer, parameter, public precond_spl3_1