278 rhoa, rhob, norm_drhoa, norm_drhob, rho_1_3, rhoa_1_3, &
279 rhob_1_3, laplace_rho, laplace_rhoa, laplace_rhob, drhoa, drhob, rho_cutoff, &
280 drho_cutoff, tau_cutoff, tau, tau_a, tau_b, local_bounds)
282 LOGICAL,
INTENT(in),
OPTIONAL :: can_return_null
283 REAL(kind=
dp),
DIMENSION(:, :, :),
OPTIONAL, &
286 REAL(kind=
dp),
DIMENSION(:, :, :),
OPTIONAL, &
287 POINTER :: norm_drho, rhoa, rhob, norm_drhoa, &
288 norm_drhob, rho_1_3, rhoa_1_3, &
289 rhob_1_3, laplace_rho, laplace_rhoa, &
292 REAL(kind=
dp),
INTENT(out),
OPTIONAL :: rho_cutoff, drho_cutoff, tau_cutoff
293 REAL(kind=
dp),
DIMENSION(:, :, :),
OPTIONAL, &
294 POINTER :: tau, tau_a, tau_b
295 INTEGER,
DIMENSION(2, 3),
INTENT(OUT),
OPTIONAL :: local_bounds
298 LOGICAL :: my_can_return_null
300 my_can_return_null = .false.
301 IF (
PRESENT(can_return_null)) my_can_return_null = can_return_null
303 IF (
PRESENT(rho))
THEN
305 cpassert(my_can_return_null .OR.
ASSOCIATED(rho))
307 IF (
PRESENT(drho))
THEN
309 drho(i)%array => rho_set%drho(i)%array
310 cpassert(my_can_return_null .OR.
ASSOCIATED(rho_set%drho(i)%array))
313 IF (
PRESENT(norm_drho))
THEN
314 norm_drho => rho_set%norm_drho
315 cpassert(my_can_return_null .OR.
ASSOCIATED(norm_drho))
317 IF (
PRESENT(laplace_rho))
THEN
318 laplace_rho => rho_set%laplace_rho
319 cpassert(my_can_return_null .OR.
ASSOCIATED(laplace_rho))
321 IF (
PRESENT(rhoa))
THEN
323 cpassert(my_can_return_null .OR.
ASSOCIATED(rhoa))
325 IF (
PRESENT(rhob))
THEN
327 cpassert(my_can_return_null .OR.
ASSOCIATED(rhob))
329 IF (
PRESENT(drhoa))
THEN
331 drhoa(i)%array => rho_set%drhoa(i)%array
332 cpassert(my_can_return_null .OR.
ASSOCIATED(rho_set%drhoa(i)%array))
335 IF (
PRESENT(drhob))
THEN
337 drhob(i)%array => rho_set%drhob(i)%array
338 cpassert(my_can_return_null .OR.
ASSOCIATED(rho_set%drhob(i)%array))
341 IF (
PRESENT(laplace_rhoa))
THEN
342 laplace_rhoa => rho_set%laplace_rhoa
343 cpassert(my_can_return_null .OR.
ASSOCIATED(laplace_rhoa))
345 IF (
PRESENT(laplace_rhob))
THEN
346 laplace_rhob => rho_set%laplace_rhob
347 cpassert(my_can_return_null .OR.
ASSOCIATED(laplace_rhob))
349 IF (
PRESENT(norm_drhoa))
THEN
350 norm_drhoa => rho_set%norm_drhoa
351 cpassert(my_can_return_null .OR.
ASSOCIATED(norm_drhoa))
353 IF (
PRESENT(norm_drhob))
THEN
354 norm_drhob => rho_set%norm_drhob
355 cpassert(my_can_return_null .OR.
ASSOCIATED(norm_drhob))
357 IF (
PRESENT(rho_1_3))
THEN
358 rho_1_3 => rho_set%rho_1_3
359 cpassert(my_can_return_null .OR.
ASSOCIATED(rho_1_3))
361 IF (
PRESENT(rhoa_1_3))
THEN
362 rhoa_1_3 => rho_set%rhoa_1_3
363 cpassert(my_can_return_null .OR.
ASSOCIATED(rhoa_1_3))
365 IF (
PRESENT(rhob_1_3))
THEN
366 rhob_1_3 => rho_set%rhob_1_3
367 cpassert(my_can_return_null .OR.
ASSOCIATED(rhob_1_3))
369 IF (
PRESENT(tau))
THEN
371 cpassert(my_can_return_null .OR.
ASSOCIATED(tau))
373 IF (
PRESENT(tau_a))
THEN
374 tau_a => rho_set%tau_a
375 cpassert(my_can_return_null .OR.
ASSOCIATED(tau_a))
377 IF (
PRESENT(tau_b))
THEN
378 tau_b => rho_set%tau_b
379 cpassert(my_can_return_null .OR.
ASSOCIATED(tau_b))
381 IF (
PRESENT(rho_cutoff)) rho_cutoff = rho_set%rho_cutoff
382 IF (
PRESENT(drho_cutoff)) drho_cutoff = rho_set%drho_cutoff
383 IF (
PRESENT(tau_cutoff)) tau_cutoff = rho_set%tau_cutoff
384 IF (
PRESENT(local_bounds)) local_bounds = rho_set%local_bounds
418 rhoa, rhob, norm_drhoa, norm_drhob, rho_1_3, rhoa_1_3, &
419 rhob_1_3, laplace_rho, laplace_rhoa, laplace_rhob, drhoa, drhob, &
422 TYPE(
pw_r3d_rs_type),
DIMENSION(3),
OPTIONAL,
INTENT(OUT) :: drho, drhoa, drhob
423 TYPE(
pw_r3d_rs_type),
OPTIONAL,
POINTER :: rho, norm_drho, rhoa, rhob, norm_drhoa, &
424 norm_drhob, rho_1_3, rhoa_1_3, &
425 rhob_1_3, laplace_rho, laplace_rhoa, &
426 laplace_rhob, tau, tau_a, tau_b
429 LOGICAL,
INTENT(OUT) :: owns_data
433 IF (
PRESENT(rho))
THEN
436 CALL xc_rho_set_recover_pw_low(rho, rho_set%rho, pw_grid, pw_pool)
437 NULLIFY (rho_set%rho)
438 owns_data = rho_set%owns%rho
440 IF (
PRESENT(drho))
THEN
442 CALL xc_rho_set_recover_pw_low(drho(i), rho_set%drho(i)%array, pw_grid, pw_pool, rho_set%drhoa(i)%array,&
443 & rho_set%drhob(i)%array)
447 IF (
PRESENT(norm_drho))
THEN
450 CALL xc_rho_set_recover_pw_low(norm_drho, rho_set%norm_drho, pw_grid, pw_pool)
451 NULLIFY (rho_set%norm_drho)
452 owns_data = rho_set%owns%norm_drho
454 IF (
PRESENT(rhoa))
THEN
457 CALL xc_rho_set_recover_pw_low(rhoa, rho_set%rhoa, pw_grid, pw_pool)
458 NULLIFY (rho_set%rhoa)
459 owns_data = rho_set%owns%rho_spin
461 IF (
PRESENT(rhob))
THEN
464 CALL xc_rho_set_recover_pw_low(rhob, rho_set%rhob, pw_grid, pw_pool)
465 NULLIFY (rho_set%rhob)
466 owns_data = rho_set%owns%rho_spin
468 IF (
PRESENT(norm_drhoa))
THEN
470 ALLOCATE (norm_drhoa)
471 CALL xc_rho_set_recover_pw_low(norm_drhoa, rho_set%norm_drhoa, pw_grid, pw_pool)
472 NULLIFY (rho_set%norm_drhoa)
473 owns_data = rho_set%owns%norm_drho_spin
475 IF (
PRESENT(norm_drhob))
THEN
477 ALLOCATE (norm_drhob)
478 CALL xc_rho_set_recover_pw_low(norm_drhob, rho_set%norm_drhob, pw_grid, pw_pool)
479 NULLIFY (rho_set%norm_drhob)
480 owns_data = rho_set%owns%norm_drho_spin
482 IF (
PRESENT(rho_1_3))
THEN
485 CALL xc_rho_set_recover_pw_low(rho_1_3, rho_set%rho_1_3, pw_grid, pw_pool)
486 NULLIFY (rho_set%rho_1_3)
487 owns_data = rho_set%owns%rho_1_3
489 IF (
PRESENT(rhoa_1_3))
THEN
492 CALL xc_rho_set_recover_pw_low(rhoa_1_3, rho_set%rhoa_1_3, pw_grid, pw_pool)
493 NULLIFY (rho_set%rhoa_1_3)
494 owns_data = rho_set%owns%rho_spin_1_3
496 IF (
PRESENT(rhob_1_3))
THEN
499 CALL xc_rho_set_recover_pw_low(rhob_1_3, rho_set%rhob_1_3, pw_grid, pw_pool)
500 NULLIFY (rho_set%rhob_1_3)
501 owns_data = rho_set%owns%rho_spin_1_3
503 IF (
PRESENT(laplace_rho))
THEN
504 NULLIFY (laplace_rho)
505 ALLOCATE (laplace_rho)
506 CALL xc_rho_set_recover_pw_low(laplace_rho, rho_set%laplace_rho, pw_grid, pw_pool)
507 NULLIFY (rho_set%laplace_rho)
508 owns_data = rho_set%owns%laplace_rho
510 IF (
PRESENT(laplace_rhoa))
THEN
511 NULLIFY (laplace_rhoa)
512 ALLOCATE (laplace_rhoa)
513 CALL xc_rho_set_recover_pw_low(laplace_rhoa, rho_set%laplace_rhoa, pw_grid, pw_pool)
514 NULLIFY (rho_set%laplace_rhoa)
515 owns_data = rho_set%owns%laplace_rho_spin
517 IF (
PRESENT(laplace_rhob))
THEN
518 NULLIFY (laplace_rhob)
519 ALLOCATE (laplace_rhob)
520 CALL xc_rho_set_recover_pw_low(laplace_rhob, rho_set%laplace_rhob, pw_grid, pw_pool)
521 NULLIFY (rho_set%laplace_rhob)
522 owns_data = rho_set%owns%laplace_rho_spin
524 IF (
PRESENT(drhoa))
THEN
526 CALL xc_rho_set_recover_pw_low(drhoa(i), rho_set%drhoa(i)%array, pw_grid, pw_pool)
528 owns_data = rho_set%owns%drho_spin
530 IF (
PRESENT(drhob))
THEN
532 CALL xc_rho_set_recover_pw_low(drhob(i), rho_set%drhob(i)%array, pw_grid, pw_pool)
534 owns_data = rho_set%owns%drho_spin
536 IF (
PRESENT(tau))
THEN
539 CALL xc_rho_set_recover_pw_low(tau, rho_set%tau, pw_grid, pw_pool)
540 NULLIFY (rho_set%tau)
541 owns_data = rho_set%owns%tau
543 IF (
PRESENT(tau_a))
THEN
546 CALL xc_rho_set_recover_pw_low(tau_a, rho_set%tau_a, pw_grid, pw_pool)
547 NULLIFY (rho_set%tau_a)
548 owns_data = rho_set%owns%tau_spin
550 IF (
PRESENT(tau_b))
THEN
553 CALL xc_rho_set_recover_pw_low(tau_b, rho_set%tau_b, pw_grid, pw_pool)
554 NULLIFY (rho_set%tau_b)
555 owns_data = rho_set%owns%tau_spin
690 xc_deriv_method_id, xc_rho_smooth_id, pw_pool)
696 INTEGER,
INTENT(IN) :: xc_deriv_method_id, xc_rho_smooth_id
699 REAL(kind=
dp),
PARAMETER :: f13 = (1.0_dp/3.0_dp)
701 INTEGER :: i, idir, ispin, j, k, nspins
702 LOGICAL :: gradient_f, my_rho_g_local, &
703 needs_laplace, needs_rho_g
704 REAL(kind=
dp) :: rho_cutoff
710 IF (any(rho_set%local_bounds /= pw_pool%pw_grid%bounds_local)) &
711 cpabort(
"pw_pool cr3d have different size than expected")
713 rho_set%local_bounds = rho_r(1)%pw_grid%bounds_local
714 rho_cutoff = 0.5*rho_set%rho_cutoff
716 my_rho_g_local = .false.
720 cpassert(.NOT. needs%rho_spin)
721 cpassert(.NOT. needs%drho_spin)
722 cpassert(.NOT. needs%norm_drho_spin)
723 cpassert(.NOT. needs%rho_spin_1_3)
724 cpassert(.NOT. needs%tau_spin)
725 cpassert(.NOT. needs%laplace_rho_spin)
727 cpassert(.NOT. needs%rho)
728 cpassert(.NOT. needs%drho)
729 cpassert(.NOT. needs%rho_1_3)
730 cpassert(.NOT. needs%tau)
731 cpassert(.NOT. needs%laplace_rho)
733 cpabort(
"Unknown number of spin states")
736 CALL xc_rho_set_clean(rho_set, pw_pool=pw_pool)
738 needs_laplace = (needs%laplace_rho .OR. needs%laplace_rho_spin)
739 gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
740 needs%drho .OR. needs%norm_drho .OR. &
744 xc_deriv_method_id ==
xc_deriv_pw)) .AND. (gradient_f .OR. needs_laplace)
745 IF ((gradient_f .AND. needs_laplace) .AND. &
747 CALL cp_abort(__location__, &
748 "MGGA functionals that require the Laplacian are "// &
749 "only compatible with 'XC_DERIV PW' and 'XC_SMOOTH_RHO NONE'")
752 IF (needs_rho_g)
THEN
753 CALL pw_pool%create_pw(tmp_g)
756 CALL pw_pool%create_pw(my_rho_r(ispin))
759 IF (needs_rho_g)
THEN
760 IF (
ASSOCIATED(rho_g))
THEN
761 my_rho_g_local = .false.
762 my_rho_g = rho_g(ispin)
766 CALL pw_copy(rho_r(ispin), my_rho_r(ispin))
768 CALL xc_pw_smooth(rho_r(ispin), my_rho_r(ispin), xc_rho_smooth_id)
776 CALL pw_pool%create_pw(drho_r(idir, ispin))
778 IF (needs_rho_g)
THEN
779 IF (.NOT.
ASSOCIATED(my_rho_g%pw_grid))
THEN
780 my_rho_g_local = .true.
781 CALL pw_pool%create_pw(my_rho_g)
784 IF (.NOT. my_rho_g_local .AND. (xc_deriv_method_id ==
xc_deriv_spline2 .OR. &
786 CALL pw_pool%create_pw(my_rho_g)
787 my_rho_g_local = .true.
788 CALL pw_copy(rho_g(ispin), my_rho_g)
791 IF (needs%laplace_rho .OR. needs%laplace_rho_spin)
THEN
792 CALL pw_pool%create_pw(laplace_rho_r(ispin))
793 CALL xc_pw_laplace(my_rho_g, pw_pool, xc_deriv_method_id, laplace_rho_r(ispin), tmp_g=tmp_g)
795 CALL xc_pw_gradient(my_rho_r(ispin), my_rho_g, tmp_g, drho_r(:, ispin), xc_deriv_method_id)
797 IF (needs_rho_g)
THEN
798 IF (my_rho_g_local)
THEN
799 my_rho_g_local = .false.
800 CALL pw_pool%give_back_pw(my_rho_g)
812 IF (
ASSOCIATED(tmp_g%pw_grid))
THEN
813 CALL pw_pool%give_back_pw(tmp_g)
818 IF (needs%rho_1_3)
THEN
819 CALL pw_pool%create_cr3d(rho_set%rho_1_3)
821 DO k = rho_set%local_bounds(1, 3), rho_set%local_bounds(2, 3)
822 DO j = rho_set%local_bounds(1, 2), rho_set%local_bounds(2, 2)
823 DO i = rho_set%local_bounds(1, 1), rho_set%local_bounds(2, 1)
824 rho_set%rho_1_3(i, j, k) = max(my_rho_r(1)%array(i, j, k), 0.0_dp)**f13
828 rho_set%owns%rho_1_3 = .true.
829 rho_set%has%rho_1_3 = .true.
832 rho_set%rho => my_rho_r(1)%array
833 NULLIFY (my_rho_r(1)%array)
834 rho_set%owns%rho = .true.
835 rho_set%has%rho = .true.
837 IF (needs%norm_drho)
THEN
838 CALL pw_pool%create_cr3d(rho_set%norm_drho)
840 DO k = rho_set%local_bounds(1, 3), rho_set%local_bounds(2, 3)
841 DO j = rho_set%local_bounds(1, 2), rho_set%local_bounds(2, 2)
842 DO i = rho_set%local_bounds(1, 1), rho_set%local_bounds(2, 1)
843 rho_set%norm_drho(i, j, k) = sqrt( &
844 drho_r(1, 1)%array(i, j, k)**2 + &
845 drho_r(2, 1)%array(i, j, k)**2 + &
846 drho_r(3, 1)%array(i, j, k)**2)
850 rho_set%owns%norm_drho = .true.
851 rho_set%has%norm_drho = .true.
853 IF (needs%laplace_rho)
THEN
854 rho_set%laplace_rho => laplace_rho_r(1)%array
855 NULLIFY (laplace_rho_r(1)%array)
856 rho_set%owns%laplace_rho = .true.
857 rho_set%has%laplace_rho = .true.
862 rho_set%drho(idir)%array => drho_r(idir, 1)%array
863 NULLIFY (drho_r(idir, 1)%array)
865 rho_set%owns%drho = .true.
866 rho_set%has%drho = .true.
869 IF (needs%rho_spin_1_3)
THEN
870 CALL pw_pool%create_cr3d(rho_set%rhoa_1_3)
873 DO k = rho_set%local_bounds(1, 3), rho_set%local_bounds(2, 3)
874 DO j = rho_set%local_bounds(1, 2), rho_set%local_bounds(2, 2)
875 DO i = rho_set%local_bounds(1, 1), rho_set%local_bounds(2, 1)
876 rho_set%rhoa_1_3(i, j, k) = max(my_rho_r(1)%array(i, j, k), 0.0_dp)**f13
880 CALL pw_pool%create_cr3d(rho_set%rhob_1_3)
883 DO k = rho_set%local_bounds(1, 3), rho_set%local_bounds(2, 3)
884 DO j = rho_set%local_bounds(1, 2), rho_set%local_bounds(2, 2)
885 DO i = rho_set%local_bounds(1, 1), rho_set%local_bounds(2, 1)
886 rho_set%rhob_1_3(i, j, k) = max(my_rho_r(2)%array(i, j, k), 0.0_dp)**f13
890 rho_set%owns%rho_spin_1_3 = .true.
891 rho_set%has%rho_spin_1_3 = .true.
893 IF (needs%norm_drho)
THEN
895 CALL pw_pool%create_cr3d(rho_set%norm_drho)
897 DO k = rho_set%local_bounds(1, 3), rho_set%local_bounds(2, 3)
898 DO j = rho_set%local_bounds(1, 2), rho_set%local_bounds(2, 2)
899 DO i = rho_set%local_bounds(1, 1), rho_set%local_bounds(2, 1)
900 rho_set%norm_drho(i, j, k) = sqrt( &
901 (drho_r(1, 1)%array(i, j, k) + drho_r(1, 2)%array(i, j, k))**2 + &
902 (drho_r(2, 1)%array(i, j, k) + drho_r(2, 2)%array(i, j, k))**2 + &
903 (drho_r(3, 1)%array(i, j, k) + drho_r(3, 2)%array(i, j, k))**2)
908 rho_set%owns%norm_drho = .true.
909 rho_set%has%norm_drho = .true.
911 IF (needs%rho_spin)
THEN
913 rho_set%rhoa => my_rho_r(1)%array
914 NULLIFY (my_rho_r(1)%array)
916 rho_set%rhob => my_rho_r(2)%array
917 NULLIFY (my_rho_r(2)%array)
919 rho_set%owns%rho_spin = .true.
920 rho_set%has%rho_spin = .true.
922 IF (needs%norm_drho_spin)
THEN
924 CALL pw_pool%create_cr3d(rho_set%norm_drhoa)
926 DO k = rho_set%local_bounds(1, 3), rho_set%local_bounds(2, 3)
927 DO j = rho_set%local_bounds(1, 2), rho_set%local_bounds(2, 2)
928 DO i = rho_set%local_bounds(1, 1), rho_set%local_bounds(2, 1)
929 rho_set%norm_drhoa(i, j, k) = sqrt( &
930 drho_r(1, 1)%array(i, j, k)**2 + &
931 drho_r(2, 1)%array(i, j, k)**2 + &
932 drho_r(3, 1)%array(i, j, k)**2)
937 CALL pw_pool%create_cr3d(rho_set%norm_drhob)
938 rho_set%owns%norm_drho_spin = .true.
940 DO k = rho_set%local_bounds(1, 3), rho_set%local_bounds(2, 3)
941 DO j = rho_set%local_bounds(1, 2), rho_set%local_bounds(2, 2)
942 DO i = rho_set%local_bounds(1, 1), rho_set%local_bounds(2, 1)
943 rho_set%norm_drhob(i, j, k) = sqrt( &
944 drho_r(1, 2)%array(i, j, k)**2 + &
945 drho_r(2, 2)%array(i, j, k)**2 + &
946 drho_r(3, 2)%array(i, j, k)**2)
951 rho_set%owns%norm_drho_spin = .true.
952 rho_set%has%norm_drho_spin = .true.
954 IF (needs%laplace_rho_spin)
THEN
955 rho_set%laplace_rhoa => laplace_rho_r(1)%array
956 NULLIFY (laplace_rho_r(1)%array)
958 rho_set%laplace_rhob => laplace_rho_r(2)%array
959 NULLIFY (laplace_rho_r(2)%array)
961 rho_set%owns%laplace_rho_spin = .true.
962 rho_set%has%laplace_rho_spin = .true.
964 IF (needs%drho_spin)
THEN
966 rho_set%drhoa(idir)%array => drho_r(idir, 1)%array
967 NULLIFY (drho_r(idir, 1)%array)
968 rho_set%drhob(idir)%array => drho_r(idir, 2)%array
969 NULLIFY (drho_r(idir, 2)%array)
971 rho_set%owns%drho_spin = .true.
972 rho_set%has%drho_spin = .true.
977 IF (needs%laplace_rho .OR. needs%laplace_rho_spin)
THEN
978 CALL pw_pool%give_back_pw(laplace_rho_r(ispin))
981 CALL pw_pool%give_back_pw(drho_r(idir, ispin))
985 CALL pw_pool%give_back_pw(my_rho_r(ispin))
989 IF (needs%tau .OR. needs%tau_spin)
THEN
990 cpassert(
ASSOCIATED(tau))
992 cpassert(
ASSOCIATED(tau(ispin)%array))
996 rho_set%tau => tau(1)%array
997 rho_set%owns%tau = .false.
998 rho_set%has%tau = .true.
1000 IF (needs%tau_spin)
THEN
1001 rho_set%tau_a => tau(1)%array
1002 rho_set%tau_b => tau(2)%array
1003 rho_set%owns%tau_spin = .false.
1004 rho_set%has%tau_spin = .true.