(git:34ef472)
qs_linres_nmr_utils.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Chemical shift calculation by dfpt
10 !> Initialization of the nmr_env, creation of the special neighbor lists
11 !> Perturbation Hamiltonians by application of the p and rxp oprtators to psi0
12 !> Write output
13 !> Deallocate everything
14 !> \note
15 !> The psi0 should be localized
16 !> the Sebastiani method works within the assumption that the orbitals are
17 !> completely contained in the simulation box
18 !> \par History
19 !> created 07-2005 [MI]
20 !> \author MI
21 ! **************************************************************************************************
23 
24  USE atomic_kind_types, ONLY: atomic_kind_type
25  USE cell_types, ONLY: cell_type
26  USE cp_control_types, ONLY: dft_control_type
28  cp_logger_type
29  USE cp_output_handling, ONLY: cp_p_file,&
34  parser_get_object
35  USE cp_parser_types, ONLY: cp_parser_type,&
38  USE cp_units, ONLY: cp_unit_from_cp2k,&
41  section_vals_type,&
43  USE kinds, ONLY: default_path_length,&
44  dp
45  USE memory_utilities, ONLY: reallocate
46  USE particle_types, ONLY: particle_type
47  USE pw_env_types, ONLY: pw_env_type
48  USE qs_environment_types, ONLY: get_qs_env,&
49  qs_environment_type
50  USE qs_linres_types, ONLY: linres_control_type,&
51  nmr_env_type
52  USE qs_matrix_pools, ONLY: qs_matrix_pools_type
53  USE scf_control_types, ONLY: scf_control_type
54 #include "./base/base_uses.f90"
55 
56  IMPLICIT NONE
57 
58  PRIVATE
59  PUBLIC :: nmr_env_cleanup, nmr_env_init
60 
61  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_nmr_utils'
62 
63 CONTAINS
64 
65 ! **************************************************************************************************
66 !> \brief Initialize the nmr environment
67 !> \param nmr_env ...
68 !> \param qs_env ...
69 !> \par History
70 !> 07.2006 created [MI]
71 !> \author MI
72 ! **************************************************************************************************
73  SUBROUTINE nmr_env_init(nmr_env, qs_env)
74  !
75  TYPE(nmr_env_type) :: nmr_env
76  TYPE(qs_environment_type), POINTER :: qs_env
77 
78  CHARACTER(LEN=*), PARAMETER :: routinen = 'nmr_env_init'
79 
80  CHARACTER(LEN=default_path_length) :: nics_file_name
81  INTEGER :: handle, ini, ir, j, n_mo(2), n_rep, nao, &
82  nat_print, natom, nmoloc, nspins, &
83  output_unit
84  INTEGER, DIMENSION(:), POINTER :: bounds, list
85  LOGICAL :: gapw
86  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
87  TYPE(cell_type), POINTER :: cell
88  TYPE(cp_logger_type), POINTER :: logger
89  TYPE(dft_control_type), POINTER :: dft_control
90  TYPE(linres_control_type), POINTER :: linres_control
91  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
92  TYPE(pw_env_type), POINTER :: pw_env
93  TYPE(qs_matrix_pools_type), POINTER :: mpools
94  TYPE(scf_control_type), POINTER :: scf_control
95  TYPE(section_vals_type), POINTER :: lr_section, nmr_section
96 
97 !
98 
99  CALL timeset(routinen, handle)
100 
101  NULLIFY (atomic_kind_set, cell, dft_control, linres_control, scf_control)
102  NULLIFY (logger, mpools, nmr_section, particle_set)
103  NULLIFY (pw_env)
104 
105  n_mo(1:2) = 0
106  nao = 0
107  nmoloc = 0
108 
109  logger => cp_get_default_logger()
110  lr_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES")
111 
112  output_unit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
113  extension=".linresLog")
114 
115  CALL nmr_env_cleanup(nmr_env)
116 
117  IF (output_unit > 0) THEN
118  WRITE (output_unit, "(/,T20,A,/)") "*** Start NMR Chemical Shift Calculation ***"
119  WRITE (output_unit, "(T10,A,/)") "Inizialization of the NMR environment"
120  END IF
121 
122  ! If current_density or full_nmr different allocations are required
123  nmr_section => section_vals_get_subs_vals(qs_env%input, &
124  & "PROPERTIES%LINRES%NMR")
125  CALL section_vals_val_get(nmr_section, "INTERPOLATE_SHIFT", l_val=nmr_env%interpolate_shift)
126  CALL section_vals_val_get(nmr_section, "SHIFT_GAPW_RADIUS", r_val=nmr_env%shift_gapw_radius)
127  CALL section_vals_val_get(nmr_section, "NICS", l_val=nmr_env%do_nics)
128  IF (nmr_env%do_nics) THEN
129  CALL section_vals_val_get(nmr_section, "NICS_FILE_NAME", &
130  c_val=nics_file_name)
131  block
132  CHARACTER(LEN=2) :: label
133  LOGICAL :: my_end
134  TYPE(cp_parser_type) :: parser
135  CALL parser_create(parser, nics_file_name)
136  CALL parser_get_next_line(parser, 1)
137  CALL parser_get_object(parser, nmr_env%n_nics)
138  ALLOCATE (nmr_env%r_nics(3, nmr_env%n_nics))
139  CALL parser_get_next_line(parser, 2)
140  DO j = 1, nmr_env%n_nics
141  CALL parser_get_object(parser, label)
142  CALL parser_get_object(parser, nmr_env%r_nics(1, j))
143  CALL parser_get_object(parser, nmr_env%r_nics(2, j))
144  CALL parser_get_object(parser, nmr_env%r_nics(3, j))
145  nmr_env%r_nics(1, j) = cp_unit_to_cp2k(nmr_env%r_nics(1, j), "angstrom")
146  nmr_env%r_nics(2, j) = cp_unit_to_cp2k(nmr_env%r_nics(2, j), "angstrom")
147  nmr_env%r_nics(3, j) = cp_unit_to_cp2k(nmr_env%r_nics(3, j), "angstrom")
148  CALL parser_get_next_line(parser, 1, at_end=my_end)
149  IF (my_end) EXIT
150  END DO
151  CALL parser_release(parser)
152  END block
153  END IF
154 
155  CALL get_qs_env(qs_env=qs_env, &
156  atomic_kind_set=atomic_kind_set, &
157  cell=cell, &
158  dft_control=dft_control, &
159  linres_control=linres_control, &
160  mpools=mpools, &
161  particle_set=particle_set, &
162  pw_env=pw_env, &
163  scf_control=scf_control)
164  !
165  ! Check if restat also psi0 should be restarted
166  !IF(nmr_env%restart_nmr .AND. scf_control%density_guess/=restart_guess)THEN
167  ! CPABORT("restart_nmr requires density_guess=restart")
168  !ENDIF
169  !
170  ! check that the psi0 are localized and you have all the centers
171  IF (.NOT. linres_control%localized_psi0) &
172  cpwarn(' To get NMR parameters within PBC you need localized zero order orbitals ')
173 
174  gapw = dft_control%qs_control%gapw
175  nspins = dft_control%nspins
176  natom = SIZE(particle_set, 1)
177 
178  !
179  ! Conversion factors
180  ! factor for the CHEMICAL SHIFTS: alpha^2 * ppm.
181  nmr_env%shift_factor = (1.0_dp/137.03602_dp)**2*1.0e+6_dp/cell%deth
182  ! factor for the CHEMICAL SHIFTS: alpha^2 * ppm.
183  nmr_env%shift_factor_gapw = (1.0_dp/137.03602_dp)**2*1.0e+6_dp
184  ! chi_factor = 1/4 * e^2/m * a_0 ^2
185  nmr_env%chi_factor = 1.9727566e-29_dp/1.0e-30_dp ! -> displayed in 10^-30 J/T^2
186  ! Factor to convert 10^-30 J/T^2 into ppm cgs = ppm cm^3/mol
187  ! = 10^-30 * mu_0/4pi * N_A * 10^6 * 10^6 [one 10^6 for ppm, one for m^3 -> cm^3]
188  nmr_env%chi_SI2ppmcgs = 6.022045_dp/1.0e+2_dp
189  ! Chi to Shift: 10^-30 * 2/3 mu_0 / Omega * 1/ppm
190  nmr_env%chi_SI2shiftppm = 1.0e-30_dp*8.37758041e-7_dp/ &
191  (cp_unit_from_cp2k(cell%deth, "angstrom^3")*1.0e-30_dp)*1.0e+6_dp
192 
193  IF (output_unit > 0) THEN
194  WRITE (output_unit, "(T2,A,T65,ES15.6)") "NMR| Shift gapw radius (a.u.) ", nmr_env%shift_gapw_radius
195  IF (nmr_env%do_nics) THEN
196  WRITE (output_unit, "(T2,A,T50,I5,A)") "NMR| NICS computed in ", nmr_env%n_nics, " additional points"
197  WRITE (output_unit, "(T2,A,T60,A)") "NMR| NICS coordinates read on file ", trim(nics_file_name)
198  END IF
199  WRITE (output_unit, "(T2,A,T65,ES15.6)") "NMR| Shift factor (ppm)", nmr_env%shift_factor
200  IF (gapw) THEN
201  WRITE (output_unit, "(T2,A,T65,ES15.6)") "NMR| Shift factor gapw (ppm)", nmr_env%shift_factor_gapw
202  END IF
203  WRITE (output_unit, "(T2,A,T65,ES15.6)") "NMR| Chi factor (SI)", nmr_env%chi_factor
204  WRITE (output_unit, "(T2,A,T65,ES15.6)") "NMR| Conversion Chi (ppm/cgs)", nmr_env%chi_SI2ppmcgs
205  WRITE (output_unit, "(T2,A,T65,ES15.6)") "NMR| Conversion Chi to Shift", nmr_env%chi_SI2shiftppm
206  END IF
207 
208  ALLOCATE (nmr_env%do_calc_cs_atom(natom))
209  nmr_env%do_calc_cs_atom = 0
210 
211  IF (btest(cp_print_key_should_output(logger%iter_info, nmr_section,&
212  & "PRINT%SHIELDING_TENSOR"), cp_p_file)) THEN
213 
214  NULLIFY (bounds, list)
215  nat_print = 0
216  CALL section_vals_val_get(nmr_section,&
217  & "PRINT%SHIELDING_TENSOR%ATOMS_LU_BOUNDS", &
218  i_vals=bounds)
219  nat_print = bounds(2) - bounds(1) + 1
220  IF (nat_print > 0) THEN
221  ALLOCATE (nmr_env%cs_atom_list(nat_print))
222  DO ir = 1, nat_print
223  nmr_env%cs_atom_list(ir) = bounds(1) + (ir - 1)
224  nmr_env%do_calc_cs_atom(bounds(1) + (ir - 1)) = 1
225  END DO
226  END IF
227 
228  IF (.NOT. ASSOCIATED(nmr_env%cs_atom_list)) THEN
229  CALL section_vals_val_get(nmr_section, "PRINT%SHIELDING_TENSOR%ATOMS_LIST", &
230  n_rep_val=n_rep)
231  nat_print = 0
232  DO ir = 1, n_rep
233  NULLIFY (list)
234  CALL section_vals_val_get(nmr_section, "PRINT%SHIELDING_TENSOR%ATOMS_LIST", &
235  i_rep_val=ir, i_vals=list)
236  IF (ASSOCIATED(list)) THEN
237  CALL reallocate(nmr_env%cs_atom_list, 1, nat_print + SIZE(list))
238  DO ini = 1, SIZE(list)
239  nmr_env%cs_atom_list(ini + nat_print) = list(ini)
240  nmr_env%do_calc_cs_atom(list(ini)) = 1
241  END DO
242  nat_print = nat_print + SIZE(list)
243  END IF
244  END DO ! ir
245  END IF
246 
247  IF (.NOT. ASSOCIATED(nmr_env%cs_atom_list)) THEN
248  ALLOCATE (nmr_env%cs_atom_list(natom))
249  DO ir = 1, natom
250  nmr_env%cs_atom_list(ir) = ir
251  END DO
252  nmr_env%do_calc_cs_atom = 1
253  END IF
254  !
255  ! check the list
256  cpassert(ASSOCIATED(nmr_env%cs_atom_list))
257  DO ir = 1, SIZE(nmr_env%cs_atom_list, 1)
258  IF (nmr_env%cs_atom_list(ir) .LT. 1 .OR. nmr_env%cs_atom_list(ir) .GT. natom) THEN
259  cpabort("Unknown atom(s)")
260  END IF
261  DO j = 1, SIZE(nmr_env%cs_atom_list, 1)
262  IF (j .EQ. ir) cycle
263  IF (nmr_env%cs_atom_list(ir) .EQ. nmr_env%cs_atom_list(j)) THEN
264  cpabort("Duplicate atoms")
265  END IF
266  END DO
267  END DO
268  ELSE
269  NULLIFY (nmr_env%cs_atom_list)
270  END IF
271 
272  IF (output_unit > 0) THEN
273  IF (ASSOCIATED(nmr_env%cs_atom_list)) THEN
274  WRITE (output_unit, "(T2,A,T69,I5,A)") "NMR| Shielding tensor computed for ", &
275  SIZE(nmr_env%cs_atom_list, 1), " atoms"
276  ELSE
277  WRITE (output_unit, "(T2,A,T50)")&
278  & "NMR| Shielding tensor not computed at the atomic positions"
279  END IF
280  END IF
281  !
282  ! Initialize the chemical shift tensor
283  ALLOCATE (nmr_env%chemical_shift(3, 3, natom), &
284  nmr_env%chemical_shift_loc(3, 3, natom))
285  nmr_env%chemical_shift = 0.0_dp
286  nmr_env%chemical_shift_loc = 0.0_dp
287  IF (nmr_env%do_nics) THEN
288  ALLOCATE (nmr_env%chemical_shift_nics_loc(3, 3, nmr_env%n_nics), &
289  nmr_env%chemical_shift_nics(3, 3, nmr_env%n_nics))
290  nmr_env%chemical_shift_nics_loc = 0.0_dp
291  nmr_env%chemical_shift_nics = 0.0_dp
292  END IF
293 
294  CALL cp_print_key_finished_output(output_unit, logger, lr_section,&
295  & "PRINT%PROGRAM_RUN_INFO")
296 
297  CALL timestop(handle)
298 
299  END SUBROUTINE nmr_env_init
300 
301 ! **************************************************************************************************
302 !> \brief Deallocate the nmr environment
303 !> \param nmr_env ...
304 !> \par History
305 !> 07.2005 created [MI]
306 !> \author MI
307 ! **************************************************************************************************
308  SUBROUTINE nmr_env_cleanup(nmr_env)
309 
310  TYPE(nmr_env_type) :: nmr_env
311 
312  IF (ASSOCIATED(nmr_env%cs_atom_list)) THEN
313  DEALLOCATE (nmr_env%cs_atom_list)
314  END IF
315  IF (ASSOCIATED(nmr_env%do_calc_cs_atom)) THEN
316  DEALLOCATE (nmr_env%do_calc_cs_atom)
317  END IF
318  !chemical_shift
319  IF (ASSOCIATED(nmr_env%chemical_shift)) THEN
320  DEALLOCATE (nmr_env%chemical_shift)
321  END IF
322  IF (ASSOCIATED(nmr_env%chemical_shift_loc)) THEN
323  DEALLOCATE (nmr_env%chemical_shift_loc)
324  END IF
325  ! nics
326  IF (ASSOCIATED(nmr_env%r_nics)) THEN
327  DEALLOCATE (nmr_env%r_nics)
328  END IF
329  IF (ASSOCIATED(nmr_env%chemical_shift_nics)) THEN
330  DEALLOCATE (nmr_env%chemical_shift_nics)
331  END IF
332  IF (ASSOCIATED(nmr_env%chemical_shift_nics_loc)) THEN
333  DEALLOCATE (nmr_env%chemical_shift_nics_loc)
334  END IF
335 
336  END SUBROUTINE nmr_env_cleanup
337 
338 END MODULE qs_linres_nmr_utils
Define the atomic kind types and their sub types.
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 ...
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...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_get_next_line(parser, nline, at_end)
Read the next input line and broadcast the input information. Skip (nline-1) lines and skip also all ...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_release(parser)
releases the parser
subroutine, public parser_create(parser, file_name, unit_nr, para_env, end_section_label, separator_chars, comment_char, continuation_char, quote_char, section_char, parse_white_lines, initial_variables, apply_preprocessing)
Start a parser run. Initial variables allow to @SET stuff before opening the file.
unit conversion facility
Definition: cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition: cp_units.F:1179
real(kind=dp) function, public cp_unit_to_cp2k(value, unit_str, defaults, power)
converts to the internal cp2k units to the given unit
Definition: cp_units.F:1150
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_path_length
Definition: kinds.F:58
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition: list.F:24
Utility routines for the memory handling.
Define the data structure for the particle information.
container for various plainwaves related things
Definition: pw_env_types.F:14
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_nonbond, sab_almo, sab_kp, sab_kp_nosym, 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, ecoul_1c, rho0_s_rs, rho0_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, 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, rhs)
Get the QUICKSTEP environment.
Chemical shift calculation by dfpt Initialization of the nmr_env, creation of the special neighbor li...
subroutine, public nmr_env_cleanup(nmr_env)
Deallocate the nmr environment.
subroutine, public nmr_env_init(nmr_env, qs_env)
Initialize the nmr environment.
Type definitiona for linear response calculations.
wrapper for the pools of matrixes
parameters that control an scf iteration