(git:7f1b8e3)
Loading...
Searching...
No Matches
qs_scf_post_gpw.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 Does all kind of post scf calculations for GPW/GAPW
10!> \par History
11!> Started as a copy from the relevant part of qs_scf
12!> Start to adapt for k-points [07.2015, JGH]
13!> \author Joost VandeVondele (10.2003)
14! **************************************************************************************************
16 USE admm_types, ONLY: admm_type
19 USE ai_onecenter, ONLY: sg_overlap
25 USE cell_types, ONLY: cell_type
29 USE cp_dbcsr_api, ONLY: dbcsr_add,&
35 USE cp_ddapc_util, ONLY: get_ddapc
40 USE cp_fm_types, ONLY: cp_fm_create,&
50 USE cp_output_handling, ONLY: cp_p_file,&
55 USE dct, ONLY: pw_shrink
56 USE ed_analysis, ONLY: edmf_analysis
57 USE eeq_method, ONLY: eeq_print
59 USE hfx_ri, ONLY: print_ri_hfx
70 USE iao_types, ONLY: iao_env_type,&
72 USE input_constants, ONLY: &
83 USE kinds, ONLY: default_path_length,&
85 dp
86 USE kpoint_types, ONLY: kpoint_type
88 USE mathconstants, ONLY: pi
94 USE mulliken, ONLY: mulliken_charges
95 USE orbital_pointers, ONLY: indso
98 USE physcon, ONLY: angstrom,&
99 evolt
103 USE ps_implicit_types, ONLY: mixed_bc,&
105 neumann_bc,&
107 USE pw_env_types, ONLY: pw_env_get,&
109 USE pw_grids, ONLY: get_pw_grid_info
110 USE pw_methods, ONLY: pw_axpy,&
111 pw_copy,&
112 pw_derive,&
114 pw_scale,&
116 pw_zero
120 USE pw_pool_types, ONLY: pw_pool_p_type,&
122 USE pw_types, ONLY: pw_c1d_gs_type,&
124 USE qs_chargemol, ONLY: write_wfx
129 USE qs_dos, ONLY: calculate_dos,&
132 USE qs_elf_methods, ONLY: qs_elf_calc
138 USE qs_epr_hyp, ONLY: qs_epr_hyp_calc
141 USE qs_kind_types, ONLY: get_qs_kind,&
146 USE qs_loc_dipole, ONLY: loc_dipole
162 USE qs_mo_types, ONLY: get_mo_set,&
176 USE qs_resp, ONLY: resp_fit
177 USE qs_rho0_types, ONLY: get_rho0_mpole,&
182 USE qs_rho_types, ONLY: qs_rho_get,&
189 USE qs_scf_types, ONLY: ot_method_nr,&
191 USE qs_scf_wfn_mix, ONLY: wfn_mix
192 USE qs_subsys_types, ONLY: qs_subsys_get,&
197 USE stm_images, ONLY: th_stm_image
199 USE trexio_utils, ONLY: write_trexio
200 USE virial_types, ONLY: virial_type
204#include "./base/base_uses.f90"
205
206 IMPLICIT NONE
207 PRIVATE
208
209 ! Global parameters
210 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_post_gpw'
211 PUBLIC :: scf_post_calculation_gpw, &
215
216 PUBLIC :: make_lumo_gpw
217
218CONTAINS
219
220! **************************************************************************************************
221!> \brief collects possible post - scf calculations and prints info / computes properties.
222!> \param qs_env the qs_env in which the qs_env lives
223!> \param wf_type ...
224!> \param do_mp2 ...
225!> \par History
226!> 02.2003 created [fawzi]
227!> 10.2004 moved here from qs_scf [Joost VandeVondele]
228!> started splitting out different subroutines
229!> 10.2015 added header for wave-function correlated methods [Vladimir Rybkin]
230!> \author fawzi
231!> \note
232!> this function changes mo_eigenvectors and mo_eigenvalues, depending on the print keys.
233!> In particular, MO_CUBES causes the MOs to be rotated to make them eigenstates of the KS
234!> matrix, and mo_eigenvalues is updated accordingly. This can, for unconverged wavefunctions,
235!> change afterwards slightly the forces (hence small numerical differences between MD
236!> with and without the debug print level). Ideally this should not happen...
237! **************************************************************************************************
238 SUBROUTINE scf_post_calculation_gpw(qs_env, wf_type, do_mp2)
239
240 TYPE(qs_environment_type), POINTER :: qs_env
241 CHARACTER(6), OPTIONAL :: wf_type
242 LOGICAL, OPTIONAL :: do_mp2
243
244 CHARACTER(len=*), PARAMETER :: routinen = 'scf_post_calculation_gpw'
245
246 INTEGER :: handle, homo, ispin, min_lumos, n_rep, &
247 nchk_nmoloc, nhomo, nlumo, nlumo_stm, &
248 nlumos, nmo, nspins, output_unit, &
249 unit_nr
250 INTEGER, DIMENSION(:, :, :), POINTER :: marked_states
251 LOGICAL :: check_write, compute_lumos, do_homo, do_kpoints, do_mixed, do_mo_cubes, do_stm, &
252 do_wannier_cubes, has_homo, has_lumo, loc_explicit, loc_print_explicit, my_do_mp2, &
253 my_localized_wfn, p_loc, p_loc_homo, p_loc_lumo, p_loc_mixed
254 REAL(dp) :: e_kin
255 REAL(kind=dp) :: gap, homo_lumo(2, 2), total_zeff_corr
256 REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues
257 TYPE(admm_type), POINTER :: admm_env
258 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
259 TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: mixed_evals, occupied_evals, &
260 unoccupied_evals, unoccupied_evals_stm
261 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: mixed_orbs, occupied_orbs
262 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
263 TARGET :: homo_localized, lumo_localized, &
264 mixed_localized
265 TYPE(cp_fm_type), DIMENSION(:), POINTER :: lumo_ptr, mo_loc_history, &
266 unoccupied_orbs, unoccupied_orbs_stm
267 TYPE(cp_fm_type), POINTER :: mo_coeff
268 TYPE(cp_logger_type), POINTER :: logger
269 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_p_mp2, matrix_s, &
270 mo_derivs
271 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: kinetic_m, rho_ao
272 TYPE(dft_control_type), POINTER :: dft_control
273 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
274 TYPE(molecule_type), POINTER :: molecule_set(:)
275 TYPE(mp_para_env_type), POINTER :: para_env
276 TYPE(particle_list_type), POINTER :: particles
277 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
278 TYPE(pw_c1d_gs_type) :: wf_g
279 TYPE(pw_env_type), POINTER :: pw_env
280 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
281 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
282 TYPE(pw_r3d_rs_type) :: wf_r
283 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
284 TYPE(qs_loc_env_type), POINTER :: qs_loc_env_homo, qs_loc_env_lumo, &
285 qs_loc_env_mixed
286 TYPE(qs_rho_type), POINTER :: rho
287 TYPE(qs_scf_env_type), POINTER :: scf_env
288 TYPE(qs_subsys_type), POINTER :: subsys
289 TYPE(scf_control_type), POINTER :: scf_control
290 TYPE(section_vals_type), POINTER :: dft_section, input, loc_print_section, &
291 localize_section, print_key, &
292 stm_section
293
294 CALL timeset(routinen, handle)
295
296 logger => cp_get_default_logger()
297 output_unit = cp_logger_get_default_io_unit(logger)
298
299 ! Print out the type of wavefunction to distinguish between SCF and post-SCF
300 my_do_mp2 = .false.
301 IF (PRESENT(do_mp2)) my_do_mp2 = do_mp2
302 IF (PRESENT(wf_type)) THEN
303 IF (output_unit > 0) THEN
304 WRITE (unit=output_unit, fmt='(/,(T1,A))') repeat("-", 40)
305 WRITE (unit=output_unit, fmt='(/,(T3,A,T19,A,T25,A))') "Properties from ", wf_type, " density"
306 WRITE (unit=output_unit, fmt='(/,(T1,A))') repeat("-", 40)
307 END IF
308 END IF
309
310 ! Writes the data that is already available in qs_env
311 CALL get_qs_env(qs_env, scf_env=scf_env)
312
313 my_localized_wfn = .false.
314 NULLIFY (admm_env, dft_control, pw_env, auxbas_pw_pool, pw_pools, mos, rho, &
315 mo_coeff, ks_rmpv, matrix_s, qs_loc_env_homo, qs_loc_env_lumo, scf_control, &
316 unoccupied_orbs, mo_eigenvalues, unoccupied_evals, &
317 unoccupied_evals_stm, molecule_set, mo_derivs, &
318 subsys, particles, input, print_key, kinetic_m, marked_states, &
319 mixed_evals, qs_loc_env_mixed)
320 NULLIFY (lumo_ptr, rho_ao)
321
322 has_homo = .false.
323 has_lumo = .false.
324 p_loc = .false.
325 p_loc_homo = .false.
326 p_loc_lumo = .false.
327 p_loc_mixed = .false.
328
329 cpassert(ASSOCIATED(scf_env))
330 cpassert(ASSOCIATED(qs_env))
331 ! Here we start with data that needs a postprocessing...
332 CALL get_qs_env(qs_env, &
333 dft_control=dft_control, &
334 molecule_set=molecule_set, &
335 scf_control=scf_control, &
336 do_kpoints=do_kpoints, &
337 input=input, &
338 subsys=subsys, &
339 rho=rho, &
340 pw_env=pw_env, &
341 particle_set=particle_set, &
342 atomic_kind_set=atomic_kind_set, &
343 qs_kind_set=qs_kind_set)
344 CALL qs_subsys_get(subsys, particles=particles)
345
346 CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
347
348 IF (my_do_mp2) THEN
349 ! Get the HF+MP2 density
350 CALL get_qs_env(qs_env, matrix_p_mp2=matrix_p_mp2)
351 DO ispin = 1, dft_control%nspins
352 CALL dbcsr_add(rho_ao(ispin, 1)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, 1.0_dp)
353 END DO
354 CALL qs_rho_update_rho(rho, qs_env=qs_env)
355 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.)
356 ! In MP2 case update the Hartree potential
357 CALL update_hartree_with_mp2(rho, qs_env)
358 END IF
359
360 CALL write_available_results(qs_env, scf_env)
361
362 ! **** the kinetic energy
363 IF (cp_print_key_should_output(logger%iter_info, input, &
364 "DFT%PRINT%KINETIC_ENERGY") /= 0) THEN
365 CALL get_qs_env(qs_env, kinetic_kp=kinetic_m)
366 cpassert(ASSOCIATED(kinetic_m))
367 cpassert(ASSOCIATED(kinetic_m(1, 1)%matrix))
368 CALL calculate_ptrace(kinetic_m, rho_ao, e_kin, dft_control%nspins)
369 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%KINETIC_ENERGY", &
370 extension=".Log")
371 IF (unit_nr > 0) THEN
372 WRITE (unit_nr, '(T3,A,T55,F25.14)') "Electronic kinetic energy:", e_kin
373 END IF
374 CALL cp_print_key_finished_output(unit_nr, logger, input, &
375 "DFT%PRINT%KINETIC_ENERGY")
376 END IF
377
378 ! Atomic Charges that require further computation
379 CALL qs_scf_post_charges(input, logger, qs_env)
380
381 ! Moments of charge distribution
382 CALL qs_scf_post_moments(input, logger, qs_env, output_unit)
383
384 ! Determine if we need to computer properties using the localized centers
385 dft_section => section_vals_get_subs_vals(input, "DFT")
386 localize_section => section_vals_get_subs_vals(dft_section, "LOCALIZE")
387 loc_print_section => section_vals_get_subs_vals(localize_section, "PRINT")
388 CALL section_vals_get(localize_section, explicit=loc_explicit)
389 CALL section_vals_get(loc_print_section, explicit=loc_print_explicit)
390
391 ! Print_keys controlled by localization
392 IF (loc_print_explicit) THEN
393 print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_DIPOLES")
394 p_loc = btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
395 print_key => section_vals_get_subs_vals(loc_print_section, "TOTAL_DIPOLE")
396 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
397 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_CENTERS")
398 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
399 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_SPREADS")
400 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
401 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_CUBES")
402 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
403 print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_STATES")
404 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
405 print_key => section_vals_get_subs_vals(loc_print_section, "MOLECULAR_MOMENTS")
406 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
407 print_key => section_vals_get_subs_vals(loc_print_section, "WANNIER_STATES")
408 p_loc = p_loc .OR. btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)
409 ELSE
410 p_loc = .false.
411 END IF
412 IF (loc_explicit) THEN
413 p_loc_homo = (section_get_ival(localize_section, "STATES") == do_loc_homo .OR. &
414 section_get_ival(localize_section, "STATES") == do_loc_both) .AND. p_loc
415 p_loc_lumo = (section_get_ival(localize_section, "STATES") == do_loc_lumo .OR. &
416 section_get_ival(localize_section, "STATES") == do_loc_both) .AND. p_loc
417 p_loc_mixed = (section_get_ival(localize_section, "STATES") == do_loc_mixed) .AND. p_loc
418 CALL section_vals_val_get(localize_section, "LIST_UNOCCUPIED", n_rep_val=n_rep)
419 ELSE
420 p_loc_homo = .false.
421 p_loc_lumo = .false.
422 p_loc_mixed = .false.
423 n_rep = 0
424 END IF
425
426 IF (n_rep == 0 .AND. p_loc_lumo) THEN
427 CALL cp_abort(__location__, "No LIST_UNOCCUPIED was specified, "// &
428 "therefore localization of unoccupied states will be skipped!")
429 p_loc_lumo = .false.
430 END IF
431
432 ! Control for STM
433 stm_section => section_vals_get_subs_vals(input, "DFT%PRINT%STM")
434 CALL section_vals_get(stm_section, explicit=do_stm)
435 nlumo_stm = 0
436 IF (do_stm) nlumo_stm = section_get_ival(stm_section, "NLUMO")
437
438 ! check for CUBES (MOs and WANNIERS)
439 do_mo_cubes = btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%MO_CUBES") &
440 , cp_p_file)
441 IF (loc_print_explicit) THEN
442 do_wannier_cubes = btest(cp_print_key_should_output(logger%iter_info, loc_print_section, &
443 "WANNIER_CUBES"), cp_p_file)
444 ELSE
445 do_wannier_cubes = .false.
446 END IF
447 nlumo = section_get_ival(dft_section, "PRINT%MO_CUBES%NLUMO")
448 nhomo = section_get_ival(dft_section, "PRINT%MO_CUBES%NHOMO")
449
450 ! Setup the grids needed to compute a wavefunction given a vector..
451 IF (((do_mo_cubes .OR. do_wannier_cubes) .AND. (nlumo /= 0 .OR. nhomo /= 0)) .OR. p_loc) THEN
452 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
453 pw_pools=pw_pools)
454 CALL auxbas_pw_pool%create_pw(wf_r)
455 CALL auxbas_pw_pool%create_pw(wf_g)
456 END IF
457
458 IF (dft_control%restricted) THEN
459 !For ROKS usefull only first term
460 nspins = 1
461 ELSE
462 nspins = dft_control%nspins
463 END IF
464 !Some info about ROKS
465 IF (dft_control%restricted .AND. (do_mo_cubes .OR. p_loc_homo)) THEN
466 CALL cp_abort(__location__, "Unclear how we define MOs / localization in the restricted case ... ")
467 ! It is possible to obtain Wannier centers for ROKS without rotations for SINGLE OCCUPIED ORBITALS
468 END IF
469 ! Makes the MOs eigenstates, computes eigenvalues, write cubes
470 IF (do_kpoints) THEN
471 cpwarn_if(do_mo_cubes, "Print MO cubes not implemented for k-point calculations")
472 ELSE
473 CALL get_qs_env(qs_env, &
474 mos=mos, &
475 matrix_ks=ks_rmpv)
476 IF ((do_mo_cubes .AND. nhomo /= 0) .OR. do_stm) THEN
477 CALL get_qs_env(qs_env, mo_derivs=mo_derivs)
478 IF (dft_control%do_admm) THEN
479 CALL get_qs_env(qs_env, admm_env=admm_env)
480 CALL make_mo_eig(mos, nspins, ks_rmpv, scf_control, mo_derivs, admm_env=admm_env)
481 ELSE
482 IF (dft_control%hairy_probes) THEN
483 scf_control%smear%do_smear = .false.
484 CALL make_mo_eig(mos, dft_control%nspins, ks_rmpv, scf_control, mo_derivs, &
485 hairy_probes=dft_control%hairy_probes, &
486 probe=dft_control%probe)
487 ELSE
488 CALL make_mo_eig(mos, dft_control%nspins, ks_rmpv, scf_control, mo_derivs)
489 END IF
490 END IF
491 DO ispin = 1, dft_control%nspins
492 CALL get_mo_set(mo_set=mos(ispin), eigenvalues=mo_eigenvalues, homo=homo)
493 homo_lumo(ispin, 1) = mo_eigenvalues(homo)
494 END DO
495 has_homo = .true.
496 END IF
497 IF (do_mo_cubes .AND. nhomo /= 0) THEN
498 DO ispin = 1, nspins
499 ! Prints the cube files of OCCUPIED ORBITALS
500 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
501 eigenvalues=mo_eigenvalues, homo=homo, nmo=nmo)
502 CALL qs_scf_post_occ_cubes(input, dft_section, dft_control, logger, qs_env, &
503 mo_coeff, wf_g, wf_r, particles, homo, ispin)
504 END DO
505 END IF
506 END IF
507
508 ! Initialize the localization environment, needed e.g. for wannier functions and molecular states
509 ! Gets localization info for the occupied orbs
510 ! - Possibly gets wannier functions
511 ! - Possibly gets molecular states
512 IF (p_loc_homo) THEN
513 IF (do_kpoints) THEN
514 cpwarn("Localization not implemented for k-point calculations!")
515 ELSEIF (dft_control%restricted &
516 .AND. (section_get_ival(localize_section, "METHOD") /= do_loc_none) &
517 .AND. (section_get_ival(localize_section, "METHOD") /= do_loc_jacobi)) THEN
518 cpabort("ROKS works only with LOCALIZE METHOD NONE or JACOBI")
519 ELSE
520 ALLOCATE (occupied_orbs(dft_control%nspins))
521 ALLOCATE (occupied_evals(dft_control%nspins))
522 ALLOCATE (homo_localized(dft_control%nspins))
523 DO ispin = 1, dft_control%nspins
524 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
525 eigenvalues=mo_eigenvalues)
526 occupied_orbs(ispin) = mo_coeff
527 occupied_evals(ispin)%array => mo_eigenvalues
528 CALL cp_fm_create(homo_localized(ispin), occupied_orbs(ispin)%matrix_struct)
529 CALL cp_fm_to_fm(occupied_orbs(ispin), homo_localized(ispin))
530 END DO
531
532 CALL get_qs_env(qs_env, mo_loc_history=mo_loc_history)
533 do_homo = .true.
534
535 ALLOCATE (qs_loc_env_homo)
536 CALL qs_loc_env_create(qs_loc_env_homo)
537 CALL qs_loc_control_init(qs_loc_env_homo, localize_section, do_homo=do_homo)
538 CALL qs_loc_init(qs_env, qs_loc_env_homo, localize_section, homo_localized, do_homo, &
539 do_mo_cubes, mo_loc_history=mo_loc_history)
540 CALL get_localization_info(qs_env, qs_loc_env_homo, localize_section, homo_localized, &
541 wf_r, wf_g, particles, occupied_orbs, occupied_evals, marked_states)
542
543 !retain the homo_localized for future use
544 IF (qs_loc_env_homo%localized_wfn_control%use_history) THEN
545 CALL retain_history(mo_loc_history, homo_localized)
546 CALL set_qs_env(qs_env, mo_loc_history=mo_loc_history)
547 END IF
548
549 !write restart for localization of occupied orbitals
550 CALL loc_write_restart(qs_loc_env_homo, loc_print_section, mos, &
551 homo_localized, do_homo)
552 CALL cp_fm_release(homo_localized)
553 DEALLOCATE (occupied_orbs)
554 DEALLOCATE (occupied_evals)
555 ! Print Total Dipole if the localization has been performed
556 IF (qs_loc_env_homo%do_localize) THEN
557 CALL loc_dipole(input, dft_control, qs_loc_env_homo, logger, qs_env)
558 END IF
559 END IF
560 END IF
561
562 ! Gets the lumos, and eigenvalues for the lumos, and localize them if requested
563 IF (do_kpoints) THEN
564 IF (do_mo_cubes .OR. p_loc_lumo) THEN
565 ! nothing at the moment, not implemented
566 cpwarn("Localization and MO related output not implemented for k-point calculations!")
567 END IF
568 ELSE
569 compute_lumos = do_mo_cubes .AND. nlumo /= 0
570 compute_lumos = compute_lumos .OR. p_loc_lumo
571
572 DO ispin = 1, dft_control%nspins
573 CALL get_mo_set(mo_set=mos(ispin), homo=homo, nmo=nmo)
574 compute_lumos = compute_lumos .AND. homo == nmo
575 END DO
576
577 IF (do_mo_cubes .AND. .NOT. compute_lumos) THEN
578
579 nlumo = section_get_ival(dft_section, "PRINT%MO_CUBES%NLUMO")
580 DO ispin = 1, dft_control%nspins
581
582 CALL get_mo_set(mo_set=mos(ispin), homo=homo, nmo=nmo, eigenvalues=mo_eigenvalues)
583 IF (nlumo > nmo - homo) THEN
584 ! this case not yet implemented
585 ELSE
586 IF (nlumo == -1) THEN
587 nlumo = nmo - homo
588 END IF
589 IF (output_unit > 0) WRITE (output_unit, *) " "
590 IF (output_unit > 0) WRITE (output_unit, *) " Lowest eigenvalues of the unoccupied subspace spin ", ispin
591 IF (output_unit > 0) WRITE (output_unit, *) "---------------------------------------------"
592 IF (output_unit > 0) WRITE (output_unit, '(4(1X,1F16.8))') mo_eigenvalues(homo + 1:homo + nlumo)
593
594 ! Prints the cube files of UNOCCUPIED ORBITALS
595 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff)
596 CALL qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
597 mo_coeff, wf_g, wf_r, particles, nlumo, homo, ispin, lumo=homo + 1)
598 END IF
599 END DO
600
601 END IF
602
603 IF (compute_lumos) THEN
604 check_write = .true.
605 min_lumos = nlumo
606 IF (nlumo == 0) check_write = .false.
607 IF (p_loc_lumo) THEN
608 do_homo = .false.
609 ALLOCATE (qs_loc_env_lumo)
610 CALL qs_loc_env_create(qs_loc_env_lumo)
611 CALL qs_loc_control_init(qs_loc_env_lumo, localize_section, do_homo=do_homo)
612 min_lumos = max(maxval(qs_loc_env_lumo%localized_wfn_control%loc_states(:, :)), nlumo)
613 END IF
614
615 ALLOCATE (unoccupied_orbs(dft_control%nspins))
616 ALLOCATE (unoccupied_evals(dft_control%nspins))
617 CALL make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, min_lumos, nlumos)
618 lumo_ptr => unoccupied_orbs
619 DO ispin = 1, dft_control%nspins
620 has_lumo = .true.
621 homo_lumo(ispin, 2) = unoccupied_evals(ispin)%array(1)
622 CALL get_mo_set(mo_set=mos(ispin), homo=homo)
623 IF (check_write) THEN
624 IF (p_loc_lumo .AND. nlumo /= -1) nlumos = min(nlumo, nlumos)
625 ! Prints the cube files of UNOCCUPIED ORBITALS
626 CALL qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
627 unoccupied_orbs(ispin), wf_g, wf_r, particles, nlumos, homo, ispin)
628 END IF
629 END DO
630
631 IF (p_loc_lumo) THEN
632 ALLOCATE (lumo_localized(dft_control%nspins))
633 DO ispin = 1, dft_control%nspins
634 CALL cp_fm_create(lumo_localized(ispin), unoccupied_orbs(ispin)%matrix_struct)
635 CALL cp_fm_to_fm(unoccupied_orbs(ispin), lumo_localized(ispin))
636 END DO
637 CALL qs_loc_init(qs_env, qs_loc_env_lumo, localize_section, lumo_localized, do_homo, do_mo_cubes, &
638 evals=unoccupied_evals)
639 CALL qs_loc_env_init(qs_loc_env_lumo, qs_loc_env_lumo%localized_wfn_control, qs_env, &
640 loc_coeff=unoccupied_orbs)
641 CALL get_localization_info(qs_env, qs_loc_env_lumo, localize_section, &
642 lumo_localized, wf_r, wf_g, particles, &
643 unoccupied_orbs, unoccupied_evals, marked_states)
644 CALL loc_write_restart(qs_loc_env_lumo, loc_print_section, mos, homo_localized, do_homo, &
645 evals=unoccupied_evals)
646 lumo_ptr => lumo_localized
647 END IF
648 END IF
649
650 IF (has_homo .AND. has_lumo) THEN
651 IF (output_unit > 0) WRITE (output_unit, *) " "
652 DO ispin = 1, dft_control%nspins
653 IF (.NOT. scf_control%smear%do_smear) THEN
654 gap = homo_lumo(ispin, 2) - homo_lumo(ispin, 1)
655 IF (output_unit > 0) WRITE (output_unit, '(T2,A,F12.6)') &
656 "HOMO - LUMO gap [eV] :", gap*evolt
657 END IF
658 END DO
659 END IF
660 END IF
661
662 IF (p_loc_mixed) THEN
663 IF (do_kpoints) THEN
664 cpwarn("Localization not implemented for k-point calculations!")
665 ELSEIF (dft_control%restricted) THEN
666 IF (output_unit > 0) WRITE (output_unit, *) &
667 " Unclear how we define MOs / localization in the restricted case... skipping"
668 ELSE
669
670 ALLOCATE (mixed_orbs(dft_control%nspins))
671 ALLOCATE (mixed_evals(dft_control%nspins))
672 ALLOCATE (mixed_localized(dft_control%nspins))
673 DO ispin = 1, dft_control%nspins
674 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
675 eigenvalues=mo_eigenvalues)
676 mixed_orbs(ispin) = mo_coeff
677 mixed_evals(ispin)%array => mo_eigenvalues
678 CALL cp_fm_create(mixed_localized(ispin), mixed_orbs(ispin)%matrix_struct)
679 CALL cp_fm_to_fm(mixed_orbs(ispin), mixed_localized(ispin))
680 END DO
681
682 CALL get_qs_env(qs_env, mo_loc_history=mo_loc_history)
683 do_homo = .false.
684 do_mixed = .true.
685 total_zeff_corr = scf_env%sum_zeff_corr
686 ALLOCATE (qs_loc_env_mixed)
687 CALL qs_loc_env_create(qs_loc_env_mixed)
688 CALL qs_loc_control_init(qs_loc_env_mixed, localize_section, do_homo=do_homo, do_mixed=do_mixed)
689 CALL qs_loc_init(qs_env, qs_loc_env_mixed, localize_section, mixed_localized, do_homo, &
690 do_mo_cubes, mo_loc_history=mo_loc_history, tot_zeff_corr=total_zeff_corr, &
692
693 DO ispin = 1, dft_control%nspins
694 CALL cp_fm_get_info(mixed_localized(ispin), ncol_global=nchk_nmoloc)
695 END DO
696
697 CALL get_localization_info(qs_env, qs_loc_env_mixed, localize_section, mixed_localized, &
698 wf_r, wf_g, particles, mixed_orbs, mixed_evals, marked_states)
699
700 !retain the homo_localized for future use
701 IF (qs_loc_env_mixed%localized_wfn_control%use_history) THEN
702 CALL retain_history(mo_loc_history, mixed_localized)
703 CALL set_qs_env(qs_env, mo_loc_history=mo_loc_history)
704 END IF
705
706 !write restart for localization of occupied orbitals
707 CALL loc_write_restart(qs_loc_env_mixed, loc_print_section, mos, &
708 mixed_localized, do_homo, do_mixed=do_mixed)
709 CALL cp_fm_release(mixed_localized)
710 DEALLOCATE (mixed_orbs)
711 DEALLOCATE (mixed_evals)
712 ! Print Total Dipole if the localization has been performed
713! Revisit the formalism later
714 !IF (qs_loc_env_mixed%do_localize) THEN
715 ! CALL loc_dipole(input, dft_control, qs_loc_env_mixed, logger, qs_env)
716 !END IF
717 END IF
718 END IF
719
720 ! Deallocate grids needed to compute wavefunctions
721 IF (((do_mo_cubes .OR. do_wannier_cubes) .AND. (nlumo /= 0 .OR. nhomo /= 0)) .OR. p_loc) THEN
722 CALL auxbas_pw_pool%give_back_pw(wf_r)
723 CALL auxbas_pw_pool%give_back_pw(wf_g)
724 END IF
725
726 ! Destroy the localization environment
727 IF (.NOT. do_kpoints) THEN
728 IF (p_loc_homo) THEN
729 CALL qs_loc_env_release(qs_loc_env_homo)
730 DEALLOCATE (qs_loc_env_homo)
731 END IF
732 IF (p_loc_lumo) THEN
733 CALL qs_loc_env_release(qs_loc_env_lumo)
734 DEALLOCATE (qs_loc_env_lumo)
735 END IF
736 IF (p_loc_mixed) THEN
737 CALL qs_loc_env_release(qs_loc_env_mixed)
738 DEALLOCATE (qs_loc_env_mixed)
739 END IF
740 END IF
741
742 ! generate a mix of wfns, and write to a restart
743 IF (do_kpoints) THEN
744 ! nothing at the moment, not implemented
745 ELSE
746 CALL get_qs_env(qs_env, matrix_s=matrix_s, para_env=para_env)
747 CALL wfn_mix(mos, particle_set, dft_section, qs_kind_set, para_env, &
748 output_unit, unoccupied_orbs=lumo_ptr, scf_env=scf_env, &
749 matrix_s=matrix_s, marked_states=marked_states)
750
751 IF (p_loc_lumo) CALL cp_fm_release(lumo_localized)
752 END IF
753 IF (ASSOCIATED(marked_states)) THEN
754 DEALLOCATE (marked_states)
755 END IF
756
757 ! This is just a deallocation for printing MO_CUBES or TDDFPT
758 IF (.NOT. do_kpoints) THEN
759 IF (compute_lumos) THEN
760 DO ispin = 1, dft_control%nspins
761 DEALLOCATE (unoccupied_evals(ispin)%array)
762 CALL cp_fm_release(unoccupied_orbs(ispin))
763 END DO
764 DEALLOCATE (unoccupied_evals)
765 DEALLOCATE (unoccupied_orbs)
766 END IF
767 END IF
768
769 !stm images
770 IF (do_stm) THEN
771 IF (do_kpoints) THEN
772 cpwarn("STM not implemented for k-point calculations!")
773 ELSE
774 NULLIFY (unoccupied_orbs_stm, unoccupied_evals_stm)
775 IF (nlumo_stm > 0) THEN
776 ALLOCATE (unoccupied_orbs_stm(dft_control%nspins))
777 ALLOCATE (unoccupied_evals_stm(dft_control%nspins))
778 CALL make_lumo_gpw(qs_env, scf_env, unoccupied_orbs_stm, unoccupied_evals_stm, &
779 nlumo_stm, nlumos)
780 END IF
781
782 CALL th_stm_image(qs_env, stm_section, particles, unoccupied_orbs_stm, &
783 unoccupied_evals_stm)
784
785 IF (nlumo_stm > 0) THEN
786 DO ispin = 1, dft_control%nspins
787 DEALLOCATE (unoccupied_evals_stm(ispin)%array)
788 END DO
789 DEALLOCATE (unoccupied_evals_stm)
790 CALL cp_fm_release(unoccupied_orbs_stm)
791 END IF
792 END IF
793 END IF
794
795 ! Print coherent X-ray diffraction spectrum
796 CALL qs_scf_post_xray(input, dft_section, logger, qs_env, output_unit)
797
798 ! Calculation of Electric Field Gradients
799 CALL qs_scf_post_efg(input, logger, qs_env)
800
801 ! Calculation of ET
802 CALL qs_scf_post_et(input, qs_env, dft_control)
803
804 ! Calculation of EPR Hyperfine Coupling Tensors
805 CALL qs_scf_post_epr(input, logger, qs_env)
806
807 ! Calculation of properties needed for BASIS_MOLOPT optimizations
808 CALL qs_scf_post_molopt(input, logger, qs_env)
809
810 ! Calculate ELF
811 CALL qs_scf_post_elf(input, logger, qs_env)
812
813 ! Use Wannier90 interface
814 CALL wannier90_interface(input, logger, qs_env)
815
816 IF (my_do_mp2) THEN
817 ! Get everything back
818 DO ispin = 1, dft_control%nspins
819 CALL dbcsr_add(rho_ao(ispin, 1)%matrix, matrix_p_mp2(ispin)%matrix, 1.0_dp, -1.0_dp)
820 END DO
821 CALL qs_rho_update_rho(rho, qs_env=qs_env)
822 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.)
823 END IF
824
825 CALL timestop(handle)
826
827 END SUBROUTINE scf_post_calculation_gpw
828
829! **************************************************************************************************
830!> \brief Gets the lumos, and eigenvalues for the lumos
831!> \param qs_env ...
832!> \param scf_env ...
833!> \param unoccupied_orbs ...
834!> \param unoccupied_evals ...
835!> \param nlumo ...
836!> \param nlumos ...
837! **************************************************************************************************
838 SUBROUTINE make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, nlumo, nlumos)
839
840 TYPE(qs_environment_type), POINTER :: qs_env
841 TYPE(qs_scf_env_type), POINTER :: scf_env
842 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: unoccupied_orbs
843 TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: unoccupied_evals
844 INTEGER, INTENT(IN) :: nlumo
845 INTEGER, INTENT(OUT) :: nlumos
846
847 CHARACTER(len=*), PARAMETER :: routinen = 'make_lumo_gpw'
848
849 INTEGER :: handle, homo, ispin, n, nao, nmo, &
850 output_unit
851 TYPE(admm_type), POINTER :: admm_env
852 TYPE(cp_blacs_env_type), POINTER :: blacs_env
853 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
854 TYPE(cp_fm_type), POINTER :: mo_coeff
855 TYPE(cp_logger_type), POINTER :: logger
856 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_s
857 TYPE(dft_control_type), POINTER :: dft_control
858 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
859 TYPE(mp_para_env_type), POINTER :: para_env
860 TYPE(preconditioner_type), POINTER :: local_preconditioner
861 TYPE(scf_control_type), POINTER :: scf_control
862
863 CALL timeset(routinen, handle)
864
865 NULLIFY (mos, ks_rmpv, scf_control, dft_control, admm_env, para_env, blacs_env)
866 CALL get_qs_env(qs_env, &
867 mos=mos, &
868 matrix_ks=ks_rmpv, &
869 scf_control=scf_control, &
870 dft_control=dft_control, &
871 matrix_s=matrix_s, &
872 admm_env=admm_env, &
873 para_env=para_env, &
874 blacs_env=blacs_env)
875
876 logger => cp_get_default_logger()
877 output_unit = cp_logger_get_default_io_unit(logger)
878
879 DO ispin = 1, dft_control%nspins
880 NULLIFY (unoccupied_evals(ispin)%array)
881 ! Always write eigenvalues
882 IF (output_unit > 0) WRITE (output_unit, *) " "
883 IF (output_unit > 0) WRITE (output_unit, *) " Lowest Eigenvalues of the unoccupied subspace spin ", ispin
884 IF (output_unit > 0) WRITE (output_unit, fmt='(1X,A)') "-----------------------------------------------------"
885 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=homo, nao=nao, nmo=nmo)
886 CALL cp_fm_get_info(mo_coeff, nrow_global=n)
887 nlumos = max(1, min(nlumo, nao - nmo))
888 IF (nlumo == -1) nlumos = nao - nmo
889 ALLOCATE (unoccupied_evals(ispin)%array(nlumos))
890 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=blacs_env, &
891 nrow_global=n, ncol_global=nlumos)
892 CALL cp_fm_create(unoccupied_orbs(ispin), fm_struct_tmp, name="lumos")
893 CALL cp_fm_struct_release(fm_struct_tmp)
894 CALL cp_fm_init_random(unoccupied_orbs(ispin), nlumos)
895
896 ! the full_all preconditioner makes not much sense for lumos search
897 NULLIFY (local_preconditioner)
898 IF (ASSOCIATED(scf_env%ot_preconditioner)) THEN
899 local_preconditioner => scf_env%ot_preconditioner(1)%preconditioner
900 ! this one can for sure not be right (as it has to match a given C0)
901 IF (local_preconditioner%in_use == ot_precond_full_all) THEN
902 NULLIFY (local_preconditioner)
903 END IF
904 END IF
905
906 ! If we do ADMM, we add have to modify the Kohn-Sham matrix
907 IF (dft_control%do_admm) THEN
908 CALL admm_correct_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
909 END IF
910
911 CALL ot_eigensolver(matrix_h=ks_rmpv(ispin)%matrix, matrix_s=matrix_s(1)%matrix, &
912 matrix_c_fm=unoccupied_orbs(ispin), &
913 matrix_orthogonal_space_fm=mo_coeff, &
914 eps_gradient=scf_control%eps_lumos, &
915 preconditioner=local_preconditioner, &
916 iter_max=scf_control%max_iter_lumos, &
917 size_ortho_space=nmo)
918
919 CALL calculate_subspace_eigenvalues(unoccupied_orbs(ispin), ks_rmpv(ispin)%matrix, &
920 unoccupied_evals(ispin)%array, scr=output_unit, &
921 ionode=output_unit > 0)
922
923 ! If we do ADMM, we restore the original Kohn-Sham matrix
924 IF (dft_control%do_admm) THEN
925 CALL admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
926 END IF
927
928 END DO
929
930 CALL timestop(handle)
931
932 END SUBROUTINE make_lumo_gpw
933! **************************************************************************************************
934!> \brief Computes and Prints Atomic Charges with several methods
935!> \param input ...
936!> \param logger ...
937!> \param qs_env the qs_env in which the qs_env lives
938! **************************************************************************************************
939 SUBROUTINE qs_scf_post_charges(input, logger, qs_env)
940 TYPE(section_vals_type), POINTER :: input
941 TYPE(cp_logger_type), POINTER :: logger
942 TYPE(qs_environment_type), POINTER :: qs_env
943
944 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_charges'
945
946 INTEGER :: handle, print_level, unit_nr
947 LOGICAL :: do_kpoints, print_it
948 TYPE(section_vals_type), POINTER :: density_fit_section, print_key
949
950 CALL timeset(routinen, handle)
951
952 CALL get_qs_env(qs_env=qs_env, do_kpoints=do_kpoints)
953
954 ! Mulliken charges require no further computation and are printed from write_mo_free_results
955
956 ! Compute the Lowdin charges
957 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%LOWDIN")
958 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
959 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOWDIN", extension=".lowdin", &
960 log_filename=.false.)
961 print_level = 1
962 CALL section_vals_val_get(print_key, "PRINT_GOP", l_val=print_it)
963 IF (print_it) print_level = 2
964 CALL section_vals_val_get(print_key, "PRINT_ALL", l_val=print_it)
965 IF (print_it) print_level = 3
966 IF (do_kpoints) THEN
967 cpwarn("Lowdin charges not implemented for k-point calculations!")
968 ELSE
969 CALL lowdin_population_analysis(qs_env, unit_nr, print_level)
970 END IF
971 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%LOWDIN")
972 END IF
973
974 ! Compute the RESP charges
975 CALL resp_fit(qs_env)
976
977 ! Compute the Density Derived Atomic Point charges with the Bloechl scheme
978 print_key => section_vals_get_subs_vals(input, "PROPERTIES%FIT_CHARGE")
979 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
980 unit_nr = cp_print_key_unit_nr(logger, input, "PROPERTIES%FIT_CHARGE", extension=".Fitcharge", &
981 log_filename=.false.)
982 density_fit_section => section_vals_get_subs_vals(input, "DFT%DENSITY_FITTING")
983 CALL get_ddapc(qs_env, .false., density_fit_section, iwc=unit_nr)
984 CALL cp_print_key_finished_output(unit_nr, logger, input, "PROPERTIES%FIT_CHARGE")
985 END IF
986
987 CALL timestop(handle)
988
989 END SUBROUTINE qs_scf_post_charges
990
991! **************************************************************************************************
992!> \brief Computes and prints the Cube Files for MO
993!> \param input ...
994!> \param dft_section ...
995!> \param dft_control ...
996!> \param logger ...
997!> \param qs_env the qs_env in which the qs_env lives
998!> \param mo_coeff ...
999!> \param wf_g ...
1000!> \param wf_r ...
1001!> \param particles ...
1002!> \param homo ...
1003!> \param ispin ...
1004! **************************************************************************************************
1005 SUBROUTINE qs_scf_post_occ_cubes(input, dft_section, dft_control, logger, qs_env, &
1006 mo_coeff, wf_g, wf_r, particles, homo, ispin)
1007 TYPE(section_vals_type), POINTER :: input, dft_section
1008 TYPE(dft_control_type), POINTER :: dft_control
1009 TYPE(cp_logger_type), POINTER :: logger
1010 TYPE(qs_environment_type), POINTER :: qs_env
1011 TYPE(cp_fm_type), INTENT(IN) :: mo_coeff
1012 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: wf_g
1013 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: wf_r
1014 TYPE(particle_list_type), POINTER :: particles
1015 INTEGER, INTENT(IN) :: homo, ispin
1016
1017 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_occ_cubes'
1018
1019 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube, title
1020 INTEGER :: handle, i, ir, ivector, n_rep, nhomo, &
1021 nlist, unit_nr
1022 INTEGER, DIMENSION(:), POINTER :: list, list_index
1023 LOGICAL :: append_cube, mpi_io
1024 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1025 TYPE(cell_type), POINTER :: cell
1026 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1027 TYPE(pw_env_type), POINTER :: pw_env
1028 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1029
1030 CALL timeset(routinen, handle)
1031
1032 NULLIFY (list_index)
1033
1034 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%MO_CUBES") &
1035 , cp_p_file) .AND. section_get_lval(dft_section, "PRINT%MO_CUBES%WRITE_CUBE")) THEN
1036 nhomo = section_get_ival(dft_section, "PRINT%MO_CUBES%NHOMO")
1037 append_cube = section_get_lval(dft_section, "PRINT%MO_CUBES%APPEND")
1038 my_pos_cube = "REWIND"
1039 IF (append_cube) THEN
1040 my_pos_cube = "APPEND"
1041 END IF
1042 CALL section_vals_val_get(dft_section, "PRINT%MO_CUBES%HOMO_LIST", n_rep_val=n_rep)
1043 IF (n_rep > 0) THEN ! write the cubes of the list
1044 nlist = 0
1045 DO ir = 1, n_rep
1046 NULLIFY (list)
1047 CALL section_vals_val_get(dft_section, "PRINT%MO_CUBES%HOMO_LIST", i_rep_val=ir, &
1048 i_vals=list)
1049 IF (ASSOCIATED(list)) THEN
1050 CALL reallocate(list_index, 1, nlist + SIZE(list))
1051 DO i = 1, SIZE(list)
1052 list_index(i + nlist) = list(i)
1053 END DO
1054 nlist = nlist + SIZE(list)
1055 END IF
1056 END DO
1057 ELSE
1058
1059 IF (nhomo == -1) nhomo = homo
1060 nlist = homo - max(1, homo - nhomo + 1) + 1
1061 ALLOCATE (list_index(nlist))
1062 DO i = 1, nlist
1063 list_index(i) = max(1, homo - nhomo + 1) + i - 1
1064 END DO
1065 END IF
1066 DO i = 1, nlist
1067 ivector = list_index(i)
1068 CALL get_qs_env(qs_env=qs_env, &
1069 atomic_kind_set=atomic_kind_set, &
1070 qs_kind_set=qs_kind_set, &
1071 cell=cell, &
1072 particle_set=particle_set, &
1073 pw_env=pw_env)
1074 CALL calculate_wavefunction(mo_coeff, ivector, wf_r, wf_g, atomic_kind_set, qs_kind_set, &
1075 cell, dft_control, particle_set, pw_env)
1076 WRITE (filename, '(a4,I5.5,a1,I1.1)') "WFN_", ivector, "_", ispin
1077 mpi_io = .true.
1078 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MO_CUBES", extension=".cube", &
1079 middle_name=trim(filename), file_position=my_pos_cube, log_filename=.false., &
1080 mpi_io=mpi_io)
1081 WRITE (title, *) "WAVEFUNCTION ", ivector, " spin ", ispin, " i.e. HOMO - ", ivector - homo
1082 CALL cp_pw_to_cube(wf_r, unit_nr, title, particles=particles, &
1083 stride=section_get_ivals(dft_section, "PRINT%MO_CUBES%STRIDE"), &
1084 max_file_size_mb=section_get_rval(dft_section, "PRINT%MO_CUBES%MAX_FILE_SIZE_MB"), &
1085 mpi_io=mpi_io)
1086 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MO_CUBES", mpi_io=mpi_io)
1087 END DO
1088 IF (ASSOCIATED(list_index)) DEALLOCATE (list_index)
1089 END IF
1090
1091 CALL timestop(handle)
1092
1093 END SUBROUTINE qs_scf_post_occ_cubes
1094
1095! **************************************************************************************************
1096!> \brief Computes and prints the Cube Files for MO
1097!> \param input ...
1098!> \param dft_section ...
1099!> \param dft_control ...
1100!> \param logger ...
1101!> \param qs_env the qs_env in which the qs_env lives
1102!> \param unoccupied_orbs ...
1103!> \param wf_g ...
1104!> \param wf_r ...
1105!> \param particles ...
1106!> \param nlumos ...
1107!> \param homo ...
1108!> \param ispin ...
1109!> \param lumo ...
1110! **************************************************************************************************
1111 SUBROUTINE qs_scf_post_unocc_cubes(input, dft_section, dft_control, logger, qs_env, &
1112 unoccupied_orbs, wf_g, wf_r, particles, nlumos, homo, ispin, lumo)
1113
1114 TYPE(section_vals_type), POINTER :: input, dft_section
1115 TYPE(dft_control_type), POINTER :: dft_control
1116 TYPE(cp_logger_type), POINTER :: logger
1117 TYPE(qs_environment_type), POINTER :: qs_env
1118 TYPE(cp_fm_type), INTENT(IN) :: unoccupied_orbs
1119 TYPE(pw_c1d_gs_type), INTENT(INOUT) :: wf_g
1120 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: wf_r
1121 TYPE(particle_list_type), POINTER :: particles
1122 INTEGER, INTENT(IN) :: nlumos, homo, ispin
1123 INTEGER, INTENT(IN), OPTIONAL :: lumo
1124
1125 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_unocc_cubes'
1126
1127 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube, title
1128 INTEGER :: handle, ifirst, index_mo, ivector, &
1129 unit_nr
1130 LOGICAL :: append_cube, mpi_io
1131 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1132 TYPE(cell_type), POINTER :: cell
1133 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1134 TYPE(pw_env_type), POINTER :: pw_env
1135 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1136
1137 CALL timeset(routinen, handle)
1138
1139 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%MO_CUBES"), cp_p_file) &
1140 .AND. section_get_lval(dft_section, "PRINT%MO_CUBES%WRITE_CUBE")) THEN
1141 NULLIFY (qs_kind_set, particle_set, pw_env, cell)
1142 append_cube = section_get_lval(dft_section, "PRINT%MO_CUBES%APPEND")
1143 my_pos_cube = "REWIND"
1144 IF (append_cube) THEN
1145 my_pos_cube = "APPEND"
1146 END IF
1147 ifirst = 1
1148 IF (PRESENT(lumo)) ifirst = lumo
1149 DO ivector = ifirst, ifirst + nlumos - 1
1150 CALL get_qs_env(qs_env=qs_env, &
1151 atomic_kind_set=atomic_kind_set, &
1152 qs_kind_set=qs_kind_set, &
1153 cell=cell, &
1154 particle_set=particle_set, &
1155 pw_env=pw_env)
1156 CALL calculate_wavefunction(unoccupied_orbs, ivector, wf_r, wf_g, atomic_kind_set, &
1157 qs_kind_set, cell, dft_control, particle_set, pw_env)
1158
1159 IF (ifirst == 1) THEN
1160 index_mo = homo + ivector
1161 ELSE
1162 index_mo = ivector
1163 END IF
1164 WRITE (filename, '(a4,I5.5,a1,I1.1)') "WFN_", index_mo, "_", ispin
1165 mpi_io = .true.
1166
1167 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MO_CUBES", extension=".cube", &
1168 middle_name=trim(filename), file_position=my_pos_cube, log_filename=.false., &
1169 mpi_io=mpi_io)
1170 WRITE (title, *) "WAVEFUNCTION ", index_mo, " spin ", ispin, " i.e. LUMO + ", ifirst + ivector - 2
1171 CALL cp_pw_to_cube(wf_r, unit_nr, title, particles=particles, &
1172 stride=section_get_ivals(dft_section, "PRINT%MO_CUBES%STRIDE"), &
1173 max_file_size_mb=section_get_rval(dft_section, "PRINT%MO_CUBES%MAX_FILE_SIZE_MB"), &
1174 mpi_io=mpi_io)
1175 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MO_CUBES", mpi_io=mpi_io)
1176 END DO
1177 END IF
1178
1179 CALL timestop(handle)
1180
1181 END SUBROUTINE qs_scf_post_unocc_cubes
1182
1183! **************************************************************************************************
1184!> \brief Computes and prints electric moments
1185!> \param input ...
1186!> \param logger ...
1187!> \param qs_env the qs_env in which the qs_env lives
1188!> \param output_unit ...
1189! **************************************************************************************************
1190 SUBROUTINE qs_scf_post_moments(input, logger, qs_env, output_unit)
1191 TYPE(section_vals_type), POINTER :: input
1192 TYPE(cp_logger_type), POINTER :: logger
1193 TYPE(qs_environment_type), POINTER :: qs_env
1194 INTEGER, INTENT(IN) :: output_unit
1195
1196 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_moments'
1197
1198 CHARACTER(LEN=default_path_length) :: filename
1199 INTEGER :: handle, maxmom, reference, unit_nr
1200 LOGICAL :: com_nl, do_kpoints, magnetic, periodic, &
1201 second_ref_point, vel_reprs
1202 REAL(kind=dp), DIMENSION(:), POINTER :: ref_point
1203 TYPE(section_vals_type), POINTER :: print_key
1204
1205 CALL timeset(routinen, handle)
1206
1207 print_key => section_vals_get_subs_vals(section_vals=input, &
1208 subsection_name="DFT%PRINT%MOMENTS")
1209
1210 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1211
1212 maxmom = section_get_ival(section_vals=input, &
1213 keyword_name="DFT%PRINT%MOMENTS%MAX_MOMENT")
1214 periodic = section_get_lval(section_vals=input, &
1215 keyword_name="DFT%PRINT%MOMENTS%PERIODIC")
1216 reference = section_get_ival(section_vals=input, &
1217 keyword_name="DFT%PRINT%MOMENTS%REFERENCE")
1218 magnetic = section_get_lval(section_vals=input, &
1219 keyword_name="DFT%PRINT%MOMENTS%MAGNETIC")
1220 vel_reprs = section_get_lval(section_vals=input, &
1221 keyword_name="DFT%PRINT%MOMENTS%VEL_REPRS")
1222 com_nl = section_get_lval(section_vals=input, &
1223 keyword_name="DFT%PRINT%MOMENTS%COM_NL")
1224 second_ref_point = section_get_lval(section_vals=input, &
1225 keyword_name="DFT%PRINT%MOMENTS%SECOND_REFERENCE_POINT")
1226
1227 NULLIFY (ref_point)
1228 CALL section_vals_val_get(input, "DFT%PRINT%MOMENTS%REF_POINT", r_vals=ref_point)
1229 unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=input, &
1230 print_key_path="DFT%PRINT%MOMENTS", extension=".dat", &
1231 middle_name="moments", log_filename=.false.)
1232
1233 IF (output_unit > 0) THEN
1234 IF (unit_nr /= output_unit) THEN
1235 INQUIRE (unit=unit_nr, name=filename)
1236 WRITE (unit=output_unit, fmt="(/,T2,A,2(/,T3,A),/)") &
1237 "MOMENTS", "The electric/magnetic moments are written to file:", &
1238 trim(filename)
1239 ELSE
1240 WRITE (unit=output_unit, fmt="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
1241 END IF
1242 END IF
1243
1244 CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
1245
1246 IF (do_kpoints) THEN
1247 CALL qs_moment_kpoints(qs_env, maxmom, reference, ref_point, unit_nr)
1248 ELSE
1249 IF (periodic) THEN
1250 CALL qs_moment_berry_phase(qs_env, magnetic, maxmom, reference, ref_point, unit_nr)
1251 ELSE
1252 CALL qs_moment_locop(qs_env, magnetic, maxmom, reference, ref_point, unit_nr, vel_reprs, com_nl)
1253 END IF
1254 END IF
1255
1256 CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
1257 basis_section=input, print_key_path="DFT%PRINT%MOMENTS")
1258
1259 IF (second_ref_point) THEN
1260 reference = section_get_ival(section_vals=input, &
1261 keyword_name="DFT%PRINT%MOMENTS%REFERENCE_2")
1262
1263 NULLIFY (ref_point)
1264 CALL section_vals_val_get(input, "DFT%PRINT%MOMENTS%REF_POINT_2", r_vals=ref_point)
1265 unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=input, &
1266 print_key_path="DFT%PRINT%MOMENTS", extension=".dat", &
1267 middle_name="moments_refpoint_2", log_filename=.false.)
1268
1269 IF (output_unit > 0) THEN
1270 IF (unit_nr /= output_unit) THEN
1271 INQUIRE (unit=unit_nr, name=filename)
1272 WRITE (unit=output_unit, fmt="(/,T2,A,2(/,T3,A),/)") &
1273 "MOMENTS", "The electric/magnetic moments for the second reference point are written to file:", &
1274 trim(filename)
1275 ELSE
1276 WRITE (unit=output_unit, fmt="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
1277 END IF
1278 END IF
1279 IF (do_kpoints) THEN
1280 CALL qs_moment_kpoints(qs_env, maxmom, reference, ref_point, unit_nr)
1281 ELSE
1282 IF (periodic) THEN
1283 CALL qs_moment_berry_phase(qs_env, magnetic, maxmom, reference, ref_point, unit_nr)
1284 ELSE
1285 CALL qs_moment_locop(qs_env, magnetic, maxmom, reference, ref_point, unit_nr, vel_reprs, com_nl)
1286 END IF
1287 END IF
1288 CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
1289 basis_section=input, print_key_path="DFT%PRINT%MOMENTS")
1290 END IF
1291
1292 END IF
1293
1294 CALL timestop(handle)
1295
1296 END SUBROUTINE qs_scf_post_moments
1297
1298! **************************************************************************************************
1299!> \brief Computes and prints the X-ray diffraction spectrum.
1300!> \param input ...
1301!> \param dft_section ...
1302!> \param logger ...
1303!> \param qs_env the qs_env in which the qs_env lives
1304!> \param output_unit ...
1305! **************************************************************************************************
1306 SUBROUTINE qs_scf_post_xray(input, dft_section, logger, qs_env, output_unit)
1307
1308 TYPE(section_vals_type), POINTER :: input, dft_section
1309 TYPE(cp_logger_type), POINTER :: logger
1310 TYPE(qs_environment_type), POINTER :: qs_env
1311 INTEGER, INTENT(IN) :: output_unit
1312
1313 CHARACTER(LEN=*), PARAMETER :: routinen = 'qs_scf_post_xray'
1314
1315 CHARACTER(LEN=default_path_length) :: filename
1316 INTEGER :: handle, unit_nr
1317 REAL(kind=dp) :: q_max
1318 TYPE(section_vals_type), POINTER :: print_key
1319
1320 CALL timeset(routinen, handle)
1321
1322 print_key => section_vals_get_subs_vals(section_vals=input, &
1323 subsection_name="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM")
1324
1325 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
1326 q_max = section_get_rval(section_vals=dft_section, &
1327 keyword_name="PRINT%XRAY_DIFFRACTION_SPECTRUM%Q_MAX")
1328 unit_nr = cp_print_key_unit_nr(logger=logger, &
1329 basis_section=input, &
1330 print_key_path="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM", &
1331 extension=".dat", &
1332 middle_name="xrd", &
1333 log_filename=.false.)
1334 IF (output_unit > 0) THEN
1335 INQUIRE (unit=unit_nr, name=filename)
1336 WRITE (unit=output_unit, fmt="(/,/,T2,A)") &
1337 "X-RAY DIFFRACTION SPECTRUM"
1338 IF (unit_nr /= output_unit) THEN
1339 WRITE (unit=output_unit, fmt="(/,T3,A,/,/,T3,A,/)") &
1340 "The coherent X-ray diffraction spectrum is written to the file:", &
1341 trim(filename)
1342 END IF
1343 END IF
1344 CALL xray_diffraction_spectrum(qs_env=qs_env, &
1345 unit_number=unit_nr, &
1346 q_max=q_max)
1347 CALL cp_print_key_finished_output(unit_nr=unit_nr, &
1348 logger=logger, &
1349 basis_section=input, &
1350 print_key_path="DFT%PRINT%XRAY_DIFFRACTION_SPECTRUM")
1351 END IF
1352
1353 CALL timestop(handle)
1354
1355 END SUBROUTINE qs_scf_post_xray
1356
1357! **************************************************************************************************
1358!> \brief Computes and prints Electric Field Gradient
1359!> \param input ...
1360!> \param logger ...
1361!> \param qs_env the qs_env in which the qs_env lives
1362! **************************************************************************************************
1363 SUBROUTINE qs_scf_post_efg(input, logger, qs_env)
1364 TYPE(section_vals_type), POINTER :: input
1365 TYPE(cp_logger_type), POINTER :: logger
1366 TYPE(qs_environment_type), POINTER :: qs_env
1367
1368 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_efg'
1369
1370 INTEGER :: handle
1371 TYPE(section_vals_type), POINTER :: print_key
1372
1373 CALL timeset(routinen, handle)
1374
1375 print_key => section_vals_get_subs_vals(section_vals=input, &
1376 subsection_name="DFT%PRINT%ELECTRIC_FIELD_GRADIENT")
1377 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), &
1378 cp_p_file)) THEN
1379 CALL qs_efg_calc(qs_env=qs_env)
1380 END IF
1381
1382 CALL timestop(handle)
1383
1384 END SUBROUTINE qs_scf_post_efg
1385
1386! **************************************************************************************************
1387!> \brief Computes the Electron Transfer Coupling matrix element
1388!> \param input ...
1389!> \param qs_env the qs_env in which the qs_env lives
1390!> \param dft_control ...
1391! **************************************************************************************************
1392 SUBROUTINE qs_scf_post_et(input, qs_env, dft_control)
1393 TYPE(section_vals_type), POINTER :: input
1394 TYPE(qs_environment_type), POINTER :: qs_env
1395 TYPE(dft_control_type), POINTER :: dft_control
1396
1397 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_et'
1398
1399 INTEGER :: handle, ispin
1400 LOGICAL :: do_et
1401 TYPE(cp_fm_type), DIMENSION(:), POINTER :: my_mos
1402 TYPE(section_vals_type), POINTER :: et_section
1403
1404 CALL timeset(routinen, handle)
1405
1406 do_et = .false.
1407 et_section => section_vals_get_subs_vals(input, "PROPERTIES%ET_COUPLING")
1408 CALL section_vals_get(et_section, explicit=do_et)
1409 IF (do_et) THEN
1410 IF (qs_env%et_coupling%first_run) THEN
1411 NULLIFY (my_mos)
1412 ALLOCATE (my_mos(dft_control%nspins))
1413 ALLOCATE (qs_env%et_coupling%et_mo_coeff(dft_control%nspins))
1414 DO ispin = 1, dft_control%nspins
1415 CALL cp_fm_create(matrix=my_mos(ispin), &
1416 matrix_struct=qs_env%mos(ispin)%mo_coeff%matrix_struct, &
1417 name="FIRST_RUN_COEFF"//trim(adjustl(cp_to_string(ispin)))//"MATRIX")
1418 CALL cp_fm_to_fm(qs_env%mos(ispin)%mo_coeff, &
1419 my_mos(ispin))
1420 END DO
1421 CALL set_et_coupling_type(qs_env%et_coupling, et_mo_coeff=my_mos)
1422 DEALLOCATE (my_mos)
1423 END IF
1424 END IF
1425
1426 CALL timestop(handle)
1427
1428 END SUBROUTINE qs_scf_post_et
1429
1430! **************************************************************************************************
1431!> \brief compute the electron localization function
1432!>
1433!> \param input ...
1434!> \param logger ...
1435!> \param qs_env ...
1436!> \par History
1437!> 2012-07 Created [MI]
1438! **************************************************************************************************
1439 SUBROUTINE qs_scf_post_elf(input, logger, qs_env)
1440 TYPE(section_vals_type), POINTER :: input
1441 TYPE(cp_logger_type), POINTER :: logger
1442 TYPE(qs_environment_type), POINTER :: qs_env
1443
1444 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_elf'
1445
1446 CHARACTER(LEN=default_path_length) :: filename, mpi_filename, my_pos_cube, &
1447 title
1448 INTEGER :: handle, ispin, output_unit, unit_nr
1449 LOGICAL :: append_cube, gapw, mpi_io
1450 REAL(dp) :: rho_cutoff
1451 TYPE(dft_control_type), POINTER :: dft_control
1452 TYPE(particle_list_type), POINTER :: particles
1453 TYPE(pw_env_type), POINTER :: pw_env
1454 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
1455 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1456 TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: elf_r
1457 TYPE(qs_subsys_type), POINTER :: subsys
1458 TYPE(section_vals_type), POINTER :: elf_section
1459
1460 CALL timeset(routinen, handle)
1461 output_unit = cp_logger_get_default_io_unit(logger)
1462
1463 elf_section => section_vals_get_subs_vals(input, "DFT%PRINT%ELF_CUBE")
1464 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
1465 "DFT%PRINT%ELF_CUBE"), cp_p_file)) THEN
1466
1467 NULLIFY (dft_control, pw_env, auxbas_pw_pool, pw_pools, particles, subsys)
1468 CALL get_qs_env(qs_env, dft_control=dft_control, pw_env=pw_env, subsys=subsys)
1469 CALL qs_subsys_get(subsys, particles=particles)
1470
1471 gapw = dft_control%qs_control%gapw
1472 IF (.NOT. gapw) THEN
1473 ! allocate
1474 ALLOCATE (elf_r(dft_control%nspins))
1475 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1476 pw_pools=pw_pools)
1477 DO ispin = 1, dft_control%nspins
1478 CALL auxbas_pw_pool%create_pw(elf_r(ispin))
1479 CALL pw_zero(elf_r(ispin))
1480 END DO
1481
1482 IF (output_unit > 0) THEN
1483 WRITE (unit=output_unit, fmt="(/,T15,A,/)") &
1484 " ----- ELF is computed on the real space grid -----"
1485 END IF
1486 rho_cutoff = section_get_rval(elf_section, "density_cutoff")
1487 CALL qs_elf_calc(qs_env, elf_r, rho_cutoff)
1488
1489 ! write ELF into cube file
1490 append_cube = section_get_lval(elf_section, "APPEND")
1491 my_pos_cube = "REWIND"
1492 IF (append_cube) THEN
1493 my_pos_cube = "APPEND"
1494 END IF
1495
1496 DO ispin = 1, dft_control%nspins
1497 WRITE (filename, '(a5,I1.1)') "ELF_S", ispin
1498 WRITE (title, *) "ELF spin ", ispin
1499 mpi_io = .true.
1500 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%ELF_CUBE", extension=".cube", &
1501 middle_name=trim(filename), file_position=my_pos_cube, log_filename=.false., &
1502 mpi_io=mpi_io, fout=mpi_filename)
1503 IF (output_unit > 0) THEN
1504 IF (.NOT. mpi_io) THEN
1505 INQUIRE (unit=unit_nr, name=filename)
1506 ELSE
1507 filename = mpi_filename
1508 END IF
1509 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
1510 "ELF is written in cube file format to the file:", &
1511 trim(filename)
1512 END IF
1513
1514 CALL cp_pw_to_cube(elf_r(ispin), unit_nr, title, particles=particles, &
1515 stride=section_get_ivals(elf_section, "STRIDE"), mpi_io=mpi_io)
1516 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%ELF_CUBE", mpi_io=mpi_io)
1517
1518 CALL auxbas_pw_pool%give_back_pw(elf_r(ispin))
1519 END DO
1520
1521 ! deallocate
1522 DEALLOCATE (elf_r)
1523
1524 ELSE
1525 ! not implemented
1526 cpwarn("ELF not implemented for GAPW calculations!")
1527 END IF
1528
1529 END IF ! print key
1530
1531 CALL timestop(handle)
1532
1533 END SUBROUTINE qs_scf_post_elf
1534
1535! **************************************************************************************************
1536!> \brief computes the condition number of the overlap matrix and
1537!> prints the value of the total energy. This is needed
1538!> for BASIS_MOLOPT optimizations
1539!> \param input ...
1540!> \param logger ...
1541!> \param qs_env the qs_env in which the qs_env lives
1542!> \par History
1543!> 2007-07 Created [Joost VandeVondele]
1544! **************************************************************************************************
1545 SUBROUTINE qs_scf_post_molopt(input, logger, qs_env)
1546 TYPE(section_vals_type), POINTER :: input
1547 TYPE(cp_logger_type), POINTER :: logger
1548 TYPE(qs_environment_type), POINTER :: qs_env
1549
1550 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_molopt'
1551
1552 INTEGER :: handle, nao, unit_nr
1553 REAL(kind=dp) :: s_cond_number
1554 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
1555 TYPE(cp_fm_struct_type), POINTER :: ao_ao_fmstruct
1556 TYPE(cp_fm_type) :: fm_s, fm_work
1557 TYPE(cp_fm_type), POINTER :: mo_coeff
1558 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1559 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1560 TYPE(qs_energy_type), POINTER :: energy
1561 TYPE(section_vals_type), POINTER :: print_key
1562
1563 CALL timeset(routinen, handle)
1564
1565 print_key => section_vals_get_subs_vals(section_vals=input, &
1566 subsection_name="DFT%PRINT%BASIS_MOLOPT_QUANTITIES")
1567 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), &
1568 cp_p_file)) THEN
1569
1570 CALL get_qs_env(qs_env, energy=energy, matrix_s=matrix_s, mos=mos)
1571
1572 ! set up the two needed full matrices, using mo_coeff as a template
1573 CALL get_mo_set(mo_set=mos(1), mo_coeff=mo_coeff, nao=nao)
1574 CALL cp_fm_struct_create(fmstruct=ao_ao_fmstruct, &
1575 nrow_global=nao, ncol_global=nao, &
1576 template_fmstruct=mo_coeff%matrix_struct)
1577 CALL cp_fm_create(fm_s, matrix_struct=ao_ao_fmstruct, &
1578 name="fm_s")
1579 CALL cp_fm_create(fm_work, matrix_struct=ao_ao_fmstruct, &
1580 name="fm_work")
1581 CALL cp_fm_struct_release(ao_ao_fmstruct)
1582 ALLOCATE (eigenvalues(nao))
1583
1584 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, fm_s)
1585 CALL choose_eigv_solver(fm_s, fm_work, eigenvalues)
1586
1587 CALL cp_fm_release(fm_s)
1588 CALL cp_fm_release(fm_work)
1589
1590 s_cond_number = maxval(abs(eigenvalues))/max(minval(abs(eigenvalues)), epsilon(0.0_dp))
1591
1592 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%BASIS_MOLOPT_QUANTITIES", &
1593 extension=".molopt")
1594
1595 IF (unit_nr > 0) THEN
1596 ! please keep this format fixed, needs to be grepable for molopt
1597 ! optimizations
1598 WRITE (unit_nr, '(T2,A28,2A25)') "", "Tot. Ener.", "S Cond. Numb."
1599 WRITE (unit_nr, '(T2,A28,2E25.17)') "BASIS_MOLOPT_QUANTITIES", energy%total, s_cond_number
1600 END IF
1601
1602 CALL cp_print_key_finished_output(unit_nr, logger, input, &
1603 "DFT%PRINT%BASIS_MOLOPT_QUANTITIES")
1604
1605 END IF
1606
1607 CALL timestop(handle)
1608
1609 END SUBROUTINE qs_scf_post_molopt
1610
1611! **************************************************************************************************
1612!> \brief Dumps EPR
1613!> \param input ...
1614!> \param logger ...
1615!> \param qs_env the qs_env in which the qs_env lives
1616! **************************************************************************************************
1617 SUBROUTINE qs_scf_post_epr(input, logger, qs_env)
1618 TYPE(section_vals_type), POINTER :: input
1619 TYPE(cp_logger_type), POINTER :: logger
1620 TYPE(qs_environment_type), POINTER :: qs_env
1621
1622 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_epr'
1623
1624 INTEGER :: handle
1625 TYPE(section_vals_type), POINTER :: print_key
1626
1627 CALL timeset(routinen, handle)
1628
1629 print_key => section_vals_get_subs_vals(section_vals=input, &
1630 subsection_name="DFT%PRINT%HYPERFINE_COUPLING_TENSOR")
1631 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), &
1632 cp_p_file)) THEN
1633 CALL qs_epr_hyp_calc(qs_env=qs_env)
1634 END IF
1635
1636 CALL timestop(handle)
1637
1638 END SUBROUTINE qs_scf_post_epr
1639
1640! **************************************************************************************************
1641!> \brief Interface routine to trigger writing of results available from normal
1642!> SCF. Can write MO-dependent and MO free results (needed for call from
1643!> the linear scaling code)
1644!> \param qs_env the qs_env in which the qs_env lives
1645!> \param scf_env ...
1646! **************************************************************************************************
1647 SUBROUTINE write_available_results(qs_env, scf_env)
1648 TYPE(qs_environment_type), POINTER :: qs_env
1649 TYPE(qs_scf_env_type), OPTIONAL, POINTER :: scf_env
1650
1651 CHARACTER(len=*), PARAMETER :: routinen = 'write_available_results'
1652
1653 INTEGER :: handle
1654
1655 CALL timeset(routinen, handle)
1656
1657 ! those properties that require MOs (not suitable density matrix based methods)
1658 CALL write_mo_dependent_results(qs_env, scf_env)
1659
1660 ! those that depend only on the density matrix, they should be linear scaling in their implementation
1661 CALL write_mo_free_results(qs_env)
1662
1663 CALL timestop(handle)
1664
1665 END SUBROUTINE write_available_results
1666
1667! **************************************************************************************************
1668!> \brief Write QS results available if MO's are present (if switched on through the print_keys)
1669!> Writes only MO dependent results. Split is necessary as ls_scf does not
1670!> provide MO's
1671!> \param qs_env the qs_env in which the qs_env lives
1672!> \param scf_env ...
1673! **************************************************************************************************
1674 SUBROUTINE write_mo_dependent_results(qs_env, scf_env)
1675 TYPE(qs_environment_type), POINTER :: qs_env
1676 TYPE(qs_scf_env_type), OPTIONAL, POINTER :: scf_env
1677
1678 CHARACTER(len=*), PARAMETER :: routinen = 'write_mo_dependent_results'
1679
1680 INTEGER :: handle, homo, ispin, nmo, output_unit
1681 LOGICAL :: all_equal, do_kpoints, explicit
1682 REAL(kind=dp) :: maxocc, s_square, s_square_ideal, &
1683 total_abs_spin_dens, total_spin_dens
1684 REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues, occupation_numbers
1685 TYPE(admm_type), POINTER :: admm_env
1686 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1687 TYPE(cell_type), POINTER :: cell
1688 TYPE(cp_fm_type), POINTER :: mo_coeff
1689 TYPE(cp_logger_type), POINTER :: logger
1690 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_rmpv, matrix_s
1691 TYPE(dbcsr_type), POINTER :: mo_coeff_deriv
1692 TYPE(dft_control_type), POINTER :: dft_control
1693 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
1694 TYPE(molecule_type), POINTER :: molecule_set(:)
1695 TYPE(particle_list_type), POINTER :: particles
1696 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1697 TYPE(pw_env_type), POINTER :: pw_env
1698 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
1699 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1700 TYPE(pw_r3d_rs_type) :: wf_r
1701 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
1702 TYPE(qs_energy_type), POINTER :: energy
1703 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1704 TYPE(qs_rho_type), POINTER :: rho
1705 TYPE(qs_subsys_type), POINTER :: subsys
1706 TYPE(scf_control_type), POINTER :: scf_control
1707 TYPE(section_vals_type), POINTER :: dft_section, input, sprint_section, &
1708 trexio_section
1709
1710! TYPE(kpoint_type), POINTER :: kpoints
1711
1712 CALL timeset(routinen, handle)
1713
1714 NULLIFY (cell, dft_control, pw_env, auxbas_pw_pool, pw_pools, mo_coeff, &
1715 mo_coeff_deriv, mo_eigenvalues, mos, atomic_kind_set, qs_kind_set, &
1716 particle_set, rho, ks_rmpv, matrix_s, scf_control, dft_section, &
1717 molecule_set, input, particles, subsys, rho_r)
1718
1719 logger => cp_get_default_logger()
1720 output_unit = cp_logger_get_default_io_unit(logger)
1721
1722 cpassert(ASSOCIATED(qs_env))
1723 CALL get_qs_env(qs_env, &
1724 dft_control=dft_control, &
1725 molecule_set=molecule_set, &
1726 atomic_kind_set=atomic_kind_set, &
1727 particle_set=particle_set, &
1728 qs_kind_set=qs_kind_set, &
1729 admm_env=admm_env, &
1730 scf_control=scf_control, &
1731 input=input, &
1732 cell=cell, &
1733 subsys=subsys)
1734 CALL qs_subsys_get(subsys, particles=particles)
1735 CALL get_qs_env(qs_env, rho=rho)
1736 CALL qs_rho_get(rho, rho_r=rho_r)
1737
1738 ! k points
1739 CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
1740
1741 ! Write last MO information to output file if requested
1742 dft_section => section_vals_get_subs_vals(input, "DFT")
1743 IF (.NOT. qs_env%run_rtp) THEN
1744 CALL qs_scf_write_mos(qs_env, scf_env, final_mos=.true.)
1745 trexio_section => section_vals_get_subs_vals(dft_section, "PRINT%TREXIO")
1746 CALL section_vals_get(trexio_section, explicit=explicit)
1747 IF (explicit) THEN
1748 CALL write_trexio(qs_env, trexio_section)
1749 END IF
1750 IF (.NOT. do_kpoints) THEN
1751 CALL get_qs_env(qs_env, mos=mos, matrix_ks=ks_rmpv)
1752 CALL write_dm_binary_restart(mos, dft_section, ks_rmpv)
1753 sprint_section => section_vals_get_subs_vals(dft_section, "PRINT%MO_MOLDEN")
1754 CALL write_mos_molden(mos, qs_kind_set, particle_set, sprint_section)
1755 ! Write Chargemol .wfx
1756 IF (btest(cp_print_key_should_output(logger%iter_info, &
1757 dft_section, "PRINT%CHARGEMOL"), &
1758 cp_p_file)) THEN
1759 CALL write_wfx(qs_env, dft_section)
1760 END IF
1761 END IF
1762
1763 ! DOS printout after the SCF cycle is completed
1764 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%DOS") &
1765 , cp_p_file)) THEN
1766 IF (do_kpoints) THEN
1767 CALL calculate_dos_kp(qs_env, dft_section)
1768 ELSE
1769 CALL get_qs_env(qs_env, mos=mos)
1770 CALL calculate_dos(mos, dft_section)
1771 END IF
1772 END IF
1773
1774 ! Print the projected density of states (pDOS) for each atomic kind
1775 IF (btest(cp_print_key_should_output(logger%iter_info, dft_section, "PRINT%PDOS"), &
1776 cp_p_file)) THEN
1777 IF (do_kpoints) THEN
1778 cpwarn("Projected density of states (pDOS) is not implemented for k points")
1779 ELSE
1780 CALL get_qs_env(qs_env, &
1781 mos=mos, &
1782 matrix_ks=ks_rmpv)
1783 DO ispin = 1, dft_control%nspins
1784 ! With ADMM, we have to modify the Kohn-Sham matrix
1785 IF (dft_control%do_admm) THEN
1786 CALL admm_correct_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
1787 END IF
1788 IF (PRESENT(scf_env)) THEN
1789 IF (scf_env%method == ot_method_nr) THEN
1790 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, &
1791 eigenvalues=mo_eigenvalues)
1792 IF (ASSOCIATED(qs_env%mo_derivs)) THEN
1793 mo_coeff_deriv => qs_env%mo_derivs(ispin)%matrix
1794 ELSE
1795 mo_coeff_deriv => null()
1796 END IF
1797 CALL calculate_subspace_eigenvalues(mo_coeff, ks_rmpv(ispin)%matrix, mo_eigenvalues, &
1798 do_rotation=.true., &
1799 co_rotate_dbcsr=mo_coeff_deriv)
1800 CALL set_mo_occupation(mo_set=mos(ispin))
1801 END IF
1802 END IF
1803 IF (dft_control%nspins == 2) THEN
1804 CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
1805 qs_kind_set, particle_set, qs_env, dft_section, ispin=ispin)
1806 ELSE
1807 CALL calculate_projected_dos(mos(ispin), atomic_kind_set, &
1808 qs_kind_set, particle_set, qs_env, dft_section)
1809 END IF
1810 ! With ADMM, we have to undo the modification of the Kohn-Sham matrix
1811 IF (dft_control%do_admm) THEN
1812 CALL admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_rmpv(ispin)%matrix)
1813 END IF
1814 END DO
1815 END IF
1816 END IF
1817 END IF
1818
1819 ! Integrated absolute spin density and spin contamination ***
1820 IF (dft_control%nspins == 2) THEN
1821 CALL get_qs_env(qs_env, mos=mos)
1822 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
1823 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1824 pw_pools=pw_pools)
1825 CALL auxbas_pw_pool%create_pw(wf_r)
1826 CALL pw_copy(rho_r(1), wf_r)
1827 CALL pw_axpy(rho_r(2), wf_r, alpha=-1._dp)
1828 total_spin_dens = pw_integrate_function(wf_r)
1829 IF (output_unit > 0) WRITE (unit=output_unit, fmt='(/,(T3,A,T61,F20.10))') &
1830 "Integrated spin density: ", total_spin_dens
1831 total_abs_spin_dens = pw_integrate_function(wf_r, oprt="ABS")
1832 IF (output_unit > 0) WRITE (unit=output_unit, fmt='((T3,A,T61,F20.10))') &
1833 "Integrated absolute spin density: ", total_abs_spin_dens
1834 CALL auxbas_pw_pool%give_back_pw(wf_r)
1835 !
1836 ! XXX Fix Me XXX
1837 ! should be extended to the case where added MOs are present
1838 ! should be extended to the k-point case
1839 !
1840 IF (do_kpoints) THEN
1841 cpwarn("Spin contamination estimate not implemented for k-points.")
1842 ELSE
1843 all_equal = .true.
1844 DO ispin = 1, dft_control%nspins
1845 CALL get_mo_set(mo_set=mos(ispin), &
1846 occupation_numbers=occupation_numbers, &
1847 homo=homo, &
1848 nmo=nmo, &
1849 maxocc=maxocc)
1850 IF (nmo > 0) THEN
1851 all_equal = all_equal .AND. &
1852 (all(occupation_numbers(1:homo) == maxocc) .AND. &
1853 all(occupation_numbers(homo + 1:nmo) == 0.0_dp))
1854 END IF
1855 END DO
1856 IF (.NOT. all_equal) THEN
1857 IF (output_unit > 0) WRITE (unit=output_unit, fmt="(T3,A)") &
1858 "WARNING: S**2 computation does not yet treat fractional occupied orbitals"
1859 ELSE
1860 CALL get_qs_env(qs_env=qs_env, &
1861 matrix_s=matrix_s, &
1862 energy=energy)
1863 CALL compute_s_square(mos=mos, matrix_s=matrix_s, s_square=s_square, &
1864 s_square_ideal=s_square_ideal)
1865 IF (output_unit > 0) WRITE (unit=output_unit, fmt='(T3,A,T51,2F15.6)') &
1866 "Ideal and single determinant S**2 : ", s_square_ideal, s_square
1867 energy%s_square = s_square
1868 END IF
1869 END IF
1870 END IF
1871
1872 CALL timestop(handle)
1873
1874 END SUBROUTINE write_mo_dependent_results
1875
1876! **************************************************************************************************
1877!> \brief Write QS results always available (if switched on through the print_keys)
1878!> Can be called from ls_scf
1879!> \param qs_env the qs_env in which the qs_env lives
1880! **************************************************************************************************
1881 SUBROUTINE write_mo_free_results(qs_env)
1882 TYPE(qs_environment_type), POINTER :: qs_env
1883
1884 CHARACTER(len=*), PARAMETER :: routinen = 'write_mo_free_results'
1885 CHARACTER(len=1), DIMENSION(3), PARAMETER :: cdir = ["x", "y", "z"]
1886
1887 CHARACTER(LEN=2) :: element_symbol
1888 CHARACTER(LEN=default_path_length) :: filename, mpi_filename, my_pos_cube, &
1889 my_pos_voro
1890 CHARACTER(LEN=default_string_length) :: name, print_density
1891 INTEGER :: after, handle, i, iat, iatom, id, ikind, img, iso, ispin, iw, l, n_rep_hf, nat, &
1892 natom, nd(3), ngto, niso, nkind, np, nr, output_unit, print_level, should_print_bqb, &
1893 should_print_voro, unit_nr, unit_nr_voro
1894 LOGICAL :: append_cube, append_voro, do_hfx, do_kpoints, mpi_io, omit_headers, print_it, &
1895 rho_r_valid, voro_print_txt, write_ks, write_xc, xrd_interface
1896 REAL(kind=dp) :: norm_factor, q_max, rho_hard, rho_soft, &
1897 rho_total, rho_total_rspace, udvol, &
1898 volume, zeff
1899 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: zcharge
1900 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: bfun
1901 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: aedens, ccdens, ppdens
1902 REAL(kind=dp), DIMENSION(3) :: dr
1903 REAL(kind=dp), DIMENSION(:), POINTER :: my_q0
1904 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1905 TYPE(atomic_kind_type), POINTER :: atomic_kind
1906 TYPE(cell_type), POINTER :: cell
1907 TYPE(cp_logger_type), POINTER :: logger
1908 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_hr
1909 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ks_rmpv, matrix_vxc, rho_ao
1910 TYPE(dft_control_type), POINTER :: dft_control
1911 TYPE(grid_atom_type), POINTER :: grid_atom
1912 TYPE(iao_env_type) :: iao_env
1913 TYPE(mp_para_env_type), POINTER :: para_env
1914 TYPE(particle_list_type), POINTER :: particles
1915 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1916 TYPE(pw_c1d_gs_type) :: aux_g, rho_elec_gspace
1917 TYPE(pw_c1d_gs_type), POINTER :: rho0_s_gs, rho_core, rhoz_cneo_s_gs
1918 TYPE(pw_env_type), POINTER :: pw_env
1919 TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
1920 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1921 TYPE(pw_r3d_rs_type) :: aux_r, rho_elec_rspace, wf_r
1922 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
1923 TYPE(pw_r3d_rs_type), POINTER :: mb_rho, v_hartree_rspace, vee
1924 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1925 TYPE(qs_kind_type), POINTER :: qs_kind
1926 TYPE(qs_rho_type), POINTER :: rho
1927 TYPE(qs_subsys_type), POINTER :: subsys
1928 TYPE(rho0_mpole_type), POINTER :: rho0_mpole
1929 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
1930 TYPE(rho_atom_type), POINTER :: rho_atom
1931 TYPE(section_vals_type), POINTER :: dft_section, hfx_section, input, &
1932 print_key, print_key_bqb, &
1933 print_key_voro, xc_section
1934
1935 CALL timeset(routinen, handle)
1936 NULLIFY (cell, dft_control, pw_env, auxbas_pw_pool, pw_pools, hfx_section, &
1937 atomic_kind_set, qs_kind_set, particle_set, rho, ks_rmpv, rho_ao, rho_r, &
1938 dft_section, xc_section, input, particles, subsys, matrix_vxc, v_hartree_rspace, &
1939 vee)
1940
1941 logger => cp_get_default_logger()
1942 output_unit = cp_logger_get_default_io_unit(logger)
1943
1944 cpassert(ASSOCIATED(qs_env))
1945 CALL get_qs_env(qs_env, &
1946 atomic_kind_set=atomic_kind_set, &
1947 qs_kind_set=qs_kind_set, &
1948 particle_set=particle_set, &
1949 cell=cell, &
1950 para_env=para_env, &
1951 dft_control=dft_control, &
1952 input=input, &
1953 do_kpoints=do_kpoints, &
1954 subsys=subsys)
1955 dft_section => section_vals_get_subs_vals(input, "DFT")
1956 CALL qs_subsys_get(subsys, particles=particles)
1957
1958 CALL get_qs_env(qs_env, rho=rho)
1959 CALL qs_rho_get(rho, rho_r=rho_r)
1960
1961 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
1962 ALLOCATE (zcharge(natom))
1963 DO ikind = 1, nkind
1964 CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
1965 CALL get_atomic_kind(atomic_kind_set(ikind), natom=nat)
1966 DO iatom = 1, nat
1967 iat = atomic_kind_set(ikind)%atom_list(iatom)
1968 zcharge(iat) = zeff
1969 END DO
1970 END DO
1971
1972 ! Print the total density (electronic + core charge)
1973 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
1974 "DFT%PRINT%TOT_DENSITY_CUBE"), cp_p_file)) THEN
1975 NULLIFY (rho_core, rho0_s_gs, rhoz_cneo_s_gs)
1976 append_cube = section_get_lval(input, "DFT%PRINT%TOT_DENSITY_CUBE%APPEND")
1977 my_pos_cube = "REWIND"
1978 IF (append_cube) THEN
1979 my_pos_cube = "APPEND"
1980 END IF
1981
1982 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho_core=rho_core, &
1983 rho0_s_gs=rho0_s_gs, rhoz_cneo_s_gs=rhoz_cneo_s_gs)
1984 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1985 pw_pools=pw_pools)
1986 CALL auxbas_pw_pool%create_pw(wf_r)
1987 IF (dft_control%qs_control%gapw) THEN
1988 IF (dft_control%qs_control%gapw_control%nopaw_as_gpw) THEN
1989 CALL pw_axpy(rho_core, rho0_s_gs)
1990 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
1991 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs)
1992 END IF
1993 CALL pw_transfer(rho0_s_gs, wf_r)
1994 CALL pw_axpy(rho_core, rho0_s_gs, -1.0_dp)
1995 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
1996 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs, -1.0_dp)
1997 END IF
1998 ELSE
1999 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2000 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs)
2001 END IF
2002 CALL pw_transfer(rho0_s_gs, wf_r)
2003 IF (ASSOCIATED(rhoz_cneo_s_gs)) THEN
2004 CALL pw_axpy(rhoz_cneo_s_gs, rho0_s_gs, -1.0_dp)
2005 END IF
2006 END IF
2007 ELSE
2008 CALL pw_transfer(rho_core, wf_r)
2009 END IF
2010 DO ispin = 1, dft_control%nspins
2011 CALL pw_axpy(rho_r(ispin), wf_r)
2012 END DO
2013 filename = "TOTAL_DENSITY"
2014 mpi_io = .true.
2015 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%TOT_DENSITY_CUBE", &
2016 extension=".cube", middle_name=trim(filename), file_position=my_pos_cube, &
2017 log_filename=.false., mpi_io=mpi_io)
2018 CALL cp_pw_to_cube(wf_r, unit_nr, "TOTAL DENSITY", &
2019 particles=particles, zeff=zcharge, &
2020 stride=section_get_ivals(dft_section, "PRINT%TOT_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2021 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2022 "DFT%PRINT%TOT_DENSITY_CUBE", mpi_io=mpi_io)
2023 CALL auxbas_pw_pool%give_back_pw(wf_r)
2024 END IF
2025
2026 ! Write cube file with electron density
2027 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
2028 "DFT%PRINT%E_DENSITY_CUBE"), cp_p_file)) THEN
2029 CALL section_vals_val_get(dft_section, &
2030 keyword_name="PRINT%E_DENSITY_CUBE%DENSITY_INCLUDE", &
2031 c_val=print_density)
2032 print_density = trim(print_density)
2033 append_cube = section_get_lval(input, "DFT%PRINT%E_DENSITY_CUBE%APPEND")
2034 my_pos_cube = "REWIND"
2035 IF (append_cube) THEN
2036 my_pos_cube = "APPEND"
2037 END IF
2038 ! Write the info on core densities for the interface between cp2k and the XRD code
2039 ! together with the valence density they are used to compute the form factor (Fourier transform)
2040 xrd_interface = section_get_lval(input, "DFT%PRINT%E_DENSITY_CUBE%XRD_INTERFACE")
2041 IF (xrd_interface) THEN
2042 !cube file only contains soft density (GAPW)
2043 IF (dft_control%qs_control%gapw) print_density = "SOFT_DENSITY"
2044
2045 filename = "ELECTRON_DENSITY"
2046 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2047 extension=".xrd", middle_name=trim(filename), &
2048 file_position=my_pos_cube, log_filename=.false.)
2049 ngto = section_get_ival(input, "DFT%PRINT%E_DENSITY_CUBE%NGAUSS")
2050 IF (output_unit > 0) THEN
2051 INQUIRE (unit=unit_nr, name=filename)
2052 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2053 "The electron density (atomic part) is written to the file:", &
2054 trim(filename)
2055 END IF
2056
2057 xc_section => section_vals_get_subs_vals(input, "DFT%XC")
2058 nkind = SIZE(atomic_kind_set)
2059 IF (unit_nr > 0) THEN
2060 WRITE (unit_nr, *) "Atomic (core) densities"
2061 WRITE (unit_nr, *) "Unit cell"
2062 WRITE (unit_nr, fmt="(3F20.12)") cell%hmat(1, 1), cell%hmat(1, 2), cell%hmat(1, 3)
2063 WRITE (unit_nr, fmt="(3F20.12)") cell%hmat(2, 1), cell%hmat(2, 2), cell%hmat(2, 3)
2064 WRITE (unit_nr, fmt="(3F20.12)") cell%hmat(3, 1), cell%hmat(3, 2), cell%hmat(3, 3)
2065 WRITE (unit_nr, *) "Atomic types"
2066 WRITE (unit_nr, *) nkind
2067 END IF
2068 ! calculate atomic density and core density
2069 ALLOCATE (ppdens(ngto, 2, nkind), aedens(ngto, 2, nkind), ccdens(ngto, 2, nkind))
2070 DO ikind = 1, nkind
2071 atomic_kind => atomic_kind_set(ikind)
2072 qs_kind => qs_kind_set(ikind)
2073 CALL get_atomic_kind(atomic_kind, name=name, element_symbol=element_symbol)
2074 CALL calculate_atomic_density(ppdens(:, :, ikind), atomic_kind, qs_kind, ngto, &
2075 iunit=output_unit, confine=.true.)
2076 CALL calculate_atomic_density(aedens(:, :, ikind), atomic_kind, qs_kind, ngto, &
2077 iunit=output_unit, allelectron=.true., confine=.true.)
2078 ccdens(:, 1, ikind) = aedens(:, 1, ikind)
2079 ccdens(:, 2, ikind) = 0._dp
2080 CALL project_function_a(ccdens(1:ngto, 2, ikind), ccdens(1:ngto, 1, ikind), &
2081 ppdens(1:ngto, 2, ikind), ppdens(1:ngto, 1, ikind), 0)
2082 ccdens(:, 2, ikind) = aedens(:, 2, ikind) - ccdens(:, 2, ikind)
2083 IF (unit_nr > 0) THEN
2084 WRITE (unit_nr, fmt="(I6,A10,A20)") ikind, trim(element_symbol), trim(name)
2085 WRITE (unit_nr, fmt="(I6)") ngto
2086 WRITE (unit_nr, *) " Total density"
2087 WRITE (unit_nr, fmt="(2G24.12)") (aedens(i, 1, ikind), aedens(i, 2, ikind), i=1, ngto)
2088 WRITE (unit_nr, *) " Core density"
2089 WRITE (unit_nr, fmt="(2G24.12)") (ccdens(i, 1, ikind), ccdens(i, 2, ikind), i=1, ngto)
2090 END IF
2091 NULLIFY (atomic_kind)
2092 END DO
2093
2094 IF (dft_control%qs_control%gapw) THEN
2095 CALL get_qs_env(qs_env=qs_env, rho_atom_set=rho_atom_set)
2096
2097 IF (unit_nr > 0) THEN
2098 WRITE (unit_nr, *) "Coordinates and GAPW density"
2099 END IF
2100 np = particles%n_els
2101 DO iat = 1, np
2102 CALL get_atomic_kind(particles%els(iat)%atomic_kind, kind_number=ikind)
2103 CALL get_qs_kind(qs_kind_set(ikind), grid_atom=grid_atom)
2104 rho_atom => rho_atom_set(iat)
2105 IF (ASSOCIATED(rho_atom%rho_rad_h(1)%r_coef)) THEN
2106 nr = SIZE(rho_atom%rho_rad_h(1)%r_coef, 1)
2107 niso = SIZE(rho_atom%rho_rad_h(1)%r_coef, 2)
2108 ELSE
2109 nr = 0
2110 niso = 0
2111 END IF
2112 CALL para_env%sum(nr)
2113 CALL para_env%sum(niso)
2114
2115 ALLOCATE (bfun(nr, niso))
2116 bfun = 0._dp
2117 DO ispin = 1, dft_control%nspins
2118 IF (ASSOCIATED(rho_atom%rho_rad_h(1)%r_coef)) THEN
2119 bfun(:, :) = bfun + rho_atom%rho_rad_h(ispin)%r_coef - rho_atom%rho_rad_s(ispin)%r_coef
2120 END IF
2121 END DO
2122 CALL para_env%sum(bfun)
2123 ccdens(:, 1, ikind) = ppdens(:, 1, ikind)
2124 ccdens(:, 2, ikind) = 0._dp
2125 IF (unit_nr > 0) THEN
2126 WRITE (unit_nr, '(I10,I5,3f12.6)') iat, ikind, particles%els(iat)%r
2127 END IF
2128 DO iso = 1, niso
2129 l = indso(1, iso)
2130 CALL project_function_b(ccdens(:, 2, ikind), ccdens(:, 1, ikind), bfun(:, iso), grid_atom, l)
2131 IF (unit_nr > 0) THEN
2132 WRITE (unit_nr, fmt="(3I6)") iso, l, ngto
2133 WRITE (unit_nr, fmt="(2G24.12)") (ccdens(i, 1, ikind), ccdens(i, 2, ikind), i=1, ngto)
2134 END IF
2135 END DO
2136 DEALLOCATE (bfun)
2137 END DO
2138 ELSE
2139 IF (unit_nr > 0) THEN
2140 WRITE (unit_nr, *) "Coordinates"
2141 np = particles%n_els
2142 DO iat = 1, np
2143 CALL get_atomic_kind(particles%els(iat)%atomic_kind, kind_number=ikind)
2144 WRITE (unit_nr, '(I10,I5,3f12.6)') iat, ikind, particles%els(iat)%r
2145 END DO
2146 END IF
2147 END IF
2148
2149 DEALLOCATE (ppdens, aedens, ccdens)
2150
2151 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2152 "DFT%PRINT%E_DENSITY_CUBE")
2153
2154 END IF
2155 IF (dft_control%qs_control%gapw .AND. print_density == "TOTAL_DENSITY") THEN
2156 ! total density in g-space not implemented for k-points
2157 cpassert(.NOT. do_kpoints)
2158 ! Print total electronic density
2159 CALL get_qs_env(qs_env=qs_env, &
2160 pw_env=pw_env)
2161 CALL pw_env_get(pw_env=pw_env, &
2162 auxbas_pw_pool=auxbas_pw_pool, &
2163 pw_pools=pw_pools)
2164 CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
2165 CALL pw_zero(rho_elec_rspace)
2166 CALL auxbas_pw_pool%create_pw(pw=rho_elec_gspace)
2167 CALL pw_zero(rho_elec_gspace)
2168 CALL get_pw_grid_info(pw_grid=rho_elec_gspace%pw_grid, &
2169 dr=dr, &
2170 vol=volume)
2171 q_max = sqrt(sum((pi/dr(:))**2))
2172 CALL calculate_rhotot_elec_gspace(qs_env=qs_env, &
2173 auxbas_pw_pool=auxbas_pw_pool, &
2174 rhotot_elec_gspace=rho_elec_gspace, &
2175 q_max=q_max, &
2176 rho_hard=rho_hard, &
2177 rho_soft=rho_soft)
2178 rho_total = rho_hard + rho_soft
2179 CALL get_pw_grid_info(pw_grid=rho_elec_gspace%pw_grid, &
2180 vol=volume)
2181 ! rhotot pw coefficients are by default scaled by grid volume
2182 ! need to undo this to get proper charge from printed cube
2183 CALL pw_scale(rho_elec_gspace, 1.0_dp/volume)
2184
2185 CALL pw_transfer(rho_elec_gspace, rho_elec_rspace)
2186 rho_total_rspace = pw_integrate_function(rho_elec_rspace, isign=-1)
2187 filename = "TOTAL_ELECTRON_DENSITY"
2188 mpi_io = .true.
2189 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2190 extension=".cube", middle_name=trim(filename), &
2191 file_position=my_pos_cube, log_filename=.false., mpi_io=mpi_io, &
2192 fout=mpi_filename)
2193 IF (output_unit > 0) THEN
2194 IF (.NOT. mpi_io) THEN
2195 INQUIRE (unit=unit_nr, name=filename)
2196 ELSE
2197 filename = mpi_filename
2198 END IF
2199 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2200 "The total electron density is written in cube file format to the file:", &
2201 trim(filename)
2202 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
2203 "q(max) [1/Angstrom] :", q_max/angstrom, &
2204 "Soft electronic charge (G-space) :", rho_soft, &
2205 "Hard electronic charge (G-space) :", rho_hard, &
2206 "Total electronic charge (G-space):", rho_total, &
2207 "Total electronic charge (R-space):", rho_total_rspace
2208 END IF
2209 CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "TOTAL ELECTRON DENSITY", &
2210 particles=particles, zeff=zcharge, &
2211 stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2212 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2213 "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2214 ! Print total spin density for spin-polarized systems
2215 IF (dft_control%nspins > 1) THEN
2216 CALL pw_zero(rho_elec_gspace)
2217 CALL pw_zero(rho_elec_rspace)
2218 CALL calculate_rhotot_elec_gspace(qs_env=qs_env, &
2219 auxbas_pw_pool=auxbas_pw_pool, &
2220 rhotot_elec_gspace=rho_elec_gspace, &
2221 q_max=q_max, &
2222 rho_hard=rho_hard, &
2223 rho_soft=rho_soft, &
2224 fsign=-1.0_dp)
2225 rho_total = rho_hard + rho_soft
2226
2227 ! rhotot pw coefficients are by default scaled by grid volume
2228 ! need to undo this to get proper charge from printed cube
2229 CALL pw_scale(rho_elec_gspace, 1.0_dp/volume)
2230
2231 CALL pw_transfer(rho_elec_gspace, rho_elec_rspace)
2232 rho_total_rspace = pw_integrate_function(rho_elec_rspace, isign=-1)
2233 filename = "TOTAL_SPIN_DENSITY"
2234 mpi_io = .true.
2235 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2236 extension=".cube", middle_name=trim(filename), &
2237 file_position=my_pos_cube, log_filename=.false., mpi_io=mpi_io, &
2238 fout=mpi_filename)
2239 IF (output_unit > 0) THEN
2240 IF (.NOT. mpi_io) THEN
2241 INQUIRE (unit=unit_nr, name=filename)
2242 ELSE
2243 filename = mpi_filename
2244 END IF
2245 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2246 "The total spin density is written in cube file format to the file:", &
2247 trim(filename)
2248 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
2249 "q(max) [1/Angstrom] :", q_max/angstrom, &
2250 "Soft part of the spin density (G-space):", rho_soft, &
2251 "Hard part of the spin density (G-space):", rho_hard, &
2252 "Total spin density (G-space) :", rho_total, &
2253 "Total spin density (R-space) :", rho_total_rspace
2254 END IF
2255 CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "TOTAL SPIN DENSITY", &
2256 particles=particles, zeff=zcharge, &
2257 stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2258 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2259 "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2260 END IF
2261 CALL auxbas_pw_pool%give_back_pw(rho_elec_gspace)
2262 CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
2263
2264 ELSE IF (print_density == "SOFT_DENSITY" .OR. .NOT. dft_control%qs_control%gapw) THEN
2265 IF (dft_control%nspins > 1) THEN
2266 CALL get_qs_env(qs_env=qs_env, &
2267 pw_env=pw_env)
2268 CALL pw_env_get(pw_env=pw_env, &
2269 auxbas_pw_pool=auxbas_pw_pool, &
2270 pw_pools=pw_pools)
2271 CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
2272 CALL pw_copy(rho_r(1), rho_elec_rspace)
2273 CALL pw_axpy(rho_r(2), rho_elec_rspace)
2274 filename = "ELECTRON_DENSITY"
2275 mpi_io = .true.
2276 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2277 extension=".cube", middle_name=trim(filename), &
2278 file_position=my_pos_cube, log_filename=.false., mpi_io=mpi_io, &
2279 fout=mpi_filename)
2280 IF (output_unit > 0) THEN
2281 IF (.NOT. mpi_io) THEN
2282 INQUIRE (unit=unit_nr, name=filename)
2283 ELSE
2284 filename = mpi_filename
2285 END IF
2286 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2287 "The sum of alpha and beta density is written in cube file format to the file:", &
2288 trim(filename)
2289 END IF
2290 CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "SUM OF ALPHA AND BETA DENSITY", &
2291 particles=particles, zeff=zcharge, &
2292 stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), &
2293 mpi_io=mpi_io)
2294 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2295 "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2296 CALL pw_copy(rho_r(1), rho_elec_rspace)
2297 CALL pw_axpy(rho_r(2), rho_elec_rspace, alpha=-1.0_dp)
2298 filename = "SPIN_DENSITY"
2299 mpi_io = .true.
2300 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2301 extension=".cube", middle_name=trim(filename), &
2302 file_position=my_pos_cube, log_filename=.false., mpi_io=mpi_io, &
2303 fout=mpi_filename)
2304 IF (output_unit > 0) THEN
2305 IF (.NOT. mpi_io) THEN
2306 INQUIRE (unit=unit_nr, name=filename)
2307 ELSE
2308 filename = mpi_filename
2309 END IF
2310 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2311 "The spin density is written in cube file format to the file:", &
2312 trim(filename)
2313 END IF
2314 CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "SPIN DENSITY", &
2315 particles=particles, zeff=zcharge, &
2316 stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2317 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2318 "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2319 CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
2320 ELSE
2321 filename = "ELECTRON_DENSITY"
2322 mpi_io = .true.
2323 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2324 extension=".cube", middle_name=trim(filename), &
2325 file_position=my_pos_cube, log_filename=.false., mpi_io=mpi_io, &
2326 fout=mpi_filename)
2327 IF (output_unit > 0) THEN
2328 IF (.NOT. mpi_io) THEN
2329 INQUIRE (unit=unit_nr, name=filename)
2330 ELSE
2331 filename = mpi_filename
2332 END IF
2333 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2334 "The electron density is written in cube file format to the file:", &
2335 trim(filename)
2336 END IF
2337 CALL cp_pw_to_cube(rho_r(1), unit_nr, "ELECTRON DENSITY", &
2338 particles=particles, zeff=zcharge, &
2339 stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2340 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2341 "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2342 END IF ! nspins
2343
2344 ELSE IF (dft_control%qs_control%gapw .AND. print_density == "TOTAL_HARD_APPROX") THEN
2345 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho0_mpole=rho0_mpole, natom=natom)
2346 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, pw_pools=pw_pools)
2347 CALL auxbas_pw_pool%create_pw(rho_elec_rspace)
2348
2349 NULLIFY (my_q0)
2350 ALLOCATE (my_q0(natom))
2351 my_q0 = 0.0_dp
2352
2353 ! (eta/pi)**3: normalization for 3d gaussian of form exp(-eta*r**2)
2354 norm_factor = sqrt((rho0_mpole%zet0_h/pi)**3)
2355
2356 ! store hard part of electronic density in array
2357 DO iat = 1, natom
2358 my_q0(iat) = sum(rho0_mpole%mp_rho(iat)%Q0(1:dft_control%nspins))*norm_factor
2359 END DO
2360 ! multiply coeff with gaussian and put on realspace grid
2361 ! coeff is the gaussian prefactor, eta the gaussian exponent
2362 CALL calculate_rho_resp_all(rho_elec_rspace, coeff=my_q0, natom=natom, eta=rho0_mpole%zet0_h, qs_env=qs_env)
2363 rho_hard = pw_integrate_function(rho_elec_rspace, isign=-1)
2364
2365 rho_soft = 0.0_dp
2366 DO ispin = 1, dft_control%nspins
2367 CALL pw_axpy(rho_r(ispin), rho_elec_rspace)
2368 rho_soft = rho_soft + pw_integrate_function(rho_r(ispin), isign=-1)
2369 END DO
2370
2371 rho_total_rspace = rho_soft + rho_hard
2372
2373 filename = "ELECTRON_DENSITY"
2374 mpi_io = .true.
2375 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2376 extension=".cube", middle_name=trim(filename), &
2377 file_position=my_pos_cube, log_filename=.false., mpi_io=mpi_io, &
2378 fout=mpi_filename)
2379 IF (output_unit > 0) THEN
2380 IF (.NOT. mpi_io) THEN
2381 INQUIRE (unit=unit_nr, name=filename)
2382 ELSE
2383 filename = mpi_filename
2384 END IF
2385 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2386 "The electron density is written in cube file format to the file:", &
2387 trim(filename)
2388 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
2389 "Soft electronic charge (R-space) :", rho_soft, &
2390 "Hard electronic charge (R-space) :", rho_hard, &
2391 "Total electronic charge (R-space):", rho_total_rspace
2392 END IF
2393 CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "ELECTRON DENSITY", &
2394 particles=particles, zeff=zcharge, &
2395 stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), &
2396 mpi_io=mpi_io)
2397 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2398 "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2399
2400 !------------
2401 IF (dft_control%nspins > 1) THEN
2402 DO iat = 1, natom
2403 my_q0(iat) = (rho0_mpole%mp_rho(iat)%Q0(1) - rho0_mpole%mp_rho(iat)%Q0(2))*norm_factor
2404 END DO
2405 CALL pw_zero(rho_elec_rspace)
2406 CALL calculate_rho_resp_all(rho_elec_rspace, coeff=my_q0, natom=natom, eta=rho0_mpole%zet0_h, qs_env=qs_env)
2407 rho_hard = pw_integrate_function(rho_elec_rspace, isign=-1)
2408
2409 CALL pw_axpy(rho_r(1), rho_elec_rspace)
2410 CALL pw_axpy(rho_r(2), rho_elec_rspace, alpha=-1.0_dp)
2411 rho_soft = pw_integrate_function(rho_r(1), isign=-1) &
2412 - pw_integrate_function(rho_r(2), isign=-1)
2413
2414 rho_total_rspace = rho_soft + rho_hard
2415
2416 filename = "SPIN_DENSITY"
2417 mpi_io = .true.
2418 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%E_DENSITY_CUBE", &
2419 extension=".cube", middle_name=trim(filename), &
2420 file_position=my_pos_cube, log_filename=.false., mpi_io=mpi_io, &
2421 fout=mpi_filename)
2422 IF (output_unit > 0) THEN
2423 IF (.NOT. mpi_io) THEN
2424 INQUIRE (unit=unit_nr, name=filename)
2425 ELSE
2426 filename = mpi_filename
2427 END IF
2428 WRITE (unit=output_unit, fmt="(/,T2,A,/,/,T2,A)") &
2429 "The spin density is written in cube file format to the file:", &
2430 trim(filename)
2431 WRITE (unit=output_unit, fmt="(/,(T2,A,F20.10))") &
2432 "Soft part of the spin density :", rho_soft, &
2433 "Hard part of the spin density :", rho_hard, &
2434 "Total spin density (R-space) :", rho_total_rspace
2435 END IF
2436 CALL cp_pw_to_cube(rho_elec_rspace, unit_nr, "SPIN DENSITY", &
2437 particles=particles, zeff=zcharge, &
2438 stride=section_get_ivals(dft_section, "PRINT%E_DENSITY_CUBE%STRIDE"), mpi_io=mpi_io)
2439 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2440 "DFT%PRINT%E_DENSITY_CUBE", mpi_io=mpi_io)
2441 END IF ! nspins
2442 CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
2443 DEALLOCATE (my_q0)
2444 END IF ! print_density
2445 END IF ! print key
2446
2447 IF (btest(cp_print_key_should_output(logger%iter_info, &
2448 dft_section, "PRINT%ENERGY_WINDOWS"), cp_p_file) .AND. .NOT. do_kpoints) THEN
2449 CALL energy_windows(qs_env)
2450 END IF
2451
2452 ! Print the hartree potential
2453 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
2454 "DFT%PRINT%V_HARTREE_CUBE"), cp_p_file)) THEN
2455
2456 CALL get_qs_env(qs_env=qs_env, &
2457 pw_env=pw_env, &
2458 v_hartree_rspace=v_hartree_rspace)
2459 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2460 CALL auxbas_pw_pool%create_pw(aux_r)
2461
2462 append_cube = section_get_lval(input, "DFT%PRINT%V_HARTREE_CUBE%APPEND")
2463 my_pos_cube = "REWIND"
2464 IF (append_cube) THEN
2465 my_pos_cube = "APPEND"
2466 END IF
2467 mpi_io = .true.
2468 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
2469 CALL pw_env_get(pw_env)
2470 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%V_HARTREE_CUBE", &
2471 extension=".cube", middle_name="v_hartree", file_position=my_pos_cube, mpi_io=mpi_io)
2472 udvol = 1.0_dp/v_hartree_rspace%pw_grid%dvol
2473
2474 CALL pw_copy(v_hartree_rspace, aux_r)
2475 CALL pw_scale(aux_r, udvol)
2476
2477 CALL cp_pw_to_cube(aux_r, unit_nr, "HARTREE POTENTIAL", particles=particles, zeff=zcharge, &
2478 stride=section_get_ivals(dft_section, &
2479 "PRINT%V_HARTREE_CUBE%STRIDE"), mpi_io=mpi_io)
2480 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2481 "DFT%PRINT%V_HARTREE_CUBE", mpi_io=mpi_io)
2482
2483 CALL auxbas_pw_pool%give_back_pw(aux_r)
2484 END IF
2485
2486 ! Print the external potential
2487 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
2488 "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE"), cp_p_file)) THEN
2489 IF (dft_control%apply_external_potential) THEN
2490 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, vee=vee)
2491 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2492 CALL auxbas_pw_pool%create_pw(aux_r)
2493
2494 append_cube = section_get_lval(input, "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE%APPEND")
2495 my_pos_cube = "REWIND"
2496 IF (append_cube) THEN
2497 my_pos_cube = "APPEND"
2498 END IF
2499 mpi_io = .true.
2500 CALL pw_env_get(pw_env)
2501 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE", &
2502 extension=".cube", middle_name="ext_pot", file_position=my_pos_cube, mpi_io=mpi_io)
2503
2504 CALL pw_copy(vee, aux_r)
2505
2506 CALL cp_pw_to_cube(aux_r, unit_nr, "EXTERNAL POTENTIAL", particles=particles, zeff=zcharge, &
2507 stride=section_get_ivals(dft_section, &
2508 "PRINT%EXTERNAL_POTENTIAL_CUBE%STRIDE"), mpi_io=mpi_io)
2509 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2510 "DFT%PRINT%EXTERNAL_POTENTIAL_CUBE", mpi_io=mpi_io)
2511
2512 CALL auxbas_pw_pool%give_back_pw(aux_r)
2513 END IF
2514 END IF
2515
2516 ! Print the Electrical Field Components
2517 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
2518 "DFT%PRINT%EFIELD_CUBE"), cp_p_file)) THEN
2519
2520 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
2521 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2522 CALL auxbas_pw_pool%create_pw(aux_r)
2523 CALL auxbas_pw_pool%create_pw(aux_g)
2524
2525 append_cube = section_get_lval(input, "DFT%PRINT%EFIELD_CUBE%APPEND")
2526 my_pos_cube = "REWIND"
2527 IF (append_cube) THEN
2528 my_pos_cube = "APPEND"
2529 END IF
2530 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, &
2531 v_hartree_rspace=v_hartree_rspace)
2532 CALL pw_env_get(pw_env)
2533 udvol = 1.0_dp/v_hartree_rspace%pw_grid%dvol
2534 DO id = 1, 3
2535 mpi_io = .true.
2536 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EFIELD_CUBE", &
2537 extension=".cube", middle_name="efield_"//cdir(id), file_position=my_pos_cube, &
2538 mpi_io=mpi_io)
2539
2540 CALL pw_transfer(v_hartree_rspace, aux_g)
2541 nd = 0
2542 nd(id) = 1
2543 CALL pw_derive(aux_g, nd)
2544 CALL pw_transfer(aux_g, aux_r)
2545 CALL pw_scale(aux_r, udvol)
2546
2547 CALL cp_pw_to_cube(aux_r, &
2548 unit_nr, "ELECTRIC FIELD", particles=particles, zeff=zcharge, &
2549 stride=section_get_ivals(dft_section, &
2550 "PRINT%EFIELD_CUBE%STRIDE"), mpi_io=mpi_io)
2551 CALL cp_print_key_finished_output(unit_nr, logger, input, &
2552 "DFT%PRINT%EFIELD_CUBE", mpi_io=mpi_io)
2553 END DO
2554
2555 CALL auxbas_pw_pool%give_back_pw(aux_r)
2556 CALL auxbas_pw_pool%give_back_pw(aux_g)
2557 END IF
2558
2559 ! Write cube files from the local energy
2560 CALL qs_scf_post_local_energy(input, logger, qs_env)
2561
2562 ! Write cube files from the local stress tensor
2563 CALL qs_scf_post_local_stress(input, logger, qs_env)
2564
2565 ! Write cube files from the implicit Poisson solver
2566 CALL qs_scf_post_ps_implicit(input, logger, qs_env)
2567
2568 ! post SCF Transport
2569 CALL qs_scf_post_transport(qs_env)
2570
2571 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%OMIT_HEADERS", l_val=omit_headers)
2572 ! Write the density matrices
2573 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
2574 "DFT%PRINT%AO_MATRICES/DENSITY"), cp_p_file)) THEN
2575 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/DENSITY", &
2576 extension=".Log")
2577 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2578 CALL qs_rho_get(rho, rho_ao_kp=rho_ao)
2579 after = min(max(after, 1), 16)
2580 DO ispin = 1, dft_control%nspins
2581 DO img = 1, dft_control%nimages
2582 CALL cp_dbcsr_write_sparse_matrix(rho_ao(ispin, img)%matrix, 4, after, qs_env, &
2583 para_env, output_unit=iw, omit_headers=omit_headers)
2584 END DO
2585 END DO
2586 CALL cp_print_key_finished_output(iw, logger, input, &
2587 "DFT%PRINT%AO_MATRICES/DENSITY")
2588 END IF
2589
2590 ! Write the Kohn-Sham matrices
2591 write_ks = btest(cp_print_key_should_output(logger%iter_info, input, &
2592 "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX"), cp_p_file)
2593 write_xc = btest(cp_print_key_should_output(logger%iter_info, input, &
2594 "DFT%PRINT%AO_MATRICES/MATRIX_VXC"), cp_p_file)
2595 ! we need to update stuff before writing, potentially computing the matrix_vxc
2596 IF (write_ks .OR. write_xc) THEN
2597 IF (write_xc) qs_env%requires_matrix_vxc = .true.
2598 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.)
2599 CALL qs_ks_update_qs_env(qs_env, calculate_forces=.false., &
2600 just_energy=.false.)
2601 IF (write_xc) qs_env%requires_matrix_vxc = .false.
2602 END IF
2603
2604 ! Write the Kohn-Sham matrices
2605 IF (write_ks) THEN
2606 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX", &
2607 extension=".Log")
2608 CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=ks_rmpv)
2609 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2610 after = min(max(after, 1), 16)
2611 DO ispin = 1, dft_control%nspins
2612 DO img = 1, dft_control%nimages
2613 CALL cp_dbcsr_write_sparse_matrix(ks_rmpv(ispin, img)%matrix, 4, after, qs_env, &
2614 para_env, output_unit=iw, omit_headers=omit_headers)
2615 END DO
2616 END DO
2617 CALL cp_print_key_finished_output(iw, logger, input, &
2618 "DFT%PRINT%AO_MATRICES/KOHN_SHAM_MATRIX")
2619 END IF
2620
2621 ! write csr matrices
2622 ! matrices in terms of the PAO basis will be taken care of in pao_post_scf.
2623 IF (.NOT. dft_control%qs_control%pao) THEN
2624 CALL write_ks_matrix_csr(qs_env, input)
2625 CALL write_s_matrix_csr(qs_env, input)
2626 CALL write_hcore_matrix_csr(qs_env, input)
2627 CALL write_p_matrix_csr(qs_env, input)
2628 END IF
2629
2630 ! write adjacency matrix
2631 CALL write_adjacency_matrix(qs_env, input)
2632
2633 ! Write the xc matrix
2634 IF (write_xc) THEN
2635 CALL get_qs_env(qs_env=qs_env, matrix_vxc_kp=matrix_vxc)
2636 cpassert(ASSOCIATED(matrix_vxc))
2637 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/MATRIX_VXC", &
2638 extension=".Log")
2639 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2640 after = min(max(after, 1), 16)
2641 DO ispin = 1, dft_control%nspins
2642 DO img = 1, dft_control%nimages
2643 CALL cp_dbcsr_write_sparse_matrix(matrix_vxc(ispin, img)%matrix, 4, after, qs_env, &
2644 para_env, output_unit=iw, omit_headers=omit_headers)
2645 END DO
2646 END DO
2647 CALL cp_print_key_finished_output(iw, logger, input, &
2648 "DFT%PRINT%AO_MATRICES/MATRIX_VXC")
2649 END IF
2650
2651 ! Write the [H,r] commutator matrices
2652 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
2653 "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR"), cp_p_file)) THEN
2654 iw = cp_print_key_unit_nr(logger, input, "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR", &
2655 extension=".Log")
2656 CALL section_vals_val_get(input, "DFT%PRINT%AO_MATRICES%NDIGITS", i_val=after)
2657 NULLIFY (matrix_hr)
2658 CALL build_com_hr_matrix(qs_env, matrix_hr)
2659 after = min(max(after, 1), 16)
2660 DO img = 1, 3
2661 CALL cp_dbcsr_write_sparse_matrix(matrix_hr(img)%matrix, 4, after, qs_env, &
2662 para_env, output_unit=iw, omit_headers=omit_headers)
2663 END DO
2664 CALL dbcsr_deallocate_matrix_set(matrix_hr)
2665 CALL cp_print_key_finished_output(iw, logger, input, &
2666 "DFT%PRINT%AO_MATRICES/COMMUTATOR_HR")
2667 END IF
2668
2669 ! Compute the Mulliken charges
2670 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MULLIKEN")
2671 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2672 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MULLIKEN", extension=".mulliken", log_filename=.false.)
2673 print_level = 1
2674 CALL section_vals_val_get(print_key, "PRINT_GOP", l_val=print_it)
2675 IF (print_it) print_level = 2
2676 CALL section_vals_val_get(print_key, "PRINT_ALL", l_val=print_it)
2677 IF (print_it) print_level = 3
2678 CALL mulliken_population_analysis(qs_env, unit_nr, print_level)
2679 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MULLIKEN")
2680 END IF
2681
2682 ! Compute the Hirshfeld charges
2683 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%HIRSHFELD")
2684 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2685 ! we check if real space density is available
2686 NULLIFY (rho)
2687 CALL get_qs_env(qs_env=qs_env, rho=rho)
2688 CALL qs_rho_get(rho, rho_r_valid=rho_r_valid)
2689 IF (rho_r_valid) THEN
2690 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%HIRSHFELD", extension=".hirshfeld", log_filename=.false.)
2691 CALL hirshfeld_charges(qs_env, print_key, unit_nr)
2692 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%HIRSHFELD")
2693 END IF
2694 END IF
2695
2696 ! Compute EEQ charges
2697 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%EEQ_CHARGES")
2698 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2699 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%EEQ_CHARGES", extension=".eeq", log_filename=.false.)
2700 print_level = 1
2701 CALL eeq_print(qs_env, unit_nr, print_level, ext=.false.)
2702 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MULLIKEN")
2703 END IF
2704
2705 ! Do a Voronoi Integration or write a compressed BQB File
2706 print_key_voro => section_vals_get_subs_vals(input, "DFT%PRINT%VORONOI")
2707 print_key_bqb => section_vals_get_subs_vals(input, "DFT%PRINT%E_DENSITY_BQB")
2708 IF (btest(cp_print_key_should_output(logger%iter_info, print_key_voro), cp_p_file)) THEN
2709 should_print_voro = 1
2710 ELSE
2711 should_print_voro = 0
2712 END IF
2713 IF (btest(cp_print_key_should_output(logger%iter_info, print_key_bqb), cp_p_file)) THEN
2714 should_print_bqb = 1
2715 ELSE
2716 should_print_bqb = 0
2717 END IF
2718 IF ((should_print_voro /= 0) .OR. (should_print_bqb /= 0)) THEN
2719
2720 ! we check if real space density is available
2721 NULLIFY (rho)
2722 CALL get_qs_env(qs_env=qs_env, rho=rho)
2723 CALL qs_rho_get(rho, rho_r_valid=rho_r_valid)
2724 IF (rho_r_valid) THEN
2725
2726 IF (dft_control%nspins > 1) THEN
2727 CALL get_qs_env(qs_env=qs_env, &
2728 pw_env=pw_env)
2729 CALL pw_env_get(pw_env=pw_env, &
2730 auxbas_pw_pool=auxbas_pw_pool, &
2731 pw_pools=pw_pools)
2732 NULLIFY (mb_rho)
2733 ALLOCATE (mb_rho)
2734 CALL auxbas_pw_pool%create_pw(pw=mb_rho)
2735 CALL pw_copy(rho_r(1), mb_rho)
2736 CALL pw_axpy(rho_r(2), mb_rho)
2737 !CALL voronoi_analysis(qs_env, rho_elec_rspace, print_key, unit_nr)
2738 ELSE
2739 mb_rho => rho_r(1)
2740 !CALL voronoi_analysis( qs_env, rho_r(1), print_key, unit_nr )
2741 END IF ! nspins
2742
2743 IF (should_print_voro /= 0) THEN
2744 CALL section_vals_val_get(print_key_voro, "OUTPUT_TEXT", l_val=voro_print_txt)
2745 IF (voro_print_txt) THEN
2746 append_voro = section_get_lval(input, "DFT%PRINT%VORONOI%APPEND")
2747 my_pos_voro = "REWIND"
2748 IF (append_voro) THEN
2749 my_pos_voro = "APPEND"
2750 END IF
2751 unit_nr_voro = cp_print_key_unit_nr(logger, input, "DFT%PRINT%VORONOI", extension=".voronoi", &
2752 file_position=my_pos_voro, log_filename=.false.)
2753 ELSE
2754 unit_nr_voro = 0
2755 END IF
2756 ELSE
2757 unit_nr_voro = 0
2758 END IF
2759
2760 CALL entry_voronoi_or_bqb(should_print_voro, should_print_bqb, print_key_voro, print_key_bqb, &
2761 unit_nr_voro, qs_env, mb_rho)
2762
2763 IF (dft_control%nspins > 1) THEN
2764 CALL auxbas_pw_pool%give_back_pw(mb_rho)
2765 DEALLOCATE (mb_rho)
2766 END IF
2767
2768 IF (unit_nr_voro > 0) THEN
2769 CALL cp_print_key_finished_output(unit_nr_voro, logger, input, "DFT%PRINT%VORONOI")
2770 END IF
2771
2772 END IF
2773 END IF
2774
2775 ! MAO analysis
2776 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MAO_ANALYSIS")
2777 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2778 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MAO_ANALYSIS", extension=".mao", log_filename=.false.)
2779 CALL mao_analysis(qs_env, print_key, unit_nr)
2780 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MAO_ANALYSIS")
2781 END IF
2782
2783 ! MINBAS analysis
2784 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%MINBAS_ANALYSIS")
2785 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2786 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%MINBAS_ANALYSIS", extension=".mao", log_filename=.false.)
2787 CALL minbas_analysis(qs_env, print_key, unit_nr)
2788 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%MINBAS_ANALYSIS")
2789 END IF
2790
2791 ! IAO analysis
2792 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%IAO_ANALYSIS")
2793 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2794 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IAO_ANALYSIS", extension=".iao", log_filename=.false.)
2795 CALL iao_read_input(iao_env, print_key, cell)
2796 IF (iao_env%do_iao) THEN
2797 CALL iao_wfn_analysis(qs_env, iao_env, unit_nr)
2798 END IF
2799 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%IAO_ANALYSIS")
2800 END IF
2801
2802 ! Energy Decomposition Analysis
2803 print_key => section_vals_get_subs_vals(input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS")
2804 IF (btest(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
2805 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS", &
2806 extension=".mao", log_filename=.false.)
2807 CALL edmf_analysis(qs_env, print_key, unit_nr)
2808 CALL cp_print_key_finished_output(unit_nr, logger, input, "DFT%PRINT%ENERGY_DECOMPOSITION_ANALYSIS")
2809 END IF
2810
2811 ! Print the density in the RI-HFX basis
2812 hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
2813 CALL section_vals_get(hfx_section, explicit=do_hfx)
2814 CALL section_vals_get(hfx_section, n_repetition=n_rep_hf)
2815 IF (do_hfx) THEN
2816 DO i = 1, n_rep_hf
2817 IF (qs_env%x_data(i, 1)%do_hfx_ri) CALL print_ri_hfx(qs_env%x_data(i, 1)%ri_data, qs_env)
2818 END DO
2819 END IF
2820
2821 DEALLOCATE (zcharge)
2822
2823 CALL timestop(handle)
2824
2825 END SUBROUTINE write_mo_free_results
2826
2827! **************************************************************************************************
2828!> \brief Calculates Hirshfeld charges
2829!> \param qs_env the qs_env where to calculate the charges
2830!> \param input_section the input section for Hirshfeld charges
2831!> \param unit_nr the output unit number
2832! **************************************************************************************************
2833 SUBROUTINE hirshfeld_charges(qs_env, input_section, unit_nr)
2834 TYPE(qs_environment_type), POINTER :: qs_env
2835 TYPE(section_vals_type), POINTER :: input_section
2836 INTEGER, INTENT(IN) :: unit_nr
2837
2838 INTEGER :: i, iat, ikind, natom, nkind, nspin, &
2839 radius_type, refc, shapef
2840 INTEGER, DIMENSION(:), POINTER :: atom_list
2841 LOGICAL :: do_radius, do_sc, paw_atom
2842 REAL(kind=dp) :: zeff
2843 REAL(kind=dp), DIMENSION(:), POINTER :: radii
2844 REAL(kind=dp), DIMENSION(:, :), POINTER :: charges
2845 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2846 TYPE(atomic_kind_type), POINTER :: atomic_kind
2847 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p, matrix_s
2848 TYPE(dft_control_type), POINTER :: dft_control
2849 TYPE(hirshfeld_type), POINTER :: hirshfeld_env
2850 TYPE(mp_para_env_type), POINTER :: para_env
2851 TYPE(mpole_rho_atom), DIMENSION(:), POINTER :: mp_rho
2852 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2853 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2854 TYPE(qs_rho_type), POINTER :: rho
2855 TYPE(rho0_mpole_type), POINTER :: rho0_mpole
2856
2857 NULLIFY (hirshfeld_env)
2858 NULLIFY (radii)
2859 CALL create_hirshfeld_type(hirshfeld_env)
2860 !
2861 CALL get_qs_env(qs_env, nkind=nkind, natom=natom)
2862 ALLOCATE (hirshfeld_env%charges(natom))
2863 ! input options
2864 CALL section_vals_val_get(input_section, "SELF_CONSISTENT", l_val=do_sc)
2865 CALL section_vals_val_get(input_section, "USER_RADIUS", l_val=do_radius)
2866 CALL section_vals_val_get(input_section, "SHAPE_FUNCTION", i_val=shapef)
2867 CALL section_vals_val_get(input_section, "REFERENCE_CHARGE", i_val=refc)
2868 IF (do_radius) THEN
2869 radius_type = radius_user
2870 CALL section_vals_val_get(input_section, "ATOMIC_RADII", r_vals=radii)
2871 IF (.NOT. SIZE(radii) == nkind) &
2872 CALL cp_abort(__location__, &
2873 "Length of keyword HIRSHFELD\ATOMIC_RADII does not "// &
2874 "match number of atomic kinds in the input coordinate file.")
2875 ELSE
2876 radius_type = radius_covalent
2877 END IF
2878 CALL set_hirshfeld_info(hirshfeld_env, shape_function_type=shapef, &
2879 iterative=do_sc, ref_charge=refc, &
2880 radius_type=radius_type)
2881 ! shape function
2882 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, atomic_kind_set=atomic_kind_set)
2883 CALL create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, &
2884 radii_list=radii)
2885 ! reference charges
2886 CALL get_qs_env(qs_env, rho=rho)
2887 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
2888 nspin = SIZE(matrix_p, 1)
2889 ALLOCATE (charges(natom, nspin))
2890 SELECT CASE (refc)
2891 CASE (ref_charge_atomic)
2892 DO ikind = 1, nkind
2893 CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
2894 atomic_kind => atomic_kind_set(ikind)
2895 CALL get_atomic_kind(atomic_kind, atom_list=atom_list)
2896 DO iat = 1, SIZE(atom_list)
2897 i = atom_list(iat)
2898 hirshfeld_env%charges(i) = zeff
2899 END DO
2900 END DO
2901 CASE (ref_charge_mulliken)
2902 CALL get_qs_env(qs_env, matrix_s_kp=matrix_s, para_env=para_env)
2903 CALL mulliken_charges(matrix_p, matrix_s, para_env, charges)
2904 DO iat = 1, natom
2905 hirshfeld_env%charges(iat) = sum(charges(iat, :))
2906 END DO
2907 CASE DEFAULT
2908 cpabort("Unknown type of reference charge for Hirshfeld partitioning.")
2909 END SELECT
2910 !
2911 charges = 0.0_dp
2912 IF (hirshfeld_env%iterative) THEN
2913 ! Hirshfeld-I charges
2914 CALL comp_hirshfeld_i_charges(qs_env, hirshfeld_env, charges, unit_nr)
2915 ELSE
2916 ! Hirshfeld charges
2917 CALL comp_hirshfeld_charges(qs_env, hirshfeld_env, charges)
2918 END IF
2919 CALL get_qs_env(qs_env, particle_set=particle_set, dft_control=dft_control)
2920 IF (dft_control%qs_control%gapw) THEN
2921 ! GAPW: add core charges (rho_hard - rho_soft)
2922 CALL get_qs_env(qs_env, rho0_mpole=rho0_mpole)
2923 CALL get_rho0_mpole(rho0_mpole, mp_rho=mp_rho)
2924 DO iat = 1, natom
2925 atomic_kind => particle_set(iat)%atomic_kind
2926 CALL get_atomic_kind(atomic_kind, kind_number=ikind)
2927 CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom)
2928 IF (paw_atom) THEN
2929 charges(iat, 1:nspin) = charges(iat, 1:nspin) + mp_rho(iat)%q0(1:nspin)
2930 END IF
2931 END DO
2932 END IF
2933 !
2934 IF (unit_nr > 0) THEN
2935 CALL write_hirshfeld_charges(charges, hirshfeld_env, particle_set, &
2936 qs_kind_set, unit_nr)
2937 END IF
2938 ! Save the charges to the results under the tag [HIRSHFELD-CHARGES]
2939 CALL save_hirshfeld_charges(charges, particle_set, qs_kind_set, qs_env)
2940 !
2941 CALL release_hirshfeld_type(hirshfeld_env)
2942 DEALLOCATE (charges)
2943
2944 END SUBROUTINE hirshfeld_charges
2945
2946! **************************************************************************************************
2947!> \brief ...
2948!> \param ca ...
2949!> \param a ...
2950!> \param cb ...
2951!> \param b ...
2952!> \param l ...
2953! **************************************************************************************************
2954 SUBROUTINE project_function_a(ca, a, cb, b, l)
2955 ! project function cb on ca
2956 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: ca
2957 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: a, cb, b
2958 INTEGER, INTENT(IN) :: l
2959
2960 INTEGER :: info, n
2961 INTEGER, ALLOCATABLE, DIMENSION(:) :: ipiv
2962 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: smat, tmat, v
2963
2964 n = SIZE(ca)
2965 ALLOCATE (smat(n, n), tmat(n, n), v(n, 1), ipiv(n))
2966
2967 CALL sg_overlap(smat, l, a, a)
2968 CALL sg_overlap(tmat, l, a, b)
2969 v(:, 1) = matmul(tmat, cb)
2970 CALL dgesv(n, 1, smat, n, ipiv, v, n, info)
2971 cpassert(info == 0)
2972 ca(:) = v(:, 1)
2973
2974 DEALLOCATE (smat, tmat, v, ipiv)
2975
2976 END SUBROUTINE project_function_a
2977
2978! **************************************************************************************************
2979!> \brief ...
2980!> \param ca ...
2981!> \param a ...
2982!> \param bfun ...
2983!> \param grid_atom ...
2984!> \param l ...
2985! **************************************************************************************************
2986 SUBROUTINE project_function_b(ca, a, bfun, grid_atom, l)
2987 ! project function f on ca
2988 REAL(kind=dp), DIMENSION(:), INTENT(OUT) :: ca
2989 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: a, bfun
2990 TYPE(grid_atom_type), POINTER :: grid_atom
2991 INTEGER, INTENT(IN) :: l
2992
2993 INTEGER :: i, info, n, nr
2994 INTEGER, ALLOCATABLE, DIMENSION(:) :: ipiv
2995 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: afun
2996 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: smat, v
2997
2998 n = SIZE(ca)
2999 nr = grid_atom%nr
3000 ALLOCATE (smat(n, n), v(n, 1), ipiv(n), afun(nr))
3001
3002 CALL sg_overlap(smat, l, a, a)
3003 DO i = 1, n
3004 afun(:) = grid_atom%rad(:)**l*exp(-a(i)*grid_atom%rad2(:))
3005 v(i, 1) = sum(afun(:)*bfun(:)*grid_atom%wr(:))
3006 END DO
3007 CALL dgesv(n, 1, smat, n, ipiv, v, n, info)
3008 cpassert(info == 0)
3009 ca(:) = v(:, 1)
3010
3011 DEALLOCATE (smat, v, ipiv, afun)
3012
3013 END SUBROUTINE project_function_b
3014
3015! **************************************************************************************************
3016!> \brief Performs printing of cube files from local energy
3017!> \param input input
3018!> \param logger the logger
3019!> \param qs_env the qs_env in which the qs_env lives
3020!> \par History
3021!> 07.2019 created
3022!> \author JGH
3023! **************************************************************************************************
3024 SUBROUTINE qs_scf_post_local_energy(input, logger, qs_env)
3025 TYPE(section_vals_type), POINTER :: input
3026 TYPE(cp_logger_type), POINTER :: logger
3027 TYPE(qs_environment_type), POINTER :: qs_env
3028
3029 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_local_energy'
3030
3031 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3032 INTEGER :: handle, io_unit, natom, unit_nr
3033 LOGICAL :: append_cube, gapw, gapw_xc, mpi_io
3034 TYPE(dft_control_type), POINTER :: dft_control
3035 TYPE(particle_list_type), POINTER :: particles
3036 TYPE(pw_env_type), POINTER :: pw_env
3037 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3038 TYPE(pw_r3d_rs_type) :: eden
3039 TYPE(qs_subsys_type), POINTER :: subsys
3040 TYPE(section_vals_type), POINTER :: dft_section
3041
3042 CALL timeset(routinen, handle)
3043 io_unit = cp_logger_get_default_io_unit(logger)
3044 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3045 "DFT%PRINT%LOCAL_ENERGY_CUBE"), cp_p_file)) THEN
3046 dft_section => section_vals_get_subs_vals(input, "DFT")
3047 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, natom=natom)
3048 gapw = dft_control%qs_control%gapw
3049 gapw_xc = dft_control%qs_control%gapw_xc
3050 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3051 CALL qs_subsys_get(subsys, particles=particles)
3052 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3053 CALL auxbas_pw_pool%create_pw(eden)
3054 !
3055 CALL qs_local_energy(qs_env, eden)
3056 !
3057 append_cube = section_get_lval(input, "DFT%PRINT%LOCAL_ENERGY_CUBE%APPEND")
3058 IF (append_cube) THEN
3059 my_pos_cube = "APPEND"
3060 ELSE
3061 my_pos_cube = "REWIND"
3062 END IF
3063 mpi_io = .true.
3064 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOCAL_ENERGY_CUBE", &
3065 extension=".cube", middle_name="local_energy", &
3066 file_position=my_pos_cube, mpi_io=mpi_io)
3067 CALL cp_pw_to_cube(eden, &
3068 unit_nr, "LOCAL ENERGY", particles=particles, &
3069 stride=section_get_ivals(dft_section, &
3070 "PRINT%LOCAL_ENERGY_CUBE%STRIDE"), mpi_io=mpi_io)
3071 IF (io_unit > 0) THEN
3072 INQUIRE (unit=unit_nr, name=filename)
3073 IF (gapw .OR. gapw_xc) THEN
3074 WRITE (unit=io_unit, fmt="(/,T3,A,A)") &
3075 "The soft part of the local energy is written to the file: ", trim(adjustl(filename))
3076 ELSE
3077 WRITE (unit=io_unit, fmt="(/,T3,A,A)") &
3078 "The local energy is written to the file: ", trim(adjustl(filename))
3079 END IF
3080 END IF
3081 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3082 "DFT%PRINT%LOCAL_ENERGY_CUBE", mpi_io=mpi_io)
3083 !
3084 CALL auxbas_pw_pool%give_back_pw(eden)
3085 END IF
3086 CALL timestop(handle)
3087
3088 END SUBROUTINE qs_scf_post_local_energy
3089
3090! **************************************************************************************************
3091!> \brief Performs printing of cube files from local energy
3092!> \param input input
3093!> \param logger the logger
3094!> \param qs_env the qs_env in which the qs_env lives
3095!> \par History
3096!> 07.2019 created
3097!> \author JGH
3098! **************************************************************************************************
3099 SUBROUTINE qs_scf_post_local_stress(input, logger, qs_env)
3100 TYPE(section_vals_type), POINTER :: input
3101 TYPE(cp_logger_type), POINTER :: logger
3102 TYPE(qs_environment_type), POINTER :: qs_env
3103
3104 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_local_stress'
3105
3106 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3107 INTEGER :: handle, io_unit, natom, unit_nr
3108 LOGICAL :: append_cube, gapw, gapw_xc, mpi_io
3109 REAL(kind=dp) :: beta
3110 TYPE(dft_control_type), POINTER :: dft_control
3111 TYPE(particle_list_type), POINTER :: particles
3112 TYPE(pw_env_type), POINTER :: pw_env
3113 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3114 TYPE(pw_r3d_rs_type) :: stress
3115 TYPE(qs_subsys_type), POINTER :: subsys
3116 TYPE(section_vals_type), POINTER :: dft_section
3117
3118 CALL timeset(routinen, handle)
3119 io_unit = cp_logger_get_default_io_unit(logger)
3120 IF (btest(cp_print_key_should_output(logger%iter_info, input, &
3121 "DFT%PRINT%LOCAL_STRESS_CUBE"), cp_p_file)) THEN
3122 dft_section => section_vals_get_subs_vals(input, "DFT")
3123 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, natom=natom)
3124 gapw = dft_control%qs_control%gapw
3125 gapw_xc = dft_control%qs_control%gapw_xc
3126 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3127 CALL qs_subsys_get(subsys, particles=particles)
3128 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3129 CALL auxbas_pw_pool%create_pw(stress)
3130 !
3131 ! use beta=0: kinetic energy density in symmetric form
3132 beta = 0.0_dp
3133 CALL qs_local_stress(qs_env, beta=beta)
3134 !
3135 append_cube = section_get_lval(input, "DFT%PRINT%LOCAL_STRESS_CUBE%APPEND")
3136 IF (append_cube) THEN
3137 my_pos_cube = "APPEND"
3138 ELSE
3139 my_pos_cube = "REWIND"
3140 END IF
3141 mpi_io = .true.
3142 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%LOCAL_STRESS_CUBE", &
3143 extension=".cube", middle_name="local_stress", &
3144 file_position=my_pos_cube, mpi_io=mpi_io)
3145 CALL cp_pw_to_cube(stress, &
3146 unit_nr, "LOCAL STRESS", particles=particles, &
3147 stride=section_get_ivals(dft_section, &
3148 "PRINT%LOCAL_STRESS_CUBE%STRIDE"), mpi_io=mpi_io)
3149 IF (io_unit > 0) THEN
3150 INQUIRE (unit=unit_nr, name=filename)
3151 WRITE (unit=io_unit, fmt="(/,T3,A)") "Write 1/3*Tr(sigma) to cube file"
3152 IF (gapw .OR. gapw_xc) THEN
3153 WRITE (unit=io_unit, fmt="(T3,A,A)") &
3154 "The soft part of the local stress is written to the file: ", trim(adjustl(filename))
3155 ELSE
3156 WRITE (unit=io_unit, fmt="(T3,A,A)") &
3157 "The local stress is written to the file: ", trim(adjustl(filename))
3158 END IF
3159 END IF
3160 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3161 "DFT%PRINT%LOCAL_STRESS_CUBE", mpi_io=mpi_io)
3162 !
3163 CALL auxbas_pw_pool%give_back_pw(stress)
3164 END IF
3165
3166 CALL timestop(handle)
3167
3168 END SUBROUTINE qs_scf_post_local_stress
3169
3170! **************************************************************************************************
3171!> \brief Performs printing of cube files related to the implicit Poisson solver
3172!> \param input input
3173!> \param logger the logger
3174!> \param qs_env the qs_env in which the qs_env lives
3175!> \par History
3176!> 03.2016 refactored from write_mo_free_results [Hossein Bani-Hashemian]
3177!> \author Mohammad Hossein Bani-Hashemian
3178! **************************************************************************************************
3179 SUBROUTINE qs_scf_post_ps_implicit(input, logger, qs_env)
3180 TYPE(section_vals_type), POINTER :: input
3181 TYPE(cp_logger_type), POINTER :: logger
3182 TYPE(qs_environment_type), POINTER :: qs_env
3183
3184 CHARACTER(len=*), PARAMETER :: routinen = 'qs_scf_post_ps_implicit'
3185
3186 CHARACTER(LEN=default_path_length) :: filename, my_pos_cube
3187 INTEGER :: boundary_condition, handle, i, j, &
3188 n_cstr, n_tiles, unit_nr
3189 LOGICAL :: append_cube, do_cstr_charge_cube, do_dielectric_cube, do_dirichlet_bc_cube, &
3190 has_dirichlet_bc, has_implicit_ps, mpi_io, tile_cubes
3191 TYPE(particle_list_type), POINTER :: particles
3192 TYPE(pw_env_type), POINTER :: pw_env
3193 TYPE(pw_poisson_type), POINTER :: poisson_env
3194 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3195 TYPE(pw_r3d_rs_type) :: aux_r
3196 TYPE(pw_r3d_rs_type), POINTER :: dirichlet_tile
3197 TYPE(qs_subsys_type), POINTER :: subsys
3198 TYPE(section_vals_type), POINTER :: dft_section
3199
3200 CALL timeset(routinen, handle)
3201
3202 NULLIFY (pw_env, auxbas_pw_pool, dft_section, particles)
3203
3204 dft_section => section_vals_get_subs_vals(input, "DFT")
3205 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, subsys=subsys)
3206 CALL qs_subsys_get(subsys, particles=particles)
3207 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
3208
3209 has_implicit_ps = .false.
3210 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
3211 IF (pw_env%poisson_env%parameters%solver == pw_poisson_implicit) has_implicit_ps = .true.
3212
3213 ! Write the dielectric constant into a cube file
3214 do_dielectric_cube = btest(cp_print_key_should_output(logger%iter_info, input, &
3215 "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE"), cp_p_file)
3216 IF (has_implicit_ps .AND. do_dielectric_cube) THEN
3217 append_cube = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE%APPEND")
3218 my_pos_cube = "REWIND"
3219 IF (append_cube) THEN
3220 my_pos_cube = "APPEND"
3221 END IF
3222 mpi_io = .true.
3223 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE", &
3224 extension=".cube", middle_name="DIELECTRIC_CONSTANT", file_position=my_pos_cube, &
3225 mpi_io=mpi_io)
3226 CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
3227 CALL auxbas_pw_pool%create_pw(aux_r)
3228
3229 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3230 SELECT CASE (boundary_condition)
3232 CALL pw_copy(poisson_env%implicit_env%dielectric%eps, aux_r)
3233 CASE (mixed_bc, neumann_bc)
3234 CALL pw_shrink(pw_env%poisson_env%parameters%ps_implicit_params%neumann_directions, &
3235 pw_env%poisson_env%implicit_env%dct_env%dests_shrink, &
3236 pw_env%poisson_env%implicit_env%dct_env%srcs_shrink, &
3237 pw_env%poisson_env%implicit_env%dct_env%bounds_local_shftd, &
3238 poisson_env%implicit_env%dielectric%eps, aux_r)
3239 END SELECT
3240
3241 CALL cp_pw_to_cube(aux_r, unit_nr, "DIELECTRIC CONSTANT", particles=particles, &
3242 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE%STRIDE"), &
3243 mpi_io=mpi_io)
3244 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3245 "DFT%PRINT%IMPLICIT_PSOLVER%DIELECTRIC_CUBE", mpi_io=mpi_io)
3246
3247 CALL auxbas_pw_pool%give_back_pw(aux_r)
3248 END IF
3249
3250 ! Write Dirichlet constraint charges into a cube file
3251 do_cstr_charge_cube = btest(cp_print_key_should_output(logger%iter_info, input, &
3252 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE"), cp_p_file)
3253
3254 has_dirichlet_bc = .false.
3255 IF (has_implicit_ps) THEN
3256 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3257 IF (boundary_condition == mixed_periodic_bc .OR. boundary_condition == mixed_bc) THEN
3258 has_dirichlet_bc = .true.
3259 END IF
3260 END IF
3261
3262 IF (has_implicit_ps .AND. do_cstr_charge_cube .AND. has_dirichlet_bc) THEN
3263 append_cube = section_get_lval(input, &
3264 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE%APPEND")
3265 my_pos_cube = "REWIND"
3266 IF (append_cube) THEN
3267 my_pos_cube = "APPEND"
3268 END IF
3269 mpi_io = .true.
3270 unit_nr = cp_print_key_unit_nr(logger, input, &
3271 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE", &
3272 extension=".cube", middle_name="dirichlet_cstr_charge", file_position=my_pos_cube, &
3273 mpi_io=mpi_io)
3274 CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
3275 CALL auxbas_pw_pool%create_pw(aux_r)
3276
3277 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3278 SELECT CASE (boundary_condition)
3279 CASE (mixed_periodic_bc)
3280 CALL pw_copy(poisson_env%implicit_env%cstr_charge, aux_r)
3281 CASE (mixed_bc)
3282 CALL pw_shrink(pw_env%poisson_env%parameters%ps_implicit_params%neumann_directions, &
3283 pw_env%poisson_env%implicit_env%dct_env%dests_shrink, &
3284 pw_env%poisson_env%implicit_env%dct_env%srcs_shrink, &
3285 pw_env%poisson_env%implicit_env%dct_env%bounds_local_shftd, &
3286 poisson_env%implicit_env%cstr_charge, aux_r)
3287 END SELECT
3288
3289 CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET CONSTRAINT CHARGE", particles=particles, &
3290 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE%STRIDE"), &
3291 mpi_io=mpi_io)
3292 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3293 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_CSTR_CHARGE_CUBE", mpi_io=mpi_io)
3294
3295 CALL auxbas_pw_pool%give_back_pw(aux_r)
3296 END IF
3297
3298 ! Write Dirichlet type constranits into cube files
3299 do_dirichlet_bc_cube = btest(cp_print_key_should_output(logger%iter_info, input, &
3300 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE"), cp_p_file)
3301 has_dirichlet_bc = .false.
3302 IF (has_implicit_ps) THEN
3303 boundary_condition = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
3304 IF (boundary_condition == mixed_periodic_bc .OR. boundary_condition == mixed_bc) THEN
3305 has_dirichlet_bc = .true.
3306 END IF
3307 END IF
3308
3309 IF (has_implicit_ps .AND. has_dirichlet_bc .AND. do_dirichlet_bc_cube) THEN
3310 append_cube = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%APPEND")
3311 my_pos_cube = "REWIND"
3312 IF (append_cube) THEN
3313 my_pos_cube = "APPEND"
3314 END IF
3315 tile_cubes = section_get_lval(input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%TILE_CUBES")
3316
3317 CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
3318 CALL auxbas_pw_pool%create_pw(aux_r)
3319 CALL pw_zero(aux_r)
3320
3321 IF (tile_cubes) THEN
3322 ! one cube file per tile
3323 n_cstr = SIZE(poisson_env%implicit_env%contacts)
3324 DO j = 1, n_cstr
3325 n_tiles = poisson_env%implicit_env%contacts(j)%dirichlet_bc%n_tiles
3326 DO i = 1, n_tiles
3327 filename = "dirichlet_cstr_"//trim(adjustl(cp_to_string(j)))// &
3328 "_tile_"//trim(adjustl(cp_to_string(i)))
3329 mpi_io = .true.
3330 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", &
3331 extension=".cube", middle_name=filename, file_position=my_pos_cube, &
3332 mpi_io=mpi_io)
3333
3334 CALL pw_copy(poisson_env%implicit_env%contacts(j)%dirichlet_bc%tiles(i)%tile%tile_pw, aux_r)
3335
3336 CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET TYPE CONSTRAINT", particles=particles, &
3337 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%STRIDE"), &
3338 mpi_io=mpi_io)
3339 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3340 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", mpi_io=mpi_io)
3341 END DO
3342 END DO
3343 ELSE
3344 ! a single cube file
3345 NULLIFY (dirichlet_tile)
3346 ALLOCATE (dirichlet_tile)
3347 CALL auxbas_pw_pool%create_pw(dirichlet_tile)
3348 CALL pw_zero(dirichlet_tile)
3349 mpi_io = .true.
3350 unit_nr = cp_print_key_unit_nr(logger, input, "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", &
3351 extension=".cube", middle_name="DIRICHLET_CSTR", file_position=my_pos_cube, &
3352 mpi_io=mpi_io)
3353
3354 n_cstr = SIZE(poisson_env%implicit_env%contacts)
3355 DO j = 1, n_cstr
3356 n_tiles = poisson_env%implicit_env%contacts(j)%dirichlet_bc%n_tiles
3357 DO i = 1, n_tiles
3358 CALL pw_copy(poisson_env%implicit_env%contacts(j)%dirichlet_bc%tiles(i)%tile%tile_pw, dirichlet_tile)
3359 CALL pw_axpy(dirichlet_tile, aux_r)
3360 END DO
3361 END DO
3362
3363 CALL cp_pw_to_cube(aux_r, unit_nr, "DIRICHLET TYPE CONSTRAINT", particles=particles, &
3364 stride=section_get_ivals(dft_section, "PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE%STRIDE"), &
3365 mpi_io=mpi_io)
3366 CALL cp_print_key_finished_output(unit_nr, logger, input, &
3367 "DFT%PRINT%IMPLICIT_PSOLVER%DIRICHLET_BC_CUBE", mpi_io=mpi_io)
3368 CALL auxbas_pw_pool%give_back_pw(dirichlet_tile)
3369 DEALLOCATE (dirichlet_tile)
3370 END IF
3371
3372 CALL auxbas_pw_pool%give_back_pw(aux_r)
3373 END IF
3374
3375 CALL timestop(handle)
3376
3377 END SUBROUTINE qs_scf_post_ps_implicit
3378
3379!**************************************************************************************************
3380!> \brief write an adjacency (interaction) matrix
3381!> \param qs_env qs environment
3382!> \param input the input
3383!> \author Mohammad Hossein Bani-Hashemian
3384! **************************************************************************************************
3385 SUBROUTINE write_adjacency_matrix(qs_env, input)
3386 TYPE(qs_environment_type), POINTER :: qs_env
3387 TYPE(section_vals_type), POINTER :: input
3388
3389 CHARACTER(len=*), PARAMETER :: routinen = 'write_adjacency_matrix'
3390
3391 INTEGER :: adjm_size, colind, handle, iatom, ikind, &
3392 ind, jatom, jkind, k, natom, nkind, &
3393 output_unit, rowind, unit_nr
3394 INTEGER, ALLOCATABLE, DIMENSION(:) :: interact_adjm
3395 LOGICAL :: do_adjm_write, do_symmetric
3396 TYPE(cp_logger_type), POINTER :: logger
3397 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
3398 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
3399 TYPE(mp_para_env_type), POINTER :: para_env
3401 DIMENSION(:), POINTER :: nl_iterator
3402 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
3403 POINTER :: nl
3404 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
3405 TYPE(section_vals_type), POINTER :: dft_section
3406
3407 CALL timeset(routinen, handle)
3408
3409 NULLIFY (dft_section)
3410
3411 logger => cp_get_default_logger()
3412 output_unit = cp_logger_get_default_io_unit(logger)
3413
3414 dft_section => section_vals_get_subs_vals(input, "DFT")
3415 do_adjm_write = btest(cp_print_key_should_output(logger%iter_info, dft_section, &
3416 "PRINT%ADJMAT_WRITE"), cp_p_file)
3417
3418 IF (do_adjm_write) THEN
3419 NULLIFY (qs_kind_set, nl_iterator)
3420 NULLIFY (basis_set_list_a, basis_set_list_b, basis_set_a, basis_set_b)
3421
3422 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, sab_orb=nl, natom=natom, para_env=para_env)
3423
3424 nkind = SIZE(qs_kind_set)
3425 cpassert(SIZE(nl) > 0)
3426 CALL get_neighbor_list_set_p(neighbor_list_sets=nl, symmetric=do_symmetric)
3427 cpassert(do_symmetric)
3428 ALLOCATE (basis_set_list_a(nkind), basis_set_list_b(nkind))
3429 CALL basis_set_list_setup(basis_set_list_a, "ORB", qs_kind_set)
3430 CALL basis_set_list_setup(basis_set_list_b, "ORB", qs_kind_set)
3431
3432 adjm_size = ((natom + 1)*natom)/2
3433 ALLOCATE (interact_adjm(4*adjm_size))
3434 interact_adjm = 0
3435
3436 NULLIFY (nl_iterator)
3437 CALL neighbor_list_iterator_create(nl_iterator, nl)
3438 DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
3439 CALL get_iterator_info(nl_iterator, &
3440 ikind=ikind, jkind=jkind, &
3441 iatom=iatom, jatom=jatom)
3442
3443 basis_set_a => basis_set_list_a(ikind)%gto_basis_set
3444 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
3445 basis_set_b => basis_set_list_b(jkind)%gto_basis_set
3446 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
3447
3448 ! move everything to the upper triangular part
3449 IF (iatom <= jatom) THEN
3450 rowind = iatom
3451 colind = jatom
3452 ELSE
3453 rowind = jatom
3454 colind = iatom
3455 ! swap the kinds too
3456 ikind = ikind + jkind
3457 jkind = ikind - jkind
3458 ikind = ikind - jkind
3459 END IF
3460
3461 ! indexing upper triangular matrix
3462 ind = adjm_size - (natom - rowind + 1)*((natom - rowind + 1) + 1)/2 + colind - rowind + 1
3463 ! convert the upper triangular matrix into a adjm_size x 4 matrix
3464 ! columns are: iatom, jatom, ikind, jkind
3465 interact_adjm((ind - 1)*4 + 1) = rowind
3466 interact_adjm((ind - 1)*4 + 2) = colind
3467 interact_adjm((ind - 1)*4 + 3) = ikind
3468 interact_adjm((ind - 1)*4 + 4) = jkind
3469 END DO
3470
3471 CALL para_env%sum(interact_adjm)
3472
3473 unit_nr = cp_print_key_unit_nr(logger, dft_section, "PRINT%ADJMAT_WRITE", &
3474 extension=".adjmat", file_form="FORMATTED", &
3475 file_status="REPLACE")
3476 IF (unit_nr > 0) THEN
3477 WRITE (unit_nr, "(1A,2X,1A,5X,1A,4X,A5,3X,A5)") "#", "iatom", "jatom", "ikind", "jkind"
3478 DO k = 1, 4*adjm_size, 4
3479 ! print only the interacting atoms
3480 IF (interact_adjm(k) > 0 .AND. interact_adjm(k + 1) > 0) THEN
3481 WRITE (unit_nr, "(I8,2X,I8,3X,I6,2X,I6)") interact_adjm(k:k + 3)
3482 END IF
3483 END DO
3484 END IF
3485
3486 CALL cp_print_key_finished_output(unit_nr, logger, dft_section, "PRINT%ADJMAT_WRITE")
3487
3488 CALL neighbor_list_iterator_release(nl_iterator)
3489 DEALLOCATE (basis_set_list_a, basis_set_list_b)
3490 END IF
3491
3492 CALL timestop(handle)
3493
3494 END SUBROUTINE write_adjacency_matrix
3495
3496! **************************************************************************************************
3497!> \brief Updates Hartree potential with MP2 density. Important for REPEAT charges
3498!> \param rho ...
3499!> \param qs_env ...
3500!> \author Vladimir Rybkin
3501! **************************************************************************************************
3502 SUBROUTINE update_hartree_with_mp2(rho, qs_env)
3503 TYPE(qs_rho_type), POINTER :: rho
3504 TYPE(qs_environment_type), POINTER :: qs_env
3505
3506 LOGICAL :: use_virial
3507 TYPE(pw_c1d_gs_type) :: rho_tot_gspace, v_hartree_gspace
3508 TYPE(pw_c1d_gs_type), POINTER :: rho_core
3509 TYPE(pw_env_type), POINTER :: pw_env
3510 TYPE(pw_poisson_type), POINTER :: poisson_env
3511 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3512 TYPE(pw_r3d_rs_type), POINTER :: v_hartree_rspace
3513 TYPE(qs_energy_type), POINTER :: energy
3514 TYPE(virial_type), POINTER :: virial
3515
3516 NULLIFY (auxbas_pw_pool, pw_env, poisson_env, energy, rho_core, v_hartree_rspace, virial)
3517 CALL get_qs_env(qs_env, pw_env=pw_env, energy=energy, &
3518 rho_core=rho_core, virial=virial, &
3519 v_hartree_rspace=v_hartree_rspace)
3520
3521 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
3522
3523 IF (.NOT. use_virial) THEN
3524
3525 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
3526 poisson_env=poisson_env)
3527 CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
3528 CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
3529
3530 CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
3531 CALL pw_poisson_solve(poisson_env, rho_tot_gspace, energy%hartree, &
3532 v_hartree_gspace, rho_core=rho_core)
3533
3534 CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
3535 CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
3536
3537 CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
3538 CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
3539 END IF
3540
3541 END SUBROUTINE update_hartree_with_mp2
3542
3543END MODULE qs_scf_post_gpw
static double norm_factor(double alpha, int L)
Types and set/get functions for auxiliary density matrix methods.
Definition admm_types.F:15
Contains methods used in the context of density fitting.
Definition admm_utils.F:15
subroutine, public admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_matrix)
...
Definition admm_utils.F:127
subroutine, public admm_correct_for_eigenvalues(ispin, admm_env, ks_matrix)
...
Definition admm_utils.F:53
subroutine, public sg_overlap(smat, l, pa, pb)
...
calculate the orbitals for a given atomic kind type
subroutine, public calculate_atomic_density(density, atomic_kind, qs_kind, ngto, iunit, optbasis, allelectron, confine)
...
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
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
DBCSR output in CP2K.
subroutine, public cp_dbcsr_write_sparse_matrix(sparse_matrix, before, after, qs_env, para_env, first_row, last_row, first_col, last_col, scale, output_unit, omit_headers)
...
Density Derived atomic point charges from a QM calculation (see Bloechl, J. Chem. Phys....
recursive subroutine, public get_ddapc(qs_env, calc_force, density_fit_section, density_type, qout1, qout2, out_radii, dq_out, ext_rho_tot_g, itype_of_density, iwc)
Computes the Density Derived Atomic Point Charges.
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
Definition cp_fm_diag.F:17
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
Definition cp_fm_diag.F:234
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_init_random(matrix, ncol, start_col)
fills a matrix with random numbers
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...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
...
the type I Discrete Cosine Transform (DCT-I)
Definition dct.F:16
subroutine, public pw_shrink(neumann_directions, dests_shrink, srcs_shrink, bounds_local_shftd, pw_in, pw_shrinked)
shrinks an evenly symmetric pw_r3d_rs_type data to a pw_r3d_rs_type data that is 8 times smaller (the...
Definition dct.F:700
Calculate Energy Decomposition analysis.
Definition ed_analysis.F:14
subroutine, public edmf_analysis(qs_env, input_section, unit_nr)
...
Calculation of charge equilibration method.
Definition eeq_method.F:12
subroutine, public eeq_print(qs_env, iounit, print_level, ext)
...
Definition eeq_method.F:124
Definition and initialisation of the et_coupling data type.
subroutine, public set_et_coupling_type(et_coupling, et_mo_coeff, rest_mat)
...
RI-methods for HFX.
Definition hfx_ri.F:12
subroutine, public print_ri_hfx(ri_data, qs_env)
Print RI-HFX quantities, as required by the PRINT subsection.
Definition hfx_ri.F:3627
Calculate Hirshfeld charges and related functions.
subroutine, public comp_hirshfeld_charges(qs_env, hirshfeld_env, charges)
...
subroutine, public create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, radius, radii_list)
creates kind specific shape functions for Hirshfeld charges
subroutine, public write_hirshfeld_charges(charges, hirshfeld_env, particle_set, qs_kind_set, unit_nr)
...
subroutine, public comp_hirshfeld_i_charges(qs_env, hirshfeld_env, charges, ounit)
...
subroutine, public save_hirshfeld_charges(charges, particle_set, qs_kind_set, qs_env)
saves the Hirshfeld charges to the results structure
The types needed for the calculation of Hirshfeld charges and related functions.
subroutine, public create_hirshfeld_type(hirshfeld_env)
...
subroutine, public set_hirshfeld_info(hirshfeld_env, shape_function_type, iterative, ref_charge, fnorm, radius_type, use_bohr)
Set values of a Hirshfeld env.
subroutine, public release_hirshfeld_type(hirshfeld_env)
...
Calculate intrinsic atomic orbitals and analyze wavefunctions.
subroutine, public iao_wfn_analysis(qs_env, iao_env, unit_nr, c_iao_coef, mos, bond_centers)
...
Calculate ntrinsic atomic orbitals and analyze wavefunctions.
Definition iao_types.F:14
subroutine, public iao_read_input(iao_env, iao_section, cell)
...
Definition iao_types.F:116
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_loc_jacobi
integer, parameter, public ref_charge_atomic
integer, parameter, public do_loc_mixed
integer, parameter, public do_loc_none
integer, parameter, public do_loc_lumo
integer, parameter, public radius_user
integer, parameter, public radius_covalent
integer, parameter, public ref_charge_mulliken
integer, parameter, public do_loc_homo
integer, parameter, public do_mixed
integer, parameter, public do_loc_both
integer, parameter, public ot_precond_full_all
objects that represent the structure of input sections and the data contained in an input section
real(kind=dp) function, public section_get_rval(section_vals, keyword_name)
...
integer function, dimension(:), pointer, public section_get_ivals(section_vals, keyword_name)
...
integer function, public section_get_ival(section_vals, keyword_name)
...
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
logical function, public section_get_lval(section_vals, keyword_name)
...
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
integer, parameter, public default_path_length
Definition kinds.F:58
Types and basic routines needed for a kpoint calculation.
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Calculate MAO's and analyze wavefunctions.
subroutine, public mao_analysis(qs_env, input_section, unit_nr)
...
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Utility routines for the memory handling.
Interface to the message passing library MPI.
Calculate localized minimal basis and analyze wavefunctions.
subroutine, public minbas_analysis(qs_env, input_section, unit_nr)
...
Functions handling the MOLDEN format. Split from mode_selective.
subroutine, public write_mos_molden(mos, qs_kind_set, particle_set, print_section)
Write out the MOs in molden format for visualisation.
Define the data structure for the molecule information.
compute mulliken charges we (currently) define them as c_i = 1/2 [ (PS)_{ii} + (SP)_{ii} ]
Definition mulliken.F:13
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:, :), allocatable, public indso
represent a simple array based list of the given type
Define the data structure for the particle information.
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public evolt
Definition physcon.F:183
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
Provide various population analyses and print the requested output information.
subroutine, public lowdin_population_analysis(qs_env, output_unit, print_level)
Perform a Lowdin population analysis based on a symmetric orthogonalisation of the density matrix usi...
subroutine, public mulliken_population_analysis(qs_env, output_unit, print_level)
Perform a Mulliken population analysis.
types of preconditioners
computes preconditioners, and implements methods to apply them currently used in qs_ot
Types containing essential information for running implicit (iterative) Poisson solver.
integer, parameter, public neumann_bc
integer, parameter, public mixed_bc
integer, parameter, public mixed_periodic_bc
integer, parameter, public periodic_bc
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
This module defines the grid data type and some basic operations on it.
Definition pw_grids.F:36
subroutine, public get_pw_grid_info(pw_grid, id_nr, mode, vol, dvol, npts, ngpts, ngpts_cut, dr, cutoff, orthorhombic, gvectors, gsquare)
Access to information stored in the pw_grid_type.
Definition pw_grids.F:185
subroutine, public pw_derive(pw, n)
Calculate the derivative of a plane wave vector.
functions related to the poisson solver on regular grids
integer, parameter, public pw_poisson_implicit
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Write wfx file, works as interface to chargemol and multiwfn.
subroutine, public write_wfx(qs_env, dft_section)
...
Calculate the plane wave density by collocating the primitive Gaussian functions (pgf).
subroutine, public calculate_wavefunction(mo_vectors, ivector, rho, rho_gspace, atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, pw_env, basis_type)
maps a given wavefunction on the grid
Calculation of commutator [H,r] matrices.
subroutine, public build_com_hr_matrix(qs_env, matrix_hr)
Calculation of the [H,r] commutators matrices over Cartesian Gaussian functions.
Calculation of the energies concerning the core charge distribution.
Calculation and writing of density of states.
Definition qs_dos.F:14
subroutine, public calculate_dos(mos, dft_section)
Compute and write density of states.
Definition qs_dos.F:59
subroutine, public calculate_dos_kp(qs_env, dft_section)
Compute and write density of states (kpoints)
Definition qs_dos.F:206
Calculates electric field gradients H.M. Petrili, P.E. Blochl, P. Blaha, K. Schwarz,...
subroutine, public qs_efg_calc(qs_env)
...
Does all kind of post scf calculations for GPW/GAPW.
subroutine, public qs_elf_calc(qs_env, elf_r, rho_cutoff)
...
Does all kind of post scf calculations for GPW/GAPW.
subroutine, public energy_windows(qs_env)
...
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, 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.
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.
Calculates hyperfine values.
Definition qs_epr_hyp.F:15
subroutine, public qs_epr_hyp_calc(qs_env)
...
Definition qs_epr_hyp.F:75
Some utility functions for the calculation of integrals.
subroutine, public basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
Set up an easy accessible list of the basis sets for all kinds.
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.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public qs_ks_update_qs_env(qs_env, calculate_forces, just_energy, print_active)
updates the Kohn Sham matrix of the given qs_env (facility method)
subroutine, public calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho, skip_nuclear_density)
...
subroutine, public qs_ks_did_change(ks_env, s_mstruct_changed, rho_changed, potential_changed, full_reset)
tells that some of the things relevant to the ks calculation did change. has to be called when change...
subroutine, public loc_dipole(input, dft_control, qs_loc_env, logger, qs_env)
Computes and prints the Dipole (using localized charges)
subroutine, public get_localization_info(qs_env, qs_loc_env, loc_section, mo_local, wf_r, wf_g, particles, coeff, evals, marked_states)
Performs localization of the orbitals.
New version of the module for the localization of the molecular orbitals This should be able to use d...
subroutine, public qs_loc_env_release(qs_loc_env)
...
subroutine, public qs_loc_env_create(qs_loc_env)
...
Some utilities for the construction of the localization environment.
subroutine, public loc_write_restart(qs_loc_env, section, mo_array, coeff_localized, do_homo, evals, do_mixed)
...
subroutine, public qs_loc_env_init(qs_loc_env, localized_wfn_control, qs_env, myspin, do_localize, loc_coeff, mo_loc_history)
allocates the data, and initializes the operators
subroutine, public qs_loc_control_init(qs_loc_env, loc_section, do_homo, do_mixed, do_xas, nloc_xas, spin_xas)
initializes everything needed for localization of the HOMOs
subroutine, public retain_history(mo_loc_history, mo_loc)
copy old mos to new ones, allocating as necessary
subroutine, public qs_loc_init(qs_env, qs_loc_env, localize_section, mos_localized, do_homo, do_mo_cubes, mo_loc_history, evals, tot_zeff_corr, do_mixed)
initializes everything needed for localization of the molecular orbitals
Routines for calculating local energy and stress tensor.
subroutine, public qs_local_stress(qs_env, stress_tensor, beta)
Routine to calculate the local stress.
subroutine, public qs_local_energy(qs_env, energy_density)
Routine to calculate the local energy.
Definition and initialisation of the mo data type.
Definition qs_mo_io.F:21
subroutine, public write_dm_binary_restart(mo_array, dft_section, tmpl_matrix)
calculates density matrix from mo set and writes the density matrix into a binary restart file
Definition qs_mo_io.F:174
collects routines that perform operations directly related to MOs
subroutine, public make_mo_eig(mos, nspins, ks_rmpv, scf_control, mo_derivs, admm_env, hairy_probes, probe)
Calculate KS eigenvalues starting from OF MOS.
Set occupation of molecular orbitals.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>
Definition qs_moments.F:14
subroutine, public qs_moment_locop(qs_env, magnetic, nmoments, reference, ref_point, unit_number, vel_reprs, com_nl)
...
subroutine, public qs_moment_kpoints(qs_env, nmoments, reference, ref_point, unit_number)
Calculate and print dipole moment elements d_nm(k) for k-point calculations.
subroutine, public qs_moment_berry_phase(qs_env, magnetic, nmoments, reference, ref_point, unit_number)
...
Define the neighbor list data types and the corresponding functionality.
subroutine, public neighbor_list_iterator_create(iterator_set, nl, search, nthread)
Neighbor list iterator functions.
subroutine, public neighbor_list_iterator_release(iterator_set)
...
subroutine, public get_neighbor_list_set_p(neighbor_list_sets, nlist, symmetric)
Return the components of the first neighbor list set.
integer function, public neighbor_list_iterate(iterator_set, mepos)
...
subroutine, public get_iterator_info(iterator_set, mepos, ikind, jkind, nkind, ilist, nlist, inode, nnode, iatom, jatom, r, cell)
...
an eigen-space solver for the generalised symmetric eigenvalue problem for sparse matrices,...
subroutine, public ot_eigensolver(matrix_h, matrix_s, matrix_orthogonal_space_fm, matrix_c_fm, preconditioner, eps_gradient, iter_max, size_ortho_space, silent, ot_settings)
...
Calculation and writing of projected density of states The DOS is computed per angular momentum and p...
Definition qs_pdos.F:15
subroutine, public calculate_projected_dos(mo_set, atomic_kind_set, qs_kind_set, particle_set, qs_env, dft_section, ispin, xas_mittle, external_matrix_shalf)
Compute and write projected density of states.
Definition qs_pdos.F:139
provides a resp fit for gas phase systems
Definition qs_resp.F:16
subroutine, public resp_fit(qs_env)
performs resp fit and generates RESP charges
Definition qs_resp.F:132
subroutine, public get_rho0_mpole(rho0_mpole, g0_h, vg0_h, iat, ikind, lmax_0, l0_ikind, mp_gau_ikind, mp_rho, norm_g0l_h, qlm_gg, qlm_car, qlm_tot, zet0_h, igrid_zet0_s, rpgf0_h, rpgf0_s, max_rpgf0_s, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs)
...
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...
Functions to print the KS and S matrix in the CSR format to file.
subroutine, public write_s_matrix_csr(qs_env, input)
writing the overlap matrix in csr format into a file
subroutine, public write_ks_matrix_csr(qs_env, input)
writing the KS matrix in csr format into a file
subroutine, public write_p_matrix_csr(qs_env, input)
writing the density matrix in csr format into a file
subroutine, public write_hcore_matrix_csr(qs_env, input)
writing the core Hamiltonian matrix in csr format into a file
subroutine, public qs_scf_write_mos(qs_env, scf_env, final_mos)
Write the MO eigenvector, eigenvalues, and occupation numbers to the output unit.
Does all kind of post scf calculations for GPW/GAPW.
subroutine, public make_lumo_gpw(qs_env, scf_env, unoccupied_orbs, unoccupied_evals, nlumo, nlumos)
Gets the lumos, and eigenvalues for the lumos.
subroutine, public write_mo_free_results(qs_env)
Write QS results always available (if switched on through the print_keys) Can be called from ls_scf.
subroutine, public qs_scf_post_moments(input, logger, qs_env, output_unit)
Computes and prints electric moments.
subroutine, public write_mo_dependent_results(qs_env, scf_env)
Write QS results available if MO's are present (if switched on through the print_keys) Writes only MO...
subroutine, public scf_post_calculation_gpw(qs_env, wf_type, do_mp2)
collects possible post - scf calculations and prints info / computes properties.
module that contains the definitions of the scf types
integer, parameter, public ot_method_nr
Does all kind of post scf calculations for GPW/GAPW.
subroutine, public wfn_mix(mos, particle_set, dft_section, qs_kind_set, para_env, output_unit, unoccupied_orbs, scf_env, matrix_s, marked_states, for_rtp)
writes a new 'mixed' set of mos to restart file, without touching the current MOs
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
Interface to Wannier90 code.
subroutine, public wannier90_interface(input, logger, qs_env)
...
Methods related to (\cal S)^2 (i.e. spin)
subroutine, public compute_s_square(mos, matrix_s, s_square, s_square_ideal, mo_derivs, strength)
Compute the expectation value <(\cal S)^2> of the single determinant defined by the spin up (alpha) a...
parameters that control an scf iteration
Calculation of STM image as post processing of an electronic structure calculation,...
Definition stm_images.F:15
subroutine, public th_stm_image(qs_env, stm_section, particles, unoccupied_orbs, unoccupied_evals)
Driver for the calculation of STM image, as post processing of a ground-state electronic structure ca...
Definition stm_images.F:90
routines for DFT+NEGF calculations (coupling with the quantum transport code OMEN)
Definition transport.F:19
subroutine, public qs_scf_post_transport(qs_env)
post scf calculations for transport
Definition transport.F:747
The module to read/write TREX IO files for interfacing CP2K with other programs.
subroutine, public write_trexio(qs_env, trexio_section, energy_derivative)
Write a trexio file.
Interface for Voronoi Integration and output of BQB files.
subroutine, public entry_voronoi_or_bqb(do_voro, do_bqb, input_voro, input_bqb, unit_voro, qs_env, rspace_pw)
Does a Voronoi integration of density or stores the density to compressed BQB format.
subroutine, public xray_diffraction_spectrum(qs_env, unit_number, q_max)
Calculate the coherent X-ray diffraction spectrum using the total electronic density in reciprocal sp...
subroutine, public calculate_rhotot_elec_gspace(qs_env, auxbas_pw_pool, rhotot_elec_gspace, q_max, rho_hard, rho_soft, fsign)
The total electronic density in reciprocal space (g-space) is calculated.
stores some data used in wavefunction fitting
Definition admm_types.F:120
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represent a pointer to a 1d array
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
quantities needed for a Hirshfeld based partitioning of real space
Contains information about kpoints.
stores all the informations relevant to an mpi environment
contained for different pw related things
environment for the poisson solver
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 ...
Provides all information about a quickstep kind.
contains all the info needed by quickstep to calculate the spread of a selected set of orbitals and i...
keeps the density in various representations, keeping track of which ones are valid.