(git:fdbe441)
Loading...
Searching...
No Matches
qs_linres_module.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Contains the setup for the calculation of properties by linear response
10!> by the application of second order density functional perturbation theory.
11!> The knowledge of the ground state energy, density and wavefunctions is assumed.
12!> Uses the self consistent approach.
13!> Properties that can be calculated : none
14!> \par History
15!> created 06-2005 [MI]
16!> \author MI
17! **************************************************************************************************
19 USE bibliography, ONLY: ditler2021,&
21 weber2009,&
22 cite_reference
24 USE cp_dbcsr_api, ONLY: dbcsr_p_type
31 use_qmmm,&
33 USE input_constants, ONLY: lr_current,&
34 lr_none,&
45 USE kinds, ONLY: dp
46 USE qs_dcdr, ONLY: apt_dr,&
65 epr_g_so,&
66 epr_g_soo,&
67 epr_g_zke,&
73 issc_issc,&
90 USE qs_linres_types, ONLY: &
93 USE qs_mfp, ONLY: mfp_aat,&
97 USE qs_mo_types, ONLY: mo_set_type
100 USE qs_p_env_types, ONLY: p_env_release,&
103 USE qs_rho_types, ONLY: qs_rho_get,&
105 USE qs_vcd, ONLY: aat_dv,&
106 apt_dv,&
110 USE qs_vcd_utils, ONLY: vcd_env_cleanup,&
114#include "./base/base_uses.f90"
115
116 IMPLICIT NONE
117
118 PRIVATE
120
121 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_linres_module'
122 CHARACTER(len=*), PARAMETER, PRIVATE :: dcdr_meta_gga_error = &
123 "Analytical DCDR is not implemented for functionals that depend on the kinetic energy density. "// &
124 "Use PROPERTIES%LINRES%DCDR%APT_FD T to calculate APTs by finite differences."
125
126CONTAINS
127! *****************************************************************************
128!> \brief Calculates the derivatives of the MO coefficients dC/dV^lambda_beta
129!> wrt to nuclear velocities. The derivative is indexed by `beta`, the
130!> electric dipole operator by `alpha`.
131!> Calculates the APT and AAT in velocity form
132!> P^lambda_alpha,beta = d< mu_alpha >/dV^lambda_beta
133!> M^lambda_alpha,beta = d< m_alpha >/dV^lambda_beta
134!> \param qs_env ...
135!> \param p_env ...
136!> \author Edward Ditler
137! **************************************************************************************************
138 SUBROUTINE vcd_linres(qs_env, p_env)
139 TYPE(qs_environment_type), POINTER :: qs_env
140 TYPE(qs_p_env_type) :: p_env
141
142 INTEGER :: beta, i, latom
143 LOGICAL :: mfp_is_done, mfp_repeat
144 TYPE(vcd_env_type) :: vcd_env
145
146 CALL cite_reference(ditler2022)
147
148 ! We need the position perturbation for the velocity perturbation operator
149 CALL vcd_env_init(vcd_env, qs_env)
150
151 mfp_repeat = vcd_env%distributed_origin
152 mfp_is_done = .false.
153
154 qs_env%linres_control%linres_restart = .true.
155
156 ! Iterate over the list of atoms for which we want to calculate the APTs/AATs
157 ! default is all atoms.
158 DO latom = 1, SIZE(vcd_env%dcdr_env%list_of_atoms)
159 vcd_env%dcdr_env%lambda = vcd_env%dcdr_env%list_of_atoms(latom)
160
161 CALL prepare_per_atom(vcd_env%dcdr_env, qs_env)
162 CALL prepare_per_atom_vcd(vcd_env, qs_env)
163
164 DO beta = 1, 3 ! in every direction
165
166 vcd_env%dcdr_env%beta = beta
167 vcd_env%dcdr_env%deltaR(vcd_env%dcdr_env%beta, vcd_env%dcdr_env%lambda) = 1._dp
168
169 ! Since we do the heavy lifting anyways, we might also calculate the length form APTs here
170 CALL dcdr_build_op_dr(vcd_env%dcdr_env, qs_env)
171 CALL dcdr_response_dr(vcd_env%dcdr_env, p_env, qs_env)
172 CALL apt_dr(qs_env, vcd_env%dcdr_env)
173
174 ! And with the position perturbation ready, we can calculate the NVP
175 CALL vcd_build_op_dv(vcd_env, qs_env)
176 CALL vcd_response_dv(vcd_env, p_env, qs_env)
177
178 CALL apt_dv(vcd_env, qs_env)
179 CALL aat_dv(vcd_env, qs_env)
180
181 IF (vcd_env%do_mfp) THEN
182 ! Since we came so far, we might as well calculate the MFP AATs
183 ! If we use a distributed origin we need to compute the MFP response again for each
184 ! atom, because the reference point changes.
185 IF (.NOT. mfp_is_done .OR. mfp_repeat) THEN
186 DO i = 1, 3
187 IF (vcd_env%origin_dependent_op_mfp) THEN
188 cpwarn("Using the origin dependent MFP operator")
189 CALL mfp_build_operator_gauge_dependent(vcd_env, qs_env, i)
190 ELSE
191 CALL mfp_build_operator_gauge_independent(vcd_env, qs_env, i)
192 END IF
193 CALL mfp_response(vcd_env, p_env, qs_env, i)
194 END DO
195 mfp_is_done = .true.
196 END IF
197
198 CALL mfp_aat(vcd_env, qs_env)
199 END IF
200 END DO ! beta
201
202 vcd_env%dcdr_env%apt_total_dcdr(:, :, vcd_env%dcdr_env%lambda) = &
203 vcd_env%dcdr_env%apt_el_dcdr(:, :, vcd_env%dcdr_env%lambda) &
204 + vcd_env%dcdr_env%apt_nuc_dcdr(:, :, vcd_env%dcdr_env%lambda)
205
206 vcd_env%apt_total_nvpt(:, :, vcd_env%dcdr_env%lambda) = &
207 vcd_env%apt_el_nvpt(:, :, vcd_env%dcdr_env%lambda) + vcd_env%apt_nuc_nvpt(:, :, vcd_env%dcdr_env%lambda)
208
209 IF (vcd_env%do_mfp) THEN
210 vcd_env%aat_atom_mfp(:, :, vcd_env%dcdr_env%lambda) = vcd_env%aat_atom_mfp(:, :, vcd_env%dcdr_env%lambda)*4._dp
211 END IF
212
213 END DO !lambda
214
215 CALL vcd_print(vcd_env, qs_env)
216 CALL vcd_env_cleanup(qs_env, vcd_env)
217
218 END SUBROUTINE vcd_linres
219
220! **************************************************************************************************
221!> \brief Calculates the derivatives of the MO coefficients dC/dR^lambda_beta
222!> wrt to nuclear coordinates. The derivative is index by `beta`, the
223!> electric dipole operator by `alpha`.
224!> Also calculates the APT
225!> P^lambda_alpha,beta = d< mu_alpha >/dR^lambda_beta
226!> and calculates the sum rules for the APT elements.
227!> \param qs_env ...
228!> \param p_env ...
229! **************************************************************************************************
230 SUBROUTINE dcdr_linres(qs_env, p_env)
231 TYPE(qs_environment_type), POINTER :: qs_env
232 TYPE(qs_p_env_type) :: p_env
233
234 INTEGER :: beta, latom
235 TYPE(dcdr_env_type) :: dcdr_env
236 TYPE(polar_env_type), POINTER :: polar_env
237
238 CALL cite_reference(ditler2021)
239 CALL dcdr_env_init(dcdr_env, qs_env)
240
241 IF (.NOT. dcdr_env%z_matrix_method) THEN
242
243 DO latom = 1, SIZE(dcdr_env%list_of_atoms)
244 dcdr_env%lambda = dcdr_env%list_of_atoms(latom)
245 CALL prepare_per_atom(dcdr_env, qs_env)
246
247 DO beta = 1, 3 ! in every direction
248 dcdr_env%beta = beta
249 dcdr_env%deltaR(dcdr_env%beta, dcdr_env%lambda) = 1._dp
250
251 CALL dcdr_build_op_dr(dcdr_env, qs_env)
252 CALL dcdr_response_dr(dcdr_env, p_env, qs_env)
253
254 IF (.NOT. dcdr_env%localized_psi0) THEN
255 CALL apt_dr(qs_env, dcdr_env)
256 ELSE IF (dcdr_env%localized_psi0) THEN
257 CALL apt_dr_localization(qs_env, dcdr_env)
258 END IF
259
260 END DO !beta
261
262 dcdr_env%apt_total_dcdr(:, :, dcdr_env%lambda) = &
263 dcdr_env%apt_el_dcdr(:, :, dcdr_env%lambda) + dcdr_env%apt_nuc_dcdr(:, :, dcdr_env%lambda)
264 END DO !lambda
265
266 ELSE
267
268 CALL polar_env_init(qs_env)
269 CALL get_qs_env(qs_env=qs_env, polar_env=polar_env)
270 CALL get_polar_env(polar_env=polar_env)
271
272 IF (.NOT. dcdr_env%localized_psi0) THEN
273 CALL polar_operators_local(qs_env)
274 ELSE
275 CALL polar_operators_local_wannier(qs_env, dcdr_env)
276 END IF
277
278 polar_env%do_periodic = .false.
279 CALL polar_response(p_env, qs_env)
280
281 DO latom = 1, SIZE(dcdr_env%list_of_atoms)
282 dcdr_env%lambda = dcdr_env%list_of_atoms(latom)
283 CALL prepare_per_atom(dcdr_env, qs_env)
284
285 DO beta = 1, 3 ! in every direction
286 dcdr_env%beta = beta
287 dcdr_env%deltaR(dcdr_env%beta, dcdr_env%lambda) = 1._dp
288
289 CALL dcdr_build_op_dr(dcdr_env, qs_env)
290 IF (.NOT. dcdr_env%localized_psi0) THEN
291 CALL apt_dr(qs_env, dcdr_env)
292 ELSE
293 CALL apt_dr_localization(qs_env, dcdr_env)
294 END IF
295 END DO !beta
296
297 dcdr_env%apt_total_dcdr(:, :, dcdr_env%lambda) = &
298 dcdr_env%apt_el_dcdr(:, :, dcdr_env%lambda) + dcdr_env%apt_nuc_dcdr(:, :, dcdr_env%lambda)
299 END DO !lambda
300
301 END IF
302
303 CALL dcdr_print(dcdr_env, qs_env)
304 CALL dcdr_env_cleanup(qs_env, dcdr_env)
305 END SUBROUTINE dcdr_linres
306
307! **************************************************************************************************
308!> \brief Driver for the linear response calculatios
309!> \param force_env ...
310!> \par History
311!> 06.2005 created [MI]
312!> \author MI
313! **************************************************************************************************
314 SUBROUTINE linres_calculation(force_env)
315
316 TYPE(force_env_type), POINTER :: force_env
317
318 CHARACTER(LEN=*), PARAMETER :: routinen = 'linres_calculation'
319
320 INTEGER :: handle
321 TYPE(qs_environment_type), POINTER :: qs_env
322
323 CALL timeset(routinen, handle)
324
325 NULLIFY (qs_env)
326
327 cpassert(ASSOCIATED(force_env))
328 cpassert(force_env%ref_count > 0)
329
330 SELECT CASE (force_env%in_use)
331 CASE (use_qs_force)
332 CALL force_env_get(force_env, qs_env=qs_env)
333 CASE (use_qmmm)
334 qs_env => force_env%qmmm_env%qs_env
335 CASE DEFAULT
336 cpabort("Does not recognize this force_env")
337 END SELECT
338
339 qs_env%linres_run = .true.
340
341 CALL linres_calculation_low(qs_env)
342
343 CALL timestop(handle)
344
345 END SUBROUTINE linres_calculation
346
347! **************************************************************************************************
348!> \brief Linear response can be called as run type or as post scf calculation
349!> Initialize the perturbation environment
350!> Define which properties is to be calculated
351!> Start up the optimization of the response density and wfn
352!> \param qs_env ...
353!> \par History
354!> 06.2005 created [MI]
355!> 02.2013 added polarizability section [SL]
356!> \author MI
357! **************************************************************************************************
358 SUBROUTINE linres_calculation_low(qs_env)
359
360 TYPE(qs_environment_type), POINTER :: qs_env
361
362 CHARACTER(LEN=*), PARAMETER :: routinen = 'linres_calculation_low'
363
364 INTEGER :: every_n_step, handle, iounit
365 LOGICAL :: dcdr_present, do_apt_fd, epr_present, &
366 issc_present, lr_calculation, &
367 nmr_present, polar_present, vcd_present
368 TYPE(cp_logger_type), POINTER :: logger
369 TYPE(dft_control_type), POINTER :: dft_control
370 TYPE(linres_control_type), POINTER :: linres_control
371 TYPE(qs_p_env_type) :: p_env
372 TYPE(section_vals_type), POINTER :: lr_section, prop_section, xc_fun_section
373
374 CALL timeset(routinen, handle)
375
376 lr_calculation = .false.
377 nmr_present = .false.
378 epr_present = .false.
379 issc_present = .false.
380 polar_present = .false.
381 dcdr_present = .false.
382 do_apt_fd = .false.
383
384 NULLIFY (dft_control, linres_control, logger, prop_section, lr_section, xc_fun_section)
385
386 lr_section => section_vals_get_subs_vals(qs_env%input, "PROPERTIES%LINRES")
387 CALL section_vals_get(lr_section, explicit=lr_calculation)
388
389 CALL section_vals_val_get(lr_section, "DCDR%APT_FD", l_val=do_apt_fd)
390 IF (do_apt_fd) THEN
391 CALL timestop(handle)
392 RETURN
393 END IF
394
395 logger => cp_get_default_logger()
396
397 CALL section_vals_val_get(lr_section, "EVERY_N_STEP", i_val=every_n_step)
398
399 IF (lr_calculation .AND. modulo(qs_env%sim_step, every_n_step) == 0) THEN
400 prop_section => section_vals_get_subs_vals(lr_section, "DCDR")
401 CALL section_vals_get(prop_section, explicit=dcdr_present)
402 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
403 xc_fun_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC%XC_FUNCTIONAL")
404 IF (dcdr_present .AND. xc_uses_kinetic_energy_density(xc_fun_section, dft_control%lsd)) THEN
405 cpabort(dcdr_meta_gga_error)
406 END IF
407
408 CALL linres_init(lr_section, p_env, qs_env)
409 iounit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
410 extension=".linresLog")
411 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, &
412 linres_control=linres_control)
413
414 ! The type of perturbation has not been defined yet
415 linres_control%property = lr_none
416
417 ! We do NMR or EPR, then compute the current response
418 prop_section => section_vals_get_subs_vals(lr_section, "NMR")
419 CALL section_vals_get(prop_section, explicit=nmr_present)
420 prop_section => section_vals_get_subs_vals(lr_section, "EPR")
421 CALL section_vals_get(prop_section, explicit=epr_present)
422
423 IF (nmr_present .OR. epr_present) THEN
424 CALL nmr_epr_linres(linres_control, qs_env, p_env, dft_control, &
425 nmr_present, epr_present, iounit)
426 END IF
427
428 ! We do the indirect spin-spin coupling calculation
429 prop_section => section_vals_get_subs_vals(lr_section, "SPINSPIN")
430 CALL section_vals_get(prop_section, explicit=issc_present)
431
432 IF (issc_present) THEN
433 CALL issc_linres(linres_control, qs_env, p_env, dft_control)
434 END IF
435
436 ! We do the polarizability calculation
437 prop_section => section_vals_get_subs_vals(lr_section, "POLAR")
438 CALL section_vals_get(prop_section, explicit=polar_present)
439 IF (polar_present) THEN
440 CALL polar_linres(qs_env, p_env)
441 END IF
442
443 ! Nuclear Position Perturbation
444 IF (dcdr_present) THEN
445 CALL dcdr_linres(qs_env, p_env)
446 END IF
447
448 ! VCD
449 prop_section => section_vals_get_subs_vals(lr_section, "VCD")
450 CALL section_vals_get(prop_section, explicit=vcd_present)
451
452 IF (vcd_present) THEN
453 CALL vcd_linres(qs_env, p_env)
454 END IF
455
456 ! Other possible LR calculations can be introduced here
457
458 CALL p_env_release(p_env)
459
460 IF (iounit > 0) THEN
461 WRITE (unit=iounit, fmt="(/,T2,A,/,T25,A,/,T2,A,/)") &
462 repeat("=", 79), &
463 "ENDED LINRES CALCULATION", &
464 repeat("=", 79)
465 END IF
466 CALL cp_print_key_finished_output(iounit, logger, lr_section, &
467 "PRINT%PROGRAM_RUN_INFO")
468 END IF
469
470 CALL timestop(handle)
471
472 END SUBROUTINE linres_calculation_low
473
474! **************************************************************************************************
475!> \brief Initialize some general settings like the p_env
476!> Localize the psi0 if required
477!> \param lr_section ...
478!> \param p_env ...
479!> \param qs_env ...
480!> \par History
481!> 06.2005 created [MI]
482!> \author MI
483!> \note
484!> - The localization should probably be always for all the occupied states
485! **************************************************************************************************
486 SUBROUTINE linres_init(lr_section, p_env, qs_env)
487
488 TYPE(section_vals_type), POINTER :: lr_section
489 TYPE(qs_p_env_type), INTENT(OUT) :: p_env
490 TYPE(qs_environment_type), POINTER :: qs_env
491
492 INTEGER :: iounit, ispin
493 LOGICAL :: do_it
494 TYPE(cp_logger_type), POINTER :: logger
495 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, rho_ao
496 TYPE(dft_control_type), POINTER :: dft_control
497 TYPE(linres_control_type), POINTER :: linres_control
498 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
499 TYPE(qs_rho_type), POINTER :: rho
500 TYPE(section_vals_type), POINTER :: loc_section
501
502 NULLIFY (logger)
503 logger => cp_get_default_logger()
504 iounit = cp_print_key_unit_nr(logger, lr_section, "PRINT%PROGRAM_RUN_INFO", &
505 extension=".linresLog")
506 NULLIFY (dft_control, linres_control, loc_section, rho, mos, matrix_ks, rho_ao)
507
508 ALLOCATE (linres_control)
509 CALL set_qs_env(qs_env=qs_env, linres_control=linres_control)
510 CALL get_qs_env(qs_env=qs_env, &
511 dft_control=dft_control, matrix_ks=matrix_ks, mos=mos, rho=rho)
512 CALL qs_rho_get(rho, rho_ao=rho_ao)
513
514 ! Localized Psi0 are required when the position operator has to be defined (nmr)
515 loc_section => section_vals_get_subs_vals(lr_section, "LOCALIZE")
516 CALL section_vals_val_get(loc_section, "_SECTION_PARAMETERS_", &
517 l_val=linres_control%localized_psi0)
518 IF (linres_control%localized_psi0) THEN
519 IF (iounit > 0) THEN
520 WRITE (unit=iounit, fmt="(/,T3,A,A)") &
521 "Localization of ground state orbitals", &
522 " before starting linear response calculation"
523 END IF
524
525 CALL linres_localize(qs_env, linres_control, dft_control%nspins)
526
527 DO ispin = 1, dft_control%nspins
528 CALL calculate_density_matrix(mos(ispin), rho_ao(ispin)%matrix)
529 END DO
530 ! ** update qs_env%rho
531 CALL qs_rho_update_rho(rho, qs_env=qs_env)
532 END IF
533
534 CALL section_vals_val_get(lr_section, "RESTART", l_val=linres_control%linres_restart)
535 CALL section_vals_val_get(lr_section, "MAX_ITER", i_val=linres_control%max_iter)
536 CALL section_vals_val_get(lr_section, "EPS", r_val=linres_control%eps)
537 CALL section_vals_val_get(lr_section, "EPS_FILTER", r_val=linres_control%eps_filter)
538 CALL section_vals_val_get(lr_section, "RESTART_EVERY", i_val=linres_control%restart_every)
539 CALL section_vals_val_get(lr_section, "PRECONDITIONER", i_val=linres_control%preconditioner_type)
540 CALL section_vals_val_get(lr_section, "ENERGY_GAP", r_val=linres_control%energy_gap)
541
542 IF (iounit > 0) THEN
543 WRITE (unit=iounit, fmt="(/,T2,A,/,T25,A,/,T2,A,/)") &
544 repeat("=", 79), &
545 "START LINRES CALCULATION", &
546 repeat("=", 79)
547
548 WRITE (unit=iounit, fmt="(T2,A)") &
549 "LINRES| Properties to be calculated:"
550 CALL section_vals_val_get(lr_section, "NMR%_SECTION_PARAMETERS_", l_val=do_it)
551 IF (do_it) WRITE (unit=iounit, fmt="(T62,A)") "NMR Chemical Shift"
552 CALL section_vals_val_get(lr_section, "EPR%_SECTION_PARAMETERS_", l_val=do_it)
553 IF (do_it) WRITE (unit=iounit, fmt="(T68,A)") "EPR g Tensor"
554 CALL section_vals_val_get(lr_section, "SPINSPIN%_SECTION_PARAMETERS_", l_val=do_it)
555 IF (do_it) WRITE (unit=iounit, fmt="(T43,A)") "Indirect spin-spin coupling constants"
556 CALL section_vals_val_get(lr_section, "POLAR%_SECTION_PARAMETERS_", l_val=do_it)
557 IF (do_it) WRITE (unit=iounit, fmt="(T57,A)") "Electric Polarizability"
558
559 IF (linres_control%localized_psi0) WRITE (unit=iounit, fmt="(T2,A,T65,A)") &
560 "LINRES|", " LOCALIZED PSI0"
561
562 WRITE (unit=iounit, fmt="(T2,A,T60,A)") &
563 "LINRES| Optimization algorithm", " Conjugate Gradients"
564
565 SELECT CASE (linres_control%preconditioner_type)
566 CASE (ot_precond_none)
567 WRITE (unit=iounit, fmt="(T2,A,T60,A)") &
568 "LINRES| Preconditioner", " NONE"
570 WRITE (unit=iounit, fmt="(T2,A,T60,A)") &
571 "LINRES| Preconditioner", " FULL_SINGLE"
573 WRITE (unit=iounit, fmt="(T2,A,T60,A)") &
574 "LINRES| Preconditioner", " FULL_KINETIC"
576 WRITE (unit=iounit, fmt="(T2,A,T60,A)") &
577 "LINRES| Preconditioner", " FULL_S_INVERSE"
579 WRITE (unit=iounit, fmt="(T2,A,T60,A)") &
580 "LINRES| Preconditioner", " FULL_SINGLE_INVERSE"
582 WRITE (unit=iounit, fmt="(T2,A,T60,A)") &
583 "LINRES| Preconditioner", " FULL_ALL"
584 CASE DEFAULT
585 cpabort("Preconditioner NYI")
586 END SELECT
587
588 WRITE (unit=iounit, fmt="(T2,A,T72,ES8.1)") &
589 "LINRES| EPS", linres_control%eps
590 WRITE (unit=iounit, fmt="(T2,A,T72,I8)") &
591 "LINRES| MAX_ITER", linres_control%max_iter
592 END IF
593
594 !------------------!
595 ! create the p_env !
596 !------------------!
597 CALL p_env_create(p_env, qs_env, orthogonal_orbitals=.true., linres_control=linres_control)
598
599 ! update the m_epsilon matrix
600 CALL p_env_psi0_changed(p_env, qs_env)
601
602 p_env%new_preconditioner = .true.
603 CALL cp_print_key_finished_output(iounit, logger, lr_section, &
604 "PRINT%PROGRAM_RUN_INFO")
605
606 END SUBROUTINE linres_init
607
608! **************************************************************************************************
609!> \brief ...
610!> \param linres_control ...
611!> \param qs_env ...
612!> \param p_env ...
613!> \param dft_control ...
614!> \param nmr_present ...
615!> \param epr_present ...
616!> \param iounit ...
617! **************************************************************************************************
618 SUBROUTINE nmr_epr_linres(linres_control, qs_env, p_env, dft_control, nmr_present, epr_present, iounit)
619
620 TYPE(linres_control_type), POINTER :: linres_control
621 TYPE(qs_environment_type), POINTER :: qs_env
622 TYPE(qs_p_env_type) :: p_env
623 TYPE(dft_control_type), POINTER :: dft_control
624 LOGICAL :: nmr_present, epr_present
625 INTEGER :: iounit
626
627 INTEGER :: ib
628 LOGICAL :: do_qmmm
629 TYPE(current_env_type) :: current_env
630 TYPE(epr_env_type) :: epr_env
631 TYPE(nmr_env_type) :: nmr_env
632
633 linres_control%property = lr_current
634
635 CALL cite_reference(weber2009)
636
637 IF (.NOT. linres_control%localized_psi0) THEN
638 CALL cp_abort(__location__, &
639 "Are you sure that you want to calculate the chemical "// &
640 "shift without localized psi0?")
641 CALL linres_localize(qs_env, linres_control, &
642 dft_control%nspins, centers_only=.true.)
643 END IF
644 IF (dft_control%nspins /= 2 .AND. epr_present) THEN
645 cpabort("LSD is needed to perform a g tensor calculation!")
646 END IF
647 !
648 !Initialize the current environment
649 do_qmmm = .false.
650 IF (qs_env%qmmm) do_qmmm = .true.
651 current_env%do_qmmm = do_qmmm
652 !current_env%prop='nmr'
653 CALL current_env_init(current_env, qs_env)
654 CALL current_operators(current_env, qs_env)
655 CALL current_response(current_env, p_env, qs_env)
656 !
657 IF (current_env%all_pert_op_done) THEN
658 !Initialize the nmr environment
659 IF (nmr_present) THEN
660 CALL nmr_env_init(nmr_env, qs_env)
661 END IF
662 !
663 !Initialize the epr environment
664 IF (epr_present) THEN
665 CALL epr_env_init(epr_env, qs_env)
666 CALL epr_g_zke(epr_env, qs_env)
667 CALL epr_nablavks(epr_env, qs_env)
668 END IF
669 !
670 ! Build the rs_gauge if needed
671 !CALL current_set_gauge(current_env,qs_env)
672 !
673 ! Loop over field direction
674 DO ib = 1, 3
675 !
676 ! Build current response and succeptibility
677 CALL current_build_current(current_env, qs_env, ib)
678 CALL current_build_chi(current_env, qs_env, ib)
679 !
680 ! Compute NMR shift
681 IF (nmr_present) THEN
682 CALL nmr_shift(nmr_env, current_env, qs_env, ib)
683 END IF
684 !
685 ! Compute EPR
686 IF (epr_present) THEN
687 CALL epr_ind_magnetic_field(epr_env, current_env, qs_env, ib)
688 CALL epr_g_so(epr_env, current_env, qs_env, ib)
689 CALL epr_g_soo(epr_env, current_env, qs_env, ib)
690 END IF
691 END DO
692 !
693 ! Finalized the nmr environment
694 IF (nmr_present) THEN
695 CALL nmr_shift_print(nmr_env, current_env, qs_env)
696 CALL nmr_env_cleanup(nmr_env)
697 END IF
698 !
699 ! Finalized the epr environment
700 IF (epr_present) THEN
701 CALL epr_g_print(epr_env, qs_env)
702 CALL epr_env_cleanup(epr_env)
703 END IF
704 !
705 ELSE
706 IF (iounit > 0) THEN
707 WRITE (iounit, "(T10,A,/T20,A,/)") &
708 "CURRENT: Not all responses to perturbation operators could be calculated.", &
709 " Hence: NO nmr and NO epr possible."
710 END IF
711 END IF
712 ! Finalized the current environment
713 CALL current_env_cleanup(current_env)
714
715 END SUBROUTINE nmr_epr_linres
716
717! **************************************************************************************************
718!> \brief ...
719!> \param linres_control ...
720!> \param qs_env ...
721!> \param p_env ...
722!> \param dft_control ...
723! **************************************************************************************************
724 SUBROUTINE issc_linres(linres_control, qs_env, p_env, dft_control)
725
726 TYPE(linres_control_type), POINTER :: linres_control
727 TYPE(qs_environment_type), POINTER :: qs_env
728 TYPE(qs_p_env_type) :: p_env
729 TYPE(dft_control_type), POINTER :: dft_control
730
731 INTEGER :: iatom
732 LOGICAL :: do_qmmm
733 TYPE(current_env_type) :: current_env
734 TYPE(issc_env_type) :: issc_env
735
736 linres_control%property = lr_current
737 IF (.NOT. linres_control%localized_psi0) THEN
738 CALL cp_abort(__location__, &
739 "Are you sure that you want to calculate the chemical "// &
740 "shift without localized psi0?")
741 CALL linres_localize(qs_env, linres_control, &
742 dft_control%nspins, centers_only=.true.)
743 END IF
744 !
745 !Initialize the current environment
746 do_qmmm = .false.
747 IF (qs_env%qmmm) do_qmmm = .true.
748 current_env%do_qmmm = do_qmmm
749 !current_env%prop='issc'
750 !CALL current_env_init(current_env,qs_env)
751 !CALL current_response(current_env,p_env,qs_env)
752 !
753 !Initialize the issc environment
754 CALL issc_env_init(issc_env, qs_env)
755 !
756 ! Loop over atoms
757 DO iatom = 1, issc_env%issc_natms
758 CALL issc_operators(issc_env, qs_env, iatom)
759 CALL issc_response(issc_env, p_env, qs_env)
760 CALL issc_issc(issc_env, qs_env, iatom)
761 END DO
762 !
763 ! Finalized the issc environment
764 CALL issc_print(issc_env, qs_env)
765 CALL issc_env_cleanup(issc_env)
766
767 END SUBROUTINE issc_linres
768
769! **************************************************************************************************
770!> \brief ...
771!> \param qs_env ...
772!> \param p_env ...
773!> \par History
774!> 06.2018 polar_env integrated into qs_env (MK)
775! **************************************************************************************************
776 SUBROUTINE polar_linres(qs_env, p_env)
777
778 TYPE(qs_environment_type), POINTER :: qs_env
779 TYPE(qs_p_env_type) :: p_env
780
781 CALL polar_env_init(qs_env)
782 CALL polar_operators(qs_env)
783 CALL polar_response(p_env, qs_env)
784 CALL polar_polar(qs_env)
785 CALL polar_print(qs_env)
786
787 END SUBROUTINE polar_linres
788
789END MODULE qs_linres_module
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public weber2009
integer, save, public ditler2021
integer, save, public ditler2022
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,...
Interface for the force calculations.
integer, parameter, public use_qmmm
recursive subroutine, public force_env_get(force_env, in_use, fist_env, qs_env, meta_env, fp_env, subsys, para_env, potential_energy, additional_potential, kinetic_energy, harmonic_shell, kinetic_shell, cell, sub_force_env, qmmm_env, qmmmx_env, eip_env, pwdft_env, globenv, input, force_env_section, method_name_id, root_section, mixed_env, nnp_env, embed_env, ipi_env)
returns various attributes about the force environment
integer, parameter, public use_qs_force
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public lr_none
integer, parameter, public ot_precond_full_kinetic
integer, parameter, public do_qmmm
integer, parameter, public ot_precond_full_single
integer, parameter, public ot_precond_none
integer, parameter, public ot_precond_full_single_inverse
integer, parameter, public lr_current
integer, parameter, public ot_precond_s_inverse
integer, parameter, public ot_precond_full_all
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_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
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
Calculate the derivatives of the MO coefficients wrt nuclear coordinates.
subroutine, public dcdr_env_cleanup(qs_env, dcdr_env)
Deallocate the dcdr environment.
subroutine, public dcdr_print(dcdr_env, qs_env)
Print the APT and sum rules.
subroutine, public dcdr_env_init(dcdr_env, qs_env)
Initialize the dcdr environment.
Calculate the derivatives of the MO coefficients wrt nuclear coordinates.
Definition qs_dcdr.F:13
subroutine, public prepare_per_atom(dcdr_env, qs_env)
Prepare the environment for a choice of lambda.
Definition qs_dcdr.F:90
subroutine, public apt_dr_localization(qs_env, dcdr_env)
Calculate atomic polar tensor using the localized dipole operator.
Definition qs_dcdr.F:519
subroutine, public apt_dr(qs_env, dcdr_env)
Calculate atomic polar tensor.
Definition qs_dcdr.F:376
subroutine, public dcdr_response_dr(dcdr_env, p_env, qs_env)
Get the dC/dR by solving the Sternheimer equation, using the op_dR matrix.
Definition qs_dcdr.F:269
subroutine, public dcdr_build_op_dr(dcdr_env, qs_env)
Build the operator for the position perturbation.
Definition qs_dcdr.F:194
collects routines that calculate density matrices
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, mimic, 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, matrix_vhxc, 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, xcint_weights, 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.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, mimic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, rhoz_cneo_set, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Set the QUICKSTEP environment.
Chemical shift calculation by dfpt Initialization of the nmr_env, creation of the special neighbor li...
subroutine, public current_response(current_env, p_env, qs_env)
...
subroutine, public current_env_init(current_env, qs_env)
...
subroutine, public current_env_cleanup(current_env)
...
given the response wavefunctions obtained by the application of the (rxp), p, and ((dk-dl)xp) operato...
subroutine, public current_build_current(current_env, qs_env, ib)
First calculate the density matrixes, for each component of the current they are 3 because of the r d...
subroutine, public current_build_chi(current_env, qs_env, ib)
...
Calculates Nabla V_KS (local part if PSP) on the different grids.
subroutine, public epr_nablavks(epr_env, qs_env)
Evaluates Nabla V_KS on the grids.
subroutine, public epr_g_soo(epr_env, current_env, qs_env, ib)
Calculates g_soo (soft part only for now)
subroutine, public epr_g_so(epr_env, current_env, qs_env, ib)
Calculates g_so.
subroutine, public epr_g_zke(epr_env, qs_env)
Calculate zke part of the g tensor.
subroutine, public epr_ind_magnetic_field(epr_env, current_env, qs_env, ib)
...
subroutine, public epr_g_print(epr_env, qs_env)
Prints the g tensor.
g tensor calculation by dfpt Initialization of the epr_env, creation of the special neighbor lists Pe...
subroutine, public epr_env_cleanup(epr_env)
Deallocate the epr environment.
subroutine, public epr_env_init(epr_env, qs_env)
Initialize the epr environment.
Chemical shift calculation by dfpt Initialization of the issc_env, creation of the special neighbor l...
subroutine, public issc_issc(issc_env, qs_env, iatom)
...
subroutine, public issc_response(issc_env, p_env, qs_env)
Initialize the issc environment.
subroutine, public issc_env_cleanup(issc_env)
Deallocate the issc environment.
subroutine, public issc_env_init(issc_env, qs_env)
Initialize the issc environment.
subroutine, public issc_print(issc_env, qs_env)
...
localize wavefunctions linear response scf
subroutine, public linres_localize(qs_env, linres_control, nspins, centers_only)
Find the centers and spreads of the wfn, if required apply a localization algorithm.
Contains the setup for the calculation of properties by linear response by the application of second ...
subroutine, public linres_calculation(force_env)
Driver for the linear response calculatios.
subroutine, public linres_calculation_low(qs_env)
Linear response can be called as run type or as post scf calculation Initialize the perturbation envi...
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)
...
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.
Calculate the operators p rxp and D needed in the optimization of the different contribution of the f...
subroutine, public polar_operators_local_wannier(qs_env, dcdr_env)
Calculate the dipole operator referenced at the Wannier centers in the MO basis.
subroutine, public current_operators(current_env, qs_env)
Calculate the first order hamiltonian applied to the ao and then apply them to the ground state orbit...
subroutine, public polar_operators(qs_env)
Calculate the dipole operator in the AO basis and its derivative wrt to MOs.
subroutine, public polar_operators_local(qs_env)
Calculate the Berry phase operator in the AO basis and then the derivative of the Berry phase operato...
subroutine, public issc_operators(issc_env, qs_env, iatom)
...
Polarizability calculation by dfpt Initialization of the polar_env, Perturbation Hamiltonian by appli...
subroutine, public polar_polar(qs_env)
...
subroutine, public polar_print(qs_env)
Print information related to the polarisability tensor.
subroutine, public polar_env_init(qs_env)
Initialize the polar environment.
subroutine, public polar_response(p_env, qs_env)
Calculate the polarisability tensor using response theory.
Type definitiona for linear response calculations.
subroutine, public get_polar_env(polar_env, do_raman, do_periodic, dberry_psi0, polar, psi1_dberry, run_stopped)
...
Definition qs_mfp.F:7
subroutine, public mfp_build_operator_gauge_independent(vcd_env, qs_env, alpha)
...
Definition qs_mfp.F:848
subroutine, public mfp_response(vcd_env, p_env, qs_env, alpha)
Get the dC/dB using the vcd_envop_dB.
Definition qs_mfp.F:1150
subroutine, public mfp_build_operator_gauge_dependent(vcd_env, qs_env, alpha)
...
Definition qs_mfp.F:522
subroutine, public mfp_aat(vcd_env, qs_env)
...
Definition qs_mfp.F:90
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
Utility functions for the perturbation calculations.
subroutine, public p_env_psi0_changed(p_env, qs_env)
To be called after the value of psi0 has changed. Recalculates the quantities S_psi0 and m_epsilon.
subroutine, public p_env_create(p_env, qs_env, p1_option, p1_admm_option, orthogonal_orbitals, linres_control)
allocates and initializes the perturbation environment (no setup)
basis types for the calculation of the perturbation of density theory.
subroutine, public p_env_release(p_env)
relases the given p_env (see doc/ReferenceCounting.html)
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
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...
subroutine, public vcd_print(vcd_env, qs_env)
Print the APTs, AATs, and sum rules.
subroutine, public vcd_env_cleanup(qs_env, vcd_env)
Deallocate the vcd environment.
subroutine, public vcd_env_init(vcd_env, qs_env)
Initialize the vcd environment.
Definition qs_vcd.F:7
subroutine, public vcd_build_op_dv(vcd_env, qs_env)
What we are building here is the operator for the NVPT response: H0 * C1 - S0 * E0 * C1 = - op_dV lin...
Definition qs_vcd.F:960
subroutine, public vcd_response_dv(vcd_env, p_env, qs_env)
Get the dC/dV using the vcd_envop_dV.
Definition qs_vcd.F:1043
subroutine, public aat_dv(vcd_env, qs_env)
Compute I_{alpha beta}^lambda = d/dV^lambda_beta <m_alpha> = d/dV^lambda_beta < r x.
Definition qs_vcd.F:82
subroutine, public apt_dv(vcd_env, qs_env)
Compute E_{alpha beta}^lambda = d/dV^lambda_beta <\mu_alpha> = d/dV^lambda_beta <.
Definition qs_vcd.F:593
subroutine, public prepare_per_atom_vcd(vcd_env, qs_env)
Initialize the matrices for the NVPT calculation.
Definition qs_vcd.F:830
Exchange and Correlation functional calculations.
Definition xc.F:17
logical function, public xc_uses_kinetic_energy_density(xc_fun_section, lsd)
...
Definition xc.F:95
type of a logger, at the moment it contains just a print level starting at which level it should be l...
wrapper to abstract the force evaluation of the various methods
General settings for linear response calculations.
Represent a qs system that is perturbed. Can calculate the linear operator and the rhs of the system ...
keeps the density in various representations, keeping track of which ones are valid.