LCOV - code coverage report
Current view: top level - src - qs_linres_nmr_shift.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 100.0 % 446 446
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 6 6

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief from the response current density calculates the shift tensor
      10              : !>      and the susceptibility
      11              : !> \par History
      12              : !>      created 02-2006 [MI]
      13              : !> \author MI
      14              : ! **************************************************************************************************
      15              : MODULE qs_linres_nmr_shift
      16              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      17              :                                               get_atomic_kind
      18              :    USE cell_types,                      ONLY: cell_type,&
      19              :                                               pbc
      20              :    USE cp_control_types,                ONLY: dft_control_type
      21              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      22              :                                               cp_logger_get_default_io_unit,&
      23              :                                               cp_logger_type
      24              :    USE cp_output_handling,              ONLY: cp_p_file,&
      25              :                                               cp_print_key_finished_output,&
      26              :                                               cp_print_key_should_output,&
      27              :                                               cp_print_key_unit_nr
      28              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      29              :                                               section_vals_type,&
      30              :                                               section_vals_val_get
      31              :    USE kinds,                           ONLY: default_string_length,&
      32              :                                               dp
      33              :    USE mathconstants,                   ONLY: gaussi,&
      34              :                                               twopi,&
      35              :                                               z_zero
      36              :    USE mathlib,                         ONLY: diamat_all
      37              :    USE message_passing,                 ONLY: mp_para_env_type
      38              :    USE particle_types,                  ONLY: particle_type
      39              :    USE pw_env_types,                    ONLY: pw_env_get,&
      40              :                                               pw_env_type
      41              :    USE pw_grid_types,                   ONLY: pw_grid_type
      42              :    USE pw_methods,                      ONLY: pw_axpy,&
      43              :                                               pw_transfer,&
      44              :                                               pw_zero
      45              :    USE pw_pool_types,                   ONLY: pw_pool_p_type,&
      46              :                                               pw_pool_type
      47              :    USE pw_spline_utils,                 ONLY: Eval_Interp_Spl3_pbc,&
      48              :                                               find_coeffs,&
      49              :                                               pw_spline_do_precond,&
      50              :                                               pw_spline_precond_create,&
      51              :                                               pw_spline_precond_release,&
      52              :                                               pw_spline_precond_set_kind,&
      53              :                                               pw_spline_precond_type,&
      54              :                                               spl3_pbc
      55              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      56              :                                               pw_r3d_rs_type
      57              :    USE qs_environment_types,            ONLY: get_qs_env,&
      58              :                                               qs_environment_type
      59              :    USE qs_grid_atom,                    ONLY: grid_atom_type
      60              :    USE qs_harmonics_atom,               ONLY: harmonics_atom_type
      61              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      62              :                                               qs_kind_type
      63              :    USE qs_linres_nmr_epr_common_utils,  ONLY: mult_G_ov_G2_grid
      64              :    USE qs_linres_op,                    ONLY: fac_vecp,&
      65              :                                               set_vecp,&
      66              :                                               set_vecp_rev
      67              :    USE qs_linres_types,                 ONLY: current_env_type,&
      68              :                                               get_current_env,&
      69              :                                               get_nmr_env,&
      70              :                                               jrho_atom_type,&
      71              :                                               nmr_env_type
      72              :    USE qs_rho_types,                    ONLY: qs_rho_get
      73              :    USE realspace_grid_types,            ONLY: realspace_grid_desc_type
      74              :    USE util,                            ONLY: get_limit
      75              : #include "./base/base_uses.f90"
      76              : 
      77              :    IMPLICIT NONE
      78              : 
      79              :    PRIVATE
      80              : 
      81              :    ! *** Public subroutines ***
      82              :    PUBLIC :: nmr_shift_print, &
      83              :              nmr_shift
      84              : 
      85              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_nmr_shift'
      86              : 
      87              : ! **************
      88              : 
      89              : CONTAINS
      90              : 
      91              : ! **************************************************************************************************
      92              : !> \brief ...
      93              : !> \param nmr_env ...
      94              : !> \param current_env ...
      95              : !> \param qs_env ...
      96              : !> \param iB ...
      97              : ! **************************************************************************************************
      98          480 :    SUBROUTINE nmr_shift(nmr_env, current_env, qs_env, iB)
      99              : 
     100              :       TYPE(nmr_env_type)                                 :: nmr_env
     101              :       TYPE(current_env_type)                             :: current_env
     102              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     103              :       INTEGER, INTENT(IN)                                :: iB
     104              : 
     105              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'nmr_shift'
     106              : 
     107              :       INTEGER                                            :: handle, idir, idir2, idir3, iiB, iiiB, &
     108              :                                                             ispin, natom, nspins
     109              :       LOGICAL                                            :: gapw, interpolate_shift
     110              :       REAL(dp)                                           :: scale_fac
     111          480 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: chemical_shift, chemical_shift_loc, &
     112          480 :                                                             chemical_shift_nics, &
     113          480 :                                                             chemical_shift_nics_loc
     114              :       TYPE(cell_type), POINTER                           :: cell
     115              :       TYPE(dft_control_type), POINTER                    :: dft_control
     116          480 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     117              :       TYPE(pw_c1d_gs_type)                               :: pw_gspace_work
     118          480 :       TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:, :) :: shift_pw_gspace
     119          480 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: jrho1_g
     120              :       TYPE(pw_env_type), POINTER                         :: pw_env
     121          480 :       TYPE(pw_pool_p_type), DIMENSION(:), POINTER        :: pw_pools
     122              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     123              :       TYPE(pw_r3d_rs_type)                               :: shift_pw_rspace
     124              :       TYPE(realspace_grid_desc_type), POINTER            :: auxbas_rs_desc
     125              :       TYPE(section_vals_type), POINTER                   :: nmr_section
     126              : 
     127          480 :       CALL timeset(routineN, handle)
     128              : 
     129          480 :       NULLIFY (chemical_shift, chemical_shift_loc, chemical_shift_nics, &
     130          480 :                chemical_shift_nics_loc, cell, dft_control, pw_env, &
     131          480 :                auxbas_rs_desc, auxbas_pw_pool, pw_pools, particle_set, jrho1_g)
     132              : 
     133              :       CALL get_qs_env(qs_env=qs_env, cell=cell, dft_control=dft_control, &
     134          480 :                       particle_set=particle_set)
     135              : 
     136          480 :       gapw = dft_control%qs_control%gapw
     137          480 :       natom = SIZE(particle_set, 1)
     138          480 :       nspins = dft_control%nspins
     139              : 
     140              :       CALL get_nmr_env(nmr_env=nmr_env, chemical_shift=chemical_shift, &
     141              :                        chemical_shift_loc=chemical_shift_loc, &
     142              :                        chemical_shift_nics=chemical_shift_nics, &
     143              :                        chemical_shift_nics_loc=chemical_shift_nics_loc, &
     144          480 :                        interpolate_shift=interpolate_shift)
     145              : 
     146          480 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
     147              :       CALL pw_env_get(pw_env, auxbas_rs_desc=auxbas_rs_desc, &
     148          480 :                       auxbas_pw_pool=auxbas_pw_pool, pw_pools=pw_pools)
     149              :       !
     150              :       !
     151              :       nmr_section => section_vals_get_subs_vals(qs_env%input, &
     152          480 :            & "PROPERTIES%LINRES%NMR")
     153              :       !
     154              :       ! Initialize
     155              :       ! Allocate grids for the calculation of jrho and the shift
     156         4104 :       ALLOCATE (shift_pw_gspace(3, nspins))
     157         1146 :       DO ispin = 1, nspins
     158         3144 :          DO idir = 1, 3
     159         1998 :             CALL auxbas_pw_pool%create_pw(shift_pw_gspace(idir, ispin))
     160         2664 :             CALL pw_zero(shift_pw_gspace(idir, ispin))
     161              :          END DO
     162              :       END DO
     163              :       !
     164              :       !
     165          480 :       CALL set_vecp(iB, iiB, iiiB)
     166              :       !
     167          480 :       CALL auxbas_pw_pool%create_pw(pw_gspace_work)
     168          480 :       CALL pw_zero(pw_gspace_work)
     169         1146 :       DO ispin = 1, nspins
     170              :          !
     171         3144 :          DO idir = 1, 3
     172         1998 :             CALL qs_rho_get(current_env%jrho1_set(idir)%rho, rho_g=jrho1_g)
     173              :             ! Field gradient
     174              :             ! loop over the Gvec  components: x,y,z
     175         8658 :             DO idir2 = 1, 3
     176         7992 :                IF (idir /= idir2) THEN
     177              :                   ! in reciprocal space multiply (G_idir2(i)/G(i)^2)J_(idir)(G(i))
     178              :                   CALL mult_G_ov_G2_grid(auxbas_pw_pool, jrho1_g(ispin), &
     179         3996 :                                          pw_gspace_work, idir2, 0.0_dp)
     180              :                   !
     181              :                   ! scale and add to the correct component of the shift column
     182         3996 :                   CALL set_vecp_rev(idir, idir2, idir3)
     183         3996 :                   scale_fac = fac_vecp(idir3, idir2, idir)
     184         3996 :                   CALL pw_axpy(pw_gspace_work, shift_pw_gspace(idir3, ispin), scale_fac)
     185              :                END IF
     186              :             END DO
     187              :             !
     188              :          END DO ! idir
     189              :       END DO ! ispin
     190              :       !
     191          480 :       CALL auxbas_pw_pool%give_back_pw(pw_gspace_work)
     192              :       !
     193              :       ! compute shildings
     194          480 :       IF (interpolate_shift) THEN
     195           24 :          CALL auxbas_pw_pool%create_pw(shift_pw_rspace)
     196           60 :          DO ispin = 1, nspins
     197          168 :             DO idir = 1, 3
     198              :                ! Here first G->R and then interpolation to get the shifts.
     199              :                ! The interpolation doesnt work in parallel yet.
     200              :                ! The choice between both methods should be left to the user.
     201          108 :                CALL pw_transfer(shift_pw_gspace(idir, ispin), shift_pw_rspace)
     202              :                CALL interpolate_shift_pwgrid(nmr_env, pw_env, particle_set, cell, shift_pw_rspace, &
     203          144 :                                              iB, idir, nmr_section)
     204              :             END DO
     205              :          END DO
     206           24 :          CALL auxbas_pw_pool%give_back_pw(shift_pw_rspace)
     207              :       ELSE
     208         1086 :          DO ispin = 1, nspins
     209         2976 :             DO idir = 1, 3
     210              :                ! Here the shifts are computed from summation of the coeff on the G-grip .
     211              :                CALL gsum_shift_pwgrid(nmr_env, particle_set, cell, &
     212         2520 :                                       shift_pw_gspace(idir, ispin), iB, idir)
     213              :             END DO
     214              :          END DO
     215              :       END IF
     216              :       !
     217          480 :       IF (gapw) THEN
     218         1032 :          DO idir = 1, 3
     219              :             ! Finally the radial functions are multiplied by the YLM and properly summed
     220              :             ! The resulting array is J on the local grid. One array per atom.
     221              :             ! Local contributions by numerical integration over the spherical grids
     222         1032 :             CALL nmr_shift_gapw(nmr_env, current_env, qs_env, iB, idir)
     223              :          END DO ! idir
     224              :       END IF
     225              :       !
     226              :       ! Dellocate grids for the calculation of jrho and the shift
     227         1146 :       DO ispin = 1, nspins
     228         3144 :          DO idir = 1, 3
     229         2664 :             CALL auxbas_pw_pool%give_back_pw(shift_pw_gspace(idir, ispin))
     230              :          END DO
     231              :       END DO
     232          480 :       DEALLOCATE (shift_pw_gspace)
     233              :       !
     234              :       ! Finalize
     235          480 :       CALL timestop(handle)
     236              :       !
     237         1440 :    END SUBROUTINE nmr_shift
     238              : 
     239              : ! **************************************************************************************************
     240              : !> \brief ...
     241              : !> \param nmr_env ...
     242              : !> \param current_env ...
     243              : !> \param qs_env ...
     244              : !> \param iB ...
     245              : !> \param idir ...
     246              : ! **************************************************************************************************
     247          774 :    SUBROUTINE nmr_shift_gapw(nmr_env, current_env, qs_env, iB, idir)
     248              : 
     249              :       TYPE(nmr_env_type)                                 :: nmr_env
     250              :       TYPE(current_env_type)                             :: current_env
     251              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     252              :       INTEGER, INTENT(IN)                                :: IB, idir
     253              : 
     254              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'nmr_shift_gapw'
     255              : 
     256              :       INTEGER :: handle, ia, iat, iatom, idir2_1, idir3_1, ikind, ir, ira, ispin, j, jatom, &
     257              :          n_nics, na, natom, natom_local, natom_tot, nkind, nnics_local, nr, nra, nspins, &
     258              :          output_unit
     259          774 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: list_j, list_nics_j
     260              :       INTEGER, DIMENSION(2)                              :: bo
     261          774 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     262              :       LOGICAL                                            :: do_nics, paw_atom
     263              :       REAL(dp)                                           :: ddiff, dist, dum, itegrated_jrho, &
     264              :                                                             r_jatom(3), rdiff(3), rij(3), s_1, &
     265              :                                                             s_2, scale_fac_1, shift_gapw_radius
     266          774 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: j_grid
     267          774 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: cs_loc_tmp, cs_nics_loc_tmp, dist_ij, &
     268          774 :                                                             dist_nics_ij, r_grid
     269          774 :       REAL(dp), DIMENSION(:, :), POINTER                 :: jrho_h_grid, jrho_s_grid, r_nics
     270          774 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: chemical_shift_loc, &
     271          774 :                                                             chemical_shift_nics_loc
     272          774 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     273              :       TYPE(cell_type), POINTER                           :: cell
     274              :       TYPE(cp_logger_type), POINTER                      :: logger
     275              :       TYPE(dft_control_type), POINTER                    :: dft_control
     276              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     277              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     278          774 :       TYPE(jrho_atom_type), DIMENSION(:), POINTER        :: jrho1_atom_set
     279              :       TYPE(jrho_atom_type), POINTER                      :: jrho1_atom
     280              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     281          774 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     282          774 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     283              : 
     284          774 :       CALL timeset(routineN, handle)
     285              :       !
     286          774 :       NULLIFY (atomic_kind_set, qs_kind_set, cell, dft_control, para_env, particle_set, &
     287          774 :                chemical_shift_loc, chemical_shift_nics_loc, jrho1_atom_set, &
     288          774 :                jrho1_atom, r_nics, jrho_h_grid, jrho_s_grid, &
     289          774 :                atom_list, grid_atom, harmonics, logger)
     290              :       !
     291          774 :       logger => cp_get_default_logger()
     292          774 :       output_unit = cp_logger_get_default_io_unit(logger)
     293              :       !
     294              :       CALL get_qs_env(qs_env=qs_env, &
     295              :                       atomic_kind_set=atomic_kind_set, &
     296              :                       qs_kind_set=qs_kind_set, &
     297              :                       cell=cell, &
     298              :                       dft_control=dft_control, &
     299              :                       para_env=para_env, &
     300          774 :                       particle_set=particle_set)
     301              : 
     302              :       CALL get_nmr_env(nmr_env=nmr_env, &
     303              :                        chemical_shift_loc=chemical_shift_loc, &
     304              :                        chemical_shift_nics_loc=chemical_shift_nics_loc, &
     305              :                        shift_gapw_radius=shift_gapw_radius, &
     306              :                        n_nics=n_nics, &
     307              :                        r_nics=r_nics, &
     308          774 :                        do_nics=do_nics)
     309              : 
     310              :       CALL get_current_env(current_env=current_env, &
     311          774 :                            jrho1_atom_set=jrho1_atom_set)
     312              :       !
     313          774 :       nkind = SIZE(atomic_kind_set, 1)
     314          774 :       natom_tot = SIZE(particle_set, 1)
     315          774 :       nspins = dft_control%nspins
     316          774 :       itegrated_jrho = 0.0_dp
     317              :       !
     318          774 :       idir2_1 = MODULO(idir, 3) + 1
     319          774 :       idir3_1 = MODULO(idir + 1, 3) + 1
     320          774 :       scale_fac_1 = fac_vecp(idir3_1, idir2_1, idir)
     321              :       !
     322              :       ALLOCATE (cs_loc_tmp(3, natom_tot), list_j(natom_tot), &
     323         4644 :                 dist_ij(3, natom_tot))
     324        11070 :       cs_loc_tmp = 0.0_dp
     325          774 :       IF (do_nics) THEN
     326              :          ALLOCATE (cs_nics_loc_tmp(3, n_nics), list_nics_j(n_nics), &
     327          108 :                    dist_nics_ij(3, n_nics))
     328          234 :          cs_nics_loc_tmp = 0.0_dp
     329              :       END IF
     330              :       !
     331              :       ! Loop over atoms to collocate the current on each atomic grid, JA
     332              :       ! Per each JA, loop over the points where the shift needs to be computed
     333         2196 :       DO ikind = 1, nkind
     334              : 
     335         1422 :          NULLIFY (atom_list, grid_atom, harmonics)
     336              :          CALL get_atomic_kind(atomic_kind_set(ikind), &
     337              :                               atom_list=atom_list, &
     338         1422 :                               natom=natom)
     339              : 
     340              :          CALL get_qs_kind(qs_kind_set(ikind), &
     341              :                           paw_atom=paw_atom, &
     342              :                           harmonics=harmonics, &
     343         1422 :                           grid_atom=grid_atom)
     344              :          !
     345         1422 :          na = grid_atom%ng_sphere
     346         1422 :          nr = grid_atom%nr
     347         1422 :          nra = nr*na
     348         7110 :          ALLOCATE (r_grid(3, nra), j_grid(nra))
     349        69282 :          ira = 1
     350        69282 :          DO ia = 1, na
     351      3469482 :             DO ir = 1, nr
     352     13600800 :                r_grid(:, ira) = grid_atom%rad(ir)*harmonics%a(:, ia)
     353      3468060 :                ira = ira + 1
     354              :             END DO
     355              :          END DO
     356              :          !
     357              :          ! Quick cycle if needed
     358         1422 :          IF (paw_atom) THEN
     359              :             !
     360              :             ! Distribute the atoms of this kind
     361         1062 :             bo = get_limit(natom, para_env%num_pe, para_env%mepos)
     362              :             !
     363         1773 :             DO iat = bo(1), bo(2)
     364          711 :                iatom = atom_list(iat)
     365              :                !
     366              :                ! find all the atoms within the radius
     367          711 :                natom_local = 0
     368         3150 :                DO jatom = 1, natom_tot
     369         2439 :                   rij(:) = pbc(particle_set(iatom)%r, particle_set(jatom)%r, cell)
     370         2439 :                   dist = SQRT(rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3))
     371         3150 :                   IF (dist <= shift_gapw_radius) THEN
     372         2403 :                      natom_local = natom_local + 1
     373         2403 :                      list_j(natom_local) = jatom
     374         9612 :                      dist_ij(:, natom_local) = rij(:)
     375              :                   END IF
     376              :                END DO
     377              :                !
     378              :                ! ... also for nics
     379          711 :                IF (do_nics) THEN
     380           18 :                   nnics_local = 0
     381           72 :                   DO jatom = 1, n_nics
     382          216 :                      r_jatom(:) = r_nics(:, jatom)
     383           54 :                      rij(:) = pbc(particle_set(iatom)%r, r_jatom, cell)
     384           54 :                      dist = SQRT(rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3))
     385           72 :                      IF (dist <= shift_gapw_radius) THEN
     386           54 :                         nnics_local = nnics_local + 1
     387           54 :                         list_nics_j(nnics_local) = jatom
     388          216 :                         dist_nics_ij(:, nnics_local) = rij(:)
     389              :                      END IF
     390              :                   END DO
     391              :                END IF
     392              :                !
     393          711 :                NULLIFY (jrho1_atom, jrho_h_grid, jrho_s_grid)
     394          711 :                jrho1_atom => jrho1_atom_set(iatom)
     395              :                !
     396         2826 :                DO ispin = 1, nspins
     397         1053 :                   jrho_h_grid => jrho1_atom%jrho_vec_rad_h(idir, ispin)%r_coef
     398         1053 :                   jrho_s_grid => jrho1_atom%jrho_vec_rad_s(idir, ispin)%r_coef
     399              :                   !
     400              :                   ! loop over the atoms neighbors of iatom in terms of the current density
     401              :                   ! for each compute the contribution to the shift coming from the
     402              :                   ! local current density at iatom
     403         1053 :                   ira = 1
     404        50787 :                   DO ia = 1, na
     405      2548467 :                      DO ir = 1, nr
     406      2497680 :                         j_grid(ira) = (jrho_h_grid(ir, ia) - jrho_s_grid(ir, ia))*grid_atom%weight(ia, ir)
     407      2497680 :                         itegrated_jrho = itegrated_jrho + j_grid(ira)
     408      2547414 :                         ira = ira + 1
     409              :                      END DO
     410              :                   END DO
     411              :                   !
     412         4410 :                   DO j = 1, natom_local
     413         3357 :                      jatom = list_j(j)
     414        13428 :                      rij(:) = dist_ij(:, j)
     415              :                      !
     416              :                      s_1 = 0.0_dp
     417              :                      s_2 = 0.0_dp
     418      7826517 :                      DO ira = 1, nra
     419              :                         !
     420     31292640 :                         rdiff(:) = rij(:) - r_grid(:, ira)
     421      7823160 :                         ddiff = SQRT(rdiff(1)*rdiff(1) + rdiff(2)*rdiff(2) + rdiff(3)*rdiff(3))
     422      7826517 :                         IF (ddiff > 1.0E-12_dp) THEN
     423      7823160 :                            dum = scale_fac_1*j_grid(ira)/(ddiff*ddiff*ddiff)
     424      7823160 :                            s_1 = s_1 + rdiff(idir2_1)*dum
     425      7823160 :                            s_2 = s_2 + rdiff(idir3_1)*dum
     426              :                         END IF ! ddiff
     427              :                      END DO ! ira
     428         3357 :                      cs_loc_tmp(idir3_1, jatom) = cs_loc_tmp(idir3_1, jatom) + s_1
     429         4410 :                      cs_loc_tmp(idir2_1, jatom) = cs_loc_tmp(idir2_1, jatom) - s_2
     430              :                   END DO ! j
     431              :                   !
     432         1764 :                   IF (do_nics) THEN
     433          144 :                      DO j = 1, nnics_local
     434          108 :                         jatom = list_nics_j(j)
     435          432 :                         rij(:) = dist_nics_ij(:, j)
     436              :                         !
     437              :                         s_1 = 0.0_dp
     438              :                         s_2 = 0.0_dp
     439       270108 :                         DO ira = 1, nra
     440              :                            !
     441      1080000 :                            rdiff(:) = rij(:) - r_grid(:, ira)
     442       270000 :                            ddiff = SQRT(rdiff(1)*rdiff(1) + rdiff(2)*rdiff(2) + rdiff(3)*rdiff(3))
     443       270108 :                            IF (ddiff > 1.0E-12_dp) THEN
     444       270000 :                               dum = scale_fac_1*j_grid(ira)/(ddiff*ddiff*ddiff)
     445       270000 :                               s_1 = s_1 + rdiff(idir2_1)*dum
     446       270000 :                               s_2 = s_2 + rdiff(idir3_1)*dum
     447              :                            END IF ! ddiff
     448              :                         END DO ! ira
     449          108 :                         cs_nics_loc_tmp(idir3_1, jatom) = cs_nics_loc_tmp(idir3_1, jatom) + s_1
     450          144 :                         cs_nics_loc_tmp(idir2_1, jatom) = cs_nics_loc_tmp(idir2_1, jatom) - s_2
     451              :                      END DO ! j
     452              :                   END IF ! do_nics
     453              :                END DO ! ispin
     454              :             END DO ! iat
     455              :          END IF
     456         3618 :          DEALLOCATE (r_grid, j_grid)
     457              :       END DO ! ikind
     458              :       !
     459              :       !
     460          774 :       CALL para_env%sum(itegrated_jrho)
     461          774 :       IF (output_unit > 0) THEN
     462              :          WRITE (output_unit, '(T2,A,E24.16)') 'Integrated local j_'&
     463          387 :               &//ACHAR(idir + 119)//ACHAR(iB + 119)//'(r)=', itegrated_jrho
     464              :       END IF
     465              :       !
     466          774 :       CALL para_env%sum(cs_loc_tmp)
     467              :       chemical_shift_loc(:, iB, :) = chemical_shift_loc(:, iB, :) &
     468        11070 :            & - nmr_env%shift_factor_gapw*cs_loc_tmp(:, :)/2.0_dp
     469              :       !
     470          774 :       DEALLOCATE (cs_loc_tmp, list_j, dist_ij)
     471              :       !
     472          774 :       IF (do_nics) THEN
     473           18 :          CALL para_env%sum(cs_nics_loc_tmp)
     474              :          chemical_shift_nics_loc(:, iB, :) = chemical_shift_nics_loc(:, iB, :) &
     475          234 :               & - nmr_env%shift_factor_gapw*cs_nics_loc_tmp(:, :)/2.0_dp
     476              :          !
     477           18 :          DEALLOCATE (cs_nics_loc_tmp, list_nics_j, dist_nics_ij)
     478              :       END IF
     479              :       !
     480          774 :       CALL timestop(handle)
     481              :       !
     482         2322 :    END SUBROUTINE nmr_shift_gapw
     483              : 
     484              : ! **************************************************************************************************
     485              : !> \brief interpolate the shift calculated on the PW grid in order to ger
     486              : !>       the value on arbitrary points in real space
     487              : !> \param nmr_env to get the shift tensor and the list of additional points
     488              : !> \param pw_env ...
     489              : !> \param particle_set for the atomic position
     490              : !> \param cell to take into account the pbs, and to have the volume
     491              : !> \param shift_pw_rspace specific component of the shift tensor on the pw grid
     492              : !> \param i_B component of the magnetic field for which the shift is calculated (row)
     493              : !> \param idir component of the vector \int_{r}[ ((r-r') x j(r))/|r-r'|^3 ] = Bind(r')
     494              : !> \param nmr_section ...
     495              : !> \author MI
     496              : ! **************************************************************************************************
     497          864 :    SUBROUTINE interpolate_shift_pwgrid(nmr_env, pw_env, particle_set, cell, shift_pw_rspace, &
     498              :                                        i_B, idir, nmr_section)
     499              : 
     500              :       TYPE(nmr_env_type)                                 :: nmr_env
     501              :       TYPE(pw_env_type), POINTER                         :: pw_env
     502              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     503              :       TYPE(cell_type), POINTER                           :: cell
     504              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: shift_pw_rspace
     505              :       INTEGER, INTENT(IN)                                :: i_B, idir
     506              :       TYPE(section_vals_type), POINTER                   :: nmr_section
     507              : 
     508              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'interpolate_shift_pwgrid'
     509              : 
     510              :       INTEGER                                            :: aint_precond, handle, iat, iatom, &
     511              :                                                             max_iter, n_nics, natom, precond_kind
     512          108 :       INTEGER, DIMENSION(:), POINTER                     :: cs_atom_list
     513              :       LOGICAL                                            :: do_nics, success
     514              :       REAL(dp)                                           :: eps_r, eps_x, R_iatom(3), ra(3), &
     515              :                                                             shift_val
     516          108 :       REAL(dp), DIMENSION(:, :), POINTER                 :: r_nics
     517          108 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: chemical_shift, chemical_shift_nics
     518              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     519              :       TYPE(pw_r3d_rs_type)                               :: shiftspl
     520              :       TYPE(pw_spline_precond_type)                       :: precond
     521              :       TYPE(section_vals_type), POINTER                   :: interp_section
     522              : 
     523          108 :       CALL timeset(routineN, handle)
     524              :       !
     525          108 :       NULLIFY (interp_section, auxbas_pw_pool)
     526          108 :       NULLIFY (cs_atom_list, chemical_shift, chemical_shift_nics, r_nics)
     527              : 
     528              :       interp_section => section_vals_get_subs_vals(nmr_section, &
     529          108 :                                                    "INTERPOLATOR")
     530              :       CALL section_vals_val_get(interp_section, "aint_precond", &
     531          108 :                                 i_val=aint_precond)
     532          108 :       CALL section_vals_val_get(interp_section, "precond", i_val=precond_kind)
     533          108 :       CALL section_vals_val_get(interp_section, "max_iter", i_val=max_iter)
     534          108 :       CALL section_vals_val_get(interp_section, "eps_r", r_val=eps_r)
     535          108 :       CALL section_vals_val_get(interp_section, "eps_x", r_val=eps_x)
     536              : 
     537              :       ! calculate spline coefficients
     538          108 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     539          108 :       CALL auxbas_pw_pool%create_pw(shiftspl)
     540              : 
     541              :       CALL pw_spline_precond_create(precond, precond_kind=aint_precond, &
     542          108 :                                     pool=auxbas_pw_pool, pbc=.TRUE., transpose=.FALSE.)
     543          108 :       CALL pw_spline_do_precond(precond, shift_pw_rspace, shiftspl)
     544          108 :       CALL pw_spline_precond_set_kind(precond, precond_kind)
     545              :       success = find_coeffs(values=shift_pw_rspace, coeffs=shiftspl, &
     546              :                             linOp=spl3_pbc, preconditioner=precond, pool=auxbas_pw_pool, &
     547          108 :                             eps_r=eps_r, eps_x=eps_x, max_iter=max_iter)
     548          108 :       CPASSERT(success)
     549          108 :       CALL pw_spline_precond_release(precond)
     550              : 
     551              :       CALL get_nmr_env(nmr_env=nmr_env, cs_atom_list=cs_atom_list, &
     552              :                        chemical_shift=chemical_shift, &
     553              :                        chemical_shift_nics=chemical_shift_nics, &
     554              :                        n_nics=n_nics, r_nics=r_nics, &
     555          108 :                        do_nics=do_nics)
     556              : 
     557          108 :       IF (ASSOCIATED(cs_atom_list)) THEN
     558          108 :          natom = SIZE(cs_atom_list, 1)
     559              :       ELSE
     560              :          natom = -1
     561              :       END IF
     562              : 
     563          378 :       DO iat = 1, natom
     564          270 :          iatom = cs_atom_list(iat)
     565          270 :          R_iatom = pbc(particle_set(iatom)%r, cell)
     566          270 :          shift_val = Eval_Interp_Spl3_pbc(R_iatom, shiftspl)
     567              :          chemical_shift(idir, i_B, iatom) = chemical_shift(idir, i_B, iatom) + &
     568          378 :                                             nmr_env%shift_factor*twopi**2*shift_val
     569              :       END DO
     570              : 
     571          108 :       IF (do_nics) THEN
     572          144 :          DO iatom = 1, n_nics
     573          432 :             ra(:) = r_nics(:, iatom)
     574          108 :             R_iatom = pbc(ra, cell)
     575          108 :             shift_val = Eval_Interp_Spl3_pbc(R_iatom, shiftspl)
     576              :             chemical_shift_nics(idir, i_B, iatom) = chemical_shift_nics(idir, i_B, iatom) + &
     577          144 :                                                     nmr_env%shift_factor*twopi**2*shift_val
     578              :          END DO
     579              :       END IF
     580              : 
     581          108 :       CALL auxbas_pw_pool%give_back_pw(shiftspl)
     582              : 
     583              :       !
     584          108 :       CALL timestop(handle)
     585              :       !
     586          972 :    END SUBROUTINE interpolate_shift_pwgrid
     587              : 
     588              : ! **************************************************************************************************
     589              : !> \brief ...
     590              : !> \param nmr_env ...
     591              : !> \param particle_set ...
     592              : !> \param cell ...
     593              : !> \param shift_pw_gspace ...
     594              : !> \param i_B ...
     595              : !> \param idir ...
     596              : ! **************************************************************************************************
     597         3780 :    SUBROUTINE gsum_shift_pwgrid(nmr_env, particle_set, cell, shift_pw_gspace, &
     598              :                                 i_B, idir)
     599              :       TYPE(nmr_env_type)                                 :: nmr_env
     600              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     601              :       TYPE(cell_type), POINTER                           :: cell
     602              :       TYPE(pw_c1d_gs_type), INTENT(IN)                   :: shift_pw_gspace
     603              :       INTEGER, INTENT(IN)                                :: i_B, idir
     604              : 
     605              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'gsum_shift_pwgrid'
     606              : 
     607              :       COMPLEX(dp)                                        :: cplx
     608              :       INTEGER                                            :: handle, iat, iatom, n_nics, natom
     609         1890 :       INTEGER, DIMENSION(:), POINTER                     :: cs_atom_list
     610              :       LOGICAL                                            :: do_nics
     611              :       REAL(dp)                                           :: R_iatom(3), ra(3)
     612         1890 :       REAL(dp), DIMENSION(:, :), POINTER                 :: r_nics
     613         1890 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: chemical_shift, chemical_shift_nics
     614              : 
     615         1890 :       CALL timeset(routineN, handle)
     616              :       !
     617         1890 :       NULLIFY (cs_atom_list, chemical_shift, chemical_shift_nics, r_nics)
     618              :       !
     619              :       CALL get_nmr_env(nmr_env=nmr_env, cs_atom_list=cs_atom_list, &
     620              :                        chemical_shift=chemical_shift, &
     621              :                        chemical_shift_nics=chemical_shift_nics, &
     622         1890 :                        n_nics=n_nics, r_nics=r_nics, do_nics=do_nics)
     623              :       !
     624         1890 :       IF (ASSOCIATED(cs_atom_list)) THEN
     625         1890 :          natom = SIZE(cs_atom_list, 1)
     626              :       ELSE
     627              :          natom = -1
     628              :       END IF
     629              :       !
     630              :       ! compute the chemical shift
     631         7254 :       DO iat = 1, natom
     632         5364 :          iatom = cs_atom_list(iat)
     633         5364 :          R_iatom = pbc(particle_set(iatom)%r, cell)
     634         5364 :          CALL gsumr(R_iatom, shift_pw_gspace, cplx)
     635              :          chemical_shift(idir, i_B, iatom) = chemical_shift(idir, i_B, iatom) + &
     636         7254 :                                             nmr_env%shift_factor*twopi**2*REAL(cplx, dp)
     637              :       END DO
     638              :       !
     639              :       ! compute nics
     640         1890 :       IF (do_nics) THEN
     641          198 :          DO iat = 1, n_nics
     642          162 :             ra = pbc(r_nics(:, iat), cell)
     643          162 :             CALL gsumr(ra, shift_pw_gspace, cplx)
     644              :             chemical_shift_nics(idir, i_B, iat) = chemical_shift_nics(idir, i_B, iat) + &
     645          198 :                                                   nmr_env%shift_factor*twopi**2*REAL(cplx, dp)
     646              :          END DO
     647              :       END IF
     648              : 
     649         1890 :       CALL timestop(handle)
     650              : 
     651         1890 :    END SUBROUTINE gsum_shift_pwgrid
     652              : 
     653              : ! **************************************************************************************************
     654              : !> \brief ...
     655              : !> \param r ...
     656              : !> \param pw ...
     657              : !> \param cplx ...
     658              : ! **************************************************************************************************
     659         5526 :    SUBROUTINE gsumr(r, pw, cplx)
     660              :       REAL(dp), INTENT(IN)                               :: r(3)
     661              :       TYPE(pw_c1d_gs_type), INTENT(IN)                   :: pw
     662              :       COMPLEX(dp)                                        :: cplx
     663              : 
     664              :       COMPLEX(dp)                                        :: rg
     665              :       INTEGER                                            :: ig
     666              :       TYPE(pw_grid_type), POINTER                        :: grid
     667              : 
     668         5526 :       grid => pw%pw_grid
     669         5526 :       cplx = z_zero
     670    102609198 :       DO ig = grid%first_gne0, grid%ngpts_cut_local
     671    102603672 :          rg = (grid%g(1, ig)*r(1) + grid%g(2, ig)*r(2) + grid%g(3, ig)*r(3))*gaussi
     672    102609198 :          cplx = cplx + pw%array(ig)*EXP(rg)
     673              :       END DO
     674         5526 :       IF (grid%have_g0) cplx = cplx + pw%array(1)
     675         5526 :       CALL grid%para%group%sum(cplx)
     676         5526 :    END SUBROUTINE gsumr
     677              : 
     678              : ! **************************************************************************************************
     679              : !> \brief Shielding tensor and Chi are printed into a file
     680              : !>       if required from input
     681              : !>       It is possible to print only for a subset of atoms or
     682              : !>       or points in non-ionic positions
     683              : !> \param nmr_env ...
     684              : !> \param current_env ...
     685              : !> \param qs_env ...
     686              : !> \author MI
     687              : ! **************************************************************************************************
     688          160 :    SUBROUTINE nmr_shift_print(nmr_env, current_env, qs_env)
     689              :       TYPE(nmr_env_type)                                 :: nmr_env
     690              :       TYPE(current_env_type)                             :: current_env
     691              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     692              : 
     693              :       CHARACTER(LEN=2)                                   :: element_symbol
     694              :       CHARACTER(LEN=default_string_length)               :: name, title
     695              :       INTEGER                                            :: iatom, ir, n_nics, nat_print, natom, &
     696              :                                                             output_unit, unit_atoms, unit_nics
     697          160 :       INTEGER, DIMENSION(:), POINTER                     :: cs_atom_list
     698              :       LOGICAL                                            :: do_nics, gapw
     699              :       REAL(dp) :: chi_aniso, chi_iso, chi_sym_tot(3, 3), chi_tensor(3, 3, 2), &
     700              :          chi_tensor_loc(3, 3, 2), chi_tensor_loc_tmp(3, 3), chi_tensor_tmp(3, 3), chi_tmp(3, 3), &
     701              :          eig(3), rpos(3), shift_aniso, shift_iso, shift_sym_tot(3, 3)
     702          160 :       REAL(dp), DIMENSION(:, :), POINTER                 :: r_nics
     703          160 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: cs, cs_loc, cs_nics, cs_nics_loc, &
     704          160 :                                                             cs_nics_tot, cs_tot
     705              :       REAL(dp), EXTERNAL                                 :: DDOT
     706              :       TYPE(atomic_kind_type), POINTER                    :: atom_kind
     707              :       TYPE(cp_logger_type), POINTER                      :: logger
     708              :       TYPE(dft_control_type), POINTER                    :: dft_control
     709          160 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     710              :       TYPE(section_vals_type), POINTER                   :: nmr_section
     711              : 
     712          160 :       NULLIFY (cs, cs_nics, r_nics, cs_loc, cs_nics_loc, logger, particle_set, atom_kind, dft_control)
     713              : 
     714          320 :       logger => cp_get_default_logger()
     715          160 :       output_unit = cp_logger_get_default_io_unit(logger)
     716              : 
     717              :       nmr_section => section_vals_get_subs_vals(qs_env%input, &
     718          160 :                                                 "PROPERTIES%LINRES%NMR")
     719              : 
     720              :       CALL get_nmr_env(nmr_env=nmr_env, &
     721              :                        chemical_shift=cs, &
     722              :                        chemical_shift_nics=cs_nics, &
     723              :                        chemical_shift_loc=cs_loc, &
     724              :                        chemical_shift_nics_loc=cs_nics_loc, &
     725              :                        cs_atom_list=cs_atom_list, &
     726              :                        n_nics=n_nics, &
     727              :                        r_nics=r_nics, &
     728          160 :                        do_nics=do_nics)
     729              :       !
     730              :       CALL get_current_env(current_env=current_env, &
     731              :                            chi_tensor=chi_tensor, &
     732          160 :                            chi_tensor_loc=chi_tensor_loc)
     733              :       !
     734              :       ! multiply by the appropriate factor
     735          160 :       chi_tensor_tmp(:, :) = 0.0_dp
     736          160 :       chi_tensor_loc_tmp(:, :) = 0.0_dp
     737         2080 :       chi_tensor_tmp(:, :) = (chi_tensor(:, :, 1) + chi_tensor(:, :, 2))*nmr_env%chi_factor
     738              :       !chi_tensor_loc_tmp(:,:) = (chi_tensor_loc(:,:,1) + chi_tensor_loc(:,:,2)) * here there is another factor
     739              :       !
     740              :       CALL get_qs_env(qs_env=qs_env, &
     741              :                       dft_control=dft_control, &
     742          160 :                       particle_set=particle_set)
     743              : 
     744          160 :       natom = SIZE(particle_set, 1)
     745          160 :       gapw = dft_control%qs_control%gapw
     746          160 :       nat_print = SIZE(cs_atom_list, 1)
     747              : 
     748          480 :       ALLOCATE (cs_tot(3, 3, nat_print))
     749          160 :       IF (do_nics) THEN
     750           18 :          ALLOCATE (cs_nics_tot(3, 3, n_nics))
     751              :       END IF
     752              :       ! Finalize Chi calculation
     753              :       ! Symmetrize
     754         2080 :       chi_sym_tot(:, :) = (chi_tensor_tmp(:, :) + TRANSPOSE(chi_tensor_tmp(:, :)))/2.0_dp
     755          160 :       IF (gapw) THEN
     756              :          chi_sym_tot(:, :) = chi_sym_tot(:, :) &
     757         1118 :               & + (chi_tensor_loc_tmp(:, :) + TRANSPOSE(chi_tensor_loc_tmp(:, :)))/2.0_dp
     758              :       END IF
     759          160 :       chi_tmp(:, :) = chi_sym_tot(:, :)
     760          160 :       CALL diamat_all(chi_tmp, eig)
     761          160 :       chi_iso = (eig(1) + eig(2) + eig(3))/3.0_dp
     762          160 :       chi_aniso = eig(3) - (eig(2) + eig(1))/2.0_dp
     763              :       !
     764          160 :       IF (output_unit > 0) THEN
     765           80 :          WRITE (output_unit, '(T2,A,E14.6)') 'CheckSum Chi =', &
     766          160 :             SQRT(DDOT(9, chi_tensor_tmp(1, 1), 1, chi_tensor_tmp(1, 1), 1))
     767              :       END IF
     768              :       !
     769          160 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, nmr_section, &
     770              :                                            "PRINT%CHI_TENSOR"), cp_p_file)) THEN
     771              : 
     772              :          unit_atoms = cp_print_key_unit_nr(logger, nmr_section, "PRINT%CHI_TENSOR", &
     773           22 :                                            extension=".data", middle_name="CHI", log_filename=.FALSE.)
     774              : 
     775           22 :          WRITE (title, '(A)') "Magnetic Susceptibility Tensor "
     776           22 :          IF (unit_atoms > 0) THEN
     777           11 :             WRITE (unit_atoms, '(T2,A)') title
     778           11 :             WRITE (unit_atoms, '(T1,A)') " CHI from SOFT J in 10^-30 J/T^2 units"
     779           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  XX = ', chi_tensor_tmp(1, 1),&
     780           11 :                  &                           '  XY = ', chi_tensor_tmp(1, 2),&
     781           22 :                  &                           '  XZ = ', chi_tensor_tmp(1, 3)
     782           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  YX = ', chi_tensor_tmp(2, 1),&
     783           11 :                  &                           '  YY = ', chi_tensor_tmp(2, 2),&
     784           22 :                  &                           '  YZ = ', chi_tensor_tmp(2, 3)
     785           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  ZX = ', chi_tensor_tmp(3, 1),&
     786           11 :                  &                           '  ZY = ', chi_tensor_tmp(3, 2),&
     787           22 :                  &                           '  ZZ = ', chi_tensor_tmp(3, 3)
     788           11 :             IF (gapw) THEN
     789           11 :                WRITE (unit_atoms, '(T1,A)') " CHI from LOCAL J in 10^-30 J/T^2 units"
     790           11 :                WRITE (unit_atoms, '(3(A,f10.4))') '  XX = ', chi_tensor_loc_tmp(1, 1),&
     791           11 :                     &                           '  XY = ', chi_tensor_loc_tmp(1, 2),&
     792           22 :                     &                           '  XZ = ', chi_tensor_loc_tmp(1, 3)
     793           11 :                WRITE (unit_atoms, '(3(A,f10.4))') '  YX = ', chi_tensor_loc_tmp(2, 1),&
     794           11 :                     &                           '  YY = ', chi_tensor_loc_tmp(2, 2),&
     795           22 :                     &                           '  YZ = ', chi_tensor_loc_tmp(2, 3)
     796           11 :                WRITE (unit_atoms, '(3(A,f10.4))') '  ZX = ', chi_tensor_loc_tmp(3, 1),&
     797           11 :                     &                           '  ZY = ', chi_tensor_loc_tmp(3, 2),&
     798           22 :                     &                           '  ZZ = ', chi_tensor_loc_tmp(3, 3)
     799              :             END IF
     800           11 :             WRITE (unit_atoms, '(T1,A)') " Total CHI in 10^-30 J/T^2 units"
     801           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  XX = ', chi_sym_tot(1, 1),&
     802           11 :                  &                          '  XY = ', chi_sym_tot(1, 2),&
     803           22 :                  &                          '  XZ = ', chi_sym_tot(1, 3)
     804           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  YX = ', chi_sym_tot(2, 1),&
     805           11 :                  &                          '  YY = ', chi_sym_tot(2, 2),&
     806           22 :                  &                          '  YZ = ', chi_sym_tot(2, 3)
     807           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  ZX = ', chi_sym_tot(3, 1),&
     808           11 :                  &                          '  ZY = ', chi_sym_tot(3, 2),&
     809           22 :                  &                          '  ZZ = ', chi_sym_tot(3, 3)
     810          143 :             chi_sym_tot(:, :) = chi_sym_tot(:, :)*nmr_env%chi_SI2ppmcgs
     811           11 :             WRITE (unit_atoms, '(T1,A)') " Total CHI in ppm-cgs units"
     812           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  XX = ', chi_sym_tot(1, 1),&
     813           11 :                  &                          '  XY = ', chi_sym_tot(1, 2),&
     814           22 :                  &                          '  XZ = ', chi_sym_tot(1, 3)
     815           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  YX = ', chi_sym_tot(2, 1),&
     816           11 :                  &                          '  YY = ', chi_sym_tot(2, 2),&
     817           22 :                  &                          '  YZ = ', chi_sym_tot(2, 3)
     818           11 :             WRITE (unit_atoms, '(3(A,f10.4))') '  ZX = ', chi_sym_tot(3, 1),&
     819           11 :                  &                          '  ZY = ', chi_sym_tot(3, 2),&
     820           22 :                  &                          '  ZZ = ', chi_sym_tot(3, 3)
     821              :             WRITE (unit_atoms, '(/T1,3(A,f10.4))') &
     822           11 :                '  PV1=', nmr_env%chi_SI2ppmcgs*eig(1), &
     823           11 :                '  PV2=', nmr_env%chi_SI2ppmcgs*eig(2), &
     824           22 :                '  PV3=', nmr_env%chi_SI2ppmcgs*eig(3)
     825              :             WRITE (unit_atoms, '(T1,A,F10.4,10X,A,F10.4)') &
     826           11 :                '  ISO=', nmr_env%chi_SI2ppmcgs*chi_iso, &
     827           22 :                'ANISO=', nmr_env%chi_SI2ppmcgs*chi_aniso
     828              :          END IF
     829              : 
     830              :          CALL cp_print_key_finished_output(unit_atoms, logger, nmr_section,&
     831           22 :               &                            "PRINT%CHI_TENSOR")
     832              :       END IF ! print chi
     833              :       !
     834              :       ! Add the chi part to the shifts
     835         6504 :       cs_tot(:, :, :) = 0.0_dp
     836          648 :       DO ir = 1, nat_print
     837          488 :          iatom = cs_atom_list(ir)
     838         1952 :          rpos(1:3) = particle_set(iatom)%r(1:3)
     839          488 :          atom_kind => particle_set(iatom)%atomic_kind
     840          488 :          CALL get_atomic_kind(atom_kind, name=name, element_symbol=element_symbol)
     841        12200 :          cs_tot(:, :, ir) = chi_tensor_tmp(:, :)*nmr_env%chi_SI2shiftppm + cs(:, :, iatom)
     842         7368 :          IF (gapw) cs_tot(:, :, ir) = cs_tot(:, :, ir) + cs_loc(:, :, iatom)
     843              :       END DO ! ir
     844          160 :       IF (output_unit > 0) THEN
     845           80 :          WRITE (output_unit, '(T2,A,E14.6)') 'CheckSum Shifts =', &
     846          160 :             SQRT(DDOT(9*SIZE(cs_tot, 3), cs_tot(1, 1, 1), 1, cs_tot(1, 1, 1), 1))
     847              :       END IF
     848              :       !
     849              :       ! print shifts
     850          160 :       IF (BTEST(cp_print_key_should_output(logger%iter_info, nmr_section, &
     851              :                                            "PRINT%SHIELDING_TENSOR"), cp_p_file)) THEN
     852              : 
     853              :          unit_atoms = cp_print_key_unit_nr(logger, nmr_section, "PRINT%SHIELDING_TENSOR", &
     854              :                                            extension=".data", middle_name="SHIFT", &
     855          160 :                                            log_filename=.FALSE.)
     856              : 
     857          160 :          nat_print = SIZE(cs_atom_list, 1)
     858          160 :          IF (unit_atoms > 0) THEN
     859           80 :             WRITE (title, '(A,1X,I5)') "Shielding atom at atomic positions. # tensors printed ", nat_print
     860           80 :             WRITE (unit_atoms, '(T2,A)') title
     861          324 :             DO ir = 1, nat_print
     862          244 :                iatom = cs_atom_list(ir)
     863          976 :                rpos(1:3) = particle_set(iatom)%r(1:3)
     864          244 :                atom_kind => particle_set(iatom)%atomic_kind
     865          244 :                CALL get_atomic_kind(atom_kind, name=name, element_symbol=element_symbol)
     866         3172 :                shift_sym_tot(:, :) = 0.5_dp*(cs_tot(:, :, ir) + TRANSPOSE(cs_tot(:, :, ir)))
     867          244 :                CALL diamat_all(shift_sym_tot, eig)
     868          244 :                shift_iso = (eig(1) + eig(2) + eig(3))/3.0_dp
     869          244 :                shift_aniso = eig(3) - (eig(2) + eig(1))/2.0_dp
     870              :                !
     871          244 :                WRITE (unit_atoms, '(T2,I5,A,2X,A2,2X,3f15.6)') iatom, TRIM(name), element_symbol, rpos(1:3)
     872              :                !
     873          244 :                IF (gapw) THEN
     874          140 :                   WRITE (unit_atoms, '(T1,A)') " SIGMA from SOFT J"
     875          140 :                   WRITE (unit_atoms, '(3(A,f10.4))') '  XX = ', cs(1, 1, iatom),&
     876          140 :                        &                           '  XY = ', cs(1, 2, iatom),&
     877          280 :                        &                           '  XZ = ', cs(1, 3, iatom)
     878          140 :                   WRITE (unit_atoms, '(3(A,f10.4))') '  YX = ', cs(2, 1, iatom),&
     879          140 :                        &                           '  YY = ', cs(2, 2, iatom),&
     880          280 :                        &                           '  YZ = ', cs(2, 3, iatom)
     881          140 :                   WRITE (unit_atoms, '(3(A,f10.4))') '  ZX = ', cs(3, 1, iatom),&
     882          140 :                        &                           '  ZY = ', cs(3, 2, iatom),&
     883          280 :                        &                           '  ZZ = ', cs(3, 3, iatom)
     884          140 :                   WRITE (unit_atoms, '(T1,A)') " SIGMA from LOCAL J"
     885          140 :                   WRITE (unit_atoms, '(3(A,f10.4))') '  XX = ', cs_loc(1, 1, iatom),&
     886          140 :                        &                           '  XY = ', cs_loc(1, 2, iatom),&
     887          280 :                        &                           '  XZ = ', cs_loc(1, 3, iatom)
     888          140 :                   WRITE (unit_atoms, '(3(A,f10.4))') '  YX = ', cs_loc(2, 1, iatom),&
     889          140 :                        &                           '  YY = ', cs_loc(2, 2, iatom),&
     890          280 :                        &                           '  YZ = ', cs_loc(2, 3, iatom)
     891          140 :                   WRITE (unit_atoms, '(3(A,f10.4))') '  ZX = ', cs_loc(3, 1, iatom),&
     892          140 :                        &                           '  ZY = ', cs_loc(3, 2, iatom),&
     893          280 :                        &                           '  ZZ = ', cs_loc(3, 3, iatom)
     894              :                END IF
     895          244 :                WRITE (unit_atoms, '(T1,A)') " SIGMA TOTAL"
     896          244 :                WRITE (unit_atoms, '(3(A,f10.4))') '  XX = ', cs_tot(1, 1, ir),&
     897          244 :                     &                           '  XY = ', cs_tot(1, 2, ir),&
     898          488 :                     &                           '  XZ = ', cs_tot(1, 3, ir)
     899          244 :                WRITE (unit_atoms, '(3(A,f10.4))') '  YX = ', cs_tot(2, 1, ir),&
     900          244 :                     &                           '  YY = ', cs_tot(2, 2, ir),&
     901          488 :                     &                           '  YZ = ', cs_tot(2, 3, ir)
     902          244 :                WRITE (unit_atoms, '(3(A,f10.4))') '  ZX = ', cs_tot(3, 1, ir),&
     903          244 :                     &                           '  ZY = ', cs_tot(3, 2, ir),&
     904          488 :                     &                           '  ZZ = ', cs_tot(3, 3, ir)
     905          244 :                WRITE (unit_atoms, '(T1,2(A,f12.4))') '  ISOTROPY = ', shift_iso,&
     906          568 :                     &                            '  ANISOTROPY = ', shift_aniso
     907              :             END DO ! ir
     908              :          END IF
     909              :          CALL cp_print_key_finished_output(unit_atoms, logger, nmr_section,&
     910          160 :               &                            "PRINT%SHIELDING_TENSOR")
     911              : 
     912          160 :          IF (do_nics) THEN
     913              :             !
     914              :             ! Add the chi part to the nics
     915          318 :             cs_nics_tot(:, :, :) = 0.0_dp
     916           30 :             DO ir = 1, n_nics
     917          600 :                cs_nics_tot(:, :, ir) = chi_tensor_tmp(:, :)*nmr_env%chi_SI2shiftppm + cs_nics(:, :, ir)
     918          174 :                IF (gapw) cs_nics_tot(:, :, ir) = cs_nics_tot(:, :, ir) + cs_nics_loc(:, :, ir)
     919              :             END DO ! ir
     920            6 :             IF (output_unit > 0) THEN
     921            3 :                WRITE (output_unit, '(T2,A,E14.6)') 'CheckSum NICS =', &
     922            6 :                   SQRT(DDOT(9*SIZE(cs_nics_tot, 3), cs_nics_tot(1, 1, 1), 1, cs_nics_tot(1, 1, 1), 1))
     923              :             END IF
     924              :             !
     925              :             unit_nics = cp_print_key_unit_nr(logger, nmr_section, "PRINT%SHIELDING_TENSOR", &
     926              :                                              extension=".data", middle_name="NICS", &
     927            6 :                                              log_filename=.FALSE.)
     928            6 :             IF (unit_nics > 0) THEN
     929            3 :                WRITE (title, '(A,1X,I5)') "Shielding at nics positions. # tensors printed ", n_nics
     930            3 :                WRITE (unit_nics, '(T2,A)') title
     931           15 :                DO ir = 1, n_nics
     932          156 :                   shift_sym_tot(:, :) = 0.5_dp*(cs_nics_tot(:, :, ir) + TRANSPOSE(cs_nics_tot(:, :, ir)))
     933           12 :                   CALL diamat_all(shift_sym_tot, eig)
     934           12 :                   shift_iso = (eig(1) + eig(2) + eig(3))/3.0_dp
     935           12 :                   shift_aniso = eig(3) - (eig(2) + eig(1))/2.0_dp
     936              :                   !
     937           12 :                   WRITE (unit_nics, '(T2,I5,2X,3f15.6)') ir, r_nics(1:3, ir)
     938              :                   !
     939           12 :                   IF (gapw) THEN
     940            3 :                      WRITE (unit_nics, '(T1,A)') " SIGMA from SOFT J"
     941            3 :                      WRITE (unit_nics, '(3(A,f10.4))') '  XX = ', cs_nics(1, 1, ir),&
     942            3 :                           &                          '  XY = ', cs_nics(1, 2, ir),&
     943            6 :                           &                          '  XZ = ', cs_nics(1, 3, ir)
     944            3 :                      WRITE (unit_nics, '(3(A,f10.4))') '  YX = ', cs_nics(2, 1, ir),&
     945            3 :                           &                          '  YY = ', cs_nics(2, 2, ir),&
     946            6 :                           &                          '  YZ = ', cs_nics(2, 3, ir)
     947            3 :                      WRITE (unit_nics, '(3(A,f10.4))') '  ZX = ', cs_nics(3, 1, ir),&
     948            3 :                           &                          '  ZY = ', cs_nics(3, 2, ir),&
     949            6 :                           &                          '  ZZ = ', cs_nics(3, 3, ir)
     950            3 :                      WRITE (unit_nics, '(T1,A)') " SIGMA from LOCAL J"
     951            3 :                      WRITE (unit_nics, '(3(A,f10.4))') '  XX = ', cs_nics_loc(1, 1, ir),&
     952            3 :                           &                          '  XY = ', cs_nics_loc(1, 2, ir),&
     953            6 :                           &                          '  XZ = ', cs_nics_loc(1, 3, ir)
     954            3 :                      WRITE (unit_nics, '(3(A,f10.4))') '  YX = ', cs_nics_loc(2, 1, ir),&
     955            3 :                           &                          '  YY = ', cs_nics_loc(2, 2, ir),&
     956            6 :                           &                          '  YZ = ', cs_nics_loc(2, 3, ir)
     957            3 :                      WRITE (unit_nics, '(3(A,f10.4))') '  ZX = ', cs_nics_loc(3, 1, ir),&
     958            3 :                           &                          '  ZY = ', cs_nics_loc(3, 2, ir),&
     959            6 :                           &                          '  ZZ = ', cs_nics_loc(3, 3, ir)
     960              :                   END IF
     961           12 :                   WRITE (unit_nics, '(T1,A)') " SIGMA TOTAL"
     962           12 :                   WRITE (unit_nics, '(3(A,f10.4))') '  XX = ', cs_nics_tot(1, 1, ir),&
     963           12 :                        &                          '  XY = ', cs_nics_tot(1, 2, ir),&
     964           24 :                        &                          '  XZ = ', cs_nics_tot(1, 3, ir)
     965           12 :                   WRITE (unit_nics, '(3(A,f10.4))') '  YX = ', cs_nics_tot(2, 1, ir),&
     966           12 :                        &                          '  YY = ', cs_nics_tot(2, 2, ir),&
     967           24 :                        &                          '  YZ = ', cs_nics_tot(2, 3, ir)
     968           12 :                   WRITE (unit_nics, '(3(A,f10.4))') '  ZX = ', cs_nics_tot(3, 1, ir),&
     969           12 :                        &                          '  ZY = ', cs_nics_tot(3, 2, ir),&
     970           24 :                        &                          '  ZZ = ', cs_nics_tot(3, 3, ir)
     971           12 :                   WRITE (unit_nics, '(T1,2(A,f12.4))') '  ISOTROPY = ', shift_iso,&
     972           27 :                        &                           '  ANISOTROPY = ', shift_aniso
     973              :                END DO
     974              :             END IF
     975              :             CALL cp_print_key_finished_output(unit_nics, logger, nmr_section,&
     976            6 :                  &                            "PRINT%SHIELDING_TENSOR")
     977              :          END IF
     978              :       END IF ! print shift
     979              :       !
     980              :       ! clean up
     981          160 :       DEALLOCATE (cs_tot)
     982          160 :       IF (do_nics) THEN
     983            6 :          DEALLOCATE (cs_nics_tot)
     984              :       END IF
     985              :       !
     986              : !100 FORMAT(A,1X,I5)
     987              : !101 FORMAT(T2,A)
     988              : !102 FORMAT(T2,I5,A,2X,A2,2X,3f15.6)
     989              : !103 FORMAT(T2,I5,2X,3f15.6)
     990              : !104 FORMAT(T1,A)
     991              : !105 FORMAT(3(A,f10.4))
     992              : !106 FORMAT(T1,2(A,f12.4))
     993          320 :    END SUBROUTINE nmr_shift_print
     994              : 
     995              : END MODULE qs_linres_nmr_shift
     996              : 
        

Generated by: LCOV version 2.0-1