(git:936074a)
Loading...
Searching...
No Matches
qs_linres_nmr_shift.F
Go to the documentation of this file.
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! **************************************************************************************************
18 USE cell_types, ONLY: cell_type,&
19 pbc
24 USE cp_output_handling, ONLY: cp_p_file,&
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
39 USE pw_env_types, ONLY: pw_env_get,&
42 USE pw_methods, ONLY: pw_axpy,&
45 USE pw_pool_types, ONLY: pw_pool_p_type,&
55 USE pw_types, ONLY: pw_c1d_gs_type,&
61 USE qs_kind_types, ONLY: get_qs_kind,&
64 USE qs_linres_op, ONLY: fac_vecp,&
65 set_vecp,&
72 USE qs_rho_types, ONLY: qs_rho_get
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, &
84
85 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_nmr_shift'
86
87! **************
88
89CONTAINS
90
91! **************************************************************************************************
92!> \brief ...
93!> \param nmr_env ...
94!> \param current_env ...
95!> \param qs_env ...
96!> \param iB ...
97! **************************************************************************************************
98 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 REAL(dp), DIMENSION(:, :, :), POINTER :: chemical_shift, chemical_shift_loc, &
112 chemical_shift_nics, &
113 chemical_shift_nics_loc
114 TYPE(cell_type), POINTER :: cell
115 TYPE(dft_control_type), POINTER :: dft_control
116 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
117 TYPE(pw_c1d_gs_type) :: pw_gspace_work
118 TYPE(pw_c1d_gs_type), ALLOCATABLE, DIMENSION(:, :) :: shift_pw_gspace
119 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: jrho1_g
120 TYPE(pw_env_type), POINTER :: pw_env
121 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 CALL timeset(routinen, handle)
128
129 NULLIFY (chemical_shift, chemical_shift_loc, chemical_shift_nics, &
130 chemical_shift_nics_loc, cell, dft_control, pw_env, &
131 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 particle_set=particle_set)
135
136 gapw = dft_control%qs_control%gapw
137 natom = SIZE(particle_set, 1)
138 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 interpolate_shift=interpolate_shift)
145
146 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 auxbas_pw_pool=auxbas_pw_pool, pw_pools=pw_pools)
149 !
150 !
151 nmr_section => section_vals_get_subs_vals(qs_env%input, &
152 & "PROPERTIES%LINRES%NMR")
153 !
154 ! Initialize
155 ! Allocate grids for the calculation of jrho and the shift
156 ALLOCATE (shift_pw_gspace(3, nspins))
157 DO ispin = 1, nspins
158 DO idir = 1, 3
159 CALL auxbas_pw_pool%create_pw(shift_pw_gspace(idir, ispin))
160 CALL pw_zero(shift_pw_gspace(idir, ispin))
161 END DO
162 END DO
163 !
164 !
165 CALL set_vecp(ib, iib, iiib)
166 !
167 CALL auxbas_pw_pool%create_pw(pw_gspace_work)
168 CALL pw_zero(pw_gspace_work)
169 DO ispin = 1, nspins
170 !
171 DO idir = 1, 3
172 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 DO idir2 = 1, 3
176 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 pw_gspace_work, idir2, 0.0_dp)
180 !
181 ! scale and add to the correct component of the shift column
182 CALL set_vecp_rev(idir, idir2, idir3)
183 scale_fac = fac_vecp(idir3, idir2, idir)
184 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 CALL auxbas_pw_pool%give_back_pw(pw_gspace_work)
192 !
193 ! compute shildings
194 IF (interpolate_shift) THEN
195 CALL auxbas_pw_pool%create_pw(shift_pw_rspace)
196 DO ispin = 1, nspins
197 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 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 ib, idir, nmr_section)
204 END DO
205 END DO
206 CALL auxbas_pw_pool%give_back_pw(shift_pw_rspace)
207 ELSE
208 DO ispin = 1, nspins
209 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 shift_pw_gspace(idir, ispin), ib, idir)
213 END DO
214 END DO
215 END IF
216 !
217 IF (gapw) THEN
218 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 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 DO ispin = 1, nspins
228 DO idir = 1, 3
229 CALL auxbas_pw_pool%give_back_pw(shift_pw_gspace(idir, ispin))
230 END DO
231 END DO
232 DEALLOCATE (shift_pw_gspace)
233 !
234 ! Finalize
235 CALL timestop(handle)
236 !
237 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 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 INTEGER, ALLOCATABLE, DIMENSION(:) :: list_j, list_nics_j
260 INTEGER, DIMENSION(2) :: bo
261 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 REAL(dp), ALLOCATABLE, DIMENSION(:) :: j_grid
267 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: cs_loc_tmp, cs_nics_loc_tmp, dist_ij, &
268 dist_nics_ij, r_grid
269 REAL(dp), DIMENSION(:, :), POINTER :: jrho_h_grid, jrho_s_grid, r_nics
270 REAL(dp), DIMENSION(:, :, :), POINTER :: chemical_shift_loc, &
271 chemical_shift_nics_loc
272 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 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 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
282 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
283
284 CALL timeset(routinen, handle)
285 !
286 NULLIFY (atomic_kind_set, qs_kind_set, cell, dft_control, para_env, particle_set, &
287 chemical_shift_loc, chemical_shift_nics_loc, jrho1_atom_set, &
288 jrho1_atom, r_nics, jrho_h_grid, jrho_s_grid, &
289 atom_list, grid_atom, harmonics, logger)
290 !
291 logger => cp_get_default_logger()
292 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 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 do_nics=do_nics)
309
310 CALL get_current_env(current_env=current_env, &
311 jrho1_atom_set=jrho1_atom_set)
312 !
313 nkind = SIZE(atomic_kind_set, 1)
314 natom_tot = SIZE(particle_set, 1)
315 nspins = dft_control%nspins
316 itegrated_jrho = 0.0_dp
317 !
318 idir2_1 = modulo(idir, 3) + 1
319 idir3_1 = modulo(idir + 1, 3) + 1
320 scale_fac_1 = fac_vecp(idir3_1, idir2_1, idir)
321 !
322 ALLOCATE (cs_loc_tmp(3, natom_tot), list_j(natom_tot), &
323 dist_ij(3, natom_tot))
324 cs_loc_tmp = 0.0_dp
325 IF (do_nics) THEN
326 ALLOCATE (cs_nics_loc_tmp(3, n_nics), list_nics_j(n_nics), &
327 dist_nics_ij(3, n_nics))
328 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 DO ikind = 1, nkind
334
335 NULLIFY (atom_list, grid_atom, harmonics)
336 CALL get_atomic_kind(atomic_kind_set(ikind), &
337 atom_list=atom_list, &
338 natom=natom)
339
340 CALL get_qs_kind(qs_kind_set(ikind), &
341 paw_atom=paw_atom, &
342 harmonics=harmonics, &
343 grid_atom=grid_atom)
344 !
345 na = grid_atom%ng_sphere
346 nr = grid_atom%nr
347 nra = nr*na
348 ALLOCATE (r_grid(3, nra), j_grid(nra))
349 ira = 1
350 DO ia = 1, na
351 DO ir = 1, nr
352 r_grid(:, ira) = grid_atom%rad(ir)*harmonics%a(:, ia)
353 ira = ira + 1
354 END DO
355 END DO
356 !
357 ! Quick cycle if needed
358 IF (paw_atom) THEN
359 !
360 ! Distribute the atoms of this kind
361 bo = get_limit(natom, para_env%num_pe, para_env%mepos)
362 !
363 DO iat = bo(1), bo(2)
364 iatom = atom_list(iat)
365 !
366 ! find all the atoms within the radius
367 natom_local = 0
368 DO jatom = 1, natom_tot
369 rij(:) = pbc(particle_set(iatom)%r, particle_set(jatom)%r, cell)
370 dist = sqrt(rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3))
371 IF (dist <= shift_gapw_radius) THEN
372 natom_local = natom_local + 1
373 list_j(natom_local) = jatom
374 dist_ij(:, natom_local) = rij(:)
375 END IF
376 END DO
377 !
378 ! ... also for nics
379 IF (do_nics) THEN
380 nnics_local = 0
381 DO jatom = 1, n_nics
382 r_jatom(:) = r_nics(:, jatom)
383 rij(:) = pbc(particle_set(iatom)%r, r_jatom, cell)
384 dist = sqrt(rij(1)*rij(1) + rij(2)*rij(2) + rij(3)*rij(3))
385 IF (dist <= shift_gapw_radius) THEN
386 nnics_local = nnics_local + 1
387 list_nics_j(nnics_local) = jatom
388 dist_nics_ij(:, nnics_local) = rij(:)
389 END IF
390 END DO
391 END IF
392 !
393 NULLIFY (jrho1_atom, jrho_h_grid, jrho_s_grid)
394 jrho1_atom => jrho1_atom_set(iatom)
395 !
396 DO ispin = 1, nspins
397 jrho_h_grid => jrho1_atom%jrho_vec_rad_h(idir, ispin)%r_coef
398 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 ira = 1
404 DO ia = 1, na
405 DO ir = 1, nr
406 j_grid(ira) = (jrho_h_grid(ir, ia) - jrho_s_grid(ir, ia))*grid_atom%weight(ia, ir)
407 itegrated_jrho = itegrated_jrho + j_grid(ira)
408 ira = ira + 1
409 END DO
410 END DO
411 !
412 DO j = 1, natom_local
413 jatom = list_j(j)
414 rij(:) = dist_ij(:, j)
415 !
416 s_1 = 0.0_dp
417 s_2 = 0.0_dp
418 DO ira = 1, nra
419 !
420 rdiff(:) = rij(:) - r_grid(:, ira)
421 ddiff = sqrt(rdiff(1)*rdiff(1) + rdiff(2)*rdiff(2) + rdiff(3)*rdiff(3))
422 IF (ddiff > 1.0e-12_dp) THEN
423 dum = scale_fac_1*j_grid(ira)/(ddiff*ddiff*ddiff)
424 s_1 = s_1 + rdiff(idir2_1)*dum
425 s_2 = s_2 + rdiff(idir3_1)*dum
426 END IF ! ddiff
427 END DO ! ira
428 cs_loc_tmp(idir3_1, jatom) = cs_loc_tmp(idir3_1, jatom) + s_1
429 cs_loc_tmp(idir2_1, jatom) = cs_loc_tmp(idir2_1, jatom) - s_2
430 END DO ! j
431 !
432 IF (do_nics) THEN
433 DO j = 1, nnics_local
434 jatom = list_nics_j(j)
435 rij(:) = dist_nics_ij(:, j)
436 !
437 s_1 = 0.0_dp
438 s_2 = 0.0_dp
439 DO ira = 1, nra
440 !
441 rdiff(:) = rij(:) - r_grid(:, ira)
442 ddiff = sqrt(rdiff(1)*rdiff(1) + rdiff(2)*rdiff(2) + rdiff(3)*rdiff(3))
443 IF (ddiff > 1.0e-12_dp) THEN
444 dum = scale_fac_1*j_grid(ira)/(ddiff*ddiff*ddiff)
445 s_1 = s_1 + rdiff(idir2_1)*dum
446 s_2 = s_2 + rdiff(idir3_1)*dum
447 END IF ! ddiff
448 END DO ! ira
449 cs_nics_loc_tmp(idir3_1, jatom) = cs_nics_loc_tmp(idir3_1, jatom) + s_1
450 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 DEALLOCATE (r_grid, j_grid)
457 END DO ! ikind
458 !
459 !
460 CALL para_env%sum(itegrated_jrho)
461 IF (output_unit > 0) THEN
462 WRITE (output_unit, '(T2,A,E24.16)') 'Integrated local j_'&
463 &//achar(idir + 119)//achar(ib + 119)//'(r)=', itegrated_jrho
464 END IF
465 !
466 CALL para_env%sum(cs_loc_tmp)
467 chemical_shift_loc(:, ib, :) = chemical_shift_loc(:, ib, :) &
468 & - nmr_env%shift_factor_gapw*cs_loc_tmp(:, :)/2.0_dp
469 !
470 DEALLOCATE (cs_loc_tmp, list_j, dist_ij)
471 !
472 IF (do_nics) THEN
473 CALL para_env%sum(cs_nics_loc_tmp)
474 chemical_shift_nics_loc(:, ib, :) = chemical_shift_nics_loc(:, ib, :) &
475 & - nmr_env%shift_factor_gapw*cs_nics_loc_tmp(:, :)/2.0_dp
476 !
477 DEALLOCATE (cs_nics_loc_tmp, list_nics_j, dist_nics_ij)
478 END IF
479 !
480 CALL timestop(handle)
481 !
482 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 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 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 REAL(dp), DIMENSION(:, :), POINTER :: r_nics
517 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 CALL timeset(routinen, handle)
524 !
525 NULLIFY (interp_section, auxbas_pw_pool)
526 NULLIFY (cs_atom_list, chemical_shift, chemical_shift_nics, r_nics)
527
528 interp_section => section_vals_get_subs_vals(nmr_section, &
529 "INTERPOLATOR")
530 CALL section_vals_val_get(interp_section, "aint_precond", &
531 i_val=aint_precond)
532 CALL section_vals_val_get(interp_section, "precond", i_val=precond_kind)
533 CALL section_vals_val_get(interp_section, "max_iter", i_val=max_iter)
534 CALL section_vals_val_get(interp_section, "eps_r", r_val=eps_r)
535 CALL section_vals_val_get(interp_section, "eps_x", r_val=eps_x)
536
537 ! calculate spline coefficients
538 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
539 CALL auxbas_pw_pool%create_pw(shiftspl)
540
541 CALL pw_spline_precond_create(precond, precond_kind=aint_precond, &
542 pool=auxbas_pw_pool, pbc=.true., transpose=.false.)
543 CALL pw_spline_do_precond(precond, shift_pw_rspace, shiftspl)
544 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 eps_r=eps_r, eps_x=eps_x, max_iter=max_iter)
548 cpassert(success)
549 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 do_nics=do_nics)
556
557 IF (ASSOCIATED(cs_atom_list)) THEN
558 natom = SIZE(cs_atom_list, 1)
559 ELSE
560 natom = -1
561 END IF
562
563 DO iat = 1, natom
564 iatom = cs_atom_list(iat)
565 r_iatom = pbc(particle_set(iatom)%r, cell)
566 shift_val = eval_interp_spl3_pbc(r_iatom, shiftspl)
567 chemical_shift(idir, i_b, iatom) = chemical_shift(idir, i_b, iatom) + &
568 nmr_env%shift_factor*twopi**2*shift_val
569 END DO
570
571 IF (do_nics) THEN
572 DO iatom = 1, n_nics
573 ra(:) = r_nics(:, iatom)
574 r_iatom = pbc(ra, cell)
575 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 nmr_env%shift_factor*twopi**2*shift_val
578 END DO
579 END IF
580
581 CALL auxbas_pw_pool%give_back_pw(shiftspl)
582
583 !
584 CALL timestop(handle)
585 !
586 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 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 INTEGER, DIMENSION(:), POINTER :: cs_atom_list
610 LOGICAL :: do_nics
611 REAL(dp) :: r_iatom(3), ra(3)
612 REAL(dp), DIMENSION(:, :), POINTER :: r_nics
613 REAL(dp), DIMENSION(:, :, :), POINTER :: chemical_shift, chemical_shift_nics
614
615 CALL timeset(routinen, handle)
616 !
617 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 n_nics=n_nics, r_nics=r_nics, do_nics=do_nics)
623 !
624 IF (ASSOCIATED(cs_atom_list)) THEN
625 natom = SIZE(cs_atom_list, 1)
626 ELSE
627 natom = -1
628 END IF
629 !
630 ! compute the chemical shift
631 DO iat = 1, natom
632 iatom = cs_atom_list(iat)
633 r_iatom = pbc(particle_set(iatom)%r, cell)
634 CALL gsumr(r_iatom, shift_pw_gspace, cplx)
635 chemical_shift(idir, i_b, iatom) = chemical_shift(idir, i_b, iatom) + &
636 nmr_env%shift_factor*twopi**2*real(cplx, dp)
637 END DO
638 !
639 ! compute nics
640 IF (do_nics) THEN
641 DO iat = 1, n_nics
642 ra = pbc(r_nics(:, iat), cell)
643 CALL gsumr(ra, shift_pw_gspace, cplx)
644 chemical_shift_nics(idir, i_b, iat) = chemical_shift_nics(idir, i_b, iat) + &
645 nmr_env%shift_factor*twopi**2*real(cplx, dp)
646 END DO
647 END IF
648
649 CALL timestop(handle)
650
651 END SUBROUTINE gsum_shift_pwgrid
652
653! **************************************************************************************************
654!> \brief ...
655!> \param r ...
656!> \param pw ...
657!> \param cplx ...
658! **************************************************************************************************
659 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 grid => pw%pw_grid
669 cplx = z_zero
670 DO ig = grid%first_gne0, grid%ngpts_cut_local
671 rg = (grid%g(1, ig)*r(1) + grid%g(2, ig)*r(2) + grid%g(3, ig)*r(3))*gaussi
672 cplx = cplx + pw%array(ig)*exp(rg)
673 END DO
674 IF (grid%have_g0) cplx = cplx + pw%array(1)
675 CALL grid%para%group%sum(cplx)
676 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 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 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 REAL(dp), DIMENSION(:, :), POINTER :: r_nics
703 REAL(dp), DIMENSION(:, :, :), POINTER :: cs, cs_loc, cs_nics, cs_nics_loc, &
704 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 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
710 TYPE(section_vals_type), POINTER :: nmr_section
711
712 NULLIFY (cs, cs_nics, r_nics, cs_loc, cs_nics_loc, logger, particle_set, atom_kind, dft_control)
713
714 logger => cp_get_default_logger()
715 output_unit = cp_logger_get_default_io_unit(logger)
716
717 nmr_section => section_vals_get_subs_vals(qs_env%input, &
718 "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 do_nics=do_nics)
729 !
730 CALL get_current_env(current_env=current_env, &
731 chi_tensor=chi_tensor, &
732 chi_tensor_loc=chi_tensor_loc)
733 !
734 ! multiply by the appropriate factor
735 chi_tensor_tmp(:, :) = 0.0_dp
736 chi_tensor_loc_tmp(:, :) = 0.0_dp
737 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 particle_set=particle_set)
743
744 natom = SIZE(particle_set, 1)
745 gapw = dft_control%qs_control%gapw
746 nat_print = SIZE(cs_atom_list, 1)
747
748 ALLOCATE (cs_tot(3, 3, nat_print))
749 IF (do_nics) THEN
750 ALLOCATE (cs_nics_tot(3, 3, n_nics))
751 END IF
752 ! Finalize Chi calculation
753 ! Symmetrize
754 chi_sym_tot(:, :) = (chi_tensor_tmp(:, :) + transpose(chi_tensor_tmp(:, :)))/2.0_dp
755 IF (gapw) THEN
756 chi_sym_tot(:, :) = chi_sym_tot(:, :) &
757 & + (chi_tensor_loc_tmp(:, :) + transpose(chi_tensor_loc_tmp(:, :)))/2.0_dp
758 END IF
759 chi_tmp(:, :) = chi_sym_tot(:, :)
760 CALL diamat_all(chi_tmp, eig)
761 chi_iso = (eig(1) + eig(2) + eig(3))/3.0_dp
762 chi_aniso = eig(3) - (eig(2) + eig(1))/2.0_dp
763 !
764 IF (output_unit > 0) THEN
765 WRITE (output_unit, '(T2,A,E14.6)') 'CheckSum Chi =', &
766 sqrt(ddot(9, chi_tensor_tmp(1, 1), 1, chi_tensor_tmp(1, 1), 1))
767 END IF
768 !
769 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 extension=".data", middle_name="CHI", log_filename=.false.)
774
775 WRITE (title, '(A)') "Magnetic Susceptibility Tensor "
776 IF (unit_atoms > 0) THEN
777 WRITE (unit_atoms, '(T2,A)') title
778 WRITE (unit_atoms, '(T1,A)') " CHI from SOFT J in 10^-30 J/T^2 units"
779 WRITE (unit_atoms, '(3(A,f10.4))') ' XX = ', chi_tensor_tmp(1, 1),&
780 & ' XY = ', chi_tensor_tmp(1, 2),&
781 & ' XZ = ', chi_tensor_tmp(1, 3)
782 WRITE (unit_atoms, '(3(A,f10.4))') ' YX = ', chi_tensor_tmp(2, 1),&
783 & ' YY = ', chi_tensor_tmp(2, 2),&
784 & ' YZ = ', chi_tensor_tmp(2, 3)
785 WRITE (unit_atoms, '(3(A,f10.4))') ' ZX = ', chi_tensor_tmp(3, 1),&
786 & ' ZY = ', chi_tensor_tmp(3, 2),&
787 & ' ZZ = ', chi_tensor_tmp(3, 3)
788 IF (gapw) THEN
789 WRITE (unit_atoms, '(T1,A)') " CHI from LOCAL J in 10^-30 J/T^2 units"
790 WRITE (unit_atoms, '(3(A,f10.4))') ' XX = ', chi_tensor_loc_tmp(1, 1),&
791 & ' XY = ', chi_tensor_loc_tmp(1, 2),&
792 & ' XZ = ', chi_tensor_loc_tmp(1, 3)
793 WRITE (unit_atoms, '(3(A,f10.4))') ' YX = ', chi_tensor_loc_tmp(2, 1),&
794 & ' YY = ', chi_tensor_loc_tmp(2, 2),&
795 & ' YZ = ', chi_tensor_loc_tmp(2, 3)
796 WRITE (unit_atoms, '(3(A,f10.4))') ' ZX = ', chi_tensor_loc_tmp(3, 1),&
797 & ' ZY = ', chi_tensor_loc_tmp(3, 2),&
798 & ' ZZ = ', chi_tensor_loc_tmp(3, 3)
799 END IF
800 WRITE (unit_atoms, '(T1,A)') " Total CHI in 10^-30 J/T^2 units"
801 WRITE (unit_atoms, '(3(A,f10.4))') ' XX = ', chi_sym_tot(1, 1),&
802 & ' XY = ', chi_sym_tot(1, 2),&
803 & ' XZ = ', chi_sym_tot(1, 3)
804 WRITE (unit_atoms, '(3(A,f10.4))') ' YX = ', chi_sym_tot(2, 1),&
805 & ' YY = ', chi_sym_tot(2, 2),&
806 & ' YZ = ', chi_sym_tot(2, 3)
807 WRITE (unit_atoms, '(3(A,f10.4))') ' ZX = ', chi_sym_tot(3, 1),&
808 & ' ZY = ', chi_sym_tot(3, 2),&
809 & ' ZZ = ', chi_sym_tot(3, 3)
810 chi_sym_tot(:, :) = chi_sym_tot(:, :)*nmr_env%chi_SI2ppmcgs
811 WRITE (unit_atoms, '(T1,A)') " Total CHI in ppm-cgs units"
812 WRITE (unit_atoms, '(3(A,f10.4))') ' XX = ', chi_sym_tot(1, 1),&
813 & ' XY = ', chi_sym_tot(1, 2),&
814 & ' XZ = ', chi_sym_tot(1, 3)
815 WRITE (unit_atoms, '(3(A,f10.4))') ' YX = ', chi_sym_tot(2, 1),&
816 & ' YY = ', chi_sym_tot(2, 2),&
817 & ' YZ = ', chi_sym_tot(2, 3)
818 WRITE (unit_atoms, '(3(A,f10.4))') ' ZX = ', chi_sym_tot(3, 1),&
819 & ' ZY = ', chi_sym_tot(3, 2),&
820 & ' ZZ = ', chi_sym_tot(3, 3)
821 WRITE (unit_atoms, '(/T1,3(A,f10.4))') &
822 ' PV1=', nmr_env%chi_SI2ppmcgs*eig(1), &
823 ' PV2=', nmr_env%chi_SI2ppmcgs*eig(2), &
824 ' PV3=', nmr_env%chi_SI2ppmcgs*eig(3)
825 WRITE (unit_atoms, '(T1,A,F10.4,10X,A,F10.4)') &
826 ' ISO=', nmr_env%chi_SI2ppmcgs*chi_iso, &
827 'ANISO=', nmr_env%chi_SI2ppmcgs*chi_aniso
828 END IF
829
830 CALL cp_print_key_finished_output(unit_atoms, logger, nmr_section,&
831 & "PRINT%CHI_TENSOR")
832 END IF ! print chi
833 !
834 ! Add the chi part to the shifts
835 cs_tot(:, :, :) = 0.0_dp
836 DO ir = 1, nat_print
837 iatom = cs_atom_list(ir)
838 rpos(1:3) = particle_set(iatom)%r(1:3)
839 atom_kind => particle_set(iatom)%atomic_kind
840 CALL get_atomic_kind(atom_kind, name=name, element_symbol=element_symbol)
841 cs_tot(:, :, ir) = chi_tensor_tmp(:, :)*nmr_env%chi_SI2shiftppm + cs(:, :, iatom)
842 IF (gapw) cs_tot(:, :, ir) = cs_tot(:, :, ir) + cs_loc(:, :, iatom)
843 END DO ! ir
844 IF (output_unit > 0) THEN
845 WRITE (output_unit, '(T2,A,E14.6)') 'CheckSum Shifts =', &
846 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 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 log_filename=.false.)
856
857 nat_print = SIZE(cs_atom_list, 1)
858 IF (unit_atoms > 0) THEN
859 WRITE (title, '(A,1X,I5)') "Shielding atom at atomic positions. # tensors printed ", nat_print
860 WRITE (unit_atoms, '(T2,A)') title
861 DO ir = 1, nat_print
862 iatom = cs_atom_list(ir)
863 rpos(1:3) = particle_set(iatom)%r(1:3)
864 atom_kind => particle_set(iatom)%atomic_kind
865 CALL get_atomic_kind(atom_kind, name=name, element_symbol=element_symbol)
866 shift_sym_tot(:, :) = 0.5_dp*(cs_tot(:, :, ir) + transpose(cs_tot(:, :, ir)))
867 CALL diamat_all(shift_sym_tot, eig)
868 shift_iso = (eig(1) + eig(2) + eig(3))/3.0_dp
869 shift_aniso = eig(3) - (eig(2) + eig(1))/2.0_dp
870 !
871 WRITE (unit_atoms, '(T2,I5,A,2X,A2,2X,3f15.6)') iatom, trim(name), element_symbol, rpos(1:3)
872 !
873 IF (gapw) THEN
874 WRITE (unit_atoms, '(T1,A)') " SIGMA from SOFT J"
875 WRITE (unit_atoms, '(3(A,f10.4))') ' XX = ', cs(1, 1, iatom),&
876 & ' XY = ', cs(1, 2, iatom),&
877 & ' XZ = ', cs(1, 3, iatom)
878 WRITE (unit_atoms, '(3(A,f10.4))') ' YX = ', cs(2, 1, iatom),&
879 & ' YY = ', cs(2, 2, iatom),&
880 & ' YZ = ', cs(2, 3, iatom)
881 WRITE (unit_atoms, '(3(A,f10.4))') ' ZX = ', cs(3, 1, iatom),&
882 & ' ZY = ', cs(3, 2, iatom),&
883 & ' ZZ = ', cs(3, 3, iatom)
884 WRITE (unit_atoms, '(T1,A)') " SIGMA from LOCAL J"
885 WRITE (unit_atoms, '(3(A,f10.4))') ' XX = ', cs_loc(1, 1, iatom),&
886 & ' XY = ', cs_loc(1, 2, iatom),&
887 & ' XZ = ', cs_loc(1, 3, iatom)
888 WRITE (unit_atoms, '(3(A,f10.4))') ' YX = ', cs_loc(2, 1, iatom),&
889 & ' YY = ', cs_loc(2, 2, iatom),&
890 & ' YZ = ', cs_loc(2, 3, iatom)
891 WRITE (unit_atoms, '(3(A,f10.4))') ' ZX = ', cs_loc(3, 1, iatom),&
892 & ' ZY = ', cs_loc(3, 2, iatom),&
893 & ' ZZ = ', cs_loc(3, 3, iatom)
894 END IF
895 WRITE (unit_atoms, '(T1,A)') " SIGMA TOTAL"
896 WRITE (unit_atoms, '(3(A,f10.4))') ' XX = ', cs_tot(1, 1, ir),&
897 & ' XY = ', cs_tot(1, 2, ir),&
898 & ' XZ = ', cs_tot(1, 3, ir)
899 WRITE (unit_atoms, '(3(A,f10.4))') ' YX = ', cs_tot(2, 1, ir),&
900 & ' YY = ', cs_tot(2, 2, ir),&
901 & ' YZ = ', cs_tot(2, 3, ir)
902 WRITE (unit_atoms, '(3(A,f10.4))') ' ZX = ', cs_tot(3, 1, ir),&
903 & ' ZY = ', cs_tot(3, 2, ir),&
904 & ' ZZ = ', cs_tot(3, 3, ir)
905 WRITE (unit_atoms, '(T1,2(A,f12.4))') ' ISOTROPY = ', shift_iso,&
906 & ' ANISOTROPY = ', shift_aniso
907 END DO ! ir
908 END IF
909 CALL cp_print_key_finished_output(unit_atoms, logger, nmr_section,&
910 & "PRINT%SHIELDING_TENSOR")
911
912 IF (do_nics) THEN
913 !
914 ! Add the chi part to the nics
915 cs_nics_tot(:, :, :) = 0.0_dp
916 DO ir = 1, n_nics
917 cs_nics_tot(:, :, ir) = chi_tensor_tmp(:, :)*nmr_env%chi_SI2shiftppm + cs_nics(:, :, ir)
918 IF (gapw) cs_nics_tot(:, :, ir) = cs_nics_tot(:, :, ir) + cs_nics_loc(:, :, ir)
919 END DO ! ir
920 IF (output_unit > 0) THEN
921 WRITE (output_unit, '(T2,A,E14.6)') 'CheckSum NICS =', &
922 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 log_filename=.false.)
928 IF (unit_nics > 0) THEN
929 WRITE (title, '(A,1X,I5)') "Shielding at nics positions. # tensors printed ", n_nics
930 WRITE (unit_nics, '(T2,A)') title
931 DO ir = 1, n_nics
932 shift_sym_tot(:, :) = 0.5_dp*(cs_nics_tot(:, :, ir) + transpose(cs_nics_tot(:, :, ir)))
933 CALL diamat_all(shift_sym_tot, eig)
934 shift_iso = (eig(1) + eig(2) + eig(3))/3.0_dp
935 shift_aniso = eig(3) - (eig(2) + eig(1))/2.0_dp
936 !
937 WRITE (unit_nics, '(T2,I5,2X,3f15.6)') ir, r_nics(1:3, ir)
938 !
939 IF (gapw) THEN
940 WRITE (unit_nics, '(T1,A)') " SIGMA from SOFT J"
941 WRITE (unit_nics, '(3(A,f10.4))') ' XX = ', cs_nics(1, 1, ir),&
942 & ' XY = ', cs_nics(1, 2, ir),&
943 & ' XZ = ', cs_nics(1, 3, ir)
944 WRITE (unit_nics, '(3(A,f10.4))') ' YX = ', cs_nics(2, 1, ir),&
945 & ' YY = ', cs_nics(2, 2, ir),&
946 & ' YZ = ', cs_nics(2, 3, ir)
947 WRITE (unit_nics, '(3(A,f10.4))') ' ZX = ', cs_nics(3, 1, ir),&
948 & ' ZY = ', cs_nics(3, 2, ir),&
949 & ' ZZ = ', cs_nics(3, 3, ir)
950 WRITE (unit_nics, '(T1,A)') " SIGMA from LOCAL J"
951 WRITE (unit_nics, '(3(A,f10.4))') ' XX = ', cs_nics_loc(1, 1, ir),&
952 & ' XY = ', cs_nics_loc(1, 2, ir),&
953 & ' XZ = ', cs_nics_loc(1, 3, ir)
954 WRITE (unit_nics, '(3(A,f10.4))') ' YX = ', cs_nics_loc(2, 1, ir),&
955 & ' YY = ', cs_nics_loc(2, 2, ir),&
956 & ' YZ = ', cs_nics_loc(2, 3, ir)
957 WRITE (unit_nics, '(3(A,f10.4))') ' ZX = ', cs_nics_loc(3, 1, ir),&
958 & ' ZY = ', cs_nics_loc(3, 2, ir),&
959 & ' ZZ = ', cs_nics_loc(3, 3, ir)
960 END IF
961 WRITE (unit_nics, '(T1,A)') " SIGMA TOTAL"
962 WRITE (unit_nics, '(3(A,f10.4))') ' XX = ', cs_nics_tot(1, 1, ir),&
963 & ' XY = ', cs_nics_tot(1, 2, ir),&
964 & ' XZ = ', cs_nics_tot(1, 3, ir)
965 WRITE (unit_nics, '(3(A,f10.4))') ' YX = ', cs_nics_tot(2, 1, ir),&
966 & ' YY = ', cs_nics_tot(2, 2, ir),&
967 & ' YZ = ', cs_nics_tot(2, 3, ir)
968 WRITE (unit_nics, '(3(A,f10.4))') ' ZX = ', cs_nics_tot(3, 1, ir),&
969 & ' ZY = ', cs_nics_tot(3, 2, ir),&
970 & ' ZZ = ', cs_nics_tot(3, 3, ir)
971 WRITE (unit_nics, '(T1,2(A,f12.4))') ' ISOTROPY = ', shift_iso,&
972 & ' ANISOTROPY = ', shift_aniso
973 END DO
974 END IF
975 CALL cp_print_key_finished_output(unit_nics, logger, nmr_section,&
976 & "PRINT%SHIELDING_TENSOR")
977 END IF
978 END IF ! print shift
979 !
980 ! clean up
981 DEALLOCATE (cs_tot)
982 IF (do_nics) THEN
983 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 END SUBROUTINE nmr_shift_print
994
995END MODULE qs_linres_nmr_shift
996
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public gaussi
real(kind=dp), parameter, public twopi
complex(kind=dp), parameter, public z_zero
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Definition mathlib.F:380
Interface to the message passing library MPI.
Define the data structure for the particle information.
computes preconditioners, and implements methods to apply them currently used in qs_ot
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
different utils that are useful to manipulate splines on the regular grid of a pw
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_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_spline_precond_set_kind(preconditioner, precond_kind, pbc, transpose)
switches the types of precoditioner to use
real(kind=dp) function, public eval_interp_spl3_pbc(vec, pw)
Evaluates the PBC interpolated Spline (pw) function on the generic input vector (vec)
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 spl3_pbc(pw_in, pw_out)
...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
given the response wavefunctions obtained by the application of the (rxp), p, and ((dk-dl)xp) operato...
subroutine, public mult_g_ov_g2_grid(pw_pool, rho_gspace, funcg_times_rho, idir, my_chi)
Given the current density on the PW grid in reciprcal space (obtained by FFT), calculate the integral...
from the response current density calculates the shift tensor and the susceptibility
subroutine, public nmr_shift_print(nmr_env, current_env, qs_env)
Shielding tensor and Chi are printed into a file if required from input It is possible to print only ...
subroutine, public nmr_shift(nmr_env, current_env, qs_env, ib)
...
Calculate the operators p rxp and D needed in the optimization of the different contribution of the f...
subroutine, public set_vecp(i1, i2, i3)
...
real(dp) function, public fac_vecp(a, b, c)
...
subroutine, public set_vecp_rev(i1, i2, i3)
...
Type definitiona for linear response calculations.
subroutine, public get_current_env(current_env, simple_done, simple_converged, full_done, nao, nstates, gauge, list_cubes, statetrueindex, gauge_name, basisfun_center, nbr_center, center_list, centers_set, psi1_p, psi1_rxp, psi1_d, p_psi0, rxp_psi0, jrho1_atom_set, jrho1_set, chi_tensor, chi_tensor_loc, gauge_atom_radius, rs_gauge, use_old_gauge_atom, chi_pbc, psi0_order)
...
subroutine, public get_nmr_env(nmr_env, n_nics, cs_atom_list, do_calc_cs_atom, r_nics, chemical_shift, chemical_shift_loc, chemical_shift_nics_loc, chemical_shift_nics, shift_gapw_radius, do_nics, interpolate_shift)
...
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
All kind of helpful little routines.
Definition util.F:14
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
Definition util.F:333
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
contained for different pw related things
to create arrays of pools
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
stores information for the preconditioner used to calculate the coeffs of splines
Provides all information about a quickstep kind.