(git:374b731)
Loading...
Searching...
No Matches
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
25 USE cell_types, ONLY: cell_type
29 USE cp_output_handling, ONLY: cp_p_file,&
38 USE cp_units, ONLY: cp_unit_from_cp2k,&
43 USE kinds, ONLY: default_path_length,&
44 dp
47 USE pw_env_types, ONLY: pw_env_type
54#include "./base/base_uses.f90"
55
56 IMPLICIT NONE
57
58 PRIVATE
60
61 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_nmr_utils'
62
63CONTAINS
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
338END 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
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
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
type of a logger, at the moment it contains just a print level starting at which level it should be l...
contained for different pw related things
General settings for linear response calculations.
container for the pools of matrixes used by qs